def _convert()

in pywb/ftwhelper.py [0:0]


def _convert(source, target_type):
    if not hasattr(source, "FTW_TYPE") \
            or source.FTW_TYPE == FTW_TYPE.INVALID \
            or target_type == FTW_TYPE.INVALID:
        raise ValueError("%s is invalid type" % (source, ))
    if source.FTW_TYPE > FTW_TYPE:
        raise ValueError(
            "Cannot do this upper convert from %s to %s"
            % (source.FTW_TYPE, FTW_TYPE))

    if source.FTW_TYPE == FTW_TYPE:
        yield source
    # ftw.stage => pkt
    elif source.FTW_TYPE == FTW_TYPE.STAGE \
            and target_type == FTW_TYPE.PACKETS:
        http_ua = ftw.http.HttpUA()
        http_ua.request_object = source.ORIGINAL_DATA.input
        http_ua.build_request()
        packet = FtwStr(
            FTW_TYPE.PACKETS,
            source.ORIGINAL_FILE,
            http_ua.request)
        yield packet
    # ftw.test => ftw.stage
    elif source.FTW_TYPE == FTW_TYPE.TEST \
            and target_type == FTW_TYPE.STAGE:
        for ftw_stage in source.ORIGINAL_DATA.stages:
            stage = FtwDict(
                FTW_TYPE.STAGE,
                source.ORIGINAL_FILE,
                ftw_stage,
                ftw_stage.stage_dict)
            yield stage
    # ftw.rule => ftw.test
    elif source.FTW_TYPE == FTW_TYPE.RULE \
            and target_type == FTW_TYPE.TEST:
        for ftw_test in source.ORIGINAL_DATA.tests:
            test = FtwDict(
                FTW_TYPE.TEST,
                source.ORIGINAL_FILE,
                ftw_test,
                ftw_test.test_dict)
            yield test
    # ftw.* => ftw.*
    else:
        internal_type = source.FTW_TYPE + 1
        source = _convert(source, internal_type)
        visitor = source.__iter__()
        visit_stack = [visitor]
        while visit_stack:
            visitor = visit_stack[-1]
            try:
                visitor = next(visitor)
                if visitor.FTW_TYPE < target_type:
                    visitor = _convert(visitor, visitor.FTW_TYPE + 1)
                    visit_stack.append(visitor)
                else:
                    yield visitor
            except StopIteration:
                visit_stack.pop()