From 167f5af5e67f9d9d936138b2ecfad32dab1a0ae7 Mon Sep 17 00:00:00 2001 From: rocky Date: Thu, 2 Jun 2016 16:58:42 -0400 Subject: [PATCH] Misc refactorings --- .gitignore | 1 + README.rst | 7 +-- uncompyle6/parsers/parse2.py | 13 ++---- uncompyle6/scanners/scanner2.py | 78 +++----------------------------- uncompyle6/scanners/scanner26.py | 8 +++- uncompyle6/scanners/scanner3.py | 26 ----------- 6 files changed, 20 insertions(+), 113 deletions(-) diff --git a/.gitignore b/.gitignore index d7268703..dbf118fb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *_dis +*.pyc *~ /.cache /.eggs diff --git a/README.rst b/README.rst index 43e9ad47..d463aac2 100644 --- a/README.rst +++ b/README.rst @@ -84,9 +84,10 @@ for usage help. Known Bugs/Restrictions ----------------------- -Python 2 deparsing decompiles about the first 140 or so of the Python -2.7.10 and 2.7.11 standard library files and all but less that 10% -verify. So as such, it is probably a little better than uncompyle2. +Python 2 deparsing decompiles each and all the Python 2.7.10 and 2.7.11 installed packages +I have on my system. All but less that 10% +verify. Some of thse failures may be bugs in the verification process. +So as such, it is probably a little better than uncompyle2. Other Python 2 versions do worse. Python 3 deparsing before 3.5 is okay, but even there, more work is needed to diff --git a/uncompyle6/parsers/parse2.py b/uncompyle6/parsers/parse2.py index 13ebba37..075e66d2 100644 --- a/uncompyle6/parsers/parse2.py +++ b/uncompyle6/parsers/parse2.py @@ -1,9 +1,6 @@ -# Copyright (c) 1999 John Aycock -# Copyright (c) 2000-2002 by hartmut Goebel -# Copyright (c) 2005 by Dan Pascu # Copyright (c) 2015 Rocky Bernstein -# -# See LICENSE for license +# Copyright (c) 2000-2002 by hartmut Goebel +# Copyright (c) 1999 John Aycock """ A spark grammar for Python 2.x. @@ -20,15 +17,11 @@ from __future__ import print_function from uncompyle6.parser import PythonParser, PythonParserSingle, nop_func from uncompyle6.parsers.astnode import AST from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG -from uncompyle6 import PYTHON3 class Python2Parser(PythonParser): def __init__(self, debug_parser=PARSER_DEFAULT_DEBUG): - if PYTHON3: - super().__init__(AST, 'stmts', debug=debug_parser) - else: - super(Python2Parser, self).__init__(AST, 'stmts', debug=debug_parser) + super(Python2Parser, self).__init__(AST, 'stmts', debug=debug_parser) self.customized = {} def p_list_comprehension2(self, args): diff --git a/uncompyle6/scanners/scanner2.py b/uncompyle6/scanners/scanner2.py index f0044c69..79195dff 100755 --- a/uncompyle6/scanners/scanner2.py +++ b/uncompyle6/scanners/scanner2.py @@ -49,9 +49,11 @@ class Scanner2(scan.Scanner): dis.disassemble(). """ - ## FIXME: DRY with disassemble_native - - # import dis; dis.disassemble(co) # DEBUG + # DEBUG + # from xdis.bytecode import Bytecode + # bytecode = Bytecode(co, self.opc) + # for instr in bytecode.get_instructions(co): + # print(instr._disassemble()) # Container for tokens tokens = [] @@ -60,6 +62,7 @@ class Scanner2(scan.Scanner): Token = self.Token # shortcut n = self.setup_code(co) + self.build_lines_data(co, n) self.build_prev_op(n) @@ -203,75 +206,6 @@ class Scanner2(scan.Scanner): tokens.append(Token(replace[offset], oparg, pattr, offset, linestart)) return tokens, customize - def disassemble_native(self, co, classname=None, code_objects={}): - """ - Like disassemble3 but doesn't try to adjust any opcodes. - """ - - ## FIXME: DRY with disassemble - - # Container for tokens - tokens = [] - - customize = {} - Token = self.Token # shortcut - - n = self.setup_code(co) - self.build_lines_data(co, n) - - # self.lines contains (block,addrLastInstr) - if classname: - classname = '_' + classname.lstrip('_') + '__' - - def unmangle(name): - if name.startswith(classname) and name[-2:] != '__': - return name[len(classname) - 2:] - return name - - free = [ unmangle(name) for name in (co.co_cellvars + co.co_freevars) ] - names = [ unmangle(name) for name in co.co_names ] - varnames = [ unmangle(name) for name in co.co_varnames ] - else: - free = co.co_cellvars + co.co_freevars - names = co.co_names - varnames = co.co_varnames - - extended_arg = 0 - for offset in self.op_range(0, n): - op = self.code[offset] - op_name = self.opc.opname[op] - - oparg = None; pattr = None - if op >= self.opc.HAVE_ARGUMENT: - oparg = self.get_argument(offset) + extended_arg - extended_arg = 0 - if op == self.opc.EXTENDED_ARG: - extended_arg = oparg * scan.L65536 - continue - if op in self.opc.hasconst: - pattr = co.co_consts[oparg] - elif op in self.opc.hasname: - pattr = names[oparg] - elif op in self.opc.hasjrel: - pattr = repr(offset + 3 + oparg) - elif op in self.opc.hasjabs: - pattr = repr(oparg) - elif op in self.opc.haslocal: - pattr = varnames[oparg] - elif op in self.opc.hascompare: - pattr = self.opc.cmp_op[oparg] - elif op in self.opc.hasfree: - pattr = free[oparg] - - if offset in self.linestartoffsets: - linestart = self.linestartoffsets[offset] - else: - linestart = None - - tokens.append(Token(op_name, oparg, pattr, offset, linestart)) - pass - return tokens, customize - def op_size(self, op): """ Return size of operator with its arguments diff --git a/uncompyle6/scanners/scanner26.py b/uncompyle6/scanners/scanner26.py index e3953bf7..545fa9fd 100755 --- a/uncompyle6/scanners/scanner26.py +++ b/uncompyle6/scanners/scanner26.py @@ -73,7 +73,10 @@ class Scanner26(scan.Scanner2): dis.disassemble(). ''' - # import dis; dis.disassemble(co) # DEBUG + # from xdis.bytecode import Bytecode + # bytecode = Bytecode(co, self.opc) + # for instr in bytecode.get_instructions(co): + # print(instr._disassemble()) # Container for tokens tokens = [] @@ -82,7 +85,8 @@ class Scanner26(scan.Scanner2): Token = self.Token # shortcut n = self.setup_code(co) - self.build_lines_data(co, n) + + self.build_lines_data(co, n-1) # linestarts contains block code adresses (addr,block) self.linestarts = list(findlinestarts(co)) diff --git a/uncompyle6/scanners/scanner3.py b/uncompyle6/scanners/scanner3.py index 4254df0b..3475c126 100644 --- a/uncompyle6/scanners/scanner3.py +++ b/uncompyle6/scanners/scanner3.py @@ -176,32 +176,6 @@ class Scanner3(scan.Scanner): pass return tokens, {} - def disassemble_native(self, co, classname=None, code_objects={}): - """ - Like disassemble3 but doesn't try to adjust any opcodes. - """ - # Container for tokens - tokens = [] - - self.code = array('B', co.co_code) - - bytecode = Bytecode(co, self.opc) - - for inst in bytecode: - pattr = inst.argrepr - opname = inst.opname - tokens.append( - Token( - type_ = opname, - attr = inst.argval, - pattr = pattr, - offset = inst.offset, - linestart = inst.starts_line, - ) - ) - pass - return tokens, {} - def build_lines_data(self, code_obj): """ Generate various line-related helper data.