Why can't I call hash() on an apparently hashable method of an unhashable instance?
It is a bound method, and bound methods have a reference to self
, e.g. the dictionary. This makes the method un-hashable.
You can hash the unbound dict.clear
method:
>>> d = {}>>> d.clear.__self__{}>>> d.clear.__self__ is dTrue>>> hash(d.clear)Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: unhashable type: 'dict'>>> hash(dict.clear)-9223372036586189204
Methods on instances that are hashable will themselves be hashable, so the object type for built-in bound methods implements a __hash__
method but raises TypeError
when the __self__
attribute is not hashable. This is consistent with the object.__hash__
method documentation; if you can set it to None
or not implement it at all then that is preferable but for these cases where the hashability is only known at runtime raising a TypeError
is the only option available.
Martijn is right as he very often is. If you have a dict
subclass that does implement the __hash__
method, even the bound methods become hashable
class MyHashableDict(dict): def __hash__(self): return 42x = MyHashableDict()print(x, hash(x), hash(x.clear))y = {}print(y, hash(y.clear))
Output:
{} 42 287254Traceback (most recent call last): File "y.py", line 9, in <module> print(hash(y.clear))TypeError: unhashable type: 'dict'