Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

False positive for inconsistent-return-statements with method annotated with NoReturn return type #8747

Closed
kdestin opened this issue Jun 7, 2023 · 0 comments · Fixed by #8750
Labels
False Positive 🦟 A message is emitted but nothing is wrong with the code
Milestone

Comments

@kdestin
Copy link
Contributor

kdestin commented Jun 7, 2023

Bug description

repro.py

from typing import NoReturn

class Foo:
    def _never_returns() -> NoReturn:
        raise Exception

    def bar(self) -> int:
        try:
            return 1
        except Exception:
            self._never_returns()

Configuration

Default Config

Command used

pylint --disable=all --enable=inconsistent-return-statements repro.py

Pylint output

************* Module repro
repro.py:7:4: R1710: Either all return statements in a function should return an expression, or none of them should. (inconsistent-return-statements)

------------------------------------------------------------------
Your code has been rated at 8.89/10 (previous run: 0.00/10, +8.89)

Expected behavior

------------------------------------
Your code has been rated at 10.00/10

Pylint version

My pylint configuration is pinned to 


pylint 2.15.8
astroid 2.13.5
Python 3.10.6 (main, Mar 10 2023, 10:55:28) [GCC 11.3.0]


But I was able to repro this on the latest released version of pylint (2.17.4 at time of writing).

OS / Environment

$ lsb_release -a
Distributor ID:	Ubuntu
Description:	Ubuntu 22.04.2 LTS
Release:	22.04
Codename:	jammy
$ uname -r
5.15.0-72-generic

Additional dependencies

No response


I did an initial investigation, and might have an idea of what's going on:

  • During the inconsistent-return-statements lint, there's an attempt made infer whether the return type of a function call is NoReturn.

    def _is_function_def_never_returning(self, node: nodes.FunctionDef) -> bool:
    """Return True if the function never returns, False otherwise.
    Args:
    node (nodes.FunctionDef): function definition node to be analyzed.
    Returns:
    bool: True if the function never returns, False otherwise.
    """
    if isinstance(node, nodes.FunctionDef) and node.returns:
    return (
    isinstance(node.returns, nodes.Attribute)
    and node.returns.attrname == "NoReturn"
    or isinstance(node.returns, nodes.Name)
    and node.returns.name == "NoReturn"
    )

  • But _is_function_def_never_returning only inspects the return type if the node passed in is a nodes.FunctionDef. But calling node.func.inferred()[0] on the method call (e.g. self._never_returns()) returns the corresponding method definition node as type astroid.BoundMethod. Since that isn't a nodes.FunctionDef, _is_function_def_never_returning never even looks to see if the return type is NoReturn.

    funcdef_node = node.func.inferred()[0]
    if self._is_function_def_never_returning(funcdef_node):

@kdestin kdestin added the Needs triage 📥 Just created, needs acknowledgment, triage, and proper labelling label Jun 7, 2023
@Pierre-Sassoulas Pierre-Sassoulas added this to the 2.17.5 milestone Jun 7, 2023
@Pierre-Sassoulas Pierre-Sassoulas added False Positive 🦟 A message is emitted but nothing is wrong with the code Work in progress and removed Needs triage 📥 Just created, needs acknowledgment, triage, and proper labelling labels Jun 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
False Positive 🦟 A message is emitted but nothing is wrong with the code
Projects
None yet
3 participants