The docs say that a class is hashable as long as it defines __hash__ method and __eq__ method. However:
class X(list):
# read-only interface of `tuple` and `list` should be the same, so reuse tuple.__hash__
__hash__ = tuple.__hash__
x1 = X()
s = {x1} # TypeError: unhashable type: 'X'
What makes X unhashable?
Note that I must have identical lists (in terms of regular equality) to be hashed to the same value; otherwise, I will violate this requirement on hash functions:
The only required property is that objects which compare equal have
the same hash value
The docs do warn that a hashable object shouldn’t be modified during its lifetime, and of course I don’t modify instances of X after creation. Of course, the interpreter won’t check that anyway.
Simply setting the
__hash__method to that of thetupleclass is not enough. You haven’t actually told it how to hash any differently. tuples are hashable because they are immutable. If you really wanted to make you specific example work, it might be like this:In this case you are actually defining how to hash your custom list subclass. You just have to define exactly how it can generate a hash. You can hash on whatever you want, as opposed to using the tuple’s hashing method: