@@ -592,16 +592,65 @@ def fromshare(info):
592
592
return socket (0 , 0 , 0 , info )
593
593
__all__ .append ("fromshare" )
594
594
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 ()
596
633
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
599
649
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 ):
605
654
if family is None :
606
655
try :
607
656
family = AF_UNIX
@@ -613,61 +662,7 @@ def socketpair(family=None, type=SOCK_STREAM, proto=0):
613
662
return a , b
614
663
615
664
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
671
666
__all__ .append ("socketpair" )
672
667
673
668
socketpair .__doc__ = """socketpair([family[, type[, proto]]]) -> (socket object, socket object)
0 commit comments