Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

erroneous complaint that overloaded function implementation does not accept all possible arguments of signature #18596

Open
cjw296 opened this issue Feb 4, 2025 · 4 comments · May be fixed by #18627
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code topic-overloads

Comments

@cjw296
Copy link

cjw296 commented Feb 4, 2025

Bug Report

Erroneous complaint that overloaded function implementation does not accept all possible arguments of signature.

To Reproduce

from datetime import datetime
from typing import overload

class Sample:

    @overload
    @classmethod
    def set(cls, year: int) -> None:
        ...

    @overload
    @classmethod
    def set(cls, instance: datetime, / ) -> None:
        ...

    @classmethod
    def set(cls, *args: datetime | int, **kw: int) -> None:
        pass

Expected Behavior

The above should pass type checking.

Pyright's happy enough:

$ pyright typing_bug.py 
0 errors, 0 warnings, 0 informations 

Actual Behavior

$ mypy typing_bug.py 
typing_bug.py:16: error: Overloaded function implementation does not accept all possible arguments of signature 1  [misc]
Found 1 error in 1 file (checked 1 source file)

Your Environment

  • Mypy version used: 1.14.1 (compiled: yes)
  • Mypy command-line flags: None, see above
  • Mypy configuration options from mypy.ini (and other config files): None.
  • Python version used: Python 3.12.1
@cjw296 cjw296 added the bug mypy got something wrong label Feb 4, 2025
@cjw296
Copy link
Author

cjw296 commented Feb 4, 2025

If I change the implemention to this, mypy is happy:

    @classmethod
    def set(cls, *args: datetime | int, **kw: int | datetime) -> None:
        pass

But that's not correct: it's never valid to pass a datetime as a keyword parameter, note the "positional argument only" marker in signature 2.

The following also make mypy happy, but doesn't match the behaviour I need:

from datetime import datetime
from typing import overload

class Sample:

    @overload
    @classmethod
    def set(cls, *, year: int) -> None:
        ...

    @overload
    @classmethod
    def set(cls, instance: datetime, / ) -> None:
        ...

    @classmethod
    def set(cls, *args: datetime, **kw: int) -> None:
        pass

@A5rocks
Copy link
Collaborator

A5rocks commented Feb 4, 2025

Smaller reproducer:

from typing import overload

@overload
def set(year: int) -> None:
    ...

@overload
def set() -> None:
    ...

def set(*args: object | int, **kw: int) -> None:  # E: Overloaded function implementation does not accept all possible arguments of signature 1
    pass

If you remove the object | then it passes type checking.

@A5rocks A5rocks added false-positive mypy gave an error on correct code topic-overloads labels Feb 4, 2025
@cjw296
Copy link
Author

cjw296 commented Feb 4, 2025

The error message is also frustratingly poor: why not specify which types are missing from the implementation? :-/

@A5rocks
Copy link
Collaborator

A5rocks commented Feb 7, 2025

The very wish-washy answer is that it's because "is this implementation alright" uses a generalized subtype check, so there's not the available information. I think mypy could definitely provide more provenance information though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code topic-overloads
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants