<div class="gmail_quote">On Sun, Jan 15, 2012 at 8:46 AM, Stefan Behnel <span dir="ltr">&lt;<a href="mailto:stefan_ml@behnel.de">stefan_ml@behnel.de</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

Guido van Rossum, 15.01.2012 17:10:<br>
<div class="im">&gt; On Sun, Jan 15, 2012 at 6:30 AM, Stefan Behnel wrote:<br>
&gt;&gt; Terry Reedy, 14.01.2012 06:43:<br>
&gt;&gt;&gt; On 1/13/2012 8:58 PM, Gregory P. Smith wrote:<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; It is perfectly okay to break existing users who had anything depending<br>
&gt;&gt;&gt;&gt; on ordering of internal hash tables. Their code was already broken.<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Given that the doc says &quot;Return the hash value of the object&quot;, I do not<br>
&gt;&gt;&gt; think we should be so hard-nosed. The above clearly implies that there is<br>
&gt;&gt;&gt; such a thing as *the* Python hash value for an object. And indeed, that<br>
&gt;&gt; has<br>
&gt;&gt;&gt; been true across many versions. If we had written &quot;Return a hash value<br>
&gt;&gt; for<br>
&gt;&gt;&gt; the object, which can vary from run to run&quot;, the case would be different.<br>
&gt;&gt;<br>
&gt;&gt; Just a side note, but I don&#39;t think hash() is the right place to document<br>
&gt;&gt; this.<br>
&gt;<br>
&gt; You mean we shouldn&#39;t document that the hash() of a string will vary per<br>
&gt; run?<br>
<br>
</div>No, I mean that the hash() builtin function is not the right place to<br>
document the behaviour of a string hash. That should go into the string<br>
object documentation.<br>
<br>
Although, arguably, it may be worth mentioning in the docs of hash() that,<br>
in general, hash values of builtin types are bound to the lifetime of the<br>
interpreter instance (or entire runtime?) and may change after restarts. I<br>
think that&#39;s a reasonable restriction to document that prominently, even if<br>
it will only apply to str for the time being.<br><div class="im"></div></blockquote><div><br>Actually it will apply to a lot more than str, because the hash of (immutable) compound objects is often derived from the hash of the constituents, e.g. hash of a tuple.<br>

 </div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="im">
&gt;&gt; Hashing is a protocol in Python, just like indexing or iteration.<br>
&gt;&gt; Nothing keeps an object from changing its hash value due to modification,<br>
&gt;<br>
&gt; Eh? There&#39;s a huge body of cultural awareness that only immutable objects<br>
&gt; should define a hash, implying that the hash remains constant during the<br>
&gt; object&#39;s lifetime.<br>
&gt;<br>
&gt;&gt; and that would even be valid in the face of the usual dict lookup<br>
&gt;&gt; invariants if changes are only applied while the object is not referenced<br>
&gt;&gt; by any dict.<br>
&gt;<br>
&gt; And how would you know it isn&#39;t?<br>
<br>
</div>Well, if it&#39;s an object with a mutable hash then it&#39;s up to the application<br>
defining that object to make sure it&#39;s used in a sensible way. Immutability<br>
just makes your life easier. I can imagine that an object gets removed from<br>
a dict (say, a cache), modified and then reinserted, and I think it&#39;s valid<br>
to allow the modification to have an impact on the hash in this case, in<br>
order to accommodate for any changes to equality comparisons due to the<br>
modification.<br></blockquote><div><br>That could be considered valid only in a very abstract, theoretical, non-constructive way, since there is no protocol to detect removal from a dict (and you cannot assume an object is used in only one dict at a time).<br>

 </div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
That being said, it seems that the Python docs actually consider constant<br>
hashes a requirement rather than a virtue.<br>
<br>
<a href="http://docs.python.org/glossary.html#term-hashable" target="_blank">http://docs.python.org/glossary.html#term-hashable</a><br>
<br>
&quot;&quot;&quot;<br>
An object is hashable if it has a hash value which never changes during its<br>
lifetime (it needs a __hash__() method), and can be compared to other<br>
objects (it needs an __eq__() or __cmp__() method). Hashable objects which<br>
compare equal must have the same hash value.<br>
&quot;&quot;&quot;<br>
<br>
It also seems to me that the wording &quot;has a hash value which never changes<br>
during its lifetime&quot; makes it pretty clear that the lifetime of the hash<br>
value is not guaranteed to supersede the lifetime of the object (although<br>
that&#39;s a rather muddy definition - memory lifetime? or pickle-unpickle as<br>
well?).<br></blockquote><div><br>Across pickle-unpickle it&#39;s not considered the same object. Pickling at best preserves values.<br><br></div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">


However, this entry in the glossary only seems to have appeared with Py2.6,<br>
likely as a result of the abc changes. So it won&#39;t help in defending a<br>
change to the hash function.<br>
<div class="im"><br>
<br>
&gt;&gt; So the guarantees do not depend on the function hash() and may<br>
&gt;&gt; be even weaker than your above statement.<br>
&gt;<br>
&gt; There are no actual guarantees for hash(), but lots of rules for<br>
&gt; well-behaved hashes.<br>
<br>
</div>Absolutely.<br></blockquote></div><br>-- <br>--Guido van Rossum (<a href="http://python.org/~guido">python.org/~guido</a>)<br>