[Python-checkins] cpython (3.4): Issue #18643: asyncio.windows_utils now reuse socket.socketpair() on Windows if

victor.stinner python-checkins at python.org
Tue Oct 14 23:06:17 CEST 2014


https://hg.python.org/cpython/rev/03d3f2664930
changeset:   93057:03d3f2664930
branch:      3.4
parent:      93055:db5e431125b1
user:        Victor Stinner <victor.stinner at gmail.com>
date:        Tue Oct 14 22:56:25 2014 +0200
summary:
  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.

files:
  Lib/asyncio/windows_utils.py                |  80 +++++----
  Lib/test/test_asyncio/test_windows_utils.py |   4 +
  2 files changed, 45 insertions(+), 39 deletions(-)


diff --git a/Lib/asyncio/windows_utils.py b/Lib/asyncio/windows_utils.py
--- a/Lib/asyncio/windows_utils.py
+++ b/Lib/asyncio/windows_utils.py
@@ -28,49 +28,51 @@
 _mmap_counter = itertools.count()
 
 
-# Replacement for socket.socketpair()
+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")
 
-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)
+        # 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
--- a/Lib/test/test_asyncio/test_windows_utils.py
+++ b/Lib/test/test_asyncio/test_windows_utils.py
@@ -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

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list