@@ -5301,7 +5301,6 @@ class Z(Generic[P]):
5301
5301
class ProtoZ (Protocol [P ]):
5302
5302
pass
5303
5303
5304
- things = "arguments" if sys .version_info >= (3 , 10 ) else "parameters"
5305
5304
for klass in Z , ProtoZ :
5306
5305
with self .subTest (klass = klass .__name__ ):
5307
5306
# Note: For 3.10+ __args__ are nested tuples here ((int, ),) instead of (int, )
@@ -5344,13 +5343,20 @@ class ProtoZ(Protocol[P]):
5344
5343
G6 = klass [int , str , T ]
5345
5344
G8 = klass [Concatenate [T , ...]]
5346
5345
G9 = klass [Concatenate [T , P_2 ]]
5347
- G10 = klass [int , Concatenate [str , P ]]
5348
5346
5349
- with self .subTest ("Check generic substitution" , klass = klass .__name__ ):
5350
- if sys .version_info < (3 , 10 ):
5351
- self .skipTest ("_ConcatenateGenericAlias not subscriptable" )
5352
- with self .assertRaisesRegex (TypeError , "Expected a list of types, an ellipsis, ParamSpec, or Concatenate" ):
5353
- G9 [int , int ]
5347
+ with self .assertRaisesRegex (TypeError ,
5348
+ (
5349
+ "The last parameter to Concatenate should be a ParamSpec variable or ellipsis."
5350
+ if sys .version_info < (3 , 10 ) else
5351
+ # from __typing_subst__
5352
+ "Expected a list of types, an ellipsis, ParamSpec, or Concatenate"
5353
+ )
5354
+ ):
5355
+ G9 [int , int ]
5356
+
5357
+ self .assertEqual (G9 .__parameters__ , (T , P_2 ))
5358
+ with self .assertRaisesRegex (TypeError , f"Too few { things } " ):
5359
+ G9 [int ]
5354
5360
5355
5361
with self .subTest ("Check list as parameter expression" , klass = klass .__name__ ):
5356
5362
if sys .version_info < (3 , 10 ):
@@ -5359,41 +5365,36 @@ class ProtoZ(Protocol[P]):
5359
5365
self .assertEqual (G5 .__args__ , ((int , str , T ),))
5360
5366
H9 = G9 [int , [T ]]
5361
5367
5362
- self .assertEqual (G9 .__parameters__ , (T , P_2 ))
5363
- with self .assertRaisesRegex (TypeError , f"Too few { things } " ):
5364
- G9 [int ]
5365
5368
5366
5369
with self .subTest ("Check parametrization" , klass = klass .__name__ ):
5367
- if sys .version_info [:2 ] == (3 , 10 ):
5368
- self .skipTest ("Parameter detection fails in 3.10" )
5369
- with self .assertRaisesRegex (TypeError , f"Too few { things } " ):
5370
- G9 [int ] # for python 3.10 this has no parameters
5371
- if sys .version_info >= (3 , 10 ): # skipped above
5372
- self .assertEqual (G5 .__parameters__ , (T ,))
5370
+ if sys .version_info >= (3 , 10 ): # only availiable for 3.10+
5373
5371
self .assertEqual (H9 .__parameters__ , (T ,))
5372
+ self .assertEqual (G5 .__parameters__ , (T ,))
5374
5373
self .assertEqual (G6 .__parameters__ , (T ,))
5375
- self .assertEqual (G8 .__parameters__ , (T ,))
5376
- self .assertEqual (G9 .__parameters__ , (T , P_2 ))
5377
5374
5378
5375
with self .subTest ("Check further substitution" , klass = klass .__name__ ):
5379
- if sys .version_info < (3 , 10 ):
5380
- self .skipTest ("_ConcatenateGenericAlias not subscriptable" )
5381
- if sys .version_info [:2 ] == (3 , 10 ):
5382
- self .skipTest ("Parameter detection fails in 3.10" )
5383
- if (3 , 11 , 0 ) <= sys .version_info [:3 ] < (3 , 11 , 3 ):
5384
- self .skipTest ("Wrong recursive substitution" )
5385
5376
H1 = G8 [int ]
5386
5377
self .assertEqual (H1 .__parameters__ , ())
5387
5378
with self .assertRaisesRegex (TypeError , "not a generic class" ):
5388
- H1 [str ] # for python 3.11.0-3 this still has a parameter
5379
+ H1 [str ]
5389
5380
5390
5381
H2 = G8 [T ][int ]
5391
5382
self .assertEqual (H2 .__parameters__ , ())
5392
5383
with self .assertRaisesRegex (TypeError , "not a generic class" ):
5393
- H2 [str ] # for python 3.11.0-3 this still has a parameter
5384
+ H2 [str ]
5394
5385
5386
+ # This is an invalid parameter expression but useful for testing correct subsitution
5387
+ G10 = klass [int , Concatenate [str , P ]]
5388
+ with self .subTest ("Check invalid form substitution" ):
5389
+ self .assertEqual (G10 .__parameters__ , (P , ))
5390
+ if sys .version_info < (3 , 9 ):
5391
+ self .skipTest ("3.8 typing._type_subst does not support this substitution process" )
5395
5392
H3 = G10 [int ]
5396
- self .assertEqual (H3 .__args__ , ((int , (str , int )),))
5393
+ if (3 , 10 ) <= sys .version_info < (3 , 11 , 3 ):
5394
+ self .skipTest ("3.10-3.11.2 does not substitute Concatenate here" )
5395
+ self .assertEqual (H3 .__parameters__ , ())
5396
+ H3args = H3 .__args__ [0 ] if sys .version_info >= (3 , 10 ) else H3 .__args__
5397
+ self .assertEqual (H3args , (int , (str , int )))
5397
5398
5398
5399
def test_pickle (self ):
5399
5400
global P , P_co , P_contra , P_default
@@ -5591,6 +5592,7 @@ def test_substitution(self):
5591
5592
U2 = Unpack [Ts ]
5592
5593
self .assertEqual (C2 [U1 ], (str , int , str ))
5593
5594
self .assertEqual (C2 [U2 ], (str , Unpack [Ts ]))
5595
+ self .assertEqual (C2 ["U2" ], (str , typing .ForwardRef ("U2" )))
5594
5596
5595
5597
if (3 , 12 , 0 ) <= sys .version_info < (3 , 12 , 4 ):
5596
5598
with self .assertRaises (AssertionError ):
@@ -5602,7 +5604,6 @@ def test_substitution(self):
5602
5604
C3 = Concatenate [str , T , P ]
5603
5605
self .assertEqual (C3 [int , [bool ]], (str , int , bool ))
5604
5606
5605
-
5606
5607
class TypeGuardTests (BaseTestCase ):
5607
5608
def test_basics (self ):
5608
5609
TypeGuard [int ] # OK
0 commit comments