new-style classes, __hash__. is the documentation wrong?

G

gabor

hi,

if you have a new-style class,

it will have a __hash__ method, even if you don't define it,
because it inherits from object().

and, if you implement __eq__, then that default-hash-value will be
probably wrong.

i understand that this is a bug, and described here:

http://www.python.org/sf/660098

but please look at the documentation about __hash__ here:

http://docs.python.org/ref/customization.html

it says:

====
If a class defines mutable objects and implements a __cmp__() or
__eq__() method, it should not implement __hash__(), since the
dictionary implementation requires that a key's hash value is immutable
(if the object's hash value changes, it will be in the wrong hash bucket).
====

now, with new style classes, the class will have __hash__, whatever i
do. (well, i assume i could play with __getattribute__...).

so is that part of the documentation currently wrong?

because from what i see (the bug will not be fixed),
it's still much safer to define a __hash__ even for mutable objects
(when the object also defines __eq__).

gabor
 
K

Klaas

gabor said:
====
If a class defines mutable objects and implements a __cmp__() or
__eq__() method, it should not implement __hash__(), since the
dictionary implementation requires that a key's hash value is immutable
(if the object's hash value changes, it will be in the wrong hash bucket).
====
now, with new style classes, the class will have __hash__, whatever i
do. (well, i assume i could play with __getattribute__...).

There is a proposal to fix this, though I don't think we'll see it for
a while.

class CantHash(object):
__hash__ = None
so is that part of the documentation currently wrong?
yes

because from what i see (the bug will not be fixed),
it's still much safer to define a __hash__ even for mutable objects
(when the object also defines __eq__).

Better is to define __hash__ in a way that prevents errors:

class Mutable(object):
def __hash__(self):
raise TypeError('unhashable instance')

It will behave similarly to an old-style class that defines __eq__ and
not __hash__

-Mike
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,066
Latest member
VytoKetoReviews

Latest Threads

Top