Skip to content

Commit 7438158

Browse files
Fix recursion issue with nested instances and unions (#9663)
* Fix recursion issue with nested instances and unions * Change to use `==` in `is_protocol_implementation` * Add test that verifies Union[a, b] == Union[b, a] Co-authored-by: Shantanu <[email protected]>
1 parent 082c937 commit 7438158

File tree

3 files changed

+100
-2
lines changed

3 files changed

+100
-2
lines changed

mypy/subtypes.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -547,8 +547,7 @@ def f(self) -> A: ...
547547
return False
548548
assuming = right.type.assuming_proper if proper_subtype else right.type.assuming
549549
for (l, r) in reversed(assuming):
550-
if (mypy.sametypes.is_same_type(l, left)
551-
and mypy.sametypes.is_same_type(r, right)):
550+
if l == left and r == right:
552551
return True
553552
with pop_on_exit(assuming, left, right):
554553
for member in right.type.protocol_members:

mypy/test/testtypes.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,6 +1055,7 @@ def setUp(self) -> None:
10551055
self.fx = TypeFixture()
10561056

10571057
def test_literal_type(self) -> None:
1058+
a = self.fx.a
10581059
b = self.fx.b # Reminder: b is a subclass of a
10591060

10601061
lit1 = self.fx.lit1
@@ -1064,6 +1065,7 @@ def test_literal_type(self) -> None:
10641065
self.assert_same(lit1, lit1)
10651066
self.assert_same(UnionType([lit1, lit2]), UnionType([lit1, lit2]))
10661067
self.assert_same(UnionType([lit1, lit2]), UnionType([lit2, lit1]))
1068+
self.assert_same(UnionType([a, b]), UnionType([b, a]))
10671069
self.assert_not_same(lit1, b)
10681070
self.assert_not_same(lit1, lit2)
10691071
self.assert_not_same(lit1, lit3)

test-data/unit/check-unions.test

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,3 +1059,100 @@ x: Union[None, Any]
10591059
y: Union[int, None]
10601060
reveal_type(f(x, y)) # N: Revealed type is "Union[None, Any, builtins.int]"
10611061
reveal_type(f(y, x)) # N: Revealed type is "Union[builtins.int, None, Any]"
1062+
1063+
[case testNestedProtocolUnions]
1064+
from typing import Union, Iterator, Iterable
1065+
def foo(
1066+
values: Union[
1067+
Iterator[Union[
1068+
Iterator[Union[Iterator[int], Iterable[int]]],
1069+
Iterable[Union[Iterator[int], Iterable[int]]],
1070+
]],
1071+
Iterable[Union[
1072+
Iterator[Union[Iterator[int], Iterable[int]]],
1073+
Iterable[Union[Iterator[int], Iterable[int]]],
1074+
]],
1075+
]
1076+
) -> Iterator[int]:
1077+
for i in values:
1078+
for j in i:
1079+
for k in j:
1080+
yield k
1081+
foo([[[1]]])
1082+
[builtins fixtures/list.pyi]
1083+
1084+
[case testNestedProtocolGenericUnions]
1085+
from typing import Union, Iterator, List
1086+
def foo(
1087+
values: Union[
1088+
Iterator[Union[
1089+
Iterator[Union[Iterator[int], List[int]]],
1090+
List[Union[Iterator[int], List[int]]],
1091+
]],
1092+
List[Union[
1093+
Iterator[Union[Iterator[int], List[int]]],
1094+
List[Union[Iterator[int], List[int]]],
1095+
]],
1096+
]
1097+
) -> Iterator[int]:
1098+
for i in values:
1099+
for j in i:
1100+
for k in j:
1101+
yield k
1102+
foo([[[1]]])
1103+
[builtins fixtures/list.pyi]
1104+
1105+
[case testNestedProtocolGenericUnionsDeep]
1106+
from typing import TypeVar, Union, Iterator, List
1107+
T = TypeVar("T")
1108+
Iter = Union[Iterator[T], List[T]]
1109+
def foo(
1110+
values: Iter[Iter[Iter[Iter[Iter[int]]]]],
1111+
) -> Iterator[int]:
1112+
for i in values:
1113+
for j in i:
1114+
for k in j:
1115+
for l in k:
1116+
for m in l:
1117+
yield m
1118+
foo([[[[[1]]]]])
1119+
[builtins fixtures/list.pyi]
1120+
1121+
[case testNestedInstanceUnsimplifiedUnion]
1122+
from typing import TypeVar, Union, Iterator, List, Any
1123+
T = TypeVar("T")
1124+
1125+
Iter = Union[Iterator[T], List[T]]
1126+
def foo(
1127+
values: Iter[Union[Any, Any]],
1128+
) -> Iterator[Any]:
1129+
for i in values:
1130+
yield i
1131+
foo([1])
1132+
[builtins fixtures/list.pyi]
1133+
1134+
[case testNestedInstanceTypeAlias]
1135+
from typing import TypeVar, Union, Iterator, List, Any
1136+
T = TypeVar("T")
1137+
1138+
Iter = Union[Iterator[T], List[T]]
1139+
def foo(
1140+
values: Iter["Any"],
1141+
) -> Iterator[Any]:
1142+
for i in values:
1143+
yield i
1144+
foo([1])
1145+
[builtins fixtures/list.pyi]
1146+
1147+
[case testNestedInstanceTypeAliasUnsimplifiedUnion]
1148+
from typing import TypeVar, Union, Iterator, List, Any
1149+
T = TypeVar("T")
1150+
1151+
Iter = Union[Iterator[T], List[T]]
1152+
def foo(
1153+
values: Iter["Union[Any, Any]"],
1154+
) -> Iterator[Any]:
1155+
for i in values:
1156+
yield i
1157+
foo([1])
1158+
[builtins fixtures/list.pyi]

0 commit comments

Comments
 (0)