Skip to content

Fix crash when unpacking a fixed-length tuple inside a tuple type - #21934

Open
afonsojanu wants to merge 1 commit into
python:masterfrom
afonsojanu:fix/tuple-fallback-unpack-fixed-tuple
Open

Fix crash when unpacking a fixed-length tuple inside a tuple type#21934
afonsojanu wants to merge 1 commit into
python:masterfrom
afonsojanu:fix/tuple-fallback-unpack-fixed-tuple

Conversation

@afonsojanu

Copy link
Copy Markdown

Fixes #21933.

The crash happens in tuple_fallback(). That function knows how to fold an unpacked item into the tuple's combined fallback type in two cases: a TypeVarTuple (using its upper bound) or a variable-length tuple Instance. It never learned about a third case PEP 646 also allows, unpacking a plain fixed-length tuple, so anything that hit this path raised NotImplementedError and mypy crashed outright.

This is easy to trigger with a type alias:

type Inner = tuple[int, str]
type Outer = tuple[bool, *Inner]

Outer unpacks Inner, a fixed tuple, not a variable-length one or a TypeVarTuple, so tuple_fallback had nowhere to go. The reporter's repro needed deque[Outer] specifically because computing the fallback here only gets triggered along certain code paths (checking a generic type argument against its bound during overload resolution, in this case), but the underlying gap is in tuple_fallback itself, independent of deque.

The fix recurses into tuple_fallback() for the nested TupleType to get its own combined element type, then folds that into the union the same way the other two branches already do.

Added a regression test to pythoneval.test using the reporter's original repro (it needs the real collections stub, so it belongs there rather than in one of the in-process check-*.test files). Confirmed it reproduces the exact INTERNAL ERROR crash from the issue before the fix and passes cleanly after. Ran the full test suite locally, no regressions.

tuple_fallback() only knew how to handle two shapes for an unpacked
item inside a tuple: a TypeVarTuple (via its upper bound) or a
variable-length tuple Instance. Unpacking a fixed-length tuple, which
PEP 646 also allows and which shows up easily through a type alias
like `type Outer = tuple[bool, *tuple[int, str]]`, fell through to the
NotImplementedError branch and crashed mypy outright whenever that
tuple type needed its fallback computed (e.g. when checking it against
a generic upper bound during overload resolution).

Handle the TupleType case the same way as the others: recurse into its
own tuple_fallback() to get the right combined element type, then fold
that into the union like everything else here does.

Fixes python#21933.
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Crash on unpacked tuple in tuple type definition

2 participants