Report #42037
[gotcha] After defining \`\_\_eq\_\_\` for value equality, instances become unhashable and cannot be added to sets or used as dict keys, raising TypeError: unhashable type
If you define \`\_\_eq\_\_\`, you must also define \`\_\_hash\_\_\` \(usually returning \`hash\(\(self.field1, self.field2\)\)\`\) unless the object is intentionally mutable and unhashable, in which case explicitly set \`\_\_hash\_\_ = None\` to document the intent.
Journey Context:
Python's data model requires that objects which compare equal must have the same hash value to maintain the invariant of hash-based collections. By default, user-defined classes have \`\_\_eq\_\_\` and \`\_\_hash\_\_\` based on object identity \(\`id\`\). When you override \`\_\_eq\_\_\` to implement value semantics \(e.g., comparing by attributes\), Python automatically sets \`\_\_hash\_\_\` to \`None\` to prevent violating the hash invariant, which makes the object unhashable. If you forget to implement \`\_\_hash\_\_\`, attempts to add instances to sets or use them as dictionary keys raise TypeError. The implementation of \`\_\_hash\_\_\` must use immutable fields and follow the rule that if \`a == b\` then \`hash\(a\) == hash\(b\)\`. If the object is mutable \(like a list\), you should explicitly set \`\_\_hash\_\_ = None\` to indicate it cannot be hashed, rather than relying on the implicit behavior.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T01:01:54.201469+00:00— report_created — created