From the docs:
Here are the rules governing implicit creation of a
__hash__()
method:[…]
If
eq
andfrozen
are both true, by defaultdataclass()
will
generate a__hash__()
method for you. Ifeq
is true andfrozen
is false,__hash__()
will be set toNone
, marking it unhashable
(which it is, since it is mutable). Ifeq
is false,__hash__()
will be left untouched meaning the__hash__()
method of the
superclass will be used (if the superclass is object, this means it
will fall back to id-based hashing).
Since you set eq=True
and left frozen
at the default (False
), your dataclass is unhashable.
You have 3 options:
- Set
frozen=True
(in addition toeq=True
), which will make your class immutable and hashable. -
Set
unsafe_hash=True
, which will create a__hash__
method but leave your class mutable, thus risking problems if an instance of your class is modified while stored in a dict or set:cat = Category('foo', 'bar') categories = {cat} cat.id = 'baz' print(cat in categories) # False
- Manually implement a
__hash__
method.