Skip to content

Commit 7d0c7ac

Browse files
[used-before-assignment] Fix FP for try/else/continue (#9374)
1 parent 81bd39a commit 7d0c7ac

File tree

4 files changed

+58
-0
lines changed

4 files changed

+58
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
``used-before-assignment`` is no longer emitted when using a name in a loop and
2+
depending on an earlier name assignment in an ``except`` block paired with
3+
``else: continue``.
4+
5+
Closes #6804

pylint/checkers/variables.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -883,6 +883,16 @@ def _uncertain_nodes_in_except_blocks(
883883
and utils.is_terminating_func(else_statement.value)
884884
for else_statement in closest_try_except.orelse
885885
)
886+
else_block_continues = any(
887+
isinstance(else_statement, nodes.Continue)
888+
for else_statement in closest_try_except.orelse
889+
)
890+
if (
891+
else_block_continues
892+
and isinstance(node_statement.parent, (nodes.For, nodes.While))
893+
and closest_try_except.parent.parent_of(node_statement)
894+
):
895+
continue
886896

887897
if try_block_returns or else_block_returns or else_block_exits:
888898
# Exception: if this node is in the final block of the other_node_statement,
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
"""If the else block continues, it is generally safe to rely on assignments in the except,
2+
inside the same for loop only."""
3+
4+
5+
def safe():
6+
"""Name used safely inside the loop."""
7+
while True:
8+
try:
9+
pass
10+
except ValueError:
11+
error = True
12+
else:
13+
continue
14+
15+
print(error)
16+
17+
18+
def halfway_safe():
19+
"""Name used safely inside the loop, unsafely outside it."""
20+
for _temp in range(0, 1):
21+
try:
22+
pass
23+
except ValueError:
24+
error = True
25+
else:
26+
continue
27+
28+
print(error)
29+
print(error) # https://github.com/pylint-dev/pylint/issues/9379
30+
31+
32+
def unsafe():
33+
"""Name used unsafely outside the loop."""
34+
for _temp in range(0, 1):
35+
try:
36+
pass
37+
except ValueError:
38+
error = True
39+
else:
40+
continue
41+
42+
print(error) # [used-before-assignment]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
used-before-assignment:42:10:42:15:unsafe:Using variable 'error' before assignment:CONTROL_FLOW

0 commit comments

Comments
 (0)