Message158644
From http://docs.python.org/py3k/reference/datamodel.html#object.__hash__
-----------------------------------------------------------------------
Classes which inherit a __hash__() method from a parent class but change the meaning of __eq__() such that the hash value returned is no longer appropriate (e.g. by switching to a value-based concept of equality instead of the default identity based equality) can explicitly flag themselves as being unhashable by setting __hash__ = None in the class definition. Doing so means that not only will instances of the class raise an appropriate TypeError when a program attempts to retrieve their hash value, but they will also be correctly identified as unhashable when checking isinstance(obj, collections.Hashable) (unlike classes which define their own __hash__() to explicitly raise TypeError).
If a class that overrides __eq__() needs to retain the implementation of __hash__() from a parent class, the interpreter must be told this explicitly by setting __hash__ = <ParentClass>.__hash__. Otherwise the inheritance of __hash__() will be blocked, just as if __hash__ had been explicitly set to None.
-----------------------------------------------------------------------
The first paragraph says the user has to change __hash__ if it's different because of changes to __eq__, the second paragraph says __hash__ is automatically removed if __eq__ is changed; the second paragraph reflects reality.
Proposed change:
-----------------------------------------------------------------------
Classes which change the meaning of __eq__() (thus losing automatic delegation to the parent class' __hash__) can explicitly flag themselves as being unhashable by setting __hash__ = None in the class definition (which is otherwise done implicity). Having __hash__ set to None, either explicitly or implicitly, means that not only will instances of the class raise an appropriate TypeError when a program attempts to retrieve their hash value, but they will also be correctly identified as unhashable when checking isinstance(obj, collections.Hashable) (unlike classes which define their own __hash__() to explicitly raise TypeError).
If a class that overrides __eq__() needs to retain the implementation of __hash__() from a parent class, the interpreter must be told this explicitly by setting __hash__ = <ParentClass>.__hash__.
-----------------------------------------------------------------------
Patch attached. |
|
Date |
User |
Action |
Args |
2012-04-18 17:55:28 | ethan.furman | set | recipients:
+ ethan.furman, docs@python |
2012-04-18 17:55:28 | ethan.furman | set | messageid: <1334771728.14.0.513778784524.issue14617@psf.upfronthosting.co.za> |
2012-04-18 17:55:27 | ethan.furman | link | issue14617 messages |
2012-04-18 17:55:27 | ethan.furman | create | |
|