def validate_uncompyle(text, mode="exec"): """ Validate decompilation of the given source code. :param text: Source to validate decompilation of. """ original_code = compile(text, "<string>", mode) original_dis = _dis_to_text(original_code) original_text = text deparsed = code_deparse(original_code, out=six.StringIO(), version=PYTHON_VERSION, compile_mode=mode) uncompyled_text = deparsed.text uncompyled_code = compile(uncompyled_text, "<string>", "exec") if not are_code_objects_equal(uncompyled_code, original_code): uncompyled_dis = _dis_to_text(uncompyled_text) def output(text, dis): width = 60 return "\n\n".join([ " SOURCE CODE ".center(width, "#"), text.strip(), " BYTECODE ".center(width, "#"), dis, ]) original = output(original_text, original_dis) uncompyled = output(uncompyled_text, uncompyled_dis) print_diff(original, uncompyled) assert "original" == "uncompyled"
def run_deparse(expr: str, compile_mode: bool, debug=False) -> object: if debug: debug_opts = {"asm": "both", "tree": True, "grammar": True} else: debug_opts = {"asm": False, "tree": False, "grammar": False} if compile_mode == "lambda": compile_mode = "eval" code = compile(expr + "\n", "<string %s>" % expr, compile_mode) deparsed = code_deparse(code, out=out, compile_mode=compile_mode, debug_opts=debug_opts) return deparsed
def test_single_mode(): single_expressions = ( "i = 1", "i and (j or k)", "i += 1", "i = j % 4", "i = {}", "i = []", "for i in range(10):\n i\n", "for i in range(10):\n for j in range(10):\n i + j\n", # 'try:\n i\nexcept Exception:\n j\nelse:\n k\n' ) for expr in single_expressions: code = compile(expr + "\n", "<string>", "single") assert code_deparse(code, compile_mode="single").text == expr + "\n"
def test_single_mode(): single_expressions = ( 'i = 1', 'i and (j or k)', 'i += 1', 'i = j % 4', 'i = {}', 'i = []', 'for i in range(10):\n i\n', 'for i in range(10):\n for j in range(10):\n i + j\n', # 'try:\n i\nexcept Exception:\n j\nelse:\n k\n' ) for expr in single_expressions: code = compile(expr + '\n', '<string>', 'single') assert code_deparse(code, compile_mode='single').text == expr + '\n'
def run_test(text): hypothesis.assume(len(text)) hypothesis.assume("f'{" in text) expr = text + "\n" code = compile(expr, "<string>", "single") deparsed = code_deparse(code, sys.stdout, PYTHON_VERSION, compile_mode="single") recompiled = compile(deparsed.text, "<string>", "single") if recompiled != code: print(recompiled) print("================") print(code) print("----------------") assert ("dis(" + deparsed.text.strip("\n") + ")" == "dis(" + expr.strip("\n") + ")")