Skip to content

Commit 662bbeb

Browse files
authored
Fix crash for callable with *args and suffix against Any (#18781)
Fixes #18780 Fix is trivial: handle a missing case. Note I re-use `flatten_nested_tuples()` out of laziness. In theory, there should be at most one level of nesting at this point, after which we should put an assert (and IIRC we do something like this in other places). But I think it is not worth the effort here, as this is a quite niche edge case anyway.
1 parent a4313e4 commit 662bbeb

File tree

3 files changed

+17
-2
lines changed

3 files changed

+17
-2
lines changed

mypy/constraints.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
UnionType,
5454
UnpackType,
5555
find_unpack_in_list,
56+
flatten_nested_tuples,
5657
get_proper_type,
5758
has_recursive_types,
5859
has_type_vars,
@@ -1347,7 +1348,9 @@ def visit_type_alias_type(self, template: TypeAliasType) -> list[Constraint]:
13471348

13481349
def infer_against_any(self, types: Iterable[Type], any_type: AnyType) -> list[Constraint]:
13491350
res: list[Constraint] = []
1350-
for t in types:
1351+
# Some items may be things like `*Tuple[*Ts, T]` for example from callable types with
1352+
# suffix after *arg, so flatten them.
1353+
for t in flatten_nested_tuples(types):
13511354
if isinstance(t, UnpackType):
13521355
if isinstance(t.type, TypeVarTupleType):
13531356
res.append(Constraint(t.type, self.direction, any_type))

mypy/types.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3726,7 +3726,7 @@ def find_unpack_in_list(items: Sequence[Type]) -> int | None:
37263726
return unpack_index
37273727

37283728

3729-
def flatten_nested_tuples(types: Sequence[Type]) -> list[Type]:
3729+
def flatten_nested_tuples(types: Iterable[Type]) -> list[Type]:
37303730
"""Recursively flatten TupleTypes nested with Unpack.
37313731
37323732
For example this will transform

test-data/unit/check-typevar-tuple.test

+12
Original file line numberDiff line numberDiff line change
@@ -2606,3 +2606,15 @@ def test(xs: tuple[Unpack[Ts]], xsi: tuple[int, Unpack[Ts]]) -> None:
26062606
reveal_type(join(xsi, ai)) # N: Revealed type is "Tuple[builtins.int, Unpack[builtins.tuple[Any, ...]]]"
26072607
reveal_type(join(ai, xsi)) # N: Revealed type is "Tuple[builtins.int, Unpack[builtins.tuple[Any, ...]]]"
26082608
[builtins fixtures/tuple.pyi]
2609+
2610+
[case testTypeVarTupleInferAgainstAnyCallableSuffix]
2611+
from typing import Any, Callable, TypeVar, TypeVarTuple
2612+
2613+
Ts = TypeVarTuple("Ts")
2614+
R = TypeVar("R")
2615+
def deco(func: Callable[[*Ts, int], R]) -> Callable[[*Ts], R]:
2616+
...
2617+
2618+
untyped: Any
2619+
reveal_type(deco(untyped)) # N: Revealed type is "def (*Any) -> Any"
2620+
[builtins fixtures/tuple.pyi]

0 commit comments

Comments
 (0)