Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion mypy/partially_defined.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,11 +206,13 @@ def __init__(self) -> None:
# disable_branch_skip is used to disable skipping a branch due to a return/raise/etc. This is useful
# in things like try/except/finally statements.
self.disable_branch_skip = False
self.in_finally = False

def copy(self) -> DefinedVariableTracker:
result = DefinedVariableTracker()
result.scopes = [s.copy() for s in self.scopes]
result.disable_branch_skip = self.disable_branch_skip
result.in_finally = self.in_finally
return result

def _scope(self) -> Scope:
Expand Down Expand Up @@ -579,7 +581,9 @@ def process_try_stmt(self, o: TryStmt) -> None:
self.tracker.end_branch_statement()

if o.finally_body is not None:
self.tracker.in_finally = True
o.finally_body.accept(self)
self.tracker.in_finally = False

def visit_while_stmt(self, o: WhileStmt) -> None:
o.expr.accept(self)
Expand Down Expand Up @@ -620,7 +624,10 @@ def visit_starred_pattern(self, o: StarredPattern) -> None:
def visit_name_expr(self, o: NameExpr) -> None:
if o.name in self.builtins and self.tracker.in_scope(ScopeType.Global):
return
if self.tracker.is_possibly_undefined(o.name):
if (
self.tracker.is_possibly_undefined(o.name)
and self.tracker.in_finally == self.tracker.disable_branch_skip
):
# A variable is only defined in some branches.
self.variable_may_be_undefined(o.name, o)
# We don't want to report the error on the same variable multiple times.
Expand Down
15 changes: 13 additions & 2 deletions test-data/unit/check-possibly-undefined.test
Original file line number Diff line number Diff line change
Expand Up @@ -628,7 +628,7 @@ def f7() -> int:
x = 1
assert False
except:
pass
y = x # E: Name "x" may be undefined
return x # E: Name "x" may be undefined
[builtins fixtures/exception.pyi]

Expand Down Expand Up @@ -678,7 +678,7 @@ def f3() -> int:
pass
finally:
y = x # E: Name "x" may be undefined
return x
return x # E: Name "x" may be undefined

def f4() -> int:
try:
Expand Down Expand Up @@ -708,6 +708,17 @@ def f6() -> int:
finally:
a = x # E: Name "x" may be undefined
return a

def f7() -> int:
try:
if int():
x = 1
else:
raise BaseException
return x # No error.
finally:
y = x # E: Name "x" may be undefined
return 0
[builtins fixtures/exception.pyi]

[case testTryElse]
Expand Down