From: R David Murray Date: Tue, 11 Sep 2012 17:02:13 +0000 (-0400) Subject: Merge #14617: clarify discussion of interrelationship of __eq__ and __hash__. X-Git-Tag: v3.3.1rc1~818^2^2~86 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a96be78ed151ea6a429b730df78defcd7e69c18c;p=python Merge #14617: clarify discussion of interrelationship of __eq__ and __hash__. --- a96be78ed151ea6a429b730df78defcd7e69c18c diff --cc Doc/reference/datamodel.rst index b2ce4ffe73,2ddb852468..1c8c190fc8 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@@ -1266,49 -1250,29 +1266,49 @@@ Basic customizatio immutable (if the object's hash value changes, it will be in the wrong hash bucket). - User-defined classes have :meth:`__eq__` and :meth:`__hash__` methods by default; with them, all objects compare unequal (except with themselves) - and ``x.__hash__()`` returns ``id(x)``. + and ``x.__hash__()`` returns an appropriate value such that ``x == y`` + implies both that ``x is y`` and ``hash(x) == hash(y)``. - Classes which inherit a :meth:`__hash__` method from a parent class but - change the meaning of :meth:`__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 :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`). + A class that overrides :meth:`__eq__` and does not define :meth:`__hash__` + will have its :meth:`__hash__` implicitly set to ``None``. When the + :meth:`__hash__` method of a class is ``None``, instances of the class will + raise an appropriate :exc:`TypeError` when a program attempts to retrieve + their hash value, and will also be correctly identified as unhashable when + checking ``isinstance(obj, collections.Hashable``). 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 - explicitly by setting ``__hash__ = .__hash__``. Otherwise the - inheritance of :meth:`__hash__` will be blocked, just as if :attr:`__hash__` - had been explicitly set to :const:`None`. + explicitly by setting ``__hash__ = .__hash__``. + + 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. - See also the :option:`-R` command-line option. + + .. note:: + + By default, the :meth:`__hash__` values of str, bytes and datetime + objects are "salted" with an unpredictable random value. Although they + remain constant within an individual Python process, they are not + predictable between repeated invocations of Python. + + This is intended to provide protection against a denial-of-service caused + by carefully-chosen inputs that exploit the worst case performance of a + dict insertion, O(n^2) complexity. See + http://www.ocert.org/advisories/ocert-2011-003.html for details. + + Changing hash values affects the iteration order of dicts, sets and + other mappings. Python has never made guarantees about this ordering + (and it typically varies between 32-bit and 64-bit builds). + + See also :envvar:`PYTHONHASHSEED`. + + .. versionchanged:: 3.3 + Hash randomization is enabled by default. .. method:: object.__bool__(self)