Skip to content

Commit 80e024a

Browse files
Fix false positive inconsistent-return-statement for method marked NoReturn (#8750) (#8761)
Allow inspection of BoundMethod when checking if annotated as NoReturn (cherry picked from commit 8614ccf) Co-authored-by: kdestin <[email protected]>
1 parent b59dfea commit 80e024a

File tree

4 files changed

+51
-3
lines changed

4 files changed

+51
-3
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 where pylint was ignoring method calls annotated as ``NoReturn`` during the ``inconsistent-return-statements`` check.
2+
3+
Closes #8747

pylint/checkers/refactoring/refactoring_checker.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2002,16 +2002,18 @@ def _has_return_in_siblings(node: nodes.NodeNG) -> bool:
20022002
next_sibling = next_sibling.next_sibling()
20032003
return False
20042004

2005-
def _is_function_def_never_returning(self, node: nodes.FunctionDef) -> bool:
2005+
def _is_function_def_never_returning(
2006+
self, node: nodes.FunctionDef | astroid.BoundMethod
2007+
) -> bool:
20062008
"""Return True if the function never returns, False otherwise.
20072009
20082010
Args:
2009-
node (nodes.FunctionDef): function definition node to be analyzed.
2011+
node (nodes.FunctionDef or astroid.BoundMethod): function definition node to be analyzed.
20102012
20112013
Returns:
20122014
bool: True if the function never returns, False otherwise.
20132015
"""
2014-
if isinstance(node, nodes.FunctionDef) and node.returns:
2016+
if isinstance(node, (nodes.FunctionDef, astroid.BoundMethod)) and node.returns:
20152017
return (
20162018
isinstance(node.returns, nodes.Attribute)
20172019
and node.returns.attrname == "NoReturn"

tests/functional/i/inconsistent/inconsistent_returns_noreturn.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,45 @@ def bug_pylint_4122_bis(s):
5353
return n
5454
except ValueError:
5555
parser_error_name('parser error')
56+
57+
class ClassUnderTest:
58+
def _no_return_method(self) -> typing.NoReturn:
59+
sys.exit(1)
60+
61+
def _falsely_no_return_method(self) -> typing.NoReturn:
62+
return 1
63+
64+
def _does_return_method(self) -> int:
65+
return 1
66+
67+
def bug_pylint_8747(self, s: str) -> int:
68+
"""Every return is consistent because self._no_return_method hints NoReturn"""
69+
try:
70+
n = int(s)
71+
if n < 1:
72+
raise ValueError
73+
return n
74+
except ValueError:
75+
self._no_return_method()
76+
77+
def bug_pylint_8747_wrong(self, s: str) -> int: # [inconsistent-return-statements]
78+
"""Every return is not consistent because self._does_return_method() returns a value"""
79+
try:
80+
n = int(s)
81+
if n < 1:
82+
raise ValueError
83+
return n
84+
except ValueError:
85+
self._does_return_method()
86+
87+
def bug_pylint_8747_incorrect_annotation(self, s: str) -> int:
88+
"""Every return is consistent since pylint does not attempt to detect that the
89+
NoReturn annotation is incorrect and the function actually returns
90+
"""
91+
try:
92+
n = int(s)
93+
if n < 1:
94+
raise ValueError
95+
return n
96+
except ValueError:
97+
self._falsely_no_return_method()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
inconsistent-return-statements:32:0:32:25:bug_pylint_4122_wrong:Either all return statements in a function should return an expression, or none of them should.:UNDEFINED
2+
inconsistent-return-statements:77:4:77:29:ClassUnderTest.bug_pylint_8747_wrong:Either all return statements in a function should return an expression, or none of them should.:UNDEFINED

0 commit comments

Comments
 (0)