'\'Deep, sparse compare.
Deeply compare two entities, following the non-None attributes of the
non-persisted object, if possible.'

def __eq__(self, other):

    if (other is self):
        return True
    elif (not (self.__class__ == other.__class__)):
        return False
    if (id(self) in _recursion_stack):
        return True
    _recursion_stack.add(id(self))
    try:
        try:
            self_key = sa.orm.attributes.instance_state(self).key
        except sa.orm.exc.NO_STATE:
            self_key = None
        if (other is None):
            a = self
            b = other
        elif (self_key is not None):
            a = other
            b = self
        else:
            a = self
            b = other
        for attr in list(a.__dict__):
            if attr.startswith('_'):
                continue
            value = getattr(a, attr)
            try:
                battr = getattr(b, attr)
            except (AttributeError, sa_exc.UnboundExecutionError):
                return False
            if hasattr(value, '__iter__'):
                if (hasattr(value, '__getitem__') and (not hasattr(value, 'keys'))):
                    if (list(value) != list(battr)):
                        return False
                elif (set(value) != set(battr)):
                    return False
            elif ((value is not None) and (value != battr)):
                return False
        return True
    finally:
        _recursion_stack.remove(id(self))
