8
8
import tempfile
9
9
from pathlib import Path
10
10
from socket import AddressFamily , SocketKind
11
- from typing import TYPE_CHECKING , Any , Callable , Union
11
+ from typing import TYPE_CHECKING , Callable , Union , cast
12
12
13
13
import attrs
14
14
import pytest
15
15
16
16
from .. import _core , socket as tsocket
17
17
from .._core ._tests .tutil import binds_ipv6 , creates_ipv6
18
- from .._socket import _NUMERIC_ONLY , SocketType , _SocketType , _try_sync
18
+ from .._socket import _NUMERIC_ONLY , AddressFormat , SocketType , _SocketType , _try_sync
19
19
from ..testing import assert_checkpoints , wait_all_tasks_blocked
20
20
21
21
if TYPE_CHECKING :
41
41
42
42
43
43
class MonkeypatchedGAI :
44
+ __slots__ = ("_orig_getaddrinfo" , "_responses" , "record" )
45
+
44
46
# Explicit .../"Any" is not allowed
45
47
def __init__ ( # type: ignore[misc]
46
48
self ,
47
49
orig_getaddrinfo : Callable [..., GetAddrInfoResponse ],
48
50
) -> None :
49
51
self ._orig_getaddrinfo = orig_getaddrinfo
50
- self ._responses : dict [tuple [Any , ...], GetAddrInfoResponse | str ] = {} # type: ignore[misc]
51
- self .record : list [tuple [Any , ...]] = [] # type: ignore[misc]
52
+ self ._responses : dict [
53
+ tuple [str | int | bytes | None , ...],
54
+ GetAddrInfoResponse | str ,
55
+ ] = {}
56
+ self .record : list [tuple [str | int | bytes | None , ...]] = []
52
57
53
58
# get a normalized getaddrinfo argument tuple
54
- # Explicit "Any" is not allowed
55
- def _frozenbind ( # type: ignore[misc]
59
+ def _frozenbind (
56
60
self ,
57
- * args : Any ,
58
- ** kwargs : Any ,
59
- ) -> tuple [Any , ...]:
61
+ host : str | bytes | None ,
62
+ port : str | bytes | int | None ,
63
+ family : int = 0 ,
64
+ type : int = 0 ,
65
+ proto : int = 0 ,
66
+ flags : int = 0 ,
67
+ ) -> tuple [str | int | bytes | None , ...]:
60
68
sig = inspect .signature (self ._orig_getaddrinfo )
61
- bound = sig .bind (* args , ** kwargs )
69
+ bound = sig .bind (host , port , family , proto , flags )
62
70
bound .apply_defaults ()
63
71
frozenbound = bound .args
64
72
assert not bound .kwargs
65
73
return frozenbound
66
74
67
- # Explicit "Any" is not allowed
68
- def set ( # type: ignore[misc]
75
+ def set (
69
76
self ,
70
77
response : GetAddrInfoResponse | str ,
71
- * args : Any ,
72
- ** kwargs : Any ,
78
+ host : str | bytes | None ,
79
+ port : str | bytes | int | None ,
80
+ family : int = 0 ,
81
+ type : int = 0 ,
82
+ proto : int = 0 ,
83
+ flags : int = 0 ,
73
84
) -> None :
74
- self ._responses [self ._frozenbind (* args , ** kwargs )] = response
85
+ self ._responses [self ._frozenbind (host , port , family , proto , flags )] = response
75
86
76
- # Explicit "Any" is not allowed
77
- def getaddrinfo ( # type: ignore[misc]
87
+ def getaddrinfo (
78
88
self ,
79
- * args : Any ,
80
- ** kwargs : Any ,
89
+ host : str | bytes | None ,
90
+ port : str | bytes | int | None ,
91
+ family : int = 0 ,
92
+ type : int = 0 ,
93
+ proto : int = 0 ,
94
+ flags : int = 0 ,
81
95
) -> GetAddrInfoResponse | str :
82
- bound = self ._frozenbind (* args , ** kwargs )
96
+ bound = self ._frozenbind (host , port , family , proto , flags )
83
97
self .record .append (bound )
84
98
if bound in self ._responses :
85
99
return self ._responses [bound ]
86
- elif bound [ - 1 ] & stdlib_socket .AI_NUMERICHOST :
87
- return self ._orig_getaddrinfo (* args , ** kwargs )
100
+ elif flags & stdlib_socket .AI_NUMERICHOST :
101
+ return self ._orig_getaddrinfo (host , port , family , proto , flags )
88
102
else :
89
103
raise RuntimeError (f"gai called with unexpected arguments { bound } " )
90
104
@@ -601,8 +615,7 @@ def assert_eq(
601
615
# local=True/local=False should work the same:
602
616
for local in [False , True ]:
603
617
604
- # Explicit "Any" is not allowed
605
- async def res ( # type: ignore[misc]
618
+ async def res (
606
619
args : (
607
620
tuple [str , int ]
608
621
| tuple [str , int , int ]
@@ -611,11 +624,13 @@ async def res( # type: ignore[misc]
611
624
| tuple [str , str , int ]
612
625
| tuple [str , str , int , int ]
613
626
),
614
- ) -> Any :
615
- return await sock ._resolve_address_nocp (
627
+ ) -> tuple [ str | int , ...] :
628
+ value = await sock ._resolve_address_nocp (
616
629
args ,
617
630
local = local , # noqa: B023 # local is not bound in function definition
618
631
)
632
+ assert isinstance (value , tuple )
633
+ return cast (tuple [Union [str , int ], ...], value )
619
634
620
635
assert_eq (await res ((addrs .arbitrary , "http" )), (addrs .arbitrary , 80 ))
621
636
if v6 :
@@ -810,11 +825,9 @@ async def test_SocketType_connect_paths() -> None:
810
825
# nose -- and then swap it back out again before we hit
811
826
# wait_socket_writable, which insists on a real socket.
812
827
class CancelSocket (stdlib_socket .socket ):
813
- # Explicit "Any" is not allowed
814
- def connect ( # type: ignore[misc]
828
+ def connect (
815
829
self ,
816
- * args : Any ,
817
- ** kwargs : Any ,
830
+ address : AddressFormat ,
818
831
) -> None :
819
832
# accessing private method only available in _SocketType
820
833
assert isinstance (sock , _SocketType )
@@ -825,7 +838,7 @@ def connect( # type: ignore[misc]
825
838
self .family ,
826
839
self .type ,
827
840
)
828
- sock ._sock .connect (* args , ** kwargs )
841
+ sock ._sock .connect (address )
829
842
# If connect *doesn't* raise, then pretend it did
830
843
raise BlockingIOError # pragma: no cover
831
844
@@ -871,11 +884,14 @@ async def test_resolve_address_exception_in_connect_closes_socket() -> None:
871
884
with _core .CancelScope () as cancel_scope :
872
885
with tsocket .socket () as sock :
873
886
874
- # Explicit "Any" is not allowed
875
- async def _resolve_address_nocp ( # type: ignore[misc]
887
+ async def _resolve_address_nocp (
876
888
self : _SocketType ,
877
- * args : Any ,
878
- ** kwargs : Any ,
889
+ host : str | bytes | None ,
890
+ port : str | bytes | int | None ,
891
+ family : int = 0 ,
892
+ type : int = 0 ,
893
+ proto : int = 0 ,
894
+ flags : int = 0 ,
879
895
) -> None :
880
896
cancel_scope .cancel ()
881
897
await _core .checkpoint ()
0 commit comments