diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | pylint/checkers/refactoring/refactoring_checker.py | 9 | ||||
-rw-r--r-- | tests/functional/i/inconsistent/inconsistent_returns.py | 52 | ||||
-rw-r--r-- | tests/functional/i/inconsistent/inconsistent_returns.txt | 1 |
4 files changed, 66 insertions, 1 deletions
@@ -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. |