Skip to content

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

Description

@cjw296

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

Activity

cjw296 commented on Feb 4, 2025

@cjw296
Author

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 commented on Feb 4, 2025

@A5rocks
Collaborator

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.

cjw296 commented on Feb 4, 2025

@cjw296
Author

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

A5rocks commented on Feb 7, 2025

@A5rocks
Collaborator

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.

cjw296 commented on Jul 8, 2025

@cjw296
Author

Summary question (and hopefully eventually a thread!) on related problems:
python/typing#2040

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions