diff --git a/Lib/test/test_errno.py b/Lib/test/test_errno.py index 7a37d3a6a59a094..a682a7c1e7c525a 100644 --- a/Lib/test/test_errno.py +++ b/Lib/test/test_errno.py @@ -3,6 +3,7 @@ """ import errno +import sys from test import test_support import unittest @@ -31,8 +32,38 @@ def test_attributes_in_errorcode(self): 'no %s attr in errno.errorcode' % attribute) +@unittest.skipUnless(sys.platform == 'win32', 'Windows specific') +class WinsockErrnoTests(unittest.TestCase): + + # VS2010+ errno.h defines its own values for these; sockets report the + # Winsock ones, so the errno module must use those. + names = ['EADDRINUSE', 'EADDRNOTAVAIL', 'EAFNOSUPPORT', 'EALREADY', + 'ECONNABORTED', 'ECONNREFUSED', 'ECONNRESET', 'EDESTADDRREQ', + 'EHOSTUNREACH', 'EINPROGRESS', 'EISCONN', 'ELOOP', 'EMSGSIZE', + 'ENETDOWN', 'ENETRESET', 'ENETUNREACH', 'ENOBUFS', 'ENOPROTOOPT', + 'ENOTCONN', 'ENOTSOCK', 'EOPNOTSUPP', 'EPROTONOSUPPORT', + 'EPROTOTYPE', 'ETIMEDOUT', 'EWOULDBLOCK'] + + def test_socket_constants_are_winsock_values(self): + for name in self.names: + self.assertEqual(getattr(errno, name), getattr(errno, 'WSA' + name), + name) + + def test_socket_error_matches_errno(self): + import socket + s = socket.socket() + try: + s.setblocking(False) + # Connecting to a non-routable address does not complete at once. + self.assertEqual(s.connect_ex(('10.255.255.1', 80)), + errno.EWOULDBLOCK) + finally: + s.close() + + def test_main(): - test_support.run_unittest(ErrnoAttributeTests, ErrorcodeTests) + test_support.run_unittest(ErrnoAttributeTests, ErrorcodeTests, + WinsockErrnoTests) if __name__ == '__main__': diff --git a/Misc/NEWS.d/2.7.18.16.rst b/Misc/NEWS.d/2.7.18.16.rst index 58a4d70473933e1..b938f37ed827c10 100644 --- a/Misc/NEWS.d/2.7.18.16.rst +++ b/Misc/NEWS.d/2.7.18.16.rst @@ -256,3 +256,19 @@ Removed an unused function from ``Modules/socketmodule.c`` that referenced a symbol Python 2.7 does not build, so ``-O0`` and ``--with-pydebug`` builds produced a ``_socket`` module (and :mod:`ssl`) that failed to import. ``test_ssl`` no longer needs the third-party ``mock`` package. + +.. bpo: 0 +.. date: 2026-10-28 +.. nonce: as1916 +.. release date: 2026-10-28 +.. original section: Windows +.. section: Windows + +Use the Winsock values for socket errno constants on Windows + +Visual Studio 2010 and later define their own ``ECONNRESET``, +``EWOULDBLOCK``, ``ETIMEDOUT`` and other socket error numbers in +``errno.h``, but Windows sockets report the Winsock ``WSAE*`` codes, so +``errno.EWOULDBLOCK`` (140) never matched a socket error (10035). The +:mod:`errno` module now uses the Winsock values for these 25 constants, as +Python 3.5 and later do. diff --git a/Modules/errnomodule.c b/Modules/errnomodule.c index 87ebab013a0b7ca..3868fe8a93f8ac3 100644 --- a/Modules/errnomodule.c +++ b/Modules/errnomodule.c @@ -6,6 +6,34 @@ /* Windows socket errors (WSA*) */ #ifdef MS_WINDOWS #include +/* The following constants were added to errno.h in VS2010 but have + preferred WSA equivalents: the socket module reports Winsock errors, + so errno.ECONNRESET and friends must be the WSAE* values (as in 3.5+). */ +#undef EADDRINUSE +#undef EADDRNOTAVAIL +#undef EAFNOSUPPORT +#undef EALREADY +#undef ECONNABORTED +#undef ECONNREFUSED +#undef ECONNRESET +#undef EDESTADDRREQ +#undef EHOSTUNREACH +#undef EINPROGRESS +#undef EISCONN +#undef ELOOP +#undef EMSGSIZE +#undef ENETDOWN +#undef ENETRESET +#undef ENETUNREACH +#undef ENOBUFS +#undef ENOPROTOOPT +#undef ENOTCONN +#undef ENOTSOCK +#undef EOPNOTSUPP +#undef EPROTONOSUPPORT +#undef EPROTOTYPE +#undef ETIMEDOUT +#undef EWOULDBLOCK #endif /*