import types

from test.support.bytecode_helper import AssemblerTestCase


# Tests for the code-object creation stage of the compiler.

class IsolatedAssembleTests(AssemblerTestCase):

    def complete_metadata(self, metadata, filename="myfile.py"):
        if metadata is None:
            metadata = {}
        for key in ['name', 'qualname']:
            metadata.setdefault(key, key)
        for key in ['consts']:
            metadata.setdefault(key, [])
        for key in ['names', 'varnames', 'cellvars', 'freevars', 'fasthidden']:
            metadata.setdefault(key, {})
        for key in ['argcount', 'posonlyargcount', 'kwonlyargcount']:
            metadata.setdefault(key, 0)
        metadata.setdefault('firstlineno', 1)
        metadata.setdefault('filename', filename)
        return metadata

    def assemble_test(self, insts, metadata, expected):
        metadata = self.complete_metadata(metadata)
        insts = self.complete_insts_info(insts)

        co = self.get_code_object(metadata['filename'], insts, metadata)
        self.assertIsInstance(co, types.CodeType)

        expected_metadata = {}
        for key, value in metadata.items():
            if key == "fasthidden":
                # not exposed on code object
                continue
            if isinstance(value, list):
                expected_metadata[key] = tuple(value)
            elif isinstance(value, dict):
                expected_metadata[key] = tuple(value.keys())
            else:
                expected_metadata[key] = value

        for key, value in expected_metadata.items():
            self.assertEqual(getattr(co, "co_" + key), value)

        f = types.FunctionType(co, {})
        for args, res in expected.items():
            self.assertEqual(f(*args), res)

    def test_simple_expr(self):
        metadata = {
            'filename' : 'avg.py',
            'name'     : 'avg',
            'qualname' : 'stats.avg',
            'consts'   : {2 : 0},
            'argcount' : 2,
            'varnames' : {'x' : 0, 'y' : 1},
        }

        # code for "return (x+y)/2"
        insts = [
            ('RESUME', 0),
            ('LOAD_FAST', 0, 1),   # 'x'
            ('LOAD_FAST', 1, 1),   # 'y'
            ('BINARY_OP', 0, 1),   # '+'
            ('LOAD_CONST', 0, 1),  # 2
            ('BINARY_OP', 11, 1),   # '/'
            ('RETURN_VALUE', 1),
        ]
        expected = {(3, 4) : 3.5, (-100, 200) : 50, (10, 18) : 14}
        self.assemble_test(insts, metadata, expected)


    def test_expression_with_pseudo_instruction_load_closure(self):

        def mod_two(x):
            def inner():
                return x
            return inner() % 2

        inner_code = mod_two.__code__.co_consts[1]
        assert isinstance(inner_code, types.CodeType)

        metadata = {
            'filename' : 'mod_two.py',
            'name'     : 'mod_two',
            'qualname' : 'nested.mod_two',
            'cellvars' : {'x' : 0},
            'consts': {None: 0, inner_code: 1, 2: 2},
            'argcount' : 1,
            'varnames' : {'x' : 0},
        }

        instructions = [
            ('RESUME', 0,),
            ('LOAD_CLOSURE', 0, 1),
            ('BUILD_TUPLE', 1, 1),
            ('LOAD_CONST', 1, 1),
            ('MAKE_FUNCTION', 0, 2),
            ('SET_FUNCTION_ATTRIBUTE', 8, 2),
            ('PUSH_NULL', 0, 1),
            ('CALL', 0, 2),                     # (lambda: x)()
            ('LOAD_CONST', 2, 2),               # 2
            ('BINARY_OP', 6, 2),                # %
            ('RETURN_VALUE', 0, 2)
        ]

        expected = {(0,): 0, (1,): 1, (2,): 0, (120,): 0, (121,): 1}
        self.assemble_test(instructions, metadata, expected)
