Skip to content

Commit 103f5f3

Browse files
authored
Disable promotions when restricting types in isinstance checks (#6142)
This fixes a bug left behind by #6114, where too much would get subtracted out of a union type after an isinstance. Fixes #6141.
1 parent 49ad7de commit 103f5f3

File tree

3 files changed

+9
-4
lines changed

3 files changed

+9
-4
lines changed

mypy/checker.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -3764,7 +3764,8 @@ def conditional_type_map(expr: Expression,
37643764
proposed_precise_type = UnionType([type_range.item
37653765
for type_range in proposed_type_ranges
37663766
if not type_range.is_upper_bound])
3767-
remaining_type = restrict_subtype_away(current_type, proposed_precise_type)
3767+
remaining_type = restrict_subtype_away(current_type, proposed_precise_type,
3768+
ignore_promotions=True)
37683769
return {expr: proposed_type}, {expr: remaining_type}
37693770
else:
37703771
return {expr: proposed_type}, {}

mypy/subtypes.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -997,7 +997,7 @@ def unify_generic_callable(type: CallableType, target: CallableType,
997997
return applied
998998

999999

1000-
def restrict_subtype_away(t: Type, s: Type) -> Type:
1000+
def restrict_subtype_away(t: Type, s: Type, *, ignore_promotions: bool = False) -> Type:
10011001
"""Return t minus s.
10021002
10031003
If we can't determine a precise result, return a supertype of the
@@ -1014,8 +1014,10 @@ def restrict_subtype_away(t: Type, s: Type) -> Type:
10141014
# TODO: Implement more robust support for runtime isinstance() checks,
10151015
# see issue #3827
10161016
new_items = [item for item in t.relevant_items()
1017-
if (not (is_proper_subtype(erase_type(item), erased_s) or
1018-
is_proper_subtype(item, erased_s))
1017+
if (not (is_proper_subtype(erase_type(item), erased_s,
1018+
ignore_promotions=ignore_promotions) or
1019+
is_proper_subtype(item, erased_s,
1020+
ignore_promotions=ignore_promotions))
10191021
or isinstance(item, AnyType))]
10201022
return UnionType.make_union(new_items)
10211023
else:

test-data/unit/check-isinstance.test

+2
Original file line numberDiff line numberDiff line change
@@ -1323,6 +1323,8 @@ def f1(x: Union[float, int]) -> None:
13231323
# We ignore promotions in isinstance checks
13241324
if isinstance(x, float):
13251325
reveal_type(x) # E: Revealed type is 'builtins.float'
1326+
else:
1327+
reveal_type(x) # E: Revealed type is 'builtins.int'
13261328

13271329
def f2(x: Union[FloatLike, IntLike]) -> None:
13281330
# ...but not regular subtyping relationships

0 commit comments

Comments
 (0)