Skip to content

Commit e36fcf4

Browse files
committed
tmp
1 parent e5cd1f9 commit e36fcf4

3 files changed

Lines changed: 30 additions & 9 deletions

File tree

mypy/checker.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8625,15 +8625,16 @@ def and_conditional_maps(m1: TypeMap, m2: TypeMap, *, use_meet: bool = False) ->
86258625
the truth of e2.
86268626
"""
86278627
# Both conditions can be true; combine the information. Anything
8628-
# we learn from either conditions' truth is valid. If the same
8629-
# expression's type is refined by both conditions, we somewhat
8630-
# arbitrarily give precedence to m2 unless m1 value is Any.
8631-
# In the future, we could use an intersection type or meet_types().
8628+
# we learn from either conditions' truth is valid.
8629+
# If the same expression's type is refined by both conditions and use_meet=False, we somewhat
8630+
# arbitrarily give precedence to m2 unless m2's value is Any or Never.
86328631
result = m2.copy()
8633-
m2_keys = {literal_hash(n2) for n2 in m2}
8632+
m2_exprs = {literal_hash(n2): n2 for n2 in m2}
86348633
for n1 in m1:
8635-
if literal_hash(n1) not in m2_keys or isinstance(
8636-
get_proper_type(m1[n1]), (AnyType, UninhabitedType)
8634+
n1_hash = literal_hash(n1)
8635+
if n1_hash not in m2_exprs or (
8636+
not use_meet
8637+
and isinstance(get_proper_type(m2[m2_exprs[n1_hash]]), (AnyType, UninhabitedType))
86378638
):
86388639
result[n1] = m1[n1]
86398640
if use_meet:

test-data/unit/check-isinstance.test

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,26 @@ if int():
127127
reveal_type(x) # N: Revealed type is "Any"
128128
reveal_type(x) # N: Revealed type is "__main__.A"
129129

130+
[case testIsinstanceNarrowingAfterAnyCondition]
131+
from typing import Any
132+
133+
class A: pass
134+
class B(A): pass
135+
class Foo: pass
136+
137+
value: Any
138+
if isinstance(value, A) and not isinstance(value, B):
139+
reveal_type(value) # N: Revealed type is "__main__.A"
140+
if not isinstance(value, B) and isinstance(value, A):
141+
reveal_type(value) # N: Revealed type is "__main__.A"
142+
143+
x: Any
144+
if x and isinstance(x, Foo):
145+
reveal_type(x) # N: Revealed type is "__main__.Foo"
146+
if isinstance(x, Foo) and x:
147+
reveal_type(x) # N: Revealed type is "__main__.Foo"
148+
[builtins fixtures/isinstance.pyi]
149+
130150
[case testSingleMultiAssignment]
131151
# flags: --warn-unreachable
132152
x = 'a'

test-data/unit/check-narrowing.test

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1727,7 +1727,7 @@ reveal_type(c) # N: Revealed type is "__main__.C"
17271727

17281728
c1: C
17291729
if isinstance(c1, tp) and isinstance(c1, D):
1730-
reveal_type(c1) # N: Revealed type is "Any"
1730+
reveal_type(c1) # N: Revealed type is "__main__.D"
17311731
else:
17321732
reveal_type(c1) # N: Revealed type is "__main__.C"
17331733
reveal_type(c1) # N: Revealed type is "__main__.C"
@@ -1741,7 +1741,7 @@ reveal_type(c2) # N: Revealed type is "__main__.C"
17411741

17421742
c3: C
17431743
if isinstance(c3, D) and isinstance(c3, tp):
1744-
reveal_type(c3) # N: Revealed type is "Any"
1744+
reveal_type(c3) # N: Revealed type is "__main__.D"
17451745
else:
17461746
reveal_type(c3) # N: Revealed type is "__main__.C"
17471747
reveal_type(c3) # N: Revealed type is "__main__.C"

0 commit comments

Comments
 (0)