["python","python-3.x","hash","python-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'
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: Set frozen=True (in combination with the default eq=True), which will make your class immutable and hashable. @dataclass(frozen=True) Set unsafe_hash=True, which will create a __hash__ method but leave your class mutable. @dataclass(unsafe_hash=True) Mutability risks 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.