You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-04 09:22:40 +08:00
Python 3 decompilation from Python2
This commit is contained in:
@@ -9,30 +9,38 @@ NATIVE_CHECK = check-$(PYTHON_VERSION)
|
|||||||
# Set COMPILE='--compile' to force compilation before check
|
# Set COMPILE='--compile' to force compilation before check
|
||||||
COMPILE ?=
|
COMPILE ?=
|
||||||
|
|
||||||
#: Run working tests from Python 2.7
|
# Run short tests
|
||||||
check-2.7: check-short-2.7 check-bytecode-2.5 check-2.7-ok
|
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
|
# Run all tests
|
||||||
check-3.4: check-short-3.4 check-short-2.7 check-bytecode-2.5 check-bytecode-3.2
|
check:
|
||||||
|
|
||||||
check: check-short
|
|
||||||
@$(PYTHON) -V && PYTHON_VERSION=`$(PYTHON) -V 2>&1 | cut -d ' ' -f 2 | cut -d'.' -f1,2`; \
|
@$(PYTHON) -V && PYTHON_VERSION=`$(PYTHON) -V 2>&1 | cut -d ' ' -f 2 | cut -d'.' -f1,2`; \
|
||||||
$(MAKE) check-$$PYTHON_VERSION
|
$(MAKE) check-$$PYTHON_VERSION
|
||||||
|
|
||||||
check-short:
|
#: Run working tests from Python 2.7
|
||||||
@$(PYTHON) -V && PYTHON_VERSION=`$(PYTHON) -V 2>&1 | cut -d ' ' -f 2 | cut -d'.' -f1,2`; \
|
check-2.7: check-bytecode check-2.7-ok
|
||||||
$(MAKE) check-short-$$PYTHON_VERSION
|
|
||||||
|
#: Run working tests from Python 3.4
|
||||||
|
check-3.4: check-bytecode
|
||||||
|
|
||||||
#: Check deparsing only, but from a different Python version
|
#: Check deparsing only, but from a different Python version
|
||||||
check-disasm:
|
check-disasm:
|
||||||
$(PYTHON) dis-compare.py
|
$(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:
|
check-bytecode-2.5:
|
||||||
$(PYTHON) test_pythonlib.py --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:
|
check-bytecode-3.2:
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.2
|
$(PYTHON) test_pythonlib.py --bytecode-3.2
|
||||||
|
|
||||||
@@ -40,14 +48,6 @@ check-bytecode-3.2:
|
|||||||
check-native-short:
|
check-native-short:
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-$(PYTHON_VERSION) --verify $(COMPILE)
|
$(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
|
#: Run longer Python 2.7's lib files known to be okay
|
||||||
check-2.7-ok:
|
check-2.7-ok:
|
||||||
$(PYTHON) test_pythonlib.py --ok-2.7 --verify $(COMPILE)
|
$(PYTHON) test_pythonlib.py --ok-2.7 --verify $(COMPILE)
|
||||||
|
BIN
test/bytecode_3.2/assign.pyc
Normal file
BIN
test/bytecode_3.2/assign.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.2/assign_none.pyc
Normal file
BIN
test/bytecode_3.2/assign_none.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.2/assign_none_str.pyc
Normal file
BIN
test/bytecode_3.2/assign_none_str.pyc
Normal file
Binary file not shown.
1
test/simple-source/misc/assign_none.py
Normal file
1
test/simple-source/misc/assign_none.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
vario = None
|
1
test/simple-source/misc/assign_none_str.py
Normal file
1
test/simple-source/misc/assign_none_str.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
vario = 'None'
|
@@ -92,6 +92,14 @@ def load_code_internal(fp, magic_int, bytes_for_s=False):
|
|||||||
co_firstlineno, bytes(co_lnotab, encoding='utf-8'),
|
co_firstlineno, bytes(co_lnotab, encoding='utf-8'),
|
||||||
co_freevars, co_cellvars)
|
co_freevars, co_cellvars)
|
||||||
else:
|
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,
|
return Code(co_argcount, co_nlocals, co_stacksize, co_flags, co_code,
|
||||||
co_consts, co_names, co_varnames, co_filename, co_name,
|
co_consts, co_names, co_varnames, co_filename, co_name,
|
||||||
co_firstlineno, co_lnotab, co_freevars, co_cellvars)
|
co_firstlineno, co_lnotab, co_freevars, co_cellvars)
|
||||||
|
@@ -14,6 +14,7 @@ from __future__ import print_function
|
|||||||
|
|
||||||
import dis, marshal
|
import dis, marshal
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
from array import array
|
||||||
|
|
||||||
from uncompyle6.scanner import Token, L65536
|
from uncompyle6.scanner import Token, L65536
|
||||||
|
|
||||||
@@ -42,7 +43,7 @@ class Scanner32(scan.Scanner):
|
|||||||
# Container for tokens
|
# Container for tokens
|
||||||
tokens = []
|
tokens = []
|
||||||
customize = {}
|
customize = {}
|
||||||
self.code = code = co.co_code
|
self.code = code = array('B', co.co_code)
|
||||||
codelen = len(code)
|
codelen = len(code)
|
||||||
self.build_lines_data(co)
|
self.build_lines_data(co)
|
||||||
self.build_prev_op()
|
self.build_prev_op()
|
||||||
@@ -97,7 +98,6 @@ class Scanner32(scan.Scanner):
|
|||||||
free = co.co_cellvars + co.co_freevars
|
free = co.co_cellvars + co.co_freevars
|
||||||
current_token.pattr = free[oparg]
|
current_token.pattr = free[oparg]
|
||||||
tokens.append(current_token)
|
tokens.append(current_token)
|
||||||
|
|
||||||
return tokens, customize
|
return tokens, customize
|
||||||
|
|
||||||
def build_lines_data(self, code_obj):
|
def build_lines_data(self, code_obj):
|
||||||
|
@@ -163,11 +163,12 @@ class Scanner34(scan.Scanner):
|
|||||||
def disassemble_cross_version(self, co):
|
def disassemble_cross_version(self, co):
|
||||||
"""
|
"""
|
||||||
Convert code object <co> into a sequence of tokens
|
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.
|
FIXME: the below is not based on the current Python 3.4 dis.disassemble_bytes().
|
||||||
It needs to be rewritten and moduled off of Python 3.4's dis.disassemble_bytes().
|
Fix that.
|
||||||
"""
|
"""
|
||||||
# Container for tokens
|
# Container for tokens
|
||||||
tokens = []
|
tokens = []
|
||||||
|
customize = {}
|
||||||
self.code = code = array('B', co.co_code)
|
self.code = code = array('B', co.co_code)
|
||||||
codelen = len(code)
|
codelen = len(code)
|
||||||
self.build_lines_data(co)
|
self.build_lines_data(co)
|
||||||
@@ -223,7 +224,7 @@ class Scanner34(scan.Scanner):
|
|||||||
free = co.co_cellvars + co.co_freevars
|
free = co.co_cellvars + co.co_freevars
|
||||||
current_token.pattr = free[oparg]
|
current_token.pattr = free[oparg]
|
||||||
tokens.append(current_token)
|
tokens.append(current_token)
|
||||||
return tokens, {}
|
return tokens, customize
|
||||||
|
|
||||||
def build_lines_data(self, code_obj):
|
def build_lines_data(self, code_obj):
|
||||||
"""
|
"""
|
||||||
@@ -620,7 +621,6 @@ class Scanner34(scan.Scanner):
|
|||||||
return filtered
|
return filtered
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import inspect
|
|
||||||
co = inspect.currentframe().f_code
|
co = inspect.currentframe().f_code
|
||||||
tokens, customize = Scanner34().disassemble(co)
|
tokens, customize = Scanner34().disassemble(co)
|
||||||
for t in tokens:
|
for t in tokens:
|
||||||
|
Reference in New Issue
Block a user