Compare commits

..

293 Commits

Author SHA1 Message Date
rocky
350a16cfa2 Administrivia 2018-10-27 12:54:25 -04:00
rocky
5a7024d2a3 Tweak travis 2018-10-27 11:30:49 -04:00
rocky
e16138527a Merge branch 'master' of github.com:rocky/python-uncompyle6 2018-10-27 11:23:02 -04:00
rocky
2362045c84 Get ready for release 2018-10-27 11:21:05 -04:00
rocky
a29afd6832 Get ready for release 2018-10-27 11:20:07 -04:00
rocky
1bcf0d54f7 Get ready for release 3.2.4 2018-10-27 11:04:26 -04:00
rocky
4c6bdd58ab Fix indentation iftrue_stmt24
Fixes #187
2018-10-17 15:35:51 -04:00
rocky
7898fa157b extend Python 2.6- lastc grammar-rule
Fixes #192
2018-10-05 12:37:16 -04:00
rocky
bbdb238ddb Note that bytecode should be provided. 2018-10-01 23:59:06 -04:00
rocky
ec42ee540c Small typos 2018-09-20 17:40:23 -04:00
rocky
616e5c82f6 Reinstat expr32 and expr1024 rules...
to speed up handling long literal lists. See also issue #188

Update issue forms to simplfy via putting instructions as comments.
2018-09-19 20:14:42 -04:00
rocky
1cb31a85fd decompile bytecode_version defaults to Python intepreter version
Fixes #189
2018-09-19 15:20:23 -04:00
rocky
7d1ecf957c Not sure why this is here, but fix it so it works. 2018-09-19 08:41:02 -04:00
rocky
c96e796ff5 Handle Python 2.4 if true 2018-08-12 02:24:13 -04:00
rocky
f14e1dd62f Update bug report template 2018-08-02 12:32:50 -04:00
rocky
5f1667988f Guidleines for reporting bugs and openning feature requests 2018-08-02 12:28:58 -04:00
rocky
19ec52eb63 Change AST to SyntaxTree in many places 2018-07-15 12:37:50 -04:00
rocky
c3e722ad51 Python 3.7 is too new for TravisCI 2018-07-13 10:39:48 -04:00
rocky
31de342528 Try 3.7.0 on travis 2018-07-13 10:32:10 -04:00
rocky
70f25d5f8d Merge branch 'master' of github.com:rocky/python-uncompyle6 2018-07-05 21:48:53 -04:00
rocky
1b71cfef07 3.6 omit END_FINALLY sometimes
Fixes #182
2018-07-05 21:47:36 -04:00
R. Bernstein
e7845ed2e4 Update HOW-TO-REPORT-A-BUG.md 2018-07-05 07:19:33 -04:00
rocky
f4a1e9e40f Skip botched 3.8.5 release 2018-07-03 16:32:23 -04:00
rocky
b9e8e619f6 Add a 3.0 test 2018-07-03 15:45:27 -04:00
rocky
5c88f804c1 Remove CircleCI 1.1 2018-06-26 22:36:51 -04:00
rocky
35834b06d4 Generalize stdlib test 2018-06-25 16:43:06 -04:00
rocky
27febca918 Another CircleCI 2.0 try 2018-06-25 13:18:14 -04:00
rocky
37b917ed7c Convert to CircleCI 2.0 2018-06-25 13:12:46 -04:00
rocky
82499b50bb Small typo 2018-06-24 18:24:53 -04:00
rocky
c6b3e20b47 Remove some of the 3.0 3.x instruction hackiness 2018-06-24 18:23:38 -04:00
rocky
93e889e82a Python 3.0 comprehensions are a snowflake 2018-06-24 16:46:56 -04:00
rocky
4cbd136635 Make Python 3.0 control flow more like 3.x 2018-06-24 12:56:43 -04:00
rocky
488a14488c Python 3.0 compare-chained2 grammar rule 2018-06-24 11:19:10 -04:00
rocky
44321fcedf Extend Python 3.0 "or" grammar rule 2018-06-24 11:07:37 -04:00
rocky
1e0a6d528e Expand 3.0 while grammar rule 2018-06-24 07:42:36 -04:00
rocky
40fa379fd9 Add 3.0 comp_if_not grammar rule 2018-06-24 07:28:58 -04:00
rocky
34ec41f274 Improve 3.0 list comprehensions 2018-06-24 06:56:30 -04:00
rocky
3daf3732c3 Fix Python 3.0 "and" parse rule 2018-06-23 23:04:17 -04:00
rocky
988efa3693 Had botched 2.6 grammar 2018-06-23 13:48:01 -04:00
rocky
bc16cc93d6 More Python 3.0 parse errors 2018-06-23 13:31:16 -04:00
rocky
8d1bd6d5b5 Fix one more Python 3.0 parse bug 2018-06-23 12:24:22 -04:00
rocky
c148e49670 Python 3.0 chained comparisions 2018-06-23 07:38:34 -04:00
rocky
fb31fe1f35 Another Python 3.0 (while) parse bug 2018-06-23 05:48:14 -04:00
rocky
fa5da2b1ef Fix 3.0 try except bug 2018-06-23 00:06:35 -04:00
rocky
f331deb864 2nd attempt to get check_grammar working on 3.x 2018-06-22 21:27:46 -04:00
rocky
1350f4c899 Some bugs...
Python 3 compiling Python 2 tolerance. Fixes issue #180.
pytest test_grammar.py and validate.py fixes for 3.6 testing
2018-06-22 21:06:54 -04:00
rocky
6fd8d2556b Fix another 3.0 bug 2018-06-22 14:32:52 -04:00
rocky
276fb77e71 Fix two Python 3.0 bugs...
* don't add _[0] list comprehension variables
* add POP_TOP in _ifstmts_jmp; c_stmst for now isn't optional
2018-06-22 09:58:28 -04:00
rocky
f547ec9291 Better is_pypy defaults 2018-06-19 12:26:22 -04:00
rocky
4f994b4cae Merge branch 'master' of github.com:rocky/python-uncompyle6 2018-06-19 04:08:58 -04:00
rocky
98cd06d6e0 Remove a use of deparse_code. 2018-06-19 04:08:20 -04:00
rocky
a3b6806c33 Omit another test on gcc110 2018-06-18 11:19:51 -04:00
rocky
66ebb15d42 Previous two releases botched iterated list comprehensions 2018-06-14 10:32:54 -04:00
rocky
8955788990 Add first 3.0 run test 2018-06-13 18:47:36 -04:00
rocky
9415ad34ff One last grammar typo 2018-06-13 13:37:21 -04:00
rocky
476db9ad1d Get ready for release 3.2.3 2018-06-13 13:11:58 -04:00
rocky
9ba0b1bad2 Fix one more 3.0 parsing bug 2018-06-13 13:08:25 -04:00
rocky
b7942bc5f2 Add Python 1.3 decompilation ..
Reduced checking via "make check-short"
2018-06-13 12:26:21 -04:00
rocky
3ac4f1ee61 Had botched parameter order in 3.x. Sigh 2018-06-13 11:29:57 -04:00
rocky
55d2df04f7 Note that we handle Python 1.4 now 2018-06-12 15:28:40 -04:00
rocky
6d529d3cee Fix wording 2018-06-12 15:26:40 -04:00
rocky
201e5b18b1 Administrivia: Remove six dependency..
add version of hypothesis known to work
2018-06-12 14:44:08 -04:00
rocky
ac2bbfc65a Disable hypothesis on 2.6.9 2018-06-12 14:34:54 -04:00
rocky
3b8e6635e2 Get ready for release 3.2.2 2018-06-12 13:37:24 -04:00
rocky
7e172b63d1 Update documentation 2018-06-12 13:13:48 -04:00
rocky
c01eb554ed Fix bug introduced in last commit 2018-06-12 12:35:13 -04:00
rocky
d32e67891b More 3.0 bug fixing and tollerance and...
add some 1.4 bytecode tests
2018-06-12 12:19:43 -04:00
rocky
78b8d1cd06 Python 3.0 fixes + administrivia 2018-06-12 08:29:13 -04:00
rocky
600e56b1d7 Better "continue" detection on Python 3.0 2018-06-12 04:47:29 -04:00
rocky
170504c518 Remove unused 3.0 grammar rules 2018-06-11 11:54:08 -04:00
rocky
e3d918df3d Allow Python 3.0 and fix default param bug in 3.0 2018-06-11 11:33:50 -04:00
rocky
e7b62a722f Fix more Python 3.0 parse bugs 2018-06-10 16:49:04 -04:00
rocky
92d63ac598 More 3.0 grammar fixes...
3.0 is such as snowflake
2018-06-10 05:26:00 -04:00
rocky
79bed3419f last change left 3.2 finding comp_iter broken 2018-06-10 04:56:57 -04:00
rocky
0353b74a7a 3.0 list comprehensions 2018-06-09 23:14:04 -04:00
rocky
67910e7d8e Python 3.0 set comprehensions 2018-06-09 22:51:07 -04:00
rocky
61fa4fe391 Some Python 3.0 fixes...
Needs more in this direction though.
2018-06-09 10:05:23 -04:00
rocky
a8cdcc4d85 wrong test disabled 2018-06-04 15:35:17 -04:00
rocky
f0176add7a More bugs - note and disable tests for them 2018-06-04 15:29:04 -04:00
rocky
45c8d62e68 Get ready for release 3.2.1 2018-06-04 10:55:10 -04:00
rocky
096563cf91 Fix Python 1.5- bug in handling unpack list 2018-06-04 10:49:20 -04:00
rocky
7fd21aa227 Fix more Python 1.4 decompilation bugs 2018-06-04 09:37:35 -04:00
rocky
82bc294995 Improve Python 1.4 bytecode coverage 2018-06-04 08:54:09 -04:00
rocky
9d3e4a6660 Some Python 1.4 fixes 2018-06-04 02:09:48 -04:00
rocky
7dfade1195 Remove schmutz 2018-06-03 03:53:53 -04:00
rocky
1df5aa0ef9 Better Python 1.4 support 2018-06-03 03:21:15 -04:00
rocky
c06ba45991 See if we can get Appveyor working again... 2018-05-21 12:06:11 -04:00
rocky
7fab91eb4e Past fix of conditional_not bleed into 2.5...
and it shouldn't have
2018-05-19 13:00:44 -04:00
rocky
c2181e3235 Get ready for release 3.2.0 2018-05-19 12:29:26 -04:00
rocky
3695921364 CircleCI administrivia 2018-05-19 11:59:55 -04:00
rocky
d14193f219 xdis 3.8.2 has python 1.4 support 2018-05-19 11:53:32 -04:00
rocky
94251cd294 Tolerate bytecode < 1.5 2018-05-19 11:49:42 -04:00
rocky
a9515c7aab Add bytecode 1.4 small tests
Many bugs in 1.4 exist. For a future release
2018-05-19 11:31:23 -04:00
rocky
e5f3d803a8 Start Python 1.4 decompilation ...
Tidy up test code for issue 162 and comments for some disassembly massaging.
2018-05-19 07:14:00 -04:00
rocky
e5ae70bea8 batch workaround 2018-05-14 22:28:54 -04:00
rocky
189605ea2c Adjust showtree() calls 2018-05-13 14:23:52 -04:00
rocky
4c74bf1d9d --tree++ shows template rule when it is used 2018-05-13 14:21:46 -04:00
rocky
c087bd785e Tweak 2.6.9 for batch test machine 2018-05-11 09:57:08 -04:00
rocky
80b68af2d3 More 2.6 control flow logix futzing 2018-05-09 11:12:16 -04:00
rocky
24ccc16701 Need full filename in runtests.sh 2018-05-08 10:38:50 -04:00
rocky
69714fb65a Limit more tests in batch 2018-05-08 10:30:59 -04:00
rocky
b94f98f8f7 Note we can't handle try/else sometimes in 2.7 2018-05-08 10:17:38 -04:00
rocky
f05b092983 "and" handling before 2.6 is different 2018-05-08 09:29:41 -04:00
rocky
76a66c3460 2.6 if-else-not handling...
For now, we say that conditional-not can't be in an "and".
2018-05-08 09:17:20 -04:00
rocky
91224b2382 Merge branch 'master' of github.com:rocky/python-uncompyle6 2018-05-08 08:50:23 -04:00
rocky
e76f1f107f Better testing of named %c format specifiers 2018-05-08 08:49:43 -04:00
rocky
2f8e063a99 remove 2.6.9 test_grammar.py for now 2018-05-03 21:20:22 -04:00
rocky
15533c5e38 Fixes #174 2018-05-03 14:56:18 -04:00
rocky
6511cc4dd4 Add Another 2.7.5 "while 1" rule 2018-05-01 04:00:35 -04:00
rocky
fdf97a1cc0 Add if_not rule for Python 2.7 2018-05-01 03:10:46 -04:00
rocky
24011bb0da Python 2.7.5 tolerance 2018-05-01 02:48:51 -04:00
rocky
4f61321c91 stdlib batch testing workarounds 2018-04-29 10:03:47 -04:00
rocky
269f4f2e1b 2.6, 2.7 Parse if else inside list comprehension
Fixes #171
2018-04-28 20:44:09 -04:00
rocky
aab951280b Set precedence better for list comprehensions. 2018-04-28 17:27:29 -04:00
rocky
f1e48fb60a while1 grammar rule cleanup
Closes #172
2018-04-27 10:57:27 -04:00
rocky
c0022ed5b7 Typo 2018-04-25 13:05:56 -04:00
rocky
41a50b5e46 Handle if not else in lambdas...
Fixes #170
2018-04-25 12:57:09 -04:00
rocky
0154c87d63 CALL_FUNCTION_EX specialization in 3.6 2018-04-23 18:47:30 -04:00
rocky
c9c70103aa Merge branch 'master' of github.com:rocky/python-uncompyle6 2018-04-23 15:40:19 -04:00
rocky
a18dc340ce Start to narrow 3.7 FUNCTION_EX grammar 2018-04-23 15:40:04 -04:00
rocky
037648577f Start to narrow 3.7 FUNCTION_EX grammar 2018-04-23 15:16:03 -04:00
rocky
cd62e54c88 Correct (3.7) use fof BUILD_MAP_UNPACK_WITH_CALL 2018-04-21 00:41:14 -04:00
rocky
ef9ccc3a8c Fix 3.7 aysnc def testing 2018-04-20 11:15:52 -04:00
rocky
c397bf6bda Generalize 3.7 attribute with LOAD_METHOD 2018-04-19 19:28:53 -04:00
rocky
0aa41058a6 customize "async for" on 3.6. and 3.7 2018-04-19 15:03:09 -04:00
rocky
27f67e6fca Fix some 3.6/3.7 bugs 2018-04-19 10:00:40 -04:00
rocky
6fcf49b214 2.6 compatability 2018-04-18 12:18:32 -04:00
rocky
49661b222e Ooops - remove debug statement. 2018-04-18 12:11:56 -04:00
rocky
c481d97866 A more uniform way to track opcodes seen...
use a set rather than these boolean variables. Done in 3.x
only for now. May do more later..
2018-04-18 12:01:46 -04:00
rocky
ab5303f504 Administrivia 2018-04-16 13:06:16 -04:00
rocky
6c6d62edb8 python 2.6 grammar test tweak 2018-04-16 13:00:30 -04:00
rocky
245deb0931 Get ready for release 3.8.1 ...
and more 3.7 grammar customization
2018-04-16 12:53:35 -04:00
rocky
87b70cfd13 Plough forward on 3.7 CALL_FUNCTION_EX 2018-04-15 14:15:25 -04:00
rocky
bbc7616e24 More wordsmithing 2018-04-15 14:05:38 -04:00
rocky
d5b7be59c5 Wordsmithing 2018-04-15 13:18:06 -04:00
rocky
7a4c11c3f4 testing administrivia 2018-04-15 05:57:25 -04:00
rocky
9ef38285f4 Fix bug in fragment parser 2018-04-14 06:54:15 -04:00
rocky
5de8a33286 codeNode->code_node 2018-04-13 15:44:41 -04:00
rocky
9e652f3fc6 More 3.7 grammar rules...
largely adapted from 3.6
2018-04-13 14:24:20 -04:00
rocky
9fa7b9ea53 Forge on with 3.7 2018-04-13 13:31:47 -04:00
rocky
1890aad660 Small 3.7 steps 2018-04-13 07:26:32 -04:00
rocky
7237658f1f Start to handle 3.7 2018-04-12 23:49:37 -04:00
rocky
fa6408d53b Testing with other decompiler tools 2018-04-12 19:57:53 -04:00
rocky
da57e2d416 Note verification process and results 2018-04-12 18:56:57 -04:00
rocky
9545541be7 Isolate Python 3 class code from Python2 2018-04-12 18:10:32 -04:00
rocky
98f969592c Merge branch 'master' of github.com:rocky/python-uncompyle6 2018-04-12 18:00:50 -04:00
rocky
edbab038ca Fix improper 3.0 class handling...
... is like 3.1 not 2.7
2018-04-12 17:59:39 -04:00
rocky
08cbf56eea Batch testing adjustment 2018-04-12 11:20:27 -04:00
rocky
8734608929 Small doc typos 2018-04-09 01:36:42 -04:00
rocky
ab414d3d9c Get ready for release 3.1.2 2018-04-08 05:34:25 -04:00
rocky
ede6eabc40 Slightly Python 3.x handing of subclasses...
which are created via a call to create a subclass.

Should be more general though.
2018-04-08 05:22:35 -04:00
rocky
61e2b3b635 Can run on 3.1. Fix some 3.1 function-call bugs 2018-04-08 04:11:01 -04:00
rocky
23fb07b1c9 Update test 2018-04-07 07:21:22 -04:00
rocky
1bbb72a6ce Handle class with one kwarg subclass 2018-04-07 07:13:49 -04:00
rocky
17361a9baa Administrivia 2018-04-06 22:11:30 -04:00
rocky
68821efdb0 Improve 3.5+ BUILD_MAP_UNPACK...
And add build_tuple_unpack runtime test from a previous commit.

We are far from out of the woods, as there is more to do and
we've uncovered more bugs in handling this.
2018-04-06 21:34:31 -04:00
rocky
e9ee671874 Testing administriva 2018-04-06 19:06:11 -04:00
rocky
9593043432 Add more stdlib run test coverage 2018-04-06 14:23:56 -04:00
rocky
1c95eb7b4e Make sure we call 'expr' go set precidence right 2018-04-06 14:04:58 -04:00
rocky
ff9ae4e792 Better handling of BUILD_TUPLE_UNPACK 2018-04-06 11:35:41 -04:00
rocky
d9eb5c5b09 Start folding in 3.5 vararg ops as varargs ops 2018-04-05 23:02:45 -04:00
rocky
e7b7de8842 Bump xdis version 2018-04-04 23:55:01 -04:00
rocky
3f26589bf1 More testing 2018-04-04 22:43:19 -04:00
rocky
30ce3a8bea Small tweaks 2018-04-04 22:36:26 -04:00
rocky
341e17f62c Split of Python 3 semantic-action customization...
And remove duplicate customization code in pysource.
2018-04-04 21:54:09 -04:00
rocky
b561b0090c Increase testing 2018-04-04 20:32:54 -04:00
rocky
ca41ea99f2 Fix 3.2 to 3.3 make_function more properly 2018-04-04 14:30:34 -04:00
rocky
e3040c78a9 3.2-3.4 Functions cals/defininitions yet again
And we're still not out of the woods.
2018-04-03 21:27:31 -04:00
rocky
a556e96c22 Merge branch 'master' of github.com:rocky/python-uncompyle6 2018-04-03 19:44:09 -04:00
rocky
e9c0d03b8b 3.2 mk_func tweak...
...more is needed though
2018-04-03 17:57:37 -04:00
rocky
155fd06372 More administrivia 2018-04-03 11:08:22 -04:00
rocky
acff1b6ee0 Administrivia
Adjust requirements-dev for 2.6.9
2018-04-03 11:00:16 -04:00
rocky
1cd2d1e915 DRY scanner code more...
Expand 2.6 testing
2018-04-03 10:35:02 -04:00
rocky
e2dec73a62 3.5 CALL_FUNCTION_VAR bug 2018-04-03 05:56:45 -04:00
rocky
fad43feb3d DRY instruction building code...
There is a little more that could be done with  self.offset2inst_index
2018-04-03 04:41:36 -04:00
rocky
96d8daeae9 More pyenv testing 2018-04-01 21:19:55 -04:00
rocky
8f6a1cb10b Add 3.2 to list of supported distributions 2018-04-01 16:54:10 -04:00
rocky
fc98bc972e Update NEWS 2018-04-01 14:53:45 -04:00
rocky
007ba4a8f3 Get ready for release 3.1.1 2018-04-01 14:17:50 -04:00
rocky
6b78677a74 Work on 3.5+ BUILD_MAP_UNPACK...
bugs still remain, just reduced.
2018-04-01 13:41:16 -04:00
rocky
ab1dba1536 Handle 3.5+ BUILD_MAP_UNPACK used in dictionaries
A number of weaknesses have been uncovered though
2018-04-01 12:56:58 -04:00
rocky
254d0519bb More 3.6 CALL_FUNCTION argument parsing 2018-04-01 11:26:46 -04:00
rocky
120412f5a8 Add Python 3.6 setcomp and another call bug 2018-04-01 07:09:24 -04:00
rocky
b54be24e14 3.6 argument parsing 2018-03-31 23:07:06 -04:00
rocky
535df1592e Another 3.6 control-flow bug...
and add source to some previous bytecode tests
2018-03-31 19:28:35 -04:00
rocky
64ffa5f6ab Add semantic action rule for except_return 2018-03-29 22:50:25 -04:00
rocky
9be4908c9c Python 3.6 MAKE_FUNCTION yet again...
And we'll eventually have to do more down the line
2018-03-29 22:04:46 -04:00
rocky
f18ce71e91 Replace all_instrs with inst_matches...
which works on 3.6+. Still should write a pytest for this.
2018-03-29 21:23:26 -04:00
rocky
362a353e03 Merge branch 'master' of github.com:rocky/python-uncompyle6 2018-03-29 17:21:51 -04:00
rocky
7d110f17bc 3.6 decompilation problems 2018-03-29 17:21:22 -04:00
R. Bernstein
04f4f3c25f Merge pull request #166 from rocky/grammer-reduce
Some 3.x grammar reduction...
2018-03-29 11:59:37 -04:00
rocky
1d5f4b0a05 Some 3.x grammar reduction...
Add 3.2 to grammar testing
2018-03-28 21:19:27 -04:00
rocky
dc3e6b31ca Limit coverage on 3.6 for now 2018-03-28 13:47:30 -04:00
rocky
94a81a36b7 3.5, 3.6 loop if/continue handling 2018-03-28 09:23:34 -04:00
rocky
e568d68baa Reinstate a test 2018-03-28 07:52:04 -04:00
R. Bernstein
8c22d57979 Merge pull request #165 from rocky/grammar-cleanup2
Grammar reduction for 2.6/2.7,3.x
2018-03-27 20:11:29 -04:00
rocky
bf0f5715a3 Adjust grammar-checking test 2018-03-27 19:47:08 -04:00
rocky
d90c44b454 3.5+ handle then before "if" jump going to loop 2018-03-27 19:24:29 -04:00
rocky
9d807501af Grammar reduction for 2.6/2.7,3.x 2018-03-27 17:02:03 -04:00
rocky
aa4416571b grammar-cover run-and-email fixup 2018-03-27 14:21:28 -04:00
rocky
d38395334c grammar-cover administrivia 2018-03-27 04:33:01 -04:00
rocky
516c7a0e9a Python 3.6 CALL_FUNCTION_EX fixes 2018-03-27 04:10:11 -04:00
rocky
681588f12d 3.5 CALL_FUNCTION_EX 2018-03-26 20:56:17 -04:00
rocky
3500c49daf More Python 3.4 CALL_FUNCTION_VAR 2018-03-26 19:40:33 -04:00
rocky
3d218c84b0 LOAD assert needs to be on 3.x...
Expand testing
2018-03-26 18:11:57 -04:00
rocky
1afe1fd943 Merge branch 'master' of github.com:rocky/python-uncompyle6 2018-03-26 14:50:54 -04:00
rocky
c5f8bbf32d Remove hacky 3.x offset address arithmetic 2018-03-26 14:50:17 -04:00
rocky
6b36d14859 Limit grammar coverage of 3.5.5 for now 2018-03-26 13:33:22 -04:00
rocky
ccbe8a8e2b cover all of 2.6.9 2018-03-26 12:55:43 -04:00
rocky
46c02bd352 There is no 2.8 2018-03-26 12:38:48 -04:00
rocky
30ba043000 Grammar coverage hacking 2018-03-26 11:12:56 -04:00
rocky
1f0e5f27d5 DRY grammar code 2018-03-26 11:08:27 -04:00
rocky
75245ba38c Back off full 2.7.14 testing for now 2018-03-26 09:47:18 -04:00
rocky
4889916304 Grammar coverage work 2018-03-26 09:26:24 -04:00
rocky
d1806edaad Administrivia: grammar coverage 2018-03-26 09:23:24 -04:00
rocky
c968e31be8 Administrivia: grammar coverage 2018-03-26 09:16:15 -04:00
rocky
c8870c6ed8 Grammar coverage hacking 2018-03-26 08:41:40 -04:00
rocky
23180806b4 More grammar coverage hacking 2018-03-26 08:19:03 -04:00
rocky
1f835d6237 Start grammar coverage testing 2018-03-26 08:03:54 -04:00
rocky
3d072e29a6 3.5 CALL_FUNCTION_VAR runnable test 2018-03-26 07:45:34 -04:00
rocky
74f01fbe33 Python 3.5 CALL_FUNCTION_VAR handling 2018-03-26 07:42:15 -04:00
rocky
710c950965 Bang on 3.4 CALL_FUNCTION_VAR 2018-03-26 00:19:39 -04:00
rocky
7aa6ff1d9b 3.6.4 runtests.sh futzing 2018-03-25 22:48:33 -04:00
rocky
421c358f9d Put 3.5.5 back into testing 2018-03-25 22:30:36 -04:00
rocky
cfb4ad625f 3.5 *() arg without further args 2018-03-25 22:24:32 -04:00
R. Bernstein
0b622a0ad8 Merge pull request #163 from rocky/grammar-cleanup
Grammar cleanup
2018-03-25 21:30:50 -04:00
rocky
8b7d5d3270 Merge branch 'master' into grammar-cleanup 2018-03-25 20:57:51 -04:00
rocky
5c7fdf6e8f Adjust stdlib tests 2018-03-25 20:55:04 -04:00
rocky
d2c8e4e12c Adjust test_grammar for recent changes 2018-03-25 20:52:28 -04:00
rocky
626f690a5a More grammar specialization by instruction 2018-03-25 20:38:21 -04:00
rocky
39cef6a41b More raise vs. assert hacky distinctions 2018-03-25 17:56:35 -04:00
rocky
116fbb33e0 Merge branch 'master' of github.com:rocky/python-uncompyle6 2018-03-25 17:36:46 -04:00
rocky
631940887f Additional Python 2.x assert vs raise testing 2018-03-25 17:35:18 -04:00
rocky
47beff57b2 Increase testing 2018-03-25 14:56:48 -04:00
rocky
7fb94176b1 Less ambigouus 2.x grammar rule for BUILD_MAP 2018-03-25 12:09:42 -04:00
rocky
2ae9cd7d08 bang on CALL_FUNCTION_EX_KW 2018-03-24 10:52:55 -04:00
rocky
1f663013ab 3.5 CALL_FUNCTION_VAR semantic handling 2018-03-24 10:24:16 -04:00
rocky
e3c7afb94d Towards handling 3.x' CALL_FUNCTION_VAR correctly 2018-03-24 08:26:45 -04:00
rocky
0d327ab0ce Fix bug introduced in last commit 2018-03-24 06:29:35 -04:00
rocky
35a60e0274 Fix parser slowness in decompiling 3.x locale.py..
And remove grammar inefficiency in adding extraneous kwargs in <= 3.2
kwargs was nullable so it might not have been wasn't wrong, just inefficient.
2018-03-23 11:59:04 -04:00
rocky
1b2b45642b 3.6 try except-as bug 2018-03-22 23:54:12 -04:00
rocky
28bfb453f5 Localize call_kw precedence to 3.6 2018-03-22 14:21:36 -04:00
rocky
df55ce3212 Isolate some 3.x dictcomp grammar rules 2018-03-22 13:34:39 -04:00
rocky
fcb4409e50 Omit 2.7 test_generators.py 2018-03-21 21:01:01 -04:00
rocky
155031a7c4 Get ready for release 3.1.0 2018-03-21 20:11:06 -04:00
rocky
c81b40b43b Comment out test/demo code 2018-03-21 20:00:25 -04:00
rocky
7fc7e083c3 A couple of 3.6 bugs...
remove parens around decorators by adjusting precidence
Partial handling of quotes within 3.6 format strings
2018-03-21 19:54:28 -04:00
rocky
d41a858f80 Messed up API compatibility 2018-03-21 17:38:38 -04:00
rocky
6dd0ad0810 Merge branch 'master' of github.com:rocky/python-uncompyle6 2018-03-21 17:01:21 -04:00
rocky
9368b63a2f Add 3.5 and 3.6 exclusions for runtests.sh...
All 3.x unit-test-type tests can be run via runtests.sh
2018-03-21 17:00:40 -04:00
rocky
da06d83a87 3.6 subclass extraction bug 2018-03-21 15:14:23 -04:00
rocky
6fb5808ff0 Merge branch 'master' of github.com:rocky/python-uncompyle6 2018-03-21 13:18:50 -04:00
rocky
0c3db340fa 2.7 bug confusing "or" with "if" and "assert" 2018-03-21 13:18:18 -04:00
rocky
925b6667d7 3.6 CALL_FUNCTION_KW handling 2018-03-21 08:01:45 -04:00
rocky
b8547346b7 Back off write "mode" setting to < 3.0 2018-03-21 00:25:41 -04:00
rocky
0aa7a7c223 Python code output should be binary...
as it may contain weird characters in strings. in 3.6 or so

r
2018-03-21 00:17:42 -04:00
rocky
cf5445c202 Test administrivia 2018-03-20 21:59:50 -04:00
rocky
bc8c38ee58 Another 2.7 runtests.sh ignore. 2018-03-20 21:01:05 -04:00
rocky
4cd81dab61 ignore 2.6.9 test in runtests.sh
It seems to fail intermittently
2018-03-20 19:29:47 -04:00
rocky
4f4b628842 Merge branch 'master' of github.com:rocky/python-uncompyle6 2018-03-20 16:15:28 -04:00
rocky
ff50a7f37b In 2.7: raise <expr>; expr can't be a "or" 2018-03-20 16:14:53 -04:00
rocky
85a49aec2f Work on fragments API...
* Add code_deparse_around_offset
* find_globals -> find_globals_and_nonlocals
2018-03-20 13:43:16 -04:00
rocky
9f2c7352e7 Administrivia: run-and-email.sh tweaks 2018-03-20 12:34:48 -04:00
rocky
e9cf370e11 Administrivia:
Adjust Travis 2.7 environment
Batch testing of all 3.4.8 pyenv files
2018-03-20 11:44:46 -04:00
rocky
90ac8a463d Adjust 3.x while1else reduction check 2018-03-20 11:33:10 -04:00
rocky
0e64111195 Extend 3.4: "while 1: if : continue" handling 2018-03-20 10:37:19 -04:00
rocky
fd84325e4f Fix status on failed runtests 2018-03-20 07:26:42 -04:00
rocky
ddc00edd42 Correct max on email subject header 2018-03-20 07:17:07 -04:00
rocky
4259963859 Increase batch testing for 3.4.8 2018-03-20 05:30:07 -04:00
rocky
4905cc6bb0 Note where 3.4's 05 test came from 2018-03-20 05:14:28 -04:00
rocky
f008b8f411 Two 3.4 fixes..
* LOAD_DEREF does not signal "nonlocal" variables
* Add rule for "if" with a "continue" and "return"
2018-03-20 05:07:19 -04:00
rocky
2e81ee5d2e Add 3.5.5 pyenv testing 2018-03-19 22:04:54 -04:00
rocky
50e59a37c1 Python 2 "for" grammar rule isolation 2018-03-19 16:15:53 -04:00
rocky
5c8f93b735 Fix 3.6 try/except with return 2018-03-19 16:12:44 -04:00
rocky
88ef4baca8 Fix a 3.6 try/except-as bug 2018-03-19 11:10:37 -04:00
rocky
6ab711baab More 3.6 lambda handling 2018-03-19 09:36:02 -04:00
rocky
9e05750537 Another 3.6 lambda parsing bug 2018-03-19 09:09:59 -04:00
rocky
5c662b334e Handle 3.x "nonlocal" statement 2018-03-19 07:57:25 -04:00
rocky
56b2e17e30 Adjust 3.6 "while" loop grammar 2018-03-19 06:01:39 -04:00
rocky
94038151f4 Add Python 3.6 mklambda rule 2018-03-18 23:37:32 -04:00
rocky
b9281c79be Fix 3.6 list if "and" comprehension bug 2018-03-18 19:12:16 -04:00
rocky
51dec051df Slightly better assert detection 2018-03-08 08:31:50 -05:00
rocky
f5ac06013f We don't do python 3.1 or 3.2 2018-03-08 02:34:05 -05:00
rocky
06bbacef45 And another 2018-03-07 13:27:20 -05:00
rocky
bfdc6529a0 One more 2018-03-07 13:24:57 -05:00
rocky
1ed389ce61 More run-and-email tweaks 2018-03-07 13:22:33 -05:00
rocky
19f2e1277b Another run-and-email shell tweak 2018-03-07 13:06:27 -05:00
rocky
6290311143 Test administrivia 2018-03-07 11:46:14 -05:00
rocky
947d619c77 Tweak summary message 2018-03-07 11:07:56 -05:00
rocky
908d313204 More test shell tweaking 2018-03-07 08:12:34 -05:00
rocky
38dffa3290 Allow setting max tests via MAX_TESTS env var 2018-03-07 08:00:36 -05:00
rocky
c8747cc899 Only run if pyenv works 2018-03-07 07:53:19 -05:00
rocky
8a705a70f5 Set pyenv version in test 2018-03-07 07:48:45 -05:00
285 changed files with 4720 additions and 2317 deletions

89
.circleci/config.yml Normal file
View File

@@ -0,0 +1,89 @@
# This configuration was automatically generated from a CircleCI 1.0 config.
# It should include any build commands you had along with commands that CircleCI
# inferred from your project structure. We strongly recommend you read all the
# comments in this file to understand the structure of CircleCI 2.0, as the idiom
# for configuration has changed substantially in 2.0 to allow arbitrary jobs rather
# than the prescribed lifecycle of 1.0. In general, we recommend using this generated
# configuration as a reference rather than using it in production, though in most
# cases it should duplicate the execution of your original 1.0 config.
version: 2
jobs:
build:
working_directory: ~/rocky/python-uncompyle6
parallelism: 1
shell: /bin/bash --login
# CircleCI 2.0 does not support environment variables that refer to each other the same way as 1.0 did.
# If any of these refer to each other, rewrite them so that they don't or see https://circleci.com/docs/2.0/env-vars/#interpolating-environment-variables-to-set-other-environment-variables .
environment:
CIRCLE_ARTIFACTS: /tmp/circleci-artifacts
CIRCLE_TEST_REPORTS: /tmp/circleci-test-results
COMPILE: --compile
# In CircleCI 1.0 we used a pre-configured image with a large number of languages and other packages.
# In CircleCI 2.0 you can now specify your own image, or use one of our pre-configured images.
# The following configuration line tells CircleCI to use the specified docker image as the runtime environment for you job.
# We have selected a pre-built image that mirrors the build environment we use on
# the 1.0 platform, but we recommend you choose an image more tailored to the needs
# of each job. For more information on choosing an image (or alternatively using a
# VM instead of a container) see https://circleci.com/docs/2.0/executor-types/
# To see the list of pre-built images that CircleCI provides for most common languages see
# https://circleci.com/docs/2.0/circleci-images/
docker:
- image: circleci/build-image:ubuntu-14.04-XXL-upstart-1189-5614f37
command: /sbin/init
steps:
# Machine Setup
# If you break your build into multiple jobs with workflows, you will probably want to do the parts of this that are relevant in each
# The following `checkout` command checks out your code to your working directory. In 1.0 we did this implicitly. In 2.0 you can choose where in the course of a job your code should be checked out.
- checkout
# Prepare for artifact and test results collection equivalent to how it was done on 1.0.
# In many cases you can simplify this from what is generated here.
# 'See docs on artifact collection here https://circleci.com/docs/2.0/artifacts/'
- run: mkdir -p $CIRCLE_ARTIFACTS $CIRCLE_TEST_REPORTS
# This is based on your 1.0 configuration file or project settings
- run:
working_directory: ~/rocky/python-uncompyle6
command: pyenv install 2.7.13 && pyenv local 2.7.13 && pyenv rehash && pip install virtualenv && pip install nose && pip install pep8 && pip install six && pyenv rehash
# Dependencies
# This would typically go in either a build or a build-and-test job when using workflows
# Restore the dependency cache
- restore_cache:
keys:
# This branch if available
- v1-dep-{{ .Branch }}-
# Default branch if not
- v1-dep-master-
# Any branch if there are none on the default branch - this should be unnecessary if you have your default branch configured correctly
- v1-dep-
# This is based on your 1.0 configuration file or project settings
- run: pip install --upgrade setuptools
- run: pip install -e .
- run: pip install pytest==3.2.5 hypothesis
# Save dependency cache
- save_cache:
key: v1-dep-{{ .Branch }}-{{ epoch }}
paths:
# This is a broad list of cache paths to include many possible development environments
# You can probably delete some of these entries
- vendor/bundle
- ~/virtualenvs
- ~/.m2
- ~/.ivy2
- ~/.bundle
- ~/.go_workspace
- ~/.gradle
- ~/.cache/bower
# Test
# This would typically be a build job when using workflows, possibly combined with build
# This is based on your 1.0 configuration file or project settings
- run: python ./setup.py develop && make check-2.7
- run: cd ./test/stdlib && pyenv local 2.7.13 && bash ./runtests.sh 'test_[p-z]*.py'
# Teardown
# If you break your build into multiple jobs with workflows, you will probably want to do the parts of this that are relevant in each
# Save test results
- store_test_results:
path: /tmp/circleci-test-results
# Save artifacts
- store_artifacts:
path: /tmp/circleci-artifacts
- store_artifacts:
path: /tmp/circleci-test-results

77
.github/ISSUE_TEMPLATE/bug-report.md vendored Normal file
View File

@@ -0,0 +1,77 @@
---
name: Bug report
about: Tell us about uncompyle6 bugs
---
<!-- __Note:__ Have you read https://github.com/rocky/python-uncompyle6/blob/master/HOW-TO-REPORT-A-BUG.md ?
Please remove any of the optional sections if they are not applicable.
Prerequisites
* Make sure the bytecode you have can be disassembled with a
disassembler.
* Don't put bytecode and corresponding source code on any service that
requires registration to download.
* When you open a bug report there is no privacy. If the legitimacy of
the activity is deemed suspicous, I may flag it as suspicious,
making the issue even more easy to detect.
Bug reports that violate a prerequisite may be discarded.
Note that there are way more bug-fix requestors than there are bug
fixers. If you want you need more immediate, confidential or urgent
assistance
http://www.crazy-compilers.com/decompyle/ offers a byte-code
decompiler service for versions of Python up to 2.6.
-->
## Description
<!-- Add a clear and concise description of the bug. -->
## How to Reproduce
<!-- Please show both the input you gave and the
output you got in describing how to reproduce the bug:
or give a complete console log with input and output
```console
$ uncompyle6 <command-line-options>
...
$
```
Provide links to the Python bytecode. For example you can create a
gist with the information. If you have the correct source code, you
can add that too.
-->
## Expected behavior
<!-- Add a clear and concise description of what you expected to happen. -->
## Environment
<!-- _This section sometimes is optional but helpful to us._
Please modify for your setup
- Uncompyle6 version: output from `uncompyle6 --version` or `pip show uncompyle6`
- Python version: `python -V`
- OS and Version: [e.g. Ubuntu bionic]
-->
## Additional Environment or Context
<!-- _This section is optional._
Add any other context about the problem here or special environment setup.
-->

View File

@@ -0,0 +1,22 @@
---
name: Feature Request
about: Tell us about a new feature that you would like to see in uncompyle6
---
## Description
<!-- Add a short description of the feature. This might
include same input and output. -->
## Background
<!-- Add any additional background for the
feature, for example: user scenarios, or the value of the feature. -->
## Tests
<!-- _This section is optional._
Add text with suggestions on how to test the feature,
if it is not obvious.
-->

1
.gitignore vendored
View File

@@ -21,3 +21,4 @@
ChangeLog
__pycache__
build
nohup.out

View File

@@ -4,11 +4,9 @@ sudo: false
python:
- '3.5'
- '2.7.12'
- '2.7'
- '2.6'
- '3.3'
- '3.4'
- '3.2'
- '3.6'
install:

View File

@@ -33,7 +33,7 @@ prescribed cases, the ill-defined amorphous cases as well will get
handled as well.
In sum, you may need to do some work to have the bug you have found
handled before the hundreds of other bugs, and things I could be
handled before the hundreds of other bugs, and other things I could be
doing.
No one is getting paid to work to work on this project, let alone the

View File

@@ -27,20 +27,18 @@ check:
check-short: pytest
$(MAKE) -C test check-short
# Note for 2.6 use <=3.0.1 see requirements-dev.txt
#: Tests for Python 2.7, 3.3 and 3.4
check-2.7 check-3.3 check-3.4: pytest
check-2.6 check-2.7 check-3.3 check-3.4 check-3.5: pytest
$(MAKE) -C test $@
#: Tests for Python 3.2 and 3.5 - pytest doesn't work here
# Or rather 3.5 doesn't work not on Travis
check-3.0 check-3.1 check-3.2 check-3.5 check-3.6:
check-3.0 check-3.1 check-3.2 check-3.6:
$(MAKE) -C test $@
check-3.7: pytest
#:Tests for Python 2.6 (doesn't have pytest)
check-2.6:
$(MAKE) -C test $@
$(MAKE) -C test check
#:PyPy 2.6.1 PyPy 5.0.1, or PyPy 5.8.0-beta0
# Skip for now

61
NEWS
View File

@@ -1,3 +1,64 @@
uncompyle6 3.2.4 2018-06-04 7x9 release
- Bug fixes #180, #182, #187, #192
- Enhancements #189
- Internal improvements
uncompyle6 3.2.3 2018-06-04 Michael Cohen flips and Fleetwood Redux
- Python 1.3 support 3.0 bug and
- fix botched parameter ordering of 3.x in last release
uncompyle6 3.2.2 2018-06-04 When I'm 64
- Python 3.0 support and bug fixes
uncompyle6 3.2.1 2018-06-04 MF
- Python 1.4 and 1.5 bug fixes
uncompyle6 3.2.0 2018-05-19 Rocket Scientist
- Add rudimentary 1.4 support (still a bit buggy)
- add --tree+ option to show formatting rule, when it is constant
- Python 2.7.15candidate1 support (via xdis)
- bug fixes, especially for 3.7 (but 2.7 and 3.6 and others as well)
uncompyle6 3.1.3 2018-04-16
- Add some Python 3.7 rules, such as for handling LOAD_METHOD (not complete)
- Fix some fragment bugs
- small doc changes
uncompyle6 3.1.2 2018-04-08 Eastern Orthodox Easter
- Python 3.x subclass and call parsing fixes
- Allow/note running on Python 3.1
- improve 3.5+ BUILD_MAP_UNPACK
- DRY instruction building code between 2.x and 3.x
- expand testing
uncompyle6 3.1.1 2018-04-01 Easter April Fool's
Jesus on Friday's New York Times puzzle: "I'm stuck on 2A"
- fill out 3.5+ BUILD_MAP_UNPACK (more work is needed)
- fill out 3.4+ CALL_FUNCTION_... (more work is needed)
- fill out 3.5 MAKE_FUNCTION (more work is needed)
- reduce 3.5, 3.6 control-flow bugs
- reduce ambiguity in rules that lead to long (exponential?) parses
- limit/isolate some 2.6/2.7,3.x grammar rules
- more runtime testing of decompiled code
- more removal of parenthesis around calls via setting precidence
uncompyle6 3.1.0 2018-03-21 Equinox
- Add code_deparse_with_offset() fragment function.
- Correct paramenter call fragment deparse_code()
- Lots of 3.6, 3.x, and 2.7 bug fixes
About 5% of 3.6 fail parsing now. But
semantics still needs much to be desired.
uncompyle6 3.0.1 2018-02-17
- All Python 2.6.9 standard library files weakly verify

View File

@@ -1,4 +1,4 @@
|buildstatus|
|buildstatus| |Latest Version| |Supported Python Versions|
uncompyle6
==========
@@ -11,8 +11,9 @@ Introduction
------------
*uncompyle6* translates Python bytecode back into equivalent Python
source code. It accepts bytecodes from Python version 1.5, and 2.1 to
3.7 or so, including PyPy bytecode and Dropbox's Python 2.5 bytecode.
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
Python 2.5 bytecode and some PyPy bytecode.
Why this?
---------
@@ -29,11 +30,11 @@ CPython bytecode decompilers is the ability to deparse just
*fragments* of source code and give source-code information around a
given bytecode offset.
I use the tree fragments to deparse fragments of code inside my
trepan_ debuggers_. For that, bytecode offsets are recorded and
associated with fragments of the source code. This purpose, although
compatible with the original intention, is yet a little bit different.
See this_ for more information.
I use the tree fragments to deparse fragments of code *at run time*
inside my trepan_ debuggers_. For that, bytecode offsets are recorded
and associated with fragments of the source code. This purpose,
although compatible with the original intention, is yet a little bit
different. See this_ for more information.
Python fragment deparsing given an instruction offset is useful in
showing stack traces and can be encorporated into any program that
@@ -52,8 +53,17 @@ You get the idea. This code pulls all of these forks together and
*moves forward*. There is some serious refactoring and cleanup in this
code base over those old forks.
This project has the most complete support for Python 3.3 and above
and the best all-around Python support.
This demonstrably does the best in decompiling Python across all
Python versions. And even when there is another project that only
provides decompilation for subset of Python versions, we generally do
demonstrably better for those as well.
How can we tell? By taking Python bytecode that comes distributed with
that version of Python and decompiling these. Among those that
successfully decompile, we can then make sure the resulting programs
are syntactically correct by running the Python interpreter for that
bytecode version. Finally, in cases where the program has a test for
itself, we can run the check on the decompiled code.
We are serious about testing, and use automated processes to find
bugs. In the issue trackers for other decompilers, you will find a
@@ -66,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.5, 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.6 and the
above-mentioned PyPy versions.
Installation
@@ -136,26 +146,26 @@ All of the Python decompilers that I have looked at have problems
decompiling Python's control flow. In some cases we can detect an
erroneous decompilation and report that.
*Verification* is the process of decompiling bytecode, compiling with
a Python for that bytecode version, and then comparing the bytecode
produced by the decompiled/compiled program. Some allowance is made
for inessential differences. But other semantically equivalent
differences are not caught. For example ``1 and 0`` is decompiled to
the equivalent ``0``; remnants of the first true evaluation (1) is
lost when Python compiles this. When Python next compiles ``0`` the
resulting code is simpler.
In older versions of Python it was possible to verify bytecode by
decompiling bytecode, and then compiling using the Python interpreter
for that bytecode version. Having done this the bytecode produced
could be compared with the original bytecode. However as Python's code
generation got better, this is no longer feasible.
*Weak Verification*
on the other hand doesn't check bytecode for equivalence but does
check to see if the resulting decompiled source is a valid Python
program by running the Python interpreter. Because the Python language
has changed so much, for best results you should use the same Python
Version in checking as used in the bytecode.
There verification that we use that doesn't check bytecode for
equivalence but does check to see if the resulting decompiled source
is a valid Python program by running the Python interpreter. Because
the Python language has changed so much, for best results you should
use the same Python version in checking as was used in creating the
bytecode.
Finally, we have automated running the standard Python tests after
first compiling and decompiling the test program. Results here are a
bit weak (if not better than most other Python decompilers). But over
time this will probably get better.
There are however an interesting class of these programs that is
readily available give stronger verification: those programs that
when run check some computation, or even better themselves.
And already Python has a set of programs like this: the test suite
for the standard library that comes with Python. We have some
code in `test/stdlib` to facilitate this kind of checking.
Python support is strongest in Python 2 for 2.7 and drops off as you
get further away from that. Support is also probably pretty good for
@@ -165,19 +175,21 @@ that era was minimal)
There is some work to do on the lower end Python versions which is
more difficult for us to handle since we don't have a Python
interpreter for versions 1.5, 1.6, and 2.0.
interpreter for versions 1.6, and 2.0.
In the Python 3 series, Python support is is strongest around 3.4 or
3.3 and drops off as you move further away from those versions. Python
3.6 changes things drastically by using word codes rather than byte
codes. As a result, the jump offset field in a jump instruction
argument has been reduced. This makes the `EXTENDED_ARG` instructions
are now more prevalent in jump instruction; previously they had been
rare. Perhaps to compensate for the additional `EXTENDED_ARG`
instructions, additional jump optimization has been added. So in sum
handling control flow by ad hoc means as is currently done is worse.
3.0 is weird in that it in some ways resembles 2.6 more than it does
3.1 or 2.7. Python 3.6 changes things drastically by using word codes
rather than byte codes. As a result, the jump offset field in a jump
instruction argument has been reduced. This makes the `EXTENDED_ARG`
instructions are now more prevalent in jump instruction; previously
they had been rare. Perhaps to compensate for the additional
`EXTENDED_ARG` instructions, additional jump optimization has been
added. So in sum handling control flow by ad hoc means as is currently
done is worse.
Also, between Python 3.5, 3.6 and 3.7 there have been major changes to the
Between Python 3.5, 3.6 and 3.7 there have been major changes to the
`MAKE_FUNCTION` and `CALL_FUNCTION` instructions.
Currently not all Python magic numbers are supported. Specifically in
@@ -203,11 +215,12 @@ There is lots to do, so please dig in and help.
See Also
--------
* https://github.com/zrax/pycdc : supports all versions of Python and is written in C++. Support for later Python 3 versions is a bit lacking though.
* https://code.google.com/archive/p/unpyc3/ : supports Python 3.2 only. The above projects use a different decompiling technique than what is used here.
* https://github.com/figment/unpyc3/ : fork of above, but supports Python 3.3 only. Includes some fixes like supporting function annotations
* The HISTORY_ file.
* https://github.com/zrax/pycdc : purports to support all versions of Python. It is written in C++ and is most accurate for Python versions around 2.7 and 3.3 when the code was more actively developed. Accuracy for more recent versions of Python 3 and early versions of Python are especially lacking. See its `issue tracker <https://github.com/zrax/pycdc/issues>`_ for details. Currently lightly maintained.
* https://code.google.com/archive/p/unpyc3/ : supports Python 3.2 only. The above projects use a different decompiling technique than what is used here. Currently unmaintained.
* https://github.com/figment/unpyc3/ : fork of above, but supports Python 3.3 only. Includes some fixes like supporting function annotations. Currently unmaintained.
* https://github.com/wibiti/uncompyle2 : supports Python 2.7 only, but does that fairly well. There are situtations where `uncompyle6` results are incorrect while `uncompyle2` results are not, but more often uncompyle6 is correct when uncompyle2 is not. Because `uncompyle6` adheres to accuracy over idiomatic Python, `uncompyle2` can produce more natural-looking code when it is correct. Currently `uncompyle2` is lightly maintained. See its issue `tracker <https://github.com/wibiti/uncompyle2/issues>`_ for more details
* `How to report a bug <https://github.com/rocky/python-uncompyle6/blob/master/HOW-TO-REPORT-A-BUG.md>`_
* The HISTORY_ file.
* https://github.com/rocky/python-xdis : Cross Python version disassembler
* https://github.com/rocky/python-xasm : Cross Python version assembler
* https://github.com/rocky/python-uncompyle6/wiki : Wiki Documents which describe the code and aspects of it in more detail
@@ -225,3 +238,6 @@ See Also
.. _PJOrion: http://www.koreanrandom.com/forum/topic/15280-pjorion-%D1%80%D0%B5%D0%B4%D0%B0%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D0%BA%D0%BE%D0%BC%D0%BF%D0%B8%D0%BB%D1%8F%D1%86%D0%B8%D1%8F-%D0%B4%D0%B5%D0%BA%D0%BE%D0%BC%D0%BF%D0%B8%D0%BB%D1%8F%D1%86%D0%B8%D1%8F-%D0%BE%D0%B1%D1%84
.. _Deobfuscator: https://github.com/extremecoders-re/PjOrion-Deobfuscator
.. _Py2EXE: https://en.wikipedia.org/wiki/Py2exe
.. |Supported Python Versions| image:: https://img.shields.io/pypi/pyversions/uncompyle6.svg
.. |Latest Version| image:: https://badge.fury.io/py/uncompyle6.svg
:target: https://badge.fury.io/py/uncompyle6

View File

@@ -35,6 +35,7 @@ classifiers = ['Development Status :: 5 - Production/Stable',
'Programming Language :: Python :: 2.5',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.0',
'Programming Language :: Python :: 3.1',
'Programming Language :: Python :: 3.2',
'Programming Language :: Python :: 3.3',
@@ -55,8 +56,8 @@ entry_points = {
'pydisassemble=uncompyle6.bin.pydisassemble:main',
]}
ftp_url = None
install_requires = ['spark-parser >= 1.8.5, < 1.9.0',
'xdis >= 3.7.0, < 3.8.0', 'six']
install_requires = ['spark-parser >= 1.8.7, < 1.9.0',
'xdis >= 3.8.8, < 3.9.0']
license = 'GPL3'
mailing_list = 'python-debugger@googlegroups.com'

View File

@@ -16,6 +16,7 @@ if ! source ./setup-master.sh ; then
fi
cd ..
for version in $PYVERSIONS; do
echo --- $version ---
if ! pyenv local $version ; then
exit $?
fi
@@ -23,4 +24,5 @@ for version in $PYVERSIONS; do
if ! make check; then
exit $?
fi
echo === $version ===
done

View File

@@ -15,6 +15,7 @@ fi
cd ..
for version in $PYVERSIONS; do
echo --- $version ---
if ! pyenv local $version ; then
exit $?
fi
@@ -22,4 +23,5 @@ for version in $PYVERSIONS; do
if ! make check ; then
exit $?
fi
echo === $version ===
done

15
admin-tools/pycdc-runtests.sh Executable file
View File

@@ -0,0 +1,15 @@
#!/bin/bash
# Use pycdc to run our test/bytecode* test suite
bs=${BASH_SOURCE[0]}
testdir=$(dirname $bs)/../test
fulldir=$(readlink -f $testdir)
cd $fulldir
for dir in bytecode_* ; do
echo ========= $dir ================
cd $fulldir/$dir
for file in *.pyc; do
if ! pycdc $file > /dev/null ; then
echo ----- $dir/$file ------
fi
done
done

View File

@@ -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.5.5 3.6.4 2.6.9 3.3.7 2.7.14 3.4.8'
export PYVERSIONS='3.5.5 3.6.6 3.7.1 2.6.9 3.3.7 2.7.15 3.2.6 3.1.5 3.4.8'

View File

@@ -1,5 +1,5 @@
#!/bin/bash
PYTHON_VERSION=3.6.4
PYTHON_VERSION=3.6.5
# FIXME put some of the below in a common routine
function finish {

View File

@@ -0,0 +1,32 @@
#!/bin/bash
# Use pycdc to run our test/bytecode_2.7* test suite
bs=${BASH_SOURCE[0]}
topdir=$(dirname $bs)/..
(cd $topdir && pyenv local 2.7.14)
testdir=$topdir/test
fulldir=$(readlink -f $testdir)
cd $fulldir
for bytecode in bytecode_2.7/*.pyc ; do
echo $bytecode
uncompyle2 $bytecode > /dev/null
echo ================ $bytecode rc: $? ==============
done
tmpdir=/tmp/test-2.7
( cd bytecode_2.7_run &&
mkdir $tmpdir || true
for bytecode in *.pyc ; do
shortname=$(basename $bytecode .pyc)
echo $bytecode
py_file=${tmpdir}/${shortname}.py
typeset -i rc=0
uncompyle2 $bytecode > $py_file
rc=$?
if (( rc == 0 )); then
python $py_file
rc=$?
fi
echo ================ $bytecode rc: $rc ==============
done
)

View File

@@ -47,7 +47,7 @@ install:
# Upgrade to the latest version of pip to avoid it displaying warnings
# about it being out of date.
- "pip install --disable-pip-version-check --user --upgrade pip"
- "%PYTHON%\\python.exe -m pip install --disable-pip-version-check --user --upgrade pip"
# Install the build dependencies of the project. If some dependencies contain
# compiled extensions and are not provided as pre-built wheel packages,

View File

@@ -1,14 +0,0 @@
machine:
python:
version: 2.7.10
environment:
COMPILE: --compile
dependencies:
override:
- pip install -e .
- pip install pytest==3.2.5 hypothesis
test:
override:
- python ./setup.py develop && make check-2.7
- cd ./test/stdlib && pyenv local 2.7.10 && bash ./runtests.sh 'test_[p-z]*.py'

View File

@@ -1,8 +1,6 @@
#!/usr/bin/env python
from uncompyle6 import PYTHON_VERSION, IS_PYPY
from uncompyle6.scanner import get_scanner
from xdis.bytecode import Bytecode
from array import array
def bug(state, slotstate):
if state:
if slotstate is not None:
@@ -24,16 +22,8 @@ def bug_loop(disassemble, tb=None):
def test_if_in_for():
code = bug.__code__
scan = get_scanner(PYTHON_VERSION)
print(PYTHON_VERSION)
if 2.7 <= PYTHON_VERSION <= 3.0 and not IS_PYPY:
n = scan.setup_code(code)
bytecode = Bytecode(code, scan.opc)
scan.build_lines_data(code, n)
scan.insts = list(bytecode)
scan.offset2inst_index = {}
for i, inst in enumerate(scan.insts):
scan.offset2inst_index[inst.offset] = i
scan.build_prev_op(n)
scan.build_instructions(code)
fjt = scan.find_jump_targets(False)
## FIXME: the data below is wrong.
@@ -48,14 +38,7 @@ def test_if_in_for():
# {'start': 62, 'end': 63, 'type': 'for-else'}]
code = bug_loop.__code__
n = scan.setup_code(code)
bytecode = Bytecode(code, scan.opc)
scan.build_lines_data(code, n)
scan.insts = list(bytecode)
scan.build_prev_op(n)
scan.offset2inst_index = {}
for i, inst in enumerate(scan.insts):
scan.offset2inst_index[inst.offset] = i
scan.build_instructions(code)
fjt = scan.find_jump_targets(False)
assert{64: [42], 67: [42, 42], 42: [16, 41], 19: [6]} == fjt
assert scan.structs == [
@@ -69,14 +52,7 @@ def test_if_in_for():
{'start': 48, 'end': 67, 'type': 'while-loop'}]
elif 3.2 < PYTHON_VERSION <= 3.4:
bytecode = Bytecode(code, scan.opc)
scan.code = array('B', code.co_code)
scan.lines = scan.build_lines_data(code)
scan.build_prev_op()
scan.insts = list(bytecode)
scan.offset2inst_index = {}
for i, inst in enumerate(scan.insts):
scan.offset2inst_index[inst.offset] = i
scan.build_instructions(code)
fjt = scan.find_jump_targets(False)
assert {69: [66], 63: [18]} == fjt
assert scan.structs == \
@@ -86,5 +62,6 @@ def test_if_in_for():
{'end': 59, 'type': 'for-loop', 'start': 31},
{'end': 63, 'type': 'for-else', 'start': 62}]
else:
assert True, "FIXME: should note fixed"
print("FIXME: should fix for %s" % PYTHON_VERSION)
assert True
return

View File

@@ -1,150 +1,154 @@
# std
import os
# test
import pytest
import hypothesis
from hypothesis import strategies as st
# uncompyle6
from uncompyle6 import PYTHON_VERSION, deparse_code
import pytest
pytestmark = pytest.mark.skipif(PYTHON_VERSION <= 2.6,
reason='hypothesis needs 2.7 or later')
if PYTHON_VERSION > 2.6:
import hypothesis
from hypothesis import strategies as st
# uncompyle6
@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 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:
@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" | "%"
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
See https://docs.python.org/2/library/string.html
:param draw: Let hypothesis draw from other strategies.
: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 ''
: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'
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 ''
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)
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 ''
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 = ''
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_,))
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
@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.
: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)
: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
@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') + ')'
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')
@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)
@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)

View File

@@ -1,175 +1,185 @@
# std
import string
# 3rd party
from hypothesis import given, assume, example, settings, strategies as st
from uncompyle6 import PYTHON_VERSION
import pytest
# uncompyle
from validate import validate_uncompyle
from test_fstring import expressions
pytestmark = pytest.mark.skip(PYTHON_VERSION < 2.7,
reason="need at least Python 2.7")
if PYTHON_VERSION > 2.6:
from hypothesis import given, assume, example, settings, strategies as st
from validate import validate_uncompyle
from test_fstring import expressions
alpha = st.sampled_from(string.ascii_lowercase)
numbers = st.sampled_from(string.digits)
alphanum = st.sampled_from(string.ascii_lowercase + string.digits)
alpha = st.sampled_from(string.ascii_lowercase)
numbers = st.sampled_from(string.digits)
alphanum = st.sampled_from(string.ascii_lowercase + string.digits)
@st.composite
def function_calls(draw,
min_keyword_args=0, max_keyword_args=5,
min_positional_args=0, max_positional_args=5,
min_star_args=0, max_star_args=1,
min_double_star_args=0, max_double_star_args=1):
"""
Strategy factory for generating function calls.
:param draw: Callable which draws examples from other strategies.
:return: The function call text.
"""
st_positional_args = st.lists(
alpha,
min_size=min_positional_args,
max_size=max_positional_args
)
st_keyword_args = st.lists(
alpha,
min_size=min_keyword_args,
max_size=max_keyword_args
)
st_star_args = st.lists(
alpha,
min_size=min_star_args,
max_size=max_star_args
)
st_double_star_args = st.lists(
alpha,
min_size=min_double_star_args,
max_size=max_double_star_args
)
positional_args = draw(st_positional_args)
keyword_args = draw(st_keyword_args)
st_values = st.lists(
expressions(),
min_size=len(keyword_args),
max_size=len(keyword_args)
)
keyword_args = [
x + '=' + e
for x, e in
zip(keyword_args, draw(st_values))
]
star_args = ['*' + x for x in draw(st_star_args)]
double_star_args = ['**' + x for x in draw(st_double_star_args)]
arguments = positional_args + keyword_args + star_args + double_star_args
draw(st.randoms()).shuffle(arguments)
arguments = ','.join(arguments)
function_call = 'fn({arguments})'.format(arguments=arguments)
try:
# TODO: Figure out the exact rules for ordering of positional, keyword,
# star args, double star args and in which versions the various
# types of arguments are supported so we don't need to check that the
# expression compiles like this.
compile(function_call, '<string>', 'single')
except:
assume(False)
return function_call
@st.composite
def function_calls(draw,
min_keyword_args=0, max_keyword_args=5,
min_positional_args=0, max_positional_args=5,
min_star_args=0, max_star_args=1,
min_double_star_args=0, max_double_star_args=1):
"""
Strategy factory for generating function calls.
def test_function_no_args():
validate_uncompyle("fn()")
:param draw: Callable which draws examples from other strategies.
@pytest.mark.skipif(PYTHON_VERSION < 2.7,
reason="need at least Python 2.7")
def isolated_function_calls(which):
"""
Returns a strategy for generating function calls, but isolated to
particular types of arguments, for example only positional arguments.
:return: The function call text.
"""
st_positional_args = st.lists(
alpha,
min_size=min_positional_args,
max_size=max_positional_args
)
st_keyword_args = st.lists(
alpha,
min_size=min_keyword_args,
max_size=max_keyword_args
)
st_star_args = st.lists(
alpha,
min_size=min_star_args,
max_size=max_star_args
)
st_double_star_args = st.lists(
alpha,
min_size=min_double_star_args,
max_size=max_double_star_args
)
This can help reason about debugging errors in specific types of function
calls.
positional_args = draw(st_positional_args)
keyword_args = draw(st_keyword_args)
st_values = st.lists(
expressions(),
min_size=len(keyword_args),
max_size=len(keyword_args)
)
keyword_args = [
x + '=' + e
for x, e in
zip(keyword_args, draw(st_values))
]
star_args = ['*' + x for x in draw(st_star_args)]
double_star_args = ['**' + x for x in draw(st_double_star_args)]
:param which: One of 'keyword', 'positional', 'star', 'double_star'
arguments = positional_args + keyword_args + star_args + double_star_args
draw(st.randoms()).shuffle(arguments)
arguments = ','.join(arguments)
function_call = 'fn({arguments})'.format(arguments=arguments)
try:
# TODO: Figure out the exact rules for ordering of positional, keyword,
# star args, double star args and in which versions the various
# types of arguments are supported so we don't need to check that the
# expression compiles like this.
compile(function_call, '<string>', 'single')
except:
assume(False)
return function_call
:return: Strategy for generating an function call isolated to specific
argument types.
"""
kwargs = dict(
max_keyword_args=0,
max_positional_args=0,
max_star_args=0,
max_double_star_args=0,
)
kwargs['_'.join(('min', which, 'args'))] = 1
kwargs['_'.join(('max', which, 'args'))] = 5 if 'star' not in which else 1
return function_calls(**kwargs)
def test_function_no_args():
validate_uncompyle("fn()")
with settings(max_examples=25):
@pytest.mark.skipif(PYTHON_VERSION < 2.7,
reason="need at least Python 2.7")
@given(isolated_function_calls('positional'))
@example("fn(0)")
def test_function_positional_only(expr):
validate_uncompyle(expr)
@pytest.mark.skipif(PYTHON_VERSION < 2.7,
reason="need at least Python 2.7")
@given(isolated_function_calls('keyword'))
@example("fn(a=0)")
def test_function_call_keyword_only(expr):
validate_uncompyle(expr)
@pytest.mark.skipif(PYTHON_VERSION < 2.7,
reason="need at least Python 2.7")
@given(isolated_function_calls('star'))
@example("fn(*items)")
def test_function_call_star_only(expr):
validate_uncompyle(expr)
@pytest.mark.skipif(PYTHON_VERSION < 2.7,
reason="need at least Python 2.7")
@given(isolated_function_calls('double_star'))
@example("fn(**{})")
def test_function_call_double_star_only(expr):
validate_uncompyle(expr)
def isolated_function_calls(which):
"""
Returns a strategy for generating function calls, but isolated to
particular types of arguments, for example only positional arguments.
This can help reason about debugging errors in specific types of function
calls.
:param which: One of 'keyword', 'positional', 'star', 'double_star'
:return: Strategy for generating an function call isolated to specific
argument types.
"""
kwargs = dict(
max_keyword_args=0,
max_positional_args=0,
max_star_args=0,
max_double_star_args=0,
)
kwargs['_'.join(('min', which, 'args'))] = 1
kwargs['_'.join(('max', which, 'args'))] = 5 if 'star' not in which else 1
return function_calls(**kwargs)
@pytest.mark.xfail()
def test_BUILD_CONST_KEY_MAP_BUILD_MAP_UNPACK_WITH_CALL_BUILD_TUPLE_CALL_FUNCTION_EX():
validate_uncompyle("fn(w=0,m=0,**v)")
with settings(max_examples=25):
@given(isolated_function_calls('positional'))
@example("fn(0)")
def test_function_positional_only(expr):
validate_uncompyle(expr)
@given(isolated_function_calls('keyword'))
@example("fn(a=0)")
def test_function_call_keyword_only(expr):
validate_uncompyle(expr)
@given(isolated_function_calls('star'))
@example("fn(*items)")
def test_function_call_star_only(expr):
validate_uncompyle(expr)
@given(isolated_function_calls('double_star'))
@example("fn(**{})")
def test_function_call_double_star_only(expr):
validate_uncompyle(expr)
@pytest.mark.xfail()
def test_BUILD_MAP_BUILD_MAP_UNPACK_WITH_CALL_BUILD_TUPLE_CALL_FUNCTION_EX():
validate_uncompyle("fn(a=0,**g)")
@pytest.mark.xfail()
def test_BUILD_CONST_KEY_MAP_BUILD_MAP_UNPACK_WITH_CALL_BUILD_TUPLE_CALL_FUNCTION_EX():
validate_uncompyle("fn(w=0,m=0,**v)")
@pytest.mark.xfail()
def test_CALL_FUNCTION_EX():
validate_uncompyle("fn(*g,**j)")
@pytest.mark.xfail()
def test_BUILD_MAP_BUILD_MAP_UNPACK_WITH_CALL_BUILD_TUPLE_CALL_FUNCTION_EX():
validate_uncompyle("fn(a=0,**g)")
@pytest.mark.xfail()
def test_BUILD_MAP_CALL_FUNCTION_EX():
validate_uncompyle("fn(*z,u=0)")
@pytest.mark.xfail()
def test_CALL_FUNCTION_EX():
validate_uncompyle("fn(*g,**j)")
@pytest.mark.xfail()
def test_BUILD_TUPLE_CALL_FUNCTION_EX():
validate_uncompyle("fn(**a)")
@pytest.mark.xfail()
def test_BUILD_MAP_CALL_FUNCTION_EX():
validate_uncompyle("fn(*z,u=0)")
@pytest.mark.xfail()
def test_BUILD_MAP_BUILD_TUPLE_BUILD_TUPLE_UNPACK_WITH_CALL_CALL_FUNCTION_EX():
validate_uncompyle("fn(b,b,b=0,*a)")
@pytest.mark.xfail()
def test_BUILD_TUPLE_CALL_FUNCTION_EX():
validate_uncompyle("fn(**a)")
@pytest.mark.xfail()
def test_BUILD_TUPLE_BUILD_TUPLE_UNPACK_WITH_CALL_CALL_FUNCTION_EX():
validate_uncompyle("fn(*c,v)")
@pytest.mark.xfail()
def test_BUILD_MAP_BUILD_TUPLE_BUILD_TUPLE_UNPACK_WITH_CALL_CALL_FUNCTION_EX():
validate_uncompyle("fn(b,b,b=0,*a)")
@pytest.mark.xfail()
def test_BUILD_CONST_KEY_MAP_CALL_FUNCTION_EX():
validate_uncompyle("fn(i=0,y=0,*p)")
@pytest.mark.xfail()
def test_BUILD_TUPLE_BUILD_TUPLE_UNPACK_WITH_CALL_CALL_FUNCTION_EX():
validate_uncompyle("fn(*c,v)")
@pytest.mark.xfail()
def test_BUILD_CONST_KEY_MAP_CALL_FUNCTION_EX():
validate_uncompyle("fn(i=0,y=0,*p)")
@pytest.mark.skip(reason='skipping property based test until all individual tests are passing')
@given(function_calls())
def test_function_call(function_call):
validate_uncompyle(function_call)
@pytest.mark.skip(reason='skipping property based test until all individual tests are passing')
@given(function_calls())
def test_function_call(function_call):
validate_uncompyle(function_call)

View File

@@ -18,46 +18,46 @@ def test_grammar():
right_recursive, dup_rhs) = p.check_sets()
# We have custom rules that create the below
expect_lhs = set(['expr1024', 'pos_arg', 'get_iter', 'attribute'])
expect_lhs = set(['pos_arg', 'get_iter', 'attribute'])
unused_rhs = set(['list', 'mkfunc',
'mklambda',
'unpack',])
expect_right_recursive = set([('designList',
('store', 'DUP_TOP', 'designList'))])
if PYTHON3:
expect_lhs.add('load_genexpr')
if PYTHON_VERSION != 3.7:
unused_rhs.add('call')
if PYTHON_VERSION > 2.6:
expect_lhs.add('kvlist')
expect_lhs.add('kv3')
unused_rhs.add('dict')
if PYTHON3:
expect_lhs.add('load_genexpr')
unused_rhs = unused_rhs.union(set("""
except_pop_except generator_exp classdefdeco2
dict
except_pop_except generator_exp
""".split()))
if PYTHON_VERSION >= 3.0:
expect_lhs.add("annotate_arg")
expect_lhs.add("annotate_tuple")
unused_rhs.add("mkfunc_annotate")
unused_rhs.add('call')
if PYTHON_VERSION < 3.6:
# 3.6 has at least one non-custom call rule
# the others don't
unused_rhs.add('call')
if PYTHON_VERSION == 3.5:
expect_right_recursive.add((('l_stmts',
('lastl_stmt', 'COME_FROM', 'l_stmts'))))
pass
unused_rhs.add("dict_comp")
unused_rhs.add("classdefdeco1")
if PYTHON_VERSION >= 3.5:
expect_right_recursive.add((('l_stmts',
('lastl_stmt', 'come_froms', 'l_stmts'))))
pass
else:
elif 3.0 < PYTHON_VERSION < 3.3:
expect_right_recursive.add((('l_stmts',
('lastl_stmt', 'COME_FROM', 'l_stmts'))))
# expect_lhs.add('kwargs1')
pass
pass
pass
else:
expect_lhs.add('kwarg')
unused_rhs.add('call')
assert expect_lhs == set(lhs)
assert unused_rhs == set(rhs)
@@ -85,6 +85,8 @@ def test_grammar():
""".split())
if 2.6 <= PYTHON_VERSION <= 2.7:
opcode_set = set(s.opc.opname).union(ignore_set)
if PYTHON_VERSION == 2.6:
opcode_set.add("THEN")
check_tokens(tokens, opcode_set)
elif PYTHON_VERSION == 3.4:
ignore_set.add('LOAD_CLASSNAME')

View File

@@ -1,19 +1,22 @@
import pytest
from uncompyle6 import PYTHON_VERSION, PYTHON3, deparse_code
from uncompyle6 import PYTHON_VERSION, code_deparse
pytestmark = pytest.mark.skip(PYTHON_VERSION < 2.7,
reason="need at least Python 2.7")
def test_single_mode():
single_expressions = (
'i = 1',
'i and (j or k)',
'i += 1',
'i = j % 4',
'i = {}',
'i = []',
'for i in range(10):\n i\n',
'for i in range(10):\n for j in range(10):\n i + j\n',
'try:\n i\nexcept Exception:\n j\nelse:\n k\n'
)
if PYTHON_VERSION > 2.6:
def test_single_mode():
single_expressions = (
'i = 1',
'i and (j or k)',
'i += 1',
'i = j % 4',
'i = {}',
'i = []',
'for i in range(10):\n i\n',
'for i in range(10):\n for j in range(10):\n i + j\n',
'try:\n i\nexcept Exception:\n j\nelse:\n k\n'
)
for expr in single_expressions:
code = compile(expr + '\n', '<string>', 'single')
assert deparse_code(PYTHON_VERSION, code, compile_mode='single').text == expr + '\n'
for expr in single_expressions:
code = compile(expr + '\n', '<string>', 'single')
assert code_deparse(code, compile_mode='single').text == expr + '\n'

View File

@@ -6,16 +6,19 @@ import difflib
import subprocess
import tempfile
import functools
# compatability
import six
# uncompyle6 / xdis
from uncompyle6 import PYTHON_VERSION, IS_PYPY, deparse_code
from uncompyle6 import PYTHON_VERSION, PYTHON3, IS_PYPY, deparse_code
# TODO : I think we can get xdis to support the dis api (python 3 version) by doing something like this there
from xdis.bytecode import Bytecode
from xdis.main import get_opcode
opc = get_opcode(PYTHON_VERSION, IS_PYPY)
Bytecode = functools.partial(Bytecode, opc=opc)
import six
if PYTHON3:
from io import StringIO
else:
from StringIO import StringIO
def _dis_to_text(co):
return Bytecode(co).dis()

View File

@@ -1,3 +1,2 @@
pytest>=3.0.0
flake8
hypothesis<=3.8.3
hypothesis<=3.0.0

View File

@@ -1,2 +1,4 @@
# Pick up stuff from setup.py
hypothesis==2.0.0
pytest
-e .

View File

@@ -4,12 +4,12 @@ import sys
"""Setup script for the 'uncompyle6' distribution."""
SYS_VERSION = sys.version_info[0:2]
if not ((2, 6) <= SYS_VERSION <= (3, 7)) or ((3, 0) <= SYS_VERSION <= (3, 1)):
mess = "Python Release 2.6 .. 3.7 excluding 3.0 and 3.1 are supported in this code branch."
if not ((2, 6) <= SYS_VERSION <= (3, 7)):
mess = "Python Release 2.6 .. 3.7 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])
elif SYS_VERSION < (2, 4) or ((3, 0) <= SYS_VERSION <= (3, 1)):
elif SYS_VERSION < (2, 4):
mess += ("\nThis package is not supported for Python version %s."
% sys.version[0:3])
print(mess)

1
test/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/nohup.out

View File

@@ -1,12 +1,13 @@
PHONY=check clean dist distclean test test-unit test-functional rmChangeLog clean_pyc nosetests \
check-bytecode-1.5 check-bytecode-1 check-bytecode-2 check-bytecode-3 \
check-bytecode-1 check-bytecode-1.3 check-bytecode-1.4 check-bytecode-1.5 \
check-bytecode-2 check-bytecode-3 check-bytecode-3-short \
check-bytecode-2.2 check-byteocde-2.3 check-bytecode-2.4 \
check-short check-2.6 check-2.7 check-3.0 check-3.1 check-3.2 check-3.3 \
check-3.4 check-3.5 check-5.6 5.6 5.8 \
grammar-coverage-2.5 grammar-coverage-2.6 grammarcoverage-2.7 \
grammar-coverage-3.1 grammar-coverage-3.2 grammarcoverage-3.3 \
grammar-coverage-3.4 grammar-coverage-3.5 grammarcoverage-3.6
check-3.4 check-3.5 check-3.6 check-3.7 check-5.6 5.6 5.8 \
grammar-coverage-2.5 grammar-coverage-2.6 grammar-coverage-2.7 \
grammar-coverage-3.1 grammar-coverage-3.2 grammar-coverage-3.3 \
grammar-coverage-3.4 grammar-coverage-3.5 grammar-coverage-3.6 \
grammar-coverage-3.7
GIT2CL ?= git2cl
PYTHON ?= python
@@ -21,7 +22,7 @@ COVER_DIR=../tmp/grammar-cover
# Run short tests
check-short:
@$(PYTHON) -V && PYTHON_VERSION=`$(PYTHON) -V 2>&1 | cut -d ' ' -f 2 | cut -d'.' -f1,2`; \
$(MAKE) check-bytecode
$(MAKE) check-bytecode-short
# Run all tests
check:
@@ -33,22 +34,27 @@ 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
#: 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
#: 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
#: 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
#: 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
#: Run working tests from Python 3.5
check-3.5: check-bytecode
@@ -59,6 +65,10 @@ check-3.5: check-bytecode
check-3.6: check-bytecode
$(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)
# FIXME
#: this is called when running under pypy3.5-5.8.0 or pypy2-5.6.0
5.8 5.6:
@@ -68,7 +78,7 @@ check-disasm:
$(PYTHON) dis-compare.py
#: Check deparsing bytecode 1.x only
check-bytecode-1: check-bytecode-1.5
check-bytecode-1: check-bytecode-1.4 check-bytecode-1.5
#: Check deparsing bytecode 2.x only
check-bytecode-2:
@@ -82,14 +92,35 @@ check-bytecode-3:
--bytecode-3.1 --bytecode-3.2 --bytecode-3.3 \
--bytecode-3.4 --bytecode-3.5 --bytecode-3.6 --bytecode-pypy3.2
#: Check deparsing bytecode that works running Python 2 and Python 3
#: Check deparsing on selected bytecode 3.x
check-bytecode-3-short:
$(PYTHON) test_pythonlib.py \
--bytecode-3.4 --bytecode-3.5 --bytecode-3.6
#: Check deparsing bytecode on all Python 2 and Python 3 versions
check-bytecode: check-bytecode-3
$(PYTHON) test_pythonlib.py \
--bytecode-1.3 --bytecode-1.4 --bytecode-1.5 \
--bytecode-2.2 --bytecode-2.3 --bytecode-2.4 \
--bytecode-2.1 --bytecode-2.2 --bytecode-2.3 --bytecode-2.4 \
--bytecode-2.5 --bytecode-2.6 --bytecode-2.7 \
--bytecode-pypy2.7
#: Check deparsing bytecode on selected Python 2 and Python 3 versions
check-bytecode-short: check-bytecode-3-short
$(PYTHON) test_pythonlib.py \
--bytecode-2.6 --bytecode-2.7 --bytecode-pypy2.7
#: Check deparsing bytecode 1.3 only
check-bytecode-1.3:
$(PYTHON) test_pythonlib.py --bytecode-1.3
#: Check deparsing bytecode 1.4 only
check-bytecode-1.4:
$(PYTHON) test_pythonlib.py --bytecode-1.4
#: Check deparsing bytecode 1.5 only
check-bytecode-1.5:
$(PYTHON) test_pythonlib.py --bytecode-1.5
@@ -114,23 +145,29 @@ check-bytecode-2.4:
check-bytecode-2.5:
$(PYTHON) test_pythonlib.py --bytecode-2.5
#: Get grammar coverage for Python 2.4
grammar-coverage-2.4:
-rm $(COVER_DIR)/spark-grammar-24.cover
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-2.4.cover $(PYTHON) test_pythonlib.py --bytecode-2.4
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-2.4.cover $(PYTHON) test_pyenvlib.py --2.4.6 --max= 800
#: Get grammar coverage for Python 2.5
grammar-coverage-2.5:
-rm $(COVER_DIR)/spark-grammar-25.cover
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-25.cover $(PYTHON) test_pythonlib.py --bytecode-2.5
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-25.cover $(PYTHON) test_pyenvlib.py --2.5.6
-rm $(COVER_DIR)/spark-grammar-2.5.cover || true
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-2.5.cover $(PYTHON) test_pythonlib.py --bytecode-2.5
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-2.5.cover $(PYTHON) test_pyenvlib.py --2.5.6 --max=800
#: Get grammar coverage for Python 2.6
grammar-coverage-2.6:
-rm $(COVER_DIR)/spark-grammar-26.cover
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-26.cover $(PYTHON) test_pythonlib.py --bytecode-2.6
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-26.cover $(PYTHON) test_pyenvlib.py --2.6.9
-rm $(COVER_DIR)/spark-grammar-2.6.cover || true
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-2.6.cover $(PYTHON) test_pythonlib.py --bytecode-2.6
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-2.6.cover $(PYTHON) test_pyenvlib.py --2.6.9 --max=800
#: Get grammar coverage for Python 2.7
grammar-coverage-2.7:
-rm $(COVER_DIR)/spark-grammar-27.cover
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-27.cover $(PYTHON) test_pythonlib.py --bytecode-2.7
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-27.cover $(PYTHON) test_pyenvlib.py --2.7.13
-rm $(COVER_DIR)/spark-grammar-2.7.cover || true
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-2.7.cover $(PYTHON) test_pythonlib.py --bytecode-2.7
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-2.7.cover $(PYTHON) test_pyenvlib.py --2.7.14 --max=600
#: Get grammar coverage for Python 3.0
grammar-coverage-3.0:
@@ -141,33 +178,39 @@ SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-30.cover $(PYTHON) test_pythonl
#: Get grammar coverage for Python 3.1
grammar-coverage-3.1:
-rm $(COVER_DIR)/spark-grammar-31.cover
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-31.cover $(PYTHON) test_pythonlib.py --bytecode-3.1
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-31.cover $(PYTHON) test_pyenvlib.py --3.1.5
-rm $(COVER_DIR)/spark-grammar-3.1.cover
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-3.1.cover $(PYTHON) test_pythonlib.py --bytecode-3.1
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-3.1.cover $(PYTHON) test_pyenvlib.py --3.1.5
#: Get grammar coverage for Python 3.2
grammar-coverage-3.2:
-rm $(COVER_DIR)/spark-grammar-32.cover
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-32.cover $(PYTHON) test_pythonlib.py --bytecode-3.2
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-32.cover $(PYTHON) test_pyenvlib.py --3.2.6
-rm $(COVER_DIR)/spark-grammar-3.2.cover || true
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-3.2.cover $(PYTHON) test_pythonlib.py --bytecode-3.2
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-3.2.cover $(PYTHON) test_pyenvlib.py --3.2.6
#: Get grammar coverage for Python 3.3
grammar-coverage-3.3:
-rm $(COVER_DIR)/spark-grammar-33.cover
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-33.cover $(PYTHON) test_pythonlib.py --bytecode-3.3
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-33.cover $(PYTHON) test_pyenvlib.py --3.3.6
-rm $(COVER_DIR)/spark-grammar-3.3.cover || true
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-3.3.cover $(PYTHON) test_pythonlib.py --bytecode-3.3
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-3.3.cover $(PYTHON) test_pyenvlib.py --3.3.7 --max=800
#: Get grammar coverage for Python 3.4
grammar-coverage-3.4:
-rm $(COVER_DIR)/spark-grammar-34.cover
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-34.cover $(PYTHON) test_pythonlib.py --bytecode-3.4
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-34.cover $(PYTHON) test_pyenvlib.py --3.4.2
-rm $(COVER_DIR)/spark-grammar-3.4.cover || true
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-3.4.cover $(PYTHON) test_pythonlib.py --bytecode-3.4
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-3.4.cover $(PYTHON) test_pyenvlib.py --3.4.8 --max=800
#: Get grammar coverage for Python 3.5
grammar-coverage-3.5:
rm $(COVER_DIR)/spark-grammar-35.cover || /bin/true
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-35.cover $(PYTHON) test_pythonlib.py --bytecode-3.5
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-35.cover $(PYTHON) test_pyenvlib.py --3.5.3
rm $(COVER_DIR)/spark-grammar-3.5.cover || /bin/true
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-3.5.cover $(PYTHON) test_pythonlib.py --bytecode-3.5
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-3.5.cover $(PYTHON) test_pyenvlib.py --3.5.5 --max=450
#: Get grammar coverage for Python 3.6
grammar-coverage-3.6:
rm $(COVER_DIR)/spark-grammar-3.6.cover || /bin/true
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-3.6.cover $(PYTHON) test_pythonlib.py --bytecode-3.6
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-3.6.cover $(PYTHON) test_pyenvlib.py --3.6.4 --max=280
#: Check deparsing Python 2.6
check-bytecode-2.6:
@@ -182,14 +225,17 @@ check-bytecode-2.7:
#: 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
#: 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
#: 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
#: Check deparsing Python 3.3
check-bytecode-3.3:
@@ -211,6 +257,10 @@ check-bytecode-3.6:
$(PYTHON) test_pythonlib.py --bytecode-3.6 --weak-verify
$(PYTHON) test_pythonlib.py --bytecode-3.6-run --verify-run
#: Check deparsing Python 3.7
check-bytecode-3.7:
$(PYTHON) test_pythonlib.py --bytecode-3.7 --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)
@@ -237,7 +287,7 @@ check-3.4-ok:
2.6:
#: PyPy 5.0.x with Python 2.7 ...
pypy-2.7 5.0 5.3:
pypy-2.7 5.0 5.3 6.0:
$(PYTHON) test_pythonlib.py --bytecode-pypy2.7 --verify
#: PyPy 2.4.x with Python 3.2 ...

Binary file not shown.

Binary file not shown.

Binary file not shown.

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_1.4/cmp.pyc Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
test/bytecode_1.4/emacs.pyc Normal file

Binary file not shown.

BIN
test/bytecode_1.4/glob.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.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,5 +1,5 @@
These are byte-compiled programs compiled by Python 2.4
Furthrmore the programs here are self-checking: when decompiled and
then run again in a 2.4 interpreter, they will give an error if they
Furthermore, the programs here are self-checking: when decompiled and
then run again in a 2.4 interpreter, they are likely to give an error when they
are miscompiled.

View File

@@ -1,5 +1,5 @@
These are byte-compiled programs compiled by Python 2.5.
Furthrmore the programs here are self-checking: when decompiled and
then run again in a 2.5 interpreter, they will give an error if they
are miscompiled.
Furthermore the programs here are self-checking: when decompiled and
then run again in a 2.5 interpreter, they are likely to give an error
when they are miscompiled.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,5 +1,5 @@
These are byte-compiled programs compiled by Python 2.6.
Furthrmore the programs here are self-checking: when decompiled and
then run again in a 2.6 interpreter, they will give an error if they
are miscompiled.
Furthermore the programs here are self-checking: when decompiled and
then run again in a 2.6 interpreter, they are likely to give an error
when they are miscompiled.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,5 +1,5 @@
These are byte-compiled programs compiled by Python 2.7.
Furthrmore the programs here are self-checking: when decompiled and
then run again in a 2.7 interpreter, they will give an error if they
are miscompiled.
Furthermore, the programs here are self-checking: when decompiled and
then run again in a 2.7 interpreter, they are likely to give an error
when they are miscompiled.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,5 +1,5 @@
These are byte-compiled programs compiled by Python 3.0.
Furthrmore the programs here are self-checking: when decompiled and
then run again in a 3.0 interpreter, they will give an error if they
are miscompiled.
Furthermore, the programs here are self-checking: when decompiled and
then run again in a 3.0 interpreter, they are likely to give an error
when they are miscompiled.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,5 +1,5 @@
These are byte-compiled programs compiled by Python 3.1.
Furthrmore the programs here are self-checking: when decompiled and
then run again in a 3.1 interpreter, they will give an error if they
are miscompiled.
Furthrmore, the programs here are self-checking: when decompiled and
then run again in a 3.1 interpreter, they are likely to give an error
when they are miscompiled.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More