Skip to content

Commit

Permalink
Fix false-positive 'used-before-assignment' for assignments in except…
Browse files Browse the repository at this point in the history
… blocks following try blocks that return (#5506)
  • Loading branch information
jacobtylerwalls committed Dec 13, 2021
1 parent e3e5aeb commit 35254c2
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 7 deletions.
12 changes: 9 additions & 3 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,21 @@ Release date: TBA
..
Put new features here and also in 'doc/whatsnew/2.13.rst'

* ``used-before-assignment`` now considers that assignments in a try block
may not have occurred when the except or finally blocks are executed.

Closes #85, #2615

* ``used-before-assignment`` now assumes that assignments in except blocks
may not have occurred and warns accordingly.

Closes #4761

* ``used-before-assignment`` now considers that assignments in a try block
may not have occurred when the except or finally blocks are executed.
* When evaluating statements after an except block, ``used-before-assignment``
assumes that assignments in the except blocks took place if the
corresponding try block contained a return statement.

Closes #85, #2615
Closes #5500

* ``used-before-assignment`` now checks names in try blocks.

Expand Down
12 changes: 9 additions & 3 deletions doc/whatsnew/2.13.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,21 @@ Other Changes

Closes #5323

* ``used-before-assignment`` now considers that assignments in a try block
may not have occurred when the except or finally blocks are executed.

Closes #85, #2615

* ``used-before-assignment`` now assumes that assignments in except blocks
may not have occurred and warns accordingly.

Closes #4761

* ``used-before-assignment`` now considers that assignments in a try block
may not have occurred when the except or finally blocks are executed.
* When evaluating statements after an except block, ``used-before-assignment``
assumes that assignments in the except blocks took place if the
corresponding try block contained a return statement.

Closes #85, #2615
Closes #5500

* ``used-before-assignment`` now checks names in try blocks.

Expand Down
22 changes: 21 additions & 1 deletion pylint/checkers/variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,8 @@ def _has_locals_call_after_node(stmt, scope):
"Emitted when a local variable is accessed before its assignment took place. "
"Assignments in try blocks are assumed not to have occurred when evaluating "
"associated except/finally blocks. Assignments in except blocks are assumed "
"not to have occurred when evaluating statements outside the block.",
"not to have occurred when evaluating statements outside the block, except "
"when the associated try block contains a return statement.",
),
"E0602": (
"Undefined variable %r",
Expand Down Expand Up @@ -656,6 +657,25 @@ def get_next_to_consume(self, node):
and isinstance(
n.statement(future=True).parent.parent, nodes.TryExcept
)
# If the try block returns we assume that assignments in the except
# handlers could have happened.
and (
not any(
isinstance(try_statement, nodes.Return)
for try_statement in n.statement(
future=True
).parent.parent.body
)
# But not if this node is in the final block, which will
# execute before the return.
or (
isinstance(node_statement.parent, nodes.TryFinally)
and node_statement in node_statement.parent.finalbody
and n.statement(future=True).parent.parent.parent.parent_of(
node_statement
)
)
)
)
or n.statement(future=True).parent.parent_of(node)
]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"""Tests for used-before-assignment with assignments in except handlers after
try blocks with return statements.
See: https://github.com/PyCQA/pylint/issues/5500.
"""
def function():
"""Assume except blocks execute if the try block returns."""
try:
success_message = "success message"
return success_message
except ValueError:
failure_message = "failure message"
finally:
print(failure_message) # [used-before-assignment]

return failure_message
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
used-before-assignment:13:14:13:29:function:Using variable 'failure_message' before assignment:UNDEFINED

0 comments on commit 35254c2

Please sign in to comment.