Skip to content

mypy and pylint disagree about uselessness of return statements #6530

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

Closed
clo-vis opened this issue May 6, 2022 · 4 comments
Closed

mypy and pylint disagree about uselessness of return statements #6530

clo-vis opened this issue May 6, 2022 · 4 comments
Labels
Milestone

Comments

@clo-vis
Copy link

clo-vis commented May 6, 2022

Bug description

from contextlib import AbstractContextManager
from types import TracebackType
from typing import Optional, Type


class Playground(AbstractContextManager["Playground"]):
    def __exit__(
        self,
        exc_type: Optional[Type[BaseException]],
        exc_value: Optional[BaseException],
        traceback: Optional[TracebackType],
    ) -> Optional[bool]:
        print("closing what needs to be closed")
        return None

Configuration

No response

Command used

pylint playground.py

Pylint output

src\playground.py:7:4: R1711: Useless return at end of function or method (useless-return)

Expected behavior

No error message, because without return None mypy complains:

error: Missing return statement [return]

And mypy swears that they are right, see for example python/mypy#3974

(By the way, the signature from exit was copied from https://mypy.readthedocs.io/en/stable/protocols.html#contextmanager-t)

Pylint version

pylint 2.13.8
astroid 2.11.4
Python 3.9.5 (tags/v3.9.5:0a7dcbd, May  3 2021, 17:27:52) [MSC v.1928 64 bit (AMD64)]

OS / Environment

No response

Additional dependencies

No response

@clo-vis clo-vis added the Needs triage 📥 Just created, needs acknowledgment, triage, and proper labelling label May 6, 2022
@Pierre-Sassoulas
Copy link
Member

I think both tools are right according to pep8 : Either all return statements in a function should return an expression, or none of them should.

If you don't want to return anything use -> None instead of -> Optional[bool], mypy will be happy :)

@Pierre-Sassoulas Pierre-Sassoulas added this to the 2.15.0 milestone May 6, 2022
@Pierre-Sassoulas Pierre-Sassoulas added Question Waiting on author Indicate that maintainers are waiting for a message of the author and removed Needs triage 📥 Just created, needs acknowledgment, triage, and proper labelling labels May 6, 2022
@mbyrnepr2
Copy link
Member

To add to Pierre's comment, there is also an instructive docstring relating to this:
https://github.com/PyCQA/pylint/blob/main/pylint/checkers/refactoring/refactoring_checker.py#L1866

@Pierre-Sassoulas
Copy link
Member

Closing as answered.

@Pierre-Sassoulas Pierre-Sassoulas removed the Waiting on author Indicate that maintainers are waiting for a message of the author label May 13, 2022
@clo-vis
Copy link
Author

clo-vis commented May 14, 2022

If you don't want to return anything use -> None instead of -> Optional[bool], mypy will be happy :)

A better answer is "use # type: ignore and mypy will be happy.

Even though for the example above using -> None does the job, you cannot always just replace the type of the return value with -> None and expect that mypy won't complain, as in

from typing import overload, Union, Literal


@overload
def fetch_data(parse: Literal[True]) -> int:
    ...


@overload
def fetch_data(parse: Literal[False]) -> None:
    ...


@overload
def fetch_data(parse: bool) -> Union[int, None]:
    ...


def fetch_data(parse: bool) -> Union[int, None]:  # type: ignore[return]
    print(parse)

@Pierre-Sassoulas Pierre-Sassoulas modified the milestones: 2.15.0, 2.14.0 May 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants