@@ -7267,6 +7267,80 @@ def test_attributes(self):
7267
7267
self .assertEqual (Variadic .__type_params__ , (Ts ,))
7268
7268
self .assertEqual (Variadic .__parameters__ , tuple (iter (Ts )))
7269
7269
7270
+ P = ParamSpec ('P' )
7271
+ CallableP = TypeAliasType ("CallableP" , Callable [P , Any ], type_params = (P , ))
7272
+ self .assertEqual (CallableP .__name__ , "CallableP" )
7273
+ self .assertEqual (CallableP .__value__ , Callable [P , Any ])
7274
+ self .assertEqual (CallableP .__type_params__ , (P ,))
7275
+ self .assertEqual (CallableP .__parameters__ , (P ,))
7276
+
7277
+ def test_alias_types_and_substitutions (self ):
7278
+ T = TypeVar ('T' )
7279
+ T2 = TypeVar ('T2' )
7280
+ T_default = TypeVar ("T_default" , default = int )
7281
+ Ts = TypeVarTuple ("Ts" )
7282
+ P = ParamSpec ('P' )
7283
+
7284
+ test_argument_cases = {
7285
+ # arguments : expected parameters
7286
+ int : (),
7287
+ ... : (),
7288
+ None : (),
7289
+ T2 : (T2 ,),
7290
+ Union [int , List [T2 ]] : (T2 ,),
7291
+ Tuple [int , str ] : (),
7292
+ Tuple [T , T_default , T2 ] : (T , T_default , T2 ),
7293
+ Tuple [Unpack [Ts ]] : (Ts ,),
7294
+ Callable [[Unpack [Ts ]], T2 ] : (Ts , T2 ),
7295
+ Callable [P , T2 ] : (P , T2 ),
7296
+ Callable [Concatenate [T2 , P ], T_default ] : (T2 , P , T_default ),
7297
+ TypeAliasType ("NestedAlias" , List [T ], type_params = (T ,))[T2 ] : (T2 ,),
7298
+ Unpack [Ts ] : (Ts ,),
7299
+ Unpack [Tuple [int , T2 ]] : (T2 ,),
7300
+ Concatenate [int , P ] : (P ,),
7301
+ # Not tested usage of bare TypeVarTuple, would need 3.11+
7302
+ # Ts : (Ts,), # invalid case
7303
+ }
7304
+
7305
+ test_alias_cases = [
7306
+ # Simple cases
7307
+ TypeAliasType ("ListT" , List [T ], type_params = (T ,)),
7308
+ TypeAliasType ("UnionT" , Union [int , List [T ]], type_params = (T ,)),
7309
+ # Value has no parameter but in type_param
7310
+ TypeAliasType ("ValueWithoutT" , int , type_params = (T ,)),
7311
+ # Callable
7312
+ TypeAliasType ("CallableP" , Callable [P , Any ], type_params = (P , )),
7313
+ TypeAliasType ("CallableT" , Callable [..., T ], type_params = (T , )),
7314
+ TypeAliasType ("CallableTs" , Callable [[Unpack [Ts ]], Any ], type_params = (Ts , )),
7315
+ # TypeVarTuple
7316
+ TypeAliasType ("Variadic" , Tuple [int , Unpack [Ts ]], type_params = (Ts ,)),
7317
+ # TypeVar with default
7318
+ TypeAliasType ("TupleT_default" , Tuple [T_default , T ], type_params = (T , T_default )),
7319
+ TypeAliasType ("CallableT_default" , Callable [[T ], T_default ], type_params = (T , T_default )),
7320
+ ]
7321
+
7322
+ for alias in test_alias_cases :
7323
+ with self .subTest (alias = alias , args = []):
7324
+ subscripted = alias [[]]
7325
+ self .assertEqual (get_args (subscripted ), ([],))
7326
+ self .assertEqual (subscripted .__parameters__ , ())
7327
+ with self .subTest (alias = alias , args = ()):
7328
+ subscripted = alias [()]
7329
+ self .assertEqual (get_args (subscripted ), ())
7330
+ self .assertEqual (subscripted .__parameters__ , ())
7331
+ with self .subTest (alias = alias , args = (int , float )):
7332
+ subscripted = alias [int , float ]
7333
+ self .assertEqual (get_args (subscripted ), (int , float ))
7334
+ self .assertEqual (subscripted .__parameters__ , ())
7335
+ with self .subTest (alias = alias , args = [int , float ]):
7336
+ subscripted = alias [[int , float ]]
7337
+ self .assertEqual (get_args (subscripted ), ([int , float ],))
7338
+ self .assertEqual (subscripted .__parameters__ , ())
7339
+ for expected_args , expected_parameters in test_argument_cases .items ():
7340
+ with self .subTest (alias = alias , args = expected_args ):
7341
+ self .assertEqual (get_args (alias [expected_args ]), (expected_args ,))
7342
+ self .assertEqual (alias [expected_args ].__parameters__ , expected_parameters )
7343
+
7270
7344
def test_cannot_set_attributes (self ):
7271
7345
Simple = TypeAliasType ("Simple" , int )
7272
7346
with self .assertRaisesRegex (AttributeError , "readonly attribute" ):
@@ -7327,12 +7401,19 @@ def test_or(self):
7327
7401
Alias | "Ref"
7328
7402
7329
7403
def test_getitem (self ):
7404
+ T = TypeVar ('T' )
7330
7405
ListOrSetT = TypeAliasType ("ListOrSetT" , Union [List [T ], Set [T ]], type_params = (T ,))
7331
7406
subscripted = ListOrSetT [int ]
7332
7407
self .assertEqual (get_args (subscripted ), (int ,))
7333
7408
self .assertIs (get_origin (subscripted ), ListOrSetT )
7334
- with self .assertRaises (TypeError ):
7335
- subscripted [str ]
7409
+ with self .assertRaisesRegex (TypeError ,
7410
+ "not a generic class"
7411
+ # types.GenericAlias raises a different error in 3.10
7412
+ if sys .version_info [:2 ] != (3 , 10 )
7413
+ else "There are no type variables left in ListOrSetT"
7414
+ ):
7415
+ subscripted [int ]
7416
+
7336
7417
7337
7418
still_generic = ListOrSetT [Iterable [T ]]
7338
7419
self .assertEqual (get_args (still_generic ), (Iterable [T ],))
@@ -7341,6 +7422,114 @@ def test_getitem(self):
7341
7422
self .assertEqual (get_args (fully_subscripted ), (Iterable [float ],))
7342
7423
self .assertIs (get_origin (fully_subscripted ), ListOrSetT )
7343
7424
7425
+ ValueWithoutTypeVar = TypeAliasType ("ValueWithoutTypeVar" , int , type_params = (T ,))
7426
+ still_subscripted = ValueWithoutTypeVar [str ]
7427
+ self .assertEqual (get_args (still_subscripted ), (str ,))
7428
+
7429
+ def test_callable_without_concatenate (self ):
7430
+ P = ParamSpec ('P' )
7431
+ CallableP = TypeAliasType ("CallableP" , Callable [P , Any ], type_params = (P ,))
7432
+ get_args_test_cases = [
7433
+ # List of (alias, expected_args)
7434
+ # () -> Any
7435
+ (CallableP [()], ()),
7436
+ (CallableP [[]], ([],)),
7437
+ # (int) -> Any
7438
+ (CallableP [int ], (int ,)),
7439
+ (CallableP [[int ]], ([int ],)),
7440
+ # (int, int) -> Any
7441
+ (CallableP [int , int ], (int , int )),
7442
+ (CallableP [[int , int ]], ([int , int ],)),
7443
+ # (...) -> Any
7444
+ (CallableP [...], (...,)),
7445
+ # (int, ...) -> Any
7446
+ (CallableP [[int , ...]], ([int , ...],)),
7447
+ ]
7448
+
7449
+ for index , (expression , expected_args ) in enumerate (get_args_test_cases ):
7450
+ with self .subTest (index = index , expression = expression ):
7451
+ self .assertEqual (get_args (expression ), expected_args )
7452
+
7453
+ self .assertEqual (CallableP [...], CallableP [(...,)])
7454
+ # (T) -> Any
7455
+ CallableT = CallableP [T ]
7456
+ self .assertEqual (get_args (CallableT ), (T ,))
7457
+ self .assertEqual (CallableT .__parameters__ , (T ,))
7458
+
7459
+ def test_callable_with_concatenate (self ):
7460
+ P = ParamSpec ('P' )
7461
+ P2 = ParamSpec ('P2' )
7462
+ CallableP = TypeAliasType ("CallableP" , Callable [P , Any ], type_params = (P ,))
7463
+
7464
+ callable_concat = CallableP [Concatenate [int , P2 ]]
7465
+ self .assertEqual (callable_concat .__parameters__ , (P2 ,))
7466
+ concat_usage = callable_concat [str ]
7467
+ with self .subTest ("get_args of Concatenate in TypeAliasType" ):
7468
+ if not TYPING_3_9_0 :
7469
+ # args are: ([<class 'int'>, ~P2],)
7470
+ self .skipTest ("Nested ParamSpec is not substituted" )
7471
+ if sys .version_info < (3 , 10 , 2 ):
7472
+ self .skipTest ("GenericAlias keeps Concatenate in __args__ prior to 3.10.2" )
7473
+ self .assertEqual (get_args (concat_usage ), ((int , str ),))
7474
+ with self .subTest ("Equality of parameter_expression without []" ):
7475
+ if not TYPING_3_10_0 :
7476
+ self .skipTest ("Nested list is invalid type form" )
7477
+ self .assertEqual (concat_usage , callable_concat [[str ]])
7478
+
7479
+ def test_substitution (self ):
7480
+ T = TypeVar ('T' )
7481
+ Ts = TypeVarTuple ("Ts" )
7482
+
7483
+ CallableTs = TypeAliasType ("CallableTs" , Callable [[Unpack [Ts ]], Any ], type_params = (Ts , ))
7484
+ unpack_callable = CallableTs [Unpack [Tuple [int , T ]]]
7485
+ self .assertEqual (get_args (unpack_callable ), (Unpack [Tuple [int , T ]],))
7486
+
7487
+ P = ParamSpec ('P' )
7488
+ CallableP = TypeAliasType ("CallableP" , Callable [P , T ], type_params = (P , T ))
7489
+ callable_concat = CallableP [Concatenate [int , P ], Any ]
7490
+ self .assertEqual (get_args (callable_concat ), (Concatenate [int , P ], Any ))
7491
+
7492
+ def test_wrong_amount_of_parameters (self ):
7493
+ T = TypeVar ('T' )
7494
+ T2 = TypeVar ("T2" )
7495
+ P = ParamSpec ('P' )
7496
+ ListOrSetT = TypeAliasType ("ListOrSetT" , Union [List [T ], Set [T ]], type_params = (T ,))
7497
+ TwoT = TypeAliasType ("TwoT" , Union [List [T ], Set [T2 ]], type_params = (T , T2 ))
7498
+ CallablePT = TypeAliasType ("CallablePT" , Callable [P , T ], type_params = (P , T ))
7499
+
7500
+ # Not enough parameters
7501
+ test_cases = [
7502
+ # not_enough
7503
+ (TwoT [int ], [(int ,), ()]),
7504
+ (TwoT [T ], [(T ,), (T ,)]),
7505
+ # callable and not enough
7506
+ (CallablePT [int ], [(int ,), ()]),
7507
+ # too many
7508
+ (ListOrSetT [int , bool ], [(int , bool ), ()]),
7509
+ # callable and too many
7510
+ (CallablePT [str , float , int ], [(str , float , int ), ()]),
7511
+ # Check if TypeVar is still present even if over substituted
7512
+ (ListOrSetT [int , T ], [(int , T ), (T ,)]),
7513
+ # With and without list for ParamSpec
7514
+ (CallablePT [str , float , T ], [(str , float , T ), (T ,)]),
7515
+ (CallablePT [[str ], float , int , T2 ], [([str ], float , int , T2 ), (T2 ,)]),
7516
+ ]
7517
+
7518
+ for index , (alias , [expected_args , expected_params ]) in enumerate (test_cases ):
7519
+ with self .subTest (index = index , alias = alias ):
7520
+ self .assertEqual (get_args (alias ), expected_args )
7521
+ self .assertEqual (alias .__parameters__ , expected_params )
7522
+
7523
+ # The condition should align with the version of GeneriAlias usage in __getitem__ or be 3.11+
7524
+ @skipIf (TYPING_3_10_0 , "Most arguments are allowed in 3.11+ or with GenericAlias" )
7525
+ def test_invalid_cases_before_3_10 (self ):
7526
+ T = TypeVar ('T' )
7527
+ ListOrSetT = TypeAliasType ("ListOrSetT" , Union [List [T ], Set [T ]], type_params = (T ,))
7528
+ with self .assertRaises (TypeError ):
7529
+ ListOrSetT [Generic [T ]]
7530
+ with self .assertRaises (TypeError ):
7531
+ ListOrSetT [(Generic [T ], )]
7532
+
7344
7533
def test_unpack_parameter_collection (self ):
7345
7534
Ts = TypeVarTuple ("Ts" )
7346
7535
0 commit comments