Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 3f4f577

Browse filesBrowse files
freakboy3742gpshead
authored andcommitted
pythongh-122133: Rework pure Python socketpair tests to avoid use of importlib.reload. (pythonGH-122493)
(cherry picked from commit f071f01) Co-authored-by: Russell Keith-Magee <russell@keith-magee.com> Co-authored-by: Gregory P. Smith <greg@krypto.org>
1 parent ef21e48 commit 3f4f577
Copy full SHA for 3f4f577

File tree

2 files changed

+64
-77
lines changed
Filter options

2 files changed

+64
-77
lines changed

‎Lib/socket.py

Copy file name to clipboardExpand all lines: Lib/socket.py
+58-63Lines changed: 58 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -592,16 +592,65 @@ def fromshare(info):
592592
return socket(0, 0, 0, info)
593593
__all__.append("fromshare")
594594

595-
if hasattr(_socket, "socketpair"):
595+
# Origin: https://gist.github.com/4325783, by Geert Jansen. Public domain.
596+
# This is used if _socket doesn't natively provide socketpair. It's
597+
# always defined so that it can be patched in for testing purposes.
598+
def _fallback_socketpair(family=AF_INET, type=SOCK_STREAM, proto=0):
599+
if family == AF_INET:
600+
host = _LOCALHOST
601+
elif family == AF_INET6:
602+
host = _LOCALHOST_V6
603+
else:
604+
raise ValueError("Only AF_INET and AF_INET6 socket address families "
605+
"are supported")
606+
if type != SOCK_STREAM:
607+
raise ValueError("Only SOCK_STREAM socket type is supported")
608+
if proto != 0:
609+
raise ValueError("Only protocol zero is supported")
610+
611+
# We create a connected TCP socket. Note the trick with
612+
# setblocking(False) that prevents us from having to create a thread.
613+
lsock = socket(family, type, proto)
614+
try:
615+
lsock.bind((host, 0))
616+
lsock.listen()
617+
# On IPv6, ignore flow_info and scope_id
618+
addr, port = lsock.getsockname()[:2]
619+
csock = socket(family, type, proto)
620+
try:
621+
csock.setblocking(False)
622+
try:
623+
csock.connect((addr, port))
624+
except (BlockingIOError, InterruptedError):
625+
pass
626+
csock.setblocking(True)
627+
ssock, _ = lsock.accept()
628+
except:
629+
csock.close()
630+
raise
631+
finally:
632+
lsock.close()
596633

597-
def socketpair(family=None, type=SOCK_STREAM, proto=0):
598-
"""socketpair([family[, type[, proto]]]) -> (socket object, socket object)
634+
# Authenticating avoids using a connection from something else
635+
# able to connect to {host}:{port} instead of us.
636+
# We expect only AF_INET and AF_INET6 families.
637+
try:
638+
if (
639+
ssock.getsockname() != csock.getpeername()
640+
or csock.getsockname() != ssock.getpeername()
641+
):
642+
raise ConnectionError("Unexpected peer connection")
643+
except:
644+
# getsockname() and getpeername() can fail
645+
# if either socket isn't connected.
646+
ssock.close()
647+
csock.close()
648+
raise
599649

600-
Create a pair of socket objects from the sockets returned by the platform
601-
socketpair() function.
602-
The arguments are the same as for socket() except the default family is
603-
AF_UNIX if defined on the platform; otherwise, the default is AF_INET.
604-
"""
650+
return (ssock, csock)
651+
652+
if hasattr(_socket, "socketpair"):
653+
def socketpair(family=None, type=SOCK_STREAM, proto=0):
605654
if family is None:
606655
try:
607656
family = AF_UNIX
@@ -613,61 +662,7 @@ def socketpair(family=None, type=SOCK_STREAM, proto=0):
613662
return a, b
614663

615664
else:
616-
617-
# Origin: https://gist.github.com/4325783, by Geert Jansen. Public domain.
618-
def socketpair(family=AF_INET, type=SOCK_STREAM, proto=0):
619-
if family == AF_INET:
620-
host = _LOCALHOST
621-
elif family == AF_INET6:
622-
host = _LOCALHOST_V6
623-
else:
624-
raise ValueError("Only AF_INET and AF_INET6 socket address families "
625-
"are supported")
626-
if type != SOCK_STREAM:
627-
raise ValueError("Only SOCK_STREAM socket type is supported")
628-
if proto != 0:
629-
raise ValueError("Only protocol zero is supported")
630-
631-
# We create a connected TCP socket. Note the trick with
632-
# setblocking(False) that prevents us from having to create a thread.
633-
lsock = socket(family, type, proto)
634-
try:
635-
lsock.bind((host, 0))
636-
lsock.listen()
637-
# On IPv6, ignore flow_info and scope_id
638-
addr, port = lsock.getsockname()[:2]
639-
csock = socket(family, type, proto)
640-
try:
641-
csock.setblocking(False)
642-
try:
643-
csock.connect((addr, port))
644-
except (BlockingIOError, InterruptedError):
645-
pass
646-
csock.setblocking(True)
647-
ssock, _ = lsock.accept()
648-
except:
649-
csock.close()
650-
raise
651-
finally:
652-
lsock.close()
653-
654-
# Authenticating avoids using a connection from something else
655-
# able to connect to {host}:{port} instead of us.
656-
# We expect only AF_INET and AF_INET6 families.
657-
try:
658-
if (
659-
ssock.getsockname() != csock.getpeername()
660-
or csock.getsockname() != ssock.getpeername()
661-
):
662-
raise ConnectionError("Unexpected peer connection")
663-
except:
664-
# getsockname() and getpeername() can fail
665-
# if either socket isn't connected.
666-
ssock.close()
667-
csock.close()
668-
raise
669-
670-
return (ssock, csock)
665+
socketpair = _fallback_socketpair
671666
__all__.append("socketpair")
672667

673668
socketpair.__doc__ = """socketpair([family[, type[, proto]]]) -> (socket object, socket object)

‎Lib/test/test_socket.py

Copy file name to clipboardExpand all lines: Lib/test/test_socket.py
+6-14Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4795,7 +4795,6 @@ def _testSend(self):
47954795

47964796

47974797
class PurePythonSocketPairTest(SocketPairTest):
4798-
47994798
# Explicitly use socketpair AF_INET or AF_INET6 to ensure that is the
48004799
# code path we're using regardless platform is the pure python one where
48014800
# `_socket.socketpair` does not exist. (AF_INET does not work with
@@ -4810,28 +4809,21 @@ def socketpair(self):
48104809
# Local imports in this class make for easy security fix backporting.
48114810

48124811
def setUp(self):
4813-
import _socket
4814-
self._orig_sp = getattr(_socket, 'socketpair', None)
4815-
if self._orig_sp is not None:
4812+
if hasattr(_socket, "socketpair"):
4813+
self._orig_sp = socket.socketpair
48164814
# This forces the version using the non-OS provided socketpair
48174815
# emulation via an AF_INET socket in Lib/socket.py.
4818-
del _socket.socketpair
4819-
import importlib
4820-
global socket
4821-
socket = importlib.reload(socket)
4816+
socket.socketpair = socket._fallback_socketpair
48224817
else:
4823-
pass # This platform already uses the non-OS provided version.
4818+
# This platform already uses the non-OS provided version.
4819+
self._orig_sp = None
48244820
super().setUp()
48254821

48264822
def tearDown(self):
48274823
super().tearDown()
4828-
import _socket
48294824
if self._orig_sp is not None:
48304825
# Restore the default socket.socketpair definition.
4831-
_socket.socketpair = self._orig_sp
4832-
import importlib
4833-
global socket
4834-
socket = importlib.reload(socket)
4826+
socket.socketpair = self._orig_sp
48354827

48364828
def test_recv(self):
48374829
msg = self.serv.recv(1024)

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.