25
25
from typing import Pattern , Match
26
26
from typing import Annotated , ForwardRef
27
27
from typing import TypeAlias
28
+ from typing import ParamSpec , Concatenate
28
29
import abc
29
30
import typing
30
31
import weakref
@@ -1130,10 +1131,6 @@ class P(PR[int, T], Protocol[T]):
1130
1131
PR [int ]
1131
1132
with self .assertRaises (TypeError ):
1132
1133
P [int , str ]
1133
- with self .assertRaises (TypeError ):
1134
- PR [int , 1 ]
1135
- with self .assertRaises (TypeError ):
1136
- PR [int , ClassVar ]
1137
1134
1138
1135
class C (PR [int , T ]): pass
1139
1136
@@ -1155,8 +1152,6 @@ class P(PR[int, str], Protocol):
1155
1152
self .assertIsSubclass (P , PR )
1156
1153
with self .assertRaises (TypeError ):
1157
1154
PR [int ]
1158
- with self .assertRaises (TypeError ):
1159
- PR [int , 1 ]
1160
1155
1161
1156
class P1 (Protocol , Generic [T ]):
1162
1157
def bar (self , x : T ) -> str : ...
@@ -1175,8 +1170,6 @@ def bar(self, x: str) -> str:
1175
1170
return x
1176
1171
1177
1172
self .assertIsInstance (Test (), PSub )
1178
- with self .assertRaises (TypeError ):
1179
- PR [int , ClassVar ]
1180
1173
1181
1174
def test_init_called (self ):
1182
1175
T = TypeVar ('T' )
@@ -1746,8 +1739,6 @@ def test_extended_generic_rules_eq(self):
1746
1739
self .assertEqual (typing .Iterable [Tuple [T , T ]][T ], typing .Iterable [Tuple [T , T ]])
1747
1740
with self .assertRaises (TypeError ):
1748
1741
Tuple [T , int ][()]
1749
- with self .assertRaises (TypeError ):
1750
- Tuple [T , U ][T , ...]
1751
1742
1752
1743
self .assertEqual (Union [T , int ][int ], int )
1753
1744
self .assertEqual (Union [T , U ][int , Union [int , str ]], Union [int , str ])
@@ -1759,10 +1750,6 @@ class Derived(Base): ...
1759
1750
1760
1751
self .assertEqual (Callable [[T ], T ][KT ], Callable [[KT ], KT ])
1761
1752
self .assertEqual (Callable [..., List [T ]][int ], Callable [..., List [int ]])
1762
- with self .assertRaises (TypeError ):
1763
- Callable [[T ], U ][..., int ]
1764
- with self .assertRaises (TypeError ):
1765
- Callable [[T ], U ][[], int ]
1766
1753
1767
1754
def test_extended_generic_rules_repr (self ):
1768
1755
T = TypeVar ('T' )
@@ -4243,6 +4230,111 @@ def test_cannot_subscript(self):
4243
4230
TypeAlias [int ]
4244
4231
4245
4232
4233
+ class ParamSpecTests (BaseTestCase ):
4234
+
4235
+ def test_basic_plain (self ):
4236
+ P = ParamSpec ('P' )
4237
+ self .assertEqual (P , P )
4238
+ self .assertIsInstance (P , ParamSpec )
4239
+
4240
+ def test_valid_uses (self ):
4241
+ P = ParamSpec ('P' )
4242
+ T = TypeVar ('T' )
4243
+ C1 = Callable [P , int ]
4244
+ self .assertEqual (C1 .__args__ , (P , int ))
4245
+ self .assertEqual (C1 .__parameters__ , (P ,))
4246
+ C2 = Callable [P , T ]
4247
+ self .assertEqual (C2 .__args__ , (P , T ))
4248
+ self .assertEqual (C2 .__parameters__ , (P , T ))
4249
+ # Test collections.abc.Callable too.
4250
+ C3 = collections .abc .Callable [P , int ]
4251
+ self .assertEqual (C3 .__args__ , (P , int ))
4252
+ self .assertEqual (C3 .__parameters__ , (P ,))
4253
+ C4 = collections .abc .Callable [P , T ]
4254
+ self .assertEqual (C4 .__args__ , (P , T ))
4255
+ self .assertEqual (C4 .__parameters__ , (P , T ))
4256
+
4257
+ # ParamSpec instances should also have args and kwargs attributes.
4258
+ self .assertIn ('args' , dir (P ))
4259
+ self .assertIn ('kwargs' , dir (P ))
4260
+ P .args
4261
+ P .kwargs
4262
+
4263
+ def test_user_generics (self ):
4264
+ T = TypeVar ("T" )
4265
+ P = ParamSpec ("P" )
4266
+ P_2 = ParamSpec ("P_2" )
4267
+
4268
+ class X (Generic [T , P ]):
4269
+ f : Callable [P , int ]
4270
+ x : T
4271
+ G1 = X [int , P_2 ]
4272
+ self .assertEqual (G1 .__args__ , (int , P_2 ))
4273
+ self .assertEqual (G1 .__parameters__ , (P_2 ,))
4274
+
4275
+ G2 = X [int , Concatenate [int , P_2 ]]
4276
+ self .assertEqual (G2 .__args__ , (int , Concatenate [int , P_2 ]))
4277
+ self .assertEqual (G2 .__parameters__ , (P_2 ,))
4278
+
4279
+ G3 = X [int , [int , bool ]]
4280
+ self .assertEqual (G3 .__args__ , (int , (int , bool )))
4281
+ self .assertEqual (G3 .__parameters__ , ())
4282
+
4283
+ G4 = X [int , ...]
4284
+ self .assertEqual (G4 .__args__ , (int , Ellipsis ))
4285
+ self .assertEqual (G4 .__parameters__ , ())
4286
+
4287
+ class Z (Generic [P ]):
4288
+ f : Callable [P , int ]
4289
+
4290
+ G5 = Z [[int , str , bool ]]
4291
+ self .assertEqual (G5 .__args__ , ((int , str , bool ),))
4292
+ self .assertEqual (G5 .__parameters__ , ())
4293
+
4294
+ G6 = Z [int , str , bool ]
4295
+ self .assertEqual (G6 .__args__ , ((int , str , bool ),))
4296
+ self .assertEqual (G6 .__parameters__ , ())
4297
+
4298
+ # G5 and G6 should be equivalent according to the PEP
4299
+ self .assertEqual (G5 .__args__ , G6 .__args__ )
4300
+ self .assertEqual (G5 .__origin__ , G6 .__origin__ )
4301
+ self .assertEqual (G5 .__parameters__ , G6 .__parameters__ )
4302
+ self .assertEqual (G5 , G6 )
4303
+
4304
+ def test_var_substitution (self ):
4305
+ T = TypeVar ("T" )
4306
+ P = ParamSpec ("P" )
4307
+ C1 = Callable [P , T ]
4308
+ self .assertEqual (C1 [int , str ], Callable [[int ], str ])
4309
+ self .assertEqual (C1 [[int , str , dict ], float ], Callable [[int , str , dict ], float ])
4310
+
4311
+
4312
+ class ConcatenateTests (BaseTestCase ):
4313
+ def test_basics (self ):
4314
+ P = ParamSpec ('P' )
4315
+ class MyClass : ...
4316
+ c = Concatenate [MyClass , P ]
4317
+ self .assertNotEqual (c , Concatenate )
4318
+
4319
+ def test_valid_uses (self ):
4320
+ P = ParamSpec ('P' )
4321
+ T = TypeVar ('T' )
4322
+ C1 = Callable [Concatenate [int , P ], int ]
4323
+ self .assertEqual (C1 .__args__ , (Concatenate [int , P ], int ))
4324
+ self .assertEqual (C1 .__parameters__ , (P ,))
4325
+ C2 = Callable [Concatenate [int , T , P ], T ]
4326
+ self .assertEqual (C2 .__args__ , (Concatenate [int , T , P ], T ))
4327
+ self .assertEqual (C2 .__parameters__ , (T , P ))
4328
+
4329
+ # Test collections.abc.Callable too.
4330
+ C3 = collections .abc .Callable [Concatenate [int , P ], int ]
4331
+ self .assertEqual (C3 .__args__ , (Concatenate [int , P ], int ))
4332
+ self .assertEqual (C3 .__parameters__ , (P ,))
4333
+ C4 = collections .abc .Callable [Concatenate [int , T , P ], T ]
4334
+ self .assertEqual (C4 .__args__ , (Concatenate [int , T , P ], T ))
4335
+ self .assertEqual (C4 .__parameters__ , (T , P ))
4336
+
4337
+
4246
4338
class AllTests (BaseTestCase ):
4247
4339
"""Tests for __all__."""
4248
4340
0 commit comments