diff --git a/doc/whatsnew/fragments/9751.bugfix b/doc/whatsnew/fragments/9751.bugfix new file mode 100644 index 0000000000..ddd37ac2b0 --- /dev/null +++ b/doc/whatsnew/fragments/9751.bugfix @@ -0,0 +1,4 @@ +Fixed a false positive ``unreachable-code`` when using ``typing.Any`` as return type in python +3.8, the ``typing.NoReturn`` are not taken into account anymore for python 3.8 however. + +Closes #9751 diff --git a/pylint/checkers/utils.py b/pylint/checkers/utils.py index 7f7df0eb12..f30b5984b4 100644 --- a/pylint/checkers/utils.py +++ b/pylint/checkers/utils.py @@ -2184,7 +2184,9 @@ def is_terminating_func(node: nodes.Call) -> bool: *TYPING_NEVER, *TYPING_NORETURN, # In Python 3.7 - 3.8, NoReturn is alias of '_SpecialForm' - "typing._SpecialForm", + # "typing._SpecialForm", + # But 'typing.Any' also inherits _SpecialForm + # See #9751 ) ): return True diff --git a/tests/functional/r/regression_02/regression_9751.py b/tests/functional/r/regression_02/regression_9751.py new file mode 100644 index 0000000000..c3b9d787f2 --- /dev/null +++ b/tests/functional/r/regression_02/regression_9751.py @@ -0,0 +1,15 @@ +""" +pylint 3.2.4 regression +https://github.com/pylint-dev/pylint/issues/9751 +""" + +# pylint: disable=missing-function-docstring + +from typing import Any + +def repro() -> Any: + return 5 + +def main(): + x = repro() + 5 + print(x) diff --git a/tests/functional/u/used/used_before_assignment.py b/tests/functional/u/used/used_before_assignment.py index 37da03d7e5..5e589e81bb 100644 --- a/tests/functional/u/used/used_before_assignment.py +++ b/tests/functional/u/used/used_before_assignment.py @@ -2,7 +2,7 @@ # pylint: disable=consider-using-f-string, missing-function-docstring import datetime import sys -from typing import NoReturn +# from typing import NoReturn # uncomment when we reunite with used_before_assignment_py38.py MSG = "hello %s" % MSG # [used-before-assignment] @@ -206,19 +206,3 @@ def inner_if_continues_outer_if_has_no_other_statements(): else: order = None print(order) - - -class PlatformChecks: - """https://github.com/pylint-dev/pylint/issues/9674""" - def skip(self, msg) -> NoReturn: - raise Exception(msg) # pylint: disable=broad-exception-raised - - def print_platform_specific_command(self): - if sys.platform == "linux": - cmd = "ls" - elif sys.platform == "win32": - cmd = "dir" - else: - self.skip("only runs on Linux/Windows") - - print(cmd) diff --git a/tests/functional/u/used/used_before_assignment_py38.py b/tests/functional/u/used/used_before_assignment_py38.py new file mode 100644 index 0000000000..81d69268e2 --- /dev/null +++ b/tests/functional/u/used/used_before_assignment_py38.py @@ -0,0 +1,26 @@ +""" +Temporary file until we drop python 3.8 +See https://github.com/pylint-dev/pylint/issues/9751 +Please reunite with used_before_assignment.py at this point +""" + +# pylint: disable=missing-docstring + +import sys +from typing import NoReturn + + +class PlatformChecks: + """https://github.com/pylint-dev/pylint/issues/9674""" + def skip(self, msg) -> NoReturn: + raise Exception(msg) # pylint: disable=broad-exception-raised + + def print_platform_specific_command(self): + if sys.platform == "linux": + cmd = "ls" + elif sys.platform == "win32": + cmd = "dir" + else: + self.skip("only runs on Linux/Windows") + + print(cmd) diff --git a/tests/functional/u/used/used_before_assignment_py38.rc b/tests/functional/u/used/used_before_assignment_py38.rc new file mode 100644 index 0000000000..16b75eea75 --- /dev/null +++ b/tests/functional/u/used/used_before_assignment_py38.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.9