Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f67f460

Browse files
committed
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.
1 parent ee3e561 commit f67f460

2 files changed

Lines changed: 47 additions & 41 deletions

File tree

Lib/asyncio/windows_utils.py

Lines changed: 43 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -28,49 +28,51 @@
2828
_mmap_counter = itertools.count()
2929

3030

31-
# Replacement for socket.socketpair()
32-
33-
34-
def socketpair(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0):
35-
"""A socket pair usable as a self-pipe, for Windows.
36-
37-
Origin: https://gist.github.com/4325783, by Geert Jansen. Public domain.
38-
"""
39-
if family == socket.AF_INET:
40-
host = '127.0.0.1'
41-
elif family == socket.AF_INET6:
42-
host = '::1'
43-
else:
44-
raise ValueError("Ony AF_INET and AF_INET6 socket address families "
45-
"are supported")
46-
if type != socket.SOCK_STREAM:
47-
raise ValueError("Only SOCK_STREAM socket type is supported")
48-
if proto != 0:
49-
raise ValueError("Only protocol zero is supported")
50-
51-
# We create a connected TCP socket. Note the trick with setblocking(0)
52-
# that prevents us from having to create a thread.
53-
lsock = socket.socket(family, type, proto)
54-
try:
55-
lsock.bind((host, 0))
56-
lsock.listen(1)
57-
# On IPv6, ignore flow_info and scope_id
58-
addr, port = lsock.getsockname()[:2]
59-
csock = socket.socket(family, type, proto)
31+
if hasattr(socket, 'socketpair'):
32+
# Since Python 3.5, socket.socketpair() is now also available on Windows
33+
socketpair = socket.socketpair
34+
else:
35+
# Replacement for socket.socketpair()
36+
def socketpair(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0):
37+
"""A socket pair usable as a self-pipe, for Windows.
38+
39+
Origin: https://gist.github.com/4325783, by Geert Jansen. Public domain.
40+
"""
41+
if family == socket.AF_INET:
42+
host = '127.0.0.1'
43+
elif family == socket.AF_INET6:
44+
host = '::1'
45+
else:
46+
raise ValueError("Only AF_INET and AF_INET6 socket address families "
47+
"are supported")
48+
if type != socket.SOCK_STREAM:
49+
raise ValueError("Only SOCK_STREAM socket type is supported")
50+
if proto != 0:
51+
raise ValueError("Only protocol zero is supported")
52+
53+
# We create a connected TCP socket. Note the trick with setblocking(0)
54+
# that prevents us from having to create a thread.
55+
lsock = socket.socket(family, type, proto)
6056
try:
61-
csock.setblocking(False)
57+
lsock.bind((host, 0))
58+
lsock.listen(1)
59+
# On IPv6, ignore flow_info and scope_id
60+
addr, port = lsock.getsockname()[:2]
61+
csock = socket.socket(family, type, proto)
6262
try:
63-
csock.connect((addr, port))
64-
except (BlockingIOError, InterruptedError):
65-
pass
66-
ssock, _ = lsock.accept()
67-
csock.setblocking(True)
68-
except:
69-
csock.close()
70-
raise
71-
finally:
72-
lsock.close()
73-
return (ssock, csock)
63+
csock.setblocking(False)
64+
try:
65+
csock.connect((addr, port))
66+
except (BlockingIOError, InterruptedError):
67+
pass
68+
csock.setblocking(True)
69+
ssock, _ = lsock.accept()
70+
except:
71+
csock.close()
72+
raise
73+
finally:
74+
lsock.close()
75+
return (ssock, csock)
7476

7577

7678
# Replacement for os.pipe() using handles instead of fds

Lib/test/test_asyncio/test_windows_utils.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ def test_winsocketpair_ipv6(self):
3333
ssock, csock = windows_utils.socketpair(family=socket.AF_INET6)
3434
self.check_winsocketpair(ssock, csock)
3535

36+
@unittest.skipIf(hasattr(socket, 'socketpair'),
37+
'socket.socketpair is available')
3638
@mock.patch('asyncio.windows_utils.socket')
3739
def test_winsocketpair_exc(self, m_socket):
3840
m_socket.AF_INET = socket.AF_INET
@@ -51,6 +53,8 @@ def test_winsocketpair_invalid_args(self):
5153
self.assertRaises(ValueError,
5254
windows_utils.socketpair, proto=1)
5355

56+
@unittest.skipIf(hasattr(socket, 'socketpair'),
57+
'socket.socketpair is available')
5458
@mock.patch('asyncio.windows_utils.socket')
5559
def test_winsocketpair_close(self, m_socket):
5660
m_socket.AF_INET = socket.AF_INET

0 commit comments

Comments
 (0)