From f7069cacaa55bf7163e4cb32e02c861a3bc30d26 Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Fri, 28 Dec 2018 17:05:49 -0800 Subject: [PATCH] Disable promotions in isinstance checks This pull request resolves https://github.com/python/mypy/issues/6060 by modifying `conditional_type_map` function in `checker.py` to ignore promotions. --- mypy/checker.py | 5 +++-- test-data/unit/check-isinstance.test | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/mypy/checker.py b/mypy/checker.py index b88278d3d0ba..6b66875c6f26 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -3756,11 +3756,12 @@ def conditional_type_map(expr: Expression, proposed_type = UnionType([type_range.item for type_range in proposed_type_ranges]) if current_type: if (not any(type_range.is_upper_bound for type_range in proposed_type_ranges) - and is_proper_subtype(current_type, proposed_type)): + and is_proper_subtype(current_type, proposed_type, ignore_promotions=True)): # Expression is always of one of the types in proposed_type_ranges return {}, None elif not is_overlapping_types(current_type, proposed_type, - prohibit_none_typevar_overlap=True): + prohibit_none_typevar_overlap=True, + ignore_promotions=True): # Expression is never of any type in proposed_type_ranges return None, {} else: diff --git a/test-data/unit/check-isinstance.test b/test-data/unit/check-isinstance.test index fc418015ed23..9076ef9aea6b 100644 --- a/test-data/unit/check-isinstance.test +++ b/test-data/unit/check-isinstance.test @@ -1313,6 +1313,23 @@ def f(x: Union[A, B]) -> None: f(x) [builtins fixtures/isinstance.pyi] +[case testIsinstanceWithOverlappingPromotionTypes] +from typing import Union + +class FloatLike: pass +class IntLike(FloatLike): pass + +def f1(x: Union[float, int]) -> None: + # We ignore promotions in isinstance checks + if isinstance(x, float): + reveal_type(x) # E: Revealed type is 'builtins.float' + +def f2(x: Union[FloatLike, IntLike]) -> None: + # ...but not regular subtyping relationships + if isinstance(x, FloatLike): + reveal_type(x) # E: Revealed type is 'Union[__main__.FloatLike, __main__.IntLike]' +[builtins fixtures/isinstance.pyi] + [case testIsinstanceOfSuperclass] class A: pass class B(A): pass