mypy icon indicating copy to clipboard operation
mypy copied to clipboard

overload with wrong return type is ignored

Open ggirol-rc opened this issue 1 year ago • 2 comments

Bug Report

When one of the alternatives of an overload has a return type T which is a subtype of the return type of the annotation U but that the body of the function returns a type V which is a subtype of U but not T, no error is reported

To Reproduce

from typing import overload

@overload
def f(a: int) -> str:
    ...

# this is completely wrong
@overload
def f(a: str) -> bool:
    ...


def f(a: str | int) -> str | bool:
    return "Hello"

reveal_type(f("some string"))

https://mypy-play.net/?mypy=latest&python=3.12&flags=strict&gist=83c5a353e087d8bbe03d542e7340b4b5

Expected Behavior

mypy should complain that the body of the function returns an str which is incompatible with type bool (overload 2)

More generally, for each overload signature, mypy should check that the body of the function typechecks with the overload signature.

Actual Behavior

mypy reports no error

main.py:16: note: Revealed type is "builtins.bool"
Success: no issues found in 1 source file

ggirol-rc avatar Oct 01 '24 13:10 ggirol-rc

But the type declaration you provided should be treated as an "or" statement. For example, int | str is regarded by mypy as either int or str. Sorry for being a bit naive, but would you mind explaining a bit more about the expected output you want so that I can help solve the problem for you? Like what's the final result you excepted.

JasonHonKL avatar Oct 07 '24 03:10 JasonHonKL

I would like mypy to report that return Hello in incompatible with overload #2: if a is of type str, the body of f does not return a bool.

Something like that:

main.py:14: error: Incompatible return value type in overload 2 (got "str", expected "bool")  [return-value]

This is evidenced in the example by the fact that f("some string") is "Hello" while reveal_type(f("some string")) is bool.

ggirol-rc avatar Oct 07 '24 07:10 ggirol-rc

Overload specification does not require any function body checks against overloaded signatures. Overloads are explicitly external to the function itself: foreign callers see them and don't see the implementation signature, while the impl itself is only checked against its own signature.

sterliakov avatar Feb 13 '25 19:02 sterliakov

For reference, PEP 484 says:

The @overload-decorated definitions are for the benefit of the type checker only, since they will be overwritten by the non-@overload-decorated definition, while the latter is used at runtime but should be ignored by a type checker.

(emphasis mine)

I must say I find this underwhelming.

ggirol-rc avatar Feb 14 '25 08:02 ggirol-rc