diff --git a/test/Makefile b/test/Makefile index 914e936d..72bea477 100644 --- a/test/Makefile +++ b/test/Makefile @@ -100,7 +100,7 @@ check-bytecode-2.5: #: Check deparsing Python 2.6 check-bytecode-2.6: - $(PYTHON) test_pythonlib.py --bytecode-2.6 + $(PYTHON) test_pythonlib.py --bytecode-2.6 --weak-verify #: Check deparsing Python 2.7 check-bytecode-2.7: diff --git a/test/bytecode_2.6/05_ifelse.pyc b/test/bytecode_2.6/05_ifelse.pyc deleted file mode 100644 index babe2894..00000000 Binary files a/test/bytecode_2.6/05_ifelse.pyc and /dev/null differ diff --git a/uncompyle6/main.py b/uncompyle6/main.py index 585166f1..a95882bd 100644 --- a/uncompyle6/main.py +++ b/uncompyle6/main.py @@ -230,11 +230,11 @@ def status_msg(do_verify, tot_files, okay_files, failed_files, verify_failed_files): if tot_files == 1: if failed_files: - return "decompile failed" + return "\n# decompile failed" elif verify_failed_files: - return "decompile verify failed" + return "\n# decompile verify failed" else: - return "Successfully decompiled file" + return "\n# Successfully decompiled file" pass pass mess = "decompiled %i files: %i okay, %i failed" % (tot_files, okay_files, failed_files) diff --git a/uncompyle6/parsers/parse26.py b/uncompyle6/parsers/parse26.py index b0b01671..7657b19b 100644 --- a/uncompyle6/parsers/parse26.py +++ b/uncompyle6/parsers/parse26.py @@ -232,17 +232,37 @@ class Python26Parser(Python2Parser): ''' def p_except26(self, args): - ''' + """ except_suite ::= c_stmts_opt jmp_abs POP_TOP - ''' + """ def p_misc26(self, args): - ''' + """ conditional ::= expr jmp_false expr jf_cf_pop expr come_from_opt and ::= expr JUMP_IF_FALSE POP_TOP expr JUMP_IF_FALSE POP_TOP cmp_list ::= expr cmp_list1 ROT_TWO COME_FROM POP_TOP _come_from - ''' + conditional_lambda ::= expr jmp_false_then return_if_stmt return_stmt LAMBDA_MARKER + """ + + def add_custom_rules(self, tokens, customize): + super(Python26Parser, self).add_custom_rules(tokens, customize) + self.check_reduce['and'] = 'AST' + + def reduce_is_invalid(self, rule, ast, tokens, first, last): + invalid = super(Python26Parser, + self).reduce_is_invalid(rule, ast, + tokens, first, last) + if invalid: + return invalid + if rule == ('and', ('expr', 'jmp_false', 'expr', '\\e_come_from_opt')): + # Test that jmp_false jumps to the end of "and" + # or that it jumps to the same place as the end of "and" + jmp_false = ast[1][0] + jmp_target = jmp_false.offset + jmp_false.attr + 3 + return not (jmp_target == tokens[last].offset or + tokens[last].pattr == jmp_false.pattr) + return False class Python26ParserSingle(Python2Parser, PythonParserSingle): pass diff --git a/uncompyle6/verify.py b/uncompyle6/verify.py index 7a5dcb0f..31c4b829 100755 --- a/uncompyle6/verify.py +++ b/uncompyle6/verify.py @@ -407,7 +407,8 @@ def compare_code_with_srcfile(pyc_filename, src_filename, weak_verify=False): try: code_obj2 = load_file(src_filename) except SyntaxError as e: - return str(e) + # src_filename can be the first of a group sometimes + return str(e).replace(src_filename, pyc_filename) cmp_code_objects(version, is_pypy, code_obj1, code_obj2, ignore_code=weak_verify) return None