Skip to content

Conversation

@cdce8p
Copy link
Collaborator

@cdce8p cdce8p commented Dec 22, 2025

Fixes #20451

@cdce8p cdce8p added crash topic-pep-696 TypeVar defaults topic-pep-646 PEP 646 (TypeVarTuple, Unpack) labels Dec 22, 2025
@github-actions

This comment has been minimized.

mypy/typeops.py Outdated
and unpacked_type.type.fullname == "builtins.tuple"
):
items.append(unpacked_type.args[0])
elif isinstance(unpacked_type, TupleType):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC the idea was that it should never be true when we call tuple_fallback - we have several places where things like tuple[*tuple[X,Y]] are normalized to a plain tuple, and the original intent was to get rid of such constructs as early as possible. This is fine as a quickfix, but I'm afraid that this will manifest again when such nested tuple is used elsewhere.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not entirely sure about that but isn't the function already doing the flatting? E.g. just the line above flattens builtins.tuple Instances.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

builtins.tuple is already normalized: you can't rewrite e.g. tuple[str, *tuple[int, ...]] as a single tuple[...] construct. This is only about expanding unpacks of fixed-size TupleType types (which is always possible), see flatten_nested_tuples

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think I found the right place now. The normalization happens in the TypeArgumentAnalyzer.

def visit_tuple_type(self, t: TupleType) -> None:
t.items = flatten_nested_tuples(t.items)
# We could also normalize Tuple[*tuple[X, ...]] -> tuple[X, ...] like in
# expand_type() but we can't do this here since it is not a translator visitor,
# and we need to return an Instance instead of TupleType.
super().visit_tuple_type(t)

The visitor wasn't traversing TypeVar defaults.

@github-actions
Copy link
Contributor

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

@ilevkivskyi ilevkivskyi merged commit 04efeb2 into python:master Dec 23, 2025
23 checks passed
@cdce8p cdce8p deleted the fix-crash-tuple-unpack branch December 23, 2025 23:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

crash topic-pep-646 PEP 646 (TypeVarTuple, Unpack) topic-pep-696 TypeVar defaults

Projects

None yet

Development

Successfully merging this pull request may close these issues.

In TypeVar, using * and Unpack for default argument gets error while they work properly for *constraints and bound argument

3 participants