Skip to content

Commit 91b6fc3

Browse files
ilevkivskyisvalentin
authored andcommitted
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.
1 parent 42a4c69 commit 91b6fc3

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

mypy/typeops.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,13 @@ def is_recursive_pair(s: Type, t: Type) -> bool:
7171
"""
7272
if isinstance(s, TypeAliasType) and s.is_recursive:
7373
return (
74-
isinstance(get_proper_type(t), Instance)
74+
isinstance(get_proper_type(t), (Instance, UnionType))
7575
or isinstance(t, TypeAliasType)
7676
and t.is_recursive
7777
)
7878
if isinstance(t, TypeAliasType) and t.is_recursive:
7979
return (
80-
isinstance(get_proper_type(s), Instance)
80+
isinstance(get_proper_type(s), (Instance, UnionType))
8181
or isinstance(s, TypeAliasType)
8282
and s.is_recursive
8383
)

test-data/unit/check-recursive-types.test

+18
Original file line numberDiff line numberDiff line change
@@ -808,3 +808,21 @@ def test2() -> Tree2:
808808
def test3() -> Tree3:
809809
return 42 # E: Incompatible return value type (got "int", expected "Union[str, Tuple[Tree3, Tree3, Tree3]]")
810810
[builtins fixtures/tuple.pyi]
811+
812+
[case testRecursiveDoubleUnionNoCrash]
813+
from typing import Tuple, Union, Callable, Sequence
814+
815+
K = Union[int, Tuple[Union[int, K]]]
816+
L = Union[int, Callable[[], Union[int, L]]]
817+
M = Union[int, Sequence[Union[int, M]]]
818+
819+
x: K
820+
x = x
821+
y: L
822+
y = y
823+
z: M
824+
z = z
825+
826+
x = y # E: Incompatible types in assignment (expression has type "L", variable has type "K")
827+
z = x # OK
828+
[builtins fixtures/tuple.pyi]

0 commit comments

Comments
 (0)