summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhippo91 <guillaume.peillex@gmail.com>2021-04-07 12:42:40 +0200
committerGitHub <noreply@github.com>2021-04-07 12:42:40 +0200
commit4168e80a70e2f54cf589304c7cc50b3c32dbe710 (patch)
tree2ba4ef4022b0abd9f41de1e95412d26213597cce
parent07df776717718cb5d6b63121786298c2fd0acd46 (diff)
downloadpylint-git-4168e80a70e2f54cf589304c7cc50b3c32dbe710.tar.gz
Bug pylint 4122 (#4304)
* Adds detection of return type hint to determine if a function has NoReturn * Adds unittests to check return type hints are correctly interpreted * Adds an entry * Adds argparse.parse_error as default for never-returning-functions option * Simplification of NoReturn detection as suggested by cdce8p
-rw-r--r--ChangeLog5
-rw-r--r--pylint/checkers/refactoring/refactoring_checker.py9
-rw-r--r--tests/functional/i/inconsistent/inconsistent_returns.py52
-rw-r--r--tests/functional/i/inconsistent/inconsistent_returns.txt1
4 files changed, 66 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 354e0ea0d..be6c358c5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -30,6 +30,11 @@ Release date: Undefined
..
Put bug fixes that will be cherry-picked to latest major version here
+* Functions that never returns may declare ``NoReturn`` as type hints, so that
+ ``inconsistent-return-statements`` is not emitted.
+
+ Closes #4122, #4188
+
* Improved protected access checks to allow access inside class methods
Closes #1159
diff --git a/pylint/checkers/refactoring/refactoring_checker.py b/pylint/checkers/refactoring/refactoring_checker.py
index a84b995e2..57955a23f 100644
--- a/pylint/checkers/refactoring/refactoring_checker.py
+++ b/pylint/checkers/refactoring/refactoring_checker.py
@@ -305,7 +305,7 @@ class RefactoringChecker(checkers.BaseTokenChecker):
(
"never-returning-functions",
{
- "default": ("sys.exit",),
+ "default": ("sys.exit", "argparse.parse_error"),
"type": "csv",
"help": "Complete name of functions that never returns. When checking "
"for inconsistent-return-statements if a never returning function is "
@@ -1405,6 +1405,13 @@ class RefactoringChecker(checkers.BaseTokenChecker):
Returns:
bool: True if the function never returns, False otherwise.
"""
+ if isinstance(node, astroid.FunctionDef) and node.returns:
+ return (
+ isinstance(node.returns, astroid.Attribute)
+ and node.returns.attrname == "NoReturn"
+ or isinstance(node.returns, astroid.Name)
+ and node.returns.name == "NoReturn"
+ )
try:
return node.qname() in self._never_returning_functions
except TypeError:
diff --git a/tests/functional/i/inconsistent/inconsistent_returns.py b/tests/functional/i/inconsistent/inconsistent_returns.py
index fef090fc4..a1782979c 100644
--- a/tests/functional/i/inconsistent/inconsistent_returns.py
+++ b/tests/functional/i/inconsistent/inconsistent_returns.py
@@ -335,3 +335,55 @@ def bug_pylint_3873_2():
except IndexError:
nothing_to_do()
return False
+
+import typing # pylint: disable=wrong-import-position
+
+def parser_error(msg) -> typing.NoReturn: #pylint:disable=unused-argument
+ sys.exit(1)
+
+def parser_error_nortype(msg): #pylint:disable=unused-argument
+ sys.exit(2)
+
+
+from typing import NoReturn # pylint: disable=wrong-import-position
+
+def parser_error_name(msg) -> NoReturn: #pylint:disable=unused-argument
+ sys.exit(3)
+
+def bug_pylint_4122(s):
+ """
+ Every returns is consistent because parser_error has type hints
+ indicating it never returns
+ """
+ try:
+ n = int(s)
+ if n < 1:
+ raise ValueError()
+ return n
+ except ValueError:
+ parser_error('parser error')
+
+def bug_pylint_4122_wrong(s): # [inconsistent-return-statements]
+ """
+ Every returns is not consistent because parser_error_nortype has no type hints
+ """
+ try:
+ n = int(s)
+ if n < 1:
+ raise ValueError()
+ return n
+ except ValueError:
+ parser_error_nortype('parser error')
+
+def bug_pylint_4122_bis(s):
+ """
+ Every returns is consistent because parser_error has type hints
+ indicating it never returns
+ """
+ try:
+ n = int(s)
+ if n < 1:
+ raise ValueError()
+ return n
+ except ValueError:
+ parser_error_name('parser error')
diff --git a/tests/functional/i/inconsistent/inconsistent_returns.txt b/tests/functional/i/inconsistent/inconsistent_returns.txt
index 34978d5fd..74b0ea1a7 100644
--- a/tests/functional/i/inconsistent/inconsistent_returns.txt
+++ b/tests/functional/i/inconsistent/inconsistent_returns.txt
@@ -14,3 +14,4 @@ inconsistent-return-statements:262:8:bug_1794_inner_func_in_if_counter_example_3
inconsistent-return-statements:267:0:bug_3468:Either all return statements in a function should return an expression, or none of them should.
inconsistent-return-statements:277:0:bug_3468_variant:Either all return statements in a function should return an expression, or none of them should.
inconsistent-return-statements:322:0:bug_pylint_3873_1:Either all return statements in a function should return an expression, or none of them should.
+inconsistent-return-statements:366:0:bug_pylint_4122_wrong:Either all return statements in a function should return an expression, or none of them should.