def stableShaHashForObject(x, unhashableObjectPolicy = allObjectsShouldBeHashable):
    if x in memoizedHashes_:
        return memoizedHashes_[x]
    
    assert type(x) not in badTypes, type(x)
    
    #first, check if its a computed graph location or a function. These have special forms required
    #to make them work
    if type(x) in hashFunctionsByType:
        h = hashFunctionsByType[type(x)](x, unhashableObjectPolicy)
        
        memoizedHashes_[x] = h
        return h
    
    if isinstance(x, funcType_):
        h = stableHashForIterable_( 
            (getClosure(x),
                x.func_code.co_code, 
                x.func_globals['__version__'] if '__version__' in x.func_globals else 0
                ),
            unhashableObjectPolicy
            )
        memoizedHashes_[x] = h
        return h

    #tuples, lists, dicts, and sets, we can't use the memo because of the weakrefs. So,
    #we just hash their hashes. If they have anything big/complex in them, we'll hash those.
    if isinstance(x, tuple) or isinstance(x, list):
        return stableHashOfHashes_(
            [stableShaHashForObject(x, unhashableObjectPolicy) for x in x]
            )
    
    elif isinstance(x, dict):
        return stableHashOfHashes_(
            sorted([stableShaHashForObject(x, unhashableObjectPolicy) for x in x.iteritems()])
            )

    elif isinstance(x, set) or isinstance(x, frozenset):
        return stableHashOfHashes_(
            sorted([stableShaHashForObject(elt, unhashableObjectPolicy) for elt in x])
            )

    elif x is None:
        return theNoneHash_

    if isinstance(x,unicode):
        x = str(x)

    #just a regular object. first, see if it has a getstate function
    objectState = None
    try:
        objectState = (x.__class__.__getstate__(x), x.__class__)
    except AttributeError:
        pass

    if objectState is None:
        try:
            objectState = (x.__class__, x.__class__.__stable_hash_state__(x))
        except AttributeError:
            pass

    if objectState is not None:
        #yes, so we use that
        h = stableHashForIterable_(objectState, unhashableObjectPolicy)
    else:
        #no - check if we should use pickle
        if type(x) in pickleablePrimitiveTypes:
            h = str(HashNative.Hash.sha1(pickle.dumps(x,0)))
        else:
            #we can't use pickle, so the object instance ID is the next best thing
            h = unhashableObjectPolicy(x)

    try:
        memoizedHashes_[x] = h
    except TypeError:
        #some types can't go in the memo
        pass

    return h
dataset/ETHPy150Open ufora/ufora/ufora/core/math/StableHashFunction.py/stableShaHashForObject/original