Skip to content

Commit b17027e

Browse files
Fix TypeGuard/TypeIs being forgotten when semanal defers (#19325)
Fixes #19318 Don't re-analyze `type_is`/`type_guard` if the callable's type was successfully analyzed on a previous semanal pass. After the first successful pass, the return type will have been replaced by `builtins.bool`, so subsequent analysis can't detect `Type{Guard,Is}`.
1 parent b678d9f commit b17027e

File tree

3 files changed

+36
-2
lines changed

3 files changed

+36
-2
lines changed

mypy/typeanal.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,8 +1109,8 @@ def visit_callable_type(
11091109
variables = t.variables
11101110
else:
11111111
variables, _ = self.bind_function_type_variables(t, t)
1112-
type_guard = self.anal_type_guard(t.ret_type)
1113-
type_is = self.anal_type_is(t.ret_type)
1112+
type_guard = self.anal_type_guard(t.ret_type) if t.type_guard is None else t.type_guard
1113+
type_is = self.anal_type_is(t.ret_type) if t.type_is is None else t.type_is
11141114

11151115
arg_kinds = t.arg_kinds
11161116
arg_types = []

test-data/unit/check-typeguard.test

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,3 +813,20 @@ raw_target: object
813813
if isinstance(raw_target, type) and is_xlike(raw_target):
814814
reveal_type(raw_target) # N: Revealed type is "type[__main__.X]"
815815
[builtins fixtures/tuple.pyi]
816+
817+
[case testTypeGuardWithDefer]
818+
from typing import Union
819+
from typing_extensions import TypeGuard
820+
821+
class A: ...
822+
class B: ...
823+
824+
def is_a(x: object) -> TypeGuard[A]:
825+
return defer_not_defined() # E: Name "defer_not_defined" is not defined
826+
827+
def main(x: Union[A, B]) -> None:
828+
if is_a(x):
829+
reveal_type(x) # N: Revealed type is "__main__.A"
830+
else:
831+
reveal_type(x) # N: Revealed type is "Union[__main__.A, __main__.B]"
832+
[builtins fixtures/tuple.pyi]

test-data/unit/check-typeis.test

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,3 +933,20 @@ def main(f: Callable[[], int | Awaitable[int]]) -> None:
933933
else:
934934
reveal_type(f) # N: Revealed type is "def () -> Union[builtins.int, typing.Awaitable[builtins.int]]"
935935
[builtins fixtures/tuple.pyi]
936+
937+
[case testTypeIsWithDefer]
938+
from typing import Union
939+
from typing_extensions import TypeIs
940+
941+
class A: ...
942+
class B: ...
943+
944+
def is_a(x: object) -> TypeIs[A]:
945+
return defer_not_defined() # E: Name "defer_not_defined" is not defined
946+
947+
def main(x: Union[A, B]) -> None:
948+
if is_a(x):
949+
reveal_type(x) # N: Revealed type is "__main__.A"
950+
else:
951+
reveal_type(x) # N: Revealed type is "__main__.B"
952+
[builtins fixtures/tuple.pyi]

0 commit comments

Comments
 (0)