Closed
Description
The following code:
from typing import *
P = ParamSpec('P')
Ts = TypeVarTuple('Ts')
C = Callable[P, Tuple[*Ts]]
C[[int], str, bytes]
gives an error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/serhiy/py/cpython3.11/Lib/typing.py", line 363, in inner
return func(*args, **kwds)
^^^^^^^^^^^^^^^^^^^
File "/home/serhiy/py/cpython3.11/Lib/typing.py", line 1393, in __getitem__
new_args = self._determine_new_args(args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/serhiy/py/cpython3.11/Lib/typing.py", line 1417, in _determine_new_args
args = prepare(self, args)
^^^^^^^^^^^^^^^^^^^
File "/home/serhiy/py/cpython3.11/Lib/typing.py", line 1229, in __typing_prepare_subst__
return _prepare_paramspec_params(alias, args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/serhiy/py/cpython3.11/Lib/typing.py", line 297, in _prepare_paramspec_params
_check_generic(cls, params, len(cls.__parameters__))
File "/home/serhiy/py/cpython3.11/Lib/typing.py", line 274, in _check_generic
raise TypeError(f"Too {'many' if alen > elen else 'few'} arguments for {cls};"
TypeError: Too many arguments for typing.Callable[~P, typing.Tuple[*Ts]]; actual 3, expected 2
The same for the C implementation (types.GenericAlias
):
import collections.abc
C = collections.abc.Callable[P, Tuple[*Ts]]
C[[int], str, bytes]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/serhiy/py/cpython3.11/Lib/_collections_abc.py", line 468, in __getitem__
new_args = super().__getitem__(item).__args__
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/serhiy/py/cpython3.11/Lib/typing.py", line 1229, in __typing_prepare_subst__
return _prepare_paramspec_params(alias, args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/serhiy/py/cpython3.11/Lib/typing.py", line 297, in _prepare_paramspec_params
_check_generic(cls, params, len(cls.__parameters__))
File "/home/serhiy/py/cpython3.11/Lib/typing.py", line 274, in _check_generic
raise TypeError(f"Too {'many' if alen > elen else 'few'} arguments for {cls};"
TypeError: Too many arguments for collections.abc.Callable[~P, typing.Tuple[*Ts]]; actual 3, expected 2
And for user generics:
T = TypeVar('T')
class A(Generic[P, T]):
pass
B = A[P, Tuple[*Ts]]
B[[int], str, bytes]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/serhiy/py/cpython3.11/Lib/typing.py", line 363, in inner
return func(*args, **kwds)
^^^^^^^^^^^^^^^^^^^
File "/home/serhiy/py/cpython3.11/Lib/typing.py", line 1393, in __getitem__
new_args = self._determine_new_args(args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/serhiy/py/cpython3.11/Lib/typing.py", line 1417, in _determine_new_args
args = prepare(self, args)
^^^^^^^^^^^^^^^^^^^
File "/home/serhiy/py/cpython3.11/Lib/typing.py", line 1229, in __typing_prepare_subst__
return _prepare_paramspec_params(alias, args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/serhiy/py/cpython3.11/Lib/typing.py", line 297, in _prepare_paramspec_params
_check_generic(cls, params, len(cls.__parameters__))
File "/home/serhiy/py/cpython3.11/Lib/typing.py", line 274, in _check_generic
raise TypeError(f"Too {'many' if alen > elen else 'few'} arguments for {cls};"
TypeError: Too many arguments for __main__.A[~P, typing.Tuple[*Ts]]; actual 3, expected 2
But it works if ParamSpec
and TypeVarTuple
are in different order:
class A(Generic[T, P]):
pass
B = A[Tuple[*Ts], P]
B[str, bytes, [int]]
It is a different bug than #99344 because it happens when you substitute in a generic alias instead of a user generic.