from collections.abc import Iterator from itertools import tee from typing import Tuple, List, Collection, Dict def safehash(obj)->int: ''' Tool to take a hash of an object in a safe way. The idea is that it intercepts non-hashable types and works around it. ''' try: # first try the dumb way, because the safe way is expensive return hash(obj) except TypeError: # occurs for some built-in types if isinstance(obj, Collection): # list, set, tuple, .iterable return hash( tuple ( safehash(elt) for elt in obj ) ) if isinstance(obj, Dict): return safehash( obj.items() )