Here's my folder structure: . ├── foo │ ├── __init__.py │ └── classic.py ├── foo-stubs │ ├── __init__.pyi │ └── classic.pyi ├── pyproject.toml └── t.py Contents are: $ cat foo/__init__.py from foo.classic import my_func $ cat foo/classic.py def my_func(a): return 3 $ cat foo-stubs/__init__.pyi from typing import Any from foo.classic import my_func __all__ = ['my_func'] $ cat foo-stubs/classic.pyi from typing import Any def my_func(a: Any) -> int: ... $ cat pyproject.toml [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [project] name = "foo" version = "0.1.0" requires-python = ">=3.9" Then, in t.py, I write from foo import my_func reveal_type(my_func) If I then run mypy t.py, I get: t.py:3: note: Revealed type is "def (a: Any) -> Any" Success: no issues found in 1 source file But...why? Shouldn't it be revealed as def (a: Any) -> builtins.int? Note I'm aware that I can also put the .pyi files directly in the foo directory, along with py.typed. My question is specifically about how to solve this problem with a -stubs directory, which is mentioned as a strategy on https://typing.python.org/en/latest/spec/distributing.html#stub-only-packages However, the stubs can also be put in a separate package and distributed separately. Third parties can also find this method useful if they wish to distribute stub files. The name of the stub package MUST follow the scheme foopkg-stubs for type stubs for the package named foopkg. Continue reading...