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
42 Commits
3.9.0
...
release-py
Author | SHA1 | Date | |
---|---|---|---|
|
5566b9ba6c | ||
|
e56ab2dcd5 | ||
|
d6c45979ba | ||
|
a06e9bf32e | ||
|
7e8f7ba674 | ||
|
09eb7f7f78 | ||
|
f7a910ec66 | ||
|
6d6a73eea7 | ||
|
e4a7641927 | ||
|
b24b46d48c | ||
|
a65d7dce5b | ||
|
718a0a5d34 | ||
|
ea9e3ab3f5 | ||
|
770e988ff8 | ||
|
0fa0641974 | ||
|
c13e23cdae | ||
|
fab4ebb768 | ||
|
89429339fa | ||
|
6ed129bd7a | ||
|
c4fde6b53e | ||
|
a7d93e88b4 | ||
|
9891494142 | ||
|
f8544dfbbe | ||
|
b00651d428 | ||
|
da8dccbaca | ||
|
37272ae827 | ||
|
7f2bee46b7 | ||
|
c8a4dcf72b | ||
|
012ff91cfb | ||
|
e690ddd50a | ||
|
45b7c1948c | ||
|
e2fb7ca3d2 | ||
|
b3bda76582 | ||
|
ab6d322eca | ||
|
1a8a0df107 | ||
|
0a37709b0a | ||
|
98cd1417df | ||
|
460069ceaa | ||
|
316aa44f23 | ||
|
7133540c23 | ||
|
590231741d | ||
|
a9349b8f3d |
@@ -3,13 +3,7 @@ language: python
|
||||
sudo: false
|
||||
|
||||
python:
|
||||
- '3.5'
|
||||
- '2.7.12'
|
||||
- '2.6'
|
||||
- '3.3'
|
||||
- '3.4'
|
||||
- '3.2'
|
||||
- '3.6'
|
||||
- '2.7' # this is a cheat here because travis doesn't do 2.4-2.6
|
||||
|
||||
install:
|
||||
- pip install -r requirements.txt
|
||||
|
593
ChangeLog
593
ChangeLog
@@ -1,11 +1,415 @@
|
||||
2017-02-25 rocky <rb@dustyfeet.com>
|
||||
2017-05-06 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/version.py: Get ready for release 2.9.10
|
||||
* uncompyle6/version.py: Get ready for release 2.9.11
|
||||
|
||||
2017-05-06 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/Makefile, uncompyle6/scanners/scanner2.py,
|
||||
uncompyle6/scanners/scanner3.py, uncompyle6/semantics/fragments.py:
|
||||
Sync with master
|
||||
|
||||
2017-05-06 rocky <rb@dustyfeet.com>
|
||||
|
||||
* : commit 4a4782290490187ac2fcaaecd3ca808f933722b2 Author: rocky
|
||||
<rb@dustyfeet.com> Date: Sat May 6 05:25:56 2017 -0400
|
||||
|
||||
2017-05-05 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/parsers/parse32.py, uncompyle6/scanners/scanner3.py:
|
||||
Improve Python 3.2 decompilation ... by removing a lot of the control-flow labels of 3.3+
|
||||
|
||||
2017-05-05 rocky <rb@dustyfeet.com>
|
||||
|
||||
* .travis.yml: Try CI testing on Python 3.6
|
||||
|
||||
2017-05-02 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/simple_source/bug35/01_map_unpack.py, uncompyle6/parser.py,
|
||||
uncompyle6/parsers/parse3.py, uncompyle6/parsers/parse35.py,
|
||||
uncompyle6/semantics/pysource.py: Bang more on BUIlD_MAP_UNPACK there are still bugs. Note: {**{'x': 1}, **{'y': 2}} and {{'x': 1}, **{'y': 2}} generate the same Python 3.5+ bytecode.
|
||||
|
||||
2017-05-02 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/simple_source/bug35/01_map_unpack.py, uncompyle6/parser.py,
|
||||
uncompyle6/parsers/parse3.py, uncompyle6/parsers/parse35.py:
|
||||
BUILD_MAP_UNPACK'ing of dictionaries in 3.5
|
||||
|
||||
2017-05-01 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/semantics/pysource.py: Remove extra unpack *. Issue #98
|
||||
|
||||
2017-04-29 R. Bernstein <rocky@users.noreply.github.com>
|
||||
|
||||
* HISTORY.md: Update HISTORY.md
|
||||
|
||||
2017-04-29 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/simple_source/bug35/01_map_unpack.py,
|
||||
uncompyle6/parsers/parse35.py, uncompyle6/semantics/pysource.py:
|
||||
Handle BUILD_MAP_UNPACK in a build_list
|
||||
|
||||
2017-04-27 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/semantics/pysource.py: A hacky way to get
|
||||
CALL_FUNCTION_EX_KW to work.
|
||||
|
||||
2017-04-26 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/semantics/pysource.py: remove debug code
|
||||
|
||||
2017-04-25 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/simple_source/bug36/01_call_function.py,
|
||||
uncompyle6/parsers/parse36.py, uncompyle6/scanners/scanner36.py,
|
||||
uncompyle6/semantics/pysource.py: Python 3.6 CALL_FUNCTION_EX first
|
||||
attempt
|
||||
|
||||
2017-04-22 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/parser.py, uncompyle6/parsers/parse34.py: Reduse scope
|
||||
of LOAD_ASSERT as expr to 3.4+
|
||||
|
||||
2017-04-22 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/parser.py, uncompyle6/verify.py: LOAD_ASSERT can also
|
||||
be an expr This may have the undesirable property that assert statements might
|
||||
get tagged with equivalant low-level Python code that uses "raise
|
||||
AssertionError", but so be it. Fixes #103
|
||||
|
||||
2017-04-22 R. Bernstein <rocky@users.noreply.github.com>
|
||||
|
||||
* HISTORY.md: Update HISTORY.md
|
||||
|
||||
2017-04-22 R. Bernstein <rocky@users.noreply.github.com>
|
||||
|
||||
* HISTORY.md: Update HISTORY.md
|
||||
|
||||
2017-04-22 rocky <rb@dustyfeet.com>
|
||||
|
||||
* HISTORY.md: History keeps gettting amended
|
||||
|
||||
2017-04-22 rocky <rb@dustyfeet.com>
|
||||
|
||||
* README.rst: Document Python 3.x status
|
||||
|
||||
2017-04-22 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/simple_source/bug35/03_async_await.py,
|
||||
uncompyle6/parsers/parse35.py, uncompyle6/semantics/pysource.py: Add
|
||||
await expr Fixes #111
|
||||
|
||||
2017-04-22 rocky <rb@dustyfeet.com>
|
||||
|
||||
* : Update test
|
||||
|
||||
2017-04-22 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/simple_source/bug33/02_pos_args.py,
|
||||
uncompyle6/parsers/parse3.py, uncompyle6/semantics/make_function.py:
|
||||
3.3+ bug in handling single kwarg after * Towards fixing issue #110
|
||||
|
||||
2017-04-20 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/simple_source/bug35/02_async_for.py,
|
||||
uncompyle6/parsers/parse35.py: Add async for with pass statement Fixes #109
|
||||
|
||||
2017-04-19 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/simple_source/bug35/03_while-if-break.py,
|
||||
uncompyle6/parsers/parse3.py: 3.5 ifelsestmtl grammar bug. Fixes #108
|
||||
|
||||
2017-04-18 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/simple_source/bug35/03_async_await.py,
|
||||
uncompyle6/parsers/parse35.py: Expand await stmt handling Fixes #107
|
||||
|
||||
2017-04-18 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/simple_source/bug33/01_delete_deref.py,
|
||||
uncompyle6/parsers/parse32.py, uncompyle6/semantics/pysource.py: Add
|
||||
DELETE_DEREF grammar rule Fixes Issue #106
|
||||
|
||||
2017-04-17 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/simple_source/bug36/01_extended_arg.py,
|
||||
test/simple_source/bug36/01_if_file.py: Rename test case to
|
||||
something more appropriate
|
||||
|
||||
2017-04-17 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/simple_source/bug36/01_if_file.py: Fix botched test case Thanks to Zm908 for pointing this out
|
||||
|
||||
2017-04-16 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/parsers/parse3.py: Comment on what's up with last
|
||||
change
|
||||
|
||||
2017-04-16 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/simple_source/bug22/03_if1.py,
|
||||
test/simple_source/bug31/02_ifelse_comprehension.py,
|
||||
uncompyle6/parsers/parse3.py: Python 3.x ifelse in comprehension Fixes Issue #91
|
||||
|
||||
2017-04-16 rocky <rb@dustyfeet.com>
|
||||
|
||||
* : Add 2.7 complex test
|
||||
|
||||
2017-04-15 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/simple_source/bug35/01_map_unpack.py,
|
||||
uncompyle6/semantics/pysource.py: Correct bug in 3.5+ build_list
|
||||
with UNPACK
|
||||
|
||||
2017-04-15 R. Bernstein <rocky@users.noreply.github.com>
|
||||
|
||||
* HOW-TO-REPORT-A-BUG.md: Update HOW-TO-REPORT-A-BUG.md
|
||||
|
||||
2017-04-15 R. Bernstein <rocky@users.noreply.github.com>
|
||||
|
||||
* HOW-TO-REPORT-A-BUG.md: Update HOW-TO-REPORT-A-BUG.md
|
||||
|
||||
2017-04-15 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/simple_source/bug36/01_if_file.py,
|
||||
uncompyle6/parsers/parse36.py: 3.6 generates Wonky EXTENDED_ARG in
|
||||
expression Fixes Issue #102
|
||||
|
||||
2017-04-15 rocky <rb@dustyfeet.com>
|
||||
|
||||
* HOW-TO-REPORT-A-BUG.md, MANIFEST.in: Add how to report a bug Add test case for ... if 1 else ...
|
||||
|
||||
2017-04-14 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/simple_source/bug35/01_map_unpack.py,
|
||||
uncompyle6/parsers/parse3.py, uncompyle6/parsers/parse35.py,
|
||||
uncompyle6/semantics/pysource.py: Python 3.5+ BUILD_UNMAP_PACK rules Towards addressing Issue #98
|
||||
|
||||
2017-04-14 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/scanners/scanner3.py: Reduce adding RETURN_END_IF in
|
||||
3.5+ The whole control flow determination has to be redone in a less
|
||||
haphazard way using real flow-control analysis. Hopefully that's on
|
||||
the way. In the meantime we have this hack.
|
||||
|
||||
2017-04-14 rocky <rb@dustyfeet.com>
|
||||
|
||||
* : commit 7e8f7ba67431725fceec08344934c929a517efc5 Author: rocky
|
||||
<rb@dustyfeet.com> Date: Fri Apr 14 05:42:44 2017 -0400
|
||||
|
||||
2017-04-14 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/simple_source/bug27+/03_if_1_else.py,
|
||||
test/simple_source/bug27+/03_if_true_else.py: Better names for a
|
||||
test
|
||||
|
||||
2017-04-13 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/simple_source/bug27+/03_if_true_else.py,
|
||||
uncompyle6/parser.py, uncompyle6/parsers/parse3.py,
|
||||
uncompyle6/semantics/consts.py: Add if1else. Fixes #101
|
||||
|
||||
2017-04-13 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/parsers/parse3.py: In 3.x come_from should include
|
||||
COME_FROM_EXCEPT
|
||||
|
||||
2017-04-13 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/parsers/parse35.py: Towards fixing issue #92
|
||||
|
||||
2017-04-13 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/parsers/parse23.py, uncompyle6/semantics/pysource.py:
|
||||
Add Python 2.3 rule for "if 1: ..." Fully fixes #97 for Python 2.3. Python 2.4 was fixed in a previous
|
||||
commit.
|
||||
|
||||
2017-04-12 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/parsers/parse3.py,
|
||||
uncompyle6/semantics/make_function.py: annotate args type need to be
|
||||
expr's not constants
|
||||
|
||||
2017-04-12 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/parsers/parse24.py: Handle Python 2.4 "if 1...."
|
||||
|
||||
2017-04-11 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/simple_source/bug31/04_def_annotate.py,
|
||||
uncompyle6/semantics/fragments.py,
|
||||
uncompyle6/semantics/make_function.py: Bang on 3.x annotations
|
||||
|
||||
2017-04-11 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/simple_source/bug31/04_def_annotate.py,
|
||||
uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py:
|
||||
Towards fixing annotated decorator functions... and annotate functions
|
||||
|
||||
2017-04-10 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/parsers/parse2.py, uncompyle6/scanners/scanner27.py,
|
||||
uncompyle6/semantics/check_ast.py, uncompyle6/semantics/pysource.py:
|
||||
Misc bugs parse2.py: restore accidently-removed while1stmt rule scanner27.py:
|
||||
grammar typo check_ast: add while1else to list of looping constructs
|
||||
pysource.py: CALL_FUNCTION_VAR_KW_ARGS with positional args rule is
|
||||
different?
|
||||
|
||||
2017-04-10 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/simple_source/stmts/02_while1else.py,
|
||||
uncompyle6/parsers/parse2.py, uncompyle6/parsers/parse3.py,
|
||||
uncompyle6/parsers/parse35.py: Add more while1else grammar rules Towards addressing issue #93
|
||||
|
||||
2017-04-10 rocky <rb@dustyfeet.com>
|
||||
|
||||
* : commit b9703cf6b41138b717c282fc791c08d807692b07 Author: rocky
|
||||
<rb@dustyfeet.com> Date: Sun Apr 9 06:58:41 2017 -0400
|
||||
|
||||
2017-04-09 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/simple_source/def/10_kw+pos_args-bug.py,
|
||||
uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py:
|
||||
Another Python 3.5 FUNCTION_VAR bug Fixes #94
|
||||
|
||||
2017-04-09 rocky <rb@dustyfeet.com>
|
||||
|
||||
* : commit 4199bc7f617e387fb03fc06939cd17366dc15c5e Author: rocky
|
||||
<rb@dustyfeet.com> Date: Sun Apr 9 05:30:45 2017 -0400
|
||||
|
||||
2017-04-03 rocky <rb@dustyfeet.com>
|
||||
|
||||
* : commit 6773a66b99d07e48290a77dbbbe3c71cc39c31ba Author: rocky
|
||||
<rb@dustyfeet.com> Date: Mon Apr 3 06:53:12 2017 -0400
|
||||
|
||||
2017-03-27 rocky <rb@dustyfeet.com>
|
||||
|
||||
* : commit a91cd716670be09d3cef34e1bb36a67f96f91712 Author: rocky
|
||||
<rb@dustyfeet.com> Date: Mon Mar 27 07:08:59 2017 -0400
|
||||
|
||||
2017-03-19 rocky <rb@dustyfeet.com>
|
||||
|
||||
* __pkginfo__.py: Use more-recent xdis
|
||||
|
||||
2017-03-15 rocky <rb@dustyfeet.com>
|
||||
|
||||
* HISTORY.md, test/simple_source/bug33/01_if_try_except.py: grammar
|
||||
typo and add another test
|
||||
|
||||
2017-03-12 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/scanners/scanner3.py: Python 3.0 doesn't have
|
||||
POP_JUMP_IF...
|
||||
|
||||
2017-03-12 rocky <rb@dustyfeet.com>
|
||||
|
||||
* README.rst: Note problem in handling pathologically long lists
|
||||
|
||||
2017-03-07 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/scanners/scanner3.py: Small cleanup - remove
|
||||
POP_JUMP_TF
|
||||
|
||||
2017-03-05 rocky <rb@dustyfeet.com>
|
||||
|
||||
* pytest/test_grammar.py, uncompyle6/parsers/parse3.py,
|
||||
uncompyle6/parsers/parse33.py, uncompyle6/scanners/scanner3.py: More
|
||||
accurate ranges of try blocks in 3.x
|
||||
|
||||
2017-03-05 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/simple_source/bug33/01_try_except.py: More accurate ranges of
|
||||
try blocks in 3.x
|
||||
|
||||
2017-03-04 R. Bernstein <rocky@users.noreply.github.com>
|
||||
|
||||
* : Merge pull request #84 from
|
||||
moagstar/property_based_test_function_call Property based test function call
|
||||
|
||||
2017-03-04 rocky <rb@dustyfeet.com>
|
||||
|
||||
* README.rst: README updates for 3.5 and 1.5
|
||||
|
||||
2017-03-04 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/simple_source/bug32/01_named_and_kwargs.py,
|
||||
uncompyle6/parsers/parse3.py: Bug found by hypothesis in creating
|
||||
function calls
|
||||
|
||||
2017-03-04 Daniel Bradburn <moagstar@gmail.com>
|
||||
|
||||
* pytest/test_function_call.py: marked all function call tests as
|
||||
failing until they pass across all python versions
|
||||
|
||||
2017-03-04 Daniel Bradburn <moagstar@gmail.com>
|
||||
|
||||
* pytest/test_function_call.py: added minimal examples for various
|
||||
function call opcodes
|
||||
|
||||
2017-03-04 Daniel Bradburn <moagstar@gmail.com>
|
||||
|
||||
* pytest/test_function_call.py: added property based test for
|
||||
verifying uncompylation of function calls. A number of minimal
|
||||
examples for the various function call opcodes have been generated
|
||||
with the majority marked as expected failure until python 3.6 opcode
|
||||
support is complete. I'm hoping this will make it easier to figure
|
||||
out what needs to be done to support the new opcodes and changed
|
||||
semntics for function calls
|
||||
|
||||
2017-03-03 Daniel Bradburn <moagstar@gmail.com>
|
||||
|
||||
* pytest/test_function_call.py: reduced errors when generating
|
||||
function call instances
|
||||
|
||||
2017-03-03 Daniel Bradburn <moagstar@gmail.com>
|
||||
|
||||
* pytest/test_function_call.py: added test file for function calls
|
||||
|
||||
2017-03-03 Daniel Bradburn <moagstar@gmail.com>
|
||||
|
||||
* .gitignore: added .idea to gitignore
|
||||
|
||||
2017-03-03 Daniel Bradburn <moagstar@gmail.com>
|
||||
|
||||
* .gitignore: added .venv to gitignore
|
||||
|
||||
2017-03-01 rocky <rb@dustyfeet.com>
|
||||
|
||||
* : commit 160ec0d9cc5fe347f6e8bdb69515a28c76cfb368 Author: rocky
|
||||
<rb@dustyfeet.com> Date: Wed Mar 1 05:50:31 2017 -0500
|
||||
|
||||
2017-02-28 rocky <rb@dustyfeet.com>
|
||||
|
||||
* README.rst, uncompyle6/parser.py, uncompyle6/parsers/parse26.py:
|
||||
Python 2.6 a == b or c == d == 3 grammar bug
|
||||
|
||||
2017-02-28 rocky <rb@dustyfeet.com>
|
||||
|
||||
* : 2.6 a == b or x == y == z bug
|
||||
|
||||
2017-02-28 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/simple_source/bug26/03_double_equals.py,
|
||||
uncompyle6/semantics/consts.py: Predidence of cmp_list: x == y == z The x, y, z should not have parenthesis around pairs of them (x ==
|
||||
y) or (y == z)
|
||||
|
||||
2017-02-28 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/parser.py, uncompyle6/parsers/parse27.py: Python 2.7
|
||||
check jump targets of "and"
|
||||
|
||||
2017-02-25 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/parser.py, uncompyle6/parsers/parse26.py: Python 2.6
|
||||
parsing bugs .. and some parser list nonterminal cleanup
|
||||
* : commit 1e3ea60055027dfd3f098661ac4f5979c5c48f7e Author: rocky
|
||||
<rb@dustyfeet.com> Date: Sat Feb 25 20:18:03 2017 -0500
|
||||
|
||||
2017-02-25 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/parser.py: Python <= 2.6 grammar fixes
|
||||
|
||||
2017-02-25 rocky <rb@dustyfeet.com>
|
||||
|
||||
* : commit 2fbbc728b10f0d3a754165708584bd80d33bc7f9 Author: rocky
|
||||
<rb@dustyfeet.com> Date: Sat Feb 25 04:45:10 2017 -0500
|
||||
|
||||
2017-02-24 rocky <rb@dustyfeet.com>
|
||||
|
||||
@@ -19,9 +423,15 @@
|
||||
uncompyle6/parsers/parse25.py: Python 2.5 wasn't handling tryelse
|
||||
properly
|
||||
|
||||
2017-02-20 rocky <rb@dustyfeet.com>
|
||||
2017-02-22 rocky <rb@dustyfeet.com>
|
||||
|
||||
* : New test doesn't --verify correctly. Sigh.
|
||||
* test/Makefile, test/simple_source/bug25/02_try_else.py,
|
||||
uncompyle6/parsers/parse25.py: Python 2.5 was missing try else stmt
|
||||
|
||||
2017-02-22 rocky <rb@dustyfeet.com>
|
||||
|
||||
* : commit b043f6bafc9b9ae26e64dc0f1441d7abae894c37 Author: rocky
|
||||
<rb@dustyfeet.com> Date: Mon Feb 20 09:22:01 2017 -0500
|
||||
|
||||
2017-02-20 rocky <rb@dustyfeet.com>
|
||||
|
||||
@@ -60,6 +470,10 @@
|
||||
* test/simple_source/bug22/01_ops.py, test/test_pythonlib.py: Beef
|
||||
up grammar coverage
|
||||
|
||||
2017-02-10 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/Makefile: Group coverage Makefile targets
|
||||
|
||||
2017-01-29 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/Makefile, test/simple_source/bug22/01_ops.py,
|
||||
@@ -67,9 +481,24 @@
|
||||
uncompyle6/semantics/pysource.py: Changes based on grammar coverage
|
||||
info
|
||||
|
||||
2017-01-29 R. Bernstein <rocky@users.noreply.github.com>
|
||||
2017-01-29 rocky <rb@dustyfeet.com>
|
||||
|
||||
* : Merge pull request #83 from rocky/coverage Coverage
|
||||
* test/Makefile, test/simple_source/bug22/01_ops.py,
|
||||
uncompyle6/parsers/parse25.py, uncompyle6/semantics/consts.py,
|
||||
uncompyle6/semantics/pysource.py: Changes based on coverage
|
||||
information
|
||||
|
||||
2017-01-29 rocky <rb@dustyfeet.com>
|
||||
|
||||
* : commit 9348411056cbe809e07c4ef341effa17bca90e2f Merge: 3dc766d
|
||||
e71dd01 Author: R. Bernstein <rocky@users.noreply.github.com> Date:
|
||||
Sun Jan 29 21:54:45 2017 -0500
|
||||
|
||||
2017-01-29 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/Makefile, test/simple_source/bug22/01_ops.py,
|
||||
test/test_pyenvlib.py, test/test_pythonlib.py,
|
||||
uncompyle6/semantics/consts.py: Simplfy getting coverage consts.py: notes on versions use which ops
|
||||
|
||||
2017-01-29 rocky <rb@dustyfeet.com>
|
||||
|
||||
@@ -173,6 +602,10 @@
|
||||
* uncompyle6/__init__.py: sys.recursionlimit is optional, not
|
||||
essential
|
||||
|
||||
2017-01-11 rocky <rb@dustyfeet.com>
|
||||
|
||||
* NEWS, uncompyle6/version.py: Get ready for release 2.9.9
|
||||
|
||||
2017-01-11 rocky <rb@dustyfeet.com>
|
||||
|
||||
* : commit b131c20e99514d3a969a51e841d3a823017f1beb Author: rocky
|
||||
@@ -182,9 +615,22 @@
|
||||
|
||||
* ChangeLog, NEWS: Get ready for release 2.10.9
|
||||
|
||||
2017-01-11 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/parsers/parse3.py, uncompyle6/scanner.py,
|
||||
uncompyle6/semantics/make_function.py, uncompyle6/version.py: Merge
|
||||
changes ... * str() in Python 2.4 doesn't detect unicode. * index() doesn't work on tuples * ifelse change
|
||||
|
||||
2017-01-11 rocky <rb@dustyfeet.com>
|
||||
|
||||
* : commit 7ece296f7638e71fad1117b940f7ffddbe095b1f Merge: 78a5b62
|
||||
5035d54 Author: R. Bernstein <rocky@users.noreply.github.com> Date:
|
||||
Wed Jan 11 07:10:23 2017 -0500
|
||||
|
||||
2017-01-11 R. Bernstein <rocky@users.noreply.github.com>
|
||||
|
||||
* : Merge pull request #79 from rocky/revert-78-patch-1 Revert "fix bug : not generate all files when use "-ro""
|
||||
* uncompyle6/main.py: Revert "fix bug : not generate all files when
|
||||
use "-ro""
|
||||
|
||||
2017-01-11 R. Bernstein <rocky@users.noreply.github.com>
|
||||
|
||||
@@ -283,6 +729,16 @@
|
||||
* uncompyle6/parsers/parse35.py, uncompyle6/scanners/scanner3.py:
|
||||
Python 3.5 continue detection bug
|
||||
|
||||
2017-01-02 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/verify.py: 2.4 verify hacks
|
||||
|
||||
2017-01-02 rocky <rb@dustyfeet.com>
|
||||
|
||||
* : commit a7d93e88b4e0dfd6876a7a31bd201a0e40f24bea Merge: 9891494
|
||||
136f42a Author: rocky <rb@dustyfeet.com> Date: Mon Jan 2 05:39:13
|
||||
2017 -0500
|
||||
|
||||
2017-01-01 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/scanners/scanner3.py: add come_from for setup_finally
|
||||
@@ -297,6 +753,14 @@
|
||||
|
||||
* README.rst: Note how to verify correctness ... with --verify, --weak-verify and cross checking with pycdc
|
||||
|
||||
2016-12-31 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/version.py: We are version 2.9.9
|
||||
|
||||
2016-12-31 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/main.py: 2.7->2.4 conversion
|
||||
|
||||
2016-12-31 rocky <rb@dustyfeet.com>
|
||||
|
||||
* ChangeLog, NEWS, uncompyle6/version.py: Get ready for release
|
||||
@@ -306,6 +770,13 @@
|
||||
|
||||
* uncompyle6/parsers/parse26.py: 2.x list_if may have a THEN in it
|
||||
|
||||
2016-12-31 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/Makefile, uncompyle6/main.py, uncompyle6/parsers/parse26.py,
|
||||
uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner26.py,
|
||||
uncompyle6/scanners/scanner3.py, uncompyle6/semantics/pysource.py,
|
||||
uncompyle6/verify.py: Merge master branche Handle 2.2 list_if
|
||||
|
||||
2016-12-31 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/scanners/scanner3.py: Towards fixing a Python 3.3
|
||||
@@ -334,10 +805,9 @@
|
||||
|
||||
* : Merge pull request #73 from rocky/then-crap Add THEN token to improve Python 2.2-2.6 control flow detection
|
||||
|
||||
2016-12-28 rocky <rb@dustyfeet.com>
|
||||
2016-12-29 R. Bernstein <rocky@users.noreply.github.com>
|
||||
|
||||
* uncompyle6/parsers/parse3.py, uncompyle6/scanners/tok.py: Misc
|
||||
bugs
|
||||
* : Merge pull request #72 from rocky/master THEN psuedo-ops for Python 2.x
|
||||
|
||||
2016-12-28 rocky <rb@dustyfeet.com>
|
||||
|
||||
@@ -364,8 +834,7 @@
|
||||
|
||||
2016-12-27 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/scanners/scanner2.py: Make 2.6 and 2.7 ingest more
|
||||
alike
|
||||
* : Merge commit '9b1dd0f' into python-2.4
|
||||
|
||||
2016-12-26 rocky <rb@dustyfeet.com>
|
||||
|
||||
@@ -385,6 +854,11 @@
|
||||
* uncompyle6/parsers/parse25.py: fix bug in using python2 AST rules
|
||||
in python 2.5
|
||||
|
||||
2016-12-26 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/parsers/parse25.py: Bug in using python2 ast checking
|
||||
in python 2.5
|
||||
|
||||
2016-12-26 rocky <rb@dustyfeet.com>
|
||||
|
||||
* : commit f1a947f106b231fb1480ba301b15e3ceaf78c94f Author: rocky
|
||||
@@ -397,15 +871,19 @@
|
||||
uncompyle6/verify.py: Scanner call fixes. NAME_MODULE removal for
|
||||
<=2.4
|
||||
|
||||
2016-12-24 rocky <rb@dustyfeet.com>
|
||||
2016-12-25 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/parsers/astnode.py, uncompyle6/parsers/parse2.py,
|
||||
uncompyle6/parsers/parse26.py, uncompyle6/parsers/parse3.py,
|
||||
uncompyle6/parsers/parse36.py, uncompyle6/scanners/scanner15.py,
|
||||
uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner21.py,
|
||||
uncompyle6/scanners/scanner22.py,
|
||||
uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py:
|
||||
Lint
|
||||
* uncompyle6/main.py, uncompyle6/scanners/scanner15.py,
|
||||
uncompyle6/scanners/scanner21.py, uncompyle6/scanners/scanner22.py,
|
||||
uncompyle6/scanners/scanner23.py, uncompyle6/scanners/scanner24.py,
|
||||
uncompyle6/semantics/pysource.py, uncompyle6/verify.py: Removing
|
||||
NAME_MODULE, lint and bug fixes scanner*.py: show_asm param is optional verify.py: call correct
|
||||
scanners main.py, verify.py: Use older Python print statements
|
||||
|
||||
2016-12-25 rocky <rb@dustyfeet.com>
|
||||
|
||||
* : commit e3f4beeb74e33d5b404094765cc63040f62a0b41 Author: rocky
|
||||
<rb@dustyfeet.com> Date: Sat Dec 24 07:45:02 2016 -0500
|
||||
|
||||
2016-12-24 rocky <rb@dustyfeet.com>
|
||||
|
||||
@@ -426,22 +904,34 @@
|
||||
|
||||
2016-12-18 rocky <rb@dustyfeet.com>
|
||||
|
||||
* pytest/.gitignore, test/simple_source/bug25/02_try_else.py,
|
||||
uncompyle6/parsers/parse25.py, uncompyle6/parsers/parse26.py: Python
|
||||
2.5 mistaken try/else
|
||||
* : commit c7c0a989829a9a625333665516387c1177c611c2 Author: rocky
|
||||
<rb@dustyfeet.com> Date: Sun Dec 18 00:56:07 2016 -0500
|
||||
|
||||
2016-12-17 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner25.py:
|
||||
show-asm on python2.5 is optional make scanner2 look a little more like scanner3
|
||||
|
||||
2016-12-17 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner25.py:
|
||||
show-asm on python2.5 is optional Make scanner2 a little more like scanner3.
|
||||
|
||||
2016-12-17 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/parser.py, uncompyle6/scanner.py,
|
||||
uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner3.py,
|
||||
uncompyle6/semantics/fragments.py: Python 2.6/2.7 tolerance in
|
||||
Python 2.4 branch
|
||||
|
||||
2016-12-16 rocky <rb@dustyfeet.com>
|
||||
|
||||
* NEWS: Release 2.9.8 news
|
||||
|
||||
2016-12-16 rocky <rb@dustyfeet.com>
|
||||
|
||||
* __pkginfo__.py, uncompyle6/version.py: Get ready for release 2.9.8
|
||||
* : commit 13d5cd1a588b7f4f2c233c436ce6b0b39db9950e Author: rocky
|
||||
<rb@dustyfeet.com> Date: Fri Dec 16 22:42:46 2016 -0500
|
||||
|
||||
2016-12-16 rocky <rb@dustyfeet.com>
|
||||
|
||||
@@ -509,15 +999,12 @@
|
||||
|
||||
2016-12-04 rocky <rb@dustyfeet.com>
|
||||
|
||||
* ChangeLog, NEWS, uncompyle6/main.py, uncompyle6/parser.py,
|
||||
uncompyle6/parsers/parse26.py, uncompyle6/parsers/parse3.py,
|
||||
uncompyle6/parsers/parse34.py, uncompyle6/parsers/parse35.py,
|
||||
uncompyle6/scanner.py, uncompyle6/scanners/scanner2.py,
|
||||
uncompyle6/scanners/scanner23.py, uncompyle6/scanners/scanner24.py,
|
||||
uncompyle6/scanners/scanner3.py, uncompyle6/scanners/tok.py,
|
||||
uncompyle6/semantics/make_function.py,
|
||||
uncompyle6/semantics/pysource.py, uncompyle6/verify.py,
|
||||
uncompyle6/version.py: Get ready for release 2.9.7 Some of the many lint things. Linting is kind of stupid though.
|
||||
* ChangeLog: Get ready for release 2.9.7
|
||||
|
||||
2016-12-04 rocky <rb@dustyfeet.com>
|
||||
|
||||
* : commit d22931cb49f0e28a0fbe48a7c1526b1f170a5b52 Author: rocky
|
||||
<rb@dustyfeet.com> Date: Sun Dec 4 07:31:34 2016 -0500
|
||||
|
||||
2016-11-28 rocky <rb@dustyfeet.com>
|
||||
|
||||
@@ -568,11 +1055,34 @@
|
||||
* uncompyle6/semantics/pysource.py: Better line number tracking Indent Python 2 list comprehensions, albeit badly. DRY code a
|
||||
little via indent_if_source_nl
|
||||
|
||||
2016-11-24 rocky <rb@dustyfeet.com>
|
||||
|
||||
* circle.yml: CircleCI build
|
||||
|
||||
2016-11-24 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/parsers/parse3.py: Remove dup Python 3 grammar rule
|
||||
|
||||
2016-11-24 rocky <rb@dustyfeet.com>
|
||||
|
||||
* uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner2.py:
|
||||
<2.7 "if" detection and dup Python 3 grammar rule
|
||||
|
||||
2016-11-24 rocky <rb@dustyfeet.com>
|
||||
|
||||
* test/test_pyenvlib.py, uncompyle6/linenumbers.py,
|
||||
uncompyle6/main.py, uncompyle6/scanners/scanner2.py,
|
||||
uncompyle6/semantics/make_function.py,
|
||||
uncompyle6/semantics/pysource.py, uncompyle6/verify.py: Bug in 2.4
|
||||
"if" dectection and... Wrong language used in old-style exceptions: use "except Error,e"
|
||||
not "except Error(e)""
|
||||
|
||||
2016-11-24 rocky <rb@dustyfeet.com>
|
||||
|
||||
* __pkginfo__.py, pytest/test_grammar.py, uncompyle6/parser.py,
|
||||
uncompyle6/parsers/parse26.py: Python 2.6 grammary bug and.. __pkginfo.py__: Bump spark_parser
|
||||
version for parse_flags 'dups'
|
||||
|
||||
2016-11-23 rocky <rb@dustyfeet.com>
|
||||
|
||||
* __pkginfo__.py, pytest/test_grammar.py, uncompyle6/parser.py,
|
||||
@@ -584,8 +1094,17 @@
|
||||
|
||||
2016-11-23 rocky <rb@dustyfeet.com>
|
||||
|
||||
* : commit 6aa1531972de83ecab15b4c96b89c873ea5a7458 Author: rocky
|
||||
<rb@dustyfeet.com> Date: Wed Nov 23 00:48:38 2016 -0500
|
||||
* : commit 7133540c235e16f02d2db62cb903b70aa311de20 Author: rocky
|
||||
<rb@dustyfeet.com> Date: Wed Nov 23 08:26:12 2016 -0500
|
||||
|
||||
2016-11-23 rocky <rb@dustyfeet.com>
|
||||
|
||||
* : commit a9349b8f3d12b2aa0cd88286617c1af9cccad018 Author: rocky
|
||||
<rb@dustyfeet.com> Date: Tue Nov 22 17:49:47 2016 -0500
|
||||
|
||||
2016-11-23 rocky <rb@dustyfeet.com>
|
||||
|
||||
* circle.yml: Circle CI uses 2.7.10 and 2.7.12 is not available
|
||||
|
||||
2016-11-22 rocky <rb@dustyfeet.com>
|
||||
|
||||
|
4
Makefile
4
Makefile
@@ -37,7 +37,7 @@ check-3.0 check-3.1 check-3.2 check-3.5 check-3.6:
|
||||
$(MAKE) -C test $@
|
||||
|
||||
#:Tests for Python 2.6 (doesn't have pytest)
|
||||
check-2.6:
|
||||
check-2.4 check-2.5 check-2.6:
|
||||
$(MAKE) -C test $@
|
||||
|
||||
#:PyPy 2.6.1 or PyPy 5.0.1
|
||||
@@ -59,7 +59,7 @@ clean: clean_pyc
|
||||
|
||||
#: Create source (tarball) and wheel distribution
|
||||
dist:
|
||||
$(PYTHON) ./setup.py sdist bdist_wheel
|
||||
$(PYTHON) ./setup.py sdist bdist_egg
|
||||
|
||||
#: Remove .pyc files
|
||||
clean_pyc:
|
||||
|
6
NEWS
6
NEWS
@@ -1,3 +1,9 @@
|
||||
uncompyle6 2.9.11 2016-04-06
|
||||
|
||||
- Better support for Python 3.5+ BUILD_MAP_UNPACK
|
||||
- Start 3.6 CALL_FUNCTION_EX support
|
||||
- Many decompilation bug fixes. (Many more remain). See ChangeLog
|
||||
|
||||
uncompyle6 2.9.10 2016-02-25
|
||||
|
||||
- Python grammar rule fixes
|
||||
|
@@ -10,4 +10,4 @@ dependencies:
|
||||
- pip install -r requirements-dev.txt
|
||||
test:
|
||||
override:
|
||||
- python ./setup.py develop && make check-2.7
|
||||
- python ./setup.py develop && make check-2.6
|
||||
|
@@ -1,150 +0,0 @@
|
||||
# std
|
||||
import os
|
||||
# test
|
||||
import pytest
|
||||
import hypothesis
|
||||
from hypothesis import strategies as st
|
||||
# uncompyle6
|
||||
from uncompyle6 import PYTHON_VERSION, deparse_code
|
||||
|
||||
|
||||
@st.composite
|
||||
def expressions(draw):
|
||||
# todo : would be nice to generate expressions using hypothesis however
|
||||
# this is pretty involved so for now just use a corpus of expressions
|
||||
# from which to select.
|
||||
return draw(st.sampled_from((
|
||||
'abc',
|
||||
'len(items)',
|
||||
'x + 1',
|
||||
'lineno',
|
||||
'container',
|
||||
'self.attribute',
|
||||
'self.method()',
|
||||
# These expressions are failing, I think these are control
|
||||
# flow problems rather than problems with FORMAT_VALUE,
|
||||
# however I need to confirm this...
|
||||
#'sorted(items, key=lambda x: x.name)',
|
||||
#'func(*args, **kwargs)',
|
||||
#'text or default',
|
||||
#'43 if life_the_universe and everything else None'
|
||||
)))
|
||||
|
||||
|
||||
@st.composite
|
||||
def format_specifiers(draw):
|
||||
"""
|
||||
Generate a valid format specifier using the rules:
|
||||
|
||||
format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]
|
||||
fill ::= <any character>
|
||||
align ::= "<" | ">" | "=" | "^"
|
||||
sign ::= "+" | "-" | " "
|
||||
width ::= integer
|
||||
precision ::= integer
|
||||
type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"
|
||||
|
||||
See https://docs.python.org/2/library/string.html
|
||||
|
||||
:param draw: Let hypothesis draw from other strategies.
|
||||
|
||||
:return: An example format_specifier.
|
||||
"""
|
||||
alphabet_strategy = st.characters(min_codepoint=ord('a'), max_codepoint=ord('z'))
|
||||
fill = draw(st.one_of(alphabet_strategy, st.none()))
|
||||
align = draw(st.sampled_from(list('<>=^')))
|
||||
fill_align = (fill + align or '') if fill else ''
|
||||
|
||||
type_ = draw(st.sampled_from('bcdeEfFgGnosxX%'))
|
||||
can_have_sign = type_ in 'deEfFgGnoxX%'
|
||||
can_have_comma = type_ in 'deEfFgG%'
|
||||
can_have_precision = type_ in 'fFgG'
|
||||
can_have_pound = type_ in 'boxX%'
|
||||
can_have_zero = type_ in 'oxX'
|
||||
|
||||
sign = draw(st.sampled_from(list('+- ') + [''])) if can_have_sign else ''
|
||||
pound = draw(st.sampled_from(('#', '',))) if can_have_pound else ''
|
||||
zero = draw(st.sampled_from(('0', '',))) if can_have_zero else ''
|
||||
|
||||
int_strategy = st.integers(min_value=1, max_value=1000)
|
||||
|
||||
width = draw(st.one_of(int_strategy, st.none()))
|
||||
width = str(width) if width is not None else ''
|
||||
|
||||
comma = draw(st.sampled_from((',', '',))) if can_have_comma else ''
|
||||
if can_have_precision:
|
||||
precision = draw(st.one_of(int_strategy, st.none()))
|
||||
precision = '.' + str(precision) if precision else ''
|
||||
else:
|
||||
precision = ''
|
||||
|
||||
return ''.join((fill_align, sign, pound, zero, width, comma, precision, type_,))
|
||||
|
||||
|
||||
@st.composite
|
||||
def fstrings(draw):
|
||||
"""
|
||||
Generate a valid f-string.
|
||||
See https://www.python.org/dev/peps/pep-0498/#specification
|
||||
|
||||
:param draw: Let hypothsis draw from other strategies.
|
||||
|
||||
:return: A valid f-string.
|
||||
"""
|
||||
character_strategy = st.characters(
|
||||
blacklist_characters='\r\n\'\\s{}',
|
||||
min_codepoint=1,
|
||||
max_codepoint=1000,
|
||||
)
|
||||
is_raw = draw(st.booleans())
|
||||
integer_strategy = st.integers(min_value=0, max_value=3)
|
||||
expression_count = draw(integer_strategy)
|
||||
content = []
|
||||
for _ in range(expression_count):
|
||||
expression = draw(expressions())
|
||||
conversion = draw(st.sampled_from(('', '!s', '!r', '!a',)))
|
||||
has_specifier = draw(st.booleans())
|
||||
specifier = ':' + draw(format_specifiers()) if has_specifier else ''
|
||||
content.append('{{{}{}}}'.format(expression, conversion, specifier))
|
||||
content.append(draw(st.text(character_strategy)))
|
||||
content = ''.join(content)
|
||||
return "f{}'{}'".format('r' if is_raw else '', content)
|
||||
|
||||
|
||||
@pytest.mark.skipif(PYTHON_VERSION < 3.6, reason='need at least python 3.6')
|
||||
@hypothesis.given(format_specifiers())
|
||||
def test_format_specifiers(format_specifier):
|
||||
"""Verify that format_specifiers generates valid specifiers"""
|
||||
try:
|
||||
exec('"{:' + format_specifier + '}".format(0)')
|
||||
except ValueError as e:
|
||||
if 'Unknown format code' not in str(e):
|
||||
raise
|
||||
|
||||
|
||||
def run_test(text):
|
||||
hypothesis.assume(len(text))
|
||||
hypothesis.assume("f'{" in text)
|
||||
expr = text + '\n'
|
||||
code = compile(expr, '<string>', 'single')
|
||||
deparsed = deparse_code(PYTHON_VERSION, code, compile_mode='single')
|
||||
recompiled = compile(deparsed.text, '<string>', 'single')
|
||||
if recompiled != code:
|
||||
assert 'dis(' + deparsed.text.strip('\n') + ')' == 'dis(' + expr.strip('\n') + ')'
|
||||
|
||||
|
||||
@pytest.mark.skipif(PYTHON_VERSION < 3.6, reason='need at least python 3.6')
|
||||
@hypothesis.given(fstrings())
|
||||
def test_uncompyle_fstring(fstring):
|
||||
"""Verify uncompyling fstring bytecode"""
|
||||
run_test(fstring)
|
||||
|
||||
|
||||
@pytest.mark.skipif(PYTHON_VERSION < 3.6, reason='need at least python 3.6')
|
||||
@pytest.mark.parametrize('fstring', [
|
||||
"f'{abc}{abc!s}'",
|
||||
"f'{abc}0'",
|
||||
])
|
||||
def test_uncompyle_direct(fstring):
|
||||
"""useful for debugging"""
|
||||
run_test(fstring)
|
@@ -3,7 +3,7 @@ PHONY=check clean dist distclean test test-unit test-functional rmChangeLog clea
|
||||
GIT2CL ?= git2cl
|
||||
PYTHON ?= python
|
||||
|
||||
PYTHON_VERSION = $(shell $(PYTHON) -V | cut -d ' ' -f 2 | cut -d'.' -f1,2)
|
||||
PYTHON_VERSION = $(shell $(PYTHON) -V 2>&1 | cut -d ' ' -f 2 | cut -d'.' -f1,2)
|
||||
NATIVE_CHECK = check-$(PYTHON_VERSION)
|
||||
|
||||
# Set COMPILE='--compile' to force compilation before check
|
||||
@@ -20,7 +20,7 @@ check:
|
||||
$(MAKE) check-$$PYTHON_VERSION
|
||||
|
||||
#: Run working tests from Python 2.6 or 2.7
|
||||
check-2.6 check-2.7: check-bytecode-2 check-bytecode-3 check-bytecode-1 check-2.7-ok
|
||||
check-2.4 check-2.5 check-2.6 check-2.7: check-bytecode-2 check-bytecode-3 check-bytecode-1 check-native-short
|
||||
|
||||
#: Run working tests from Python 3.0
|
||||
check-3.0: check-bytecode
|
||||
@@ -68,7 +68,7 @@ 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-pypy3.2
|
||||
--bytecode-3.4 --bytecode-3.5 --bytecode-3.6 --bytecode-pypy3.2
|
||||
|
||||
#: Check deparsing bytecode that works running Python 2 and Python 3
|
||||
check-bytecode: check-bytecode-3
|
||||
@@ -98,29 +98,6 @@ check-bytecode-2.4:
|
||||
check-bytecode-2.5:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-2.5
|
||||
|
||||
#: Get grammar coverage for Python 2.5
|
||||
grammar-coverage-2.5:
|
||||
SPARK_PARSER_COVERAGE=/tmp/spark-grammar-25.cover $(PYTHON) test_pythonlib.py --bytecode-2.5
|
||||
SPARK_PARSER_COVERAGE=/tmp/spark-grammar-25.cover $(PYTHON) test_pyenvlib.py --2.5.6
|
||||
|
||||
#: Get grammar coverage for Python 2.6
|
||||
grammar-coverage-2.6:
|
||||
SPARK_PARSER_COVERAGE=/tmp/spark-grammar-26.cover $(PYTHON) test_pythonlib.py --bytecode-2.6
|
||||
SPARK_PARSER_COVERAGE=/tmp/spark-grammar-26.cover $(PYTHON) test_pyenvlib.py --2.6.9
|
||||
|
||||
#: Get grammar coverage for Python 2.7
|
||||
grammar-coverage-2.7:
|
||||
SPARK_PARSER_COVERAGE=/tmp/spark-grammar-27.cover $(PYTHON) test_pythonlib.py --bytecode-2.7
|
||||
SPARK_PARSER_COVERAGE=/tmp/spark-grammar-27.cover $(PYTHON) test_pyenvlib.py --2.7.13
|
||||
|
||||
#: Check deparsing Python 2.6
|
||||
check-bytecode-2.6:
|
||||
$(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 --verify
|
||||
|
||||
#: Check deparsing Python 3.0
|
||||
check-bytecode-3.0:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.0
|
||||
@@ -149,9 +126,33 @@ check-bytecode-3.5:
|
||||
check-bytecode-3.6:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.6
|
||||
|
||||
#: Get grammar coverage for Python 2.4
|
||||
grammar-coverage-2.4:
|
||||
SPARK_PARSER_COVERAGE=/tmp/spark-grammar-24.cover $(PYTHON) test_pythonlib.py --bytecode-2.4
|
||||
SPARK_PARSER_COVERAGE=/tmp/spark-grammar-24.cover $(PYTHON) test_pyenvlib.py --2.4.6
|
||||
|
||||
#: Get grammar coverage for Python 2.5
|
||||
grammar-coverage-2.5:
|
||||
SPARK_PARSER_COVERAGE=/tmp/spark-grammar-25.cover $(PYTHON) test_pythonlib.py --bytecode-2.5
|
||||
SPARK_PARSER_COVERAGE=/tmp/spark-grammar-25.cover $(PYTHON) test_pyenvlib.py --2.5.6
|
||||
|
||||
#: Get grammar coverage for Python 2.6
|
||||
grammar-coverage-2.6:
|
||||
SPARK_PARSER_COVERAGE=/tmp/spark-grammar-26.cover $(PYTHON) test_pythonlib.py --bytecode-2.6
|
||||
SPARK_PARSER_COVERAGE=/tmp/spark-grammar-26.cover $(PYTHON) test_pyenvlib.py --2.6.9
|
||||
|
||||
#: Get grammar coverage for Python 2.7
|
||||
grammar-coverage-2.7:
|
||||
SPARK_PARSER_COVERAGE=/tmp/spark-grammar-27.cover $(PYTHON) test_pythonlib.py --bytecode-2.7
|
||||
SPARK_PARSER_COVERAGE=/tmp/spark-grammar-27.cover $(PYTHON) test_pyenvlib.py --2.7.13
|
||||
|
||||
#: short tests for bytecodes only for this version of Python
|
||||
check-native-short:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-$(PYTHON_VERSION) --verify $(COMPILE)
|
||||
$(PYTHON) test_pythonlib.py --bytecode-$(PYTHON_VERSION) --weak-verify $(COMPILE)
|
||||
|
||||
#: Run longer Python 2.6's lib files known to be okay
|
||||
check-2.4-ok:
|
||||
$(PYTHON) test_pythonlib.py --ok-2.4 --verify $(COMPILE)
|
||||
|
||||
#: Run longer Python 2.6's lib files known to be okay
|
||||
check-2.6-ok:
|
||||
|
BIN
test/bytecode_2.4/01_ops.pyc
Normal file
BIN
test/bytecode_2.4/01_ops.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_2.5/01_ops.pyc
Normal file
BIN
test/bytecode_2.5/01_ops.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -19,8 +19,6 @@ Step 2: Run the test:
|
||||
test_pyenvlib --mylib --verify # decompile verify 'mylib'
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
from uncompyle6 import main, PYTHON3
|
||||
import os, time, shutil
|
||||
from fnmatch import fnmatch
|
||||
|
@@ -27,8 +27,6 @@ Step 2: Run the test:
|
||||
test_pythonlib.py --mylib --verify # decompile verify 'mylib'
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import getopt, os, py_compile, sys, shutil, tempfile, time
|
||||
|
||||
from uncompyle6 import PYTHON_VERSION
|
||||
@@ -127,8 +125,10 @@ def do_tests(src_dir, obj_patterns, target_dir, opts):
|
||||
if opts['do_compile']:
|
||||
compiled_version = opts['compiled_version']
|
||||
if compiled_version and PYTHON_VERSION != compiled_version:
|
||||
print("Not compiling: desired Python version is %s but we are running %s" %
|
||||
(compiled_version, PYTHON_VERSION), file=sys.stderr)
|
||||
sys.stderr.write("Not compiling: "
|
||||
"desired Python version is %s "
|
||||
"but we are running %s" %
|
||||
(compiled_version, PYTHON_VERSION))
|
||||
else:
|
||||
for root, dirs, basenames in os.walk(src_dir):
|
||||
file_matches(files, root, basenames, PY)
|
||||
@@ -146,8 +146,8 @@ def do_tests(src_dir, obj_patterns, target_dir, opts):
|
||||
file_matches(files, dirname, basenames, obj_patterns)
|
||||
|
||||
if not files:
|
||||
print("Didn't come up with any files to test! Try with --compile?",
|
||||
file=sys.stderr)
|
||||
sys.stderr.write("Didn't come up with any files to test! "
|
||||
"Try with --compile?")
|
||||
exit(1)
|
||||
|
||||
os.chdir(cwd)
|
||||
@@ -161,9 +161,9 @@ def do_tests(src_dir, obj_patterns, target_dir, opts):
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
print(time.ctime())
|
||||
print('Source directory: ', src_dir)
|
||||
print('Output directory: ', target_dir)
|
||||
print time.ctime()
|
||||
print 'Source directory: ', src_dir
|
||||
print 'Output directory: ', target_dir
|
||||
try:
|
||||
_, _, failed_files, failed_verify = \
|
||||
main(src_dir, target_dir, files, [],
|
||||
@@ -236,14 +236,13 @@ if __name__ == '__main__':
|
||||
if os.path.isdir(src_dir):
|
||||
checked_dirs.append([src_dir, pattern, target_dir])
|
||||
else:
|
||||
print("Can't find directory %s. Skipping" % src_dir,
|
||||
file=sys.stderr)
|
||||
sys.stderr.write("Can't find directory %s. Skipping" % src_dir)
|
||||
continue
|
||||
last_compile_version = compiled_version
|
||||
pass
|
||||
|
||||
if not checked_dirs:
|
||||
print("No directories found to check", file=sys.stderr)
|
||||
sys.stderr.write("No directories found to check\n")
|
||||
sys.exit(1)
|
||||
|
||||
test_opts['compiled_version'] = last_compile_version
|
||||
|
@@ -3,7 +3,6 @@
|
||||
#
|
||||
# Copyright (c) 2015-2016 by Rocky Bernstein <rb@dustyfeet.com>
|
||||
#
|
||||
from __future__ import print_function
|
||||
import sys, os, getopt
|
||||
|
||||
from uncompyle6.disas import disassemble_file
|
||||
@@ -26,7 +25,7 @@ Options:
|
||||
-V | --version show version and stop
|
||||
-h | --help show this message
|
||||
|
||||
""".format(program)
|
||||
""" % (program, program)
|
||||
|
||||
PATTERNS = ('*.pyc', '*.pyo')
|
||||
|
||||
@@ -37,15 +36,15 @@ Type -h for for full help.""" % program
|
||||
native = True
|
||||
|
||||
if len(sys.argv) == 1:
|
||||
print("No file(s) given", file=sys.stderr)
|
||||
print(Usage_short, file=sys.stderr)
|
||||
sys.stderr.write("No file(s) given\n")
|
||||
sys.stderr.write(Usage_short)
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
opts, files = getopt.getopt(sys.argv[1:], 'hVU',
|
||||
['help', 'version', 'uncompyle6'])
|
||||
except getopt.GetoptError as e:
|
||||
print('%s: %s' % (os.path.basename(sys.argv[0]), e), file=sys.stderr)
|
||||
except getopt.GetoptError(e):
|
||||
sys.stderr.write('%s: %s' % (os.path.basename(sys.argv[0]), e))
|
||||
sys.exit(-1)
|
||||
|
||||
for opt, val in opts:
|
||||
@@ -59,15 +58,14 @@ Type -h for for full help.""" % program
|
||||
native = False
|
||||
else:
|
||||
print(opt)
|
||||
print(Usage_short, file=sys.stderr)
|
||||
sys.stderr.write(Usage_short)
|
||||
sys.exit(1)
|
||||
|
||||
for file in files:
|
||||
if os.path.exists(files[0]):
|
||||
disassemble_file(file, sys.stdout, native)
|
||||
else:
|
||||
print("Can't read %s - skipping" % files[0],
|
||||
file=sys.stderr)
|
||||
sys.stderr.write("Can't read %s - skipping\n" % files[0])
|
||||
pass
|
||||
pass
|
||||
return
|
||||
|
@@ -4,7 +4,6 @@
|
||||
# Copyright (c) 2015-2016 by Rocky Bernstein
|
||||
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
|
||||
#
|
||||
from __future__ import print_function
|
||||
import sys, os, getopt, time
|
||||
|
||||
program, ext = os.path.splitext(os.path.basename(__file__))
|
||||
@@ -65,11 +64,11 @@ def usage():
|
||||
|
||||
|
||||
def main_bin():
|
||||
if not (sys.version_info[0:2] in ((2, 6), (2, 7),
|
||||
(3, 1), (3, 2), (3, 3),
|
||||
if not (sys.version_info[0:2] in ((2, 4), (2, 5), (2, 6), (2, 7),
|
||||
(3, 2), (3, 3),
|
||||
(3, 4), (3, 5), (3, 6))):
|
||||
print('Error: %s requires Python 2.6-2.7, or 3.1-3.6' % program,
|
||||
file=sys.stderr)
|
||||
sys.stderr.write('Error: %s requires Python 2.4 2.5 2.6, 2.7, '
|
||||
'3.2, 3.3, 3.4, 3.5, or 3.6' % program)
|
||||
sys.exit(-1)
|
||||
|
||||
do_verify = recurse_dirs = False
|
||||
@@ -84,8 +83,8 @@ def main_bin():
|
||||
opts, files = getopt.getopt(sys.argv[1:], 'hagtdrVo:c:p:',
|
||||
'help asm grammar linemaps recurse timestamp tree '
|
||||
'verify version showgrammar'.split(' '))
|
||||
except getopt.GetoptError as e:
|
||||
print('%s: %s' % (os.path.basename(sys.argv[0]), e), file=sys.stderr)
|
||||
except getopt.GetoptError(e):
|
||||
sys.stderr.write('%s: %s\n' % (os.path.basename(sys.argv[0]), e))
|
||||
sys.exit(-1)
|
||||
|
||||
options = {}
|
||||
@@ -119,7 +118,7 @@ def main_bin():
|
||||
elif opt in ('--recurse', '-r'):
|
||||
recurse_dirs = True
|
||||
else:
|
||||
print(opt, file=sys.stderr)
|
||||
sys.stderr.write(opt)
|
||||
usage()
|
||||
|
||||
# expand directory if specified
|
||||
@@ -144,7 +143,7 @@ def main_bin():
|
||||
files = [f[sb_len:] for f in files]
|
||||
|
||||
if not files:
|
||||
print("No files given", file=sys.stderr)
|
||||
sys.stderr.write("No files given\n")
|
||||
usage()
|
||||
|
||||
if outfile == '-':
|
||||
|
@@ -16,8 +16,6 @@ Second, we need structured instruction information for the
|
||||
want to run on Python 2.7.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
from collections import deque
|
||||
|
||||
@@ -37,10 +35,9 @@ def disco(version, co, out=None, is_pypy=False):
|
||||
|
||||
# store final output stream for case of error
|
||||
real_out = out or sys.stdout
|
||||
print('# Python %s' % version, file=real_out)
|
||||
real_out.write('# Python %s\n' % version)
|
||||
if co.co_filename:
|
||||
print('# Embedded file name: %s' % co.co_filename,
|
||||
file=real_out)
|
||||
real_out.write('# Embedded file name: %s\n' % co.co_filename)
|
||||
|
||||
scanner = get_scanner(version, is_pypy=is_pypy)
|
||||
|
||||
@@ -52,16 +49,15 @@ def disco_loop(disasm, queue, real_out):
|
||||
while len(queue) > 0:
|
||||
co = queue.popleft()
|
||||
if co.co_name != '<module>':
|
||||
print('\n# %s line %d of %s' %
|
||||
(co.co_name, co.co_firstlineno, co.co_filename),
|
||||
file=real_out)
|
||||
real_out.write('\n# %s line %d of %s\n' %
|
||||
(co.co_name, co.co_firstlineno, co.co_filename))
|
||||
tokens, customize = disasm(co)
|
||||
for t in tokens:
|
||||
if iscode(t.pattr):
|
||||
queue.append(t.pattr)
|
||||
elif iscode(t.attr):
|
||||
queue.append(t.attr)
|
||||
print(t, file=real_out)
|
||||
real_out.write(t)
|
||||
pass
|
||||
pass
|
||||
|
||||
|
@@ -10,7 +10,7 @@ def line_number_mapping(pyc_filename, src_filename):
|
||||
source_size) = load_module(pyc_filename)
|
||||
try:
|
||||
code2 = load_file(src_filename)
|
||||
except SyntaxError as e:
|
||||
except SyntaxError, e:
|
||||
return str(e)
|
||||
|
||||
queue = deque([code1, code2])
|
||||
|
@@ -1,4 +1,3 @@
|
||||
from __future__ import print_function
|
||||
import datetime, os, subprocess, sys, tempfile
|
||||
|
||||
from uncompyle6 import verify, IS_PYPY
|
||||
@@ -22,31 +21,36 @@ def decompile(
|
||||
|
||||
# store final output stream for case of error
|
||||
real_out = out or sys.stdout
|
||||
co_pypy_str = 'PyPy ' if is_pypy else ''
|
||||
run_pypy_str = 'PyPy ' if IS_PYPY else ''
|
||||
print('# uncompyle6 version %s\n'
|
||||
'# %sPython bytecode %s%s\n# Decompiled from: %sPython %s' %
|
||||
(VERSION, co_pypy_str, bytecode_version,
|
||||
" (%d)" % magic_int if magic_int else "",
|
||||
run_pypy_str, '\n# '.join(sys.version.split('\n'))),
|
||||
file=real_out)
|
||||
if co.co_filename:
|
||||
print('# Embedded file name: %s' % co.co_filename,
|
||||
file=real_out)
|
||||
if timestamp:
|
||||
print('# Compiled at: %s' % datetime.datetime.fromtimestamp(timestamp),
|
||||
file=real_out)
|
||||
if source_size:
|
||||
print('# Size of source mod 2**32: %d bytes' % source_size,
|
||||
file=real_out)
|
||||
if is_pypy:
|
||||
co_pypy_str = 'PyPy '
|
||||
else:
|
||||
co_pypy_str = ''
|
||||
|
||||
try:
|
||||
pysource.deparse_code(bytecode_version, co, out, showasm, showast,
|
||||
showgrammar, code_objects=code_objects,
|
||||
is_pypy=is_pypy)
|
||||
except pysource.SourceWalkerError as e:
|
||||
# deparsing failed
|
||||
raise pysource.SourceWalkerError(str(e))
|
||||
if IS_PYPY:
|
||||
run_pypy_str = 'PyPy '
|
||||
else:
|
||||
run_pypy_str = ''
|
||||
|
||||
if magic_int:
|
||||
m = str(magic_int)
|
||||
else:
|
||||
m = ""
|
||||
real_out.write('# uncompyle6 version %s\n'
|
||||
'# %sPython bytecode %s%s\n# Decompiled from: %sPython %s\n' %
|
||||
(VERSION, co_pypy_str, bytecode_version,
|
||||
" (%s)" % m, run_pypy_str,
|
||||
'\n# '.join(sys.version.split('\n'))))
|
||||
if co.co_filename:
|
||||
real_out.write('# Embedded file name: %s\n' % co.co_filename)
|
||||
if timestamp:
|
||||
real_out.write('# Compiled at: %s\n' %
|
||||
datetime.datetime.fromtimestamp(timestamp))
|
||||
if source_size:
|
||||
real_out.write('# Size of source mod 2**32: %d bytes\n' % source_size)
|
||||
|
||||
pysource.deparse_code(bytecode_version, co, out, showasm, showast,
|
||||
showgrammar, code_objects=code_objects,
|
||||
is_pypy=is_pypy)
|
||||
|
||||
# For compatiblity
|
||||
uncompyle = decompile
|
||||
@@ -127,7 +131,10 @@ def main(in_base, out_base, files, codes, outfile=None,
|
||||
junk, outfile = tempfile.mkstemp(suffix=".py",
|
||||
prefix=prefix)
|
||||
# Unbuffer output if possible
|
||||
buffering = -1 if sys.stdout.isatty() else 0
|
||||
if sys.stdout.isatty():
|
||||
buffering = -1
|
||||
else:
|
||||
buffering = 0
|
||||
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', buffering)
|
||||
tee = subprocess.Popen(["tee", outfile], stdin=subprocess.PIPE)
|
||||
os.dup2(tee.stdin.fileno(), sys.stdout.fileno())
|
||||
@@ -144,9 +151,9 @@ def main(in_base, out_base, files, codes, outfile=None,
|
||||
try:
|
||||
decompile_file(infile, outstream, showasm, showast, showgrammar)
|
||||
tot_files += 1
|
||||
except (ValueError, SyntaxError, ParserError, pysource.SourceWalkerError) as e:
|
||||
except (ValueError, SyntaxError, ParserError, pysource.SourceWalkerError):
|
||||
sys.stdout.write("\n")
|
||||
sys.stderr.write("\n# file %s\n# %s\n" % (infile, e))
|
||||
sys.stderr.write("# file %s\n" % (infile))
|
||||
failed_files += 1
|
||||
except KeyboardInterrupt:
|
||||
if outfile:
|
||||
@@ -180,31 +187,35 @@ def main(in_base, out_base, files, codes, outfile=None,
|
||||
msg = verify.compare_code_with_srcfile(infile, outfile, weak_verify=weak_verify)
|
||||
if not outfile:
|
||||
if not msg:
|
||||
print('\n# okay decompiling %s' % infile)
|
||||
print '\n# okay decompiling %s' % infile
|
||||
okay_files += 1
|
||||
else:
|
||||
print('\n# %s\n\t%s', infile, msg)
|
||||
except verify.VerifyCmpError as e:
|
||||
print '\n# %s\n\t%s', infile, msg
|
||||
except verify.VerifyCmpError, e:
|
||||
print(e)
|
||||
verify_failed_files += 1
|
||||
os.rename(outfile, outfile + '_unverified')
|
||||
sys.stderr.write("### Error Verifying %s\n" % filename)
|
||||
sys.stderr.write(str(e) + "\n")
|
||||
if not outfile:
|
||||
sys.stder.write("### Error Verifiying %s" %
|
||||
filename)
|
||||
sys.stderr.write(e)
|
||||
if raise_on_error:
|
||||
raise
|
||||
pass
|
||||
pass
|
||||
pass
|
||||
elif do_verify:
|
||||
sys.stderr.write("\n### uncompile successful, but no file to compare against\n")
|
||||
sys.stderr.write("\n### uncompile successful, "
|
||||
"but no file to compare against")
|
||||
pass
|
||||
else:
|
||||
okay_files += 1
|
||||
if not outfile:
|
||||
mess = '\n# okay decompiling'
|
||||
# mem_usage = __memUsage()
|
||||
print(mess, infile)
|
||||
print mess, infile
|
||||
if outfile:
|
||||
sys.stdout.write("%s\r" %
|
||||
status_msg(do_verify, tot_files, okay_files, failed_files, verify_failed_files))
|
||||
|
@@ -6,8 +6,6 @@
|
||||
Common uncompyle parser routines.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
|
||||
from xdis.code import iscode
|
||||
@@ -30,13 +28,13 @@ class PythonParser(GenericASTBuilder):
|
||||
|
||||
def __init__(self, AST, start, debug):
|
||||
super(PythonParser, self).__init__(AST, start, debug)
|
||||
self.collect = frozenset(
|
||||
['stmts', 'except_stmts', '_stmts', 'load_attrs',
|
||||
'exprlist', 'kvlist', 'kwargs', 'come_froms', '_come_from',
|
||||
# Python < 3
|
||||
'print_items',
|
||||
# PyPy:
|
||||
'kvlist_n'])
|
||||
self.collect = [
|
||||
'stmts', 'except_stmts', '_stmts', 'load_attrs',
|
||||
'exprlist', 'kvlist', 'kwargs', 'come_froms', '_come_from',
|
||||
# Python < 3
|
||||
'print_items',
|
||||
# PyPy:
|
||||
'kvlist_n']
|
||||
|
||||
def ast_first_offset(self, ast):
|
||||
if hasattr(ast, 'offset'):
|
||||
@@ -92,7 +90,10 @@ class PythonParser(GenericASTBuilder):
|
||||
def fix(c):
|
||||
s = str(c)
|
||||
i = s.find('_')
|
||||
return s if i == -1 else s[:i]
|
||||
if i == -1:
|
||||
return s
|
||||
else:
|
||||
return s[:i]
|
||||
|
||||
prefix = ''
|
||||
if parent and tokens:
|
||||
@@ -123,7 +124,10 @@ class PythonParser(GenericASTBuilder):
|
||||
err_token = instructions[index]
|
||||
print("Instruction context:")
|
||||
for i in range(start, finish):
|
||||
indent = ' ' if i != index else '-> '
|
||||
if i != index:
|
||||
indent = ' '
|
||||
else:
|
||||
indent = '-> '
|
||||
print("%s%s" % (indent, instructions[i]))
|
||||
raise ParserError(err_token, err_token.offset)
|
||||
|
||||
|
@@ -12,8 +12,6 @@ If we succeed in creating a parse tree, then we have a Python program
|
||||
that a later phase can turn into a sequence of ASCII text.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
from uncompyle6.parser import PythonParser, PythonParserSingle, nop_func
|
||||
from uncompyle6.parsers.astnode import AST
|
||||
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
|
||||
|
@@ -15,8 +15,6 @@ If we succeed in creating a parse tree, then we have a Python program
|
||||
that a later phase can turn into a sequence of ASCII text.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
from uncompyle6.parser import PythonParser, PythonParserSingle, nop_func
|
||||
from uncompyle6.parsers.astnode import AST
|
||||
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
|
||||
@@ -527,7 +525,10 @@ class Python3Parser(PythonParser):
|
||||
"""Python 3.3 added a an addtional LOAD_CONST before MAKE_FUNCTION and
|
||||
this has an effect on many rules.
|
||||
"""
|
||||
new_rule = rule % (('LOAD_CONST ') * (1 if self.version >= 3.3 else 0))
|
||||
if self.version >= 3.3:
|
||||
new_rule = rule % (('LOAD_CONST ') * 1)
|
||||
else:
|
||||
new_rule = rule % (('LOAD_CONST ') * 0)
|
||||
self.add_unique_rule(new_rule, opname, attr, customize)
|
||||
|
||||
def add_custom_rules(self, tokens, customize):
|
||||
@@ -819,7 +820,8 @@ class Python3Parser(PythonParser):
|
||||
elif lhs == 'annotate_tuple':
|
||||
return not isinstance(tokens[first].attr, tuple)
|
||||
elif lhs == 'kwarg':
|
||||
return not isinstance(tokens[first].attr, str)
|
||||
return not (isinstance(tokens[first].attr, unicode) or
|
||||
isinstance(tokens[first].attr, str))
|
||||
elif lhs == 'while1elsestmt':
|
||||
# if SETUP_LOOP target spans the else part, then this is
|
||||
# not while1else. Also do for whileTrue?
|
||||
|
@@ -2,7 +2,6 @@
|
||||
"""
|
||||
spark grammar differences over Python 3.1 for Python 3.0.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
from uncompyle6.parser import PythonParserSingle
|
||||
from uncompyle6.parsers.parse31 import Python31Parser
|
||||
|
@@ -2,7 +2,6 @@
|
||||
"""
|
||||
spark grammar differences over Python 3.2 for Python 3.1.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
from uncompyle6.parser import PythonParserSingle
|
||||
from uncompyle6.parsers.parse32 import Python32Parser
|
||||
|
@@ -2,8 +2,6 @@
|
||||
"""
|
||||
spark grammar differences over Python 3 for Python 3.2.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
from uncompyle6.parser import PythonParserSingle
|
||||
from uncompyle6.parsers.parse3 import Python3Parser
|
||||
|
||||
|
@@ -2,7 +2,6 @@
|
||||
"""
|
||||
spark grammar differences over Python 3.2 for Python 3.3.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
from uncompyle6.parser import PythonParserSingle
|
||||
from uncompyle6.parsers.parse32 import Python32Parser
|
||||
|
@@ -2,7 +2,6 @@
|
||||
"""
|
||||
spark grammar differences over Python 3.4 for Python 3.5.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
from uncompyle6.parser import PythonParserSingle
|
||||
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
|
||||
|
@@ -2,7 +2,6 @@
|
||||
"""
|
||||
spark grammar differences over Python 3.5 for Python 3.6.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
from uncompyle6.parser import PythonParserSingle
|
||||
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
|
||||
|
@@ -10,8 +10,6 @@ scanner/ingestion module. From here we call various version-specific
|
||||
scanners, e.g. for Python 2.7 or 3.4.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
|
||||
from uncompyle6 import PYTHON3, IS_PYPY
|
||||
@@ -232,9 +230,15 @@ class Scanner(object):
|
||||
for given opcode <op>.
|
||||
"""
|
||||
if op < self.opc.HAVE_ARGUMENT:
|
||||
return 2 if self.version >= 3.6 else 1
|
||||
if self.version >= 3.6:
|
||||
return 2
|
||||
else:
|
||||
return 1
|
||||
else:
|
||||
return 2 if self.version >= 3.6 else 3
|
||||
if self.version >= 3.6:
|
||||
return 2
|
||||
else:
|
||||
return 3
|
||||
|
||||
def remove_mid_line_ifs(self, ifs):
|
||||
"""
|
||||
|
@@ -13,13 +13,13 @@ import uncompyle6.scanners.scanner21 as scan
|
||||
from xdis.opcodes import opcode_15
|
||||
JUMP_OPs = opcode_15.JUMP_OPs
|
||||
|
||||
# We base this off of 2.2 instead of the other way around
|
||||
# We base this off of 2.1 instead of the other way around
|
||||
# because we cleaned things up this way.
|
||||
# The history is that 2.7 support is the cleanest,
|
||||
# then from that we got 2.6 and so on.
|
||||
class Scanner15(scan.Scanner21):
|
||||
def __init__(self, show_asm=False):
|
||||
scan.Scanner21.__init__(self, show_asm)
|
||||
scan.Scanner21.__init__(self, show_asm=False)
|
||||
self.opc = opcode_15
|
||||
self.opname = opcode_15.opname
|
||||
self.version = 1.5
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2015, 2016 by Rocky Bernstein
|
||||
# Copyright (c) 2015-2017 by Rocky Bernstein
|
||||
# Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org>
|
||||
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
|
||||
"""
|
||||
@@ -20,9 +20,13 @@ For example:
|
||||
Finally we save token information.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
from uncompyle6 import PYTHON_VERSION
|
||||
|
||||
if PYTHON_VERSION < 2.6:
|
||||
from xdis.namedtuple25 import namedtuple
|
||||
else:
|
||||
from collections import namedtuple
|
||||
|
||||
from collections import namedtuple
|
||||
from array import array
|
||||
|
||||
from uncompyle6.scanner import op_has_argument
|
||||
@@ -84,7 +88,9 @@ class Scanner2(scan.Scanner):
|
||||
cause specific rules for the specific number of arguments they take.
|
||||
"""
|
||||
|
||||
show_asm = self.show_asm if not show_asm else show_asm
|
||||
if not show_asm:
|
||||
show_asm = self.show_asm
|
||||
|
||||
# show_asm = 'after'
|
||||
if show_asm in ('both', 'before'):
|
||||
from xdis.bytecode import Bytecode
|
||||
@@ -1023,8 +1029,10 @@ class Scanner2(scan.Scanner):
|
||||
|
||||
# FIXME: rocky: I think we need something like this...
|
||||
if offset not in set(self.ignore_if) or self.version == 2.7:
|
||||
source = (self.setup_loops[label]
|
||||
if label in self.setup_loops else offset)
|
||||
if label in self.setup_loops:
|
||||
source = self.setup_loops[label]
|
||||
else:
|
||||
source = offset
|
||||
targets[label] = targets.get(label, []) + [source]
|
||||
pass
|
||||
|
||||
|
@@ -19,7 +19,7 @@ JUMP_OPs = opcode_21.JUMP_OPs
|
||||
# then from that we got 2.6 and so on.
|
||||
class Scanner21(scan.Scanner22):
|
||||
def __init__(self, show_asm=False):
|
||||
scan.Scanner22.__init__(self, show_asm)
|
||||
scan.Scanner22.__init__(self, show_asm=False)
|
||||
self.opc = opcode_21
|
||||
self.opname = opcode_21.opname
|
||||
self.version = 2.1
|
||||
|
@@ -19,7 +19,7 @@ JUMP_OPs = opcode_22.JUMP_OPs
|
||||
# then from that we got 2.6 and so on.
|
||||
class Scanner22(scan.Scanner23):
|
||||
def __init__(self, show_asm=False):
|
||||
scan.Scanner23.__init__(self, show_asm)
|
||||
scan.Scanner23.__init__(self, show_asm=False)
|
||||
self.opc = opcode_22
|
||||
self.opname = opcode_22.opname
|
||||
self.version = 2.2
|
||||
|
@@ -86,7 +86,9 @@ class Scanner26(scan.Scanner2):
|
||||
cause specific rules for the specific number of arguments they take.
|
||||
"""
|
||||
|
||||
show_asm = self.show_asm if not show_asm else show_asm
|
||||
if not show_asm:
|
||||
show_asm = self.show_asm
|
||||
|
||||
# show_asm = 'after'
|
||||
if show_asm in ('both', 'before'):
|
||||
from xdis.bytecode import Bytecode
|
||||
|
@@ -7,8 +7,6 @@ grammar parsing.
|
||||
"""
|
||||
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
from uncompyle6.scanners.scanner2 import Scanner2
|
||||
|
||||
from uncompyle6 import PYTHON3
|
||||
|
@@ -20,9 +20,13 @@ For example:
|
||||
Finally we save token information.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
from uncompyle6 import PYTHON_VERSION
|
||||
|
||||
if PYTHON_VERSION < 2.6:
|
||||
from xdis.namedtuple25 import namedtuple
|
||||
else:
|
||||
from collections import namedtuple
|
||||
|
||||
from collections import namedtuple
|
||||
from array import array
|
||||
|
||||
from uncompyle6.scanner import Scanner, op_has_argument
|
||||
@@ -151,8 +155,10 @@ class Scanner3(Scanner):
|
||||
cause specific rules for the specific number of arguments they take.
|
||||
"""
|
||||
|
||||
show_asm = self.show_asm if not show_asm else show_asm
|
||||
# show_asm = 'both'
|
||||
if not show_asm:
|
||||
show_asm = self.show_asm
|
||||
|
||||
# show_asm = 'after'
|
||||
if show_asm in ('both', 'before'):
|
||||
bytecode = Bytecode(co, self.opc)
|
||||
for instr in bytecode.get_instructions(co):
|
||||
|
@@ -6,8 +6,6 @@ This sets up opcodes Python's 3.0 and calls a generalized
|
||||
scanner routine for Python 3.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
# bytecode verification, verify(), uses JUMP_OPs from here
|
||||
from xdis.opcodes import opcode_30 as opc
|
||||
JUMP_OPs = map(lambda op: opc.opname[op], opc.hasjrel + opc.hasjabs)
|
||||
|
@@ -6,8 +6,6 @@ This sets up opcodes Python's 3.1 and calls a generalized
|
||||
scanner routine for Python 3.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
# bytecode verification, verify(), uses JUMP_OPs from here
|
||||
from xdis.opcodes import opcode_31 as opc
|
||||
JUMP_OPs = map(lambda op: opc.opname[op], opc.hasjrel + opc.hasjabs)
|
||||
|
@@ -6,8 +6,6 @@ This sets up opcodes Python's 3.2 and calls a generalized
|
||||
scanner routine for Python 3.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
# bytecode verification, verify(), uses JUMP_OPs from here
|
||||
from xdis.opcodes import opcode_32 as opc
|
||||
JUMP_OPs = map(lambda op: opc.opname[op], opc.hasjrel + opc.hasjabs)
|
||||
|
@@ -6,8 +6,6 @@ This sets up opcodes Python's 3.3 and calls a generalized
|
||||
scanner routine for Python 3.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
# bytecode verification, verify(), uses JUMP_OPs from here
|
||||
from xdis.opcodes import opcode_33 as opc
|
||||
JUMP_OPs = map(lambda op: opc.opname[op], opc.hasjrel + opc.hasjabs)
|
||||
|
@@ -6,8 +6,6 @@ This sets up opcodes Python's 3.4 and calls a generalized
|
||||
scanner routine for Python 3.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
from xdis.opcodes import opcode_34 as opc
|
||||
|
||||
# bytecode verification, verify(), uses JUMP_OPs from here
|
||||
|
@@ -6,8 +6,6 @@ This sets up opcodes Python's 3.5 and calls a generalized
|
||||
scanner routine for Python 3.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
from uncompyle6.scanners.scanner3 import Scanner3
|
||||
|
||||
# bytecode verification, verify(), uses JUMP_OPs from here
|
||||
|
@@ -6,8 +6,6 @@ This sets up opcodes Python's 3.6 and calls a generalized
|
||||
scanner routine for Python 3.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
from uncompyle6.scanners.scanner3 import Scanner3
|
||||
|
||||
# bytecode verification, verify(), uses JUMP_OPs from here
|
||||
|
@@ -56,12 +56,18 @@ class Token:
|
||||
return self.format(line_prefix='')
|
||||
|
||||
def format(self, line_prefix=''):
|
||||
prefix = ('\n%s%4d ' % (line_prefix, self.linestart)
|
||||
if self.linestart else (' ' * (6 + len(line_prefix))))
|
||||
if self.linestart:
|
||||
prefix = '\n%s%4d ' % (line_prefix, self.linestart)
|
||||
else:
|
||||
prefix = ' ' * (6 + len(line_prefix))
|
||||
offset_opname = '%6s %-17s' % (self.offset, self.type)
|
||||
if not self.has_arg:
|
||||
return "%s%s" % (prefix, offset_opname)
|
||||
argstr = "%6d " % self.attr if isinstance(self.attr, int) else (' '*7)
|
||||
|
||||
if isinstance(self.attr, int):
|
||||
argstr = "%6d " % self.attr
|
||||
else:
|
||||
argstr = ' '*7
|
||||
if self.pattr:
|
||||
pattr = self.pattr
|
||||
if self.opc:
|
||||
|
@@ -51,11 +51,9 @@ The node position 0 will be associated with "import".
|
||||
|
||||
# FIXME: DRY code with pysource
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import re, sys
|
||||
|
||||
from uncompyle6 import PYTHON3, IS_PYPY
|
||||
from uncompyle6 import PYTHON3, IS_PYPY, PYTHON_VERSION
|
||||
from xdis.code import iscode
|
||||
from uncompyle6.semantics import pysource
|
||||
from uncompyle6 import parser
|
||||
@@ -83,15 +81,13 @@ from uncompyle6.semantics.make_function import (
|
||||
find_all_globals, find_none, code_has_star_arg, code_has_star_star_arg
|
||||
)
|
||||
|
||||
if PYTHON3:
|
||||
from itertools import zip_longest
|
||||
else:
|
||||
from itertools import izip_longest as zip_longest
|
||||
|
||||
|
||||
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
|
||||
|
||||
from collections import namedtuple
|
||||
if PYTHON_VERSION < 2.6:
|
||||
from xdis.namedtuple25 import namedtuple
|
||||
else:
|
||||
from collections import namedtuple
|
||||
|
||||
NodeInfo = namedtuple("NodeInfo", "node start finish")
|
||||
ExtractInfo = namedtuple("ExtractInfo",
|
||||
"lineNo lineStartOffset markerLine selectedLine selectedText")
|
||||
@@ -743,7 +739,10 @@ class FragmentsWalker(pysource.SourceWalker, object):
|
||||
def n_genexpr(self, node):
|
||||
start = len(self.f.getvalue())
|
||||
self.write('(')
|
||||
code_index = -6 if self.version > 3.2 else -5
|
||||
if self.version > 3.2:
|
||||
code_index = -6
|
||||
else:
|
||||
code_index = -5
|
||||
self.comprehension_walk(node, iter_index=3, code_index=code_index)
|
||||
self.write(')')
|
||||
self.set_pos_info(node, start, len(self.f.getvalue()))
|
||||
@@ -897,7 +896,10 @@ class FragmentsWalker(pysource.SourceWalker, object):
|
||||
subclass = n.attr
|
||||
break
|
||||
pass
|
||||
subclass_info = node if node == 'classdefdeco2' else node[0]
|
||||
if node == 'classdefdeco2':
|
||||
subclass_info = node
|
||||
else:
|
||||
subclass_info = node[0]
|
||||
elif buildclass[1][0] == 'load_closure':
|
||||
# Python 3 with closures not functions
|
||||
load_closure = buildclass[1]
|
||||
@@ -921,7 +923,10 @@ class FragmentsWalker(pysource.SourceWalker, object):
|
||||
subclass = buildclass[1][0].attr
|
||||
subclass_info = node[0]
|
||||
else:
|
||||
buildclass = node if (node == 'classdefdeco2') else node[0]
|
||||
if node == 'classdefdeco2':
|
||||
buildclass = node
|
||||
else:
|
||||
buildclass = node[0]
|
||||
build_list = buildclass[1][0]
|
||||
if hasattr(buildclass[-3][0], 'attr'):
|
||||
subclass = buildclass[-3][0].attr
|
||||
@@ -987,7 +992,9 @@ class FragmentsWalker(pysource.SourceWalker, object):
|
||||
tokens.append(Token('LAMBDA_MARKER'))
|
||||
try:
|
||||
ast = parser.parse(self.p, tokens, customize)
|
||||
except (parser.ParserError, AssertionError) as e:
|
||||
except parser.ParserError(e):
|
||||
raise ParserError(e, tokens)
|
||||
except AssertionError(e):
|
||||
raise ParserError(e, tokens)
|
||||
maybe_show_ast(self.showast, ast)
|
||||
return ast
|
||||
@@ -1012,7 +1019,9 @@ class FragmentsWalker(pysource.SourceWalker, object):
|
||||
# Build AST from disassembly.
|
||||
try:
|
||||
ast = parser.parse(self.p, tokens, customize)
|
||||
except (parser.ParserError, AssertionError) as e:
|
||||
except parser.ParserError(e):
|
||||
raise ParserError(e, tokens)
|
||||
except AssertionError(e):
|
||||
raise ParserError(e, tokens)
|
||||
|
||||
maybe_show_ast(self.showast, ast)
|
||||
@@ -1649,16 +1658,16 @@ class FragmentsWalker(pysource.SourceWalker, object):
|
||||
code._customize,
|
||||
isLambda = isLambda,
|
||||
noneInNames = ('None' in code.co_names))
|
||||
except ParserError as p:
|
||||
except ParserError(p):
|
||||
self.write(str(p))
|
||||
self.ERROR = p
|
||||
return
|
||||
|
||||
# build parameters
|
||||
|
||||
tup = [paramnames, defparams]
|
||||
params = [build_param(ast, name, default) for
|
||||
name, default in zip_longest(paramnames, defparams, fillvalue=None)]
|
||||
|
||||
name, default in map(lambda *tup:tup, *tup)]
|
||||
params.reverse() # back to correct order
|
||||
|
||||
if code_has_star_arg(code):
|
||||
|
@@ -6,14 +6,9 @@ All the crazy things we have to do to handle Python functions
|
||||
from xdis.code import iscode
|
||||
from uncompyle6.scanner import Code
|
||||
from uncompyle6.parsers.astnode import AST
|
||||
from uncompyle6 import PYTHON3
|
||||
from uncompyle6.semantics.parser_error import ParserError
|
||||
from uncompyle6.semantics.helper import print_docstring
|
||||
|
||||
if PYTHON3:
|
||||
from itertools import zip_longest
|
||||
else:
|
||||
from itertools import izip_longest as zip_longest
|
||||
|
||||
from uncompyle6.show import maybe_show_ast_param_default
|
||||
|
||||
@@ -139,7 +134,7 @@ def make_function3_annotate(self, node, isLambda, nested=1,
|
||||
code._customize,
|
||||
isLambda = isLambda,
|
||||
noneInNames = ('None' in code.co_names))
|
||||
except ParserError as p:
|
||||
except ParserError, p:
|
||||
self.write(str(p))
|
||||
self.ERROR = p
|
||||
return
|
||||
@@ -167,7 +162,7 @@ def make_function3_annotate(self, node, isLambda, nested=1,
|
||||
self.write(suffix, param)
|
||||
suffix = ', '
|
||||
if param in annotate_tuple[0].attr:
|
||||
p = annotate_tuple[0].attr.index(param)
|
||||
p = [x for x in annotate_tuple[0].attr].index(param)
|
||||
self.write(': ')
|
||||
self.preorder(node[p])
|
||||
if (line_number != self.line_number):
|
||||
@@ -179,7 +174,10 @@ def make_function3_annotate(self, node, isLambda, nested=1,
|
||||
# else:
|
||||
# self.write(': %s' % value)
|
||||
|
||||
suffix = ', ' if i > 0 else ''
|
||||
if i > 0:
|
||||
suffix = ', '
|
||||
else:
|
||||
suffix = ''
|
||||
for n in node:
|
||||
if n == 'pos_arg':
|
||||
self.write(suffix)
|
||||
@@ -358,17 +356,21 @@ def make_function2(self, node, isLambda, nested=1, codeNode=None):
|
||||
code._customize,
|
||||
isLambda = isLambda,
|
||||
noneInNames = ('None' in code.co_names))
|
||||
except ParserError as p:
|
||||
except ParserError, p:
|
||||
self.write(str(p))
|
||||
self.ERROR = p
|
||||
return
|
||||
|
||||
kw_pairs = args_node.attr[1] if self.version >= 3.0 else 0
|
||||
if self.version >= 3.0:
|
||||
kw_pairs = args_node.attr[1]
|
||||
else:
|
||||
kw_pairs = 0
|
||||
indent = self.indent
|
||||
|
||||
# build parameters
|
||||
tup = [paramnames, defparams]
|
||||
params = [build_param(ast, name, default) for
|
||||
name, default in zip_longest(paramnames, defparams, fillvalue=None)]
|
||||
name, default in map(lambda *tup:tup, *tup)]
|
||||
params.reverse() # back to correct order
|
||||
|
||||
if code_has_star_arg(code):
|
||||
@@ -494,18 +496,22 @@ def make_function3(self, node, isLambda, nested=1, codeNode=None):
|
||||
code._customize,
|
||||
isLambda = isLambda,
|
||||
noneInNames = ('None' in code.co_names))
|
||||
except ParserError as p:
|
||||
except ParserError, p:
|
||||
self.write(str(p))
|
||||
self.ERROR = p
|
||||
return
|
||||
|
||||
kw_pairs = args_node.attr[1] if self.version >= 3.0 else 0
|
||||
if self.version >= 3.0:
|
||||
kw_pairs = args_node.attr[1]
|
||||
else:
|
||||
kw_pairs = 0
|
||||
indent = self.indent
|
||||
|
||||
# build parameters
|
||||
if self.version != 3.2:
|
||||
tup = [paramnames, defparams]
|
||||
params = [build_param(ast, name, default) for
|
||||
name, default in zip_longest(paramnames, defparams, fillvalue=None)]
|
||||
name, default in map(lambda *tup:tup, *tup)]
|
||||
params.reverse() # back to correct order
|
||||
|
||||
if code_has_star_arg(code):
|
||||
@@ -540,7 +546,10 @@ def make_function3(self, node, isLambda, nested=1, codeNode=None):
|
||||
|
||||
i = len(paramnames) - len(defparams)
|
||||
self.write(", ".join(paramnames[:i]))
|
||||
suffix = ', ' if i > 0 else ''
|
||||
if i > 0:
|
||||
suffix = ', '
|
||||
else:
|
||||
suffix = ''
|
||||
for n in node:
|
||||
if n == 'pos_arg':
|
||||
self.write(suffix)
|
||||
|
@@ -67,8 +67,6 @@ methods implement most of the below.
|
||||
The '%' may optionally be followed by a number (C) in square brackets, which
|
||||
makes the engine walk down to N[C] before evaluating the escape code.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
|
||||
from uncompyle6 import PYTHON3
|
||||
@@ -895,7 +893,10 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
return
|
||||
n = node[-1]
|
||||
elif node[-1] == 'del_stmt':
|
||||
n = node[-3] if node[-2] == 'JUMP_BACK' else node[-2]
|
||||
if node[-2] == 'JUMP_BACK':
|
||||
n = node[-3]
|
||||
else:
|
||||
n = node[-2]
|
||||
|
||||
assert n == 'list_iter'
|
||||
|
||||
@@ -913,7 +914,10 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
list_iter = node[-1]
|
||||
else:
|
||||
expr = n[1]
|
||||
list_iter = node[-3] if node[-2] == 'JUMP_BACK' else node[-2]
|
||||
if node[-2] == 'JUMP_BACK':
|
||||
list_iter = node[-3]
|
||||
else:
|
||||
list_iter = node[-2]
|
||||
|
||||
assert expr == 'expr'
|
||||
assert list_iter == 'list_iter'
|
||||
@@ -965,7 +969,10 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
self.write( '[ ')
|
||||
|
||||
expr = n[0]
|
||||
list_iter = node[-2] if self.is_pypy and node[-1] == 'JUMP_BACK' else node[-1]
|
||||
if self.is_pypy and node[-1] == 'JUMP_BACK':
|
||||
list_iter = node[-2]
|
||||
else:
|
||||
list_iter = node[-1]
|
||||
|
||||
assert expr == 'expr'
|
||||
assert list_iter == 'list_iter'
|
||||
@@ -1039,7 +1046,10 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
self.write(' for ')
|
||||
self.preorder(ast[iter_index-1])
|
||||
self.write(' in ')
|
||||
iter_expr = node[2] if node[2] == 'expr' else node[-3]
|
||||
if node[2] == 'expr':
|
||||
iter_expr = node[2]
|
||||
else:
|
||||
iter_expr = node[-3]
|
||||
assert iter_expr == 'expr'
|
||||
self.preorder(iter_expr)
|
||||
self.preorder(ast[iter_index])
|
||||
@@ -1047,7 +1057,10 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
|
||||
def n_genexpr(self, node):
|
||||
self.write('(')
|
||||
code_index = -6 if self.version > 3.2 else -5
|
||||
if self.version > 3.2:
|
||||
code_index = -6
|
||||
else:
|
||||
code_index = -5
|
||||
self.comprehension_walk(node, iter_index=3, code_index=code_index)
|
||||
self.write(')')
|
||||
self.prune()
|
||||
@@ -1281,7 +1294,10 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
break
|
||||
pass
|
||||
pass
|
||||
subclass_info = node if node == 'classdefdeco2' else node[0]
|
||||
if node == 'classdefdeco2':
|
||||
subclass_info = node
|
||||
else:
|
||||
subclass_info = node[0]
|
||||
elif buildclass[1][0] == 'load_closure':
|
||||
# Python 3 with closures not functions
|
||||
load_closure = buildclass[1]
|
||||
@@ -1305,7 +1321,10 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
subclass = buildclass[1][0].attr
|
||||
subclass_info = node[0]
|
||||
else:
|
||||
buildclass = node if (node == 'classdefdeco2') else node[0]
|
||||
if node == 'classdefdeco2':
|
||||
buildclass = node
|
||||
else:
|
||||
buildclass = node[0]
|
||||
build_list = buildclass[1][0]
|
||||
if hasattr(buildclass[-3][0], 'attr'):
|
||||
subclass = buildclass[-3][0].attr
|
||||
@@ -1981,7 +2000,9 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
tokens.append(Token('LAMBDA_MARKER'))
|
||||
try:
|
||||
ast = python_parser.parse(self.p, tokens, customize)
|
||||
except (python_parser.ParserError, AssertionError) as e:
|
||||
except python_parser.ParserError, e:
|
||||
raise ParserError(e, tokens)
|
||||
except AssertionError, e:
|
||||
raise ParserError(e, tokens)
|
||||
maybe_show_ast(self.showast, ast)
|
||||
return ast
|
||||
@@ -2008,7 +2029,9 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
# Build AST from disassembly.
|
||||
try:
|
||||
ast = python_parser.parse(self.p, tokens, customize)
|
||||
except (python_parser.ParserError, AssertionError) as e:
|
||||
except python_parser.ParserError, e:
|
||||
raise ParserError(e, tokens)
|
||||
except AssertionError, e:
|
||||
raise ParserError(e, tokens)
|
||||
|
||||
maybe_show_ast(self.showast, ast)
|
||||
@@ -2086,10 +2109,10 @@ def deparse_code(version, co, out=sys.stdout, showasm=None, showast=False,
|
||||
if __name__ == '__main__':
|
||||
def deparse_test(co):
|
||||
"This is a docstring"
|
||||
sys_version = sys.version_info.major + (sys.version_info.minor / 10.0)
|
||||
sys_version = float(sys.version[0:3])
|
||||
deparsed = deparse_code(sys_version, co, showasm='after', showast=True)
|
||||
# deparsed = deparse_code(sys_version, co, showasm=None, showast=False,
|
||||
# showgrammar=True)
|
||||
print(deparsed.text)
|
||||
return
|
||||
deparse_test(deparse_test.__code__)
|
||||
deparse_test(deparse_test.func_code)
|
||||
|
@@ -12,7 +12,10 @@ def maybe_show_asm(showasm, tokens):
|
||||
:param tokens: The asm tokens to show.
|
||||
"""
|
||||
if showasm:
|
||||
stream = showasm if hasattr(showasm, 'write') else sys.stdout
|
||||
if hasattr(showasm, 'write'):
|
||||
stream = showasm
|
||||
else:
|
||||
stream = sys.stdout
|
||||
for t in tokens:
|
||||
stream.write(str(t))
|
||||
stream.write('\n')
|
||||
@@ -29,7 +32,10 @@ def maybe_show_ast(showast, ast):
|
||||
:param ast: The ast to show.
|
||||
"""
|
||||
if showast:
|
||||
stream = showast if hasattr(showast, 'write') else sys.stdout
|
||||
if hasattr(showast, 'write'):
|
||||
stream = showast
|
||||
else:
|
||||
stream = sys.stdout
|
||||
stream.write(str(ast))
|
||||
stream.write('\n')
|
||||
|
||||
@@ -48,7 +54,10 @@ def maybe_show_ast_param_default(showast, name, default):
|
||||
:param default: The function parameter default.
|
||||
"""
|
||||
if showast:
|
||||
stream = showast if hasattr(showast, 'write') else sys.stdout
|
||||
if hasattr(showast, 'write'):
|
||||
stream = showast
|
||||
else:
|
||||
stream = sys.stdout
|
||||
stream.write('\n')
|
||||
stream.write('--' + name)
|
||||
stream.write('\n')
|
||||
|
@@ -6,8 +6,6 @@
|
||||
byte-code verification
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import dis, operator
|
||||
|
||||
import uncompyle6
|
||||
@@ -365,8 +363,10 @@ def cmp_code_objects(version, is_pypy, code_obj1, code_obj2,
|
||||
elif member == 'co_flags':
|
||||
flags1 = code_obj1.co_flags
|
||||
flags2 = code_obj2.co_flags
|
||||
if is_pypy:
|
||||
if is_pypy or version == 2.4:
|
||||
# For PYPY for now we don't care about PYPY_SOURCE_IS_UTF8:
|
||||
# Python 2.4 also sets this flag and I am not sure
|
||||
# where or why
|
||||
flags2 &= ~0x0100 # PYPY_SOURCE_IS_UTF8
|
||||
# We also don't care about COROUTINE or GENERATOR for now
|
||||
flags1 &= ~0x000000a0
|
||||
@@ -375,6 +375,8 @@ def cmp_code_objects(version, is_pypy, code_obj1, code_obj2,
|
||||
raise CmpErrorMember(name, 'co_flags',
|
||||
pretty_flags(flags1),
|
||||
pretty_flags(flags2))
|
||||
|
||||
|
||||
else:
|
||||
# all other members must be equal
|
||||
if getattr(code_obj1, member) != getattr(code_obj2, member):
|
||||
@@ -418,8 +420,10 @@ def compare_code_with_srcfile(pyc_filename, src_filename, weak_verify=False):
|
||||
return msg
|
||||
try:
|
||||
code_obj2 = load_file(src_filename)
|
||||
except SyntaxError as e:
|
||||
except SyntaxError, e:
|
||||
# src_filename can be the first of a group sometimes
|
||||
if version == 2.4:
|
||||
print(pyc_filename)
|
||||
return str(e).replace(src_filename, pyc_filename)
|
||||
cmp_code_objects(version, is_pypy, code_obj1, code_obj2, ignore_code=weak_verify)
|
||||
return None
|
||||
|
@@ -1,3 +1,3 @@
|
||||
# This file is suitable for sourcing inside bash as
|
||||
# well as importing into Python
|
||||
VERSION='2.9.10'
|
||||
VERSION='2.9.11'
|
||||
|
Reference in New Issue
Block a user