@@ -7193,10 +7193,24 @@ def test_attributes(self):
71937193
71947194 subscripted_tupleT = Variadic [Unpack [Tuple [int , T ]]]
71957195 self .assertEqual (subscripted_tupleT .__name__ , "Variadic" )
7196- self .assertEqual (subscripted_tupleT .__value__ , Tuple [int , Unpack [Ts ]])
7197- self .assertEqual (subscripted_tupleT .__type_params__ , (Ts ,))
71987196 self .assertEqual (subscripted_tupleT .__parameters__ , (T , ))
71997197
7198+ # Use with Callable
7199+ # Use with Callable+Concatenate
7200+ subscripted_callable_concat = Variadic [Callable [Concatenate [Literal ["s" ], P ], T ]]
7201+ self .assertEqual (subscripted_callable_concat .__parameters__ , (P , T ))
7202+
7203+ subcriped_callable_tvt = Variadic [Callable [[Unpack [Ts ]], T ]]
7204+ self .assertEqual (subcriped_callable_tvt .__parameters__ , (Ts , T ))
7205+
7206+ # Use with Callable+Unpack
7207+ CallableTs = TypeAliasType ("CallableTs" , Callable [[Unpack [Ts ]], Any ], type_params = (Ts , ))
7208+ self .assertEqual (CallableTs .__type_params__ , (Ts ,))
7209+ self .assertEqual (CallableTs .__parameters__ , (* Ts ,))
7210+
7211+ unpack_callable = CallableTs [Unpack [Tuple [int , T ]]]
7212+ self .assertEqual (unpack_callable .__parameters__ , (T ,))
7213+
72007214 def test_cannot_set_attributes (self ):
72017215 Simple = TypeAliasType ("Simple" , int )
72027216 with self .assertRaisesRegex (AttributeError , "readonly attribute" ):
@@ -7262,8 +7276,8 @@ def test_getitem(self):
72627276 subscripted = ListOrSetT [int ]
72637277 self .assertEqual (get_args (subscripted ), (int ,))
72647278 self .assertIs (get_origin (subscripted ), ListOrSetT )
7265- with self .assertRaises (TypeError ):
7266- subscripted [int ] # TypeError: ListOrSetT[int] is not a generic class
7279+ with self .assertRaises (TypeError , msg = "not a generic class" ):
7280+ subscripted [int ]
72677281
72687282 still_generic = ListOrSetT [Iterable [T ]]
72697283 self .assertEqual (get_args (still_generic ), (Iterable [T ],))
@@ -7279,36 +7293,116 @@ def test_getitem(self):
72797293 callable_no_arg = CallableP [[]]
72807294 self .assertEqual (get_args (callable_no_arg ), ([],))
72817295 # (int) -> Any
7282- callable_arg_raw = CallableP [int ]
7283- self .assertEqual (get_args (callable_arg_raw ), (int ,))
7284- callable_arg = CallableP [[int ]]
7285- self .assertEqual (get_args (callable_arg ), ([int ],))
7296+ callable_arg = CallableP [int ]
7297+ self .assertEqual (get_args (callable_arg ), (int ,))
7298+
7299+ callable_arg_list = CallableP [[int ]]
7300+ self .assertEqual (get_args (callable_arg_list ), ([int ],))
7301+
72867302 # (int, int) -> Any
7287- callable_arg2 = CallableP [[int , int ]]
7288- self .assertEqual (get_args (callable_arg2 ), ([int , int ],))
7303+ callable_arg2 = CallableP [int , int ]
7304+ self .assertEqual (get_args (callable_arg2 ), (int , int ,))
7305+
7306+ callable_arg2_list = CallableP [[int , int ]]
7307+ self .assertEqual (get_args (callable_arg2_list ), ([int , int ],))
72897308 # (...) -> Any
72907309 callable_ellipsis = CallableP [...]
72917310 self .assertEqual (get_args (callable_ellipsis ), (...,))
7311+
72927312 callable_ellipsis2 = CallableP [(...,)]
72937313 self .assertEqual (callable_ellipsis , callable_ellipsis2 )
72947314 # (int, ...) -> Any
72957315 callable_arg_more = CallableP [[int , ...]]
72967316 self .assertEqual (get_args (callable_arg_more ), ([int , ...],))
72977317 # (T) -> Any
7298- callable_generic = CallableP [[T ]]
7299- self .assertEqual (get_args (callable_generic ), ([T ],))
73007318 callable_generic_raw = CallableP [T ]
73017319 self .assertEqual (get_args (callable_generic_raw ), (T ,))
7320+ self .assertEqual (callable_generic_raw .__parameters__ , (T ,))
73027321
7303- # test invalid usage
7304- if not TYPING_3_11_0 :
7305- with self .assertRaises (TypeError ):
7306- ListOrSetT [Generic [T ]]
7307- with self .assertRaises (TypeError ):
7308- ListOrSetT [(Generic [T ], )]
7322+ # Usage with Concatenate
7323+ callable_concat = CallableP [Concatenate [int , P ]]
7324+ self .assertEqual (callable_concat .__parameters__ , (P ,))
7325+ if TYPING_3_11_0 :
7326+ self .assertEqual (get_args (callable_concat ), (Concatenate [int , P ],))
7327+ concat_usage = callable_concat [str ]
7328+ self .assertEqual (get_args (concat_usage ), ((int , str ),))
7329+ self .assertEqual (concat_usage , callable_concat [[str ]])
7330+ elif TYPING_3_10_0 :
7331+ self .assertEqual (get_args (callable_concat ), (int , P ,))
7332+ with self .assertRaises (TypeError , msg = "Parameters to generic types must be types" ):
7333+ callable_concat [str ]
7334+ concat_usage = callable_concat [[str ]]
7335+ self .assertEqual (get_args (concat_usage ), (int , [str ]))
7336+ else :
7337+ self .assertEqual (get_args (callable_concat ), (int , P ,))
7338+ with self .assertRaises (TypeError , msg = "Parameters to generic types must be types" ):
7339+ callable_concat [[str ]]
7340+ concat_usage = callable_concat [str ]
7341+ self .assertEqual (get_args (concat_usage ), (int , str ))
7342+
7343+ # More complex cases
7344+ Ts = TypeVarTuple ("Ts" )
7345+ CallableTs = TypeAliasType ("CallableTs" , Callable [[Unpack [Ts ]], Any ], type_params = (Ts , ))
7346+ unpack_callable = CallableTs [Unpack [Tuple [int , T ]]]
7347+ if TYPING_3_11_0 :
7348+ self .assertEqual (get_args (unpack_callable ), (Unpack [Tuple [int , T ]],))
7349+ else :
7350+ self .assertEqual (get_args (unpack_callable ), (Tuple [int , T ],))
7351+ self .assertEqual (unpack_callable .__parameters__ , (T ,))
7352+
7353+ Variadic = TypeAliasType ("Variadic" , Tuple [int , Unpack [Ts ]], type_params = (Ts ,))
7354+ mixed_subscripedPT = Variadic [Callable [Concatenate [int , P ], T ]]
7355+ self .assertEqual (mixed_subscripedPT .__parameters__ , (P , T ))
7356+ self .assertEqual (get_args (mixed_subscripedPT ), (Callable [Concatenate [int , P ], T ],))
7357+
7358+ done_subscripted_no_list = mixed_subscripedPT [T , Any ] # Expected ParamSpec, ellipsis, or list of types
7359+ if TYPING_3_10_0 :
7360+ done_subscripted_list = mixed_subscripedPT [[T ], Any ]
7361+ self .assertEqual (done_subscripted_list , done_subscripted_no_list )
7362+ else :
7363+ with self .assertRaises (TypeError , msg = "Parameters to generic types must be types." ):
7364+ mixed_subscripedPT [[T ], Any ]
7365+
7366+ @skipUnless (TYPING_3_11_0 , "__args__ behaves differently" )
7367+ def test_311_substitution (self ):
7368+ # To pass these tests alias.__args__ in TypeAliasType.__getitem__ needs adjustment
7369+ # Unpack and Concatenate are unpacked in versions before
7370+ T = TypeVar ("T" )
7371+ Ts = TypeVarTuple ("Ts" )
7372+
7373+ CallableTs = TypeAliasType ("CallableTs" , Callable [[Unpack [Ts ]], Any ], type_params = (Ts , ))
7374+ unpack_callable = CallableTs [Unpack [Tuple [int , T ]]]
7375+ self .assertEqual (get_args (unpack_callable ), (Unpack [Tuple [int , T ]],))
7376+
7377+ P = ParamSpec ('P' )
7378+ CallableP = TypeAliasType ("CallableP" , Callable [P , T ], type_params = (P , T ))
7379+ callable_concat = CallableP [Concatenate [int , P ], Any ]
7380+ self .assertEqual (get_args (callable_concat ), (Concatenate [int , P ], Any ))
7381+
7382+ @skipUnless (TYPING_3_12_0 , "__args__ behaves differently" )
7383+ def test_312_substitution (self ):
7384+ # To pass these tests alias.__args__ in TypeAliasType.__getitem__ needs to be adjustment
7385+ # Would raise: TypeError: Substitution of bare TypeVarTuple is not supported
7386+ T = TypeVar ("T" )
7387+ Ts = TypeVarTuple ("Ts" )
7388+ Variadic = TypeAliasType ("Variadic" , Tuple [int , Unpack [Ts ]], type_params = (Ts ,))
7389+
7390+ subcriped_callable_tvt = Variadic [Callable [[Unpack [Ts ]], T ]]
7391+ variadic_tvt_callableA = subcriped_callable_tvt [str , object ]
7392+ variadic_tvt_callableA2 = subcriped_callable_tvt [Unpack [Tuple [str ]], object ]
7393+ self .assertEqual (variadic_tvt_callableA , variadic_tvt_callableA2 )
7394+
7395+ variadic_tvt_callableB = subcriped_callable_tvt [[str , int ], object ]
7396+ variadic_tvt_callableB2 = subcriped_callable_tvt [Unpack [Tuple [str , int ]], object ]
7397+ variadic_tvt_callableB3 = subcriped_callable_tvt [str , int , object ]
7398+ self .assertNotEqual (variadic_tvt_callableB , variadic_tvt_callableB2 )
7399+ self .assertEqual (variadic_tvt_callableB2 , variadic_tvt_callableB3 )
73097400
73107401 def test_invalid_cases (self ):
7311- # If these cases fail the specificiation might have changed
7402+ # NOTE: If these cases fail the specificiation might have changed
7403+ # some of the cases could be seen as valid but are currently not
7404+
7405+ # More parameters
73127406 T = TypeVar ("T" )
73137407 T2 = TypeVar ("T2" )
73147408 ListOrSetT = TypeAliasType ("ListOrSetT" , Union [List [T ], Set [T ]], type_params = (T ,))
@@ -7317,6 +7411,7 @@ def test_invalid_cases(self):
73177411 self .assertEqual (get_args (too_many ), (int , bool ))
73187412 self .assertEqual (too_many .__parameters__ , ())
73197413
7414+ # Not enough parameters
73207415 ListOrSet2T = TypeAliasType ("ListOrSet2T" , Union [List [T ], Set [T2 ]], type_params = (T , T2 ))
73217416 not_enough = ListOrSet2T [int ]
73227417 self .assertEqual (get_args (not_enough ), (int ,))
@@ -7357,15 +7452,45 @@ def test_invalid_cases(self):
73577452 invalud_tuple_C = Variadic [[int , T ]]
73587453 self .assertEqual (invalud_tuple_C .__parameters__ , ())
73597454 self .assertEqual (get_args (invalud_tuple_C ), ([int , T ],))
7360-
7361- @skipUnless (TYPING_3_11_0 , "Concatenate not unpacked anymore" )
7362- def test_further_invalid_cases (self ):
7363- P = ParamSpec ('P' )
7455+
7456+ # Callable
7457+ # NOTE: This these cases seem to be more like a limitation in the typing variant
7458+ # The final variable is parameterless if using a list here.
7459+ callable_T = CallableP [[T ]]
7460+ self .assertEqual (get_args (callable_T ), ([T ],))
7461+ self .assertEqual (callable_T .__parameters__ , ())
7462+ with self .assertRaises (TypeError , msg = "is not a generic class" ):
7463+ callable_T [str ]
7464+
7465+ InvalidConcatP = CallableP [[int , P ]]
7466+ self .assertEqual (get_args (InvalidConcatP ), ([int , P ],))
7467+ self .assertEqual (InvalidConcatP .__parameters__ , ())
7468+ with self .assertRaises (TypeError , msg = "is not a generic class" ):
7469+ InvalidConcatP [str ]
7470+
7471+ # Callable
7472+ # NOTE: This these cases seem to be more like a limitation in the typing variant
7473+ callable_T = CallableP [[T ]]
7474+ self .assertEqual (get_args (callable_T ), ([T ],))
7475+ self .assertEqual (callable_T .__parameters__ , ())
7476+ with self .assertRaises (TypeError , msg = "is not a generic class" ):
7477+ callable_T [str ]
7478+
7479+ InvalidConcatP = CallableP [[int , P ]]
7480+ self .assertEqual (get_args (InvalidConcatP ), ([int , P ],))
7481+ self .assertEqual (InvalidConcatP .__parameters__ , ())
7482+ with self .assertRaises (TypeError , msg = "is not a generic class" ):
7483+ InvalidConcatP [str ]
7484+
7485+ @skipIf (TYPING_3_11_0 , "Most cases are allowed in 3.11+" )
7486+ def test_invalid_cases_before_3_11 (self ):
73647487 T = TypeVar ("T" )
7365- T2 = TypeVar ("T2" )
7366- CallableP = TypeAliasType ("CallableP" , Callable [P , T ], type_params = (P ,))
7367- callable_concat = CallableP [Concatenate [Any , T2 , P ], Any ]
7368- self .assertEqual (get_args (callable_concat ), (Concatenate [Any , T2 , P ], Any ))
7488+ ListOrSetT = TypeAliasType ("ListOrSetT" , Union [List [T ], Set [T ]], type_params = (T ,))
7489+ with self .assertRaises (TypeError ):
7490+ ListOrSetT [Generic [T ]]
7491+ with self .assertRaises (TypeError ):
7492+ ListOrSetT [(Generic [T ], )]
7493+
73697494
73707495 def test_pickle (self ):
73717496 global Alias
0 commit comments