mirror of https://github.com/python/cpython
Merge #14617: clarify discussion of interrelationship of __eq__ and __hash__.
This commit is contained in:
commit
a96be78ed1
|
@ -1271,22 +1271,22 @@ Basic customization
|
||||||
and ``x.__hash__()`` returns an appropriate value such that ``x == y``
|
and ``x.__hash__()`` returns an appropriate value such that ``x == y``
|
||||||
implies both that ``x is y`` and ``hash(x) == hash(y)``.
|
implies both that ``x is y`` and ``hash(x) == hash(y)``.
|
||||||
|
|
||||||
Classes which inherit a :meth:`__hash__` method from a parent class but
|
A class that overrides :meth:`__eq__` and does not define :meth:`__hash__`
|
||||||
change the meaning of :meth:`__eq__` such that the hash value returned is no
|
will have its :meth:`__hash__` implicitly set to ``None``. When the
|
||||||
longer appropriate (e.g. by switching to a value-based concept of equality
|
:meth:`__hash__` method of a class is ``None``, instances of the class will
|
||||||
instead of the default identity based equality) can explicitly flag
|
raise an appropriate :exc:`TypeError` when a program attempts to retrieve
|
||||||
themselves as being unhashable by setting ``__hash__ = None`` in the class
|
their hash value, and will also be correctly identified as unhashable when
|
||||||
definition. Doing so means that not only will instances of the class raise an
|
checking ``isinstance(obj, collections.Hashable``).
|
||||||
appropriate :exc:`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 :meth:`__hash__` to explicitly raise :exc:`TypeError`).
|
|
||||||
|
|
||||||
If a class that overrides :meth:`__eq__` needs to retain the implementation
|
If a class that overrides :meth:`__eq__` needs to retain the implementation
|
||||||
of :meth:`__hash__` from a parent class, the interpreter must be told this
|
of :meth:`__hash__` from a parent class, the interpreter must be told this
|
||||||
explicitly by setting ``__hash__ = <ParentClass>.__hash__``. Otherwise the
|
explicitly by setting ``__hash__ = <ParentClass>.__hash__``.
|
||||||
inheritance of :meth:`__hash__` will be blocked, just as if :attr:`__hash__`
|
|
||||||
had been explicitly set to :const:`None`.
|
If a class that does not override :meth:`__eq__` wishes to suppress hash
|
||||||
|
support, it should include ``__hash__ = None`` in the class definition.
|
||||||
|
A class which defines its own :meth:`__hash__` that explicitly raises
|
||||||
|
a :exc:`TypeError` would be incorrectly identified as hashable by
|
||||||
|
an ``isinstance(obj, collections.Hashable)`` call.
|
||||||
|
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
Loading…
Reference in New Issue