Python 3 decompilation from Python2

This commit is contained in:
rocky
2015-12-20 18:10:18 -05:00
parent 21920b5852
commit 6910e1b1b4
9 changed files with 35 additions and 25 deletions

View File

@@ -9,30 +9,38 @@ NATIVE_CHECK = check-$(PYTHON_VERSION)
# Set COMPILE='--compile' to force compilation before check
COMPILE ?=
#: Run working tests from Python 2.7
check-2.7: check-short-2.7 check-bytecode-2.5 check-2.7-ok
# Run short tests
check-short:
@$(PYTHON) -V && PYTHON_VERSION=`$(PYTHON) -V 2>&1 | cut -d ' ' -f 2 | cut -d'.' -f1,2`; \
$(MAKE) check-bytecode
#: Run working tests from Python 3.4
check-3.4: check-short-3.4 check-short-2.7 check-bytecode-2.5 check-bytecode-3.2
check: check-short
# Run all tests
check:
@$(PYTHON) -V && PYTHON_VERSION=`$(PYTHON) -V 2>&1 | cut -d ' ' -f 2 | cut -d'.' -f1,2`; \
$(MAKE) check-$$PYTHON_VERSION
check-short:
@$(PYTHON) -V && PYTHON_VERSION=`$(PYTHON) -V 2>&1 | cut -d ' ' -f 2 | cut -d'.' -f1,2`; \
$(MAKE) check-short-$$PYTHON_VERSION
#: Run working tests from Python 2.7
check-2.7: check-bytecode check-2.7-ok
#: Run working tests from Python 3.4
check-3.4: check-bytecode
#: Check deparsing only, but from a different Python version
check-disasm:
$(PYTHON) dis-compare.py
#: Check deparsing only, from Python 2.5
#: Check deparsing bytecode only
check-bytecode: check-bytecode-2.5 check-bytecode-2.5 check-bytecode-3.2
#: Check deparsing Python 2.5
check-bytecode-2.5:
$(PYTHON) test_pythonlib.py --bytecode-2.5
#: Check deparsing Python 2.7
check-bytecode-2.7:
$(PYTHON) test_pythonlib.py --bytecode-2.7
#: Check deparsing only, from Python 3.2
#: Check deparsing Python 3.2
check-bytecode-3.2:
$(PYTHON) test_pythonlib.py --bytecode-3.2
@@ -40,14 +48,6 @@ check-bytecode-3.2:
check-native-short:
$(PYTHON) test_pythonlib.py --bytecode-$(PYTHON_VERSION) --verify $(COMPILE)
#: Short, quickly-running Python 2.7 programs. Useful in debugging grammar problems
check-short-2.7:
$(PYTHON) test_pythonlib.py --bytecode-2.7 --verify $(COMPILE)
#: Short, quickly-running Python 2.7 programs. Useful in debugging grammar problems
check-short-3.4:
$(PYTHON) test_pythonlib.py --bytecode-3.4 --verify $(COMPILE)
#: Run longer Python 2.7's lib files known to be okay
check-2.7-ok:
$(PYTHON) test_pythonlib.py --ok-2.7 --verify $(COMPILE)

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1 @@
vario = None

View File

@@ -0,0 +1 @@
vario = 'None'

View File

@@ -92,6 +92,14 @@ def load_code_internal(fp, magic_int, bytes_for_s=False):
co_firstlineno, bytes(co_lnotab, encoding='utf-8'),
co_freevars, co_cellvars)
else:
if (3000 < magic_int < 20121):
# Python 3 encodes some fields as Unicode while Python2
# requires the corresponding field to have string values
co_consts = tuple([str(s) if s else None for s in co_consts])
co_names = tuple([str(s) if s else None for s in co_names])
co_varnames = tuple([str(s) if s else None for s in co_varnames])
co_filename = str(co_filename)
co_name = str(co_name)
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)

View File

@@ -14,6 +14,7 @@ from __future__ import print_function
import dis, marshal
from collections import namedtuple
from array import array
from uncompyle6.scanner import Token, L65536
@@ -42,7 +43,7 @@ class Scanner32(scan.Scanner):
# Container for tokens
tokens = []
customize = {}
self.code = code = co.co_code
self.code = code = array('B', co.co_code)
codelen = len(code)
self.build_lines_data(co)
self.build_prev_op()
@@ -97,7 +98,6 @@ class Scanner32(scan.Scanner):
free = co.co_cellvars + co.co_freevars
current_token.pattr = free[oparg]
tokens.append(current_token)
return tokens, customize
def build_lines_data(self, code_obj):

View File

@@ -163,11 +163,12 @@ class Scanner34(scan.Scanner):
def disassemble_cross_version(self, co):
"""
Convert code object <co> into a sequence of tokens
FIXME: the below code faulty in many was is probably based on older Python2's dis.disassemble() function.
It needs to be rewritten and moduled off of Python 3.4's dis.disassemble_bytes().
FIXME: the below is not based on the current Python 3.4 dis.disassemble_bytes().
Fix that.
"""
# Container for tokens
tokens = []
customize = {}
self.code = code = array('B', co.co_code)
codelen = len(code)
self.build_lines_data(co)
@@ -223,7 +224,7 @@ class Scanner34(scan.Scanner):
free = co.co_cellvars + co.co_freevars
current_token.pattr = free[oparg]
tokens.append(current_token)
return tokens, {}
return tokens, customize
def build_lines_data(self, code_obj):
"""
@@ -620,7 +621,6 @@ class Scanner34(scan.Scanner):
return filtered
if __name__ == "__main__":
import inspect
co = inspect.currentframe().f_code
tokens, customize = Scanner34().disassemble(co)
for t in tokens: