From 8b240a80e7d5de064a5a28d7308d749ce427a74d Mon Sep 17 00:00:00 2001 From: rocky Date: Mon, 10 Oct 2016 09:28:07 -0400 Subject: [PATCH] Get ready for release 2.9.0 ... - Use xdis 3.0.0 protocol load_module. Needs bump in requirements.txt and _pkg_info_.py - Start Python 1.5 decompiling - another round of work is needed to remove bugs - small cleanups --- ChangeLog | 30 +++++++++++++++++++++++++++++- NEWS | 10 ++++++++++ __pkginfo__.py | 2 +- requirements.txt | 2 +- uncompyle6/disas.py | 3 ++- uncompyle6/main.py | 3 ++- uncompyle6/parser.py | 12 +++++++++--- uncompyle6/parsers/parse2.py | 14 ++------------ uncompyle6/scanner.py | 3 ++- uncompyle6/scanners/scanner2.py | 8 +++++--- uncompyle6/scanners/scanner26.py | 22 ++++++---------------- uncompyle6/verify.py | 9 ++++++--- uncompyle6/version.py | 2 +- 13 files changed, 76 insertions(+), 44 deletions(-) diff --git a/ChangeLog b/ChangeLog index 23058c3d..d6d429e0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,34 @@ +2016-10-10 rocky + + * __pkginfo__.py, requirements.txt, uncompyle6/disas.py, + uncompyle6/main.py, uncompyle6/parser.py, + uncompyle6/parsers/parse2.py, uncompyle6/scanner.py, + uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner26.py, + uncompyle6/verify.py, uncompyle6/version.py: Get ready for release + 2.9.0 ... - Use xdis 3.0.0 protocol load_module. Needs bump in + requirements.txt and _pkg_info_.py - Start Python 1.5 decompiling - another round of work is needed to + remove bugs - small cleanups + +2016-10-09 rocky + + * : Reinstate some tests + 2016-10-08 rocky - * uncompyle6/version.py: Get ready for release 2.8.4 + * uncompyle6/bin/uncompile.py, uncompyle6/parsers/parse21.py, + uncompyle6/semantics/pysource.py: Simpify python 2.1 grammar Fix bug + with -t ... Wasn't showing source text when -t option was given + +2016-10-08 rocky + + * test/simple_source/bug22/06_list_comprehension_x2_if.py, + uncompyle6/parsers/parse22.py, uncompyle6/parsers/parse26.py: Python + 2.1-2.6 bug in list comprehension + +2016-10-08 rocky + + * ChangeLog, NEWS, uncompyle6/version.py: Get ready for release + 2.8.4 2016-10-08 rocky diff --git a/NEWS b/NEWS index 7eb624c3..01a14e9f 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,13 @@ +uncompyle6 2.9.0 2016-10-09 + +- Use xdis 3.0.0 protocol load_module. + this Forces change in requirements.txt and _pkg_info_.py +- Start Python 1.5 decompiling; another round of work is needed to + remove bugs +- Simpify python 2.1 grammar +- Fix bug with -t ... Wasn't showing source text when -t option was given +- Fix 2.1-2.6 bug in list comprehension + uncompyle6 2.8.4 2016-10-08 - Python 3 disassembly bug fixes diff --git a/__pkginfo__.py b/__pkginfo__.py index 9e218966..56df01ec 100644 --- a/__pkginfo__.py +++ b/__pkginfo__.py @@ -38,7 +38,7 @@ entry_points={ ]} ftp_url = None install_requires = ['spark-parser >= 1.4.0', - 'xdis >= 2.3.1'] + 'xdis >= 3.0.0'] license = 'MIT' mailing_list = 'python-debugger@googlegroups.com' modname = 'uncompyle6' diff --git a/requirements.txt b/requirements.txt index 81fbda5d..64e91929 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ spark-parser >= 1.4.0 -xdis >= 2.2.2 +xdis >= 3.0.0 diff --git a/uncompyle6/disas.py b/uncompyle6/disas.py index de0c5128..8989c4be 100644 --- a/uncompyle6/disas.py +++ b/uncompyle6/disas.py @@ -77,7 +77,8 @@ def disassemble_file(filename, outstream=None, native=False): return filename = check_object_path(filename) - version, timestamp, magic_int, co, is_pypy = load_module(filename) + (version, timestamp, magic_int, co, is_pypy, + source_size) = load_module(filename) if type(co) == list: for con in co: disco(version, con, outstream) diff --git a/uncompyle6/main.py b/uncompyle6/main.py index 283dc09c..8696ffca 100644 --- a/uncompyle6/main.py +++ b/uncompyle6/main.py @@ -55,7 +55,8 @@ def uncompyle_file(filename, outstream=None, showasm=False, showast=False, filename = check_object_path(filename) code_objects = {} - version, timestamp, magic_int, co, is_pypy = load_module(filename, code_objects) + (version, timestamp, magic_int, co, is_pypy, + source_size) = load_module(filename, code_objects) if type(co) == list: diff --git a/uncompyle6/parser.py b/uncompyle6/parser.py index 91a5c76e..e2430872 100644 --- a/uncompyle6/parser.py +++ b/uncompyle6/parser.py @@ -329,7 +329,7 @@ class PythonParser(GenericASTBuilder): """ def p_import20(self, args): - ''' + """ stmt ::= importstmt stmt ::= importfrom stmt ::= importstar @@ -353,7 +353,7 @@ class PythonParser(GenericASTBuilder): load_attrs ::= LOAD_ATTR load_attrs ::= load_attrs LOAD_ATTR - ''' + """ def p_list_comprehension(self, args): """ @@ -553,7 +553,13 @@ def get_python_parser( # FIXME: there has to be a better way... if version < 3.0: - if version == 2.1: + if version == 1.5: + import uncompyle6.parsers.parse15 as parse15 + if compile_mode == 'exec': + p = parse15.Python15Parser(debug_parser) + else: + p = parse15.Python15ParserSingle(debug_parser) + elif version == 2.1: import uncompyle6.parsers.parse21 as parse21 if compile_mode == 'exec': p = parse21.Python21Parser(debug_parser) diff --git a/uncompyle6/parsers/parse2.py b/uncompyle6/parsers/parse2.py index 8b49b607..184723a6 100644 --- a/uncompyle6/parsers/parse2.py +++ b/uncompyle6/parsers/parse2.py @@ -76,6 +76,8 @@ class Python2Parser(PythonParser): return_if_stmts ::= _stmts return_if_stmt return_if_stmt ::= ret_expr RETURN_END_IF + stmt ::= importstmt + stmt ::= break_stmt break_stmt ::= BREAK_LOOP @@ -196,18 +198,6 @@ class Python2Parser(PythonParser): genexpr ::= LOAD_GENEXPR MAKE_FUNCTION_0 expr GET_ITER CALL_FUNCTION_1 ''' - def p_import15(self, args): - ''' - stmt ::= importstmt - stmt ::= importfrom - - importstmt ::= IMPORT_NAME STORE_FAST - importstmt ::= IMPORT_NAME STORE_NAME - - importfrom ::= IMPORT_NAME importlist - importlist ::= importlist IMPORT_FROM - importlist ::= IMPORT_FROM - ''' def p_expr2(self, args): """ expr ::= LOAD_LOCALS diff --git a/uncompyle6/scanner.py b/uncompyle6/scanner.py index 2dd3a4f3..0e70eac5 100755 --- a/uncompyle6/scanner.py +++ b/uncompyle6/scanner.py @@ -18,7 +18,8 @@ from uncompyle6 import PYTHON3, IS_PYPY from uncompyle6.scanners.tok import Token # The byte code versions we support -PYTHON_VERSIONS = (2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, +PYTHON_VERSIONS = (1.5, + 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6) # FIXME: DRY diff --git a/uncompyle6/scanners/scanner2.py b/uncompyle6/scanners/scanner2.py index d343f74e..5dccb33a 100644 --- a/uncompyle6/scanners/scanner2.py +++ b/uncompyle6/scanners/scanner2.py @@ -410,7 +410,7 @@ class Scanner2(scan.Scanner): j = self.prev[s] while code[j] in self.designator_ops: j = self.prev[j] - if code[j] == self.opc.FOR_ITER: + if self.version >= 2.1 and code[j] == self.opc.FOR_ITER: stmts.remove(s) continue last_stmt = s @@ -564,7 +564,8 @@ class Scanner2(scan.Scanner): target = self.get_target(jump_back, self.opc.JUMP_ABSOLUTE) - if code[target] in (self.opc.FOR_ITER, self.opc.GET_ITER): + if (self.version >= 2.0 and + code[target] in (self.opc.FOR_ITER, self.opc.GET_ITER)): loop_type = 'for' else: loop_type = 'while' @@ -837,7 +838,8 @@ class Scanner2(scan.Scanner): oparg = self.get_argument(offset) if label is None: - if op in self.opc.hasjrel and op != self.opc.FOR_ITER: + if (op in self.opc.hasjrel and + (self.version < 2.0 or op != self.opc.FOR_ITER)): label = offset + 3 + oparg elif self.version == 2.7 and op in self.opc.hasjabs: if op in (self.opc.JUMP_IF_FALSE_OR_POP, diff --git a/uncompyle6/scanners/scanner26.py b/uncompyle6/scanners/scanner26.py index 70a7685a..615def36 100755 --- a/uncompyle6/scanners/scanner26.py +++ b/uncompyle6/scanners/scanner26.py @@ -162,20 +162,6 @@ class Scanner26(scan.Scanner2): last_stmt = i i = self.next_stmt[i] - imports = self.all_instr(0, codelen, - (self.opc.IMPORT_NAME, self.opc.IMPORT_FROM, - self.opc.IMPORT_STAR)) - # Changes IMPORT_NAME to IMPORT_NAME_CONT. - # Possibly a Python 2.0 hangover - # FIXME: Move into a < 2.2 scanner. - if len(imports) > 1 and self.version < 2.2: - last_import = imports[0] - for i in imports[1:]: - if self.lines[last_import].next > i: - if self.code[last_import] == self.opc.IMPORT_NAME == self.code[i]: - replace[i] = 'IMPORT_NAME_CONT' - last_import = i - extended_arg = 0 for offset in self.op_range(0, codelen): op = self.code[offset] @@ -238,7 +224,11 @@ class Scanner26(scan.Scanner2): elif op in self.opc.hasjabs: pattr = repr(oparg) elif op in self.opc.haslocal: - pattr = varnames[oparg] + if self.version >= 2.0: + pattr = varnames[oparg] + elif self.version < 2.0: + if oparg < len(names): + pattr = names[oparg] elif op in self.opc.hascompare: pattr = self.opc.cmp_op[oparg] elif op in self.opc.hasfree: @@ -247,7 +237,7 @@ class Scanner26(scan.Scanner2): # CE - Hack for >= 2.5 # Now all values loaded via LOAD_CLOSURE are packed into # a tuple before calling MAKE_CLOSURE. - if (op == self.opc.BUILD_TUPLE and + if (self.version >= 2.5 and op == self.opc.BUILD_TUPLE and self.code[self.prev[offset]] == self.opc.LOAD_CLOSURE): continue else: diff --git a/uncompyle6/verify.py b/uncompyle6/verify.py index 69b4488d..260ec247 100755 --- a/uncompyle6/verify.py +++ b/uncompyle6/verify.py @@ -389,7 +389,8 @@ class Token(scanner.Token): def compare_code_with_srcfile(pyc_filename, src_filename, weak_verify=False): """Compare a .pyc with a source code file.""" - version, timestamp, magic_int, code_obj1, is_pypy = load_module(pyc_filename) + (version, timestamp, magic_int, code_obj1, is_pypy, + source_size) = load_module(pyc_filename) if magic_int != PYTHON_MAGIC_INT: msg = ("Can't compare code - Python is running with magic %s, but code is magic %s " % (PYTHON_MAGIC_INT, magic_int)) @@ -400,8 +401,10 @@ def compare_code_with_srcfile(pyc_filename, src_filename, weak_verify=False): def compare_files(pyc_filename1, pyc_filename2, weak_verify=False): """Compare two .pyc files.""" - version1, timestamp, magic_int1, code_obj1, is_pypy = uncompyle6.load_module(pyc_filename1) - version2, timestamp, magic_int2, code_obj2, is_pypy = uncompyle6.load_module(pyc_filename2) + (version1, timestamp, magic_int1, code_obj1, is_pypy, + source_size) = uncompyle6.load_module(pyc_filename1) + (version2, timestamp, magic_int2, code_obj2, is_pypy, + source_size) = uncompyle6.load_module(pyc_filename2) weak_verify = weak_verify or (magic_int1 != magic_int2) cmp_code_objects(version1, is_pypy, code_obj1, code_obj2, ignore_code=weak_verify) diff --git a/uncompyle6/version.py b/uncompyle6/version.py index 954a5a34..a7512505 100644 --- a/uncompyle6/version.py +++ b/uncompyle6/version.py @@ -1,3 +1,3 @@ # This file is suitable for sourcing inside bash as # well as importing into Python -VERSION='2.8.4' +VERSION='2.9.0'