changeset: 93057:03d3f2664930 branch: 3.4 parent: 93055:db5e431125b1 user: Victor Stinner date: Tue Oct 14 22:56:25 2014 +0200 files: Lib/asyncio/windows_utils.py Lib/test/test_asyncio/test_windows_utils.py description: 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. diff -r db5e431125b1 -r 03d3f2664930 Lib/asyncio/windows_utils.py --- a/Lib/asyncio/windows_utils.py Tue Oct 14 16:56:42 2014 -0400 +++ b/Lib/asyncio/windows_utils.py Tue Oct 14 22:56:25 2014 +0200 @@ -28,49 +28,51 @@ _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. +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("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") + 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: - 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) + # 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 -r db5e431125b1 -r 03d3f2664930 Lib/test/test_asyncio/test_windows_utils.py --- a/Lib/test/test_asyncio/test_windows_utils.py Tue Oct 14 16:56:42 2014 -0400 +++ b/Lib/test/test_asyncio/test_windows_utils.py Tue Oct 14 22:56:25 2014 +0200 @@ -33,6 +33,8 @@ 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 @@ 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