From f595f659ad79a24a7152cdf8bd450cb9c00b7e92 Mon Sep 17 00:00:00 2001 From: rocky Date: Mon, 14 Dec 2015 08:38:51 -0500 Subject: [PATCH] Python3 compatibility: (disas, scanner*) Reduce useless verbiage in status messages and DRY code a little; __init__, uncompyle6 --- scripts/uncompyle6 | 10 +++++++--- uncompyle6/__init__.py | 27 +++++++++++++++++++++------ uncompyle6/disas.py | 31 +++++++++++++++++++++++-------- uncompyle6/scanner.py | 3 +++ uncompyle6/scanner25.py | 8 ++++---- uncompyle6/scanner26.py | 4 ++-- uncompyle6/scanner27.py | 4 ++-- 7 files changed, 62 insertions(+), 25 deletions(-) diff --git a/scripts/uncompyle6 b/scripts/uncompyle6 index 9128d821..cc973d76 100755 --- a/scripts/uncompyle6 +++ b/scripts/uncompyle6 @@ -47,7 +47,7 @@ Usage_short = \ import sys, os, getopt import os.path -from uncompyle6 import main, verify +from uncompyle6 import main, status_msg, verify import time if sys.version[:3] != '2.7' and sys.version[:3] != '3.4': @@ -128,8 +128,12 @@ if timestamp: print(time.strftime(timestampfmt)) if numproc <= 1: try: - result = main(src_base, out_base, files, codes, outfile, showasm, showast, do_verify) - print('# decompiled %i files: %i okay, %i failed, %i verify failed' % result) + result = main(src_base, out_base, files, codes, outfile, showasm, + showast, do_verify) + if len(files) > 1: + mess = status_msg(do_verify, *result) + print('# ' + mess) + pass except (KeyboardInterrupt): pass except verify.VerifyCmpError: diff --git a/uncompyle6/__init__.py b/uncompyle6/__init__.py index d469e297..3f3ee0eb 100644 --- a/uncompyle6/__init__.py +++ b/uncompyle6/__init__.py @@ -107,10 +107,10 @@ def uncompyle(version, co, out=None, showasm=0, showast=0): import uncompyle6.scanner27 as scan scanner = scan.Scanner27() elif version == 2.6: - import scanner26 as scan + import uncompyle6.scanner26 as scan scanner = scan.Scanner26() elif version == 2.5: - import scanner25 as scan + import uncompyle6.scanner25 as scan scanner = scan.Scanner25() scanner.setShowAsm(showasm, out) tokens, customize = scanner.disassemble(co) @@ -166,6 +166,23 @@ else: def __memUsage(): return '' +def status_msg(do_verify, tot_files, okay_files, failed_files, + verify_failed_files): + if tot_files == 1: + if failed_files: + return "decompile failed" + elif verify_failed_files: + return "decompile verify failed" + else: + return "Successfully decompiled file" + pass + pass + mess = "decompiled %i files: %i okay, %i failed" % (tot_files, okay_files, failed_files) + if do_verify: + mess += (", %i verify failed" % verify_failed_files) + return mess + + def main(in_base, out_base, files, codes, outfile=None, showasm=0, showast=0, do_verify=0): ''' @@ -249,10 +266,8 @@ def main(in_base, out_base, files, codes, outfile=None, okay_files += 1 if not outfile: print('\n# okay decompyling', infile, __memUsage()) if outfile: - mess = "decompiled %i files: %i okay, %i failed" % (tot_files, okay_files, failed_files) - if do_verify: - mess += (", %i verify failed" % verify_failed_files) - sys.stdout.write("%s\r" % mess) + sys.stdout.write("%s\r" % + status_msg(do_verify, tot_files, okay_files, failed_files, verify_failed_files)) sys.stdout.flush() if outfile: sys.stdout.write("\n") diff --git a/uncompyle6/disas.py b/uncompyle6/disas.py index 56db4ec7..2aa4d18f 100644 --- a/uncompyle6/disas.py +++ b/uncompyle6/disas.py @@ -20,9 +20,12 @@ internStrings = [] # XXX For backwards compatibility disco = Mdis.disassemble -if (sys.version_info >= (3, 0)): - def long(n): - return n +PYTHON3 = (sys.version_info >= (3, 0)) +if PYTHON3: + def long(n): return n + +def compat_str(s): + return s.decode('utf-8', errors='ignore') if PYTHON3 else str(s) def marshalLoad(fp): global internStrings @@ -53,9 +56,21 @@ def load(fp): co_name = load(fp) co_firstlineno = unpack('i', fp.read(4))[0] co_lnotab = load(fp) - return Code(co_argcount, co_nlocals, co_stacksize, co_flags, co_code, - co_consts, co_names, co_varnames, co_filename, co_name, - co_firstlineno, co_lnotab, co_freevars, co_cellvars) + if PYTHON3: + # The Python3 code object is different than Python2's which + # we are reading if we get here. In particular, it has a + # kwonlyargcount parameter which we set to 0. + # Also various parameters which were strings are now + # bytes (which is probably more logical). + return Code(co_argcount, 0, co_nlocals, co_stacksize, co_flags, + bytes(co_code, encoding='utf-8'), + co_consts, co_names, co_varnames, co_filename, co_name, + co_firstlineno, bytes(co_lnotab, encoding='utf-8'), + co_freevars, co_cellvars) + else: + return Code(co_argcount, co_nlocals, co_stacksize, co_flags, co_code, + co_consts, co_names, co_varnames, co_filename, co_name, + co_firstlineno, co_lnotab, co_freevars, co_cellvars) # const type elif marshalType == '.': @@ -105,10 +120,10 @@ def load(fp): return internStrings[refnum] elif marshalType == 's': strsize = unpack('i', fp.read(4))[0] - return str(fp.read(strsize)) + return compat_str(fp.read(strsize)) elif marshalType == 't': strsize = unpack('i', fp.read(4))[0] - interned = str(fp.read(strsize)) + interned = compat_str(fp.read(strsize)) internStrings.append(interned) return interned elif marshalType == 'u': diff --git a/uncompyle6/scanner.py b/uncompyle6/scanner.py index d7ff2c0d..bbfc9792 100755 --- a/uncompyle6/scanner.py +++ b/uncompyle6/scanner.py @@ -16,7 +16,10 @@ from operator import itemgetter if (sys.version_info > (3, 0)): intern = sys.intern + L65536 = 65536 import uncompyle6 +else: + L65536 = long(65536) from uncompyle6.opcodes import opcode_25, opcode_26, opcode_27 diff --git a/uncompyle6/scanner25.py b/uncompyle6/scanner25.py index 33662282..731dd78b 100755 --- a/uncompyle6/scanner25.py +++ b/uncompyle6/scanner25.py @@ -12,9 +12,9 @@ from array import array from operator import itemgetter from struct import * -from uncompyle6.opcodes.opcode_25 import * import dis -import scanner as scan +from uncompyle6.opcodes.opcode_25 import * +import uncompyle6.scanner as scan class Scanner25(scan.Scanner): def __init__(self): @@ -131,7 +131,7 @@ class Scanner25(scan.Scanner): extended_arg = 0 if op == EXTENDED_ARG: raise NotImplementedError - extended_arg = oparg * 65536L + extended_arg = oparg * scan.L65536 continue if op in hasconst: const = co.co_consts[oparg] @@ -377,7 +377,7 @@ class Scanner25(scan.Scanner): result.append((block[0]+startBlock, block[1])) self.linestarts = result # handle opcodeToChange deplacement - for index in xrange(len(self.toChange)): + for index in range(len(self.toChange)): change = self.toChange[index] delta = 0 for toDel in listDel: diff --git a/uncompyle6/scanner26.py b/uncompyle6/scanner26.py index cb1db4f1..4036b6fd 100755 --- a/uncompyle6/scanner26.py +++ b/uncompyle6/scanner26.py @@ -133,7 +133,7 @@ class Scanner26(scan.Scanner): extended_arg = 0 if op == EXTENDED_ARG: raise NotImplementedError - extended_arg = oparg * 65536L + extended_arg = oparg * scan.L65536 continue if op in hasconst: const = co.co_consts[oparg] @@ -375,7 +375,7 @@ class Scanner26(scan.Scanner): result.append((block[0]+startBlock, block[1])) self.linestarts = result # handle opcodeToChange deplacement - for index in xrange(len(self.toChange)): + for index in range(len(self.toChange)): change = self.toChange[index] delta = 0 for toDel in listDel: diff --git a/uncompyle6/scanner27.py b/uncompyle6/scanner27.py index b5be6751..23ac8d28 100755 --- a/uncompyle6/scanner27.py +++ b/uncompyle6/scanner27.py @@ -55,7 +55,7 @@ class Scanner27(scan.Scanner): while j < start_byte: self.lines.append(linetuple(prev_line_no, start_byte)) j += 1 - (prev_start_byte, prev_line_no) = (start_byte, line_no) + (_, prev_line_no) = (start_byte, line_no) while j < n: self.lines.append(linetuple(prev_line_no, n)) j+=1 @@ -122,7 +122,7 @@ class Scanner27(scan.Scanner): oparg = self.get_argument(offset) + extended_arg extended_arg = 0 if op == EXTENDED_ARG: - extended_arg = oparg * 65536 + extended_arg = oparg * scan.L65536 continue if op in hasconst: const = co.co_consts[oparg]