@@ -588,16 +588,65 @@ def fromshare(info):
588
588
return socket (0 , 0 , 0 , info )
589
589
__all__ .append ("fromshare" )
590
590
591
- if hasattr (_socket , "socketpair" ):
591
+ # Origin: https://gist.github.com/4325783, by Geert Jansen. Public domain.
592
+ # This is used if _socket doesn't natively provide socketpair. It's
593
+ # always defined so that it can be patched in for testing purposes.
594
+ def _fallback_socketpair (family = AF_INET , type = SOCK_STREAM , proto = 0 ):
595
+ if family == AF_INET :
596
+ host = _LOCALHOST
597
+ elif family == AF_INET6 :
598
+ host = _LOCALHOST_V6
599
+ else :
600
+ raise ValueError ("Only AF_INET and AF_INET6 socket address families "
601
+ "are supported" )
602
+ if type != SOCK_STREAM :
603
+ raise ValueError ("Only SOCK_STREAM socket type is supported" )
604
+ if proto != 0 :
605
+ raise ValueError ("Only protocol zero is supported" )
606
+
607
+ # We create a connected TCP socket. Note the trick with
608
+ # setblocking(False) that prevents us from having to create a thread.
609
+ lsock = socket (family , type , proto )
610
+ try :
611
+ lsock .bind ((host , 0 ))
612
+ lsock .listen ()
613
+ # On IPv6, ignore flow_info and scope_id
614
+ addr , port = lsock .getsockname ()[:2 ]
615
+ csock = socket (family , type , proto )
616
+ try :
617
+ csock .setblocking (False )
618
+ try :
619
+ csock .connect ((addr , port ))
620
+ except (BlockingIOError , InterruptedError ):
621
+ pass
622
+ csock .setblocking (True )
623
+ ssock , _ = lsock .accept ()
624
+ except :
625
+ csock .close ()
626
+ raise
627
+ finally :
628
+ lsock .close ()
592
629
593
- def socketpair (family = None , type = SOCK_STREAM , proto = 0 ):
594
- """socketpair([family[, type[, proto]]]) -> (socket object, socket object)
630
+ # Authenticating avoids using a connection from something else
631
+ # able to connect to {host}:{port} instead of us.
632
+ # We expect only AF_INET and AF_INET6 families.
633
+ try :
634
+ if (
635
+ ssock .getsockname () != csock .getpeername ()
636
+ or csock .getsockname () != ssock .getpeername ()
637
+ ):
638
+ raise ConnectionError ("Unexpected peer connection" )
639
+ except :
640
+ # getsockname() and getpeername() can fail
641
+ # if either socket isn't connected.
642
+ ssock .close ()
643
+ csock .close ()
644
+ raise
595
645
596
- Create a pair of socket objects from the sockets returned by the platform
597
- socketpair() function.
598
- The arguments are the same as for socket() except the default family is
599
- AF_UNIX if defined on the platform; otherwise, the default is AF_INET.
600
- """
646
+ return (ssock , csock )
647
+
648
+ if hasattr (_socket , "socketpair" ):
649
+ def socketpair (family = None , type = SOCK_STREAM , proto = 0 ):
601
650
if family is None :
602
651
try :
603
652
family = AF_UNIX
@@ -609,61 +658,7 @@ def socketpair(family=None, type=SOCK_STREAM, proto=0):
609
658
return a , b
610
659
611
660
else :
612
-
613
- # Origin: https://gist.github.com/4325783, by Geert Jansen. Public domain.
614
- def socketpair (family = AF_INET , type = SOCK_STREAM , proto = 0 ):
615
- if family == AF_INET :
616
- host = _LOCALHOST
617
- elif family == AF_INET6 :
618
- host = _LOCALHOST_V6
619
- else :
620
- raise ValueError ("Only AF_INET and AF_INET6 socket address families "
621
- "are supported" )
622
- if type != SOCK_STREAM :
623
- raise ValueError ("Only SOCK_STREAM socket type is supported" )
624
- if proto != 0 :
625
- raise ValueError ("Only protocol zero is supported" )
626
-
627
- # We create a connected TCP socket. Note the trick with
628
- # setblocking(False) that prevents us from having to create a thread.
629
- lsock = socket (family , type , proto )
630
- try :
631
- lsock .bind ((host , 0 ))
632
- lsock .listen ()
633
- # On IPv6, ignore flow_info and scope_id
634
- addr , port = lsock .getsockname ()[:2 ]
635
- csock = socket (family , type , proto )
636
- try :
637
- csock .setblocking (False )
638
- try :
639
- csock .connect ((addr , port ))
640
- except (BlockingIOError , InterruptedError ):
641
- pass
642
- csock .setblocking (True )
643
- ssock , _ = lsock .accept ()
644
- except :
645
- csock .close ()
646
- raise
647
- finally :
648
- lsock .close ()
649
-
650
- # Authenticating avoids using a connection from something else
651
- # able to connect to {host}:{port} instead of us.
652
- # We expect only AF_INET and AF_INET6 families.
653
- try :
654
- if (
655
- ssock .getsockname () != csock .getpeername ()
656
- or csock .getsockname () != ssock .getpeername ()
657
- ):
658
- raise ConnectionError ("Unexpected peer connection" )
659
- except :
660
- # getsockname() and getpeername() can fail
661
- # if either socket isn't connected.
662
- ssock .close ()
663
- csock .close ()
664
- raise
665
-
666
- return (ssock , csock )
661
+ socketpair = _fallback_socketpair
667
662
__all__ .append ("socketpair" )
668
663
669
664
socketpair .__doc__ = """socketpair([family[, type[, proto]]]) -> (socket object, socket object)
0 commit comments