@@ -3018,6 +3018,60 @@ def f2(x: Any) -> None:
30183018 reveal_type(x) # N: Revealed type is "Any"
30193019[builtins fixtures/tuple.pyi]
30203020
3021+ [case testNarrowTypeObject]
3022+ # flags: --strict-equality --warn-unreachable
3023+ from typing import Any
3024+
3025+ # https://github.com/python/mypy/issues/13704
3026+
3027+ def f1(cls: type):
3028+ if cls is str:
3029+ reveal_type(cls) # N: Revealed type is "def (o: builtins.object =) -> builtins.str"
3030+ reveal_type(cls(5)) # N: Revealed type is "builtins.str"
3031+
3032+ if issubclass(cls, int):
3033+ reveal_type(cls) # N: Revealed type is "type[builtins.int]"
3034+ elif cls is str:
3035+ reveal_type(cls) # N: Revealed type is "def (o: builtins.object =) -> builtins.str"
3036+ reveal_type(cls(5)) # N: Revealed type is "builtins.str"
3037+
3038+ def f2(cls: type[object]):
3039+ if cls is str:
3040+ reveal_type(cls) # N: Revealed type is "def (o: builtins.object =) -> builtins.str"
3041+ reveal_type(cls(5)) # N: Revealed type is "builtins.str"
3042+
3043+ if issubclass(cls, int):
3044+ reveal_type(cls) # N: Revealed type is "type[builtins.int]"
3045+ elif cls is str:
3046+ reveal_type(cls) # N: Revealed type is "def (o: builtins.object =) -> builtins.str"
3047+ reveal_type(cls(5)) # N: Revealed type is "builtins.str"
3048+
3049+ def f3(cls: type[Any]):
3050+ if cls is str:
3051+ reveal_type(cls) # N: Revealed type is "type[Any]"
3052+ reveal_type(cls(5)) # N: Revealed type is "Any"
3053+
3054+ if issubclass(cls, int):
3055+ reveal_type(cls) # N: Revealed type is "type[builtins.int]"
3056+ elif cls is str:
3057+ reveal_type(cls) # N: Revealed type is "type[Any]"
3058+ reveal_type(cls(5)) # N: Revealed type is "Any"
3059+ [builtins fixtures/isinstance.pyi]
3060+
3061+ [case testNarrowTypeObjectUnion]
3062+ # flags: --strict-equality --warn-unreachable
3063+ from __future__ import annotations
3064+
3065+ def f4(cls: type[str | int]):
3066+ reveal_type(cls) # N: Revealed type is "type[builtins.str] | type[builtins.int]"
3067+
3068+ if cls is int:
3069+ reveal_type(cls) # N: Revealed type is "type[builtins.int]"
3070+ if cls == int:
3071+ reveal_type(cls) # N: Revealed type is "type[builtins.int]"
3072+ [builtins fixtures/primitives.pyi]
3073+
3074+
30213075[case testTypeEqualsCheck]
30223076# flags: --strict-equality --warn-unreachable
30233077from typing import Any
@@ -3261,3 +3315,23 @@ def bar(y: Any):
32613315 else:
32623316 reveal_type(y) # N: Revealed type is "Any"
32633317[builtins fixtures/dict-full.pyi]
3318+
3319+ [case testNarrowTypeVarType]
3320+ from typing import TypeVar
3321+
3322+ T = TypeVar("T")
3323+
3324+ class A: ...
3325+
3326+ def foo(X: type[T]) -> T:
3327+ if X == A:
3328+ return X()
3329+ raise
3330+
3331+ # It could be nice to make these two test cases consistent, but it would be tricky
3332+ # The above case is much more common in real world code
3333+ def bar(X: type[T]) -> T:
3334+ if X == A:
3335+ return A() # E: Incompatible return value type (got "A", expected "T")
3336+ raise
3337+ [builtins fixtures/type.pyi]
0 commit comments