diff -r 49e23a3adf26 Doc/library/socket.rst --- a/Doc/library/socket.rst Wed Aug 21 13:26:34 2013 +0200 +++ b/Doc/library/socket.rst Sat Aug 24 10:27:24 2013 +0200 @@ -484,12 +484,14 @@ 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` if defined on the platform; otherwise, the default is :const:`AF_INET`. - Availability: Unix. .. versionchanged:: 3.2 The returned socket objects now support the whole socket API, rather than a subset. + .. versionchanged:: 3.4 + This function is now available on all platforms. + .. function:: fromfd(fd, family, type[, proto]) diff -r 49e23a3adf26 Lib/socket.py --- a/Lib/socket.py Wed Aug 21 13:26:34 2013 +0200 +++ b/Lib/socket.py Sat Aug 24 10:27:24 2013 +0200 @@ -10,7 +10,7 @@ Functions: socket() -- create a new socket object -socketpair() -- create a pair of new socket objects [*] +socketpair() -- create a pair of new socket objects fromfd() -- create a socket object from an open file descriptor [*] fromshare() -- create a socket object from data received from socket.share() [*] gethostname() -- return the current hostname @@ -248,15 +248,7 @@ return socket(0, 0, 0, info) if hasattr(_socket, "socketpair"): - def socketpair(family=None, type=SOCK_STREAM, proto=0): - """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. - """ if family is None: try: family = AF_UNIX @@ -266,6 +258,34 @@ a = socket(family, type, proto, a.detach()) b = socket(family, type, proto, b.detach()) return a, b + socketpair.__doc__ = _socket.socketpair.__doc__ +else: + def socketpair(family=AF_INET, type=SOCK_STREAM, proto=0): + """socketpair([family[, type[, proto]]]) -> (socket object, socket object) + + Create a pair of connected socket objects. + The arguments are the same as for socket() except that only the AF_INET + family is supported. + """ + if family != AF_INET: + raise ValueError("Invalid family: {r}".format(family)) + + with socket(family, type, proto) as l: + l.bind(('127.0.0.1', 0)) + l.listen(3) + c = socket(family, type, proto) + try: + c.connect(l.getsockname()) + caddr = c.getsockname() + while True: + a, addr = l.accept() + # check that we've got the correct client + if addr == caddr: + return c, a + a.close() + except error: + c.close() + raise _blocking_errnos = { EAGAIN, EWOULDBLOCK } diff -r 49e23a3adf26 Lib/test/test_socket.py --- a/Lib/test/test_socket.py Wed Aug 21 13:26:34 2013 +0200 +++ b/Lib/test/test_socket.py Sat Aug 24 10:27:24 2013 +0200 @@ -4929,8 +4929,7 @@ CloexecConstantTest, NonblockConstantTest ]) - if hasattr(socket, "socketpair"): - tests.append(BasicSocketPairTest) + tests.append(BasicSocketPairTest) if hasattr(socket, "AF_UNIX"): tests.append(TestUnixDomain) if sys.platform == 'linux':