From 91b6fc32322d89c0c171090ad1c6beac467832ed Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Fri, 4 Nov 2022 16:03:33 +0000 Subject: [PATCH] Fix crash on nested unions in recursive types (#14007) Fixes #14000 This will introduce some minor perf penalty, but only for code that actually uses recursive types. --- mypy/typeops.py | 4 ++-- test-data/unit/check-recursive-types.test | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/mypy/typeops.py b/mypy/typeops.py index 7eb1a67b46ea..5b29dc71991b 100644 --- a/mypy/typeops.py +++ b/mypy/typeops.py @@ -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 ) diff --git a/test-data/unit/check-recursive-types.test b/test-data/unit/check-recursive-types.test index a0875c60362c..0d727b109658 100644 --- a/test-data/unit/check-recursive-types.test +++ b/test-data/unit/check-recursive-types.test @@ -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]