Skip to content

Commit 5a5a9be

Browse files
Fix unused-variable false positive when using same name for multiple exceptions (#10436) (#10481)
(cherry picked from commit 9e72867) Co-authored-by: Zen Lee <53538590+zenlyj@users.noreply.github.com>
1 parent 6ec71ba commit 5a5a9be

File tree

5 files changed

+35
-4
lines changed

5 files changed

+35
-4
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix a false positive for ``unused-variable`` when multiple except handlers bind the same name under a try block.
2+
3+
Closes #10426

pylint/checkers/variables.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2836,9 +2836,7 @@ def _check_is_unused(
28362836
return
28372837

28382838
# Special case for exception variable
2839-
if isinstance(stmt.parent, nodes.ExceptHandler) and any(
2840-
n.name == name for n in stmt.parent.nodes_of_class(nodes.Name)
2841-
):
2839+
if self._is_exception_binding_used_in_handler(stmt, name):
28422840
return
28432841

28442842
self.add_message(message_name, args=name, node=stmt)
@@ -2913,6 +2911,15 @@ def _check_unused_arguments(
29132911

29142912
self.add_message("unused-argument", args=name, node=stmt, confidence=confidence)
29152913

2914+
def _is_exception_binding_used_in_handler(
2915+
self, stmt: nodes.NodeNG, name: str
2916+
) -> bool:
2917+
return (
2918+
isinstance(stmt.parent, nodes.ExceptHandler)
2919+
and stmt is stmt.parent.name
2920+
and any(n.name == name for n in stmt.parent.nodes_of_class(nodes.Name))
2921+
)
2922+
29162923
def _check_late_binding_closure(self, node: nodes.Name) -> None:
29172924
"""Check whether node is a cell var that is assigned within a containing loop.
29182925
@@ -3238,6 +3245,8 @@ def _check_globals(self, not_consumed: dict[str, nodes.NodeNG]) -> None:
32383245
for node in node_lst:
32393246
if in_type_checking_block(node):
32403247
continue
3248+
if self._is_exception_binding_used_in_handler(node, name):
3249+
continue
32413250
self.add_message("unused-variable", args=(name,), node=node)
32423251

32433252
# pylint: disable = too-many-branches

tests/functional/u/unused/unused_global_variable2.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,11 @@
99

1010

1111
VAR = 'pylint' # [unused-variable]
12+
13+
14+
try:
15+
pass
16+
except TypeError as exc:
17+
print(exc)
18+
except ValueError as exc:
19+
print(exc)

tests/functional/u/unused/unused_variable.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,17 @@ def sibling_except_handlers():
187187
except ValueError as e:
188188
print(e)
189189

190+
191+
def test_multiple_except_handlers_under_try():
192+
try:
193+
pass
194+
except TypeError as exc:
195+
print(exc)
196+
except ValueError as exc:
197+
print(exc)
198+
except ArithmeticError as exc:
199+
print(exc)
200+
190201
def func6():
191202
a = 1
192203

tests/functional/u/unused/unused_variable.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,4 @@ unused-variable:150:4:154:26:func4:Unused variable 'error':UNDEFINED
2626
redefined-outer-name:153:8:154:26:func4:Redefining name 'error' from outer scope (line 150):UNDEFINED
2727
unused-variable:161:4:162:12:main:Unused variable 'e':UNDEFINED
2828
undefined-loop-variable:168:10:168:11:main:Using possibly undefined loop variable 'e':UNDEFINED
29-
unused-variable:217:8:218:16:test_regression_8595:Unused variable 'e':UNDEFINED
29+
unused-variable:228:8:229:16:test_regression_8595:Unused variable 'e':UNDEFINED

0 commit comments

Comments
 (0)