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 c21a361

Browse filesBrowse files
miss-islingtonfreakboy3742gpshead
authored
[3.13] gh-122133: Rework pure Python socketpair tests to avoid use of importlib.reload. (GH-122493) (#122504)
gh-122133: Rework pure Python socketpair tests to avoid use of importlib.reload. (GH-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 4a6365c commit c21a361
Copy full SHA for c21a361

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
@@ -4861,7 +4861,6 @@ def _testSend(self):
48614861

48624862

48634863
class PurePythonSocketPairTest(SocketPairTest):
4864-
48654864
# Explicitly use socketpair AF_INET or AF_INET6 to ensure that is the
48664865
# code path we're using regardless platform is the pure python one where
48674866
# `_socket.socketpair` does not exist. (AF_INET does not work with
@@ -4876,28 +4875,21 @@ def socketpair(self):
48764875
# Local imports in this class make for easy security fix backporting.
48774876

48784877
def setUp(self):
4879-
import _socket
4880-
self._orig_sp = getattr(_socket, 'socketpair', None)
4881-
if self._orig_sp is not None:
4878+
if hasattr(_socket, "socketpair"):
4879+
self._orig_sp = socket.socketpair
48824880
# This forces the version using the non-OS provided socketpair
48834881
# emulation via an AF_INET socket in Lib/socket.py.
4884-
del _socket.socketpair
4885-
import importlib
4886-
global socket
4887-
socket = importlib.reload(socket)
4882+
socket.socketpair = socket._fallback_socketpair
48884883
else:
4889-
pass # This platform already uses the non-OS provided version.
4884+
# This platform already uses the non-OS provided version.
4885+
self._orig_sp = None
48904886
super().setUp()
48914887

48924888
def tearDown(self):
48934889
super().tearDown()
4894-
import _socket
48954890
if self._orig_sp is not None:
48964891
# Restore the default socket.socketpair definition.
4897-
_socket.socketpair = self._orig_sp
4898-
import importlib
4899-
global socket
4900-
socket = importlib.reload(socket)
4892+
socket.socketpair = self._orig_sp
49014893

49024894
def test_recv(self):
49034895
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.