Skip to content

Commit

Permalink
Fix crash on joins with recursive tuples (#15402)
Browse files Browse the repository at this point in the history
Fixes #15351

This may have some perf impact, but I predict it will be minimal (and I
didn't notice anything locally).
  • Loading branch information
ilevkivskyi authored Jun 9, 2023
1 parent 4baf672 commit 3e982a0
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 0 deletions.
6 changes: 6 additions & 0 deletions mypy/typeops.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,18 @@ def is_recursive_pair(s: Type, t: Type) -> bool:
isinstance(get_proper_type(t), (Instance, UnionType))
or isinstance(t, TypeAliasType)
and t.is_recursive
# Tuple types are special, they can cause an infinite recursion even if
# the other type is not recursive, because of the tuple fallback that is
# calculated "on the fly".
or isinstance(get_proper_type(s), TupleType)
)
if isinstance(t, TypeAliasType) and t.is_recursive:
return (
isinstance(get_proper_type(s), (Instance, UnionType))
or isinstance(s, TypeAliasType)
and s.is_recursive
# Same as above.
or isinstance(get_proper_type(t), TupleType)
)
return False

Expand Down
9 changes: 9 additions & 0 deletions test-data/unit/check-recursive-types.test
Original file line number Diff line number Diff line change
Expand Up @@ -937,3 +937,12 @@ x: A[int, str]
if last is not None:
reveal_type(last) # N: Revealed type is "Tuple[builtins.int, builtins.str, Union[Tuple[builtins.int, builtins.str, Union[..., None]], None]]"
[builtins fixtures/tuple.pyi]

[case testRecursiveAliasLiteral]
from typing import Tuple
from typing_extensions import Literal

NotFilter = Tuple[Literal["not"], "NotFilter"]
n: NotFilter
reveal_type(n[1][1][0]) # N: Revealed type is "Literal['not']"
[builtins fixtures/tuple.pyi]

0 comments on commit 3e982a0

Please sign in to comment.