Skip to content

Commit d70a727

Browse files
committed
much softer approach
1 parent 5891413 commit d70a727

File tree

3 files changed

+11
-20
lines changed

3 files changed

+11
-20
lines changed

mypy/binder.py

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
from mypy.literals import Key, literal, literal_hash, subkeys
1111
from mypy.nodes import Expression, IndexExpr, MemberExpr, NameExpr, RefExpr, TypeInfo, Var
1212
from mypy.subtypes import is_same_type, is_subtype
13-
from mypy.typeops import make_simplified_union
1413
from mypy.types import (
1514
AnyType,
1615
Instance,
@@ -238,22 +237,8 @@ def update_from_options(self, frames: list[Frame]) -> bool:
238237
type = AnyType(TypeOfAny.from_another_any, source_any=declaration_type)
239238
else:
240239
for other in resulting_values[1:]:
241-
242240
assert other is not None
243-
244-
if (
245-
isinstance(t1 := get_proper_type(type), TupleType)
246-
and isinstance(t2 := get_proper_type(other.type), TupleType)
247-
and (len(l1 := t1.items) == len(l2 := t2.items))
248-
and (find_unpack_in_list(l1) is None)
249-
and (find_unpack_in_list(l2) is None)
250-
):
251-
type = t1.copy_modified(
252-
items=[make_simplified_union([i1, i2]) for i1, i2 in zip(l1, l2)]
253-
)
254-
else:
255-
type = make_simplified_union([type, other.type])
256-
241+
type = join_simple(self.declarations[key], type, other.type)
257242
# Try simplifying resulting type for unions involving variadic tuples.
258243
# Technically, everything is still valid without this step, but if we do
259244
# not do this, this may create long unions after exiting an if check like:

mypy/join.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
is_protocol_implementation,
1818
is_subtype,
1919
)
20+
from mypy.typeops import make_simplified_union
2021
from mypy.types import (
2122
AnyType,
2223
CallableType,
@@ -54,7 +55,8 @@
5455

5556

5657
class InstanceJoiner:
57-
def __init__(self) -> None:
58+
def __init__(self, prefer_union_over_supertype: bool = False) -> None:
59+
self.prefer_union_over_supertype: bool = prefer_union_over_supertype
5860
self.seen_instances: list[tuple[Instance, Instance]] = []
5961

6062
def join_instances(self, t: Instance, s: Instance) -> ProperType:
@@ -164,6 +166,9 @@ def join_instances_via_supertype(self, t: Instance, s: Instance) -> ProperType:
164166
if is_subtype(p, t):
165167
return join_types(t, p, self)
166168

169+
if self.prefer_union_over_supertype:
170+
return make_simplified_union([t, s])
171+
167172
# Compute the "best" supertype of t when joined with s.
168173
# The definition of "best" may evolve; for now it is the one with
169174
# the longest MRO. Ties are broken by using the earlier base.
@@ -224,7 +229,9 @@ def join_simple(declaration: Type | None, s: Type, t: Type) -> ProperType:
224229
if isinstance(s, UnionType) and not isinstance(t, UnionType):
225230
s, t = t, s
226231

227-
value = t.accept(TypeJoinVisitor(s))
232+
value = t.accept(
233+
TypeJoinVisitor(s, instance_joiner=InstanceJoiner(prefer_union_over_supertype=True))
234+
)
228235
if declaration is None or is_subtype(value, declaration):
229236
return value
230237

test-data/unit/check-narrowing.test

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2353,8 +2353,7 @@ def fn_while(arg: T) -> None:
23532353
return None
23542354
[builtins fixtures/primitives.pyi]
23552355

2356-
2357-
[case testNarrowingIsinstanceCreatesUnion]
2356+
[case testNarrowingInstancesCreatesUnion]
23582357

23592358
class A: ...
23602359
class B(A): y: int

0 commit comments

Comments
 (0)