You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 00:45:53 +08:00
Patch for while loop + manifest + bug in test_pythonlib.py
This commit is contained in:
22
MANIFEST
Executable file
22
MANIFEST
Executable file
@@ -0,0 +1,22 @@
|
||||
README
|
||||
compile_tests
|
||||
setup.cfg
|
||||
setup.py
|
||||
test/*
|
||||
uncompyle2/__init__.py
|
||||
uncompyle2/disas.py
|
||||
uncompyle2/magics.py
|
||||
uncompyle2/parser.py
|
||||
uncompyle2/scanner.py
|
||||
uncompyle2/scanner25.py
|
||||
uncompyle2/scanner26.py
|
||||
uncompyle2/scanner27.py
|
||||
uncompyle2/spark.py
|
||||
uncompyle2/verify.py
|
||||
uncompyle2/walker.py
|
||||
uncompyle2/opcode/__init__.py
|
||||
uncompyle2/opcode/opcode_23.py
|
||||
uncompyle2/opcode/opcode_24.py
|
||||
uncompyle2/opcode/opcode_25.py
|
||||
uncompyle2/opcode/opcode_26.py
|
||||
uncompyle2/opcode/opcode_27.py
|
11
MANIFEST.in
11
MANIFEST.in
@@ -1,11 +0,0 @@
|
||||
include MANIFEST
|
||||
include MANIFEST.in
|
||||
include README
|
||||
include ANNOUNCE CHANGES TODO
|
||||
include uncompyle
|
||||
include test_pythonlib
|
||||
include test_one
|
||||
include compile_tests
|
||||
graft test
|
||||
graft scripts
|
||||
global-exclude *~ .*~
|
79
README
79
README
@@ -1,59 +1,49 @@
|
||||
uncompyle2
|
||||
==========
|
||||
|
||||
uncompyle2
|
||||
A Python 2.5, 2.6, 2.7 byte-code decompiler, written in Python 2.7
|
||||
0.13
|
||||
2012-6-5
|
||||
A Python 2.5, 2.6, 2.7 byte-code decompiler, written in Python 2.7
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
'uncompyle2' converts Python byte-code back into equivalent Python
|
||||
source. It accepts byte-code from Python version 2.5, 2.6 & 2.7. Additionally,
|
||||
it will only run on Python 2.7.
|
||||
source code. It accepts byte-code from Python version 2.5 to 2.7.
|
||||
Additionally, it will only run on Python 2.7.
|
||||
|
||||
The generated source is very readable: docstrings, lists, tuples and
|
||||
hashes get pretty-printed.
|
||||
|
||||
'uncompyle2' may also verify the equivalence of the generated source by
|
||||
by compiling it and comparing both byte-codes.
|
||||
|
||||
'uncompyle2' is based on John Aycock's generic small languages compiler
|
||||
'spark' (http://www.csr.uvic.ca/~aycock/python/) and his prior work on
|
||||
'uncompyle'.
|
||||
|
||||
Additional note (3 July 2004, Ben Burton):
|
||||
### Additional note (3 July 2004, Ben Burton):
|
||||
|
||||
The original website from which this software was obtained is no longer
|
||||
available. It has now become a commercial decompilation service, with
|
||||
no software available for download.
|
||||
The original website from which this software was obtained is no longer
|
||||
available. It has now become a commercial decompilation service, with
|
||||
no software available for download.
|
||||
|
||||
Any developers seeking to make alterations or enhancements to this code
|
||||
should therefore consider these debian packages an appropriate starting
|
||||
point.
|
||||
Any developers seeking to make alterations or enhancements to this code
|
||||
should therefore consider these debian packages an appropriate starting
|
||||
point.
|
||||
|
||||
Additional note (5 June 2012):
|
||||
### Additional note (5 June 2012):
|
||||
|
||||
The decompilation of python bytecode 2.5 & 2.6 is based on the work of
|
||||
Eloi Vanderbeken. bytecode is translated to a pseudo 2.7 python bytecode
|
||||
and then decompiled.
|
||||
The decompilation of python bytecode 2.5 & 2.6 is based on the work of
|
||||
Eloi Vanderbeken. bytecode is translated to a pseudo 2.7 python bytecode
|
||||
and then decompiled.
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
* decompiles Python byte-code into equivalent Python source
|
||||
- decompiles Python byte-code into equivalent Python source
|
||||
- decompiles byte-code from Python version 2.5, 2.6, 2.7
|
||||
- pretty-prints docstrings, hashes, lists and tuples
|
||||
- reads directly from .pyc/.pyo files, bulk-decompile whole directories
|
||||
- output may be written to file, a directory or to stdout
|
||||
- option for including byte-code disassembly into generated source
|
||||
|
||||
* decompiles byte-code from Python version 2.5, 2.6, 2.7
|
||||
|
||||
* pretty-prints docstrings, hashes, lists and tuples
|
||||
|
||||
* reads directly from .pyc/.pyo files, bulk-decompile whole
|
||||
directories
|
||||
|
||||
* output may be written to file, a directory or to stdout
|
||||
|
||||
* option for including byte-code disassembly into generated source
|
||||
|
||||
For a list of changes please refer to the 'CHANGES' file.
|
||||
For a list of changes please refer to the 'CHANGES' file.
|
||||
|
||||
|
||||
Requirements
|
||||
@@ -72,25 +62,24 @@ Creating RPMS:
|
||||
|
||||
python setup.py bdist_rpm
|
||||
|
||||
If you need to force the python interpreter to eg. pyton2:
|
||||
If you need to force the python interpreter to eg. pyton2:
|
||||
|
||||
python2 setup.py bdist_rpm --python=python2
|
||||
|
||||
|
||||
Installation from the source distribution:
|
||||
### Installation from the source distribution:
|
||||
|
||||
python setup.py install
|
||||
|
||||
To install to a user's home-dir:
|
||||
To install to a user's home-dir:
|
||||
|
||||
python setup.py install --home=<dir>
|
||||
|
||||
To install to another prefix (eg. /usr/local)
|
||||
To install to another prefix (eg. /usr/local)
|
||||
|
||||
python setup.py install --prefix=/usr/local
|
||||
|
||||
If you need to force the python interpreter to eg. pyton2:
|
||||
python2 setup.py install
|
||||
|
||||
For more information on 'Installing Python Modules' please refer to
|
||||
http://www.python.org/doc/current/inst/inst.html
|
||||
For more information on 'Installing Python Modules' please refer to
|
||||
http://www.python.org/doc/current/inst/inst.html
|
||||
|
||||
|
||||
Usage
|
||||
@@ -103,4 +92,6 @@ uncompyle2 --help prints long usage
|
||||
Known Bugs/Restrictions
|
||||
-----------------------
|
||||
|
||||
I have some known bug in the 2.5 & 2.6 decompilation version but this will be fixed in a few.
|
||||
No support for python 3.2
|
||||
|
||||
It currently reconstructs most of Python code but probably needs to be tested more thoroughly. All feedback welcome
|
||||
|
@@ -114,6 +114,7 @@ if __name__ == '__main__':
|
||||
if os.path.exists(testlibfile) or os.path.exists(testfile):
|
||||
src_dir = testpath
|
||||
checked_dirs.append([src_dir, pattern, target_dir])
|
||||
break
|
||||
|
||||
for src_dir, pattern, target_dir in checked_dirs:
|
||||
target_dir = os.path.join(target_base, target_dir)
|
||||
|
@@ -139,7 +139,8 @@ def disassemble_string(code, lasti=-1, varnames=None, names=None,
|
||||
print '(' + cmp_op[oparg] + ')',
|
||||
print
|
||||
|
||||
disco = disassemble # XXX For backwards compatibility
|
||||
disco = disassemble
|
||||
# XXX For backwards compatibility
|
||||
|
||||
def findlabels(code):
|
||||
"""Detect all offsets in a byte code which are jump targets.
|
||||
|
@@ -505,7 +505,7 @@ class Scanner25(scan.Scanner):
|
||||
last_stmt = s
|
||||
slist += [s] * (s-i)
|
||||
i = s
|
||||
slist += [len(code)] * (len(code)-len(slist))
|
||||
slist += [end] * (end-len(slist))
|
||||
|
||||
def next_except_jump(self, start):
|
||||
'''
|
||||
@@ -610,7 +610,7 @@ class Scanner25(scan.Scanner):
|
||||
test = self.prev[next_line_byte]
|
||||
if test == pos:
|
||||
loop_type = 'while 1'
|
||||
else:
|
||||
elif self.code[test] in hasjabs+hasjrel:
|
||||
self.ignore_if.add(test)
|
||||
test_target = self.get_target(test)
|
||||
if test_target > (jump_back+3):
|
||||
|
@@ -502,7 +502,7 @@ class Scanner26(scan.Scanner):
|
||||
last_stmt = s
|
||||
slist += [s] * (s-i)
|
||||
i = s
|
||||
slist += [len(code)] * (len(code)-len(slist))
|
||||
slist += [end] * (end-len(slist))
|
||||
|
||||
def next_except_jump(self, start):
|
||||
'''
|
||||
@@ -607,7 +607,7 @@ class Scanner26(scan.Scanner):
|
||||
test = self.prev[next_line_byte]
|
||||
if test == pos:
|
||||
loop_type = 'while 1'
|
||||
else:
|
||||
elif self.code[test] in hasjabs+hasjrel:
|
||||
self.ignore_if.add(test)
|
||||
test_target = self.get_target(test)
|
||||
if test_target > (jump_back+3):
|
||||
|
@@ -22,7 +22,6 @@ class Scanner27(scan.Scanner):
|
||||
def disassemble(self, co, classname=None):
|
||||
'''
|
||||
Disassemble a code object, returning a list of 'Token'.
|
||||
|
||||
The main part of this procedure is modelled after
|
||||
dis.disassemble().
|
||||
'''
|
||||
@@ -98,12 +97,11 @@ class Scanner27(scan.Scanner):
|
||||
|
||||
extended_arg = 0
|
||||
for offset in self.op_range(0, n):
|
||||
|
||||
if offset in cf:
|
||||
k = 0
|
||||
for j in cf[offset]:
|
||||
rv.append(Token('COME_FROM', None, repr(j),
|
||||
offset="%s_%d" % (offset, k) ))
|
||||
offset="%s_%d" % (offset, k)))
|
||||
k += 1
|
||||
|
||||
op = code[offset]
|
||||
@@ -274,7 +272,7 @@ class Scanner27(scan.Scanner):
|
||||
last_stmt = s
|
||||
slist += [s] * (s-i)
|
||||
i = s
|
||||
slist += [len(code)] * (len(code)-len(slist))
|
||||
slist += [end] * (end-len(slist))
|
||||
|
||||
def remove_mid_line_ifs(self, ifs):
|
||||
filtered = []
|
||||
@@ -344,10 +342,10 @@ class Scanner27(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)
|
||||
|
||||
if jump_back and jump_back != self.prev[end] and code[jump_back+3] in (JA, JF):
|
||||
if code[self.prev[end]] == RETURN_VALUE or \
|
||||
(code[self.prev[end]] == POP_BLOCK and code[self.prev[self.prev[end]]] == RETURN_VALUE):
|
||||
@@ -365,8 +363,7 @@ class Scanner27(scan.Scanner):
|
||||
end = jump_back + 3
|
||||
else:
|
||||
if self.get_target(jump_back) >= next_line_byte:
|
||||
jump_back = self.last_instr(start, end, JA,
|
||||
start, False)
|
||||
jump_back = self.last_instr(start, end, JA, start, False)
|
||||
if end > jump_back+4 and code[end] in (JF, JA):
|
||||
if code[jump_back+4] in (JA, JF):
|
||||
if self.get_target(jump_back+4) == self.get_target(end):
|
||||
@@ -375,7 +372,6 @@ class Scanner27(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):
|
||||
@@ -385,7 +381,7 @@ class Scanner27(scan.Scanner):
|
||||
test = self.prev[next_line_byte]
|
||||
if test == pos:
|
||||
loop_type = 'while 1'
|
||||
else:
|
||||
elif self.code[test] in hasjabs+hasjrel:
|
||||
self.ignore_if.add(test)
|
||||
test_target = self.get_target(test)
|
||||
if test_target > (jump_back+3):
|
||||
|
Reference in New Issue
Block a user