I'm using Python 3.5.1 and the newly released MyPy v0.4.1 static type analyzer.
I have some more complex code that I've reduced down to this simplest possible python class needed to reproduce the error:
class MyObject(object):
def __init__(self, value: int=5) -> None:
self.value = value
def __eq__(self, other: MyObject) -> bool:
return self.value == other.value
Running the type checker mypy test.py
produces the following error:
test.py: note: In class "MyObject":
test.py:5: error: Argument 1 of "__eq__" incompatible with supertype "object"
My theory based on these docs is that .__eq__(...)
and .__ne__(...)
on object
already have argument types defined, which are clashing with my subclass's redefinition of these types. My question is how to I define these types to make sure __eq__
is type-checked with my chosen type.
==
is supposed to take arbitrary other objects, not just objects of your type. If it doesn't recognize the other object, it should return NotImplemented
:
class MyObject(object):
def __init__(self, value: int=5) -> None:
self.value = value
def __eq__(self, other: object) -> bool:
if not isinstance(other, MyObject):
return NotImplemented
return self.value == other.value
NotImplemented
isn't an instance of bool
, but mypy seems to have a weird special case for that. It accepts this code as-is.
On Python 3.10 and up, you can use types.NotImplementedType
to be more explicit about the NotImplemented possibility:
from types import NotImplementedType
class MyObject(object):
def __init__(self, value: int=5) -> None:
self.value = value
def __eq__(self, other: object) -> bool | NotImplementedType:
if not isinstance(other, MyObject):
return NotImplemented
return self.value == other.value
Also, if you need to refer to MyObject
for type hints inside its own body, you need to use a string, 'MyObject'
instead of MyObject
. MyObject
doesn't exist yet.