python / typing_extensions

Backported and experimental type hints for Python
Other
445 stars 109 forks source link

`TypeAliasType` when a ParamSpec should be replaced raised type error #448

Open Daraan opened 3 months ago

Daraan commented 3 months ago

TypeAliasType currently has some bug/limitation when using it together with a ParamSpec in Python <3.10.

Root of the problem is the changed typing._type_check that was changed in Python 3.11 which makes typing_extensions.TypeAliasType.__getitem__ run into the TypeError in older Python versions:

arg: Ellipsis | list[type] # should be valid
-     if not callable(arg):
-        raise TypeError(f"{msg} Got {arg!r:.100}.")
+  if type(arg) is tuple:
+        raise TypeError(f"{msg} Got {arg!r:.100}.")

The following cases work in Python 3.11+ and fail in <= Python3.10

from typing_extensions import TypeAliasType, Callable, ParamSpec, Any

P = ParamSpec('P')
Foo = TypeAliasType("Foo", Callable[P, Any], type_params=(P,))

# Ok
FooInt = Foo[int] # (int) -> Any

# Error
FooInt2 = Foo[[int]] # (int) -> Any

# Error
FooIntInt = Foo[[int, int]] # (int, int) -> Any

# Error
FooWhatever = Foo[...] # (...) -> Any

# Error; should be invalid context
FooWhatever2 = Foo[[...]] # (...) -> Any

# Error; ( but also invalid parameter expression -> should use Concatenate)
FooIntWhatever = Foo[[int, ...]] # (int, ...) -> Any

# OK, correct parameter expression
FooConcatIntWhatever = Foo[Concatenate[int, ...]]