Skip to content

Commit

Permalink
[partially defined] handle unreachable blocks (#14161)
Browse files Browse the repository at this point in the history
This adds support for unreachable blocks in `partially-defined` check.

Currently, this only supports blocks that are detected as unreachable
during semantic analysis (so mostly stuff like python version, etc.).
This doesn't support more advanced cases (see #13926 for an example
what's not covered).

Closes #13929
  • Loading branch information
ilinum authored Nov 22, 2022
1 parent b83ac9c commit 8fb482f
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 1 deletion.
9 changes: 8 additions & 1 deletion mypy/partially_defined.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,13 @@ def visit_if_stmt(self, o: IfStmt) -> None:
e.accept(self)
self.tracker.start_branch_statement()
for b in o.body:
if b.is_unreachable:
continue
b.accept(self)
self.tracker.next_branch()
if o.else_body:
if o.else_body.is_unreachable:
self.tracker.skip_branch()
o.else_body.accept(self)
self.tracker.end_branch_statement()

Expand All @@ -218,7 +222,10 @@ def visit_match_stmt(self, o: MatchStmt) -> None:
guard = o.guards[i]
if guard is not None:
guard.accept(self)
o.bodies[i].accept(self)
if not o.bodies[i].is_unreachable:
o.bodies[i].accept(self)
else:
self.tracker.skip_branch()
is_catchall = infer_pattern_value(pattern) == ALWAYS_TRUE
if not is_catchall:
self.tracker.next_branch()
Expand Down
19 changes: 19 additions & 0 deletions test-data/unit/check-partially-defined.test
Original file line number Diff line number Diff line change
Expand Up @@ -367,3 +367,22 @@ def f() -> None:
d = a
d = b
[builtins fixtures/tuple.pyi]

[case testUnreachable]
# flags: --enable-error-code partially-defined
import typing

if typing.TYPE_CHECKING:
x = 1
elif int():
y = 1
else:
y = 2
a = x

if not typing.TYPE_CHECKING:
pass
else:
z = 1
a = z
[typing fixtures/typing-medium.pyi]
24 changes: 24 additions & 0 deletions test-data/unit/check-python310.test
Original file line number Diff line number Diff line change
Expand Up @@ -1789,6 +1789,30 @@ def f6(a: object) -> None:
pass
[builtins fixtures/tuple.pyi]

[case testPartiallyDefinedMatchUnreachable]
# flags: --enable-error-code partially-defined
import typing

def f0(x: int) -> int:
match x:
case 1 if not typing.TYPE_CHECKING:
pass
case 2:
y = 2
case _:
y = 3
return y # No error.

def f1(x: int) -> int:
match x:
case 1 if not typing.TYPE_CHECKING:
pass
case 2:
y = 2
return y # E: Name "y" may be undefined

[typing fixtures/typing-medium.pyi]

[case testTypeAliasWithNewUnionSyntaxAndNoneLeftOperand]
from typing import overload
class C:
Expand Down

0 comments on commit 8fb482f

Please sign in to comment.