eq-without-hash (PLW1641)
Added in 0.12.0 · Related issues · View source
Derived from the Pylint linter.
What it does
Checks for classes that implement __eq__ but not __hash__.
Why is this bad?
A class that implements __eq__ but not __hash__ will have its hash
method implicitly set to None, regardless of if a superclass defines
__hash__. This will cause the class to be unhashable, which will in turn
cause issues when using instances of the class as keys in a dictionary or
members of a set.
Example
class Person:
def __init__(self):
self.name = "monty"
def __eq__(self, other):
return isinstance(other, Person) and other.name == self.name
Use instead:
class Person:
def __init__(self):
self.name = "monty"
def __eq__(self, other):
return isinstance(other, Person) and other.name == self.name
def __hash__(self):
return hash(self.name)
In general, it is unsound to inherit a __hash__ implementation from a parent class while
overriding the __eq__ implementation because the two must be kept in sync. However, an easy
way to resolve this error in cases where it is sound is to explicitly set __hash__ to the
parent class's implementation:
class Developer(Person):
def __init__(self): ...
def __eq__(self, other): ...
__hash__ = Person.__hash__