You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 00:45:53 +08:00
Compare commits
50 Commits
releaes-3.
...
release-3.
Author | SHA1 | Date | |
---|---|---|---|
|
0e5eb954b2 | ||
|
7d9286b353 | ||
|
0de99e5d44 | ||
|
52af2ba32a | ||
|
bd0db6c539 | ||
|
8663b4ca52 | ||
|
b2dd58a85e | ||
|
97cb193a71 | ||
|
e6e60cb49d | ||
|
2ea8c3b1b1 | ||
|
701d2af54e | ||
|
8a4189bc0e | ||
|
0c4ab699b5 | ||
|
8e11c53064 | ||
|
b4c66d4307 | ||
|
53968e535f | ||
|
d2381fbe11 | ||
|
d413ebe0e1 | ||
|
f96522e18e | ||
|
50d50af2ee | ||
|
4dc2897cdc | ||
|
47fb80494d | ||
|
830e19e3e6 | ||
|
c5cfd36a61 | ||
|
9b550b9dda | ||
|
400943bb6a | ||
|
f89ba40147 | ||
|
32c611a315 | ||
|
5d91e96358 | ||
|
44edf1d7db | ||
|
a891aa0706 | ||
|
5e1340a2fc | ||
|
94eff282f8 | ||
|
7f65a8a6dd | ||
|
cfe7feed4d | ||
|
b3a20896b2 | ||
|
1425476018 | ||
|
59c77f103d | ||
|
726045a05e | ||
|
49e354375e | ||
|
f3d86e0708 | ||
|
820283827f | ||
|
8b65cc7275 | ||
|
1e47f47527 | ||
|
19a95be3ef | ||
|
5a6550b353 | ||
|
82fb9426af | ||
|
98b91db8e6 | ||
|
ce3f815b08 | ||
|
c447b9cfa9 |
3
Makefile
3
Makefile
@@ -40,6 +40,9 @@ check-3.0 check-3.1 check-3.2 check-3.6:
|
||||
check-3.7: pytest
|
||||
$(MAKE) -C test check
|
||||
|
||||
check-3.8:
|
||||
$(MAKE) -C test check
|
||||
|
||||
#:PyPy 2.6.1 PyPy 5.0.1, or PyPy 5.8.0-beta0
|
||||
# Skip for now
|
||||
2.6 5.0 5.3 5.6 5.8:
|
||||
|
21
NEWS.md
21
NEWS.md
@@ -1,3 +1,24 @@
|
||||
3.3.1 2019-04-19 Good Friday
|
||||
==========================
|
||||
|
||||
Lots of decomplation bugs, especially in the 3.x series fixed. Don't worry though, many more remain.
|
||||
|
||||
* Add annotation return values in 3.6+
|
||||
* Fix 3.6+ lambda parameter handling decompilation
|
||||
* Fix 3.7+ chained comparision decompilation
|
||||
* split out semantic-action customization into more separate files
|
||||
* Add 3.8 try/else
|
||||
* Fix 2.7 generator decompilation
|
||||
* Fix some parser failures fixes in 3.4+ using test_pyenvlib
|
||||
* Add more run tests
|
||||
|
||||
3.3.0 2019-43-14 Holy Week
|
||||
==========================
|
||||
|
||||
* First cut at Python 3.8 (many bugs remain)
|
||||
* Reinstate -c | --compile (compile before disassembly) option
|
||||
* The usual smattering of bug and doc fixes
|
||||
|
||||
3.2.6 2019-03-23 Mueller Report
|
||||
=======================================
|
||||
|
||||
|
@@ -12,7 +12,7 @@ Introduction
|
||||
|
||||
*uncompyle6* translates Python bytecode back into equivalent Python
|
||||
source code. It accepts bytecodes from Python version 1.3 to version
|
||||
3.7, spanning over 22 years of Python releases. We include Dropbox's
|
||||
3.8, spanning over 24 years of Python releases. We include Dropbox's
|
||||
Python 2.5 bytecode and some PyPy bytecode.
|
||||
|
||||
Why this?
|
||||
@@ -76,7 +76,7 @@ Requirements
|
||||
The code here can be run on Python versions 2.6 or later, PyPy 3-2.4,
|
||||
or PyPy-5.0.1. Python versions 2.4-2.7 are supported in the
|
||||
python-2.4 branch. The bytecode files it can read have been tested on
|
||||
Python bytecodes from versions 1.4, 2.1-2.7, and 3.0-3.6 and the
|
||||
Python bytecodes from versions 1.4, 2.1-2.7, and 3.0-3.8 and the
|
||||
above-mentioned PyPy versions.
|
||||
|
||||
Installation
|
||||
|
@@ -23,7 +23,7 @@
|
||||
|
||||
# Things that change more often go here.
|
||||
copyright = """
|
||||
Copyright (C) 2015-2018 Rocky Bernstein <rb@dustyfeet.com>.
|
||||
Copyright (C) 2015-2019 Rocky Bernstein <rb@dustyfeet.com>.
|
||||
"""
|
||||
|
||||
classifiers = ['Development Status :: 5 - Production/Stable',
|
||||
@@ -43,6 +43,7 @@ classifiers = ['Development Status :: 5 - Production/Stable',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Topic :: Software Development :: Debuggers',
|
||||
'Topic :: Software Development :: Libraries :: Python Modules',
|
||||
]
|
||||
@@ -57,7 +58,7 @@ entry_points = {
|
||||
]}
|
||||
ftp_url = None
|
||||
install_requires = ['spark-parser >= 1.8.7, < 1.9.0',
|
||||
'xdis >= 3.9.0, < 3.10.0']
|
||||
'xdis >= 4.0.0, < 4.1.0']
|
||||
|
||||
license = 'GPL3'
|
||||
mailing_list = 'python-debugger@googlegroups.com'
|
||||
|
@@ -58,7 +58,8 @@
|
||||
$ git tag release-python-2.4-$VERSION
|
||||
|
||||
$ . ./admin-tools/make-dist-newer.sh
|
||||
$ git tag release-$VERSION
|
||||
|
||||
Goto https://github.com/rocky/python-uncompyle6/releases
|
||||
|
||||
# Upload single package and look at Rst Formating
|
||||
|
||||
|
@@ -5,4 +5,4 @@ if [[ $0 == ${BASH_SOURCE[0]} ]] ; then
|
||||
echo "This script should be *sourced* rather than run directly through bash"
|
||||
exit 1
|
||||
fi
|
||||
export PYVERSIONS='3.2.6 3.6.8 3.7.2 2.6.9 3.3.7 2.7.15 3.2.6 3.1.5 3.4.8'
|
||||
export PYVERSIONS='3.6.8 3.7.2 2.6.9 3.3.7 2.7.15 3.2.6 3.1.5 3.4.8'
|
||||
|
@@ -47,7 +47,7 @@ class PrintFake():
|
||||
out = out[:-self.pending_newlines]
|
||||
self.f.write(out)
|
||||
def println(self, *data):
|
||||
if data and not(len(data) == 1 and data[0] ==''):
|
||||
if data and not(len(data) == 1 and data[0] == ''):
|
||||
self.write(*data)
|
||||
self.pending_newlines = max(self.pending_newlines, 1)
|
||||
return
|
||||
|
@@ -18,15 +18,19 @@ def test_grammar():
|
||||
right_recursive, dup_rhs) = p.check_sets()
|
||||
|
||||
# We have custom rules that create the below
|
||||
expect_lhs = set(['pos_arg', 'get_iter', 'attribute'])
|
||||
expect_lhs = set(['pos_arg', 'attribute'])
|
||||
if PYTHON_VERSION < 3.8:
|
||||
expect_lhs.add('get_iter')
|
||||
|
||||
|
||||
unused_rhs = set(['list', 'mkfunc',
|
||||
'mklambda',
|
||||
'unpack',])
|
||||
|
||||
expect_right_recursive = set([('designList',
|
||||
('store', 'DUP_TOP', 'designList'))])
|
||||
|
||||
if PYTHON_VERSION != 3.7:
|
||||
if PYTHON_VERSION < 3.7:
|
||||
unused_rhs.add('call')
|
||||
|
||||
if PYTHON_VERSION > 2.6:
|
||||
@@ -61,7 +65,11 @@ def test_grammar():
|
||||
expect_lhs.add('kwarg')
|
||||
|
||||
assert expect_lhs == set(lhs)
|
||||
assert unused_rhs == set(rhs)
|
||||
|
||||
# FIXME
|
||||
if PYTHON_VERSION != 3.8:
|
||||
assert unused_rhs == set(rhs)
|
||||
|
||||
assert expect_right_recursive == right_recursive
|
||||
|
||||
expect_dup_rhs = frozenset([('COME_FROM',), ('CONTINUE',), ('JUMP_ABSOLUTE',),
|
||||
|
@@ -80,7 +80,7 @@ def are_instructions_equal(i1, i2):
|
||||
|
||||
:return: True if the two instructions are approximately equal, otherwise False.
|
||||
"""
|
||||
result = (1==1
|
||||
result = (1 == 1
|
||||
and i1.opname == i2.opname
|
||||
and i1.opcode == i2.opcode
|
||||
and i1.arg == i2.arg
|
||||
|
4
setup.py
4
setup.py
@@ -4,8 +4,8 @@ import sys
|
||||
"""Setup script for the 'uncompyle6' distribution."""
|
||||
|
||||
SYS_VERSION = sys.version_info[0:2]
|
||||
if not ((2, 6) <= SYS_VERSION <= (3, 7)):
|
||||
mess = "Python Release 2.6 .. 3.7 are supported in this code branch."
|
||||
if not ((2, 6) <= SYS_VERSION <= (3, 8)):
|
||||
mess = "Python Release 2.6 .. 3.8 are supported in this code branch."
|
||||
if ((2, 4) <= SYS_VERSION <= (2, 7)):
|
||||
mess += ("\nFor your Python, version %s, use the python-2.4 code/branch." %
|
||||
sys.version[0:3])
|
||||
|
@@ -33,43 +33,48 @@ check-2.6 check-2.7: check-bytecode-2 check-bytecode-3 check-bytecode-1 check-na
|
||||
|
||||
#: Run working tests from Python 3.0
|
||||
check-3.0: check-bytecode
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.0 --weak-verify $(COMPILE)
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.0-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.0 --weak-verify $(COMPILE)
|
||||
|
||||
#: Run working tests from Python 3.1
|
||||
check-3.1: check-bytecode
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.1 --weak-verify $(COMPILE)
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.1-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.1 --weak-verify $(COMPILE)
|
||||
|
||||
#: Run working tests from Python 3.2
|
||||
check-3.2: check-bytecode
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.2 --weak-verify $(COMPILE)
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.2-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.2 --weak-verify $(COMPILE)
|
||||
|
||||
#: Run working tests from Python 3.3
|
||||
check-3.3: check-bytecode
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.3 --weak-verify $(COMPILE)
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.3-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.3 --weak-verify $(COMPILE)
|
||||
|
||||
#: Run working tests from Python 3.4
|
||||
check-3.4: check-bytecode check-3.4-ok check-2.7-ok
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.4 --weak-verify $(COMPILE)
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.4-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.4 --weak-verify $(COMPILE)
|
||||
|
||||
#: Run working tests from Python 3.5
|
||||
check-3.5: check-bytecode
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.5 --weak-verify $(COMPILE)
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.5-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.5 --weak-verify $(COMPILE)
|
||||
|
||||
#: Run working tests from Python 3.6
|
||||
check-3.6: check-bytecode
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.6 --weak-verify $(COMPILE)
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.6-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.6 --weak-verify $(COMPILE)
|
||||
|
||||
#: Run working tests from Python 3.7
|
||||
check-3.7: check-bytecode
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.7 --weak-verify $(COMPILE)
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.7-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.7 --weak-verify $(COMPILE)
|
||||
|
||||
#: Run working tests from Python 3.8
|
||||
check-3.8: check-bytecode
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.8-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.8 --weak-verify $(COMPILE)
|
||||
|
||||
# FIXME
|
||||
#: this is called when running under pypy3.5-5.8.0 or pypy2-5.6.0
|
||||
@@ -92,7 +97,8 @@ check-bytecode-2:
|
||||
check-bytecode-3:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.0 \
|
||||
--bytecode-3.1 --bytecode-3.2 --bytecode-3.3 \
|
||||
--bytecode-3.4 --bytecode-3.5 --bytecode-3.6 --bytecode-3.7 \
|
||||
--bytecode-3.4 --bytecode-3.5 --bytecode-3.6 \
|
||||
--bytecode-3.7 --bytecode-3.8 \
|
||||
--bytecode-pypy3.2
|
||||
|
||||
#: Check deparsing on selected bytecode 3.x
|
||||
@@ -217,53 +223,58 @@ grammar-coverage-3.6:
|
||||
|
||||
#: Check deparsing Python 2.6
|
||||
check-bytecode-2.6:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-2.6 --weak-verify
|
||||
$(PYTHON) test_pythonlib.py --bytecode-2.6-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-2.6 --weak-verify
|
||||
|
||||
#: Check deparsing Python 2.7
|
||||
check-bytecode-2.7:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-2.7 --weak-verify
|
||||
$(PYTHON) test_pythonlib.py --bytecode-2.7-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-2.7 --weak-verify
|
||||
|
||||
#: Check deparsing Python 3.0
|
||||
check-bytecode-3.0:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.0 --weak-verify
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.0-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.0 --weak-verify
|
||||
|
||||
#: Check deparsing Python 3.1
|
||||
check-bytecode-3.1:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.1 --weak-verify
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.1-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.1 --weak-verify
|
||||
|
||||
#: Check deparsing Python 3.2
|
||||
check-bytecode-3.2:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.2 --weak-verify
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.2-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.2 --weak-verify
|
||||
|
||||
#: Check deparsing Python 3.3
|
||||
check-bytecode-3.3:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.3 --weak-verify
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.3-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.3 --weak-verify
|
||||
|
||||
#: Check deparsing Python 3.4
|
||||
check-bytecode-3.4:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.4 --weak-verify
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.4-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.4 --weak-verify
|
||||
|
||||
#: Check deparsing Python 3.5
|
||||
check-bytecode-3.5:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.5 --weak-verify
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.5-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.5 --weak-verify
|
||||
|
||||
#: Check deparsing Python 3.6
|
||||
check-bytecode-3.6:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.6 --weak-verify
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.6-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.6 --weak-verify
|
||||
|
||||
#: Check deparsing Python 3.7
|
||||
check-bytecode-3.7:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.7 --weak-verify
|
||||
|
||||
#: Check deparsing Python 3.8
|
||||
check-bytecode-3.8:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.8-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.8 --weak-verify
|
||||
|
||||
#: short tests for bytecodes only for this version of Python
|
||||
check-native-short:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-$(PYTHON_VERSION) --weak-verify $(COMPILE)
|
||||
|
@@ -4,12 +4,19 @@
|
||||
import os, sys, py_compile
|
||||
assert len(sys.argv) >= 2
|
||||
version = sys.version[0:3]
|
||||
for path in sys.argv[1:]:
|
||||
if sys.argv[1] == '--run':
|
||||
suffix = '_run'
|
||||
py_source = sys.argv[2:]
|
||||
else:
|
||||
suffix = ''
|
||||
py_source = sys.argv[1:]
|
||||
|
||||
for path in py_source:
|
||||
short = os.path.basename(path)
|
||||
if hasattr(sys, 'pypy_version_info'):
|
||||
cfile = "bytecode_pypy%s/%s" % (version, short) + 'c'
|
||||
cfile = "bytecode_pypy%s%s/%s" % (version, suffix, short) + 'c'
|
||||
else:
|
||||
cfile = "bytecode_%s/%s" % (version, short) + 'c'
|
||||
cfile = "bytecode_%s%s/%s" % (version, suffix, short) + 'c'
|
||||
print("byte-compiling %s to %s" % (path, cfile))
|
||||
py_compile.compile(path, cfile)
|
||||
if isinstance(version, str) or version >= (2, 6, 0):
|
||||
|
Binary file not shown.
BIN
test/bytecode_2.6_run/01_triple_compare.pyc
Normal file
BIN
test/bytecode_2.6_run/01_triple_compare.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_2.6_run/02_ifelse_comprehension.pyc
Normal file
BIN
test/bytecode_2.6_run/02_ifelse_comprehension.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
test/bytecode_2.7_run/01_triple_compare.pyc
Normal file
BIN
test/bytecode_2.7_run/01_triple_compare.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_2.7_run/02_ifelse_comprehension.pyc
Normal file
BIN
test/bytecode_2.7_run/02_ifelse_comprehension.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_2.7_run/02_slice.pyc
Normal file
BIN
test/bytecode_2.7_run/02_slice.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
test/bytecode_3.1_run/02_ifelse_comprehension.pyc
Normal file
BIN
test/bytecode_3.1_run/02_ifelse_comprehension.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
test/bytecode_3.2_run/01_triple_compare.pyc
Normal file
BIN
test/bytecode_3.2_run/01_triple_compare.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.2_run/02_slice.pyc
Normal file
BIN
test/bytecode_3.2_run/02_slice.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
test/bytecode_3.3_run/01_triple_compare.pyc
Normal file
BIN
test/bytecode_3.3_run/01_triple_compare.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.3_run/02_ifelse_comprehension.pyc
Normal file
BIN
test/bytecode_3.3_run/02_ifelse_comprehension.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.3_run/02_slice.pyc
Normal file
BIN
test/bytecode_3.3_run/02_slice.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.3_run/10_for.pyc
Normal file
BIN
test/bytecode_3.3_run/10_for.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.3_run/10_mixed_boolean.pyc
Normal file
BIN
test/bytecode_3.3_run/10_mixed_boolean.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
test/bytecode_3.4_run/02_slice.pyc
Normal file
BIN
test/bytecode_3.4_run/02_slice.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.4_run/06_while_return.pyc
Normal file
BIN
test/bytecode_3.4_run/06_while_return.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.4_run/10_for.pyc
Normal file
BIN
test/bytecode_3.4_run/10_for.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.4_run/10_mixed_boolean.pyc
Normal file
BIN
test/bytecode_3.4_run/10_mixed_boolean.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
test/bytecode_3.5_run/02_slice.pyc
Normal file
BIN
test/bytecode_3.5_run/02_slice.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.5_run/06_while_return.pyc
Normal file
BIN
test/bytecode_3.5_run/06_while_return.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.5_run/10_for.pyc
Normal file
BIN
test/bytecode_3.5_run/10_for.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.5_run/10_mixed_boolean.pyc
Normal file
BIN
test/bytecode_3.5_run/10_mixed_boolean.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.6/02_async_for.pyc
Normal file
BIN
test/bytecode_3.6/02_async_for.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.6_run/01_triple_compare.pyc
Normal file
BIN
test/bytecode_3.6_run/01_triple_compare.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.6_run/02_ifelse_comprehension.pyc
Normal file
BIN
test/bytecode_3.6_run/02_ifelse_comprehension.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.6_run/02_pos_args.pyc
Normal file
BIN
test/bytecode_3.6_run/02_pos_args.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.6_run/02_slice.pyc
Normal file
BIN
test/bytecode_3.6_run/02_slice.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.6_run/05_try_whiletrue.pyc
Normal file
BIN
test/bytecode_3.6_run/05_try_whiletrue.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.7/02_async_for.pyc
Normal file
BIN
test/bytecode_3.7/02_async_for.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.7/04_call_function.pyc
Normal file
BIN
test/bytecode_3.7/04_call_function.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.7/04_def_annotate.pyc
Normal file
BIN
test/bytecode_3.7/04_def_annotate.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.8/01_while_if_then.pyc
Normal file
BIN
test/bytecode_3.8/01_while_if_then.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.8/02_async_for.pyc
Normal file
BIN
test/bytecode_3.8/02_async_for.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.8/02_tryfinally_return.pyc
Normal file
BIN
test/bytecode_3.8/02_tryfinally_return.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.8/02_while_and.pyc
Normal file
BIN
test/bytecode_3.8/02_while_and.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.8/03_async_await.pyc
Normal file
BIN
test/bytecode_3.8/03_async_await.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.8/03_if_try.pyc
Normal file
BIN
test/bytecode_3.8/03_if_try.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.8/04_async_stmt.pyc
Normal file
BIN
test/bytecode_3.8/04_async_stmt.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.8/04_call_function.pyc
Normal file
BIN
test/bytecode_3.8/04_call_function.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.8/04_try_finally.pyc
Normal file
BIN
test/bytecode_3.8/04_try_finally.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.8/05_return_in_else.pyc
Normal file
BIN
test/bytecode_3.8/05_return_in_else.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.8/09_yield_from.pyc
Normal file
BIN
test/bytecode_3.8/09_yield_from.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.8_run/00_chained-compare.pyc
Normal file
BIN
test/bytecode_3.8_run/00_chained-compare.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.8_run/10_for.pyc
Normal file
BIN
test/bytecode_3.8_run/10_for.pyc
Normal file
Binary file not shown.
Binary file not shown.
@@ -18,7 +18,7 @@ a *= b; print a # a = a*b = 2
|
||||
a -= a; print a # a = a-a = 0
|
||||
a += 7*3; print a # == 21
|
||||
|
||||
l= [1,2,3]
|
||||
l = [1,2,3]
|
||||
l[1] *= 3; print l[1]; # 6
|
||||
l[1][2][3] = 7
|
||||
l[1][2][3] *= 3;
|
||||
|
@@ -76,7 +76,7 @@ def get_srcdir():
|
||||
src_dir = get_srcdir()
|
||||
os.chdir(src_dir)
|
||||
|
||||
files=[
|
||||
files = [
|
||||
'if',
|
||||
'ifelse',
|
||||
# 'keyword',
|
||||
|
@@ -1,7 +1,7 @@
|
||||
# We have to do contortions here because
|
||||
# lambda's have to be more or less on a line
|
||||
|
||||
f = lambda x: 1 if x<2 else 3
|
||||
f = lambda x: 1 if x < 2 else 3
|
||||
assert f(3) == 3
|
||||
assert f(1) == 1
|
||||
|
||||
|
@@ -3,7 +3,7 @@
|
||||
# while1stmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK COME_FROM
|
||||
# while1stmt ::= SETUP_LOOP l_stmts_opt CONTINUE COME_FROM
|
||||
# which is included in later code generation
|
||||
ms=0
|
||||
if ms==1:
|
||||
ms = 0
|
||||
if ms == 1:
|
||||
while 1:
|
||||
pass
|
||||
|
@@ -1,12 +1,18 @@
|
||||
# Python 2.7 sqlalchemy-1.013/sql/crud.py
|
||||
def _extend_values_for_multiparams(compiler, stmt, c):
|
||||
c(
|
||||
[
|
||||
(
|
||||
(compiler() if compiler()
|
||||
else compiler())
|
||||
if c in stmt else compiler(),
|
||||
)
|
||||
]
|
||||
for i in enumerate(stmt)
|
||||
# Adapted from Python 2.7 sqlalchemy-1.013/sql/crud.py
|
||||
# Bug was in handling generator comprehension
|
||||
# In 2.6, 2.7 JUMP_ABSOLUTEs rather than JUMP_BACKs are generated
|
||||
|
||||
# RUNNABLE!
|
||||
def extend(stmt, a, c, c1, c2, c3):
|
||||
return c(
|
||||
([ (5 if c1 else c2)
|
||||
if a else c3
|
||||
] for i in enumerate(stmt))
|
||||
)
|
||||
|
||||
def foo(gen):
|
||||
return list(gen)
|
||||
|
||||
assert extend([0], 0, foo, True, 'c2', 'c3') == [['c3']]
|
||||
assert extend([0, 1], 1, foo, False, 'c2', 'c3') == [['c2'], ['c2']]
|
||||
assert extend([0, 1], False, foo, False, 'c2', 'c3') == [['c3'], ['c3']]
|
||||
|
@@ -1,8 +1,11 @@
|
||||
# In Python 3.3+ this uses grammar rule
|
||||
# compare_chained2 ::= expr COMPARE_OP RETURN_VALUE
|
||||
# In Python 3.6 uses this uses grammar rule
|
||||
# compare_chained2 ::= expr COMPARE_OP come_froms JUMP_FORWARD
|
||||
|
||||
# Seen in Python 3.3 ipaddress.py
|
||||
|
||||
# RUNNABLE!
|
||||
def _is_valid_netmask(netmask):
|
||||
return 0 <= netmask <= 10
|
||||
|
||||
@@ -10,4 +13,4 @@ def _is_valid_netmask(netmask):
|
||||
# detections
|
||||
|
||||
# See in 2.6.9 quopri.py ishex():
|
||||
'0' <= __file__ <= '9' or 'a' <= __file__ <= 'f' or 'A' <= __file__ <= 'F'
|
||||
assert not '0' <= __file__ <= '9' or 'a' <= __file__ <= 'f' or 'A' <= __file__ <= 'F'
|
||||
|
@@ -1,6 +1,12 @@
|
||||
# From Python 3.3.6 hmac.py
|
||||
# Problem was getting wrong placement of positional args
|
||||
# Problem was getting wrong placement of positional args.
|
||||
# In 3.6+ paramter handling changes
|
||||
|
||||
# RUNNABLE!
|
||||
|
||||
digest_cons = lambda d=b'': 5
|
||||
|
||||
# Handle single kwarg
|
||||
lambda *, d=0: None
|
||||
x = lambda *, d=0: d
|
||||
assert x(d=1) == 1
|
||||
assert x() == 0
|
||||
|
@@ -1,28 +1,32 @@
|
||||
# From Python 3.4 asynchat.py
|
||||
# Tests presence or absense of
|
||||
# SETUP_LOOP testexpr return_stmts POP_BLOCK COME_FROM_LOOP
|
||||
# Note: that there is no JUMP_BACK because of the return_stmts.
|
||||
|
||||
def initiate_send(self, num_sent, first):
|
||||
while self.producer_fifo and self.connected:
|
||||
def initiate_send(a, b, c, num_sent):
|
||||
while a and b:
|
||||
try:
|
||||
5
|
||||
except OSError:
|
||||
return
|
||||
1 / (b - 1)
|
||||
except ZeroDivisionError:
|
||||
return 1
|
||||
|
||||
if num_sent:
|
||||
if first:
|
||||
self.producer_fifo = '6'
|
||||
else:
|
||||
del self.producer_fifo[0]
|
||||
return
|
||||
c = 2
|
||||
return c
|
||||
|
||||
|
||||
# FIXME: this causes a parse error:
|
||||
# def initiate_send(self):
|
||||
# while self.producer_fifo and self.connected:
|
||||
# try:
|
||||
# 6
|
||||
# except OSError:
|
||||
# return
|
||||
def initiate_send2(a, b):
|
||||
while a and b:
|
||||
try:
|
||||
1 / (b - 1)
|
||||
except ZeroDivisionError:
|
||||
return 1
|
||||
|
||||
# return
|
||||
return 2
|
||||
|
||||
assert initiate_send(1, 1, 2, False) == 1
|
||||
assert initiate_send(1, 2, 3, False) == 3
|
||||
assert initiate_send(1, 2, 3, True) == 2
|
||||
|
||||
assert initiate_send2(1, 1) == 1
|
||||
assert initiate_send2(1, 2) == 2
|
||||
|
@@ -1,3 +1,4 @@
|
||||
# Self-checking test.
|
||||
# Python 3 bug in not detecting the end bounds of if elif.
|
||||
def testit(b):
|
||||
if b == 1:
|
||||
|
@@ -2,7 +2,7 @@
|
||||
#Not detecting 2nd return is outside of
|
||||
# if/then. Fix was to ensure COME_FROM
|
||||
def return_return_bug(foo):
|
||||
if foo =='say_hello':
|
||||
if foo == 'say_hello':
|
||||
return "hello"
|
||||
return "world"
|
||||
|
||||
|
@@ -1,4 +1,5 @@
|
||||
# Self-checking 3.6+ string interpolation tests
|
||||
# Self-checking test.
|
||||
# String interpolation tests
|
||||
|
||||
var1 = 'x'
|
||||
var2 = 'y'
|
||||
|
19
test/simple_source/bug36/05_try_whiletrue.py
Normal file
19
test/simple_source/bug36/05_try_whiletrue.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# From 3.6 _collections.abc.py
|
||||
# Bug was try/execpt parsing detection since 3.6 removes
|
||||
# a JUMP_FORWARD from earlier 3.xs.
|
||||
# This could also get confused with try/else.
|
||||
|
||||
# RUNNABLE!
|
||||
def iter(self):
|
||||
i = 0
|
||||
try:
|
||||
while True:
|
||||
v = self[i]
|
||||
yield v
|
||||
i += 1
|
||||
except IndexError:
|
||||
return
|
||||
|
||||
|
||||
A = [10, 20, 30]
|
||||
assert list(iter(A)) == A
|
@@ -1,8 +1,17 @@
|
||||
# Self-checking test.
|
||||
# Tests:
|
||||
# forstmt ::= SETUP_LOOP expr _for store
|
||||
# for_block POP_BLOCK COME_FROM
|
||||
for a in [1]:
|
||||
c = 2
|
||||
# for ::= SETUP_LOOP expr for_iter store
|
||||
# for_block POP_BLOCK COME_FROM
|
||||
# In 3.8+
|
||||
# for ::= expr for_iter store
|
||||
# for_block POP_BLOCK COME_FROM
|
||||
|
||||
for a in range(2):
|
||||
c = 2
|
||||
c = 0
|
||||
for a in [1]:
|
||||
c += a
|
||||
assert c == 1, c
|
||||
|
||||
for a in range(3):
|
||||
c += a
|
||||
|
||||
assert c == 4, c
|
||||
|
@@ -1,12 +1,26 @@
|
||||
# Self-checking test.
|
||||
# Mixed boolean expresions
|
||||
|
||||
b = True
|
||||
assert b, 'b = True'
|
||||
c = False
|
||||
assert not c, 'c = False'
|
||||
d = True
|
||||
a = b and c or d
|
||||
assert a, 'b and c or d'
|
||||
a = (b or c) and d
|
||||
assert a, '(b or c) and d'
|
||||
a = b or c or d
|
||||
assert a, 'b or c or d'
|
||||
a = b and c and d
|
||||
assert not a, 'b and c and d'
|
||||
a = b or c and d
|
||||
assert a
|
||||
a = b and (c or d)
|
||||
assert a
|
||||
a = b and c or d
|
||||
assert a
|
||||
a = (b or c and d) and b
|
||||
assert a
|
||||
a = (b or c and d or a) and b
|
||||
assert a
|
||||
|
@@ -1,8 +1,15 @@
|
||||
# Self-checking test.
|
||||
# Tests of Python slice operators
|
||||
|
||||
ary = [1,2,3,4,5]
|
||||
|
||||
# Forces BUILD_SLICE 2 on 3.x
|
||||
ary[:2]
|
||||
ary[2:]
|
||||
a = ary[:2]
|
||||
assert a == [1, 2]
|
||||
|
||||
a = ary[2:]
|
||||
assert a == [3, 4, 5]
|
||||
|
||||
# Forces BUILD_SLICE 3
|
||||
ary[1:4:2]
|
||||
a = ary[1:4:2]
|
||||
assert a == [2, 4]
|
||||
|
@@ -20,7 +20,7 @@ a *= b; # print a # a = a*b = 2
|
||||
a -= a; # print a # a = a-a = 0
|
||||
a += 7*3; # print a # == 21
|
||||
|
||||
l= [1,2,3]
|
||||
l = [1,2,3]
|
||||
l[1] *= 3; # print l[1]; # 6
|
||||
l[1][2][3] = 7
|
||||
l[1][2][3] *= 3;
|
||||
|
@@ -28,7 +28,7 @@ def foo():
|
||||
z = {}
|
||||
|
||||
def a():
|
||||
b =1
|
||||
b = 1
|
||||
global z
|
||||
del z
|
||||
def b(y):
|
||||
|
@@ -36,7 +36,7 @@ python_versions = [v for v in magics.python_versions if
|
||||
# FIXME: we should remove Python versions that we don't support.
|
||||
# These include Jython, and Python bytecode changes pre release.
|
||||
|
||||
TEST_VERSIONS=(
|
||||
TEST_VERSIONS = (
|
||||
'pypy-2.4.0', 'pypy-2.6.1',
|
||||
'pypy-5.0.1', 'pypy-5.3.1', 'pypy3.5-5.7.1-beta',
|
||||
'native') + tuple(python_versions)
|
||||
|
@@ -81,7 +81,7 @@ for vers in (2.7, 3.4, 3.5, 3.6):
|
||||
for vers in (1.3, 1.4, 1.5,
|
||||
2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7,
|
||||
3.0, 3.1, 3.2, 3.3,
|
||||
3.4, 3.5, 3.6, 3.7, 'pypy3.2', 'pypy2.7'):
|
||||
3.4, 3.5, 3.6, 3.7, 3.8, 'pypy3.2', 'pypy2.7'):
|
||||
bytecode = "bytecode_%s" % vers
|
||||
key = "bytecode-%s" % vers
|
||||
test_options[key] = (bytecode, PYC, bytecode, vers)
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
# Mode: -*- python -*-
|
||||
#
|
||||
# Copyright (c) 2015-2017 by Rocky Bernstein
|
||||
# Copyright (c) 2015-2017, 2019 by Rocky Bernstein
|
||||
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
|
||||
#
|
||||
from __future__ import print_function
|
||||
@@ -30,7 +30,8 @@ Options:
|
||||
-> /tmp/bla/fasel.pyc_dis, /tmp/bar/foo.pyc_dis
|
||||
uncompyle6 -o /tmp /usr/lib/python1.5
|
||||
-> /tmp/smtplib.pyc_dis ... /tmp/lib-tk/FixTk.pyc_dis
|
||||
-c <file> attempts a disassembly after compiling <file>
|
||||
--compile | -c <python-file>
|
||||
attempts a decompilation after compiling <python-file>
|
||||
-d print timestamps
|
||||
-p <integer> use <integer> number of processes
|
||||
-r recurse directories looking for .pyc and .pyo files
|
||||
@@ -43,10 +44,10 @@ Options:
|
||||
--help show this message
|
||||
|
||||
Debugging Options:
|
||||
--asm -a include byte-code (disables --verify)
|
||||
--grammar -g show matching grammar
|
||||
--tree -t include syntax tree (disables --verify)
|
||||
--tree++ add template rules to --tree when possible
|
||||
--asm | -a include byte-code (disables --verify)
|
||||
--grammar | -g show matching grammar
|
||||
--tree | -t include syntax tree (disables --verify)
|
||||
--tree++ add template rules to --tree when possible
|
||||
|
||||
Extensions of generated files:
|
||||
'.pyc_dis' '.pyo_dis' successfully decompiled (and verified if --verify)
|
||||
@@ -61,10 +62,7 @@ from uncompyle6.main import main, status_msg
|
||||
from uncompyle6.version import VERSION
|
||||
|
||||
def usage():
|
||||
print("""usage:
|
||||
%s [--verify | --weak-verify ] [--asm] [--tree[+]] [--grammar] [-o <path>] FILE|DIR...
|
||||
%s [--help | -h | --version | -V]
|
||||
""" % (program, program))
|
||||
print(__doc__)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
@@ -72,9 +70,9 @@ def main_bin():
|
||||
if not (sys.version_info[0:2] in ((2, 6), (2, 7), (3, 0),
|
||||
(3, 1), (3, 2), (3, 3),
|
||||
(3, 4), (3, 5), (3, 6),
|
||||
(3, 7)
|
||||
(3, 7), (3, 8)
|
||||
)):
|
||||
print('Error: %s requires Python 2.6-3.7' % program,
|
||||
print('Error: %s requires Python 2.6-3.8' % program,
|
||||
file=sys.stderr)
|
||||
sys.exit(-1)
|
||||
|
||||
@@ -82,13 +80,13 @@ def main_bin():
|
||||
numproc = 0
|
||||
outfile = '-'
|
||||
out_base = None
|
||||
codes = []
|
||||
source_paths = []
|
||||
timestamp = False
|
||||
timestampfmt = "# %Y.%m.%d %H:%M:%S %Z"
|
||||
|
||||
try:
|
||||
opts, files = getopt.getopt(sys.argv[1:], 'hagtdrVo:c:p:',
|
||||
'help asm grammar linemaps recurse '
|
||||
opts, pyc_paths = getopt.getopt(sys.argv[1:], 'hac:gtdrVo:p:',
|
||||
'help asm compile= grammar linemaps recurse '
|
||||
'timestamp tree tree+ '
|
||||
'fragments verify verify-run version '
|
||||
'weak-verify '
|
||||
@@ -130,8 +128,8 @@ def main_bin():
|
||||
outfile = val
|
||||
elif opt in ('--timestamp', '-d'):
|
||||
timestamp = True
|
||||
elif opt == '-c':
|
||||
codes.append(val)
|
||||
elif opt in ('--compile', '-c'):
|
||||
source_paths.append(val)
|
||||
elif opt == '-p':
|
||||
numproc = int(val)
|
||||
elif opt in ('--recurse', '-r'):
|
||||
@@ -143,33 +141,33 @@ def main_bin():
|
||||
# expand directory if specified
|
||||
if recurse_dirs:
|
||||
expanded_files = []
|
||||
for f in files:
|
||||
for f in pyc_paths:
|
||||
if os.path.isdir(f):
|
||||
for root, _, dir_files in os.walk(f):
|
||||
for df in dir_files:
|
||||
if df.endswith('.pyc') or df.endswith('.pyo'):
|
||||
expanded_files.append(os.path.join(root, df))
|
||||
files = expanded_files
|
||||
pyc_paths = expanded_files
|
||||
|
||||
# argl, commonprefix works on strings, not on path parts,
|
||||
# thus we must handle the case with files in 'some/classes'
|
||||
# and 'some/cmds'
|
||||
src_base = os.path.commonprefix(files)
|
||||
src_base = os.path.commonprefix(pyc_paths)
|
||||
if src_base[-1:] != os.sep:
|
||||
src_base = os.path.dirname(src_base)
|
||||
if src_base:
|
||||
sb_len = len( os.path.join(src_base, '') )
|
||||
files = [f[sb_len:] for f in files]
|
||||
pyc_paths = [f[sb_len:] for f in pyc_paths]
|
||||
|
||||
if not files:
|
||||
print("No files given", file=sys.stderr)
|
||||
if not pyc_paths and not source_paths:
|
||||
print("No input files given to decompile", file=sys.stderr)
|
||||
usage()
|
||||
|
||||
if outfile == '-':
|
||||
outfile = None # use stdout
|
||||
elif outfile and os.path.isdir(outfile):
|
||||
out_base = outfile; outfile = None
|
||||
elif outfile and len(files) > 1:
|
||||
elif outfile and len(pyc_paths) > 1:
|
||||
out_base = outfile; outfile = None
|
||||
|
||||
if timestamp:
|
||||
@@ -177,10 +175,10 @@ def main_bin():
|
||||
|
||||
if numproc <= 1:
|
||||
try:
|
||||
result = main(src_base, out_base, files, None, outfile,
|
||||
result = main(src_base, out_base, pyc_paths, source_paths, outfile,
|
||||
**options)
|
||||
result = list(result) + [options.get('do_verify', None)]
|
||||
if len(files) > 1:
|
||||
if len(pyc_paths) > 1:
|
||||
mess = status_msg(do_verify, *result)
|
||||
print('# ' + mess)
|
||||
pass
|
||||
@@ -196,8 +194,8 @@ def main_bin():
|
||||
except ImportError:
|
||||
from queue import Empty
|
||||
|
||||
fqueue = Queue(len(files)+numproc)
|
||||
for f in files:
|
||||
fqueue = Queue(len(pyc_paths)+numproc)
|
||||
for f in pyc_paths:
|
||||
fqueue.put(f)
|
||||
for i in range(numproc):
|
||||
fqueue.put(None)
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# Copyright (C) 2018 Rocky Bernstein <rocky@gnu.org>
|
||||
# Copyright (C) 2018-2019 Rocky Bernstein <rocky@gnu.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -13,7 +13,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
from __future__ import print_function
|
||||
import datetime, os, subprocess, sys, tempfile
|
||||
import datetime, py_compile, os, subprocess, sys, tempfile
|
||||
|
||||
from uncompyle6 import verify, IS_PYPY, PYTHON_VERSION
|
||||
from xdis.code import iscode
|
||||
@@ -119,6 +119,22 @@ def decompile(
|
||||
# deparsing failed
|
||||
raise pysource.SourceWalkerError(str(e))
|
||||
|
||||
def compile_file(source_path):
|
||||
if source_path.endswith('.py'):
|
||||
basename = source_path[:-3]
|
||||
else:
|
||||
basename = source_path
|
||||
|
||||
if hasattr(sys, 'pypy_version_info'):
|
||||
bytecode_path = "%s-pypy%s.pyc" % (basename, PYTHON_VERSION)
|
||||
else:
|
||||
bytecode_path = "%s-%s.pyc" % (basename, PYTHON_VERSION)
|
||||
|
||||
print("compiling %s to %s" % (source_path, bytecode_path))
|
||||
py_compile.compile(source_path, bytecode_path, 'exec')
|
||||
return bytecode_path
|
||||
|
||||
|
||||
def decompile_file(filename, outstream=None, showasm=None, showast=False,
|
||||
showgrammar=False, mapstream=None, do_fragments=False):
|
||||
"""
|
||||
@@ -150,7 +166,7 @@ def decompile_file(filename, outstream=None, showasm=None, showast=False,
|
||||
|
||||
|
||||
# FIXME: combine into an options parameter
|
||||
def main(in_base, out_base, files, codes, outfile=None,
|
||||
def main(in_base, out_base, compiled_files, source_files, outfile=None,
|
||||
showasm=None, showast=False, do_verify=False,
|
||||
showgrammar=False, raise_on_error=False,
|
||||
do_linemaps=False, do_fragments=False):
|
||||
@@ -160,8 +176,6 @@ def main(in_base, out_base, files, codes, outfile=None,
|
||||
files list of filenames to be uncompyled (relative to in_base)
|
||||
outfile write output to this filename (overwrites out_base)
|
||||
|
||||
Note: `codes` is not use. Historical compatability?
|
||||
|
||||
For redirecting output to
|
||||
- <filename> outfile=<filename> (out_base is ignored)
|
||||
- files below out_base out_base=...
|
||||
@@ -171,7 +185,10 @@ def main(in_base, out_base, files, codes, outfile=None,
|
||||
current_outfile = outfile
|
||||
linemap_stream = None
|
||||
|
||||
for filename in files:
|
||||
for source_path in source_files:
|
||||
compiled_files.append(compile_file(source_path))
|
||||
|
||||
for filename in compiled_files:
|
||||
infile = os.path.join(in_base, filename)
|
||||
# print("XXX", infile)
|
||||
if not os.path.exists(infile):
|
||||
|
@@ -747,6 +747,12 @@ def get_python_parser(
|
||||
p = parse37.Python37Parser(debug_parser)
|
||||
else:
|
||||
p = parse37.Python37ParserSingle(debug_parser)
|
||||
elif version == 3.8:
|
||||
import uncompyle6.parsers.parse38 as parse38
|
||||
if compile_mode == 'exec':
|
||||
p = parse38.Python38Parser(debug_parser)
|
||||
else:
|
||||
p = parse38.Python38ParserSingle(debug_parser)
|
||||
else:
|
||||
if compile_mode == 'exec':
|
||||
p = parse3.Python3Parser(debug_parser)
|
||||
|
@@ -467,7 +467,7 @@ class Python2Parser(PythonParser):
|
||||
pass
|
||||
self.add_unique_rules([
|
||||
('mkfunc ::= %s load_closure LOAD_CONST %s' %
|
||||
('expr '* token.attr, opname))], customize)
|
||||
('expr ' * token.attr, opname))], customize)
|
||||
|
||||
if self.version >= 2.7:
|
||||
if i > 0:
|
||||
|
@@ -267,6 +267,8 @@ class Python26Parser(Python2Parser):
|
||||
# Note: preserve positions 0 2 and 4 for semantic actions
|
||||
conditional_not ::= expr jmp_true expr jf_cf_pop expr COME_FROM
|
||||
conditional ::= expr jmp_false expr jf_cf_pop expr come_from_opt
|
||||
conditional ::= expr jmp_false expr ja_cf_pop expr
|
||||
|
||||
expr ::= conditional_not
|
||||
|
||||
and ::= expr JUMP_IF_FALSE POP_TOP expr JUMP_IF_FALSE POP_TOP
|
||||
|
@@ -41,7 +41,6 @@ class Python27Parser(Python2Parser):
|
||||
comp_body ::= set_comp_body
|
||||
comp_for ::= expr for_iter store comp_iter JUMP_BACK
|
||||
|
||||
comp_iter ::= comp_if
|
||||
comp_iter ::= comp_body
|
||||
|
||||
dict_comp_body ::= expr expr MAP_ADD
|
||||
@@ -123,6 +122,7 @@ class Python27Parser(Python2Parser):
|
||||
conditional_true ::= expr JUMP_FORWARD expr COME_FROM
|
||||
|
||||
conditional ::= expr jmp_false expr JUMP_FORWARD expr COME_FROM
|
||||
conditional ::= expr jmp_false expr JUMP_ABSOLUTE expr
|
||||
"""
|
||||
|
||||
def p_stmt27(self, args):
|
||||
|
@@ -98,8 +98,9 @@ class Python3Parser(PythonParser):
|
||||
sstmt ::= return RETURN_LAST
|
||||
|
||||
return_if_stmts ::= return_if_stmt come_from_opt
|
||||
return_if_stmts ::= _stmts return_if_stmt
|
||||
return_if_stmt ::= ret_expr RETURN_END_IF
|
||||
return_if_stmts ::= _stmts return_if_stmt _come_froms
|
||||
return_if_stmt ::= ret_expr RETURN_END_IF
|
||||
returns ::= _stmts return_if_stmt
|
||||
|
||||
stmt ::= break
|
||||
break ::= BREAK_LOOP
|
||||
@@ -874,12 +875,12 @@ class Python3Parser(PythonParser):
|
||||
j = 2
|
||||
if is_pypy or (i >= j and tokens[i-j] == 'LOAD_LAMBDA'):
|
||||
rule_pat = ('mklambda ::= %sload_closure LOAD_LAMBDA %%s%s' %
|
||||
('pos_arg '* args_pos, opname))
|
||||
('pos_arg ' * args_pos, opname))
|
||||
self.add_make_function_rule(rule_pat, opname, token.attr, customize)
|
||||
|
||||
if has_get_iter_call_function1:
|
||||
rule_pat = ("generator_exp ::= %sload_closure load_genexpr %%s%s expr "
|
||||
"GET_ITER CALL_FUNCTION_1" % ('pos_arg '* args_pos, opname))
|
||||
"GET_ITER CALL_FUNCTION_1" % ('pos_arg ' * args_pos, opname))
|
||||
self.add_make_function_rule(rule_pat, opname, token.attr, customize)
|
||||
|
||||
if has_get_iter_call_function1:
|
||||
@@ -899,7 +900,7 @@ class Python3Parser(PythonParser):
|
||||
if (is_pypy or (i >= j and tokens[i-j] == 'LOAD_DICTCOMP')):
|
||||
self.add_unique_rule('dict_comp ::= %sload_closure LOAD_DICTCOMP %s '
|
||||
'expr GET_ITER CALL_FUNCTION_1' %
|
||||
('pos_arg '* args_pos, opname),
|
||||
('pos_arg ' * args_pos, opname),
|
||||
opname, token.attr, customize)
|
||||
|
||||
if args_kw > 0:
|
||||
@@ -952,19 +953,25 @@ class Python3Parser(PythonParser):
|
||||
opname))
|
||||
self.add_unique_rule(rule, opname, token.attr, customize)
|
||||
|
||||
else:
|
||||
rule = ('mklambda ::= %sLOAD_LAMBDA LOAD_CONST %s' %
|
||||
(('expr ' * stack_count), opname))
|
||||
self.add_unique_rule(rule, opname, token.attr, customize)
|
||||
|
||||
|
||||
rule = ('mkfunc ::= %s%s%s%s' %
|
||||
('expr ' * stack_count,
|
||||
'load_closure ' * closure,
|
||||
'LOAD_CONST ' * 2,
|
||||
opname))
|
||||
('expr ' * stack_count,
|
||||
'load_closure ' * closure,
|
||||
'LOAD_CONST ' * 2,
|
||||
opname))
|
||||
self.add_unique_rule(rule, opname, token.attr, customize)
|
||||
|
||||
if has_get_iter_call_function1:
|
||||
rule_pat = ("generator_exp ::= %sload_genexpr %%s%s expr "
|
||||
"GET_ITER CALL_FUNCTION_1" % ('pos_arg '* args_pos, opname))
|
||||
"GET_ITER CALL_FUNCTION_1" % ('pos_arg ' * args_pos, opname))
|
||||
self.add_make_function_rule(rule_pat, opname, token.attr, customize)
|
||||
rule_pat = ("generator_exp ::= %sload_closure load_genexpr %%s%s expr "
|
||||
"GET_ITER CALL_FUNCTION_1" % ('pos_arg '* args_pos, opname))
|
||||
"GET_ITER CALL_FUNCTION_1" % ('pos_arg ' * args_pos, opname))
|
||||
self.add_make_function_rule(rule_pat, opname, token.attr, customize)
|
||||
if is_pypy or (i >= 2 and tokens[i-2] == 'LOAD_LISTCOMP'):
|
||||
if self.version >= 3.6:
|
||||
@@ -980,8 +987,8 @@ class Python3Parser(PythonParser):
|
||||
|
||||
if is_pypy or (i >= 2 and tokens[i-2] == 'LOAD_LAMBDA'):
|
||||
rule_pat = ('mklambda ::= %s%sLOAD_LAMBDA %%s%s' %
|
||||
(('pos_arg '* args_pos),
|
||||
('kwarg '* args_kw),
|
||||
(('pos_arg ' * args_pos),
|
||||
('kwarg ' * args_kw),
|
||||
opname))
|
||||
self.add_make_function_rule(rule_pat, opname, token.attr, customize)
|
||||
continue
|
||||
@@ -998,7 +1005,7 @@ class Python3Parser(PythonParser):
|
||||
|
||||
if has_get_iter_call_function1:
|
||||
rule_pat = ("generator_exp ::= %sload_genexpr %%s%s expr "
|
||||
"GET_ITER CALL_FUNCTION_1" % ('pos_arg '* args_pos, opname))
|
||||
"GET_ITER CALL_FUNCTION_1" % ('pos_arg ' * args_pos, opname))
|
||||
self.add_make_function_rule(rule_pat, opname, token.attr, customize)
|
||||
|
||||
if is_pypy or (i >= j and tokens[i-j] == 'LOAD_LISTCOMP'):
|
||||
@@ -1014,8 +1021,8 @@ class Python3Parser(PythonParser):
|
||||
# FIXME: Fold test into add_make_function_rule
|
||||
if is_pypy or (i >= j and tokens[i-j] == 'LOAD_LAMBDA'):
|
||||
rule_pat = ('mklambda ::= %s%sLOAD_LAMBDA %%s%s' %
|
||||
(('pos_arg '* args_pos),
|
||||
('kwarg '* args_kw),
|
||||
(('pos_arg ' * args_pos),
|
||||
('kwarg ' * args_kw),
|
||||
opname))
|
||||
self.add_make_function_rule(rule_pat, opname, token.attr, customize)
|
||||
|
||||
@@ -1148,7 +1155,9 @@ class Python3Parser(PythonParser):
|
||||
self.check_reduce['ifelsestmt'] = 'AST'
|
||||
self.check_reduce['annotate_tuple'] = 'noAST'
|
||||
self.check_reduce['kwarg'] = 'noAST'
|
||||
self.check_reduce['try_except'] = 'AST'
|
||||
if self.version < 3.6:
|
||||
# 3.6+ can remove a JUMP_FORWARD which messes up our testing here
|
||||
self.check_reduce['try_except'] = 'AST'
|
||||
|
||||
# FIXME: remove parser errors caused by the below
|
||||
# self.check_reduce['while1elsestmt'] = 'noAST'
|
||||
@@ -1190,7 +1199,9 @@ class Python3Parser(PythonParser):
|
||||
last += 1
|
||||
if last == n:
|
||||
return False
|
||||
return tokens[first].attr > tokens[last].offset
|
||||
# 3.8+ Doesn't have SETUP_LOOP
|
||||
return self.version < 3.8 and tokens[first].attr > tokens[last].offset
|
||||
|
||||
elif rule == ('try_except',
|
||||
('SETUP_EXCEPT', 'suite_stmts_opt', 'POP_BLOCK',
|
||||
'except_handler', 'opt_come_from_except')):
|
||||
|
@@ -17,15 +17,10 @@ spark grammar differences over Python 3.3 for Python 3.4
|
||||
"""
|
||||
|
||||
from uncompyle6.parser import PythonParserSingle
|
||||
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
|
||||
from uncompyle6.parsers.parse33 import Python33Parser
|
||||
|
||||
class Python34Parser(Python33Parser):
|
||||
|
||||
def __init__(self, debug_parser=PARSER_DEFAULT_DEBUG):
|
||||
super(Python34Parser, self).__init__(debug_parser)
|
||||
self.customized = {}
|
||||
|
||||
def p_misc34(self, args):
|
||||
"""
|
||||
expr ::= LOAD_ASSERT
|
||||
@@ -34,6 +29,8 @@ class Python34Parser(Python33Parser):
|
||||
# passtmt is needed for semantic actions to add "pass"
|
||||
suite_stmts_opt ::= pass
|
||||
|
||||
whilestmt ::= SETUP_LOOP testexpr returns come_froms POP_BLOCK COME_FROM_LOOP
|
||||
|
||||
# Seems to be needed starting 3.4.4 or so
|
||||
while1stmt ::= SETUP_LOOP l_stmts
|
||||
COME_FROM JUMP_BACK POP_BLOCK COME_FROM_LOOP
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user