python/mypy

mypy incorrectly complains about function signature in @overload

Closed this issue · 2 comments

Bug Report

I am facing an issue with mypy and @overload when using custom imported objects.

To Reproduce

Here is the simplied code snippets and file structure I am using:

.
├─ my_package
│   ├─ __init__.py
│   ├─ config_a.py
│   ├─ config_b.py
│   └─ main.py
# my_package/config_a.py
class ConfigA:
    name: str = "A"
# my_package/config_b.py
class ConfigB:
    name: str = "B"
# my_package/main.py
from typing import overload

from config_a import ConfigA
from config_b import ConfigB

@overload
def foo(config: ConfigA) -> int: ...
@overload
def foo(config: ConfigB) -> str: ...
def foo(config: ConfigA | ConfigB) -> int | str:
    if isinstance(config, ConfigA):
        return 42
    elif isinstance(config, ConfigB):
        return "bar"
    raise NotImplementedError()

Ran the following:

mypy my_package

Expected Behavior

No errors.

Actual Behavior

Mypy gives the following error:

my_package/main.py:10: error: Overloaded function signature 2 will never be matched: signature 1's parameter type(s) are the same or broader  [overload-cannot-match]
Found 1 error in 1 file

It works if ConfigA and ConfigB are both defined within main.py but fails when they are imported from config_a.py and config_b.py.

Your Environment

  • Python version: 3.11.10
  • Mypy version: 1.13.0
  • No additional configuration

This certainly is a problem of import resolution, you're missing some mypy flags. When I run default mypy==1.13.0 on the structure you described, I receive a few more errors:

$ mypy my_package
my_package/main.py:3: error: Cannot find implementation or library stub for module named "config_a"  [import-not-found]
my_package/main.py:3: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
my_package/main.py:4: error: Cannot find implementation or library stub for module named "config_b"  [import-not-found]
my_package/main.py:9: error: Overloaded function signature 2 will never be matched: signature 1's parameter type(s) are the same or broader  [overload-cannot-match]

which pretty much explains everything. Try reveal_type(ConfigA) in main.py - you'll most likely see revealed type is "Any".

However, running mypy -m my_package works as expected. See https://mypy.readthedocs.io/en/stable/running_mypy.html for further explanation of how mypy treats the imports it encounters.

This is not an overloading issue.

Many thanks @sterliakov I didn't see these warnings and they help a lot ! I will investigate in this direction but it looks like this doesn't come from the integration with overloads indeed.