Adding Deep Immutability

This won’t work because a type is determined to be unhashable only if its __hash__ attribute is None. This means that the __hash__ attribute of an unhashable mutable type can’t be made a dynamic method to make an instance hashable when frozen.

Yes, I think this is the way to go, and to make isinstance(obj, Hashable) work for frozen objects we can make changes to abc and collections.abc such that:

  1. abc.ABCMeta offers not just a __subclasshook__ but also an __instancehook__ that is called by its __instancecheck__ before falling back to calling __subclasscheck__.
  2. collections.abc.Hashable overrides the __instancehook__ to look for type(obj).__frozen_hash__ if isfrozen(obj) is true.

This allows isinstance(obj, Hashable) to take the state of the instance itself into account. Without the change it currently can only check its type.