You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-04 01:09:52 +08:00
Add some disassemble tests using pytest.
This commit is contained in:
14
Makefile
14
Makefile
@@ -11,22 +11,22 @@ RM ?= rm
|
|||||||
LINT = flake8
|
LINT = flake8
|
||||||
|
|
||||||
#EXTRA_DIST=ipython/ipy_trepan.py trepan
|
#EXTRA_DIST=ipython/ipy_trepan.py trepan
|
||||||
PHONY=check clean dist distclean lint flake8 test test-unit test-functional rmChangeLog clean_pyc nosetests
|
PHONY=check clean pytest dist distclean lint flake8 test test-unit test-functional rmChangeLog clean_pyc nosetests
|
||||||
|
|
||||||
#: Default target - same as "check"
|
#: Default target - same as "check"
|
||||||
all: check
|
all: check
|
||||||
|
|
||||||
#: Make HTML docs
|
|
||||||
html:
|
|
||||||
cd docs && $(MAKE) html
|
|
||||||
|
|
||||||
#: Same as "check"
|
#: Same as "check"
|
||||||
test: check
|
test check: pytest check-short
|
||||||
|
|
||||||
#: Run tests
|
#: Run tests
|
||||||
check check-short:
|
check-short: pytest
|
||||||
$(MAKE) -C test $@
|
$(MAKE) -C test $@
|
||||||
|
|
||||||
|
#: Run tests
|
||||||
|
pytest:
|
||||||
|
$(MAKE) -C pytest check
|
||||||
|
|
||||||
#: Clean up temporary files and .pyc files
|
#: Clean up temporary files and .pyc files
|
||||||
clean: clean_pyc
|
clean: clean_pyc
|
||||||
$(PYTHON) ./setup.py $@
|
$(PYTHON) ./setup.py $@
|
||||||
|
@@ -4,6 +4,9 @@ machine:
|
|||||||
environment:
|
environment:
|
||||||
COMPILE: --compile
|
COMPILE: --compile
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
override:
|
||||||
|
- pip install -r test-requirements.txt
|
||||||
test:
|
test:
|
||||||
override:
|
override:
|
||||||
- python ./setup.py develop && make check
|
- python ./setup.py develop && make check
|
||||||
|
7
pytest/Makefile
Normal file
7
pytest/Makefile
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
PHONY=check test pytest
|
||||||
|
|
||||||
|
PYTHON ?= python
|
||||||
|
|
||||||
|
#: Run all tests
|
||||||
|
test check pytest:
|
||||||
|
py.test
|
33
pytest/test_disasm.py
Normal file
33
pytest/test_disasm.py
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import os.path
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from uncompyle6.disas import disassemble_file
|
||||||
|
|
||||||
|
def get_srcdir():
|
||||||
|
filename = os.path.normcase(os.path.dirname(__file__))
|
||||||
|
return os.path.realpath(filename)
|
||||||
|
|
||||||
|
src_dir = get_srcdir()
|
||||||
|
os.chdir(src_dir)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(("test_tuple", "function_to_test"), [
|
||||||
|
(
|
||||||
|
('../test/bytecode_2.5/test_import.pyc', 'testdata/test_import_25.right',),
|
||||||
|
disassemble_file
|
||||||
|
),
|
||||||
|
(
|
||||||
|
('../test/bytecode_2.7/test1.pyc', 'testdata/test1.right',),
|
||||||
|
disassemble_file
|
||||||
|
),
|
||||||
|
])
|
||||||
|
def test_funcoutput(capfd, test_tuple, function_to_test):
|
||||||
|
|
||||||
|
in_file , filename_expected = test_tuple
|
||||||
|
function_to_test(in_file)
|
||||||
|
resout, reserr = capfd.readouterr()
|
||||||
|
expected = open(filename_expected, "r").read()
|
||||||
|
if resout != expected:
|
||||||
|
with open(filename_expected + ".got", "w") as out:
|
||||||
|
out.write(resout)
|
||||||
|
assert resout == expected
|
88
pytest/testdata/test1.right
vendored
Normal file
88
pytest/testdata/test1.right
vendored
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
# Python 2.7
|
||||||
|
# Embedded file name: /src/external-vcs/github/rocky/python-uncompyle6/__pkginfo__.py
|
||||||
|
|
||||||
|
1 0 LOAD_CONST 'uncompyle6 packaging information'
|
||||||
|
3 STORE_NAME '__doc__'
|
||||||
|
|
||||||
|
13 6 LOAD_CONST '\nCopyright (C) 2015 Rocky Bernstein <rocky@gnu.org>.\n'
|
||||||
|
9 STORE_NAME 'copyright'
|
||||||
|
|
||||||
|
15 12 LOAD_CONST 'Development Status :: 3 - Alpha'
|
||||||
|
|
||||||
|
16 15 LOAD_CONST 'Intended Audience :: Developers'
|
||||||
|
|
||||||
|
17 18 LOAD_CONST 'Operating System :: OS Independent'
|
||||||
|
|
||||||
|
18 21 LOAD_CONST 'Programming Language :: Python'
|
||||||
|
|
||||||
|
19 24 LOAD_CONST 'Topic :: Software Development :: Debuggers'
|
||||||
|
|
||||||
|
20 27 LOAD_CONST 'Topic :: Software Development :: Libraries :: Python Modules'
|
||||||
|
30 BUILD_LIST_6 None
|
||||||
|
33 STORE_NAME 'classifiers'
|
||||||
|
|
||||||
|
24 36 LOAD_CONST 'Rocky Bernstein'
|
||||||
|
39 STORE_NAME 'author'
|
||||||
|
|
||||||
|
25 42 LOAD_CONST 'rb@dustyfeet.com'
|
||||||
|
45 STORE_NAME 'author_email'
|
||||||
|
|
||||||
|
26 48 LOAD_CONST None
|
||||||
|
51 STORE_NAME 'ftp_url'
|
||||||
|
|
||||||
|
28 54 LOAD_CONST 'python-debugger@googlegroups.com'
|
||||||
|
57 STORE_NAME 'mailing_list'
|
||||||
|
|
||||||
|
29 60 LOAD_CONST 'uncompyle6'
|
||||||
|
63 STORE_NAME 'modname'
|
||||||
|
|
||||||
|
30 66 LOAD_CONST 'uncompyle6'
|
||||||
|
69 LOAD_CONST 'uncompyle6.opcodes'
|
||||||
|
72 BUILD_LIST_2 None
|
||||||
|
75 STORE_NAME 'packages'
|
||||||
|
|
||||||
|
31 78 LOAD_CONST None
|
||||||
|
81 STORE_NAME 'py_modules'
|
||||||
|
|
||||||
|
32 84 LOAD_CONST 'Python byte-code disassembler and source-code converter'
|
||||||
|
87 STORE_NAME 'short_desc'
|
||||||
|
|
||||||
|
33 90 LOAD_CONST 'bin/uncompyle6'
|
||||||
|
93 LOAD_CONST 'bin/pydisassemble'
|
||||||
|
96 BUILD_LIST_2 None
|
||||||
|
99 STORE_NAME 'scripts'
|
||||||
|
|
||||||
|
35 102 LOAD_CONST -1
|
||||||
|
105 LOAD_CONST None
|
||||||
|
108 IMPORT_NAME 'os.path'
|
||||||
|
111 STORE_NAME 'os'
|
||||||
|
|
||||||
|
38 114 LOAD_CONST '<code_object get_srcdir>'
|
||||||
|
117 MAKE_FUNCTION_0 None
|
||||||
|
120 STORE_NAME 'get_srcdir'
|
||||||
|
|
||||||
|
43 123 BUILD_MAP None
|
||||||
|
126 STORE_NAME 'ns'
|
||||||
|
|
||||||
|
44 129 LOAD_CONST '2.0'
|
||||||
|
132 STORE_NAME 'version'
|
||||||
|
|
||||||
|
45 135 LOAD_CONST 'https://github.com/rocky/python-uncompyle6/'
|
||||||
|
138 STORE_NAME 'web'
|
||||||
|
|
||||||
|
48 141 LOAD_NAME 'True'
|
||||||
|
144 STORE_NAME 'zip_safe'
|
||||||
|
|
||||||
|
51 147 LOAD_CONST '<code_object read>'
|
||||||
|
150 MAKE_FUNCTION_0 None
|
||||||
|
153 STORE_NAME 'read'
|
||||||
|
|
||||||
|
54 156 LOAD_NAME 'read'
|
||||||
|
159 LOAD_CONST 'README.rst'
|
||||||
|
162 CALL_FUNCTION_1 None
|
||||||
|
165 LOAD_CONST '\n'
|
||||||
|
168 BINARY_ADD None
|
||||||
|
169 STORE_NAME 'long_description'
|
||||||
|
172 LOAD_CONST None
|
||||||
|
175 RETURN_VALUE None
|
||||||
|
|
75
pytest/testdata/test_import_25.right
vendored
Normal file
75
pytest/testdata/test_import_25.right
vendored
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
# Python 2.5
|
||||||
|
# Embedded file name: test_import.py
|
||||||
|
|
||||||
|
9 0 LOAD_CONST '\ntest_import.py -- source test pattern for import statements\n\nThis source is part of the decompyle test suite.\n\ndecompyle is a Python byte-code decompiler\nSee http://www.goebel-consult.de/decompyle/ for download and\nfor further information\n'
|
||||||
|
3 STORE_NAME '__doc__'
|
||||||
|
|
||||||
|
11 6 LOAD_CONST -1
|
||||||
|
9 LOAD_CONST None
|
||||||
|
12 IMPORT_NAME 'sys'
|
||||||
|
15 STORE_NAME 'sys'
|
||||||
|
|
||||||
|
12 18 LOAD_CONST -1
|
||||||
|
21 LOAD_CONST None
|
||||||
|
24 IMPORT_NAME 'os'
|
||||||
|
27 STORE_NAME 'os'
|
||||||
|
30 LOAD_CONST -1
|
||||||
|
33 LOAD_CONST None
|
||||||
|
36 IMPORT_NAME_CONT 'sys'
|
||||||
|
39 STORE_NAME 'sys'
|
||||||
|
42 LOAD_CONST -1
|
||||||
|
45 LOAD_CONST None
|
||||||
|
48 IMPORT_NAME_CONT 'BaseHTTPServer'
|
||||||
|
51 STORE_NAME 'BaseHTTPServer'
|
||||||
|
|
||||||
|
14 54 LOAD_CONST -1
|
||||||
|
57 LOAD_CONST None
|
||||||
|
60 IMPORT_NAME 'test.test_MimeWriter'
|
||||||
|
63 STORE_NAME 'test'
|
||||||
|
|
||||||
|
16 66 LOAD_CONST -1
|
||||||
|
69 LOAD_CONST ('Message',)
|
||||||
|
72 IMPORT_NAME 'rfc822'
|
||||||
|
75 IMPORT_FROM 'Message'
|
||||||
|
78 STORE_NAME 'Message'
|
||||||
|
81 POP_TOP None
|
||||||
|
|
||||||
|
17 82 LOAD_CONST -1
|
||||||
|
85 LOAD_CONST ('Message', 'decode', 'choose_boundary')
|
||||||
|
88 IMPORT_NAME 'mimetools'
|
||||||
|
91 IMPORT_FROM 'Message'
|
||||||
|
94 STORE_NAME 'Message'
|
||||||
|
97 IMPORT_FROM 'decode'
|
||||||
|
100 STORE_NAME 'decode'
|
||||||
|
103 IMPORT_FROM 'choose_boundary'
|
||||||
|
106 STORE_NAME 'choose_boundary'
|
||||||
|
109 POP_TOP None
|
||||||
|
|
||||||
|
18 110 LOAD_CONST -1
|
||||||
|
113 LOAD_CONST ('*',)
|
||||||
|
116 IMPORT_NAME 'os'
|
||||||
|
119 IMPORT_STAR None
|
||||||
|
|
||||||
|
20 120 SETUP_LOOP '162'
|
||||||
|
123 LOAD_NAME 'globals'
|
||||||
|
126 CALL_FUNCTION_0 None
|
||||||
|
129 LOAD_ATTR 'items'
|
||||||
|
132 CALL_FUNCTION_0 None
|
||||||
|
135 GET_ITER None
|
||||||
|
136 FOR_ITER '161'
|
||||||
|
139 UNPACK_SEQUENCE_2 None
|
||||||
|
142 STORE_NAME 'k'
|
||||||
|
145 STORE_NAME 'v'
|
||||||
|
|
||||||
|
21 148 LOAD_NAME 'k'
|
||||||
|
151 UNARY_CONVERT None
|
||||||
|
152 PRINT_ITEM None
|
||||||
|
153 LOAD_NAME 'v'
|
||||||
|
156 PRINT_ITEM_CONT None
|
||||||
|
157 PRINT_NEWLINE_CONT None
|
||||||
|
158 JUMP_BACK '136'
|
||||||
|
161 POP_BLOCK None
|
||||||
|
162_0 COME_FROM '120'
|
||||||
|
162 LOAD_CONST None
|
||||||
|
165 RETURN_VALUE None
|
||||||
|
|
1
test-requirements.txt
Normal file
1
test-requirements.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
pytest
|
@@ -38,4 +38,4 @@ clean-unverified:
|
|||||||
|
|
||||||
#: Clean temporary compile/decompile/verify direcotries in /tmp
|
#: Clean temporary compile/decompile/verify direcotries in /tmp
|
||||||
clean-py-dis:
|
clean-py-dis:
|
||||||
rm -fvr /tmp/py-dis-* || true
|
rm -fr /tmp/py-dis-* || true
|
||||||
|
@@ -138,7 +138,7 @@ def do_tests(src_dir, obj_patterns, target_dir, opts):
|
|||||||
|
|
||||||
if opts['start_with']:
|
if opts['start_with']:
|
||||||
try:
|
try:
|
||||||
start_with = files.index(start_with)
|
start_with = files.index(opts['start_with'])
|
||||||
files = files[start_with:]
|
files = files[start_with:]
|
||||||
print('>>> starting with file', files[0])
|
print('>>> starting with file', files[0])
|
||||||
except ValueError:
|
except ValueError:
|
||||||
@@ -203,7 +203,7 @@ if __name__ == '__main__':
|
|||||||
print("Can't find directory %s. Skipping" % src_dir,
|
print("Can't find directory %s. Skipping" % src_dir,
|
||||||
file=sys.stderr)
|
file=sys.stderr)
|
||||||
continue
|
continue
|
||||||
if last_compile_version and last_compile_version != compile_version:
|
if last_compile_version and last_compile_version != compiled_version:
|
||||||
print("Warning: mixed python version decompylation")
|
print("Warning: mixed python version decompylation")
|
||||||
else:
|
else:
|
||||||
last_compile_version = compiled_version
|
last_compile_version = compiled_version
|
||||||
|
@@ -62,16 +62,16 @@ def load_code_internal(fp, magic_int):
|
|||||||
# a range here.
|
# a range here.
|
||||||
if 3000 < magic_int < 20121:
|
if 3000 < magic_int < 20121:
|
||||||
fp.read(4)
|
fp.read(4)
|
||||||
co_code = load_code(fp, magic_int)
|
co_code = load_code_internal(fp, magic_int)
|
||||||
co_consts = load_code(fp, magic_int)
|
co_consts = load_code_internal(fp, magic_int)
|
||||||
co_names = load_code(fp, magic_int)
|
co_names = load_code_internal(fp, magic_int)
|
||||||
co_varnames = load_code(fp, magic_int)
|
co_varnames = load_code_internal(fp, magic_int)
|
||||||
co_freevars = load_code(fp, magic_int)
|
co_freevars = load_code_internal(fp, magic_int)
|
||||||
co_cellvars = load_code(fp, magic_int)
|
co_cellvars = load_code_internal(fp, magic_int)
|
||||||
co_filename = load_code(fp, magic_int)
|
co_filename = load_code_internal(fp, magic_int)
|
||||||
co_name = load_code(fp, magic_int)
|
co_name = load_code_internal(fp, magic_int)
|
||||||
co_firstlineno = unpack('i', fp.read(4))[0]
|
co_firstlineno = unpack('i', fp.read(4))[0]
|
||||||
co_lnotab = load_code(fp, magic_int)
|
co_lnotab = load_code_internal(fp, magic_int)
|
||||||
# The Python3 code object is different than Python2's which
|
# The Python3 code object is different than Python2's which
|
||||||
# we are reading if we get here.
|
# we are reading if we get here.
|
||||||
# Also various parameters which were strings are now
|
# Also various parameters which were strings are now
|
||||||
@@ -159,7 +159,7 @@ def load_code_internal(fp, magic_int):
|
|||||||
tuplesize = unpack('i', fp.read(4))[0]
|
tuplesize = unpack('i', fp.read(4))[0]
|
||||||
ret = tuple()
|
ret = tuple()
|
||||||
while tuplesize > 0:
|
while tuplesize > 0:
|
||||||
ret += load_code(fp, magic_int),
|
ret += load_code_internal(fp, magic_int),
|
||||||
tuplesize -= 1
|
tuplesize -= 1
|
||||||
return ret
|
return ret
|
||||||
elif marshalType == '[':
|
elif marshalType == '[':
|
||||||
|
@@ -181,7 +181,7 @@ def cmp_code_objects(version, code_obj1, code_obj2, name=''):
|
|||||||
elif version == 3.4:
|
elif version == 3.4:
|
||||||
import uncompyle6.scanners.scanner34 as scan
|
import uncompyle6.scanners.scanner34 as scan
|
||||||
scanner = scan.Scanner34()
|
scanner = scan.Scanner34()
|
||||||
scanner.setShowAsm( showasm=0 )
|
scanner.setShowAsm( showasm=False )
|
||||||
global JUMP_OPs
|
global JUMP_OPs
|
||||||
JUMP_OPs = scan.JUMP_OPs + ['JUMP_BACK']
|
JUMP_OPs = scan.JUMP_OPs + ['JUMP_BACK']
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user