Skip to content

Commit

Permalink
Fix crash on nested unions in recursive types (#14007)
Browse files Browse the repository at this point in the history
Fixes #14000 

This will introduce some minor perf penalty, but only for code that
actually uses recursive types.
  • Loading branch information
ilevkivskyi authored and svalentin committed Nov 7, 2022
1 parent 42a4c69 commit 91b6fc3
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 2 deletions.
4 changes: 2 additions & 2 deletions mypy/typeops.py
Expand Up @@ -71,13 +71,13 @@ def is_recursive_pair(s: Type, t: Type) -> bool:
"""
if isinstance(s, TypeAliasType) and s.is_recursive:
return (
isinstance(get_proper_type(t), Instance)
isinstance(get_proper_type(t), (Instance, UnionType))
or isinstance(t, TypeAliasType)
and t.is_recursive
)
if isinstance(t, TypeAliasType) and t.is_recursive:
return (
isinstance(get_proper_type(s), Instance)
isinstance(get_proper_type(s), (Instance, UnionType))
or isinstance(s, TypeAliasType)
and s.is_recursive
)
Expand Down
18 changes: 18 additions & 0 deletions test-data/unit/check-recursive-types.test
Expand Up @@ -808,3 +808,21 @@ def test2() -> Tree2:
def test3() -> Tree3:
return 42 # E: Incompatible return value type (got "int", expected "Union[str, Tuple[Tree3, Tree3, Tree3]]")
[builtins fixtures/tuple.pyi]

[case testRecursiveDoubleUnionNoCrash]
from typing import Tuple, Union, Callable, Sequence

K = Union[int, Tuple[Union[int, K]]]
L = Union[int, Callable[[], Union[int, L]]]
M = Union[int, Sequence[Union[int, M]]]

x: K
x = x
y: L
y = y
z: M
z = z

x = y # E: Incompatible types in assignment (expression has type "L", variable has type "K")
z = x # OK
[builtins fixtures/tuple.pyi]

0 comments on commit 91b6fc3

Please sign in to comment.