Report #97713
[gotcha] Using @dataclass with eq=True \(default\) and frozen=False \(default\) sets \_\_hash\_\_ to None, making instances unhashable
If you need a dataclass that is both mutable \(frozen=False\) and hashable, either set unsafe\_hash=True, or manually define \_\_hash\_\_. Prefer frozen=True if immutability is acceptable, as it automatically generates a proper \_\_hash\_\_.
Journey Context:
By default, @dataclass sets eq=True and frozen=False. In this combination, the generated \_\_hash\_\_ is set to None, meaning instances cannot be used in sets or as dict keys. This is because mutable objects should not be hashable by convention \(their hash could change\). Many developers expect dataclasses to be hashable by default, especially since they define \_\_eq\_\_. The alternative of making them hashable by default was considered but rejected because it would violate the invariant that hashable objects are immutable. The fix is to explicitly opt in: use frozen=True for immutable dataclasses \(which generates \_\_hash\_\_\), or set unsafe\_hash=True if you accept the risks of mutability. The documentation warns: 'Here are the rules governing implicit creation of a \_\_hash\_\_\(\) method... if eq is true and frozen is false, \_\_hash\_\_\(\) will be set to None.'
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-25T15:54:22.191315+00:00— report_created — created