Issue 24334: SSLSocket extra level of indirection (original) (raw)
I just noticed that #21965 has added an extra level of indirection to the SSLSocket object. In Python 3.4 and earlier the ssl.SSLSocket object has one level of indirection:
import ssl ctx = ssl.create_default_context() sock = ssl.create_connection(('www.python.org', 443)) ssock = ctx.wrap_socket(sock, server_hostname='www.python.org') ssock <ssl.SSLSocket fd=3, family=AddressFamily.AF_INET, type=SocketType.SOCK_STREAM, proto=6, laddr=('192.168.7.122', 39657), raddr=('185.31.17.223', 443)> ssock._sslobj <_ssl._SSLSocket object at 0x7efcb9fd8c00>
In 3.5 an additional level comes into play:
import ssl ctx = ssl.create_default_context() sock = ssl.create_connection(('www.python.org', 443)) ssock = ctx.wrap_socket(sock, server_hostname='www.python.org') ssock <ssl.SSLSocket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('192.168.7.122', 39664), raddr=('185.31.17.223', 443)> ssock._sslobj <ssl.SSLObject object at 0x7fa55a96bb00> ssock._sslobj._sslobj <_ssl._SSLSocket object at 0x7fa5506918a0>
Method calls like SSLSocket.read() now call SSLObject.read(), which call _SSLSocket.read(). That seems a bit excessive. Isn't there a better way with less indirections?
I have created a proof-of-concept patch that removes the extra layer with some code duplication. Maybe the common code can be moved into a commmon base class for SSLObject and SSLSocket? After all both classes provide a similar interface.
I made SSLSocket go through SSLObject so that the test suite that is primarily testing SSLSocket will test both.
Indeed, I like the fact it makes test coverage broader.
Of course, if there's another way to get such coverage without duplicating lots of code, then why not.