diff --git a/mypy/semanal.py b/mypy/semanal.py index c5b460ebb31b..14630d964b29 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -4020,8 +4020,14 @@ def infer_reachability_of_if_statement(s: IfStmt, mark_block_mypy_only(s.body[i]) for body in s.body[i + 1:]: mark_block_unreachable(body) - if s.else_body: - mark_block_unreachable(s.else_body) + + # Make sure else body always exists and is marked as + # unreachable so the type checker always knows that + # all control flow paths will flow through the if + # statement body. + if not s.else_body: + s.else_body = Block([]) + mark_block_unreachable(s.else_body) break diff --git a/test-data/unit/check-unreachable-code.test b/test-data/unit/check-unreachable-code.test index fa29290dbbf4..acf975b19193 100644 --- a/test-data/unit/check-unreachable-code.test +++ b/test-data/unit/check-unreachable-code.test @@ -517,3 +517,20 @@ else: y = 3 reveal_type(y) # E: Revealed type is 'builtins.str' [builtins fixtures/ops.pyi] + +[case testConditionalAssertWithoutElse] +import typing + +class A: pass +class B(A): pass + +x = A() +reveal_type(x) # E: Revealed type is '__main__.A' + +if typing.TYPE_CHECKING: + assert isinstance(x, B) + reveal_type(x) # E: Revealed type is '__main__.B' + +reveal_type(x) # E: Revealed type is '__main__.B' + +[builtins fixtures/isinstancelist.pyi]