def get_converter(old_type, new_type):
    ' If there is a converter old_type -> new_type, return it. Else return\n    None. If a chain of converters is necessary, return it as a tuple or\n    list (starting with the innermost, first-to-apply converter). '
    if (new_type == TYPE_OBJECT):
        return identity
    if (old_type == new_type):
        return identity
    converters_from_old = TYPE_CONVERTERS.get(old_type)
    if (converters_from_old is None):
        return None
    converter = converters_from_old.get(new_type)
    if (converter is not None):
        return converter
    else:
        backtrace = converters_from_old.copy()
        new_backtrace = backtrace.copy()
        break_all = False
        while True:
            newest_backtrace = {}
            for t in new_backtrace:
                for new_t in TYPE_CONVERTERS.get(t, {}):
                    if (new_t not in backtrace):
                        newest_backtrace[new_t] = t
                        backtrace[new_t] = t
                        if (new_t == new_type):
                            break_all = True
                            break
                if break_all:
                    break
            if (break_all or (not newest_backtrace)):
                break
            new_backtrace = newest_backtrace
        if (new_type in backtrace):
            converter_chain = []
            t = new_type
            while ((t in backtrace) and isinstance(backtrace[t], Type)):
                converter_chain.insert(0, TYPE_CONVERTERS[backtrace[t]][t])
                t = backtrace[t]
            converter_chain.insert(0, TYPE_CONVERTERS[old_type][t])
            return converter_chain
    return None
If there is a converter old_type -> new_type, return it. Else return
None. If a chain of converters is necessary, return it as a tuple or
list (starting with the innermost, first-to-apply converter).
def get_converter(old_type, new_type):
    ' If there is a converter old_type -> new_type, return it. Else return\n    None. If a chain of converters is necessary, return it as a tuple or\n    list (starting with the innermost, first-to-apply converter). '
    if (new_type == TYPE_OBJECT):
        return identity
    if (old_type == new_type):
        return identity
    converters_from_old = TYPE_CONVERTERS.get(old_type)
    if (converters_from_old is None):
        return None
    converter = converters_from_old.get(new_type)
    if (converter is not None):
        return converter
    else:
        backtrace = converters_from_old.copy()
        new_backtrace = backtrace.copy()
        break_all = False
        while True:
            newest_backtrace = {}
            for t in new_backtrace:
                for new_t in TYPE_CONVERTERS.get(t, {}):
                    if (new_t not in backtrace):
                        newest_backtrace[new_t] = t
                        backtrace[new_t] = t
                        if (new_t == new_type):
                            break_all = True
                            break
                if break_all:
                    break
            if (break_all or (not newest_backtrace)):
                break
            new_backtrace = newest_backtrace
        if (new_type in backtrace):
            converter_chain = []
            t = new_type
            while ((t in backtrace) and isinstance(backtrace[t], Type)):
                converter_chain.insert(0, TYPE_CONVERTERS[backtrace[t]][t])
                t = backtrace[t]
            converter_chain.insert(0, TYPE_CONVERTERS[old_type][t])
            return converter_chain
    return None