Why does `mypy --strict` not throw an error in this simple code?

I have the following in test.py:

def f(x: int) -> float:
    pass

if __name__=="__main__":
  f(4)

When I run mypy --strict test.py, I get no errors.

I expected mypy would be able to infer that there is a problem with my definition f. It obviously has no return statement and can never return a float.

I feel like there is something fundamental which I do not understand here. The presence (or not) of a return statement is something that can be checked statically. Why does mypy miss it?


Solution 1:

The syntax you use is recognized as a function stub, not as a function implementation.

Normally, a function stub is written as:

def f(x: int) -> float: ...

but this is merely a convenience for

def f(x: int) -> float: pass

From the mypy documentation:

Function bodies cannot be completely removed. By convention, we replace them with ... instead of the pass statement.

As mypy does no checks for the function body for stubs, you get no error in this case. And as pointed out by @domarm in the comments, adding any statement besides pass (even a second pass statement) to the function body will result in the expected mypy error.