Skip to content

Commit 187745a

Browse files
committed
Fix narrowing for unions with Any
Previously we considered the else branch in the test case here unreachable
1 parent 606973f commit 187745a

File tree

2 files changed

+28
-7
lines changed

2 files changed

+28
-7
lines changed

mypy/checker.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8301,21 +8301,27 @@ def conditional_types(
83018301
enum_name = target.fallback.type.fullname
83028302
current_type = try_expanding_sum_type_to_union(current_type, enum_name)
83038303

8304+
proposed_type: Type | None
8305+
remaining_type: Type | None
8306+
83048307
proper_type = get_proper_type(current_type)
83058308
# factorize over union types: isinstance(A|B, C) -> yes = A_yes | B_yes
83068309
if isinstance(proper_type, UnionType):
8307-
result: list[tuple[Type | None, Type | None]] = [
8308-
conditional_types(
8310+
yes_items: list[Type] = []
8311+
no_items: list[Type] = []
8312+
for union_item in proper_type.items:
8313+
yes_type, no_type = conditional_types(
83098314
union_item,
83108315
proposed_type_ranges,
83118316
default=union_item,
83128317
consider_runtime_isinstance=consider_runtime_isinstance,
83138318
)
8314-
for union_item in get_proper_types(proper_type.items)
8315-
]
8316-
# separate list of tuples into two lists
8317-
yes_types, no_types = zip(*result)
8318-
proposed_type = make_simplified_union([t for t in yes_types if t is not None])
8319+
yes_items.append(yes_type)
8320+
no_items.append(no_type)
8321+
8322+
proposed_type = make_simplified_union(yes_items)
8323+
remaining_type = make_simplified_union(no_items)
8324+
return proposed_type, remaining_type
83198325
else:
83208326
proposed_items = [type_range.item for type_range in proposed_type_ranges]
83218327
proposed_type = make_simplified_union(proposed_items)

test-data/unit/check-narrowing.test

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1608,6 +1608,21 @@ else:
16081608
reveal_type(t) # N: Revealed type is "Any"
16091609
[builtins fixtures/isinstancelist.pyi]
16101610

1611+
[case testNarrowingAnyUnion]
1612+
# flags: --strict-equality --warn-unreachable
1613+
from __future__ import annotations
1614+
from unknown import A, AA # E: Cannot find implementation or library stub for module named "unknown" \
1615+
# N: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
1616+
1617+
class B: ...
1618+
1619+
def f(x: A | B) -> None:
1620+
if isinstance(x, (AA, B)):
1621+
reveal_type(x) # N: Revealed type is "Any | __main__.B"
1622+
else:
1623+
reveal_type(x) # N: Revealed type is "Any"
1624+
[builtins fixtures/isinstancelist.pyi]
1625+
16111626
[case testNarrowingLenItemAndLenCompare]
16121627
# flags: --strict-equality --warn-unreachable
16131628
from typing import Any

0 commit comments

Comments
 (0)