tests for the codeobject creation stage of the compiler not exposed on code object code for return xy2 tests for the code object creation stage of the compiler not exposed on code object code for return x y 2 x y 2 lambda x 2
import types

from test.support.bytecode_helper import AssemblerTestCase




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":
                
                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},
        }

        
        insts = [
            ('RESUME', 0),
            ('LOAD_FAST', 0, 1),   
            ('LOAD_FAST', 1, 1),   
            ('BINARY_OP', 0, 1),   
            ('LOAD_CONST', 0, 1),  
            ('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),                     
            ('LOAD_CONST', 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)