From b468db0d308fc8e7108de05070f9ab988f1b0690 Mon Sep 17 00:00:00 2001 From: George Ogden Date: Fri, 16 Jan 2026 21:57:26 +0000 Subject: [PATCH 1/2] Add failing type narrowing test cases --- test-data/unit/check-isinstance.test | 63 +++++++++++++++++++++++++++- test-data/unit/check-narrowing.test | 2 +- 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/test-data/unit/check-isinstance.test b/test-data/unit/check-isinstance.test index 89d07a6b03c6..3a9b7051ecc5 100644 --- a/test-data/unit/check-isinstance.test +++ b/test-data/unit/check-isinstance.test @@ -2716,6 +2716,10 @@ if type(x) == type(y) == int: reveal_type(y) # N: Revealed type is "builtins.int" reveal_type(x) # N: Revealed type is "builtins.int" +z: Any +if int == type(z) == int: + reveal_type(z) # N: Revealed type is "builtins.int" + [case testTypeEqualsCheckUsingIs] from typing import Any @@ -2723,6 +2727,61 @@ y: Any if type(y) is int: reveal_type(y) # N: Revealed type is "builtins.int" +[case testTypeEqualsCheckUsingImplicitTypes] +from typing import Any + +x: str +y: Any +z: object +if type(y) is type(x): + reveal_type(x) # N: Revealed type is "builtins.str" + reveal_type(y) # N: Revealed type is "builtins.str" + +if type(x) is type(z): + reveal_type(x) # N: Revealed type is "builtins.str" + reveal_type(z) # N: Revealed type is "builtins.str" + +[case testTypeEqualsCheckUsingDifferentSpecializedTypes] +from collections import defaultdict + +x: defaultdict +y: dict +z: object +if type(x) is type(y) is type(z): + reveal_type(x) # N: Revealed type is "collections.defaultdict[Any, Any]" + reveal_type(y) # N: Revealed type is "collections.defaultdict[Any, Any]" + reveal_type(z) # N: Revealed type is "collections.defaultdict[Any, Any]" + +[case testUnionTypeEquality] +from typing import Any, reveal_type +# flags: --warn-unreachable + +x: Any = () +if type(x) == (int, str): + reveal_type(x) # E: Statement is unreachable + +[builtins fixtures/tuple.pyi] + +[case testTypeIntersectionWithConcreteTypes] +class X: x = 1 +class Y: y = 1 +class Z(X, Y): ... + +z = Z() +x: X = z +y: Y = z +if type(x) is type(y): + reveal_type(x) # N: Revealed type is "__main__." + reveal_type(y) # N: Revealed type is "__main__." + x.y + y.x + +if isinstance(x, type(y)) and isinstance(y, type(x)): + reveal_type(x) # N: Revealed type is "__main__." + reveal_type(y) # N: Revealed type is "__main__." + x.y + y.x + +[builtins fixtures/isinstance.pyi] + [case testTypeEqualsCheckUsingIsNonOverlapping] # flags: --warn-unreachable from typing import Union @@ -2732,7 +2791,6 @@ if type(y) is int: # E: Subclass of "str" and "int" cannot exist: would have in y # E: Statement is unreachable else: reveal_type(y) # N: Revealed type is "builtins.str" -[builtins fixtures/isinstance.pyi] [case testTypeEqualsCheckUsingIsNonOverlappingChild-xfail] # flags: --warn-unreachable @@ -2762,12 +2820,13 @@ else: [case testTypeEqualsMultipleTypesShouldntNarrow] # flags: --warn-unreachable # make sure we don't do any narrowing if there are multiple types being compared +# flags: --warn-unreachable from typing import Union x: Union[int, str] if type(x) == int == str: - reveal_type(x) # N: Revealed type is "builtins.int | builtins.str" + reveal_type(x) # E: Statement is unreachable else: reveal_type(x) # N: Revealed type is "builtins.int | builtins.str" diff --git a/test-data/unit/check-narrowing.test b/test-data/unit/check-narrowing.test index 237271558ac6..adfbe842e2ce 100644 --- a/test-data/unit/check-narrowing.test +++ b/test-data/unit/check-narrowing.test @@ -1262,7 +1262,7 @@ def f(t: Type[C]) -> None: if type(t) is M: reveal_type(t) # N: Revealed type is "type[__main__.C]" else: - reveal_type(t) # N: Revealed type is "type[__main__.C]" + reveal_type(t) # N: Revealed type is "type[__main__.C]" if type(t) is not M: reveal_type(t) # N: Revealed type is "type[__main__.C]" else: From f76e174e596507076daca93e67bfe34d4357e050 Mon Sep 17 00:00:00 2001 From: George Ogden Date: Fri, 16 Jan 2026 21:44:46 +0000 Subject: [PATCH 2/2] Mark failing tests with xfail --- test-data/unit/check-isinstance.test | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test-data/unit/check-isinstance.test b/test-data/unit/check-isinstance.test index 3a9b7051ecc5..e720baa0f131 100644 --- a/test-data/unit/check-isinstance.test +++ b/test-data/unit/check-isinstance.test @@ -2707,7 +2707,7 @@ if type(y) == int: reveal_type(y) # N: Revealed type is "builtins.int" -[case testMultipleTypeEqualsCheck] +[case testMultipleTypeEqualsCheck-xfail] from typing import Any x: Any @@ -2727,7 +2727,7 @@ y: Any if type(y) is int: reveal_type(y) # N: Revealed type is "builtins.int" -[case testTypeEqualsCheckUsingImplicitTypes] +[case testTypeEqualsCheckUsingImplicitTypes-xfail] from typing import Any x: str @@ -2741,7 +2741,7 @@ if type(x) is type(z): reveal_type(x) # N: Revealed type is "builtins.str" reveal_type(z) # N: Revealed type is "builtins.str" -[case testTypeEqualsCheckUsingDifferentSpecializedTypes] +[case testTypeEqualsCheckUsingDifferentSpecializedTypes-xfail] from collections import defaultdict x: defaultdict @@ -2752,7 +2752,7 @@ if type(x) is type(y) is type(z): reveal_type(y) # N: Revealed type is "collections.defaultdict[Any, Any]" reveal_type(z) # N: Revealed type is "collections.defaultdict[Any, Any]" -[case testUnionTypeEquality] +[case testUnionTypeEquality-xfail] from typing import Any, reveal_type # flags: --warn-unreachable @@ -2762,7 +2762,7 @@ if type(x) == (int, str): [builtins fixtures/tuple.pyi] -[case testTypeIntersectionWithConcreteTypes] +[case testTypeIntersectionWithConcreteTypes-xfail] class X: x = 1 class Y: y = 1 class Z(X, Y): ... @@ -2782,7 +2782,7 @@ if isinstance(x, type(y)) and isinstance(y, type(x)): [builtins fixtures/isinstance.pyi] -[case testTypeEqualsCheckUsingIsNonOverlapping] +[case testTypeEqualsCheckUsingIsNonOverlapping-xfail] # flags: --warn-unreachable from typing import Union @@ -2817,7 +2817,7 @@ if type(x) is int: else: reveal_type(x) # N: Revealed type is "builtins.int | builtins.str" -[case testTypeEqualsMultipleTypesShouldntNarrow] +[case testTypeEqualsMultipleTypesShouldntNarrow-xfail] # flags: --warn-unreachable # make sure we don't do any narrowing if there are multiple types being compared # flags: --warn-unreachable