import ast 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)