Broken __hash__ methods
|Reported by:||akaariai||Owned by:||aaugustin|
|Has patch:||no||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
We have some classes which defined __eq__ but not __hash__ before the py3 support. Python 3 doesn't allow these objects to be used in dicts, so the fix was to introduce:
__hash__ = object.__hash__
However, this is doing the wrong thing. The Python docs say that the only requirement is that objects which compare equal have the same hash value. However, if we define __eq__ so that it makes object with different id() values equal, then object.__hash__ is failing this requirement.
This isn't a regression - we have done the same thing implicitly in python 2 for ages. However, py3 introduced the requirement of defining __hash__ exactly to avoid this situation, so we should consider fixing the __hash__ functions somehow.
I am not sure what the implications of abusing object.__hash__ are.
The problematic cases seem to be:
> git grep '__hash__ = obj' django/db/backends/__init__.py: __hash__ = object.__hash__ django/db/models/fields/__init__.py: __hash__ = object.__hash__ django/dispatch/saferef.py: __hash__ = object.__hash__ django/test/html.py: __hash__ = object.__hash__ django/utils/functional.py: __hash__ = object.__hash__
Change History (10)
comment:1 Changed 3 years ago by aaugustin
- Component changed from Uncategorized to Python 3
- Triage Stage changed from Unreviewed to Accepted
comment:2 Changed 3 years ago by regebro
- Keywords sprint2013 added
- Owner changed from nobody to regebro
- Status changed from new to assigned
Changed 3 years ago by regebro
comment:8 Changed 3 years ago by Aymeric Augustin <aymeric.augustin@…>
- Resolution set to fixed
- Status changed from assigned to closed