diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2014-10-14 20:56:25 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2014-10-14 20:56:25 (GMT) |
commit | f67f4602426be4de9b0d0124cb99ecc5edbd70aa (patch) | |
tree | 19a28061d79e86f501744ffd91c0398c4f5dc13b | |
parent | ee3e56105f666c38e83cf50957b1cac23f5360e0 (diff) | |
download | cpython-f67f4602426be4de9b0d0124cb99ecc5edbd70aa.zip cpython-f67f4602426be4de9b0d0124cb99ecc5edbd70aa.tar.gz cpython-f67f4602426be4de9b0d0124cb99ecc5edbd70aa.tar.bz2 |
Issue #18643: asyncio.windows_utils now reuse socket.socketpair() on Windows if
available
Since Python 3.5, socket.socketpair() is now also available on Windows.
Make csock blocking before calling the accept() method, and fix also a typo in
an error message.
-rw-r--r-- | Lib/asyncio/windows_utils.py | 84 | ||||
-rw-r--r-- | Lib/test/test_asyncio/test_windows_utils.py | 4 |
2 files changed, 47 insertions, 41 deletions
diff --git a/Lib/asyncio/windows_utils.py b/Lib/asyncio/windows_utils.py index f7f2f35..1155a77 100644 --- a/Lib/asyncio/windows_utils.py +++ b/Lib/asyncio/windows_utils.py @@ -28,49 +28,51 @@ STDOUT = subprocess.STDOUT _mmap_counter = itertools.count() -# Replacement for socket.socketpair() - - -def socketpair(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0): - """A socket pair usable as a self-pipe, for Windows. - - Origin: https://gist.github.com/4325783, by Geert Jansen. Public domain. - """ - if family == socket.AF_INET: - host = '127.0.0.1' - elif family == socket.AF_INET6: - host = '::1' - else: - raise ValueError("Ony AF_INET and AF_INET6 socket address families " - "are supported") - if type != socket.SOCK_STREAM: - raise ValueError("Only SOCK_STREAM socket type is supported") - if proto != 0: - raise ValueError("Only protocol zero is supported") - - # We create a connected TCP socket. Note the trick with setblocking(0) - # that prevents us from having to create a thread. - lsock = socket.socket(family, type, proto) - try: - lsock.bind((host, 0)) - lsock.listen(1) - # On IPv6, ignore flow_info and scope_id - addr, port = lsock.getsockname()[:2] - csock = socket.socket(family, type, proto) +if hasattr(socket, 'socketpair'): + # Since Python 3.5, socket.socketpair() is now also available on Windows + socketpair = socket.socketpair +else: + # Replacement for socket.socketpair() + def socketpair(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0): + """A socket pair usable as a self-pipe, for Windows. + + Origin: https://gist.github.com/4325783, by Geert Jansen. Public domain. + """ + if family == socket.AF_INET: + host = '127.0.0.1' + elif family == socket.AF_INET6: + host = '::1' + else: + raise ValueError("Only AF_INET and AF_INET6 socket address families " + "are supported") + if type != socket.SOCK_STREAM: + raise ValueError("Only SOCK_STREAM socket type is supported") + if proto != 0: + raise ValueError("Only protocol zero is supported") + + # We create a connected TCP socket. Note the trick with setblocking(0) + # that prevents us from having to create a thread. + lsock = socket.socket(family, type, proto) try: - csock.setblocking(False) + lsock.bind((host, 0)) + lsock.listen(1) + # On IPv6, ignore flow_info and scope_id + addr, port = lsock.getsockname()[:2] + csock = socket.socket(family, type, proto) try: - csock.connect((addr, port)) - except (BlockingIOError, InterruptedError): - pass - ssock, _ = lsock.accept() - csock.setblocking(True) - except: - csock.close() - raise - finally: - lsock.close() - return (ssock, csock) + csock.setblocking(False) + try: + csock.connect((addr, port)) + except (BlockingIOError, InterruptedError): + pass + csock.setblocking(True) + ssock, _ = lsock.accept() + except: + csock.close() + raise + finally: + lsock.close() + return (ssock, csock) # Replacement for os.pipe() using handles instead of fds diff --git a/Lib/test/test_asyncio/test_windows_utils.py b/Lib/test/test_asyncio/test_windows_utils.py index 7ea3a6d..3e7a211 100644 --- a/Lib/test/test_asyncio/test_windows_utils.py +++ b/Lib/test/test_asyncio/test_windows_utils.py @@ -33,6 +33,8 @@ class WinsocketpairTests(unittest.TestCase): ssock, csock = windows_utils.socketpair(family=socket.AF_INET6) self.check_winsocketpair(ssock, csock) + @unittest.skipIf(hasattr(socket, 'socketpair'), + 'socket.socketpair is available') @mock.patch('asyncio.windows_utils.socket') def test_winsocketpair_exc(self, m_socket): m_socket.AF_INET = socket.AF_INET @@ -51,6 +53,8 @@ class WinsocketpairTests(unittest.TestCase): self.assertRaises(ValueError, windows_utils.socketpair, proto=1) + @unittest.skipIf(hasattr(socket, 'socketpair'), + 'socket.socketpair is available') @mock.patch('asyncio.windows_utils.socket') def test_winsocketpair_close(self, m_socket): m_socket.AF_INET = socket.AF_INET |