#!/usr/bin/env python
from xdis.version_info import PYTHON_VERSION_TRIPLE, IS_PYPY, version_tuple_to_str
from uncompyle6.scanner import get_scanner
def bug(state, slotstate):
    if state:
        if slotstate is not None:
            for key, value in slotstate.items():
                setattr(state, key, 2)

# From 2.7 disassemble
# Problem is not getting while, because
# COME_FROM not added
def bug_loop(disassemble, tb=None):
    if tb:
        try:
            tb = 5
        except AttributeError:
            raise RuntimeError
        while tb: tb = tb.tb_next
    disassemble(tb)

def test_if_in_for():
    code = bug.__code__
    scan = get_scanner(PYTHON_VERSION_TRIPLE)
    if (2, 7) <= PYTHON_VERSION_TRIPLE < (3, 1) and not IS_PYPY:
        scan.build_instructions(code)
        fjt = scan.find_jump_targets(False)

        ## FIXME: the data below is wrong.
        ## we get different results currenty as well.
        ## We need to probably fix both the code
        ## and the test below
        # assert {15: [3], 69: [66], 63: [18]} == fjt
        # assert scan.structs == \
        #   [{'start': 0, 'end': 72, 'type': 'root'},
        #    {'start': 15, 'end': 66, 'type': 'if-then'},
        #    {'start': 31, 'end': 59, 'type': 'for-loop'},
        #    {'start': 62, 'end': 63, 'type': 'for-else'}]

        code = bug_loop.__code__
        scan.build_instructions(code)
        fjt = scan.find_jump_targets(False)
        assert{64: [42], 67: [42, 42], 42: [16, 41], 19: [6]} == fjt
        assert scan.structs == [
            {'start': 0, 'end': 80, 'type': 'root'},
            {'start': 3, 'end': 64, 'type': 'if-then'},
            {'start': 6, 'end': 15, 'type': 'try'},
            {'start': 19, 'end': 38, 'type': 'except'},
            {'start': 45, 'end': 67, 'type': 'while-loop'},
            {'start': 70, 'end': 64, 'type': 'while-else'},
            # previous bug was not mistaking while-loop for if-then
            {'start': 48, 'end': 67, 'type': 'while-loop'}]

    elif (3, 2) < PYTHON_VERSION_TRIPLE <= (3, 4):
        scan.build_instructions(code)
        fjt  = scan.find_jump_targets(False)
        assert {69: [66], 63: [18]} == fjt
        assert scan.structs == \
          [{'end': 72, 'type': 'root', 'start': 0},
           {'end': 66, 'type': 'if-then', 'start': 6},
           {'end': 63, 'type': 'if-then', 'start': 18},
           {'end': 59, 'type': 'for-loop', 'start': 31},
           {'end': 63, 'type': 'for-else', 'start': 62}]
    else:
        print("FIXME: should fix for %s" % version_tuple_to_str())
        assert True
    return
