@@ -529,6 +529,77 @@ def fromshare(info):
529
529
__implements__ .append ('fromshare' )
530
530
531
531
532
+ def _fallback_socketpair (family = AF_INET ,type = SOCK_STREAM ,proto = 0 ):
533
+ # We originally used https://gist.github.com/4325783, by Geert Jansen. (Public domain.)
534
+ # We took it from 3.6 release, confirmed unchanged in 3.7 and
535
+ # 3.8a1. Expected to be used only on Win. Added to Win/3.5.
536
+ # It is always available as `socket._fallback_socketpair` from at least 3.9,
537
+ # We would like to stop carrying around our own implementation, but
538
+ # using _fallback_socketpair directly would only work if we are monkey patched.
539
+
540
+ # Current version taken from 3.13rc2
541
+
542
+ # PyPy doesn't name its fallback `_fallback_socketpair`, it uses
543
+ # an older copy of socket.py.
544
+ _LOCALHOST = '127.0.0.1'
545
+ _LOCALHOST_V6 = '::1'
546
+
547
+ if family == AF_INET :
548
+ host = _LOCALHOST
549
+ elif family == AF_INET6 :
550
+ host = _LOCALHOST_V6
551
+ else :
552
+ raise ValueError ("Only AF_INET and AF_INET6 socket address families "
553
+ "are supported" )
554
+ if type != SOCK_STREAM :
555
+ raise ValueError ("Only SOCK_STREAM socket type is supported" )
556
+ if proto != 0 :
557
+ raise ValueError ("Only protocol zero is supported" )
558
+
559
+ # We create a connected TCP socket. Note the trick with
560
+ # setblocking(False) that prevents us from having to create a thread.
561
+ lsock = socket (family ,type ,proto )
562
+ try :
563
+ lsock .bind ((host ,0 ))
564
+ lsock .listen ()
565
+ # On IPv6, ignore flow_info and scope_id
566
+ addr ,port = lsock .getsockname ()[:2 ]
567
+ csock = socket (family ,type ,proto )
568
+ try :
569
+ csock .setblocking (False )
570
+ try :
571
+ csock .connect ((addr ,port ))
572
+ except (BlockingIOError ,InterruptedError ):
573
+ pass
574
+ csock .setblocking (True )
575
+ ssock ,_ = lsock .accept ()
576
+ except :
577
+ csock .close ()
578
+ raise
579
+ finally :
580
+ lsock .close ()
581
+
582
+ # Authenticating avoids using a connection from something else
583
+ # able to connect to {host}:{port} instead of us.
584
+ # We expect only AF_INET and AF_INET6 families.
585
+ try :
586
+ if (
587
+ ssock .getsockname ()!= csock .getpeername ()
588
+ or csock .getsockname ()!= ssock .getpeername ()
589
+ ):
590
+ raise ConnectionError ("Unexpected peer connection" )
591
+ except :
592
+ # getsockname() and getpeername() can fail
593
+ # if either socket isn't connected.
594
+ ssock .close ()
595
+ csock .close ()
596
+ raise
597
+
598
+ return (ssock ,csock )
599
+
600
+ if hasattr (__socket__ ,_fallback_socketpair .__name__ ):
601
+ __implements__ .append (_fallback_socketpair .__name__ )
602
+
532
603
if hasattr (_socket ,"socketpair" ):
533
604
534
605
def socketpair (family = None ,type = SOCK_STREAM ,proto = 0 ):
@@ -554,53 +625,14 @@ def socketpair(family=None, type=SOCK_STREAM, proto=0):
554
625
return a ,b
555
626
556
627
else :# pragma: no cover
557
- # Origin: https://gist.github.com/4325783, by Geert Jansen. Public domain.
628
+ socketpair = _fallback_socketpair
558
629
559
- # gevent: taken from 3.6 release, confirmed unchanged in 3.7 and
560
- # 3.8a1. Expected to be used only on Win. Added to Win/3.5
561
-
562
- _LOCALHOST = '127.0.0.1'
563
- _LOCALHOST_V6 = '::1'
564
-
565
- def socketpair (family = AF_INET ,type = SOCK_STREAM ,proto = 0 ):
566
- if family == AF_INET :
567
- host = _LOCALHOST
568
- elif family == AF_INET6 :
569
- host = _LOCALHOST_V6
570
- else :
571
- raise ValueError ("Only AF_INET and AF_INET6 socket address families "
572
- "are supported" )
573
- if type != SOCK_STREAM :
574
- raise ValueError ("Only SOCK_STREAM socket type is supported" )
575
- if proto != 0 :
576
- raise ValueError ("Only protocol zero is supported" )
577
-
578
- # We create a connected TCP socket. Note the trick with
579
- # setblocking(False) that prevents us from having to create a thread.
580
- lsock = socket (family ,type ,proto )
581
- try :
582
- lsock .bind ((host ,0 ))
583
- lsock .listen ()
584
- # On IPv6, ignore flow_info and scope_id
585
- addr ,port = lsock .getsockname ()[:2 ]
586
- csock = socket (family ,type ,proto )
587
- try :
588
- csock .setblocking (False )
589
- try :
590
- csock .connect ((addr ,port ))
591
- except (BlockingIOError ,InterruptedError ):
592
- pass
593
- csock .setblocking (True )
594
- ssock ,_ = lsock .accept ()
595
- except :
596
- csock .close ()
597
- raise
598
- finally :
599
- lsock .close ()
600
- return (ssock ,csock )
601
630
602
631
603
632
__all__ = __implements__ + __extensions__ + __imports__
633
+ if _fallback_socketpair .__name__ in __all__ :
634
+ __all__ .remove (_fallback_socketpair .__name__ )
635
+
604
636
__version_specific__ = (
605
637
# Python 3.7b1+
606
638
'close' ,