Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f92b913

Browse files
bpo-44793: Fix checking the number of arguments when subscribe a generic type with ParamSpec parameter. (GH-27515)
For example Callable[P, T][[int], str, float] will now raise an error. Use also term "arguments" instead of "parameters" in error message for too few/many arguments.
1 parent 208a7e9 commit f92b913

3 files changed

Lines changed: 15 additions & 8 deletions

File tree

Lib/test/test_typing.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -626,8 +626,6 @@ def test_consistency(self):
626626
self.assertEqual(c1.__args__, c2.__args__)
627627
self.assertEqual(hash(c1.__args__), hash(c2.__args__))
628628

629-
test_errors = skip("known bug #44793")(BaseCallableTests.test_errors)
630-
631629

632630
class CollectionsCallableTests(BaseCallableTests, BaseTestCase):
633631
Callable = collections.abc.Callable
@@ -4588,6 +4586,10 @@ class X(Generic[T, P]):
45884586
G1 = X[int, P_2]
45894587
self.assertEqual(G1.__args__, (int, P_2))
45904588
self.assertEqual(G1.__parameters__, (P_2,))
4589+
with self.assertRaisesRegex(TypeError, "few arguments for"):
4590+
X[int]
4591+
with self.assertRaisesRegex(TypeError, "many arguments for"):
4592+
X[int, P_2, str]
45914593

45924594
G2 = X[int, Concatenate[int, P_2]]
45934595
self.assertEqual(G2.__args__, (int, Concatenate[int, P_2]))

Lib/typing.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ def _check_generic(cls, parameters, elen):
228228
raise TypeError(f"{cls} is not a generic class")
229229
alen = len(parameters)
230230
if alen != elen:
231-
raise TypeError(f"Too {'many' if alen > elen else 'few'} parameters for {cls};"
231+
raise TypeError(f"Too {'many' if alen > elen else 'few'} arguments for {cls};"
232232
f" actual {alen}, expected {elen}")
233233

234234
def _prepare_paramspec_params(cls, params):
@@ -239,6 +239,7 @@ def _prepare_paramspec_params(cls, params):
239239
if len(cls.__parameters__) == 1 and len(params) > 1:
240240
return (params,)
241241
else:
242+
_check_generic(cls, params, len(cls.__parameters__))
242243
_params = []
243244
# Convert lists to tuples to help other libraries cache the results.
244245
for p, tvar in zip(params, cls.__parameters__):
@@ -1022,10 +1023,11 @@ def __getitem__(self, params):
10221023
if not isinstance(params, tuple):
10231024
params = (params,)
10241025
params = tuple(_type_convert(p) for p in params)
1025-
if self._paramspec_tvars:
1026-
if any(isinstance(t, ParamSpec) for t in self.__parameters__):
1027-
params = _prepare_paramspec_params(self, params)
1028-
_check_generic(self, params, len(self.__parameters__))
1026+
if (self._paramspec_tvars
1027+
and any(isinstance(t, ParamSpec) for t in self.__parameters__)):
1028+
params = _prepare_paramspec_params(self, params)
1029+
else:
1030+
_check_generic(self, params, len(self.__parameters__))
10291031

10301032
subst = dict(zip(self.__parameters__, params))
10311033
new_args = []
@@ -1292,7 +1294,8 @@ def __class_getitem__(cls, params):
12921294
# Subscripting a regular Generic subclass.
12931295
if any(isinstance(t, ParamSpec) for t in cls.__parameters__):
12941296
params = _prepare_paramspec_params(cls, params)
1295-
_check_generic(cls, params, len(cls.__parameters__))
1297+
else:
1298+
_check_generic(cls, params, len(cls.__parameters__))
12961299
return _GenericAlias(cls, params,
12971300
_typevar_types=(TypeVar, ParamSpec),
12981301
_paramspec_tvars=True)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix checking the number of arguments when subscribe a generic type with
2+
``ParamSpec`` parameter.

0 commit comments

Comments
 (0)