From d69a1294327e997c323904089a2922c48cf375db Mon Sep 17 00:00:00 2001 From: Aaron Wieczorek Date: Wed, 7 Jan 2026 15:23:05 -0500 Subject: [PATCH 1/3] fix crash in split_for_callable when passing values to variadic generics --- mypy/checkexpr.py | 4 +++- test-data/unit/check-typevar-tuple.test | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 9990caaeb7a1..87f26760e6a6 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -4966,7 +4966,9 @@ class C(Generic[T, Unpack[Ts]]): ... if not vars or not any(isinstance(v, TypeVarTupleType) for v in vars): return list(args) # TODO: in future we may want to support type application to variadic functions. - assert t.is_type_obj() + if not t.is_type_obj(): + self.chk.fail(f"Invalid type argument: type expected, for {args[0]!r}", ctx) + return [AnyType(TypeOfAny.from_error)] * len(vars) info = t.type_object() # We reuse the logic from semanal phase to reduce code duplication. fake = Instance(info, args, line=ctx.line, column=ctx.column) diff --git a/test-data/unit/check-typevar-tuple.test b/test-data/unit/check-typevar-tuple.test index f6d9de8b0c1a..4edf7814d03e 100644 --- a/test-data/unit/check-typevar-tuple.test +++ b/test-data/unit/check-typevar-tuple.test @@ -2754,3 +2754,20 @@ class X(Generic[Unpack[Ts]]): def c(t: X[Concatenate[int, ...]]) -> None: # E: Cannot use "[int, VarArg(Any), KwArg(Any)]" for TypeVarTuple, only for ParamSpec reveal_type(t) # N: Revealed type is "__main__.X[Unpack[builtins.tuple[Any, ...]]]" [builtins fixtures/tuple.pyi] + +[case testTypeVarTupleLiteralValueAsTypeArgument] +# flags: --python-version 3.12 +from typing import TypeVarTuple, Generic, Unpack + +Ts = TypeVarTuple('Ts') + +def fn[*T]() -> None: + pass + +class C(Generic[*Ts]): + pass + +x = C[1, 2, 3]() # E: Invalid type: try using Literal[1] instead? \ + # E: Invalid type: try using Literal[2] instead? \ + # E: Invalid type: try using Literal[3] instead? +[builtins fixtures/tuple.pyi] From f37f381553ba85cecb7b3e74f2ec0f88874a06f2 Mon Sep 17 00:00:00 2001 From: Aaron Wieczorek Date: Wed, 7 Jan 2026 16:11:45 -0500 Subject: [PATCH 2/3] Refactor test to work with python 3.10/3.11, and 3.12+ --- test-data/unit/check-typevar-tuple.test | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/test-data/unit/check-typevar-tuple.test b/test-data/unit/check-typevar-tuple.test index 4edf7814d03e..ae5e2847d19a 100644 --- a/test-data/unit/check-typevar-tuple.test +++ b/test-data/unit/check-typevar-tuple.test @@ -2756,18 +2756,21 @@ def c(t: X[Concatenate[int, ...]]) -> None: # E: Cannot use "[int, VarArg(Any), [builtins fixtures/tuple.pyi] [case testTypeVarTupleLiteralValueAsTypeArgument] -# flags: --python-version 3.12 -from typing import TypeVarTuple, Generic, Unpack +from typing import TypeVarTuple, Generic, Unpack, Callable, TypeVar Ts = TypeVarTuple('Ts') +T = TypeVar('T') -def fn[*T]() -> None: - pass - -class C(Generic[*Ts]): +class C(Generic[Unpack[Ts]]): pass x = C[1, 2, 3]() # E: Invalid type: try using Literal[1] instead? \ # E: Invalid type: try using Literal[2] instead? \ # E: Invalid type: try using Literal[3] instead? + +def func(d: Callable[[Unpack[Ts]], T]) -> T: ... + +y = func[1, int] # E: Type application is only supported for generic classes \ + # E: Invalid type argument: type expected, for Any \ + # E: Invalid type: try using Literal[1] instead? [builtins fixtures/tuple.pyi] From 4b94d5d05f7b97af21a548b6812552ba63696ba5 Mon Sep 17 00:00:00 2001 From: Aaron Wieczorek Date: Thu, 8 Jan 2026 12:27:03 -0500 Subject: [PATCH 3/3] Refactoring to simplify --- mypy/checkexpr.py | 11 ++++++----- test-data/unit/check-typevar-tuple.test | 10 +--------- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 87f26760e6a6..9408d70e50f7 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -4963,12 +4963,13 @@ class C(Generic[T, Unpack[Ts]]): ... ) return [AnyType(TypeOfAny.from_error)] * len(vars) - if not vars or not any(isinstance(v, TypeVarTupleType) for v in vars): - return list(args) # TODO: in future we may want to support type application to variadic functions. - if not t.is_type_obj(): - self.chk.fail(f"Invalid type argument: type expected, for {args[0]!r}", ctx) - return [AnyType(TypeOfAny.from_error)] * len(vars) + if ( + not vars + or not any(isinstance(v, TypeVarTupleType) for v in vars) + or not t.is_type_obj() + ): + return list(args) info = t.type_object() # We reuse the logic from semanal phase to reduce code duplication. fake = Instance(info, args, line=ctx.line, column=ctx.column) diff --git a/test-data/unit/check-typevar-tuple.test b/test-data/unit/check-typevar-tuple.test index ae5e2847d19a..0b7f8fe06749 100644 --- a/test-data/unit/check-typevar-tuple.test +++ b/test-data/unit/check-typevar-tuple.test @@ -2756,21 +2756,13 @@ def c(t: X[Concatenate[int, ...]]) -> None: # E: Cannot use "[int, VarArg(Any), [builtins fixtures/tuple.pyi] [case testTypeVarTupleLiteralValueAsTypeArgument] -from typing import TypeVarTuple, Generic, Unpack, Callable, TypeVar +from typing import TypeVarTuple, Unpack, Callable, TypeVar Ts = TypeVarTuple('Ts') T = TypeVar('T') -class C(Generic[Unpack[Ts]]): - pass - -x = C[1, 2, 3]() # E: Invalid type: try using Literal[1] instead? \ - # E: Invalid type: try using Literal[2] instead? \ - # E: Invalid type: try using Literal[3] instead? - def func(d: Callable[[Unpack[Ts]], T]) -> T: ... y = func[1, int] # E: Type application is only supported for generic classes \ - # E: Invalid type argument: type expected, for Any \ # E: Invalid type: try using Literal[1] instead? [builtins fixtures/tuple.pyi]