@@ -6192,6 +6192,10 @@ def test_typing_extensions_defers_when_possible(self):
6192
6192
'AsyncGenerator' , 'ContextManager' , 'AsyncContextManager' ,
6193
6193
'ParamSpec' , 'TypeVar' , 'TypeVarTuple' , 'get_type_hints' ,
6194
6194
}
6195
+ if sys .version_info < (3 , 14 ):
6196
+ exclude |= {
6197
+ 'TypeAliasType'
6198
+ }
6195
6199
if not typing_extensions ._PEP_728_IMPLEMENTED :
6196
6200
exclude |= {'TypedDict' , 'is_typeddict' }
6197
6201
for item in typing_extensions .__all__ :
@@ -7586,6 +7590,80 @@ def test_no_instance_subclassing(self):
7586
7590
class MyAlias (TypeAliasType ):
7587
7591
pass
7588
7592
7593
+ def test_type_var_compatibility (self ):
7594
+ # Regression test to assure compatibility with typing variants
7595
+ typingT = typing .TypeVar ('typingT' )
7596
+ T1 = TypeAliasType ("TypingTypeVar" , ..., type_params = (typingT ,))
7597
+ self .assertEqual (T1 .__type_params__ , (typingT ,))
7598
+
7599
+ # Test typing_extensions backports
7600
+ textT = TypeVar ('textT' )
7601
+ T2 = TypeAliasType ("TypingExtTypeVar" , ..., type_params = (textT ,))
7602
+ self .assertEqual (T2 .__type_params__ , (textT ,))
7603
+
7604
+ textP = ParamSpec ("textP" )
7605
+ T3 = TypeAliasType ("TypingExtParamSpec" , ..., type_params = (textP ,))
7606
+ self .assertEqual (T3 .__type_params__ , (textP ,))
7607
+
7608
+ textTs = TypeVarTuple ("textTs" )
7609
+ T4 = TypeAliasType ("TypingExtTypeVarTuple" , ..., type_params = (textTs ,))
7610
+ self .assertEqual (T4 .__type_params__ , (textTs ,))
7611
+
7612
+ @skipUnless (TYPING_3_10_0 , "typing.ParamSpec is not available before 3.10" )
7613
+ def test_param_spec_compatibility (self ):
7614
+ # Regression test to assure compatibility with typing variant
7615
+ typingP = typing .ParamSpec ("typingP" )
7616
+ T5 = TypeAliasType ("TypingParamSpec" , ..., type_params = (typingP ,))
7617
+ self .assertEqual (T5 .__type_params__ , (typingP ,))
7618
+
7619
+ @skipUnless (TYPING_3_12_0 , "typing.TypeVarTuple is not available before 3.12" )
7620
+ def test_type_var_tuple_compatibility (self ):
7621
+ # Regression test to assure compatibility with typing variant
7622
+ typingTs = typing .TypeVarTuple ("typingTs" )
7623
+ T6 = TypeAliasType ("TypingTypeVarTuple" , ..., type_params = (typingTs ,))
7624
+ self .assertEqual (T6 .__type_params__ , (typingTs ,))
7625
+
7626
+ def test_type_params_possibilities (self ):
7627
+ T = TypeVar ('T' )
7628
+ # Test not a tuple
7629
+ with self .assertRaisesRegex (TypeError , "type_params must be a tuple" ):
7630
+ TypeAliasType ("InvalidTypeParams" , List [T ], type_params = [T ])
7631
+
7632
+ # Test default order and other invalid inputs
7633
+ T_default = TypeVar ('T_default' , default = int )
7634
+ Ts = TypeVarTuple ('Ts' )
7635
+ Ts_default = TypeVarTuple ('Ts_default' , default = Unpack [Tuple [str , int ]])
7636
+ P = ParamSpec ('P' )
7637
+ P_default = ParamSpec ('P_default' , default = [str , int ])
7638
+
7639
+ # NOTE: PEP 696 states: "TypeVars with defaults cannot immediately follow TypeVarTuples"
7640
+ # this is currently not enforced for the type statement and is not tested.
7641
+ # PEP 695: Double usage of the same name is also not enforced and not tested.
7642
+ valid_cases = [
7643
+ (T , P , Ts ),
7644
+ (T , Ts_default ),
7645
+ (P_default , T_default ),
7646
+ (P , T_default , Ts_default ),
7647
+ (T_default , P_default , Ts_default ),
7648
+ ]
7649
+ invalid_cases = [
7650
+ ((T_default , T ), f"non-default type parameter { T !r} follows default" ),
7651
+ ((P_default , P ), f"non-default type parameter { P !r} follows default" ),
7652
+ ((Ts_default , T ), f"non-default type parameter { T !r} follows default" ),
7653
+ # Only type params are accepted
7654
+ ((1 ,), "Expected a type param, got 1" ),
7655
+ ((str ,), f"Expected a type param, got { str !r} " ),
7656
+ # Unpack is not a TypeVar but isinstance(Unpack[Ts], TypeVar) is True in Python < 3.12
7657
+ ((Unpack [Ts ],), f"Expected a type param, got { re .escape (repr (Unpack [Ts ]))} " ),
7658
+ ]
7659
+
7660
+ for case in valid_cases :
7661
+ with self .subTest (type_params = case ):
7662
+ TypeAliasType ("OkCase" , List [T ], type_params = case )
7663
+ for case , msg in invalid_cases :
7664
+ with self .subTest (type_params = case ):
7665
+ with self .assertRaisesRegex (TypeError , msg ):
7666
+ TypeAliasType ("InvalidCase" , List [T ], type_params = case )
7589
7667
7590
7668
class DocTests (BaseTestCase ):
7591
7669
def test_annotation (self ):
0 commit comments