Skip to content

Special Method Overload Resolution #6710

Closed
@llchan

Description

@llchan
  • Are you reporting a bug, or opening a feature request? bug
  • Please insert below the code you are checking with mypy,
    or a mock-up repro if the source is private. We would appreciate
    if you try to simplify your case to a minimal repro.
from typing import overload

class Expr: ...

class Foo:
    @overload  # type: ignore
    def __eq__(self, other: 'Foo') -> 'Expr': ...
    @overload
    def __eq__(self, other: str) -> 'Expr': ...

foo: Foo

reveal_type(foo == 1.0)
  • What is the actual behavior/output?
main.pyi:17: error: Revealed type is 'builtins.bool'
  • What is the behavior/output you expect?
main.pyi:17: error: No overload variant of "__eq__" of "Foo" matches argument type "float"
main.pyi:17: note: Possible overload variants:
main.pyi:17: note:     def __eq__(self, Foo) -> Expr
main.pyi:17: note:     def __eq__(self, str) -> Expr

Since Foo.__eq__ exists, it will be called for all equality comparisons at runtime, and it will not fall back to float.__eq__ unless it returns NotImplemented. Since none of the overload variants do that, it should never happen and this comparison should be a type error.

My current workaround is to include a Any overload that returns NoReturn, but that's not ideal since it defers the error at the call site to a "if I get lucky it will hit an error downstream" situation. Some of that could be addressed with more precise NoReturn semantics, but as it stands right now there are still some discussions/issues surrounding that, and it also feels clunky to have to explicitly include an overload for type errors.

In any case, I think special method overload resolution needs some fine tuning, and it should not mix-and-match the left/right operand's methods unless an overload variant is allowed to return type(NotImplemented) (which, btw, needs some type tightening in typeshed, but I'll file that over there).

  • What are the versions of mypy and Python you are using?
    0.710+dev.bb7dbd5afd84656a62311e5f69a1cef6d06466bc
  • Do you see the same issue after installing mypy from Git master?
    yes

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions