]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-42413: socket.timeout is now an alias of TimeoutError (GH-23413)
authorChristian Heimes <christian@python.org>
Fri, 20 Nov 2020 08:26:07 +0000 (09:26 +0100)
committerGitHub <noreply@github.com>
Fri, 20 Nov 2020 08:26:07 +0000 (00:26 -0800)
Signed-off-by: Christian Heimes <christian@python.org>
24 files changed:
Doc/library/smtplib.rst
Doc/library/socket.rst
Doc/whatsnew/3.10.rst
Lib/http/server.py
Lib/idlelib/pyshell.py
Lib/socket.py
Lib/test/support/socket_helper.py
Lib/test/test_asyncio/functional.py
Lib/test/test_asyncore.py
Lib/test/test_exception_hierarchy.py
Lib/test/test_ftplib.py
Lib/test/test_imaplib.py
Lib/test/test_poplib.py
Lib/test/test_signal.py
Lib/test/test_smtplib.py
Lib/test/test_socket.py
Lib/test/test_ssl.py
Lib/test/test_telnetlib.py
Lib/test/test_timeout.py
Lib/test/test_urllib2net.py
Lib/test/test_xmlrpc.py
Misc/NEWS.d/next/Library/2020-11-19-20-27-51.bpo-42413.fjHrHx.rst [new file with mode: 0644]
Modules/_ssl.c
Modules/socketmodule.c

index 8f5ca0ac30022379031d065001a3ba88f6d281f9..52220f7a7f30ace2e17d0d2c7b827f37628b7317 100644 (file)
@@ -32,7 +32,7 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions).
    than a success code, an :exc:`SMTPConnectError` is raised. The optional
    *timeout* parameter specifies a timeout in seconds for blocking operations
    like the connection attempt (if not specified, the global default timeout
-   setting will be used).  If the timeout expires, :exc:`socket.timeout` is
+   setting will be used).  If the timeout expires, :exc:`TimeoutError` is
    raised.  The optional source_address parameter allows binding
    to some specific source address in a machine with multiple network
    interfaces, and/or to some specific source TCP port. It takes a 2-tuple
index faf8a76251420e27d791184ba3aa403640f1411b..d52b84f610ed674d209ee55ef2261a56317c4345 100755 (executable)
@@ -283,6 +283,8 @@ Exceptions
 
 .. exception:: timeout
 
+   A deprecated alias of :exc:`TimeoutError`.
+
    A subclass of :exc:`OSError`, this exception is raised when a timeout
    occurs on a socket which has had timeouts enabled via a prior call to
    :meth:`~socket.settimeout` (or implicitly through
@@ -292,6 +294,9 @@ Exceptions
    .. versionchanged:: 3.3
       This class was made a subclass of :exc:`OSError`.
 
+   .. versionchanged:: 3.10
+      This class was made an alias of :exc:`TimeoutError`.
+
 
 Constants
 ^^^^^^^^^
@@ -1208,7 +1213,7 @@ to sockets.
    address family --- see above.)
 
    If the connection is interrupted by a signal, the method waits until the
-   connection completes, or raise a :exc:`socket.timeout` on timeout, if the
+   connection completes, or raise a :exc:`TimeoutError` on timeout, if the
    signal handler doesn't raise an exception and the socket is blocking or has
    a timeout. For non-blocking sockets, the method raises an
    :exc:`InterruptedError` exception if the connection is interrupted by a
index ad0ec4def0b70ba45a5b20b166db19da5a3735d1..826d12704a1c9e1bd793f47c17f897492c439b69 100644 (file)
@@ -263,6 +263,12 @@ site
 When a module does not define ``__loader__``, fall back to ``__spec__.loader``.
 (Contributed by Brett Cannon in :issue:`42133`.)
 
+socket
+------
+
+The exception :exc:`socket.timeout` is now an alias of :exc:`TimeoutError`.
+(Contributed by Christian Heimes in :issue:`42413`.)
+
 sys
 ---
 
index fa204fbc15e3d71ea19e01685d942fc1e8d99551..ee991821099135ae50762a35e24fd182240ebd0b 100644 (file)
@@ -414,7 +414,7 @@ class BaseHTTPRequestHandler(socketserver.StreamRequestHandler):
             method = getattr(self, mname)
             method()
             self.wfile.flush() #actually send the response if not already done.
-        except socket.timeout as e:
+        except TimeoutError as e:
             #a read or a write timed out.  Discard this connection
             self.log_error("Request timed out: %r", e)
             self.close_connection = True
index b69916dbe876cae7afce2d6f6aac3850f54def8f..343d2ef32d7a76f6287e004860d5db67c15834f2 100755 (executable)
@@ -463,7 +463,7 @@ class ModifiedInterpreter(InteractiveInterpreter):
         self.rpcclt.listening_sock.settimeout(10)
         try:
             self.rpcclt.accept()
-        except socket.timeout:
+        except TimeoutError:
             self.display_no_subprocess_error()
             return None
         self.rpcclt.register("console", self.tkconsole)
@@ -498,7 +498,7 @@ class ModifiedInterpreter(InteractiveInterpreter):
         self.spawn_subprocess()
         try:
             self.rpcclt.accept()
-        except socket.timeout:
+        except TimeoutError:
             self.display_no_subprocess_error()
             return None
         self.transfer_path(with_cwd=with_cwd)
index cafa573a30c0525522cf0377c35cbd83cba0fed1..54a380787601ead01e2767e56eb2bdaabcdf18c6 100755 (executable)
@@ -377,7 +377,7 @@ class socket(_socket.socket):
             try:
                 while True:
                     if timeout and not selector_select(timeout):
-                        raise _socket.timeout('timed out')
+                        raise TimeoutError('timed out')
                     if count:
                         blocksize = count - total_sent
                         if blocksize <= 0:
index 7070c12c253f6dbe6562ac2ca1c1090efa8a4319..e78712b74b1377f3d65bfd6495ce152f284a4f3d 100644 (file)
@@ -225,7 +225,7 @@ def transient_internet(resource_name, *, timeout=_NOT_SET, errnos=()):
 
     def filter_error(err):
         n = getattr(err, 'errno', None)
-        if (isinstance(err, socket.timeout) or
+        if (isinstance(err, TimeoutError) or
             (isinstance(err, socket.gaierror) and n in gai_errnos) or
             (isinstance(err, urllib.error.HTTPError) and
              500 <= err.code <= 599) or
index 5cd0659387d843ba50fcb93c43dc1a33b9aea424..74490a869de9d95a39c4a466c7ff4531e7fd3b8a 100644 (file)
@@ -248,7 +248,7 @@ class TestThreadedServer(SocketThread):
                     conn, addr = self._sock.accept()
                 except BlockingIOError:
                     continue
-                except socket.timeout:
+                except TimeoutError:
                     if not self._active:
                         return
                     else:
index 06c6bc2e99dc02a65515ac625762bdada0a9ffb8..3bd904d1774bc36ce96847a314cc03c6d75d2b4c 100644 (file)
@@ -69,7 +69,7 @@ def capture_server(evt, buf, serv):
     try:
         serv.listen()
         conn, addr = serv.accept()
-    except socket.timeout:
+    except TimeoutError:
         pass
     else:
         n = 200
index 43b4af84039c0cb08e938091383fe2cbe03d7406..89fe9ddcefba3ee14ec434474cc9800181eded99 100644 (file)
@@ -40,10 +40,10 @@ class HierarchyTest(unittest.TestCase):
         self.assertIs(EnvironmentError, OSError)
 
     def test_socket_errors(self):
-        self.assertIs(socket.error, IOError)
+        self.assertIs(socket.error, OSError)
         self.assertIs(socket.gaierror.__base__, OSError)
         self.assertIs(socket.herror.__base__, OSError)
-        self.assertIs(socket.timeout.__base__, OSError)
+        self.assertIs(socket.timeout, TimeoutError)
 
     def test_select_error(self):
         self.assertIs(select.error, OSError)
index 39658f22aa18c3280a0cf22f7dc98d7e4fc713d6..2424911c7ac5e9fa9a25eb3be33eba0c66da249f 100644 (file)
@@ -1036,7 +1036,7 @@ class TestTimeouts(TestCase):
         self.evt.set()
         try:
             conn, addr = self.sock.accept()
-        except socket.timeout:
+        except TimeoutError:
             pass
         else:
             conn.sendall(b"1 Hola mundo\n")
index 96bcb09261e9e70ac5ab3e36d20c892469237681..0cab7897a96dcbd0d92628a624eb14958850bfa4 100644 (file)
@@ -476,7 +476,7 @@ class NewIMAPTestsMixin():
 
         _, server = self._setup(TimeoutHandler)
         addr = server.server_address[1]
-        with self.assertRaises(socket.timeout):
+        with self.assertRaises(TimeoutError):
             client = self.imap_class("localhost", addr, timeout=0.001)
 
     def test_with_statement(self):
index 2ac345ddd68a95def1551a78c0d651a793a4afc8..548868362a397fc5af8e472c2f05d2a2061a87df 100644 (file)
@@ -501,7 +501,7 @@ class TestTimeouts(TestCase):
             conn, addr = serv.accept()
             conn.send(b"+ Hola mundo\n")
             conn.close()
-        except socket.timeout:
+        except TimeoutError:
             pass
         finally:
             serv.close()
index c6567906321fe172ecfe7826206f98393c93c4be..5a8ff361f9656ba7aada1314a800481fdd1c6b34 100644 (file)
@@ -528,7 +528,7 @@ class WakeupSocketSignalTests(unittest.TestCase):
                 while True:
                     write.send(chunk)
                     written += chunk_size
-            except (BlockingIOError, socket.timeout):
+            except (BlockingIOError, TimeoutError):
                 pass
 
         print(f"%s bytes written into the socketpair" % written, flush=True)
index 7816ed34886e95bffb72663598776f7ec21beb3f..91985384ec7ff96b1d85a37d93ba3ea43d3e0598 100644 (file)
@@ -40,7 +40,7 @@ def server(evt, buf, serv):
     evt.set()
     try:
         conn, addr = serv.accept()
-    except socket.timeout:
+    except TimeoutError:
         pass
     else:
         n = 500
@@ -193,7 +193,7 @@ def debugging_server(serv, serv_evt, client_evt):
 
             n -= 1
 
-    except socket.timeout:
+    except TimeoutError:
         pass
     finally:
         if not client_evt.is_set():
index 80638325ba3a05f71ba6227b40bd1642f4b36d09..5f57ab2f89d8d3902700eb1dba654f9171d22bb7 100755 (executable)
@@ -1611,7 +1611,7 @@ class GeneralModuleTests(unittest.TestCase):
             if with_timeout:
                 signal.signal(signal.SIGALRM, ok_handler)
                 signal.alarm(1)
-                self.assertRaises(socket.timeout, c.sendall,
+                self.assertRaises(TimeoutError, c.sendall,
                                   b"x" * support.SOCK_MAX_SIZE)
         finally:
             signal.alarm(0)
@@ -2966,7 +2966,7 @@ class SendmsgStreamTests(SendmsgTests):
             try:
                 while True:
                     self.sendmsgToServer([b"a"*512])
-            except socket.timeout:
+            except TimeoutError:
                 pass
             except OSError as exc:
                 if exc.errno != errno.ENOMEM:
@@ -2974,7 +2974,7 @@ class SendmsgStreamTests(SendmsgTests):
                 # bpo-33937 the test randomly fails on Travis CI with
                 # "OSError: [Errno 12] Cannot allocate memory"
             else:
-                self.fail("socket.timeout not raised")
+                self.fail("TimeoutError not raised")
         finally:
             self.misc_event.set()
 
@@ -3109,7 +3109,7 @@ class RecvmsgGenericTests(SendrecvmsgBase):
         # Check that timeout works.
         try:
             self.serv_sock.settimeout(0.03)
-            self.assertRaises(socket.timeout,
+            self.assertRaises(TimeoutError,
                               self.doRecvmsg, self.serv_sock, len(MSG))
         finally:
             self.misc_event.set()
@@ -4827,7 +4827,7 @@ class FileObjectClassTestCase(SocketConnectedTest):
         self.cli_conn.settimeout(1)
         self.read_file.read(3)
         # First read raises a timeout
-        self.assertRaises(socket.timeout, self.read_file.read, 1)
+        self.assertRaises(TimeoutError, self.read_file.read, 1)
         # Second read is disallowed
         with self.assertRaises(OSError) as ctx:
             self.read_file.read(1)
@@ -5092,7 +5092,7 @@ class NetworkConnectionNoServer(unittest.TestCase):
 
     class MockSocket(socket.socket):
         def connect(self, *args):
-            raise socket.timeout('timed out')
+            raise TimeoutError('timed out')
 
     @contextlib.contextmanager
     def mocked_socket_module(self):
@@ -5142,13 +5142,13 @@ class NetworkConnectionNoServer(unittest.TestCase):
         with self.mocked_socket_module():
             try:
                 socket.create_connection((HOST, 1234))
-            except socket.timeout:
+            except TimeoutError:
                 pass
             except OSError as exc:
                 if socket_helper.IPV6_ENABLED or exc.errno != errno.EAFNOSUPPORT:
                     raise
             else:
-                self.fail('socket.timeout not raised')
+                self.fail('TimeoutError not raised')
 
 
 class NetworkConnectionAttributesTest(SocketTCPTest, ThreadableTest):
@@ -5250,7 +5250,7 @@ class NetworkConnectionBehaviourTest(SocketTCPTest, ThreadableTest):
 
     def _testOutsideTimeout(self):
         self.cli = sock = socket.create_connection((HOST, self.port), timeout=1)
-        self.assertRaises(socket.timeout, lambda: sock.recv(5))
+        self.assertRaises(TimeoutError, lambda: sock.recv(5))
 
 
 class TCPTimeoutTest(SocketTCPTest):
@@ -5259,7 +5259,7 @@ class TCPTimeoutTest(SocketTCPTest):
         def raise_timeout(*args, **kwargs):
             self.serv.settimeout(1.0)
             self.serv.accept()
-        self.assertRaises(socket.timeout, raise_timeout,
+        self.assertRaises(TimeoutError, raise_timeout,
                               "Error generating a timeout exception (TCP)")
 
     def testTimeoutZero(self):
@@ -5267,7 +5267,7 @@ class TCPTimeoutTest(SocketTCPTest):
         try:
             self.serv.settimeout(0.0)
             foo = self.serv.accept()
-        except socket.timeout:
+        except TimeoutError:
             self.fail("caught timeout instead of error (TCP)")
         except OSError:
             ok = True
@@ -5292,7 +5292,7 @@ class TCPTimeoutTest(SocketTCPTest):
             try:
                 signal.alarm(2)    # POSIX allows alarm to be up to 1 second early
                 foo = self.serv.accept()
-            except socket.timeout:
+            except TimeoutError:
                 self.fail("caught timeout instead of Alarm")
             except Alarm:
                 pass
@@ -5316,7 +5316,7 @@ class UDPTimeoutTest(SocketUDPTest):
         def raise_timeout(*args, **kwargs):
             self.serv.settimeout(1.0)
             self.serv.recv(1024)
-        self.assertRaises(socket.timeout, raise_timeout,
+        self.assertRaises(TimeoutError, raise_timeout,
                               "Error generating a timeout exception (UDP)")
 
     def testTimeoutZero(self):
@@ -5324,7 +5324,7 @@ class UDPTimeoutTest(SocketUDPTest):
         try:
             self.serv.settimeout(0.0)
             foo = self.serv.recv(1024)
-        except socket.timeout:
+        except TimeoutError:
             self.fail("caught timeout instead of error (UDP)")
         except OSError:
             ok = True
@@ -5341,7 +5341,7 @@ class UDPLITETimeoutTest(SocketUDPLITETest):
         def raise_timeout(*args, **kwargs):
             self.serv.settimeout(1.0)
             self.serv.recv(1024)
-        self.assertRaises(socket.timeout, raise_timeout,
+        self.assertRaises(TimeoutError, raise_timeout,
                               "Error generating a timeout exception (UDPLITE)")
 
     def testTimeoutZero(self):
@@ -5349,7 +5349,7 @@ class UDPLITETimeoutTest(SocketUDPLITETest):
         try:
             self.serv.settimeout(0.0)
             foo = self.serv.recv(1024)
-        except socket.timeout:
+        except TimeoutError:
             self.fail("caught timeout instead of error (UDPLITE)")
         except OSError:
             ok = True
@@ -5365,6 +5365,8 @@ class TestExceptions(unittest.TestCase):
         self.assertTrue(issubclass(socket.herror, OSError))
         self.assertTrue(issubclass(socket.gaierror, OSError))
         self.assertTrue(issubclass(socket.timeout, OSError))
+        self.assertIs(socket.error, OSError)
+        self.assertIs(socket.timeout, TimeoutError)
 
     def test_setblocking_invalidfd(self):
         # Regression test for issue #28471
@@ -6167,7 +6169,7 @@ class SendfileUsingSendTest(ThreadedTCPSocketTest):
             with socket.create_connection(address) as sock:
                 sock.settimeout(0.01)
                 meth = self.meth_from_sock(sock)
-                self.assertRaises(socket.timeout, meth, file)
+                self.assertRaises(TimeoutError, meth, file)
 
     def testWithTimeoutTriggeredSend(self):
         conn = self.accept_conn()
index 8744e597302e40e83064ccee9bb278d48f5e5ab3..e5cd962e84710e91867af1d3be46270fd9ffc3cf 100644 (file)
@@ -2574,7 +2574,7 @@ class ThreadedEchoServer(threading.Thread):
                 handler = self.ConnectionHandler(self, newconn, connaddr)
                 handler.start()
                 handler.join()
-            except socket.timeout:
+            except TimeoutError:
                 pass
             except KeyboardInterrupt:
                 self.stop()
@@ -3691,7 +3691,7 @@ class ThreadedTests(unittest.TestCase):
                 c.settimeout(0.2)
                 c.connect((host, port))
                 # Will attempt handshake and time out
-                self.assertRaisesRegex(socket.timeout, "timed out",
+                self.assertRaisesRegex(TimeoutError, "timed out",
                                        test_wrap_socket, c)
             finally:
                 c.close()
@@ -3700,7 +3700,7 @@ class ThreadedTests(unittest.TestCase):
                 c = test_wrap_socket(c)
                 c.settimeout(0.2)
                 # Will attempt handshake and time out
-                self.assertRaisesRegex(socket.timeout, "timed out",
+                self.assertRaisesRegex(TimeoutError, "timed out",
                                        c.connect, (host, port))
             finally:
                 c.close()
index 7633901c96c84e863bb4c52f905828278d869289..8e36051cd095ba34a047d0511e5ab5d9a53ba480 100644 (file)
@@ -16,7 +16,7 @@ def server(evt, serv):
     try:
         conn, addr = serv.accept()
         conn.close()
-    except socket.timeout:
+    except TimeoutError:
         pass
     finally:
         serv.close()
index ac803f5d63823773ed848c990cb7ba41673e0fd0..823d5c3e1767e4f7505c045dbef8fd307f5022aa 100644 (file)
@@ -122,7 +122,7 @@ class TimeoutTestCase(unittest.TestCase):
         """
         Test the specified socket method.
 
-        The method is run at most `count` times and must raise a socket.timeout
+        The method is run at most `count` times and must raise a TimeoutError
         within `timeout` + self.fuzz seconds.
         """
         self.sock.settimeout(timeout)
@@ -131,11 +131,11 @@ class TimeoutTestCase(unittest.TestCase):
             t1 = time.monotonic()
             try:
                 method(*args)
-            except socket.timeout as e:
+            except TimeoutError as e:
                 delta = time.monotonic() - t1
                 break
         else:
-            self.fail('socket.timeout was not raised')
+            self.fail('TimeoutError was not raised')
         # These checks should account for timing unprecision
         self.assertLess(delta, timeout + self.fuzz)
         self.assertGreater(delta, timeout - 1.0)
@@ -204,7 +204,7 @@ class TCPTimeoutTestCase(TimeoutTestCase):
         sock.settimeout(timeout)
         try:
             sock.connect((whitehole))
-        except socket.timeout:
+        except TimeoutError:
             pass
         except OSError as err:
             if err.errno == errno.ECONNREFUSED:
index c1d55ee8b29b34fcef94367280428f944a0e58f6..4750ad9600cc3ef430e54b867b28eb63ac86ea1b 100644 (file)
@@ -277,7 +277,7 @@ class OtherNetworkTests(unittest.TestCase):
                                  ioerror_peer_reset:
                                 buf = f.read()
                                 debug("read %d bytes" % len(buf))
-                        except socket.timeout:
+                        except TimeoutError:
                             print("<timeout: %s>" % url, file=sys.stderr)
                         f.close()
                 time.sleep(0.1)
index 3dfa84bf77db01861228e2d1f20a0e4b60f9fc61..c54aeb109450db7e886fc4acbbc144b93c0b02aa 100644 (file)
@@ -648,7 +648,7 @@ def http_server(evt, numrequests, requestHandler=None, encoding=None):
             serv.handle_request()
             numrequests -= 1
 
-    except socket.timeout:
+    except TimeoutError:
         pass
     finally:
         serv.socket.close()
@@ -713,7 +713,7 @@ def http_multi_server(evt, numrequests, requestHandler=None):
             serv.handle_request()
             numrequests -= 1
 
-    except socket.timeout:
+    except TimeoutError:
         pass
     finally:
         serv.socket.close()
diff --git a/Misc/NEWS.d/next/Library/2020-11-19-20-27-51.bpo-42413.fjHrHx.rst b/Misc/NEWS.d/next/Library/2020-11-19-20-27-51.bpo-42413.fjHrHx.rst
new file mode 100644 (file)
index 0000000..ef1bf0f
--- /dev/null
@@ -0,0 +1 @@
+The exception :exc:`socket.timeout` is now an alias of :exc:`TimeoutError`.
index 54c365b88e69510891dfb5917cbd6984a1eacf36..a34313b78543c9226ec835d20ce22919c1496091 100644 (file)
@@ -1102,7 +1102,7 @@ _ssl__SSLSocket_do_handshake_impl(PySSLSocket *self)
         }
 
         if (sockstate == SOCKET_HAS_TIMED_OUT) {
-            PyErr_SetString(PySocketModule.timeout_error,
+            PyErr_SetString(PyExc_TimeoutError,
                             ERRSTR("The handshake operation timed out"));
             goto error;
         } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) {
@@ -2419,7 +2419,7 @@ _ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b)
 
     sockstate = PySSL_select(sock, 1, timeout);
     if (sockstate == SOCKET_HAS_TIMED_OUT) {
-        PyErr_SetString(PySocketModule.timeout_error,
+        PyErr_SetString(PyExc_TimeoutError,
                         "The write operation timed out");
         goto error;
     } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) {
@@ -2454,7 +2454,7 @@ _ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b)
         }
 
         if (sockstate == SOCKET_HAS_TIMED_OUT) {
-            PyErr_SetString(PySocketModule.timeout_error,
+            PyErr_SetString(PyExc_TimeoutError,
                             "The write operation timed out");
             goto error;
         } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) {
@@ -2609,7 +2609,7 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, int len, int group_right_1,
             sockstate = SOCKET_OPERATION_OK;
 
         if (sockstate == SOCKET_HAS_TIMED_OUT) {
-            PyErr_SetString(PySocketModule.timeout_error,
+            PyErr_SetString(PyExc_TimeoutError,
                             "The read operation timed out");
             goto error;
         } else if (sockstate == SOCKET_IS_NONBLOCKING) {
@@ -2724,10 +2724,10 @@ _ssl__SSLSocket_shutdown_impl(PySSLSocket *self)
 
         if (sockstate == SOCKET_HAS_TIMED_OUT) {
             if (err.ssl == SSL_ERROR_WANT_READ)
-                PyErr_SetString(PySocketModule.timeout_error,
+                PyErr_SetString(PyExc_TimeoutError,
                                 "The read operation timed out");
             else
-                PyErr_SetString(PySocketModule.timeout_error,
+                PyErr_SetString(PyExc_TimeoutError,
                                 "The write operation timed out");
             goto error;
         }
index d7738367029e857af405960960a63dad87721500..f8e4de5825f7ad2835a58c7c4c77c37f98e1b5aa 100644 (file)
@@ -514,7 +514,6 @@ remove_unusable_flags(PyObject *m)
    by this module (but not argument type or memory errors, etc.). */
 static PyObject *socket_herror;
 static PyObject *socket_gaierror;
-static PyObject *socket_timeout;
 
 /* A forward reference to the socket type object.
    The sock_type variable contains pointers to various functions,
@@ -886,7 +885,7 @@ sock_call_ex(PySocketSockObject *s,
                 if (err)
                     *err = SOCK_TIMEOUT_ERR;
                 else
-                    PyErr_SetString(socket_timeout, "timed out");
+                    PyErr_SetString(PyExc_TimeoutError, "timed out");
                 return -1;
             }
 
@@ -2880,7 +2879,7 @@ sock_settimeout(PySocketSockObject *s, PyObject *arg)
     /* Blocking mode for a Python socket object means that operations
        like :meth:`recv` or :meth:`sendall` will block the execution of
        the current thread until they are complete or aborted with a
-       `socket.timeout` or `socket.error` errors.  When timeout is `None`,
+       `TimeoutError` or `socket.error` errors.  When timeout is `None`,
        the underlying FD is in a blocking mode.  When timeout is a positive
        number, the FD is in a non-blocking mode, and socket ops are
        implemented with a `select()` call.
@@ -4206,7 +4205,7 @@ sock_sendall(PySocketSockObject *s, PyObject *args)
             }
 
             if (interval <= 0) {
-                PyErr_SetString(socket_timeout, "timed out");
+                PyErr_SetString(PyExc_TimeoutError, "timed out");
                 goto done;
             }
         }
@@ -7123,13 +7122,10 @@ PyInit__socket(void)
         return NULL;
     Py_INCREF(socket_gaierror);
     PyModule_AddObject(m, "gaierror", socket_gaierror);
-    socket_timeout = PyErr_NewException("socket.timeout",
-                                        PyExc_OSError, NULL);
-    if (socket_timeout == NULL)
-        return NULL;
-    PySocketModuleAPI.timeout_error = socket_timeout;
-    Py_INCREF(socket_timeout);
-    PyModule_AddObject(m, "timeout", socket_timeout);
+
+    PySocketModuleAPI.timeout_error = PyExc_TimeoutError;
+    PyModule_AddObjectRef(m, "timeout", PyExc_TimeoutError);
+
     Py_INCREF((PyObject *)&sock_type);
     if (PyModule_AddObject(m, "SocketType",
                            (PyObject *)&sock_type) != 0)