Issue #18643: Add socket.socketpair() on Windows.

This commit is contained in:
Charles-François Natali 2014-10-14 21:22:44 +01:00
parent 987f3dd161
commit 98c745a773
4 changed files with 56 additions and 3 deletions

View File

@ -350,7 +350,6 @@ The following functions all create :ref:`socket objects <socket-objects>`.
type, and protocol number. Address family, socket type, and protocol number are type, and protocol number. Address family, socket type, and protocol number are
as for the :func:`.socket` function above. The default family is :const:`AF_UNIX` as for the :func:`.socket` function above. The default family is :const:`AF_UNIX`
if defined on the platform; otherwise, the default is :const:`AF_INET`. if defined on the platform; otherwise, the default is :const:`AF_INET`.
Availability: Unix.
The newly created sockets are :ref:`non-inheritable <fd_inheritance>`. The newly created sockets are :ref:`non-inheritable <fd_inheritance>`.
@ -361,6 +360,9 @@ The following functions all create :ref:`socket objects <socket-objects>`.
.. versionchanged:: 3.4 .. versionchanged:: 3.4
The returned sockets are now non-inheritable. The returned sockets are now non-inheritable.
.. versionchanged:: 3.5
Windows support added.
.. function:: create_connection(address[, timeout[, source_address]]) .. function:: create_connection(address[, timeout[, source_address]])

View File

@ -76,6 +76,11 @@ SocketType = IntEnum('SocketType',
if name.isupper() and name.startswith('SOCK_')}) if name.isupper() and name.startswith('SOCK_')})
globals().update(SocketType.__members__) globals().update(SocketType.__members__)
_LOCALHOST = '127.0.0.1'
_LOCALHOST_V6 = '::1'
def _intenum_converter(value, enum_klass): def _intenum_converter(value, enum_klass):
"""Convert a numeric family value to an IntEnum member. """Convert a numeric family value to an IntEnum member.
@ -468,6 +473,52 @@ if hasattr(_socket, "socketpair"):
b = socket(family, type, proto, b.detach()) b = socket(family, type, proto, b.detach())
return a, b return a, b
else:
# Origin: https://gist.github.com/4325783, by Geert Jansen. Public domain.
def socketpair(family=AF_INET, type=SOCK_STREAM, proto=0):
if family == AF_INET:
host = _LOCALHOST
elif family == AF_INET6:
host = _LOCALHOST_V6
else:
raise ValueError("Only AF_INET and AF_INET6 socket address families "
"are supported")
if type != 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(False) that prevents us from having to create a thread.
lsock = socket(family, type, proto)
try:
lsock.bind((host, 0))
lsock.listen()
# On IPv6, ignore flow_info and scope_id
addr, port = lsock.getsockname()[:2]
csock = socket(family, type, proto)
try:
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)
socketpair.__doc__ = """socketpair([family[, type[, proto]]]) -> (socket object, socket object)
Create a pair of socket objects from the sockets returned by the platform
socketpair() function.
The arguments are the same as for socket() except the default family is AF_UNIX
if defined on the platform; otherwise, the default is AF_INET.
"""
_blocking_errnos = { EAGAIN, EWOULDBLOCK } _blocking_errnos = { EAGAIN, EWOULDBLOCK }

View File

@ -3728,8 +3728,6 @@ class TCPCloserTest(ThreadedTCPSocketTest):
self.cli.connect((HOST, self.port)) self.cli.connect((HOST, self.port))
time.sleep(1.0) time.sleep(1.0)
@unittest.skipUnless(hasattr(socket, 'socketpair'),
'test needs socket.socketpair()')
@unittest.skipUnless(thread, 'Threading required for this test.') @unittest.skipUnless(thread, 'Threading required for this test.')
class BasicSocketPairTest(SocketPairTest): class BasicSocketPairTest(SocketPairTest):

View File

@ -177,6 +177,8 @@ Core and Builtins
Library Library
------- -------
- Issue #18643: Add socket.socketpair() on Windows.
- Issue #22435: Fix a file descriptor leak when SocketServer bind fails. - Issue #22435: Fix a file descriptor leak when SocketServer bind fails.
- Issue #13096: Fixed segfault in CTypes POINTER handling of large - Issue #13096: Fixed segfault in CTypes POINTER handling of large