Skip to content

Commit 4d162c3

Browse files
[used-before-assignment] Fix FP under finally block (#9452) (#9453)
Closes #9451 (cherry picked from commit a83e6b9) Co-authored-by: Jacob Walls <[email protected]>
1 parent ce9b7cb commit 4d162c3

File tree

4 files changed

+32
-10
lines changed

4 files changed

+32
-10
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Fix false positive for ``used-before-assignment`` in a ``finally`` block
2+
when assignments took place in both the ``try`` block and each exception handler.
3+
4+
Closes #9451

pylint/checkers/variables.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,7 @@ def get_next_to_consume(self, node: nodes.Name) -> list[nodes.NodeNG] | None:
666666
if found_nodes:
667667
uncertain_nodes = (
668668
self._uncertain_nodes_in_try_blocks_when_evaluating_finally_blocks(
669-
found_nodes, node_statement
669+
found_nodes, node_statement, name
670670
)
671671
)
672672
self.consumed_uncertain[node.name] += uncertain_nodes
@@ -1139,7 +1139,9 @@ def _uncertain_nodes_in_try_blocks_when_evaluating_except_blocks(
11391139

11401140
@staticmethod
11411141
def _uncertain_nodes_in_try_blocks_when_evaluating_finally_blocks(
1142-
found_nodes: list[nodes.NodeNG], node_statement: _base_nodes.Statement
1142+
found_nodes: list[nodes.NodeNG],
1143+
node_statement: _base_nodes.Statement,
1144+
name: str,
11431145
) -> list[nodes.NodeNG]:
11441146
uncertain_nodes: list[nodes.NodeNG] = []
11451147
(
@@ -1186,6 +1188,12 @@ def _uncertain_nodes_in_try_blocks_when_evaluating_finally_blocks(
11861188
)
11871189
):
11881190
continue
1191+
# Is the name defined in all exception clauses?
1192+
if other_node_try_finally_ancestor.handlers and all(
1193+
NamesConsumer._defines_name_raises_or_returns_recursive(name, handler)
1194+
for handler in other_node_try_finally_ancestor.handlers
1195+
):
1196+
continue
11891197
# Passed all tests for uncertain execution
11901198
uncertain_nodes.append(other_node)
11911199
return uncertain_nodes

tests/functional/u/used/used_before_assignment_issue85.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@ def try_except_finally_assignment_in_final_block():
3434
print(res)
3535

3636

37+
def try_except_finally_assignment_in_both_try_and_except():
38+
"""Assignment of the name in both try and except blocks is fine."""
39+
try:
40+
res = 1 / 0
41+
except ZeroDivisionError:
42+
res = 0
43+
finally:
44+
print(res)
45+
46+
3747
def try_except_finally_nested_try_finally_in_try():
3848
"""Don't confuse assignments in different finally statements where
3949
one is nested inside a try.
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
used-before-assignment:8:14:8:17:main:Using variable 'res' before assignment:CONTROL_FLOW
22
used-before-assignment:20:14:20:17:try_except_finally:Using variable 'res' before assignment:CONTROL_FLOW
3-
used-before-assignment:45:18:45:21:try_except_finally_nested_try_finally_in_try:Using variable 'res' before assignment:HIGH
4-
used-before-assignment:70:18:70:29:try_except_finally_nested_in_finally:Using variable 'outer_times' before assignment:CONTROL_FLOW
5-
used-before-assignment:84:18:84:29:try_except_finally_nested_in_finally_2:Using variable 'inner_times' before assignment:CONTROL_FLOW
6-
used-before-assignment:85:14:85:25:try_except_finally_nested_in_finally_2:Using variable 'outer_times' before assignment:CONTROL_FLOW
7-
used-before-assignment:100:18:100:29:try_except_finally_nested_in_finally_3:Using variable 'inner_times' before assignment:CONTROL_FLOW
8-
used-before-assignment:101:18:101:29:try_except_finally_nested_in_finally_3:Using variable 'outer_times' before assignment:CONTROL_FLOW
9-
used-before-assignment:122:22:122:33:try_except_finally_nested_in_finally_4:Using variable 'inner_times' before assignment:CONTROL_FLOW
10-
used-before-assignment:123:22:123:33:try_except_finally_nested_in_finally_4:Using variable 'outer_times' before assignment:CONTROL_FLOW
3+
used-before-assignment:55:18:55:21:try_except_finally_nested_try_finally_in_try:Using variable 'res' before assignment:HIGH
4+
used-before-assignment:80:18:80:29:try_except_finally_nested_in_finally:Using variable 'outer_times' before assignment:CONTROL_FLOW
5+
used-before-assignment:94:18:94:29:try_except_finally_nested_in_finally_2:Using variable 'inner_times' before assignment:CONTROL_FLOW
6+
used-before-assignment:95:14:95:25:try_except_finally_nested_in_finally_2:Using variable 'outer_times' before assignment:CONTROL_FLOW
7+
used-before-assignment:110:18:110:29:try_except_finally_nested_in_finally_3:Using variable 'inner_times' before assignment:CONTROL_FLOW
8+
used-before-assignment:111:18:111:29:try_except_finally_nested_in_finally_3:Using variable 'outer_times' before assignment:CONTROL_FLOW
9+
used-before-assignment:132:22:132:33:try_except_finally_nested_in_finally_4:Using variable 'inner_times' before assignment:CONTROL_FLOW
10+
used-before-assignment:133:22:133:33:try_except_finally_nested_in_finally_4:Using variable 'outer_times' before assignment:CONTROL_FLOW

0 commit comments

Comments
 (0)