pythonpython-3.xhashpython-dataclasses

How can I make a python dataclass hashable?


I have a dataclass whose instances I want to hash and order, using the id member as a key.

from dataclasses import dataclass, field

@dataclass(eq=True, order=True)
class Category:
    id: str = field(compare=True)
    name: str = field(default="set this in post_init", compare=False)

I know that I can implement __hash__ myself. However, I would like dataclasses to do the work for me because they are intended to handle this.


Unfortunately, the above dataclass fails:

a = sorted(list(set([ Category(id='x'), Category(id='y')])))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'Category'

Solution

  • From the docs:

    Here are the rules governing implicit creation of a __hash__() method:

    [...]

    If eq and frozen are both true, by default dataclass() will generate a __hash__() method for you. If eq is true and frozen is false, __hash__() will be set to None, marking it unhashable (which it is, since it is mutable). If eq 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: