Index: Lib/socket.py =================================================================== --- Lib/socket.py (revision 58962) +++ Lib/socket.py (working copy) @@ -21,7 +21,6 @@ htons(), htonl() -- convert 16, 32 bit int from host to network byte order inet_aton() -- convert IP addr string (123.45.67.89) to 32-bit packed format inet_ntoa() -- convert 32-bit packed format IP to string (123.45.67.89) -ssl() -- secure socket layer support (only available if configured) socket.getdefaulttimeout() -- get the default timeout value socket.setdefaulttimeout() -- set the default timeout value create_connection() -- connects to an address, with an optional timeout @@ -46,36 +45,6 @@ import _socket from _socket import * -try: - import _ssl - import ssl as _realssl -except ImportError: - # no SSL support - pass -else: - def ssl(sock, keyfile=None, certfile=None): - # we do an internal import here because the ssl - # module imports the socket module - warnings.warn("socket.ssl() is deprecated. Use ssl.wrap_socket() instead.", - DeprecationWarning, stacklevel=2) - return _realssl.sslwrap_simple(sock, keyfile, certfile) - - # we need to import the same constants we used to... - from _ssl import SSLError as sslerror - from _ssl import \ - RAND_add, \ - RAND_egd, \ - RAND_status, \ - SSL_ERROR_ZERO_RETURN, \ - SSL_ERROR_WANT_READ, \ - SSL_ERROR_WANT_WRITE, \ - SSL_ERROR_WANT_X509_LOOKUP, \ - SSL_ERROR_SYSCALL, \ - SSL_ERROR_SSL, \ - SSL_ERROR_WANT_CONNECT, \ - SSL_ERROR_EOF, \ - SSL_ERROR_INVALID_ERROR_CODE - import os, sys, io try: @@ -119,49 +88,11 @@ nfd = os.dup(fd) return socket(family, type, proto, fileno=nfd) -class SocketCloser: - - """Helper to manage socket close() logic for makefile(). - - The OS socket should not be closed until the socket and all - of its makefile-children are closed. If the refcount is zero - when socket.close() is called, this is easy: Just close the - socket. If the refcount is non-zero when socket.close() is - called, then the real close should not occur until the last - makefile-child is closed. - """ - - def __init__(self, sock): - self._sock = sock - self._makefile_refs = 0 - # Test whether the socket is open. - try: - sock.fileno() - self._socket_open = True - except error: - self._socket_open = False - - def socket_close(self): - self._socket_open = False - self.close() - - def makefile_open(self): - self._makefile_refs += 1 - - def makefile_close(self): - self._makefile_refs -= 1 - self.close() - - def close(self): - if not (self._socket_open or self._makefile_refs): - self._sock._real_close() - - class socket(_socket.socket): """A subclass of _socket.socket adding the makefile() method.""" - __slots__ = ["__weakref__", "_closer"] + __slots__ = ["__weakref__", "_io_refs", "_closed"] if not _can_dup_socket: __slots__.append("_base") @@ -170,16 +101,17 @@ _socket.socket.__init__(self, family, type, proto) else: _socket.socket.__init__(self, family, type, proto, fileno) - # Defer creating a SocketCloser until makefile() is actually called. - self._closer = None + self._io_refs = 0 + self._closed = False def __repr__(self): """Wrap __repr__() to reveal the real class name.""" s = _socket.socket.__repr__(self) if s.startswith(" 0: + self._io_refs -= 1 + if self._closed: + self.close() + def makefile(self, mode="r", buffering=None, *, encoding=None, newline=None): """Return an I/O stream connected to the socket. @@ -216,9 +154,8 @@ rawmode += "r" if writing: rawmode += "w" - if self._closer is None: - self._closer = SocketCloser(self) - raw = SocketIO(self, rawmode, self._closer) + raw = SocketIO(self, rawmode) + self._io_refs += 1 if buffering is None: buffering = -1 if buffering < 0: @@ -246,10 +183,9 @@ return text def close(self): - if self._closer is None: + self._closed = True + if self._io_refs < 1: self._real_close() - else: - self._closer.socket_close() # _real_close calls close on the _socket.socket base class. @@ -275,16 +211,14 @@ # XXX More docs - def __init__(self, sock, mode, closer): + def __init__(self, sock, mode): if mode not in ("r", "w", "rw"): raise ValueError("invalid mode: %r" % mode) io.RawIOBase.__init__(self) self._sock = sock self._mode = mode - self._closer = closer self._reading = "r" in mode self._writing = "w" in mode - closer.makefile_open() def readinto(self, b): self._checkClosed() @@ -308,10 +242,12 @@ def close(self): if self.closed: return - self._closer.makefile_close() io.RawIOBase.close(self) + def __del__(self): + self._sock.decref_socketios() + def getfqdn(name=''): """Get fully qualified domain name from name.