Skip to content

Commit af0a133

Browse files
committed
Restructured test cases
1 parent b6fefb0 commit af0a133

File tree

1 file changed

+119
-118
lines changed

1 file changed

+119
-118
lines changed

src/test_typing_extensions.py

Lines changed: 119 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -7166,57 +7166,54 @@ def test_attributes(self):
71667166
self.assertEqual(ListOrSetT.__type_params__, (T,))
71677167
self.assertEqual(ListOrSetT.__parameters__, (T,))
71687168

7169-
subscripted = ListOrSetT[int]
7170-
self.assertEqual(subscripted.__name__, "ListOrSetT")
7171-
self.assertEqual(subscripted.__value__, Union[List[T], Set[T]],)
7172-
self.assertEqual(subscripted.__type_params__, (T, ))
7173-
self.assertEqual(subscripted.__parameters__, ())
7174-
7175-
T2 = TypeVar("T2")
7176-
subscriptedT = ListOrSetT[T2]
7177-
self.assertEqual(subscriptedT.__name__, "ListOrSetT")
7178-
self.assertEqual(subscriptedT.__value__, Union[List[T], Set[T]],)
7179-
self.assertEqual(subscriptedT.__type_params__, (T, ))
7180-
self.assertEqual(subscriptedT.__parameters__, (T2, ))
7181-
71827169
Ts = TypeVarTuple("Ts")
71837170
Variadic = TypeAliasType("Variadic", Tuple[int, Unpack[Ts]], type_params=(Ts,))
71847171
self.assertEqual(Variadic.__name__, "Variadic")
71857172
self.assertEqual(Variadic.__value__, Tuple[int, Unpack[Ts]])
71867173
self.assertEqual(Variadic.__type_params__, (Ts,))
71877174
self.assertEqual(Variadic.__parameters__, tuple(iter(Ts)))
71887175

7189-
# Test bare
7190-
subscripted_tuple = Variadic[int, float]
7191-
self.assertEqual(subscripted_tuple.__name__, "Variadic")
7192-
self.assertEqual(subscripted_tuple.__value__, Tuple[int, Unpack[Ts]])
7193-
self.assertEqual(subscripted_tuple.__type_params__, (Ts,))
7194-
self.assertEqual(subscripted_tuple.__parameters__, ())
7195-
7196-
# Test with Unpack
7197-
subscripted_tupleT = Variadic[Unpack[Tuple[int, T]]]
7198-
self.assertEqual(subscripted_tupleT.__name__, "Variadic")
7199-
self.assertEqual(subscripted_tupleT.__parameters__, (T, ))
7176+
P = ParamSpec('P')
7177+
CallableP = TypeAliasType("CallableP", Callable[P, Any], type_params=(P, ))
7178+
self.assertEqual(CallableP.__name__, "CallableP")
7179+
self.assertEqual(CallableP.__value__, Callable[P, Any])
7180+
self.assertEqual(CallableP.__type_params__, (P,))
7181+
self.assertEqual(CallableP.__parameters__, (P,))
72007182

7201-
# Test with Unpack and TypeVarTuple
7202-
subscripted_Ts = Variadic[Unpack[Ts]]
7203-
self.assertEqual(subscripted_Ts.__parameters__, (Ts, ))
7183+
def test_attributes_from_origin(self):
7184+
T = TypeVar('T')
7185+
ListOrSetT = TypeAliasType("ListOrSetT", Union[List[T], Set[T]], type_params=(T,))
7186+
subscripted = ListOrSetT[int]
7187+
self.assertIs(get_origin(subscripted), ListOrSetT)
7188+
self.assertEqual(subscripted.__name__, "ListOrSetT")
7189+
self.assertEqual(subscripted.__value__, Union[List[T], Set[T]],)
7190+
self.assertEqual(subscripted.__type_params__, (T, ))
72047191

7205-
# Use with Callable
7206-
# Use with Callable+Concatenate
7207-
subscripted_callable_concat = Variadic[Callable[Concatenate[Literal["s"], P], T]]
7208-
self.assertEqual(subscripted_callable_concat.__parameters__, (P, T))
7192+
still_generic = ListOrSetT[Iterable[T]]
7193+
self.assertIs(get_origin(still_generic), ListOrSetT)
7194+
fully_subscripted = still_generic[float]
7195+
self.assertIs(get_origin(fully_subscripted), ListOrSetT)
7196+
# __name__ needs Python 3.10+
7197+
# __value__ and __type_params__ need Python 3.12+
7198+
# Further tests are below
72097199

7210-
subcriped_callable_tvt = Variadic[Callable[[Unpack[Ts]], T]]
7211-
self.assertEqual(subcriped_callable_tvt.__parameters__, (Ts, T))
7200+
@skipUnless(TYPING_3_10_0, "__name__ not added to GenericAlias")
7201+
def test_attributes_from_origin_3_10_plus(self):
7202+
T = TypeVar('T')
7203+
ListOrSetT = TypeAliasType("ListOrSetT", Union[List[T], Set[T]], type_params=(T,))
7204+
fully_subscripted = ListOrSetT[Iterable[T]][float]
7205+
self.assertEqual(fully_subscripted.__name__, "ListOrSetT")
7206+
# __value__ and __type_params__ need Python 3.12+
72127207

7213-
# Use with Callable+Unpack
7214-
CallableTs = TypeAliasType("CallableTs", Callable[[Unpack[Ts]], Any], type_params=(Ts, ))
7215-
self.assertEqual(CallableTs.__type_params__, (Ts,))
7216-
self.assertEqual(CallableTs.__parameters__, (*Ts,))
7208+
@skipUnless(TYPING_3_12_0, "attributes not added to GenericAlias")
7209+
def test_attributes_from_origin_3_12_plus(self):
7210+
T = TypeVar('T')
7211+
ListOrSetT = TypeAliasType("ListOrSetT", Union[List[T], Set[T]], type_params=(T,))
7212+
fully_subscripted = ListOrSetT[Iterable[T]][float]
7213+
self.assertEqual(fully_subscripted.__name__, "ListOrSetT")
7214+
self.assertEqual(fully_subscripted.__value__, Union[List[T], Set[T]],)
7215+
self.assertEqual(fully_subscripted.__type_params__, (T, ))
72177216

7218-
unpack_callable = CallableTs[Unpack[Tuple[int, T]]]
7219-
self.assertEqual(unpack_callable.__parameters__, (T,))
72207217

72217218
def test_cannot_set_attributes(self):
72227219
Simple = TypeAliasType("Simple", int)
@@ -7278,55 +7275,56 @@ def test_or(self):
72787275
Alias | "Ref"
72797276

72807277
def test_getitem(self):
7281-
T = TypeVar("T")
7278+
T = TypeVar('T')
7279+
ValueWithoutT = TypeAliasType("ValueWithoutT", int, type_params=(T,))
7280+
still_subscripted = ValueWithoutT[str]
7281+
self.assertEqual(get_args(still_subscripted), (str,))
7282+
72827283
ListOrSetT = TypeAliasType("ListOrSetT", Union[List[T], Set[T]], type_params=(T,))
72837284
subscripted = ListOrSetT[int]
72847285
self.assertEqual(get_args(subscripted), (int,))
7285-
self.assertIs(get_origin(subscripted), ListOrSetT)
72867286
with self.assertRaises(TypeError, msg="not a generic class"):
72877287
subscripted[int]
72887288

72897289
still_generic = ListOrSetT[Iterable[T]]
72907290
self.assertEqual(get_args(still_generic), (Iterable[T],))
7291-
self.assertIs(get_origin(still_generic), ListOrSetT)
72927291
fully_subscripted = still_generic[float]
72937292
self.assertEqual(get_args(fully_subscripted), (Iterable[float],))
7294-
self.assertIs(get_origin(fully_subscripted), ListOrSetT)
72957293

7296-
# Test ParamSpec and Ellipsis
7294+
def test_callable_without_concatenate(self):
72977295
P = ParamSpec('P')
72987296
CallableP = TypeAliasType("CallableP", Callable[P, Any], type_params=(P,))
7299-
# () -> Any
7300-
callable_no_arg = CallableP[[]]
7301-
self.assertEqual(get_args(callable_no_arg), ([],))
7302-
# (int) -> Any
7303-
callable_arg = CallableP[int]
7304-
self.assertEqual(get_args(callable_arg), (int,))
7305-
7306-
callable_arg_list = CallableP[[int]]
7307-
self.assertEqual(get_args(callable_arg_list), ([int],))
7308-
7309-
# (int, int) -> Any
7310-
callable_arg2 = CallableP[int, int]
7311-
self.assertEqual(get_args(callable_arg2), (int, int,))
7312-
7313-
callable_arg2_list = CallableP[[int, int]]
7314-
self.assertEqual(get_args(callable_arg2_list), ([int, int],))
7315-
# (...) -> Any
7316-
callable_ellipsis = CallableP[...]
7317-
self.assertEqual(get_args(callable_ellipsis), (...,))
7318-
7319-
callable_ellipsis2 = CallableP[(...,)]
7320-
self.assertEqual(callable_ellipsis, callable_ellipsis2)
7321-
# (int, ...) -> Any
7322-
callable_arg_more = CallableP[[int, ...]]
7323-
self.assertEqual(get_args(callable_arg_more), ([int, ...],))
7297+
get_args_test_cases = [
7298+
# List of (alias, expected_args)
7299+
# () -> Any
7300+
(CallableP[()], ()),
7301+
(CallableP[[]], ([],)),
7302+
# (int) -> Any
7303+
(CallableP[int], (int,)),
7304+
(CallableP[[int]], ([int],)),
7305+
# (int, int) -> Any
7306+
(CallableP[int, int], (int, int)),
7307+
(CallableP[[int, int]], ([int, int],)),
7308+
# (...) -> Any
7309+
(CallableP[...], (...,)),
7310+
# (int, ...) -> Any
7311+
(CallableP[[int, ...]], ([int, ...],)),
7312+
]
7313+
7314+
for index, (expression, expected_args) in enumerate(get_args_test_cases):
7315+
with self.subTest(index=index, expression=expression):
7316+
self.assertEqual(get_args(expression), expected_args)
7317+
7318+
self.assertEqual(CallableP[...], CallableP[(...,)])
73247319
# (T) -> Any
7325-
callable_generic_raw = CallableP[T]
7326-
self.assertEqual(get_args(callable_generic_raw), (T,))
7327-
self.assertEqual(callable_generic_raw.__parameters__, (T,))
7320+
CallableT = CallableP[T]
7321+
self.assertEqual(get_args(CallableT), (T,))
7322+
self.assertEqual(CallableT.__parameters__, (T,))
7323+
7324+
def test_callable_with_concatenate(self):
7325+
P = ParamSpec('P')
7326+
CallableP = TypeAliasType("CallableP", Callable[P, Any], type_params=(P,))
73287327

7329-
# Usage with Concatenate
73307328
callable_concat = CallableP[Concatenate[int, P]]
73317329
self.assertEqual(callable_concat.__parameters__, (P,))
73327330
if TYPING_3_11_0:
@@ -7344,18 +7342,11 @@ def test_getitem(self):
73447342
concat_usage = callable_concat[str]
73457343
self.assertEqual(get_args(concat_usage), (int, str))
73467344

7347-
# More complex cases
7348-
Ts = TypeVarTuple("Ts")
7349-
Variadic = TypeAliasType("Variadic", Tuple[int, Unpack[Ts]], type_params=(Ts,))
7350-
mixed_subscripedPT = Variadic[Callable[Concatenate[int, P], T]]
7351-
self.assertEqual(get_args(mixed_subscripedPT), (Callable[Concatenate[int, P], T],))
7352-
7353-
73547345
@skipUnless(TYPING_3_11_0, "__args__ behaves differently")
7355-
def test_311_substitution(self):
7346+
def test_substitution_311_plus(self):
73567347
# To pass these tests alias.__args__ in TypeAliasType.__getitem__ needs adjustment
73577348
# Unpack and Concatenate are unpacked in versions before
7358-
T = TypeVar("T")
7349+
T = TypeVar('T')
73597350
Ts = TypeVarTuple("Ts")
73607351

73617352
CallableTs = TypeAliasType("CallableTs", Callable[[Unpack[Ts]], Any], type_params=(Ts, ))
@@ -7368,10 +7359,10 @@ def test_311_substitution(self):
73687359
self.assertEqual(get_args(callable_concat), (Concatenate[int, P], Any))
73697360

73707361
@skipUnless(TYPING_3_12_0, "__args__ behaves differently")
7371-
def test_312_substitution(self):
7372-
# To pass these tests alias.__args__ in TypeAliasType.__getitem__ needs to be adjustment
7362+
def test_substitution_312_plus(self):
7363+
# To pass these tests alias.__args__ in TypeAliasType.__getitem__ needs adjustment
73737364
# Would raise: TypeError: Substitution of bare TypeVarTuple is not supported
7374-
T = TypeVar("T")
7365+
T = TypeVar('T')
73757366
Ts = TypeVarTuple("Ts")
73767367
Variadic = TypeAliasType("Variadic", Tuple[int, Unpack[Ts]], type_params=(Ts,))
73777368

@@ -7386,48 +7377,62 @@ def test_312_substitution(self):
73867377
self.assertNotEqual(variadic_tvt_callableB, variadic_tvt_callableB2)
73877378
self.assertEqual(variadic_tvt_callableB2, variadic_tvt_callableB3)
73887379

7389-
def test_invalid_cases(self):
7390-
# NOTE: If these cases fail the specificiation might have changed
7391-
# some of the cases could be seen as valid but are currently not
7392-
7393-
# More parameters
7394-
T = TypeVar("T")
7380+
def test_wrong_amount_of_parameters(self):
7381+
T = TypeVar('T')
73957382
T2 = TypeVar("T2")
7383+
P = ParamSpec('P')
73967384
ListOrSetT = TypeAliasType("ListOrSetT", Union[List[T], Set[T]], type_params=(T,))
7397-
7398-
too_many = ListOrSetT[int, bool]
7399-
self.assertEqual(get_args(too_many), (int, bool))
7400-
self.assertEqual(too_many.__parameters__, ())
7385+
TwoT = TypeAliasType("TwoT", Union[List[T], Set[T2]], type_params=(T, T2))
7386+
CallablePT = TypeAliasType("CallablePT", Callable[P, T], type_params=(P, T))
74017387

74027388
# Not enough parameters
7403-
ListOrSet2T = TypeAliasType("ListOrSet2T", Union[List[T], Set[T2]], type_params=(T, T2))
7404-
not_enough = ListOrSet2T[int]
7389+
not_enough = TwoT[int]
74057390
self.assertEqual(get_args(not_enough), (int,))
74067391
self.assertEqual(not_enough.__parameters__, ())
74077392

7408-
not_enough2 = ListOrSet2T[T]
7393+
not_enough2 = TwoT[T]
74097394
self.assertEqual(get_args(not_enough2), (T,))
74107395
self.assertEqual(not_enough2.__parameters__, (T,))
7411-
# ParamSpec
7412-
P = ParamSpec('P')
7413-
CallableP = TypeAliasType("CallableP", Callable[P, T], type_params=(P,))
74147396

7415-
callable_not_enough = CallableP[int]
7416-
self.assertEqual(callable_not_enough.__parameters__, ())
7397+
callable_not_enough = CallablePT[int]
74177398
self.assertEqual(get_args(callable_not_enough), (int, ))
7399+
self.assertEqual(callable_not_enough.__parameters__, ())
7400+
7401+
# Too many
7402+
too_many = ListOrSetT[int, bool]
7403+
self.assertEqual(get_args(too_many), (int, bool))
7404+
self.assertEqual(too_many.__parameters__, ())
74187405

7419-
callable_too_many = CallableP[str, float, T2, int]
7420-
self.assertEqual(callable_too_many.__parameters__, (T2, ))
7421-
self.assertEqual(get_args(callable_too_many), (str, float, T2, int, ))
7406+
callable_too_many = CallablePT[str, float, int]
7407+
self.assertEqual(get_args(callable_too_many), (str, float, int))
7408+
self.assertEqual(callable_too_many.__parameters__, ())
74227409

7423-
# Cases that result in parameterless variable
7410+
# Check if TypeVar is still present even if over substituted
7411+
too_manyT = ListOrSetT[int, T]
7412+
self.assertEqual(get_args(too_manyT), (int, T))
7413+
self.assertEqual(too_manyT.__parameters__, (T, ))
7414+
7415+
# With and without list for ParamSpec
7416+
callable_too_manyT = CallablePT[str, float, T]
7417+
self.assertEqual(get_args(callable_too_manyT), (str, float, T))
7418+
self.assertEqual(callable_too_manyT.__parameters__, (T, ))
7419+
7420+
callable_too_manyT2 = CallablePT[[str], float, int, T2]
7421+
self.assertEqual(get_args(callable_too_manyT2), ([str], float, int, T2))
7422+
self.assertEqual(callable_too_manyT2.__parameters__, (T2, ))
7423+
7424+
def test_list_argument(self):
7425+
# NOTE: These cases could be seen as valid but result in a parameterless
7426+
# variable. If these tests fail the specificiation might have changed
74247427

74257428
# Callable
7426-
CallableT = CallableP[[T]]
7427-
self.assertEqual(get_args(CallableT), ([T],))
7428-
self.assertEqual(CallableT.__parameters__, ())
7429+
P = ParamSpec('P')
7430+
CallableP = TypeAliasType("CallableP", Callable[P, Any], type_params=(P,))
7431+
CallableT_list = CallableP[[T]]
7432+
self.assertEqual(get_args(CallableT_list), ([T],))
7433+
self.assertEqual(CallableT_list.__parameters__, ())
74297434
with self.assertRaises(TypeError, msg="is not a generic class"):
7430-
CallableT[str]
7435+
CallableT_list[str]
74317436

74327437
ImplicitConcatP = CallableP[[int, P]]
74337438
self.assertEqual(get_args(ImplicitConcatP), ([int, P],))
@@ -7438,19 +7443,15 @@ def test_invalid_cases(self):
74387443
# TypeVarTuple
74397444
Ts = TypeVarTuple("Ts")
74407445
Variadic = TypeAliasType("Variadic", Tuple[int, Unpack[Ts]], type_params=(Ts,))
7441-
7442-
# No Tuple, but list
74437446
invalid_tupleT = Variadic[[int, T]]
7444-
self.assertEqual(invalid_tupleT.__parameters__, ())
74457447
self.assertEqual(get_args(invalid_tupleT), ([int, T],))
7446-
7448+
self.assertEqual(invalid_tupleT.__parameters__, ())
74477449
with self.assertRaises(TypeError, msg="is not a generic class"):
74487450
invalid_tupleT[str]
74497451

7450-
74517452
@skipIf(TYPING_3_11_0, "Most cases are allowed in 3.11+")
74527453
def test_invalid_cases_before_3_11(self):
7453-
T = TypeVar("T")
7454+
T = TypeVar('T')
74547455
ListOrSetT = TypeAliasType("ListOrSetT", Union[List[T], Set[T]], type_params=(T,))
74557456
with self.assertRaises(TypeError):
74567457
ListOrSetT[Generic[T]]
@@ -7467,7 +7468,7 @@ def test_subscription_without_type_params(self):
74677468
Simple[()]
74687469

74697470
# no TypeVar in type_params, however in value still allows subscription
7470-
T = TypeVar("T")
7471+
T = TypeVar('T')
74717472
MissingTypeParams = TypeAliasType("MissingTypeParams", List[T], type_params=())
74727473
self.assertEqual(MissingTypeParams.__type_params__, ())
74737474
self.assertEqual(MissingTypeParams.__parameters__, ())

0 commit comments

Comments
 (0)