Skip to content

Commit

Permalink
[used-before-assignment] Fix FP under finally block (#9452)
Browse files Browse the repository at this point in the history
Closes #9451
  • Loading branch information
jacobtylerwalls authored Feb 22, 2024
1 parent 6d3e6a9 commit a83e6b9
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 10 deletions.
4 changes: 4 additions & 0 deletions doc/whatsnew/fragments/9451.false_positive
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Fix false positive for ``used-before-assignment`` in a ``finally`` block
when assignments took place in both the ``try`` block and each exception handler.

Closes #9451
12 changes: 10 additions & 2 deletions pylint/checkers/variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@ def get_next_to_consume(self, node: nodes.Name) -> list[nodes.NodeNG] | None:
if found_nodes:
uncertain_nodes = (
self._uncertain_nodes_in_try_blocks_when_evaluating_finally_blocks(
found_nodes, node_statement
found_nodes, node_statement, name
)
)
self.consumed_uncertain[node.name] += uncertain_nodes
Expand Down Expand Up @@ -1140,7 +1140,9 @@ def _uncertain_nodes_in_try_blocks_when_evaluating_except_blocks(

@staticmethod
def _uncertain_nodes_in_try_blocks_when_evaluating_finally_blocks(
found_nodes: list[nodes.NodeNG], node_statement: _base_nodes.Statement
found_nodes: list[nodes.NodeNG],
node_statement: _base_nodes.Statement,
name: str,
) -> list[nodes.NodeNG]:
uncertain_nodes: list[nodes.NodeNG] = []
(
Expand Down Expand Up @@ -1187,6 +1189,12 @@ def _uncertain_nodes_in_try_blocks_when_evaluating_finally_blocks(
)
):
continue
# Is the name defined in all exception clauses?
if other_node_try_finally_ancestor.handlers and all(
NamesConsumer._defines_name_raises_or_returns_recursive(name, handler)
for handler in other_node_try_finally_ancestor.handlers
):
continue
# Passed all tests for uncertain execution
uncertain_nodes.append(other_node)
return uncertain_nodes
Expand Down
10 changes: 10 additions & 0 deletions tests/functional/u/used/used_before_assignment_issue85.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@ def try_except_finally_assignment_in_final_block():
print(res)


def try_except_finally_assignment_in_both_try_and_except():
"""Assignment of the name in both try and except blocks is fine."""
try:
res = 1 / 0
except ZeroDivisionError:
res = 0
finally:
print(res)


def try_except_finally_nested_try_finally_in_try():
"""Don't confuse assignments in different finally statements where
one is nested inside a try.
Expand Down
16 changes: 8 additions & 8 deletions tests/functional/u/used/used_before_assignment_issue85.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
used-before-assignment:8:14:8:17:main:Using variable 'res' before assignment:CONTROL_FLOW
used-before-assignment:20:14:20:17:try_except_finally:Using variable 'res' before assignment:CONTROL_FLOW
used-before-assignment:45:18:45:21:try_except_finally_nested_try_finally_in_try:Using variable 'res' before assignment:HIGH
used-before-assignment:70:18:70:29:try_except_finally_nested_in_finally:Using variable 'outer_times' before assignment:CONTROL_FLOW
used-before-assignment:84:18:84:29:try_except_finally_nested_in_finally_2:Using variable 'inner_times' before assignment:CONTROL_FLOW
used-before-assignment:85:14:85:25:try_except_finally_nested_in_finally_2:Using variable 'outer_times' before assignment:CONTROL_FLOW
used-before-assignment:100:18:100:29:try_except_finally_nested_in_finally_3:Using variable 'inner_times' before assignment:CONTROL_FLOW
used-before-assignment:101:18:101:29:try_except_finally_nested_in_finally_3:Using variable 'outer_times' before assignment:CONTROL_FLOW
used-before-assignment:122:22:122:33:try_except_finally_nested_in_finally_4:Using variable 'inner_times' before assignment:CONTROL_FLOW
used-before-assignment:123:22:123:33:try_except_finally_nested_in_finally_4:Using variable 'outer_times' before assignment:CONTROL_FLOW
used-before-assignment:55:18:55:21:try_except_finally_nested_try_finally_in_try:Using variable 'res' before assignment:HIGH
used-before-assignment:80:18:80:29:try_except_finally_nested_in_finally:Using variable 'outer_times' before assignment:CONTROL_FLOW
used-before-assignment:94:18:94:29:try_except_finally_nested_in_finally_2:Using variable 'inner_times' before assignment:CONTROL_FLOW
used-before-assignment:95:14:95:25:try_except_finally_nested_in_finally_2:Using variable 'outer_times' before assignment:CONTROL_FLOW
used-before-assignment:110:18:110:29:try_except_finally_nested_in_finally_3:Using variable 'inner_times' before assignment:CONTROL_FLOW
used-before-assignment:111:18:111:29:try_except_finally_nested_in_finally_3:Using variable 'outer_times' before assignment:CONTROL_FLOW
used-before-assignment:132:22:132:33:try_except_finally_nested_in_finally_4:Using variable 'inner_times' before assignment:CONTROL_FLOW
used-before-assignment:133:22:133:33:try_except_finally_nested_in_finally_4:Using variable 'outer_times' before assignment:CONTROL_FLOW

0 comments on commit a83e6b9

Please sign in to comment.