Skip to content

Commit 96b1c47

Browse files
crazybolilloPierre-Sassoulas
authored andcommitted
Fix useless-return false negatives
Returns inside try or if/else conditions were not being detected as useless. Said nodes are now checked for return statements to ensure their last component is not a useless return as well. Closes #9449.
1 parent 0b212cf commit 96b1c47

File tree

6 files changed

+45
-4
lines changed

6 files changed

+45
-4
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
If and Try nodes are now checked for useless return statements as well.
2+
3+
Closes #9449.

pylint/checkers/refactoring/refactoring_checker.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2078,12 +2078,18 @@ def _check_return_at_the_end(self, node: nodes.FunctionDef) -> None:
20782078
Per its implementation and PEP8 we can have a "return None" at the end
20792079
of the function body if there are other return statements before that!
20802080
"""
2081-
if len(self._return_nodes[node.name]) > 1:
2081+
if len(self._return_nodes[node.name]) != 1:
20822082
return
2083-
if len(node.body) <= 1:
2083+
if not node.body:
20842084
return
20852085

20862086
last = node.body[-1]
2087+
if isinstance(last, nodes.Return) and len(node.body) == 1:
2088+
return
2089+
2090+
while isinstance(last, (nodes.If, nodes.Try, nodes.ExceptHandler)):
2091+
last = last.last_child()
2092+
20872093
if isinstance(last, nodes.Return):
20882094
# e.g. "return"
20892095
if last.value is None:

tests/functional/i/inconsistent/inconsistent_returns.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#pylint: disable=missing-docstring, no-else-return, no-else-break, invalid-name, unused-variable, superfluous-parens, try-except-raise
2-
#pylint: disable=disallowed-name,too-few-public-methods,no-member,useless-else-on-loop
2+
#pylint: disable=disallowed-name,too-few-public-methods,no-member,useless-else-on-loop,useless-return
33
"""Testing inconsistent returns"""
44
import math
55
import sys

tests/functional/u/used/used_before_assignment_else_return.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""If the else block returns, it is generally safe to rely on assignments in the except."""
2-
# pylint: disable=missing-function-docstring, invalid-name
2+
# pylint: disable=missing-function-docstring, invalid-name, useless-return
33
import sys
44

55
def valid():

tests/functional/u/useless/useless_return.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,31 @@ def mymethod(self): # [useless-return]
1313
# These are not emitted
1414
def item_at(self):
1515
return None
16+
17+
18+
def function2(parameter): # [useless-return]
19+
if parameter:
20+
pass
21+
return
22+
23+
24+
def function3(parameter): # [useless-return]
25+
if parameter:
26+
pass
27+
else:
28+
return
29+
30+
31+
def function4(parameter): # [useless-return]
32+
try:
33+
parameter.do()
34+
except RuntimeError:
35+
parameter.other()
36+
return
37+
38+
39+
def function5(parameter): # [useless-return]
40+
try:
41+
parameter.do()
42+
except RuntimeError:
43+
return
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
11
useless-return:4:0:4:10:myfunc:Useless return at end of function or method:UNDEFINED
22
useless-return:9:4:9:16:SomeClass.mymethod:Useless return at end of function or method:UNDEFINED
3+
useless-return:18:0:18:13:function2:Useless return at end of function or method:UNDEFINED
4+
useless-return:24:0:24:13:function3:Useless return at end of function or method:UNDEFINED
5+
useless-return:31:0:31:13:function4:Useless return at end of function or method:UNDEFINED
6+
useless-return:39:0:39:13:function5:Useless return at end of function or method:UNDEFINED

0 commit comments

Comments
 (0)