Make a hash from a dictionary, list, tuple or set to any level, containing
    only other hashable types (including any lists, tuples, sets, and dictionaries).

def make_dict_hash(o):
    """Make a hash from a dictionary, list, tuple or set to any level, containing
    only other hashable types (including any lists, tuples, sets, and dictionaries).
    """
    if isinstance(o, (set, tuple, list)):
        return tuple([make_dict_hash(e) for e in o])
    elif not isinstance(o, dict):
        return hash(o)

    new_o = copy.deepcopy(o)
    for k, v in new_o.items():
        new_o[k] = make_dict_hash(v)

    return hash(tuple(frozenset(sorted(new_o.items()))))