@@ -6281,6 +6281,10 @@ def test_typing_extensions_defers_when_possible(self):
62816281 'AsyncGenerator' , 'ContextManager' , 'AsyncContextManager' ,
62826282 'ParamSpec' , 'TypeVar' , 'TypeVarTuple' , 'get_type_hints' ,
62836283 }
6284+ if sys .version_info < (3 , 14 ):
6285+ exclude |= {
6286+ 'TypeAliasType'
6287+ }
62846288 if not typing_extensions ._PEP_728_IMPLEMENTED :
62856289 exclude |= {'TypedDict' , 'is_typeddict' }
62866290 for item in typing_extensions .__all__ :
@@ -7491,6 +7495,80 @@ def test_no_instance_subclassing(self):
74917495 class MyAlias (TypeAliasType ):
74927496 pass
74937497
7498+ def test_type_var_compatibility (self ):
7499+ # Regression test to assure compatibility with typing variants
7500+ typingT = typing .TypeVar ('typingT' )
7501+ T1 = TypeAliasType ("TypingTypeVar" , ..., type_params = (typingT ,))
7502+ self .assertEqual (T1 .__type_params__ , (typingT ,))
7503+
7504+ # Test typing_extensions backports
7505+ textT = TypeVar ('textT' )
7506+ T2 = TypeAliasType ("TypingExtTypeVar" , ..., type_params = (textT ,))
7507+ self .assertEqual (T2 .__type_params__ , (textT ,))
7508+
7509+ textP = ParamSpec ("textP" )
7510+ T3 = TypeAliasType ("TypingExtParamSpec" , ..., type_params = (textP ,))
7511+ self .assertEqual (T3 .__type_params__ , (textP ,))
7512+
7513+ textTs = TypeVarTuple ("textTs" )
7514+ T4 = TypeAliasType ("TypingExtTypeVarTuple" , ..., type_params = (textTs ,))
7515+ self .assertEqual (T4 .__type_params__ , (textTs ,))
7516+
7517+ @skipUnless (TYPING_3_10_0 , "typing.ParamSpec is not available before 3.10" )
7518+ def test_param_spec_compatibility (self ):
7519+ # Regression test to assure compatibility with typing variant
7520+ typingP = typing .ParamSpec ("typingP" )
7521+ T5 = TypeAliasType ("TypingParamSpec" , ..., type_params = (typingP ,))
7522+ self .assertEqual (T5 .__type_params__ , (typingP ,))
7523+
7524+ @skipUnless (TYPING_3_12_0 , "typing.TypeVarTuple is not available before 3.12" )
7525+ def test_type_var_tuple_compatibility (self ):
7526+ # Regression test to assure compatibility with typing variant
7527+ typingTs = typing .TypeVarTuple ("typingTs" )
7528+ T6 = TypeAliasType ("TypingTypeVarTuple" , ..., type_params = (typingTs ,))
7529+ self .assertEqual (T6 .__type_params__ , (typingTs ,))
7530+
7531+ def test_type_params_possibilities (self ):
7532+ T = TypeVar ('T' )
7533+ # Test not a tuple
7534+ with self .assertRaisesRegex (TypeError , "type_params must be a tuple" ):
7535+ TypeAliasType ("InvalidTypeParams" , List [T ], type_params = [T ])
7536+
7537+ # Test default order and other invalid inputs
7538+ T_default = TypeVar ('T_default' , default = int )
7539+ Ts = TypeVarTuple ('Ts' )
7540+ Ts_default = TypeVarTuple ('Ts_default' , default = Unpack [Tuple [str , int ]])
7541+ P = ParamSpec ('P' )
7542+ P_default = ParamSpec ('P_default' , default = [str , int ])
7543+
7544+ # NOTE: PEP 696 states: "TypeVars with defaults cannot immediately follow TypeVarTuples"
7545+ # this is currently not enforced for the type statement and is not tested.
7546+ # PEP 695: Double usage of the same name is also not enforced and not tested.
7547+ valid_cases = [
7548+ (T , P , Ts ),
7549+ (T , Ts_default ),
7550+ (P_default , T_default ),
7551+ (P , T_default , Ts_default ),
7552+ (T_default , P_default , Ts_default ),
7553+ ]
7554+ invalid_cases = [
7555+ ((T_default , T ), f"non-default type parameter '{ T !r} ' follows default" ),
7556+ ((P_default , P ), f"non-default type parameter '{ P !r} ' follows default" ),
7557+ ((Ts_default , T ), f"non-default type parameter '{ T !r} ' follows default" ),
7558+ # Only type params are accepted
7559+ ((1 ,), "Expected a type param, got 1" ),
7560+ ((str ,), f"Expected a type param, got { str !r} " ),
7561+ # Unpack is not a TypeVar but isinstance(Unpack[Ts], TypeVar) is True in Python < 3.12
7562+ ((Unpack [Ts ],), f"Expected a type param, got { re .escape (repr (Unpack [Ts ]))} " ),
7563+ ]
7564+
7565+ for case in valid_cases :
7566+ with self .subTest (type_params = case ):
7567+ TypeAliasType ("OkCase" , List [T ], type_params = case )
7568+ for case , msg in invalid_cases :
7569+ with self .subTest (type_params = case ):
7570+ with self .assertRaisesRegex (TypeError , msg ):
7571+ TypeAliasType ("InvalidCase" , List [T ], type_params = case )
74947572
74957573class DocTests (BaseTestCase ):
74967574 def test_annotation (self ):
0 commit comments