def tuple_values_dict(currtuple, newtuple=None):
    """Return dictionary of attributes with their values

    :param currtuple: current Tuple
    :param newtuple: optional Tuple with new values
    :return: dictionary of attributes and values
    """
    valdict = {}
    for attr in currtuple.__dict__:
        if attr in RESERVED_ATTRIBUTE_NAMES:
            continue
        currval = getattr(currtuple, attr)
        if newtuple is None:
            valdict.update({attr: currval})
        elif hasattr(newtuple, attr):
            newval = getattr(newtuple, attr)
            try:
                diff = currval != newval
            except __HOLE__:
                # TODO: more needed for naive vs. aware datetime/time
                if isinstance(newval, datetime) or isinstance(newval, time):
                    if newval.utcoffset() is None:
                        diff = True
                else:
                    raise
            if diff:
                valdict.update({attr: newval})
    if newtuple is not None:
        for newattr in newtuple.__dict__:
            if newattr in RESERVED_ATTRIBUTE_NAMES:
                continue
            if newattr not in currtuple.__dict__:
                valdict.update({newattr: getattr(newtuple, newattr)})
    return valdict
dataset/ETHPy150Open perseas/Pyrseas/pyrseas/relation/tuple.py/tuple_values_dict