Return hashable structure from non-hashable structure using hippie means

    dict and set are sorted and their content subjected to same hippie means.

    Note that the key identifies the current content of the structure.

def make_key_hippie(obj, typed=True):
    """Return hashable structure from non-hashable structure using hippie means

    dict and set are sorted and their content subjected to same hippie means.

    Note that the key identifies the current content of the structure.

    """
    ftype = type if typed else lambda o: None
    if is_hashable(obj):
        ## DO NOT RETURN hash(obj), as hash collision would generate bad
        ## cache collisions.
        return obj, ftype(obj)
    ## should we try to convert to frozen{set,dict} to get the C
    ## hashing function speed ? But the convertion has a cost also.
    if isinstance(obj, set):
        obj = sorted(obj)
    if isinstance(obj, (list, tuple)):
        return tuple(make_key_hippie(e, typed) for e in obj)
    if isinstance(obj, dict):
        return tuple(sorted(((make_key_hippie(k, typed),
                              make_key_hippie(v, typed))
                             for k, v in obj.items())))
    raise ValueError(
        "%r can not be hashed. Try providing a custom key function."
        % obj)