Skip to content

Commit

Permalink
[used-before-assignment] Fix FP for try/else/continue (#9374)
Browse files Browse the repository at this point in the history
  • Loading branch information
jacobtylerwalls committed Jan 22, 2024
1 parent 81bd39a commit 7d0c7ac
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 0 deletions.
5 changes: 5 additions & 0 deletions doc/whatsnew/fragments/6804.false_positive
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
``used-before-assignment`` is no longer emitted when using a name in a loop and
depending on an earlier name assignment in an ``except`` block paired with
``else: continue``.

Closes #6804
10 changes: 10 additions & 0 deletions pylint/checkers/variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -883,6 +883,16 @@ def _uncertain_nodes_in_except_blocks(
and utils.is_terminating_func(else_statement.value)
for else_statement in closest_try_except.orelse
)
else_block_continues = any(
isinstance(else_statement, nodes.Continue)
for else_statement in closest_try_except.orelse
)
if (
else_block_continues
and isinstance(node_statement.parent, (nodes.For, nodes.While))
and closest_try_except.parent.parent_of(node_statement)
):
continue

if try_block_returns or else_block_returns or else_block_exits:
# Exception: if this node is in the final block of the other_node_statement,
Expand Down
42 changes: 42 additions & 0 deletions tests/functional/u/used/used_before_assignment_else_continue.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"""If the else block continues, it is generally safe to rely on assignments in the except,
inside the same for loop only."""


def safe():
"""Name used safely inside the loop."""
while True:
try:
pass
except ValueError:
error = True
else:
continue

print(error)


def halfway_safe():
"""Name used safely inside the loop, unsafely outside it."""
for _temp in range(0, 1):
try:
pass
except ValueError:
error = True
else:
continue

print(error)
print(error) # https://github.com/pylint-dev/pylint/issues/9379


def unsafe():
"""Name used unsafely outside the loop."""
for _temp in range(0, 1):
try:
pass
except ValueError:
error = True
else:
continue

print(error) # [used-before-assignment]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
used-before-assignment:42:10:42:15:unsafe:Using variable 'error' before assignment:CONTROL_FLOW

0 comments on commit 7d0c7ac

Please sign in to comment.