diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -867,16 +867,7 @@ If :func:`getdefaulttimeout` is not :const:`None`, sockets returned by the :meth:`~socket.accept` method inherit that timeout. Otherwise, the -behaviour depends on settings of the listening socket: - -* if the listening socket is in *blocking mode* or in *timeout mode*, - the socket returned by :meth:`~socket.accept` is in *blocking mode*; - -* if the listening socket is in *non-blocking mode*, whether the socket - returned by :meth:`~socket.accept` is in blocking or non-blocking mode - is operating system-dependent. If you want to ensure cross-platform - behaviour, it is recommended you manually override this setting. - +timeout state is inherited from the listening socket: .. _socket-example: diff --git a/Lib/socket.py b/Lib/socket.py --- a/Lib/socket.py +++ b/Lib/socket.py @@ -134,11 +134,10 @@ """ fd, addr = self._accept() sock = socket(self.family, self.type, self.proto, fileno=fd) - # Issue #7995: if no default timeout is set and the listening - # socket had a (non-zero) timeout, force the new socket in blocking - # mode to override platform-specific socket flags inheritance. - if getdefaulttimeout() is None and self.gettimeout(): - sock.setblocking(True) + # Issue #7995: if no default timeout is set, inherit the + # timeout of the listening socket. + if getdefaulttimeout() is None: + sock.settimeout(self.gettimeout()) return sock, addr def makefile(self, mode="r", buffering=None, *, diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -781,8 +781,12 @@ #endif { s->sock_timeout = defaulttimeout; - if (defaulttimeout >= 0.0) - internal_setblocking(s, 0); + /* the internal blocking state of the socket is + * unknown, because it may have come from an accept() + * or dup call. Make sure it is what s->sock-timeout + * expects + */ + internal_setblocking(s, s->sock_timeout < 0.0); } }