In another context (creation of a new one of these forms), an LLM (Qwen3.6) raised a concern about the Python contract around __hash__ overrides.
See hypha/apply/funds/models/forms.py where this function is defined in several classes:
def __hash__(self):
fields = [field.id for field in self.fields]
return hash((tuple(fields), self.sort_order, self.pk))
The issue is the inclusion of self.pk which is a mutable field. It starts as None and then is assigned a value on save.
See https://docs.python.org/3/reference/datamodel.html#object.__hash__:
If a class defines mutable objects and implements an eq() method, it should not implement hash(), since the implementation of hashable collections requires that a key’s hash value is immutable (if the object’s hash value changes, it will be in the wrong hash bucket).
For a bit I thought Django itself violated this, but on closer inspection, Django follows the contract.
Do we need to simply remove self.pk from the args and return hash((fields, self.sort_order))? What bad thing would happen then?
In another context (creation of a new one of these forms), an LLM (Qwen3.6) raised a concern about the Python contract around
__hash__overrides.See
hypha/apply/funds/models/forms.pywhere this function is defined in several classes:The issue is the inclusion of
self.pkwhich is a mutable field. It starts asNoneand then is assigned a value on save.See https://docs.python.org/3/reference/datamodel.html#object.__hash__:
For a bit I thought Django itself violated this, but on closer inspection, Django follows the contract.
Do we need to simply remove
self.pkfrom the args andreturn hash((fields, self.sort_order))? What bad thing would happen then?