diff --git a/.gitignore b/.gitignore index 000cba4b..0e5e5852 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.pyc *~ /.python-version +/uncompyle6.egg-info build diff --git a/__pkginfo__.py b/__pkginfo__.py new file mode 100644 index 00000000..57e65ca3 --- /dev/null +++ b/__pkginfo__.py @@ -0,0 +1,56 @@ +"""uncompyle6 packaging information""" + +# To the extent possible we make this file look more like a +# configuration file rather than code like setup.py. I find putting +# configuration stuff in the middle of a function call in setup.py, +# which for example requires commas in between parameters, is a little +# less elegant than having it here with reduced code, albeit there +# still is some room for improvement. + +# Things that change more often go here. +copyright = """ +Copyright (C) 2015 Rocky Bernstein . +""" + +# classifiers = ['Development Status :: 5 - Production/Stable', +# 'Environment :: Console', +# 'Intended Audience :: Developers', +# 'License :: OSI Approved :: GNU General Public License (GPL)', +# 'Operating System :: OS Independent', +# 'Programming Language :: Python', +# 'Topic :: Software Development :: Debuggers', +# 'Topic :: Software Development :: Libraries :: Python Modules', +# ] + +# The rest in alphabetic order +author = "Rocky Bernstein" +author_email = "rocky@gnu.org" +ftp_url = None +# license = 'GPL' +mailing_list = 'python-debugger@googlegroups.com' +modname = 'uncompyle6' +packages = ['uncompyle6', 'uncompyle6.opcodes'] +py_modules = None +short_desc = 'Python byte-code to source-code converter' + +import os +import os.path, sys + + +def get_srcdir(): + filename = os.path.normcase(os.path.dirname(os.path.abspath(__file__))) + return os.path.realpath(filename) + +# VERSION.py sets variable VERSION. +ns = {} +version = '2.0' +web = 'https://github.com/rocky/uncompyle6/' + +# tracebacks in zip files are funky and not debuggable +zip_safe = False + + +def read(*rnames): + return open(os.path.join(os.path.dirname(__file__), *rnames)).read() + +long_description = ( read("README.rst") + '\n' ) diff --git a/setup.py b/setup.py index c541c0d0..81b552f6 100755 --- a/setup.py +++ b/setup.py @@ -1,15 +1,38 @@ #! python -"""Setup script for the 'uncompyle' distribution.""" +"""Setup script for the 'uncompyle6' distribution.""" from distutils.core import setup, Extension -setup (name = "uncompyle6", - version = "2.0", - description = "Python byte-code to source-code converter", - author = "Mysterie", - author_email = "kajusska@gmail.com", - url = "http://github.com/Mysterie/uncompyle2", - packages=['uncompyle6', 'uncompyle6.opcode'], - scripts=['scripts/uncompyle6'] - ) +# Get the package information used in setup(). +# from __pkginfo__ import \ +# author, author_email, classifiers, \ +# install_requires, license, long_description, \ +# modname, packages, py_modules, \ +# short_desc, version, web, zip_safe + +from __pkginfo__ import \ + author, author_email, \ + long_description, \ + modname, packages, py_modules, \ + short_desc, version, web, zip_safe + +__import__('pkg_resources') +from setuptools import setup + +setup( + author = author, + author_email = author_email, + # classifiers = classifiers, + description = short_desc, + # install_requires = install_requires, + # license = license, + long_description = long_description, + py_modules = py_modules, + name = modname, + packages = packages, + test_suite = 'nose.collector', + url = web, + setup_requires = ['nose>=1.0'], + version = version, + zip_safe = zip_safe) diff --git a/test/compile_tests b/test/compile_tests index 410bfdb1..730fa43b 100755 --- a/test/compile_tests +++ b/test/compile_tests @@ -1,4 +1,6 @@ -#! python +#!/usr/bin/env python +from __future__ import print_function + """ compile_tests -- compile test patterns for the decompyle test suite """ @@ -20,8 +22,8 @@ for opt, val in opts: if args: raise 'This tool does not want any arguments' -print "Using files in dir %s" % src_dir -print "Compiling into dir %s" % work_dir +print("Using files in dir %s" % src_dir) +print("Compiling into dir %s" % work_dir) tests = {} @@ -46,6 +48,7 @@ tests['2.3'] = tests['2.2'] tests['2.5'] = tests['2.3'] tests['2.6'] = tests['2.5'] tests['2.7'] = ['mine'] + tests['2.6'] +tests['3.4'] = ['mine'] total_tests = len(tests['2.7']) #tests['2.2'].sort(); print tests['2.2'] @@ -62,13 +65,13 @@ def compile_for_version(version): os.mkdir(target_dir) for file in tests[version]: compile(file, target_dir) - + try: version = '%i.%i' % sys.version_info[:2] except AttributeError: version = sys.version[:3] -print 'Compiling test files for Python', version, -print '(%i/%i files)' % (len(tests[version]), total_tests) +print('Compiling test files for Python', version) +print('(%i/%i files)' % (len(tests[version]), total_tests)) compile_for_version(version) -print 'Done.' +print('Done.') diff --git a/test_pythonlib.py b/test_pythonlib.py index 32d530c4..76077b9f 100755 --- a/test_pythonlib.py +++ b/test_pythonlib.py @@ -1,4 +1,5 @@ -#! python +#!/usr/bin/env python +from __future__ import print_function ''' test_pythonlib -- uncompyle and verify Python libraries @@ -19,7 +20,7 @@ Step 2: Run the test: test_pythonlib --mylib --verify # decompile verify 'mylib' ''' -from uncompyle2 import main, verify +from uncompyle6 import main, verify import getopt, sys import os, time, shutil from fnmatch import fnmatch @@ -44,11 +45,11 @@ test_options = { #----- def help(): - print 'Usage-Examples:' - print 'test_pythonlib --all # decompile all tests (suite + libs)' - print 'test_pythonlib --all --verify # decomyile all tests and verify results' - print 'test_pythonlib --test # decompile only the testsuite' - print 'test_pythonlib --2.2 --verify # decompile and verify python lib 2.2' + print('Usage-Examples:') + print('test_pythonlib --all # decompile all tests (suite + libs)') + print('test_pythonlib --all --verify # decomyile all tests and verify results') + print('test_pythonlib --test # decompile only the testsuite') + print('test_pythonlib --2.2 --verify # decompile and verify python lib 2.2') def do_tests(src_dir, patterns, target_dir, start_with=None, do_verify=0): def visitor(files, dirname, names): @@ -69,18 +70,18 @@ def do_tests(src_dir, patterns, target_dir, start_with=None, do_verify=0): try: start_with = files.index(start_with) files = files[start_with:] - print '>>> starting with file', files[0] + print('>>> starting with file', files[0]) except ValueError: pass - print time.ctime() - print 'Working directory: ', src_dir + print(time.ctime()) + print('Working directory: ', src_dir) try: main(src_dir, target_dir, files, [], do_verify=do_verify) except (KeyboardInterrupt, OSError): - print + print exit(1) - + if __name__ == '__main__': do_verify = 0 test_dirs = [] diff --git a/uncompyle-code.py b/uncompyle-code.py index 90f53198..5c9df8df 100644 --- a/uncompyle-code.py +++ b/uncompyle-code.py @@ -1,6 +1,6 @@ -import uncompyle2 -from uncompyle2 import uncompyle, walker, verify, magics -from uncompyle2.spark import GenericASTTraversal, GenericASTTraversalPruningException +import uncompyle6 +from uncompyle6 import uncompyle, walker, verify, magics +from uncompyle6.spark import GenericASTTraversal, GenericASTTraversalPruningException import sys, inspect, types, cStringIO from collections import namedtuple @@ -137,7 +137,7 @@ def uncompyle_find(version, co, find_offset, out=sys.stdout, showasm=0, showast= # store final output stream for case of error __real_out = out or sys.stdout if version == 2.7: - import uncompyle2.scanner27 as scan + import uncompyle6.scanner27 as scan scanner = scan.Scanner27() elif version == 2.6: import scanner26 as scan diff --git a/uncompyle6/__init__.py b/uncompyle6/__init__.py index 17113c1b..9d228505 100755 --- a/uncompyle6/__init__.py +++ b/uncompyle6/__init__.py @@ -1,3 +1,6 @@ +from __future__ import print_function + + ''' Copyright (c) 1999 John Aycock Copyright (c) 2000 by hartmut Goebel @@ -68,9 +71,9 @@ def _load_module(filename): try: version = float(magics.versions[magic]) except KeyError: - raise ImportError, "Unknown magic number %s in %s" % (ord(magic[0])+256*ord(magic[1]), filename) + raise ImportError("Unknown magic number %s in %s" % (ord(magic[0])+256*ord(magic[1]), filename)) if (version > 2.7) or (version < 2.5): - raise ImportError, "This is a Python %s file! Only Python 2.5 to 2.7 files are supported." % version + raise ImportError("This is a Python %s file! Only Python 2.5 to 2.7 files are supported." % version) #print version fp.read(4) # timestamp co = dis.marshalLoad(fp) @@ -105,7 +108,7 @@ def uncompyle(version, co, out=None, showasm=0, showast=0): walk = walker.Walker(out, scanner, showast=showast) try: ast = walk.build_ast(tokens, customize) - except walker.ParserError, e : # parser failed, dump disassembly + except walker.ParserError as e : # parser failed, dump disassembly print >>__real_out, e raise del tokens # save memory @@ -223,9 +226,9 @@ def main(in_base, out_base, files, codes, outfile=None, if do_verify: try: verify.compare_code_with_srcfile(infile, outfile) - if not outfile: print '\n# okay decompyling', infile, __memUsage() + if not outfile: print('\n# okay decompyling', infile, __memUsage()) okay_files += 1 - except verify.VerifyCmpError, e: + except verify.VerifyCmpError as e: verify_failed_files += 1 os.rename(outfile, outfile + '_unverified') if not outfile: @@ -233,7 +236,7 @@ def main(in_base, out_base, files, codes, outfile=None, print >>sys.stderr, e else: okay_files += 1 - if not outfile: print '\n# okay decompyling', infile, __memUsage() + if not outfile: print('\n# okay decompyling', infile, __memUsage()) if outfile: sys.stdout.write("decompiled %i files: %i okay, %i failed, %i verify failed\r" % (tot_files, okay_files, failed_files, verify_failed_files)) sys.stdout.flush() diff --git a/uncompyle6/magics.py b/uncompyle6/magics.py index 0d3f53f2..88696d95 100755 --- a/uncompyle6/magics.py +++ b/uncompyle6/magics.py @@ -1,16 +1,20 @@ from __future__ import print_function -import struct + +import struct, sys __all__ = ['magics', 'versions'] def __build_magic(magic): - return struct.pack('Hcc', magic, '\r', '\n') + if (sys.version_info > (3, 0)): + return struct.pack('Hcc', magic, bytes('\r', 'utf-8'), bytes('\n', 'utf-8')) + else: + return struct.pack('Hcc', magic, '\r', '\n') by_magic = {} by_version = {} def __by_version(magics): - for m, v in magics.items(): + for m, v in list(magics.items()): by_magic[m] = v by_version[v] = m return by_version @@ -77,6 +81,7 @@ def test(): magic_20 = magics['2.0'] current = imp.get_magic() current_version = struct.unpack('HBB', current)[0] + from trepan.api import debug; debug() magic_current = by_magic[ current ] print(type(magic_20), len(magic_20), repr(magic_20)) print() diff --git a/uncompyle6/opcode/__init__.py b/uncompyle6/opcodes/__init__.py similarity index 100% rename from uncompyle6/opcode/__init__.py rename to uncompyle6/opcodes/__init__.py diff --git a/uncompyle6/opcode/opcode_23.py b/uncompyle6/opcodes/opcode_23.py similarity index 100% rename from uncompyle6/opcode/opcode_23.py rename to uncompyle6/opcodes/opcode_23.py diff --git a/uncompyle6/opcode/opcode_24.py b/uncompyle6/opcodes/opcode_24.py similarity index 100% rename from uncompyle6/opcode/opcode_24.py rename to uncompyle6/opcodes/opcode_24.py diff --git a/uncompyle6/opcode/opcode_25.py b/uncompyle6/opcodes/opcode_25.py similarity index 100% rename from uncompyle6/opcode/opcode_25.py rename to uncompyle6/opcodes/opcode_25.py diff --git a/uncompyle6/opcode/opcode_26.py b/uncompyle6/opcodes/opcode_26.py similarity index 100% rename from uncompyle6/opcode/opcode_26.py rename to uncompyle6/opcodes/opcode_26.py diff --git a/uncompyle6/opcode/opcode_27.py b/uncompyle6/opcodes/opcode_27.py similarity index 100% rename from uncompyle6/opcode/opcode_27.py rename to uncompyle6/opcodes/opcode_27.py diff --git a/uncompyle6/parser.py b/uncompyle6/parser.py index ed22c8a9..27274008 100755 --- a/uncompyle6/parser.py +++ b/uncompyle6/parser.py @@ -1,3 +1,5 @@ +from __future__ import print_function + ''' Copyright (c) 1999 John Aycock Copyright (c) 2000-2002 by hartmut Goebel @@ -9,8 +11,13 @@ __all__ = ['parse', 'AST', 'ParserError', 'Parser'] from spark import GenericASTBuilder -import string, exceptions, sys -from UserList import UserList +import string, sys + +if (sys.version_info > (3, 0)): + intern = sys.intern + from collections import UserList +else: + from UserList import UserList from scanner import Token @@ -44,9 +51,10 @@ class ParserError(Exception): def __str__(self): return "Syntax error at or near `%r' token at offset %s\n" % \ (self.token, self.offset) - + class Parser(GenericASTBuilder): + def __init__(self): GenericASTBuilder.__init__(self, AST, 'stmts') self.customized = {} @@ -57,7 +65,7 @@ class Parser(GenericASTBuilder): collector to collect this object. """ for dict in (self.rule2func, self.rules, self.rule2name): - for i in dict.keys(): + for i in list(dict.keys()): dict[i] = None for i in dir(self): setattr(self, i, None) @@ -67,7 +75,7 @@ class Parser(GenericASTBuilder): def typestring(self, token): return token.type - + def p_funcdef(self, args): ''' stmt ::= funcdef @@ -92,26 +100,26 @@ class Parser(GenericASTBuilder): list_iter ::= lc_body _come_from ::= COME_FROM - _come_from ::= - + _come_from ::= + list_for ::= expr _for designator list_iter JUMP_BACK - list_if ::= expr jmp_false list_iter - list_if_not ::= expr jmp_true list_iter + list_if ::= expr jmp_false list_iter + list_if_not ::= expr jmp_true list_iter lc_body ::= expr LIST_APPEND ''' - + def p_setcomp(self, args): ''' expr ::= setcomp - + setcomp ::= LOAD_SETCOMP MAKE_FUNCTION_0 expr GET_ITER CALL_FUNCTION_1 - + stmt ::= setcomp_func - + setcomp_func ::= BUILD_SET_0 LOAD_FAST FOR_ITER designator comp_iter JUMP_BACK RETURN_VALUE RETURN_LAST - + comp_iter ::= comp_if comp_iter ::= comp_ifnot comp_iter ::= comp_for @@ -131,11 +139,11 @@ class Parser(GenericASTBuilder): def p_genexpr(self, args): ''' expr ::= genexpr - + genexpr ::= LOAD_GENEXPR MAKE_FUNCTION_0 expr GET_ITER CALL_FUNCTION_1 - + stmt ::= genexpr_func - + genexpr_func ::= LOAD_FAST FOR_ITER designator comp_iter JUMP_BACK ''' @@ -145,7 +153,7 @@ class Parser(GenericASTBuilder): expr ::= dictcomp dictcomp ::= LOAD_DICTCOMP MAKE_FUNCTION_0 expr GET_ITER CALL_FUNCTION_1 stmt ::= dictcomp_func - + dictcomp_func ::= BUILD_MAP LOAD_FAST FOR_ITER designator comp_iter JUMP_BACK RETURN_VALUE RETURN_LAST @@ -177,7 +185,7 @@ class Parser(GenericASTBuilder): inplace_op ::= INPLACE_RSHIFT inplace_op ::= INPLACE_AND inplace_op ::= INPLACE_XOR - inplace_op ::= INPLACE_OR + inplace_op ::= INPLACE_OR ''' def p_assign(self, args): @@ -197,11 +205,11 @@ class Parser(GenericASTBuilder): stmt ::= print_items_stmt stmt ::= print_nl stmt ::= print_items_nl_stmt - + print_items_stmt ::= expr PRINT_ITEM print_items_opt print_items_nl_stmt ::= expr PRINT_ITEM print_items_opt PRINT_NEWLINE_CONT print_items_opt ::= print_items - print_items_opt ::= + print_items_opt ::= print_items ::= print_items print_item print_items ::= print_item print_item ::= expr PRINT_ITEM_CONT @@ -222,7 +230,7 @@ class Parser(GenericASTBuilder): ''' def p_import20(self, args): - ''' + ''' stmt ::= importstmt stmt ::= importfrom stmt ::= importstar @@ -234,20 +242,20 @@ class Parser(GenericASTBuilder): import_as ::= IMPORT_NAME load_attrs designator import_as ::= IMPORT_FROM designator - importstmt ::= LOAD_CONST LOAD_CONST import_as - importstar ::= LOAD_CONST LOAD_CONST IMPORT_NAME IMPORT_STAR + importstmt ::= LOAD_CONST LOAD_CONST import_as + importstar ::= LOAD_CONST LOAD_CONST IMPORT_NAME IMPORT_STAR importfrom ::= LOAD_CONST LOAD_CONST IMPORT_NAME importlist2 POP_TOP - importstar ::= LOAD_CONST LOAD_CONST IMPORT_NAME_CONT IMPORT_STAR + importstar ::= LOAD_CONST LOAD_CONST IMPORT_NAME_CONT IMPORT_STAR importfrom ::= LOAD_CONST LOAD_CONST IMPORT_NAME_CONT importlist2 POP_TOP importmultiple ::= LOAD_CONST LOAD_CONST import_as imports_cont - + imports_cont ::= imports_cont import_cont imports_cont ::= import_cont import_cont ::= LOAD_CONST LOAD_CONST import_as_cont import_as_cont ::= IMPORT_NAME_CONT designator import_as_cont ::= IMPORT_NAME_CONT load_attrs designator import_as_cont ::= IMPORT_FROM designator - + load_attrs ::= LOAD_ATTR load_attrs ::= load_attrs LOAD_ATTR ''' @@ -259,11 +267,11 @@ class Parser(GenericASTBuilder): sstmt ::= stmt sstmt ::= ifelsestmtr sstmt ::= return_stmt RETURN_LAST - + stmts_opt ::= stmts stmts_opt ::= passstmt - passstmt ::= - + passstmt ::= + _stmts ::= _stmts stmt _stmts ::= stmt @@ -271,7 +279,7 @@ class Parser(GenericASTBuilder): c_stmts ::= _stmts lastc_stmt c_stmts ::= lastc_stmt c_stmts ::= continue_stmts - + lastc_stmt ::= iflaststmt lastc_stmt ::= whileelselaststmt lastc_stmt ::= forelselaststmt @@ -281,28 +289,28 @@ class Parser(GenericASTBuilder): c_stmts_opt ::= c_stmts c_stmts_opt ::= passstmt - + l_stmts ::= _stmts l_stmts ::= return_stmts l_stmts ::= continue_stmts l_stmts ::= _stmts lastl_stmt l_stmts ::= lastl_stmt - + lastl_stmt ::= iflaststmtl lastl_stmt ::= ifelsestmtl lastl_stmt ::= forelselaststmtl lastl_stmt ::= tryelsestmtl - + l_stmts_opt ::= l_stmts l_stmts_opt ::= passstmt - + suite_stmts ::= _stmts suite_stmts ::= return_stmts suite_stmts ::= continue_stmts - + suite_stmts_opt ::= suite_stmts suite_stmts_opt ::= passstmt - + else_suite ::= suite_stmts else_suitel ::= l_stmts else_suitec ::= c_stmts @@ -324,7 +332,7 @@ class Parser(GenericASTBuilder): store_subscr ::= expr expr STORE_SUBSCR designator ::= unpack designator ::= unpack_list - + stmt ::= classdef stmt ::= call_stmt call_stmt ::= expr POP_TOP @@ -333,21 +341,21 @@ class Parser(GenericASTBuilder): return_stmt ::= ret_expr RETURN_VALUE return_stmts ::= return_stmt return_stmts ::= _stmts return_stmt - + return_if_stmts ::= return_if_stmt return_if_stmts ::= _stmts return_if_stmt return_if_stmt ::= ret_expr RETURN_END_IF stmt ::= break_stmt break_stmt ::= BREAK_LOOP - + stmt ::= continue_stmt continue_stmt ::= CONTINUE continue_stmt ::= CONTINUE_LOOP continue_stmts ::= _stmts lastl_stmt continue_stmt continue_stmts ::= lastl_stmt continue_stmt continue_stmts ::= continue_stmt - + stmt ::= raise_stmt0 stmt ::= raise_stmt1 stmt ::= raise_stmt2 @@ -357,16 +365,16 @@ class Parser(GenericASTBuilder): raise_stmt1 ::= expr RAISE_VARARGS_1 raise_stmt2 ::= expr expr RAISE_VARARGS_2 raise_stmt3 ::= expr expr expr RAISE_VARARGS_3 - + stmt ::= exec_stmt exec_stmt ::= expr exprlist DUP_TOP EXEC_STMT exec_stmt ::= expr exprlist EXEC_STMT - + stmt ::= assert stmt ::= assert2 stmt ::= ifstmt stmt ::= ifelsestmt - + stmt ::= whilestmt stmt ::= whilenotstmt stmt ::= while1stmt @@ -379,7 +387,7 @@ class Parser(GenericASTBuilder): stmt ::= tryfinallystmt stmt ::= withstmt stmt ::= withasstmt - + stmt ::= del_stmt del_stmt ::= DELETE_FAST del_stmt ::= DELETE_NAME @@ -391,12 +399,12 @@ class Parser(GenericASTBuilder): del_stmt ::= delete_subscr delete_subscr ::= expr expr DELETE_SUBSCR del_stmt ::= expr DELETE_ATTR - + kwarg ::= LOAD_CONST expr - + classdef ::= LOAD_CONST expr mkfunc CALL_FUNCTION_0 BUILD_CLASS designator - + stmt ::= classdefdeco classdefdeco ::= classdefdeco1 designator classdefdeco1 ::= expr classdefdeco1 CALL_FUNCTION_1 @@ -411,11 +419,11 @@ class Parser(GenericASTBuilder): jmp_false ::= JUMP_IF_FALSE jmp_true ::= POP_JUMP_IF_TRUE jmp_true ::= JUMP_IF_TRUE - + assert ::= assert_expr jmp_true LOAD_ASSERT RAISE_VARARGS_1 assert2 ::= assert_expr jmp_true LOAD_ASSERT expr CALL_FUNCTION_1 RAISE_VARARGS_1 assert2 ::= assert_expr jmp_true LOAD_ASSERT expr RAISE_VARARGS_2 - + assert_expr ::= expr assert_expr ::= assert_expr_or assert_expr ::= assert_expr_and @@ -423,17 +431,17 @@ class Parser(GenericASTBuilder): assert_expr_and ::= assert_expr jmp_false expr ifstmt ::= testexpr _ifstmts_jump - + testexpr ::= testfalse testexpr ::= testtrue testfalse ::= expr jmp_false testtrue ::= expr jmp_true - + _ifstmts_jump ::= return_if_stmts _ifstmts_jump ::= c_stmts_opt JUMP_FORWARD COME_FROM - + iflaststmt ::= testexpr c_stmts_opt JUMP_ABSOLUTE - + iflaststmtl ::= testexpr c_stmts_opt JUMP_BACK ifelsestmt ::= testexpr c_stmts_opt JUMP_FORWARD else_suite COME_FROM @@ -443,8 +451,8 @@ class Parser(GenericASTBuilder): ifelsestmtr ::= testexpr return_if_stmts return_stmts ifelsestmtl ::= testexpr c_stmts_opt JUMP_BACK else_suitel - - + + trystmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK try_middle COME_FROM @@ -461,12 +469,12 @@ class Parser(GenericASTBuilder): END_FINALLY try_middle ::= JUMP_FORWARD COME_FROM except_stmts END_FINALLY COME_FROM - + except_stmts ::= except_stmts except_stmt except_stmts ::= except_stmt - - except_stmt ::= except_cond1 except_suite - except_stmt ::= except_cond2 except_suite + + except_stmt ::= except_cond1 except_suite + except_stmt ::= except_cond2 except_suite except_stmt ::= except except_suite ::= c_stmts_opt JUMP_FORWARD @@ -474,22 +482,22 @@ class Parser(GenericASTBuilder): except_suite ::= return_stmts except_cond1 ::= DUP_TOP expr COMPARE_OP - jmp_false POP_TOP POP_TOP POP_TOP + jmp_false POP_TOP POP_TOP POP_TOP except_cond2 ::= DUP_TOP expr COMPARE_OP jmp_false POP_TOP designator POP_TOP - + except ::= POP_TOP POP_TOP POP_TOP c_stmts_opt JUMP_FORWARD except ::= POP_TOP POP_TOP POP_TOP c_stmts_opt jmp_abs except ::= POP_TOP POP_TOP POP_TOP return_stmts - + jmp_abs ::= JUMP_ABSOLUTE jmp_abs ::= JUMP_BACK - + tryfinallystmt ::= SETUP_FINALLY suite_stmts POP_BLOCK LOAD_CONST COME_FROM suite_stmts_opt END_FINALLY - + withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM WITH_CLEANUP END_FINALLY @@ -527,7 +535,7 @@ class Parser(GenericASTBuilder): for_block ::= l_stmts_opt JUMP_BACK for_block ::= return_stmts _come_from - + forstmt ::= SETUP_LOOP expr _for designator for_block POP_BLOCK COME_FROM @@ -577,7 +585,7 @@ class Parser(GenericASTBuilder): expr ::= buildslice2 expr ::= buildslice3 expr ::= yield - + binary_expr ::= expr expr binary_op binary_op ::= BINARY_ADD binary_op ::= BINARY_MULTIPLY @@ -616,7 +624,7 @@ class Parser(GenericASTBuilder): slice3 ::= expr expr expr DUP_TOPX_3 SLICE+3 buildslice3 ::= expr expr expr BUILD_SLICE_3 buildslice2 ::= expr expr BUILD_SLICE_2 - + yield ::= expr YIELD_VALUE _mklambda ::= load_closure mklambda @@ -627,17 +635,17 @@ class Parser(GenericASTBuilder): and ::= expr jmp_false expr _come_from and ::= expr JUMP_IF_FALSE_OR_POP expr COME_FROM and2 ::= _jump jmp_false COME_FROM expr COME_FROM - + expr ::= conditional conditional ::= expr jmp_false expr JUMP_FORWARD expr COME_FROM conditional ::= expr jmp_false expr JUMP_ABSOLUTE expr expr ::= conditionalnot conditionalnot ::= expr jmp_true expr _jump expr COME_FROM - + ret_expr ::= expr ret_expr ::= ret_and ret_expr ::= ret_or - + ret_expr_or_cond ::= ret_expr ret_expr_or_cond ::= ret_cond ret_expr_or_cond ::= ret_cond_not @@ -649,9 +657,9 @@ class Parser(GenericASTBuilder): stmt ::= return_lambda stmt ::= conditional_lambda - + return_lambda ::= ret_expr RETURN_VALUE LAMBDA_MARKER - conditional_lambda ::= expr jmp_false return_if_stmt return_stmt LAMBDA_MARKER + conditional_lambda ::= expr jmp_false return_if_stmt return_stmt LAMBDA_MARKER cmp ::= cmp_list cmp ::= compare @@ -704,7 +712,7 @@ class Parser(GenericASTBuilder): def __ambiguity(self, children): # only for debugging! to be removed hG/2000-10-15 - print children + print(children) return GenericASTBuilder.ambiguity(self, children) def resolve(self, list): @@ -737,9 +745,9 @@ def parse(tokens, customize): # expr ::= expr {expr}^n CALL_FUNCTION_KW_n POP_TOP # global p - for k, v in customize.items(): + for k, v in list(customize.items()): # avoid adding the same rule twice to this parser - if p.customized.has_key(k): + if k in p.customized: continue p.customized[k] = None diff --git a/uncompyle6/scanner25.py b/uncompyle6/scanner25.py index a2a7cc69..e700908f 100755 --- a/uncompyle6/scanner25.py +++ b/uncompyle6/scanner25.py @@ -12,14 +12,14 @@ from array import array from operator import itemgetter from struct import * -from uncompyle2.opcode.opcode_25 import * +from uncompyle6.opcodes.opcode_25 import * import disas as dis import scanner as scan class Scanner25(scan.Scanner): def __init__(self): self.Token = scan.Scanner.__init__(self, 2.5) - + def disassemble(self, co, classname=None): ''' Disassemble a code object, returning a list of 'Token'. @@ -38,7 +38,7 @@ class Scanner25(scan.Scanner): # linestarts contains bloc code adresse (addr,block) self.linestarts = list(dis.findlinestarts(co)) self.prev = [0] - + # class and names if classname: classname = '_' + classname.lstrip('_') + '__' @@ -46,7 +46,7 @@ class Scanner25(scan.Scanner): 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 ] @@ -82,13 +82,13 @@ class Scanner25(scan.Scanner): while j < codelen: self.lines.append(linetuple(prev_line_no, codelen)) j+=1 - + self.load_asserts = set() for i in self.op_range(0, codelen): if self.code[i] == PJIT and self.code[i+3] == LOAD_GLOBAL: if names[self.get_argument(i+3)] == 'AssertionError': self.load_asserts.add(i+3) - + # self.lines contains (block,addrLastInstr) cf = self.find_jump_targets(self.code) # contains (code, [addrRefToCode]) @@ -104,7 +104,7 @@ class Scanner25(scan.Scanner): replace[i] = 'PRINT_NEWLINE_CONT' last_stmt = i i = self.next_stmt[i] - + imports = self.all_instr(0, codelen, (IMPORT_NAME, IMPORT_FROM, IMPORT_STAR)) if len(imports) > 1: last_import = imports[0] @@ -220,10 +220,10 @@ class Scanner25(scan.Scanner): ''' opcode = self.code[i] opsize = self.op_size(opcode) - + if i+opsize >= len(self.code): return None - + if opcode == EXTENDED_ARG: raise NotImplementedError # del POP_TOP @@ -283,7 +283,7 @@ class Scanner25(scan.Scanner): target = self.get_target(target-3) self.restructJump(start, target) start += self.op_size(PJIF) - # del DELETE_NAME x + # del DELETE_NAME x start = end while end < len(self.code): end = self.first_instr(end, len(self.code), (DELETE_NAME,DELETE_FAST)) @@ -297,7 +297,7 @@ class Scanner25(scan.Scanner): return toDel # change join(for..) struct if opcode == SETUP_LOOP: - if self.code[i+3] == LOAD_FAST and self.code[i+6] == FOR_ITER: + if self.code[i+3] == LOAD_FAST and self.code[i+6] == FOR_ITER: end = self.first_instr(i, len(self.code), RETURN_VALUE) end = self.first_instr(i, end, YIELD_VALUE) if end and self.code[end+1] == POP_TOP and self.code[end+2] == JA and self.code[end+5] == POP_BLOCK: @@ -357,7 +357,7 @@ class Scanner25(scan.Scanner): i+=2 i+=1 return listExp - + def restructCode(self, listDel, listExp): ''' restruct linestarts and jump destination @@ -389,7 +389,7 @@ class Scanner25(scan.Scanner): if listDel: for jmp in self.op_range(0, len(self.code)): op = self.code[jmp] - if op in hasjrel+hasjabs: + if op in hasjrel+hasjabs: offset = 0 jmpTarget = self.get_target(jmp) for toDel in listDel: @@ -412,7 +412,7 @@ class Scanner25(scan.Scanner): if self.op_hasArgument(op) and op not in self.opc.hasArgumentExtended: jmp += 3 else: jmp += 1 - + def restructBytecode(self): ''' add/change/delete bytecode for suiting bytecode 2.7 @@ -420,9 +420,9 @@ class Scanner25(scan.Scanner): # we can't use op_range for the moment # convert jump opcode to 2.7 self.restructRelativeJump() - + listExp = self.getOpcodeToExp() - # change code structure + # change code structure if listExp: listExp = sorted(list(set(listExp))) self.restructCode([], listExp) @@ -439,7 +439,7 @@ class Scanner25(scan.Scanner): ret = self.getOpcodeToDel(i) if ret != None: listDel += ret - + # change code structure after deleting byte if listDel: listDel = sorted(list(set(listDel))) @@ -455,7 +455,7 @@ class Scanner25(scan.Scanner): else: self.code.pop(x-delta) delta += 1 - + def restructRelativeJump(self): ''' change relative JUMP_IF_FALSE/TRUE to absolut jump @@ -495,7 +495,7 @@ class Scanner25(scan.Scanner): raise NotImplementedError self.code[pos+2] = (target >> 8) & 0xFF self.code[pos+1] = target & 0xFF - + def build_stmt_indices(self): code = self.code start = 0; @@ -513,9 +513,9 @@ class Scanner25(scan.Scanner): } stmt_opcode_seqs = [(PJIF, JF), (PJIF, JA), (PJIT, JF), (PJIT, JA)] - + designator_ops = { - STORE_FAST, STORE_NAME, STORE_GLOBAL, STORE_DEREF, STORE_ATTR, + STORE_FAST, STORE_NAME, STORE_GLOBAL, STORE_DEREF, STORE_ATTR, STORE_SLICE_0, STORE_SLICE_1, STORE_SLICE_2, STORE_SLICE_3, STORE_SUBSCR, UNPACK_SEQUENCE, JA } @@ -532,17 +532,17 @@ class Scanner25(scan.Scanner): match = False break i += self.op_size(code[i]) - + if match: i = self.prev[i] stmts.add(i) pass_stmts.add(i) - + if pass_stmts: stmt_list = list(stmts) stmt_list.sort() else: - stmt_list = prelim + stmt_list = prelim last_stmt = -1 self.next_stmt = [] slist = self.next_stmt = [] @@ -573,7 +573,7 @@ class Scanner25(scan.Scanner): slist += [s] * (s-i) i = s slist += [end] * (end-len(slist)) - + def next_except_jump(self, start): ''' Return the next jump that was generated by an except SomeException: @@ -602,7 +602,7 @@ class Scanner25(scan.Scanner): elif op in (SETUP_EXCEPT, SETUP_FINALLY): count_SETUP_ += 1 #return self.lines[start].next - + def detect_structure(self, pos, op=None): ''' Detect type of block structures and their boundaries to fix optimizied jumps @@ -635,7 +635,7 @@ class Scanner25(scan.Scanner): if target != end: self.fixed_jumps[pos] = end - + (line_no, next_line_byte) = self.lines[pos] jump_back = self.last_instr(start, end, JA, next_line_byte, False) @@ -645,7 +645,7 @@ class Scanner25(scan.Scanner): jump_back = None if not jump_back: # loop suite ends in return. wtf right? jump_back = self.last_instr(start, end, RETURN_VALUE) - if not jump_back: + if not jump_back: return jump_back += 1 if code[self.prev[next_line_byte]] not in (PJIF, PJIT): @@ -667,7 +667,7 @@ class Scanner25(scan.Scanner): elif target < pos: self.fixed_jumps[pos] = jump_back+4 end = jump_back+4 - + target = self.get_target(jump_back, JA) if code[target] in (FOR_ITER, GET_ITER): @@ -677,7 +677,7 @@ class Scanner25(scan.Scanner): test = self.prev[next_line_byte] if test == pos: loop_type = 'while 1' - elif self.code[test] in hasjabs+hasjrel: + elif self.code[test] in hasjabs+hasjrel: self.ignore_if.add(test) test_target = self.get_target(test) if test_target > (jump_back+3): @@ -725,7 +725,7 @@ class Scanner25(scan.Scanner): self.structs.append({'type': 'except', 'start': i, 'end': jmp}) - i = jmp + 3 + i = jmp + 3 ## Add the try-else block if end_else != start_else: @@ -754,7 +754,7 @@ class Scanner25(scan.Scanner): 'start': start, 'end': pre[target]}) return - + # is this an if and if op == PJIF: match = self.rem_or(start, self.next_stmt[pos], PJIF, target) @@ -790,7 +790,7 @@ class Scanner25(scan.Scanner): self.fixed_jumps[pos] = fix or match[-1] return elif pos < rtarget and code[target] == ROT_TWO: - self.fixed_jumps[pos] = target + self.fixed_jumps[pos] = target return else: self.fixed_jumps[pos] = match[-1] @@ -800,7 +800,7 @@ class Scanner25(scan.Scanner): if code[pre[rtarget]] == RAISE_VARARGS: return self.load_asserts.remove(pos+3) - + next = self.next_stmt[pos] if pre[next] == pos: pass @@ -816,7 +816,7 @@ class Scanner25(scan.Scanner): #don't add a struct for a while test, it's already taken care of if pos in self.ignore_if: return - + if code[pre[rtarget]] == JA and pre[rtarget] in self.stmts \ and pre[rtarget] != pos and pre[pre[rtarget]] != pos \ and not (code[rtarget] == JA and code[rtarget+3] == POP_BLOCK and code[pre[pre[rtarget]]] != JA): @@ -824,19 +824,19 @@ class Scanner25(scan.Scanner): #does the if jump just beyond a jump op, then this is probably an if statement if code[pre[rtarget]] in (JA, JF): if_end = self.get_target(pre[rtarget]) - + #is this a loop not an if? if (if_end < pre[rtarget]) and (code[pre[if_end]] == SETUP_LOOP): if(if_end > start): return - + end = self.restrict_to_parent(if_end, parent) - + self.structs.append({'type': 'if-then', 'start': start, 'end': pre[rtarget]}) self.not_continue.add(pre[rtarget]) - + if rtarget < end: self.structs.append({'type': 'if-else', 'start': rtarget, @@ -867,7 +867,7 @@ class Scanner25(scan.Scanner): self.loops = [] ## All loop entry points self.fixed_jumps = {} ## Map fixed jumps to their real destination self.ignore_if = set() - self.build_stmt_indices() + self.build_stmt_indices() self.not_continue = set() self.return_end_ifs = set() @@ -880,7 +880,7 @@ class Scanner25(scan.Scanner): if self.op_hasArgument(op): label = self.fixed_jumps.get(i) - oparg = self.get_argument(i) + oparg = self.get_argument(i) if label is None: if op in hasjrel and op != FOR_ITER: label = i + 3 + oparg diff --git a/uncompyle6/scanner26.py b/uncompyle6/scanner26.py index 53621612..ad2f841e 100755 --- a/uncompyle6/scanner26.py +++ b/uncompyle6/scanner26.py @@ -12,14 +12,14 @@ from array import array from operator import itemgetter from struct import * -from uncompyle2.opcode.opcode_26 import * +from uncompyle6.opcodes.opcode_26 import * import disas as dis import scanner as scan class Scanner26(scan.Scanner): def __init__(self): self.Token = scan.Scanner.__init__(self, 2.6) - + def disassemble(self, co, classname=None): ''' Disassemble a code object, returning a list of 'Token'. @@ -27,7 +27,7 @@ class Scanner26(scan.Scanner): The main part of this procedure is modelled after dis.disassemble(). ''' - + rv = [] customize = {} Token = self.Token # shortcut @@ -46,7 +46,7 @@ class Scanner26(scan.Scanner): 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 ] @@ -60,7 +60,7 @@ class Scanner26(scan.Scanner): self.toChange = [] self.restructBytecode() codelen = len(self.code) - # mapping adresses of prev instru + # mapping adresses of prev instru for i in self.op_range(0, codelen): op = self.code[i] self.prev.append(i) @@ -83,13 +83,13 @@ class Scanner26(scan.Scanner): self.lines.append(linetuple(prev_line_no, codelen)) j+=1 # self.lines contains (block,addrLastInstr) - + self.load_asserts = set() for i in self.op_range(0, codelen): if self.code[i] == PJIT and self.code[i+3] == LOAD_GLOBAL: if names[self.get_argument(i+3)] == 'AssertionError': self.load_asserts.add(i+3) - + cf = self.find_jump_targets(self.code) # contains (code, [addrRefToCode]) @@ -105,7 +105,7 @@ class Scanner26(scan.Scanner): replace[i] = 'PRINT_NEWLINE_CONT' last_stmt = i i = self.next_stmt[i] - + imports = self.all_instr(0, codelen, (IMPORT_NAME, IMPORT_FROM, IMPORT_STAR)) if len(imports) > 1: last_import = imports[0] @@ -248,10 +248,10 @@ class Scanner26(scan.Scanner): if destFor == i+opsize+4: setupLoop = self.last_instr(0, jmpabs1target, SETUP_LOOP) standarFor = self.last_instr(setupLoop, jmpabs1target, GET_ITER) - if standarFor == None: + if standarFor == None: self.restructJump(jmpabs1target, destFor+self.op_size(POP_BLOCK)) toDel += [setupLoop, i+opsize+1, i+opsize+4] - + if len(toDel) > 0: return toDel return None @@ -288,7 +288,7 @@ class Scanner26(scan.Scanner): target = self.get_target(target-3) self.restructJump(start, target) start += self.op_size(PJIF) - # del DELETE_NAME x + # del DELETE_NAME x start = end while end < len(self.code): end = self.first_instr(end, len(self.code), (DELETE_NAME,DELETE_FAST)) @@ -303,7 +303,7 @@ class Scanner26(scan.Scanner): # for / while struct if opcode == SETUP_LOOP: # change join(for..) struct - if self.code[i+3] == LOAD_FAST and self.code[i+6] == FOR_ITER: + if self.code[i+3] == LOAD_FAST and self.code[i+6] == FOR_ITER: end = self.first_instr(i, len(self.code), RETURN_VALUE) end = self.first_instr(i, end, YIELD_VALUE) if end and self.code[end+1] == POP_TOP and self.code[end+2] == JA and self.code[end+5] == POP_BLOCK: @@ -385,7 +385,7 @@ class Scanner26(scan.Scanner): if listDel: for jmp in self.op_range(0, len(self.code)): op = self.code[jmp] - if op in hasjrel+hasjabs: + if op in hasjrel+hasjabs: offset = 0 jmpTarget = self.get_target(jmp) for toDel in listDel: @@ -416,9 +416,9 @@ class Scanner26(scan.Scanner): # we can't use op_range for the moment # convert jump opcode to 2.7 self.restructRelativeJump() - + listExp = self.getOpcodeToExp() - # change code structure + # change code structure if listExp: listExp = sorted(list(set(listExp))) self.restructCode([], listExp) @@ -435,7 +435,7 @@ class Scanner26(scan.Scanner): ret = self.getOpcodeToDel(i) if ret != None: listDel += ret - + # change code structure after deleting byte if listDel: listDel = sorted(list(set(listDel))) @@ -479,7 +479,7 @@ class Scanner26(scan.Scanner): if self.op_hasArgument(op) and op not in self.opc.hasArgumentExtended: i += 3 else: i += 1 - + def restructJump(self, pos, newTarget): if not (self.code[pos] in hasjabs+hasjrel): raise 'Can t change this argument. Opcode is not a jump' @@ -491,7 +491,7 @@ class Scanner26(scan.Scanner): raise NotImplementedError self.code[pos+2] = (target >> 8) & 0xFF self.code[pos+1] = target & 0xFF - + def build_stmt_indices(self): code = self.code start = 0; @@ -509,9 +509,9 @@ class Scanner26(scan.Scanner): } stmt_opcode_seqs = [(PJIF, JF), (PJIF, JA), (PJIT, JF), (PJIT, JA)] - + designator_ops = { - STORE_FAST, STORE_NAME, STORE_GLOBAL, STORE_DEREF, STORE_ATTR, + STORE_FAST, STORE_NAME, STORE_GLOBAL, STORE_DEREF, STORE_ATTR, STORE_SLICE_0, STORE_SLICE_1, STORE_SLICE_2, STORE_SLICE_3, STORE_SUBSCR, UNPACK_SEQUENCE, JA } @@ -528,17 +528,17 @@ class Scanner26(scan.Scanner): match = False break i += self.op_size(code[i]) - + if match: i = self.prev[i] stmts.add(i) pass_stmts.add(i) - + if pass_stmts: stmt_list = list(stmts) stmt_list.sort() else: - stmt_list = prelim + stmt_list = prelim last_stmt = -1 self.next_stmt = [] slist = self.next_stmt = [] @@ -634,7 +634,7 @@ class Scanner26(scan.Scanner): if target != end: self.fixed_jumps[pos] = end - + (line_no, next_line_byte) = self.lines[pos] jump_back = self.last_instr(start, end, JA, next_line_byte, False) @@ -644,7 +644,7 @@ class Scanner26(scan.Scanner): jump_back = None if not jump_back: # loop suite ends in return. wtf right? jump_back = self.last_instr(start, end, RETURN_VALUE) - if not jump_back: + if not jump_back: return jump_back += 1 if code[self.prev[next_line_byte]] not in (PJIF, PJIT): @@ -666,7 +666,7 @@ class Scanner26(scan.Scanner): elif target < pos: self.fixed_jumps[pos] = jump_back+4 end = jump_back+4 - + target = self.get_target(jump_back, JA) if code[target] in (FOR_ITER, GET_ITER): @@ -676,7 +676,7 @@ class Scanner26(scan.Scanner): test = self.prev[next_line_byte] if test == pos: loop_type = 'while 1' - elif self.code[test] in hasjabs+hasjrel: + elif self.code[test] in hasjabs+hasjrel: self.ignore_if.add(test) test_target = self.get_target(test) if test_target > (jump_back+3): @@ -725,7 +725,7 @@ class Scanner26(scan.Scanner): self.structs.append({'type': 'except', 'start': i, 'end': jmp}) - i = jmp + 3 + i = jmp + 3 ## Add the try-else block if end_else != start_else: @@ -754,7 +754,7 @@ class Scanner26(scan.Scanner): 'start': start, 'end': pre[target]}) return - + # is this an if and if op == PJIF: match = self.rem_or(start, self.next_stmt[pos], PJIF, target) @@ -790,7 +790,7 @@ class Scanner26(scan.Scanner): self.fixed_jumps[pos] = fix or match[-1] return elif pos < rtarget and code[target] == ROT_TWO: - self.fixed_jumps[pos] = target + self.fixed_jumps[pos] = target return else: self.fixed_jumps[pos] = match[-1] @@ -800,7 +800,7 @@ class Scanner26(scan.Scanner): if code[pre[rtarget]] == RAISE_VARARGS: return self.load_asserts.remove(pos+3) - + next = self.next_stmt[pos] if pre[next] == pos: pass @@ -816,7 +816,7 @@ class Scanner26(scan.Scanner): #don't add a struct for a while test, it's already taken care of if pos in self.ignore_if: return - + if code[pre[rtarget]] == JA and pre[rtarget] in self.stmts \ and pre[rtarget] != pos and pre[pre[rtarget]] != pos \ and not (code[rtarget] == JA and code[rtarget+3] == POP_BLOCK and code[pre[pre[rtarget]]] != JA): @@ -824,19 +824,19 @@ class Scanner26(scan.Scanner): #does the if jump just beyond a jump op, then this is probably an if statement if code[pre[rtarget]] in (JA, JF): if_end = self.get_target(pre[rtarget]) - + #is this a loop not an if? if (if_end < pre[rtarget]) and (code[pre[if_end]] == SETUP_LOOP): if(if_end > start): return - + end = self.restrict_to_parent(if_end, parent) - + self.structs.append({'type': 'if-then', 'start': start, 'end': pre[rtarget]}) self.not_continue.add(pre[rtarget]) - + if rtarget < end: self.structs.append({'type': 'if-else', 'start': rtarget, @@ -867,7 +867,7 @@ class Scanner26(scan.Scanner): self.loops = [] ## All loop entry points self.fixed_jumps = {} ## Map fixed jumps to their real destination self.ignore_if = set() - self.build_stmt_indices() + self.build_stmt_indices() self.not_continue = set() self.return_end_ifs = set() @@ -880,7 +880,7 @@ class Scanner26(scan.Scanner): if self.op_hasArgument(op): label = self.fixed_jumps.get(i) - oparg = self.get_argument(i) + oparg = self.get_argument(i) if label is None: if op in hasjrel and op != FOR_ITER: label = i + 3 + oparg @@ -894,4 +894,3 @@ class Scanner26(scan.Scanner): label = self.fixed_jumps[i] targets[label] = targets.get(label, []) + [i] return targets - diff --git a/uncompyle6/scanner27.py b/uncompyle6/scanner27.py index 9481cc90..f511a4f8 100755 --- a/uncompyle6/scanner27.py +++ b/uncompyle6/scanner27.py @@ -11,14 +11,14 @@ from collections import namedtuple from array import array from operator import itemgetter -from uncompyle2.opcode.opcode_27 import * +from uncompyle6.opcodes.opcode_27 import * import disas as dis import scanner as scan class Scanner27(scan.Scanner): def __init__(self): self.Token = scan.Scanner.__init__(self, 2.7) # check - + def disassemble(self, co, classname=None): ''' Disassemble a code object, returning a list of 'Token'. @@ -33,7 +33,7 @@ class Scanner27(scan.Scanner): if self.code[i] in (RETURN_VALUE, END_FINALLY): n = i + 1 self.code = array('B', co.co_code[:n]) - + self.prev = [0] # mapping adresses of instru & arg for i in self.op_range(0, n): @@ -42,7 +42,7 @@ class Scanner27(scan.Scanner): if op >= HAVE_ARGUMENT: self.prev.append(i) self.prev.append(i) - + self.lines = [] linetuple = namedtuple('linetuple', ['l_no', 'next']) j = 0 @@ -66,7 +66,7 @@ class Scanner27(scan.Scanner): 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 ] @@ -80,7 +80,7 @@ class Scanner27(scan.Scanner): if self.code[i] == PJIT and self.code[i+3] == LOAD_GLOBAL: if names[self.get_argument(i+3)] == 'AssertionError': self.load_asserts.add(i+3) - + cf = self.find_jump_targets(self.code) # contains (code, [addrRefToCode]) last_stmt = self.next_stmt[0] @@ -95,7 +95,7 @@ class Scanner27(scan.Scanner): replace[i] = 'PRINT_NEWLINE_CONT' last_stmt = i i = self.next_stmt[i] - + imports = self.all_instr(0, n, (IMPORT_NAME, IMPORT_FROM, IMPORT_STAR)) if len(imports) > 1: last_import = imports[0] @@ -104,7 +104,7 @@ class Scanner27(scan.Scanner): if self.code[last_import] == IMPORT_NAME == self.code[i]: replace[i] = 'IMPORT_NAME_CONT' last_import = i - + extended_arg = 0 for offset in self.op_range(0, n): if offset in cf: @@ -113,7 +113,7 @@ class Scanner27(scan.Scanner): rv.append(Token('COME_FROM', None, repr(j), offset="%s_%d" % (offset, k))) k += 1 - + op = self.code[offset] op_name = opname[op] oparg = None; pattr = None @@ -193,7 +193,7 @@ class Scanner27(scan.Scanner): rv.append(Token(op_name, oparg, pattr, offset, linestart = offset in linestartoffsets)) else: rv.append(Token(replace[offset], oparg, pattr, offset, linestart = offset in linestartoffsets)) - + if self.showasm: out = self.out # shortcut for t in rv: @@ -206,12 +206,12 @@ class Scanner27(scan.Scanner): return 1 else: return 3 - + def build_stmt_indices(self): code = self.code start = 0; end = len(code) - + stmt_opcodes = { SETUP_LOOP, BREAK_LOOP, CONTINUE_LOOP, SETUP_FINALLY, END_FINALLY, SETUP_EXCEPT, SETUP_WITH, @@ -226,9 +226,9 @@ class Scanner27(scan.Scanner): } stmt_opcode_seqs = [(PJIF, JF), (PJIF, JA), (PJIT, JF), (PJIT, JA)] - + designator_ops = { - STORE_FAST, STORE_NAME, STORE_GLOBAL, STORE_DEREF, STORE_ATTR, + STORE_FAST, STORE_NAME, STORE_GLOBAL, STORE_DEREF, STORE_ATTR, STORE_SLICE_0, STORE_SLICE_1, STORE_SLICE_2, STORE_SLICE_3, STORE_SUBSCR, UNPACK_SEQUENCE, JA } @@ -245,12 +245,12 @@ class Scanner27(scan.Scanner): match = False break i += self.op_size(code[i]) - + if match: i = self.prev[i] stmts.add(i) pass_stmts.add(i) - + if pass_stmts: stmt_list = list(stmts) stmt_list.sort() @@ -286,7 +286,7 @@ class Scanner27(scan.Scanner): slist += [s] * (s-i) i = s slist += [end] * (end-len(slist)) - + def remove_mid_line_ifs(self, ifs): filtered = [] for i in ifs: @@ -309,7 +309,7 @@ class Scanner27(scan.Scanner): self.ignore_if.add(except_match) self.not_continue.add(jmp) return jmp - + count_END_FINALLY = 0 count_SETUP_ = 0 for i in self.op_range(start, len(self.code)): @@ -367,7 +367,7 @@ class Scanner27(scan.Scanner): jump_back = None if not jump_back: # loop suite ends in return. wtf right? jump_back = self.last_instr(start, end, RETURN_VALUE) + 1 - if not jump_back: + if not jump_back: return if code[self.prev[next_line_byte]] not in (PJIF, PJIT): loop_type = 'for' @@ -388,7 +388,7 @@ class Scanner27(scan.Scanner): self.fixed_jumps[pos] = jump_back+4 end = jump_back+4 target = self.get_target(jump_back, JA) - + if code[target] in (FOR_ITER, GET_ITER): loop_type = 'for' else: @@ -396,7 +396,7 @@ class Scanner27(scan.Scanner): test = self.prev[next_line_byte] if test == pos: loop_type = 'while 1' - elif self.code[test] in hasjabs+hasjrel: + elif self.code[test] in hasjabs+hasjrel: self.ignore_if.add(test) test_target = self.get_target(test) if test_target > (jump_back+3): @@ -441,7 +441,7 @@ class Scanner27(scan.Scanner): self.structs.append({'type': 'except', 'start': i, 'end': jmp}) - i = jmp + 3 + i = jmp + 3 ## Add the try-else block if end_else != start_else: @@ -452,14 +452,14 @@ class Scanner27(scan.Scanner): self.fixed_jumps[i] = r_end_else else: self.fixed_jumps[i] = i+1 - + elif op in (PJIF, PJIT): - start = pos+3 + start = pos+3 target = self.get_target(pos, op) rtarget = self.restrict_to_parent(target, parent) pre = self.prev - + if target != rtarget and parent['type'] == 'and/or': self.fixed_jumps[pos] = rtarget return @@ -472,7 +472,7 @@ class Scanner27(scan.Scanner): 'start': start, 'end': pre[target]}) return - + # is this an if and if op == PJIF: match = self.rem_or(start, self.next_stmt[pos], PJIF, target) @@ -516,7 +516,7 @@ class Scanner27(scan.Scanner): if code[pre[rtarget]] == RAISE_VARARGS: return self.load_asserts.remove(pos+3) - + next = self.next_stmt[pos] if pre[next] == pos: pass @@ -533,7 +533,7 @@ class Scanner27(scan.Scanner): elif code[next_target] in (JA, JF) and self.get_target(next_target) == self.get_target(target): self.fixed_jumps[pos] = pre[next] return - + #don't add a struct for a while test, it's already taken care of if pos in self.ignore_if: return @@ -552,19 +552,19 @@ class Scanner27(scan.Scanner): #does the if jump just beyond a jump op, then this is probably an if statement if code[pre[rtarget]] in (JA, JF): if_end = self.get_target(pre[rtarget]) - + #is this a loop not an if? if (if_end < pre[rtarget]) and (code[pre[if_end]] == SETUP_LOOP): if(if_end > start): return - + end = self.restrict_to_parent(if_end, parent) - + self.structs.append({'type': 'if-then', 'start': start, 'end': pre[rtarget]}) self.not_continue.add(pre[rtarget]) - + if rtarget < end: self.structs.append({'type': 'if-else', 'start': rtarget, @@ -617,7 +617,7 @@ class Scanner27(scan.Scanner): if op in (JUMP_IF_FALSE_OR_POP, JUMP_IF_TRUE_OR_POP): if (oparg > i): label = oparg - + if label is not None and label != -1: targets[label] = targets.get(label, []) + [i] elif op == END_FINALLY and i in self.fixed_jumps: diff --git a/uncompyle6/spark.py b/uncompyle6/spark.py index ea06c1c9..4284e996 100755 --- a/uncompyle6/spark.py +++ b/uncompyle6/spark.py @@ -1,6 +1,7 @@ -''' +from __future__ import print_function +''' Copyright (c) 1998-2002 John Aycock - + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including @@ -8,17 +9,17 @@ Copyright (c) 1998-2002 John Aycock distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ''' __version__ = 'SPARK-0.7 (pre-alpha-7) uncompyle trim' @@ -28,31 +29,31 @@ def _namelist(instance): for c in classlist: for b in c.__bases__: classlist.append(b) - for name in c.__dict__.keys(): - if not namedict.has_key(name): + for name in list(c.__dict__.keys()): + if name not in namedict: namelist.append(name) namedict[name] = 1 return namelist -# -# Extracted from GenericParser and made global so that [un]picking works. -# class _State: + ''' + Extracted from GenericParser and made global so that [un]picking works. + ''' def __init__(self, stateno, items): self.T, self.complete, self.items = [], [], items self.stateno = stateno class GenericParser: - # - # An Earley parser, as per J. Earley, "An Efficient Context-Free - # Parsing Algorithm", CACM 13(2), pp. 94-102. Also J. C. Earley, - # "An Efficient Context-Free Parsing Algorithm", Ph.D. thesis, - # Carnegie-Mellon University, August 1968. New formulation of - # the parser according to J. Aycock, "Practical Earley Parsing - # and the SPARK Toolkit", Ph.D. thesis, University of Victoria, - # 2001, and J. Aycock and R. N. Horspool, "Practical Earley - # Parsing", unpublished paper, 2001. - # + ''' + An Earley parser, as per J. Earley, "An Efficient Context-Free + Parsing Algorithm", CACM 13(2), pp. 94-102. Also J. C. Earley, + "An Efficient Context-Free Parsing Algorithm", Ph.D. thesis, + Carnegie-Mellon University, August 1968. New formulation of + the parser according to J. Aycock, "Practical Earley Parsing + and the SPARK Toolkit", Ph.D. thesis, University of Victoria, + 2001, and J. Aycock and R. N. Horspool, "Practical Earley + Parsing", unpublished paper, 2001. + ''' def __init__(self, start): self.rules = {} @@ -90,7 +91,7 @@ class GenericParser: changes = 1 while changes: changes = 0 - for k, v in self.edges.items(): + for k, v in list(self.edges.items()): if v is None: state, sym = k if self.states.has_key(state): @@ -127,12 +128,12 @@ class GenericParser: rules = doc.split() index = [] - for i in xrange(len(rules)): + for i in range(len(rules)): if rules[i] == '::=': index.append(i-1) index.append(len(rules)) - for i in xrange(len(index)-1): + for i in range(len(index)-1): lhs = rules[index[i]] rhs = rules[index[i]+2:index[i+1]] rule = (lhs, tuple(rhs)) @@ -140,7 +141,7 @@ class GenericParser: if _preprocess: rule, fn = self.preprocess(rule, func) - if self.rules.has_key(lhs): + if lhs in self.rules: self.rules[lhs].append(rule) else: self.rules[lhs] = [ rule ] @@ -163,7 +164,7 @@ class GenericParser: self.nullable = {} tbd = [] - for rulelist in self.rules.values(): + for rulelist in list(self.rules.values()): lhs = rulelist[0][0] self.nullable[lhs] = 0 for rule in rulelist: @@ -178,7 +179,7 @@ class GenericParser: # grammars. # for sym in rhs: - if not self.rules.has_key(sym): + if sym not in self.rules: break else: tbd.append(rule) @@ -212,7 +213,7 @@ class GenericParser: def makeNewRules(self): worklist = [] - for rulelist in self.rules.values(): + for rulelist in list(self.rules.values()): for rule in rulelist: worklist.append((rule, 0, 1, rule)) @@ -221,7 +222,7 @@ class GenericParser: n = len(rhs) while i < n: sym = rhs[i] - if not self.rules.has_key(sym) or \ + if sym not in self.rules or \ not self.nullable[sym]: candidate = 0 i = i + 1 @@ -238,7 +239,7 @@ class GenericParser: if candidate: lhs = self._NULLABLE+lhs rule = (lhs, rhs) - if self.newrules.has_key(lhs): + if lhs in self.newrules: self.newrules[lhs].append(rule) else: self.newrules[lhs] = [ rule ] @@ -248,7 +249,7 @@ class GenericParser: return None def error(self, token): - print "Syntax error at or near `%s' token" % token + print("Syntax error at or near `%s' token" % token) raise SystemExit def parse(self, tokens): @@ -274,7 +275,7 @@ class GenericParser: else: sets.append([]) self.makeSet(None, sets, len(tokens)) - + finalitem = (self.finalState(tokens), 0) if finalitem not in sets[-2]: if len(tokens) > 0: @@ -292,7 +293,8 @@ class GenericParser: # return self._NULLABLE == sym[0:len(self._NULLABLE)] - def skip(self, (lhs, rhs), pos=0): + def skip(self, xxx_todo_changeme, pos=0): + (lhs, rhs) = xxx_todo_changeme n = len(rhs) while pos < n: if not self.isnullable(rhs[pos]): @@ -551,12 +553,12 @@ class GenericParser: rule = self.ambiguity(self.newrules[nt]) else: rule = self.newrules[nt][0] - #print rule + # print(rule) rhs = rule[1] attr = [None] * len(rhs) - for i in xrange(len(rhs)-1, -1, -1): + for i in range(len(rhs)-1, -1, -1): attr[i] = self.deriveEpsilon(rhs[i]) return self.rule2func[self.new2old[rule]](attr) @@ -570,12 +572,12 @@ class GenericParser: rule = choices[0] if len(choices) > 1: rule = self.ambiguity(choices) - #print rule + # print(rule) rhs = rule[1] attr = [None] * len(rhs) - for i in xrange(len(rhs)-1, -1, -1): + for i in range(len(rhs)-1, -1, -1): sym = rhs[i] if not self.newrules.has_key(sym): if sym != self._BOF: @@ -599,24 +601,23 @@ class GenericParser: # appears in >1 method. Also undefined results if rules # causing the ambiguity appear in the same method. # - sortlist = [] name2index = {} - for i in xrange(len(rules)): + for i in range(len(rules)): lhs, rhs = rule = rules[i] name = self.rule2name[self.new2old[rule]] sortlist.append((len(rhs), name)) name2index[name] = i sortlist.sort() - list = map(lambda (a,b): b, sortlist) + list = [a_b[1] for a_b in sortlist] return rules[name2index[self.resolve(list)]] def resolve(self, list): - # - # Resolve ambiguity in favor of the shortest RHS. - # Since we walk the tree from the top down, this - # should effectively resolve in favor of a "shift". - # + ''' + Resolve ambiguity in favor of the shortest RHS. + Since we walk the tree from the top down, this + should effectively resolve in favor of a "shift". + ''' return list[0] # @@ -645,28 +646,29 @@ class GenericASTBuilder(GenericParser): if isinstance(arg, self.AST): children.append(arg) else: - children.append(arg) + children.append(self.terminal(arg)) return self.nonterminal(lhs, children) + def terminal(self, token): return token + def nonterminal(self, type, args): rv = self.AST(type) rv[:len(args)] = args return rv -# -# GenericASTTraversal is a Visitor pattern according to Design Patterns. For -# each node it attempts to invoke the method n_, falling -# back onto the default() method if the n_* can't be found. The preorder -# traversal also looks for an exit hook named n__exit (no default -# routine is called if it's not found). To prematurely halt traversal -# of a subtree, call the prune() method -- this only makes sense for a -# preorder traversal. Node type is determined via the typestring() method. -# - class GenericASTTraversalPruningException: pass class GenericASTTraversal: + ''' + GenericASTTraversal is a Visitor pattern according to Design Patterns. For + each node it attempts to invoke the method n_, falling + back onto the default() method if the n_* can't be found. The preorder + traversal also looks for an exit hook named n__exit (no default + routine is called if it's not found). To prematurely halt traversal + of a subtree, call the prune() method -- this only makes sense for a + preorder traversal. Node type is determined via the typestring() method. + ''' def __init__(self, ast): self.ast = ast