<div dir="ltr"><br><div class="gmail_quote"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">Note that only instances have the default hash value id(obj). This<br>
is not true in general. Most types don't implement the tp_hash<br>
slot and thus are not hashable. Indeed, mutable types should not<br>
implement that slot unless they know what they're doing :-)</blockquote><div><br>By "instances" you mean "instances of user-defined classes"?<br>(I carefully avoid the term "instance" on its own, since I believe that was phased out when they merged types and classes; it probably still exists in the C API but shouldn't be mentioned in Python-facing documentation).<br>
<br>But anyway, yes, we should make that distinction.<br><br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">Sorry, I wasn't clear enough: with "not defining an equal comparison"<br>
I meant that an equal comparison does not succeed, ie. raises an<br>
exception or returns Py_NotImplemented (at the C level).</blockquote><div><br>Oh OK. I didn't even realise it was "valid" or "usual" to explicitly block __eq__ like that.<br> </div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Again, the situation is better at the C level, since types<br>
don't have a default tp_hash implementation, so have to explicitly<br>
code such a slot in order for hash(obj) to work.</blockquote><div><br>Yes but I gather that this "data model" document we are talking about is not designed for C authors, but Python authors, so it should be written for the point of view of people coding only in Python. (Only the "Extending and Embedding" and the "C API" documents are for C authors).<br>
<br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">The documentation should probably say:<br>
<br>
"If you implement __cmp__ or<br>
__eq__ on a class, also implement a __hash__ method (and either<br>
have it raise an exception or return a valid non-changing hash<br>
value for the object)."<br>
</blockquote><div><br>I agree, except maybe not for the Python 3 docs. As long as the behaviour I am observing is well-defined and not just a side-effect which could go away -- that is, if you define __eq__/__cmp__ but not __hash__, in a user-defined class, it raises a TypeError -- then I think it isn't necessary to recommend implementing a __hash__ method and raising a TypeError. Better just to leave as-is ("if it defines
<a title="object.__cmp__" class="reference" href="http://docs.python.org/dev/3.0/reference/datamodel.html#object.__cmp__"><tt class="xref docutils literal"><span class="pre">__cmp__()</span></tt></a> or <a title="object.__eq__" class="reference" href="http://docs.python.org/dev/3.0/reference/datamodel.html#object.__eq__"><tt class="xref docutils literal"><span class="pre">__eq__()</span></tt></a> but not <a title="object.__hash__" class="reference" href="http://docs.python.org/dev/3.0/reference/datamodel.html#object.__hash__"><tt class="xref docutils literal"><span class="pre">__hash__()</span></tt></a>, its instances
will not be usable as dictionary keys") and clarify the later statement.<br> </div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><br>
"If you implement __hash__ on classes, you should consider implementing<br>
__eq__ and/or __cmp__ as well, in order to control how dictionaries use<br>
your objects."</blockquote><div><br>I don't think I agree with that. I'm not sure why you'd implement __hash__ without __eq__ and/or __cmp__, but it doesn't cause issues so we may as well not address it.<br>
</div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">In general, it's probably best to always implement both methods<br>
on classes, even if the application will just use one of them.<br>
<div><div></div><div class="Wj3C7c"></div></div></blockquote><div><br>Well it certainly is for new-style classes in the 2.x branch. I don't think you should implement __hash__ in Python 3 if you just want a non-hashable object (since this is the default behaviour anyway).<br>
<br>A lot of my opinion here, though, which doesn't count very much -- so I'm just making suggestions.<br><br>Matt<br></div></div></div>