Matt Giuca wrote: > > > It's probably a good idea to implement __hash__ for objects that > implement comparisons, but it won't always work and it is certainly > not needed, unless you intend to use them as dictionary keys. > > > > > > So you're suggesting that we document something like. > > Classes that represent mutable values and define equality methods > are free to define __hash__ so long as you don't mind them being > used incorrectly if treated as dictionary keys... > > Technically true, but not very helpful in my opinion... :-) > > > No, I think he was suggesting we document that if a class overrides > __eq__, it's a good idea to also implement __hash__, so it can be used > as a dictionary key.
I strongly advise people interested in this topic to take a closer look at the functionality that was added to address issue 2235. The "don't inherit __hash__" behaviour has been backported from 3.0 and broke a bunch of code, but the naive fix of reverting to the 2.5 behaviour proceeded to make the 2.6 version of collections.Hashable completely useless (since pretty much *everything* then claimed to be hashable, including all of the container types in the standard library). After thrashing out those problems, the 2.6 behaviour ended up being: - __hash__ is still inherited by default - you can block inheritance explicitly by setting "__hash__ = None" in the class definition or on the class object - for a class defined in C, you can block __hash__ inheritance by setting the tp_hash slot to PyObject_HashNotImplemented - using one of the above approaches will cause hash(obj) to raise a TypeError, as will calling the tp_hash slot directly - unlike defining your own __hash__ method, using one of the above techniques will also mean that isinstance(obj, collections.Hashable) will also return False - defining __eq__ and/or __cmp__ without defining __hash__ will lead to a Py3k Warning being raised on the class definition when run with the -3 switch The Python 3.0 behaviour is similar to the above, except that the unconditional inheritance of __hash__ is gone. If you define __eq__ or __cmp__ without defining __hash__, __hash__ will NOT be inherited from the parent class - instead, it will be set to None. The documentation of all of this could definitely use a bit more work - that's why I reopened 2235 in response to Michael's post. Cheers, Nick. -- Nick Coghlan | [EMAIL PROTECTED] | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com