Skip to content

Incorrent "Missing return statement" in presence of bad combination of decorated function call, definition order and NoReturn #8129

Closed
@jstasiak

Description

@jstasiak

Code to reproduce:

from typing import Callable, NoReturn, TypeVar


def no_return() -> NoReturn:
    pass


def use_decorated_before_defined() -> int:
    decorated()
    if bool():
        return 0
    else:
        no_return()


T = TypeVar('T')


def wrapper(function: T) -> T:
    return function


def decorator() -> Callable[[T], T]:
    return wrapper


@decorator()
def decorated() -> None: pass


def use_decorated_after_defined() -> int:
    decorated()
    if bool():
        return 0
    else:
        no_return()


def use_wrapped_before_defined() -> int:
    wrapped()
    if bool():
        return 0
    else:
        no_return()


@wrapper
def wrapped() -> None: pass

I tested this both with mypy 0.750 and one from the current master branch (526a218), running on CPython 3.7.5. The command line and the output:

% python -m mypy repro.py
repro.py:8: error: Missing return statement
Found 1 error in 1 file (checked 1 source file)

I'd expect no errors here. After some digging in mypy source code I believe use_decorated_before_defined can't be fully processed when it's type-checked (at least the first time it's entered) because of a) the call to decorated being looked at before decorated is defined and b) decorated being decorated (pardon my repetition) with a result of another function call which I suspect creates a difficult environment for mypy to deduce things and it defers further processing of use_decorated_before_defined (or at least part of it).

Then, when the call to no_return is encountered its type is detected as Any because of the processing being deferred per above, hence the error.

I left two similar variants of the function (use_decorated_after_defined and use_wrapped_before_defined) to help narrow things down as those don't trigger the error.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions