Compare commits

..

202 Commits

Author SHA1 Message Date
rocky
06edeeeb46 Get ready for release 2.4.0 2016-05-18 12:46:23 -04:00
rocky
b629a0c5df Add 3.5 to verify 2016-05-18 10:59:57 -04:00
rocky
a08ece371e pydisassemble improvements; DRY scannners
disas.py:
 - disassembles *all* code objects found

scanner*.py:
 - no longer need to pass in version numbers; this
   is obtained from the class name
 - no longer pass in opcodes; this is done at
   initialization from the scanner name
 - all Pythoin 3 scanners support native disassembly
2016-05-18 10:58:48 -04:00
rocky
d42f84a59c Go over disassembly routine...
* tok.py:
  - add arg value when it is an integer
* pydisassemble.py:
  - add option -U --uncomplyle for which flavor of disassembly
  - remove -o option
* scanner27.py:
  - allow for native (non-uncompyle6) output
2016-05-17 22:52:16 -04:00
rocky
a3dd61c981 Fix marshal bug in handling complex numbers 2016-05-17 19:25:34 -04:00
rocky
9462e33f48 Fix Python 3.x bugs
* class definitions made via closures
* Add "make check-short" to top-level
* parse3.py: Python 3.3 uses STORE_LOGALS
2016-05-17 04:00:54 -04:00
rocky
f69c76c351 Fix a number of small bugs...
test_peynv.py: make Python3 compatible
marsh.py: remove duplicate test
scanner3.py: fix opcode typo
2016-05-16 21:31:02 -04:00
rocky
09bf364d89 Fix Python 3.x bug in function VAR and KW args 2016-05-16 20:41:22 -04:00
rocky
3d261a38c7 Readd some 3.x loop tests 2016-05-16 20:20:53 -04:00
rocky
bb384bc0b3 pytest for last commit 2016-05-16 19:44:35 -04:00
rocky
09a01dc783 Correct bugs in Python 3.2 source generation 2016-05-16 15:50:45 -04:00
rocky
73d784510a Travis can't handle pytest on Python 3.5 2016-05-16 13:48:00 -04:00
rocky
bdd7df6040 Python 2 loop scanner detection in Python 3
scanner*.py: Make scanner27 and scanner3 more aligned
Makefile: we can run py.test on Python 3.5
HISTORY.md: grammar changes
2016-05-16 13:40:55 -04:00
rocky
134b67d952 Misc small changes
Go over history yet again
code cleanups.
2016-05-16 10:15:55 -04:00
rocky
ebfe5e3ba8 Python3 mklambda bug 2016-05-15 21:16:53 -04:00
rocky
b5eaa9445d Python 3 genexpr bug 2016-05-15 20:59:28 -04:00
rocky
007328b353 Correct info on parser 2016-05-15 19:44:18 -04:00
rocky
6be6632e96 Bug in Python 3.x genexpr 2016-05-15 19:35:45 -04:00
rocky
2c121545f0 Fix bug in Python 3 lambda expression handling
Some other small cleanup changes
2016-05-15 18:14:22 -04:00
rocky
bb31629c35 pydisassemble disassemble without grammar mangling
Some other small cleanups as well
2016-05-15 13:55:21 -04:00
rocky
56dc270145 Fix verify bug in 3.2 2016-05-15 06:40:12 -04:00
rocky
4cba5a28ef 3.4 if/while bug 2016-05-15 05:37:44 -04:00
rocky
e79cecbb71 force Travis 2.7.11 for Python 2.7 2016-05-15 04:28:32 -04:00
rocky
38a5180e02 Add more Python 2.7 verify tests 2016-05-15 04:24:29 -04:00
rocky
2fdcdcb154 Fix bug in kvlist handling on Python 2.7
Created from previous DRY code in Python 3
2016-05-15 03:47:30 -04:00
rocky
b9692c9b1f DRY scanner34 and scanner35
handle 3.0..3.4 build maps as key/value pairs
2016-05-15 03:29:08 -04:00
rocky
b16a166d84 Optimize Python 2/3 code2num 2016-05-15 02:25:39 -04:00
rocky
4da2b8e2ed Python2 comptability in using Python 3 disassembly
Also fixes ablility to run bytecode 3.5 tests from 2.x now

For Python 2 reading python3 bytstrings, we need to
make sure we confer the character to a number.
2016-05-14 20:43:14 -04:00
rocky
1d9ab4e1d1 Start to DRY Python 3.4 and 3.5 scanners 2016-05-14 16:55:44 -04:00
rocky
51df8d8cbe See if travis will take spark 1.2.1 2016-05-14 15:28:16 -04:00
rocky
b69001ccbf Fix names for <program> -V 2016-05-14 00:53:46 -04:00
rocky
8c560a4791 Fix botched entry point names
Get ready for relase 2.3.6
2016-05-14 00:42:13 -04:00
rocky
931eb4a7e5 Get ready for release 2.3.5 2016-05-14 00:13:39 -04:00
rocky
2db380a77f More fragment bugs 2016-05-13 23:55:27 -04:00
rocky
de0ec195b7 More packaging crap.
Did I tell you how much I hate python packaging?

fragments.py: track recent change in class decorators.
2016-05-13 23:35:31 -04:00
rocky
e0eba6998f Python packaging - yet again.
Did I ever mention how much Python sucks at packaging?
2016-05-13 22:59:15 -04:00
rocky
e1a2860013 Test for class decorator
See https://github.com/rocky/python-uncompyle6/pull/15
2016-05-13 16:25:07 -04:00
R. Bernstein
cce40bef21 Merge pull request #15 from Tey/master
Fix for class decorators
2016-05-13 16:18:00 -04:00
Teyut
ca10f5652f Fix for class decorators 2016-05-13 17:59:12 +02:00
rocky
05898dc7cb Back off spark 1.2.0 for now 2016-05-12 13:06:13 -04:00
rocky
37406557bc More small changes 2016-05-12 12:59:31 -04:00
rocky
7929e4b57d Clean up test byte-compile directory 2016-05-12 11:40:54 -04:00
rocky
5babde61c4 Misc changes
Back off of some validation tests for now.
2016-05-12 11:22:00 -04:00
rocky
6f6f1db576 Misc fixups/cleanups
* parse3.py Had botched if-for-else test by grammar addition
* semantics/*.py: Show errorstack in failed parse when -g (requires sparck 1.2.0)
* some optimization in scanner3
2016-05-12 09:27:25 -04:00
R. Bernstein
8d51456f59 Merge pull request #14 from rocky/make-function-rewrite
Make function rewrite
2016-05-12 03:38:19 -04:00
rocky
a6320359c8 Merge branch 'make-function-rewrite' of github.com:rocky/python-uncompyle6 into make-function-rewrite 2016-05-11 20:36:13 -04:00
rocky
631d7be921 Redo make_function for *, arg
main(*, file='foo') and things like that now work
2016-05-11 20:34:20 -04:00
rocky
1e22734b6b WIP Make function redo 2016-05-11 09:53:33 -04:00
rocky
b134d08e91 add pos_arg ::= expr to make params of fns clear 2016-05-10 18:05:25 -04:00
rocky
8a66fd0be3 * call WIP 2016-05-09 20:23:54 -04:00
rocky
9ae45b363f 3.2 class bug 2016-05-09 20:11:25 -04:00
rocky
b287a305ea 3.2 WhileTrue grammar bug 2016-05-09 19:39:37 -04:00
rocky
d823dfb5d3 Python 3 "while True" bug 2016-05-09 14:44:34 -04:00
rocky
378cca27da Dan Pascu's contribution via Dan 2016-05-09 12:47:16 -04:00
rocky
f9dc797aa0 Another history tweak 2016-05-09 12:13:42 -04:00
rocky
8b9e0eca42 Some grammar cleanup 2016-05-09 11:58:05 -04:00
rocky
41f9e9e53e Track recent lc changes in fragment semantics 2016-05-09 06:57:13 -04:00
rocky
1179dc72da Another closure wrapping bug 2016-05-09 06:47:03 -04:00
rocky
e63bcd54e9 Another Python 3 closure grammar bug 2016-05-09 06:21:57 -04:00
rocky
73461d323e More small history tweaks 2016-05-09 05:34:01 -04:00
rocky
e37b197db9 Fix Python 3 list comprehansion closure bug 2016-05-09 05:03:49 -04:00
rocky
196495c40e Python 3 DUP_TOP_TWO bug 2016-05-08 18:41:59 -04:00
rocky
dddb486d78 DRY parse{2,3} code
Add test for last bug.
2016-05-08 18:15:07 -04:00
rocky
ce2ae463c4 Fix another if/loop parse bug 2016-05-08 18:07:04 -04:00
rocky
739ce7b1fd Go over history yet again. 2016-05-08 16:44:17 -04:00
rocky
b11f6d94f7 come_from_opt handles and/or precidence properly
main.py: give a better error message when file is not found.
2016-05-08 15:51:54 -04:00
rocky
debb46b0fe Semantic routine nonterminal typo 2016-05-08 13:49:15 -04:00
rocky
400153ea53 Yet another Python 3.x COME_FROM grammar problem 2016-05-08 13:08:12 -04:00
rocky
a65a8bb68e Fix 3.2 for/if loopback bug
problem was handling in Python 3.2

 for ...
    if ...
    else:
      ....
      jump for
    come from if
    jump for

In later Python 3's a "come from" is removed.

Also, start to DRY parser{,2,3} grammar rules.
2016-05-08 12:09:50 -04:00
rocky
4a79082872 Fix 3.5 if..pass bug
Update HISTORY.MD to include Dan Pascu. Some minor doc corrections
2016-05-08 10:32:11 -04:00
rocky
61c4a711a2 DRY scanner 3.{4,5} code 2016-05-08 00:52:02 -04:00
rocky
406df297df Python 3 build class parsing 2016-05-07 23:32:59 -04:00
rocky
36ffd4c31f Handle Python 3 yield from
Start dealing with MAKE_FUNCTION flags - not done yet.
2016-05-07 11:33:18 -04:00
rocky
039c115679 More Python3 deparsing
- grammar rule genexpr
- More Python3 docstring formatted
2016-05-06 23:51:25 -04:00
rocky
15b2a742e9 Administrivia
setup.py:
  don't need to import pkg_resources

pydisassemble:
  give an error is no file or directory is given
  usage should go to stderr, not stdout
2016-05-06 06:01:10 -04:00
rocky
163dfd888d Minor tweaks 2016-05-05 22:09:22 -04:00
rocky
408ba8c564 All Python 2.7 lib files decompile 2016-05-05 21:34:56 -04:00
rocky
c58481a9eb More Python 2 and 3 deparsing bugs fixed
* while + if break
* try + finall /pass
2016-05-05 20:56:41 -04:00
rocky
845a4a2003 Again, not GPL3 but MIT 2016-05-05 12:04:01 -04:00
rocky
469cadd5c9 Start PYPY 2.7 tolerance 2016-05-05 11:27:56 -04:00
rocky
4377354cf9 Get ready for release 2.3.4 2016-05-05 05:05:01 -04:00
rocky
6caa2c12fa Remove pypy3 add python 3.2 testing
Reorder list for testing preference
2016-05-05 04:45:00 -04:00
rocky
3153a955d4 Remove pypy 2016-05-05 04:42:23 -04:00
rocky
6f3a88d7e2 Fix up 3.2 tests
Remove pypy
2016-05-05 04:41:23 -04:00
rocky
109737cbef Try pypy and pypy3 2016-05-05 04:14:03 -04:00
rocky
05733c6171 Python 3.5 abc.py bug distilled 2016-05-05 04:11:53 -04:00
rocky
6765a2ea97 Add cross-Python-protable 3.5 dis module 2016-05-05 03:17:25 -04:00
rocky
c85496a92d Handle 3.5 with [as]
scanner35.py: Fix a small variable-name typo
2016-05-04 22:15:03 -04:00
rocky
e4ba73adfb One more test 2016-05-03 22:27:26 -04:00
rocky
7bf93980ce Don't repeat next_except_jump 2016-05-03 19:39:01 -04:00
rocky
8241a5e3a8 Wrong package name 2016-05-03 14:35:00 -04:00
rocky
faac11ad8c More package administrivia 2016-05-03 05:50:57 -04:00
rocky
fe04b97c6b Remove one more old-style Python class 2016-05-03 03:55:43 -04:00
rocky
62f6220082 DRY Python 2.7 scanner more 2016-05-03 03:29:56 -04:00
rocky
11e6eff427 Include LICENSE in package 2016-05-03 03:14:17 -04:00
rocky
2286aa5320 Get ready for release 2.3.3 2016-05-03 03:02:36 -04:00
rocky
72ac7eb27c Be more explicit that we need Python 2.6 or later 2016-05-02 21:32:44 -04:00
rocky
a8c5f71cfe Merge branch 'master' of github.com:rocky/python-uncompyle6 2016-05-02 21:25:35 -04:00
rocky
feec241da8 Misc: long lists, DRY 2/3 grammars, '%' count
parse{2,3,r}.py: DRY Python expressions between Python 2 and 3
pysource.py, fragment.py, parser.py: handle long lists by grouping in chunks of 32
and 256
bin/uncompyle6: count %s properly
2016-05-02 21:25:16 -04:00
rocky
c5f359f9be Note relation to other uncompyle forks
Add some other minor corrections and additions as well.
2016-05-02 12:19:57 -04:00
rocky
bfe8357f52 Trivial spacing change 2016-05-02 10:44:48 -04:00
rocky
ceb47aba9c Add -V | --version and simplfy changing it 2016-05-02 04:09:51 -04:00
rocky
08720474bf Expose uncompyle_file 2016-05-01 23:11:48 -04:00
rocky
119bb9bb26 Bug 2016-05-01 21:14:25 -04:00
rocky
4455b5e280 Add test for last fix.
Drop 2.5 test until we figure out what's wrong
2016-05-01 21:07:10 -04:00
rocky
dcbf8d2cf7 Bug in 3.5 constant map parsing 2016-05-01 20:54:42 -04:00
rocky
b52baddab6 Export module load and fns load_file, load_module 2016-05-01 13:27:00 -04:00
rocky
03bb54f8ea License is MIT
marsh.py: remove unused import
2016-05-01 11:58:46 -04:00
rocky
313e468bdc Forgot to define Python3ParserSingle 2016-05-01 07:18:29 -04:00
rocky
dc80b140c6 Start to DRY Python2 and Python3 grammars
Separate out 3.2, and 3.5+ specific grammar code
2016-05-01 07:13:36 -04:00
rocky
fa48c9fc61 Get ready for release 2.3.1 2016-04-30 11:33:50 -04:00
rocky
0a32a16d88 Python 3.0..3.2 bug in LOAD_FAST/STORE_LOCAL
LOAD_FAST         '__locals__'
STORE_LOCALS      ''

Also have to adjust doc constants for this crap

astnode.py: minor format change
2016-04-30 09:12:03 -04:00
rocky
4aa703d727 Test optimized Python code and Python 3.2 2016-04-30 06:54:01 -04:00
rocky
f3a4e6ee54 Pevious commit grammar change is Python 3.5 and up 2016-04-30 04:03:38 -04:00
rocky
43f5c5dcca Python 3.5 if statments decompyle
Sometimes it doesn't need JUMP_FORWARD _come_from _come_from

For example:

def handle2(module):
    if module == 'foo':
        try:
            module = 1
        except ImportError as exc:
            module = exc

    return module

And:

if __name__:
    for i in (1, 2):
        x = 3
2016-04-30 03:51:54 -04:00
rocky
3e49aa56bb spark -> spark_parser 2016-04-28 19:03:51 -04:00
rocky
9cc9fc99c2 Really remove spark - Use external package instead 2016-04-28 02:12:30 -04:00
R. Bernstein
2ebc558b40 Merge pull request #8 from rocky/external-spark
External spark
2016-04-27 23:30:36 -04:00
rocky
34a582b64c Administrivia 2016-04-27 23:26:31 -04:00
rocky
2711c8d06f Note dependencies on spark 2016-04-27 23:09:30 -04:00
rocky
40badefe9d Use external spark now. 2016-04-27 23:04:31 -04:00
rocky
d9ef5ff69a Back to 2.7.8 2016-04-20 05:31:38 -04:00
rocky
a4e839960f Try python 2.7.10 2016-04-20 05:16:25 -04:00
rocky
7b3c7e83ec Remove link to Mysterie uncompyle2 per request 2016-04-19 04:05:05 -04:00
rocky
1b71d0a049 Get ready for release 2.2.0 2016-04-19 03:36:21 -04:00
rocky
17b0caa4f0 Another typo 2016-04-18 05:58:35 -04:00
R. Bernstein
b88e97c17d Merge pull request #7 from rocky/single-compile
Support single-mode compile
2016-04-18 05:52:33 -04:00
R. Bernstein
158bdd9b04 Merge pull request #6 from graingert/wheels
declare Python3 support in wheel and trove
2016-04-18 05:50:16 -04:00
rocky
b0d3a4e47b Doc typo 2016-04-18 05:43:14 -04:00
Thomas Grainger
4ba2eb6981 declare Python3 support in wheel and trove 2016-04-18 10:38:22 +01:00
rocky
76768c889a Start to DRY Python 2 and Python 3 grammar code
Move common code to parser.py
2016-04-18 05:32:30 -04:00
rocky
8ae7e22f2e Add simgle-mode compilation 2016-04-18 05:14:47 -04:00
rocky
7e0526d627 Towards single compilation 2016-04-17 22:47:03 -04:00
rocky
2c7fcf9e62 Back off if_else_ternary pending
Fails on Python 3.4 investigation
Python 3.5 works though
2016-04-10 21:59:06 -04:00
rocky
5a813621cb Test administrivia 2016-04-10 21:27:41 -04:00
rocky
9f7d36f8fb Handle Ternary "or". Remove mention of uncompyle3
uncompyle3 removed per Mysterie's request
[Fixes Issue #5]
2016-04-07 07:18:46 -04:00
rocky
4e57c3da5b remove uncompyle3 and make test work again
* uncompyle3 removed by request
* make test on python 2.7 is failing on some python3 and python3.5
  bytecodes. Remove for now.
2016-03-11 02:10:07 -05:00
R. Bernstein
0de3efb01a Merge pull request #3 from lelicopter/master
Bug correction (parse cmd options)
2016-02-23 21:15:30 -05:00
lelicopter
fff4283f73 Bug correction
Bug correction of parsing cmdline parameters
2016-02-24 12:05:32 +10:00
rocky
551e2174cb Add Python 3.5 tests that we can do. 2016-01-07 04:32:20 -05:00
R. Bernstein
f25c9b45a4 Grammar fixes 2016-01-05 07:47:31 -05:00
rocky
077bca6141 Get ready for release 2.1.3 2016-01-02 23:04:55 -05:00
rocky
31ebe88b38 Start to DRY opcode code. Limited support for decopyling Python 3.5 2016-01-02 22:59:02 -05:00
rocky
bc2a36b9f7 Start 3.4 library verify tests 2016-01-02 16:48:59 -05:00
rocky
66739752d8 Regularize spelling of bytecode 2016-01-02 15:55:48 -05:00
rocky
716ee6d361 Add download shield. Add check-rst target 2016-01-02 15:54:24 -05:00
R. Bernstein
ca00e433b7 Update README.rst 2016-01-02 13:32:32 -05:00
rocky
f0cc2df543 Track recent source class semantic actions in fragment actions 2016-01-02 13:11:19 -05:00
rocky
52da6f4a8f Make ScannerXX() initialization the same on Python 2.x and 3.x 2016-01-02 07:54:21 -05:00
rocky
54a0af733b Verify 3.4 bytecode. verify API call bug fixed. 2016-01-02 07:50:09 -05:00
rocky
2927921856 Python 3 class deparsing. stop earlier in uncompyle6 on a syntax error. 2016-01-02 05:38:22 -05:00
rocky
cd480c8670 Fix make_closure compilation from 2.x of 3.3 bytecode 2016-01-01 22:17:53 -05:00
rocky
7d42329c31 Work on MAKE_CLOSURE rules for Python 3.3 2016-01-01 21:55:14 -05:00
rocky
b89177d234 track source deparsing superclass bug fix 2015-12-31 15:24:24 -05:00
rocky
31691b2003 Get ready for release 2.1.2 2015-12-31 11:47:21 -05:00
rocky
09ef875b3e Remove tests we will never use 2015-12-31 11:37:06 -05:00
rocky
0129c3a16e Try travis testing on Python 3.5. Fix up Makefile to avoid pytest on 3.5
for now
2015-12-31 11:19:46 -05:00
rocky
4d5a3bc449 Add a few tests from Python 2.7 standard library 2015-12-31 10:57:59 -05:00
rocky
8d90e33832 Handle Python 3.3 > dotted class names 2015-12-31 10:56:12 -05:00
rocky
0533bbb758 Note Python 3.5 2015-12-30 23:48:27 -05:00
rocky
b82a8b90d5 Allow Python 3.5 to decomplyle other versions. No Python 3.5
bytecode support just yet though.
2015-12-30 23:46:29 -05:00
rocky
d3a32b6877 Show details on parsing assert failures. 2015-12-30 23:17:57 -05:00
rocky
21e51004ae Remove accidental schmutz. Try using pattr on 3.4 to get fn names 2015-12-30 20:18:20 -05:00
rocky
d5b023aec4 Parses another variation of Python3 try/except. Reinstate some tests 2015-12-30 19:05:58 -05:00
rocky
e50bebb7c8 Reinstate list comprehension test. I think we've found/fixed the
initialization bug.
2015-12-30 18:51:22 -05:00
rocky
2e91de8355 Start using our replacement for inspect.iscode 2015-12-30 18:44:27 -05:00
rocky
5bbe2c4a45 Doc changes. 2015-12-30 18:20:50 -05:00
rocky
6ffd2fca90 document GenericASTTraversal.preorder and default. 2015-12-30 17:27:45 -05:00
rocky
b3ede4b64b Walker->SourceWalker Traverser->FragmentsWalker 2015-12-30 17:04:18 -05:00
rocky
1785113045 Tidy parse3 grammer a little 2015-12-30 10:26:07 -05:00
rocky
657eeb7de8 Towards Python3 getting try/except working more often. 2015-12-30 09:46:52 -05:00
rocky
313a8578b3 Fix another cross-version bug: eliminate version-specific library 'dis'
and use corresponding version-indepent routine instead.
2015-12-29 22:23:50 -05:00
rocky
a30f3625ac Fix Python 2 cross deparsing pythond bytecode tuples co_consts,
co_names, co_varnames. Reinstate cross Python 2-3 uncompiling
2015-12-29 22:11:45 -05:00
rocky
e17d94f28f Syntax error typo 2015-12-29 17:35:49 -05:00
rocky
16af79f042 Make sure internObjects is (re)initialized 2015-12-29 17:33:54 -05:00
rocky
116263dd8c inspect.iscode -> hasattr for now until we write a cross-version iscode 2015-12-29 17:05:48 -05:00
rocky
34841abe14 scanner3: Python 2.6 compatibility: change set initializations. Get rid
of * import
opcode_*: only a little of the much-needed larger cleanup
Makefile: remove 3.x bytecode checking from Python 2.x for now. DRY
Makefile a little bit (but more is needed)
2015-12-29 08:30:49 -05:00
rocky
226f3c7e63 Python 2.6.9 compatibility 2015-12-28 23:55:03 -05:00
rocky
f77c4b53c4 Marshal loading of = >python 3.4 from Python < 3.4 2015-12-28 14:56:53 -05:00
rocky
6f0a252693 Add Python3 marshal codes and start to handle cross-version Python code
object types, introducing scan.Code3
2015-12-28 14:17:28 -05:00
rocky
625feb0517 Possibly closer to getting 2.7 to read 3.4 bytecode 2015-12-27 22:24:30 -05:00
rocky
820fdb4771 Fix up Python 2.x's ability to get code from Python 3.x's bytecode 2015-12-27 19:36:02 -05:00
rocky
d774222eb1 defer some tests 2015-12-27 17:11:58 -05:00
rocky
7ec54b15d8 Merge branch 'master' of github.com:rocky/python-uncompyle6
Conflicts:
	README.rst
2015-12-27 16:51:48 -05:00
rocky
7c5b8d803c More tests 2015-12-27 16:50:45 -05:00
rocky
c508413689 3.2 bytecode 2015-12-27 15:19:53 -05:00
rocky
f859758aff Get ready for release 2.1.1 2015-12-27 12:55:52 -05:00
rocky
44cd349cc7 DRY Python3 scanner code. Some cross version handling fixed.
Some Python 3.2 and 3.3 deparse fixes.
2015-12-27 04:43:35 -05:00
rocky
276709cbb9 DRY Python3 scanner code. Some cross version handling fixed.
Some Python 3.2 and 3.3 deparse fixes.
2015-12-27 04:32:46 -05:00
rocky
4640e7dece Running native on Python 3.3 needs more work 2015-12-26 19:32:32 -05:00
rocky
ce8c7a4dc2 Add ok-2.7 tests for 3.4 full testing 2015-12-26 19:25:46 -05:00
rocky
6bd61deccc Add verify tests. Add Python 2.6 bytecode and use. 2015-12-26 19:14:53 -05:00
rocky
3ac3ef24ac Add node and template code to cleanup "for" handling 2015-12-26 10:42:57 -05:00
rocky
d6ac51d0a2 Try Python 2.6 testing on travis 2015-12-26 10:25:20 -05:00
rocky
69a8404edb For testing we can't 3.3 bytecodes on 2.7 yet, so use 3.2 2015-12-26 10:24:02 -05:00
rocky
008bd79719 Fix up Python 3.2, 3.3, and 3.4 cross-version scanners
Try travis 2.6 and 3.3
2015-12-26 10:19:26 -05:00
rocky
e8ee3ac751 Travis: try checking 3.4 2015-12-26 07:41:58 -05:00
rocky
7a2703634f Fix up looping by reinstating JUMP_ABSOLUTE -> JUMP_BACK or CONTINUE
get jump offsets into jump attributes. Fix up 3.2 scanner paritally
and use that in 3.4 for in cross version disassembly.
2015-12-26 03:06:03 -05:00
rocky
fe9c8d5734 Python3 try/except handling improvements. Add Walker exception and use
that: fixes erroneous uncompyle success message on parse error.
2015-12-26 00:12:02 -05:00
rocky
0409cee6a9 WIP redo try/except for Python3 2015-12-25 17:57:53 -05:00
rocky
39f0f7440b Fix bugs in using pysource from fragments. 2015-12-25 10:47:07 -05:00
rocky
1d533cbb23 Two modes of disassembly, one where we show hidden code and one where we don't. 2015-12-25 10:08:12 -05:00
406 changed files with 7016 additions and 75171 deletions

3
.gitignore vendored
View File

@@ -3,9 +3,12 @@
/.cache
/.eggs
/.python-version
/.tox
/README
/__pkginfo__.pyc
/dist
/how-to-make-a-release.txt
/tmp
/uncompyle6.egg-info
__pycache__
build

View File

@@ -3,7 +3,15 @@ language: python
sudo: false
python:
- '2.7'
- '3.5'
- '2.7.11'
- '2.6'
- '3.4'
- '3.2'
install:
- pip install -r requirements.txt
- pip install -r requirements-dev.txt
script:
- python ./setup.py develop && COMPILE='--compile' make check-2.7
- python ./setup.py develop && COMPILE='--compile' make check

1141
ChangeLog

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,76 @@
This is the changelog from *decompyle*'s release 2.4 passed on by Dan Pascu
release 2.4 (Dan Pascu)
- Replaced the way code structures are identified by the parser.
Previously, the scanner introduced some COME_FROM entries in the
dissasembly output to mark all the destinations of jump instructions.
Using these COME_FROM labels the parser was then able to identify the
code structures (if tests, while loops, etc). Up to python-2.3 this was
possible because the code structures were clearly defined and jump
targets were always to the same points in a given strcuture making it
easy to identify the structure. Python 2.3 however introduced optimized
jumps to increase code performance. In the previous version of decompyle
(2.3) we used a technique to identify the code structures and then used
these structures to determine where the jump targets would have been if
not optimized. Using this information we then added COME_FROM labels at
the points where they would have been if not optimized, thus emulating
the way decompyle worked with versions before python 2.3. However with
the introduction of even more optimizations in python 2.4 this technique
no longer works. Not only the jump targets are no longer an effective
mean for the parser to identify the code structures, but also trying to
emulate the old way things were solved when it clearly no longer works
is not the right solution. To solve this issue, the code to identify the
structures that we had developed in version 2.3, was used to add real
start/end points for strcuture identification, instead of the COME_FROM
labels. Now these new start/end labels are used by the parser to more
precisely identify the structures and the COME_FROM labels were removed
completely. The scanner is responsible to identify these code structures
and use any knowledge of optimizations that python applies to determine
the start/end points of any structure and then mark them with certain
keywords that are understood by the parser.
- Correctly identify certain `while 1' structures that were not
recognized in the previous version.
- Added support for new byte code constructs used by python 2.4
release 2.3.2
- tidied up copyright and changelog information for releases 2.3 and later
release 2.3.1 (Dan Pascu)
- implemented a structure detection technique that fixes problems with
optimised jumps in Python >= 2.3. In the previous release (decompyle 2.3),
these problems meant that some files were incorrectly decompiled and
others could not be decompiled at all. With this new structure detection
technique, thorough testing over the standard python libraries suggests
that decompyle 2.3.1 can handle everything that decompyle 2.2beta1 could,
plus new Python 2.3 bytecodes and constructs.
release 2.3 (Dan Pascu)
- support for Python 2.3 added
- use the marshal and disassembly code from their respective python
versions, so that decompyle can manipulate bytecode independently
of the interpreter that runs decompyle itself (for example it can
decompile python2.3 bytecode even when running under python2.2)
——————————————————
release 2.2beta1 (hartmut Goebel)
- support for Python 1.5 up to Python 2.2
- no longer requires to be run with the Python interpreter version
which generated the byte-code.
- requires Python 2.2
- pretty-prints docstrings, hashes, lists and tuples
- decompyle is now a script and a package
- added emacs mode-hint and tab-width for each file output
- enhanced test suite: more test patterns, .pyc/.pyo included
- avoids unnecessary 'global' statements
- still untested: EXTENDED_ARG
internal changes:
- major code overhoul: splitted into several modules, clean-ups
- use a list of valid magics instead of the single one from imp.py
- uses copies of 'dis.py' for every supported version. This ensures
correct disassemling of the byte-code.
- use a single Walker and a single Parser, thus saving time and memory
- use augmented assign and 'print >>' internally
- optimized 'Walker.engine', the main part of code generation

View File

@@ -4,7 +4,8 @@ There have been a number of people who have worked on this. I am awed
by the amount of work, number of people who have contributed to this,
and the cleverness in the code.
The below is an annotated history from my reading of the sources cited.
The below is an annotated history from talking to participants
involved and my reading of the code and sources cited.
In 1998, John Aycock first wrote a grammar parser in Python,
eventually called SPARK, that was usable inside a Python program. This
@@ -23,24 +24,25 @@ working on his thesis, John realized SPARK could be used to deparse
Python bytecode. In the fall of 1999, he started writing the Python
program, "decompyle", to do this.
This code introduced another clever idea: using table-driven
semantics routines, using format specifiers.
To help with control structure deparsing the instruction sequence was
augmented with pseudo instruction COME_FROM. This code introduced
another clever idea: using table-driven semantics routines, using
format specifiers.
The last mention of a release of SPARK from John is around 2002.
In the fall of 2000, Hartmut Goebel
[took over maintaining the code](https://groups.google.com/forum/#!searchin/comp.lang.python/hartmut$20goebel/comp.lang.python/35s3mp4-nuY/UZALti6ujnQJ). The
first subsequennt public release announcement that I can find is
first subsequent public release announcement that I can find is
["decompyle - A byte-code-decompiler version 2.2 beta 1"](https://mail.python.org/pipermail/python-announce-list/2002-February/001272.html).
From the CHANGES file found in
[the tarball for that release](http://old-releases.ubuntu.com/ubuntu/pool/universe/d/decompyle2.2/decompyle2.2_2.2beta1.orig.tar.gz),
it appears that Hartmut did most of the work to get this code to
accept the full Python language. He added precidence to the table
accept the full Python language. He added precedence to the table
specifiers, support for multiple versions of Python, the
pretty-printing of docstrings, lists and hashes. He also wrote
extensive tests and routines to the testing and verification of
decompiled bytecode.
pretty-printing of docstrings, lists, and hashes. He also wrote test and verification routines of
deparsed bytecode, and used this in an extensive set of tests that he also wrote. He could verify against the entire Python library.
decompyle2.2 was packaged for Debian (sarge) by
[Ben Burton around 2002](https://packages.qa.debian.org/d/decompyle.html). As
@@ -56,27 +58,52 @@ it doesn't look like he's done anything compiler-wise since SPARK). So
I hope people will use the crazy-compilers service. I wish them the
success that his good work deserves.
Next we get to
["uncompyle" and PyPI](https://pypi.python.org/pypi/uncompyle/1.1) and
the era of git repositories. In contrast to decompyle, this now runs
only on Python 2.7 although it accepts bytecode back to Python
Dan Pascu did a bit of work from late 2004 to early 2006 to get this
code to handle first Python 2.3 and then 2.4 bytecodes. Because of
jump optimization introduced in the CPython bytecode compiler at that
time, various JUMP instructions were classifed as going backwards, and
COME FROM instructions were reintroduced. See
RELEASE-2.4-CHANGELOG.txt for more details here. There wasn't a public
release of RELEASE-2.4 and bytecodes other than Python 2.4 weren't
supported. Dan says the Python 2.3 version could verify the entire
python library.
Next we get to ["uncompyle" and
PyPI](https://pypi.python.org/pypi/uncompyle/1.1) and the era of
public version control. (Dan's code although not public used
[darcs](http://darcs.net/) for version control.)
In contrast to _decompyle_, _uncompyle_ at least in its final versions,
runs only on Python 2.7. However it accepts bytecode back to Python
2.5. Thomas Grainger is the package owner of this, although Hartmut is
listed as the author.
still listed as the author.
The project exists not only on
[github](https://github.com/gstarnberger/uncompyle) but also on
[bitbucket](https://bitbucket.org/gstarnberger/uncompyle) where the
git history goes back to 2009. Somewhere in there the name was changed
from "decompyle" to "uncompyle".
[bitbucket](https://bitbucket.org/gstarnberger/uncompyle) and later
the defunct [google
code](https://code.google.com/archive/p/unpyc/). The git/svn history
goes back to 2009. Somewhere in there the name was changed from
"decompyle" to "unpyc" by Keknehv, and then to "uncompyle" by Guenther Starnberger.
The name Thomas Grainger isn't found in (m)any of the commits in the
several years of active development. Guenther Starnberger, Keknehv,
hamled, and Eike Siewertsen are principle committers here.
several years of active development. First Keknehv worked on this up
to Python 2.5 or so while acceping Python bytecode back to 2.0 or
so. Then hamled made a few commits earler on, while Eike Siewertsen
made a few commits later on. But mostly wibiti, and Guenther
Starnberger got the code to where uncompyle2 was around 2012.
This project, uncompyle6, however owes its existence to uncompyle2 by
Myst herie (Mysterie) whose first commit seems to goes back to 2012;
it is also based on Hartmut's code. I chose this as it seems had been
the most actively worked on most recently.
This project, uncompyle6, however owes its existence to the fork of
uncompyle2 by Myst herie (Mysterie) whose first commit picks up at
2012. I chose this since it seemed to have been at that time the most
actively, if briefly, worked on. Also starting around 2012 is Dark
Fenx's uncompyle3 which I used for inspiration for Python3 support.
I started working on this late 2015, mostly to add fragment support.
In that, I decided to make this runnable on Python 3.2+ and Python 2.6+
while, handling Python bytecodes from Python versions 2.5+ and
3.2+. (I think I could go back further, but I'd consider doing that
only after code is better cleaned up and supports Python 3 better.)
Over the many years, code styles and Python features have
changed. However brilliant the code was and still is, it hasn't really
@@ -91,16 +118,20 @@ Hartmut a decade an a half ago:
NB. This is not a masterpiece of software, but became more like a hack.
Probably a complete rewrite would be sensefull. hG/2000-12-27
One of the attempts to modernize it and make it available for Python3
is [the one by Anton Vorobyov (DarkFenX)](https://github.com/DarkFenX/uncompyle3). I've
followed some of the ideas there in this project.
This project deparses using an Early-algorithm parse with lots of
massaging of tokens and the grammar in the scanner
phase. Early-algorithm parsers are context free and tend to be linear
if the grammar is LR or left recursive.
Lastly, I should mention [unpyc](https://code.google.com/p/unpyc3/)
and most especially [pycdc](https://github.com/zrax/pycdc), largely by
Michael Hansen and Darryl Pogue. If they supported getting source-code
fragments and I could call it from Python, I'd probably ditch this and
use that. From what I've seen, the code runs blindingly fast and spans
all versions of Python.
Another approach that doesn't use grammars is to do something like
simulate execution symbolically and build expression trees off of
stack results. The two important projects that work this way are
[unpyc3](https://code.google.com/p/unpyc3/) and most especially
[pycdc](https://github.com/zrax/pycdc) The latter project is largely
by Michael Hansen and Darryl Pogue. If they supported getting
source-code fragments and I could call it from Python, I'd probably
ditch this and use that. From what I've seen, the code runs blindingly
fast and spans all versions of Python.
Tests for the project have been, or are being, culled from all of the
projects mentioned.

View File

@@ -1,9 +1,11 @@
include README.rst
include HISTORY.md
include ChangeLog
include HISTORY.md
include LICENSE
include DECOMPYLE-2.4-CHANGELOG.txt
include __pkginfo__.py
recursive-include uncompyle6 *.py
include bin/uncompyle6
include bin/pydisassemble
recursive-include test *.py
recursive-include test *.py *.pyc
recursive-include pytest *.py

View File

@@ -18,8 +18,26 @@ TEST_TYPES=check-long check-short check-2.7 check-3.4
#: Default target - same as "check"
all: check
#: Run working tests
check check-3.4 check-2.7: pytest
# Run all tests
check:
@PYTHON_VERSION=`$(PYTHON) -V 2>&1 | cut -d ' ' -f 2 | cut -d'.' -f1,2`; \
$(MAKE) check-$$PYTHON_VERSION
# Run all quick tests
check-short: pytest
$(MAKE) -C test check-short
#: Tests for Python 2.7, 3.3 and 3.4
check-2.7 check-3.3 check-3.4: 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.2 check-3.5:
$(MAKE) -C test $@
#:Tests for Python 2.6 (doesn't have pytest)
check-2.6:
$(MAKE) -C test $@
#: Run py.test tests
@@ -31,9 +49,9 @@ clean: clean_pyc
$(PYTHON) ./setup.py $@
(cd test && $(MAKE) clean)
#: Create source (tarball) and binary (egg) distribution
#: Create source (tarball) and wheel distribution
dist:
$(PYTHON) ./setup.py sdist bdist_egg
$(PYTHON) ./setup.py sdist bdist_wheel
#: Remove .pyc files
clean_pyc:
@@ -47,6 +65,11 @@ sdist:
#: Style check. Set env var LINT to pyflakes, flake, or flake8
lint: flake8
# Check StructuredText long description formatting
check-rst:
$(PYTHON) setup.py --long-description | rst2html.py > python3-trepan.html
#: Lint program
flake8:
$(LINT) uncompyle6
@@ -55,6 +78,11 @@ bdist_egg:
$(PYTHON) ./setup.py bdist_egg
#: Create binary wheel distribution
bdist_wheel:
$(PYTHON) ./setup.py bdist_wheel
# It is too much work to figure out how to add a new command to distutils
# to do the following. I'm sure distutils will someday get there.
DISTCLEAN_FILES = build dist *.pyc

98
NEWS
View File

@@ -1,4 +1,100 @@
uncompyle6 1.0.0 2015-12-11
uncompyle6 2.4.0 2016-05-18
- Many Python 3 bugs fixed:
* Python 3.2 to 3.5 libaries largely
uncompyle and most verify
- pydisassembler:
* disassembles all code objects in a file
* can select showing bytecode before
or after uncompyle mangling, option -U
- DRY scanner code (but more is desired)
- Some code cleanup (but more is desired)
- Misc Bugs fixed:
* handle complex number unmarshaling
* Running on Python 2 to works on Python 3.5 bytecodes now
uncompyle6 2.3.5 and 2.3.6 2016-05-14
- Python 2 class decorator fix (thanks to Tey)
- Fix fragment parsing bugs
- Fix some Python 3 parsing bugs:
* Handling single in * parameter
* "while True"
* escape from for inside if
* yield expressions
- Correct history based on info from Dan Pascu
- Fix up pip packaging, ugh.
uncompyle6 2.3.4 2016-05-5
- More Python 3.5 parsing bugs addressed
- decompiling Python 3.5 from other Python versions works
- test from Python 3.2
- remove "__module__ = __name__" in 3.0 <= Python 3.2
uncompyle6 2.3.3 2016-05-3
- Fix bug in running uncompyle6 script on Python 3
- Speed up performance on deparsing long lists by grouping in chunks of 32 and 256 items
- DRY Python expressions between Python 2 and 3
uncompyle6 2.3.2 2016-05-1
- Add --version option standalone scripts
- Correct License information in package
- expose fns uncompyle_file, load_file, and load_module
- Start to DRY Python2 and Python3 grammars Separate out 3.2, and 3.5+
specific grammar code
- Fix bug in 3.5+ constant map parsing
uncompyle6 2.3.0, 2.3.1 2016-04-30
- Require spark_parser >= 1.1.0
uncompyle6 2.2.0 2016-04-30
- Spark is no longer here but pulled separate package spark_parse
- Python 3 parsing fixes
- More tests
uncompyle6 2.2.0 2016-04-02
- Support single-mode (in addtion to exec-mode) compilation
- Start to DRY Python 2 and Python 3 grammars
- Fix bug in if else ternary construct
- Fix bug in uncomplye6 -d and -r options (via lelicopter)
uncompyle6 2.1.3 2016-01-02
- Limited support for decompiling Python 3.5
- Improve Python 3 class deparsing
- Handle MAKE_CLOSURE opcode
- Start to DRY opcode code.
- increase test coverage
- fix misc small bugs and some improvements
uncompyle6 2.1.2 2015-12-31
- Fix cross-version Marshal loading
- Handle Python 3.3 . dotted class names
- Limited 3.5 support: allows deparsing other versions
- Refactor code more, misc bug fixes
uncompyle6 2.1.1 2015-12-27
- packaging issues
uncompyle6 2.1.0 2015-12-27
- Python 3.x deparsing much more solid
- Better cross-version deparsing
Some bugs squashed while other run rampant. Some code cleanup while
much more is yet needed. More tests added, but many more are needed.
uncompyle6 2.0.0 2015-12-11
Changes from uncompyle2

View File

@@ -3,26 +3,33 @@
uncompyle6
==========
A native Python Byte-code Disassembler, Decompiler, and byte-code library
A native Python bytecode Disassembler, Decompiler, Fragment Decompiler
and bytecode library. Follows in the tradition of decompyle, uncompyle, and uncompyle2.
Introduction
------------
*uncompyle6* translates Python byte-code back into equivalent Python
source code. It accepts byte-codes from Python version 2.5 to 3.4 or
so and has been tested on Python 2.6, 2.7 and Python 3.4.
*uncompyle6* translates Python bytecode back into equivalent Python
source code. It accepts bytecodes from Python version 2.5 to 3.5 or
so. The code requires Python 2.6 or later and has been tested on Python
running versions 2.6, 2.7, 3.2, 3.3, 3.4 and 3.5.
Why this?
---------
What makes this different other CPython byte-code decompilers? Its
There were a number of decompyle, uncompile, uncompyle2, uncompyle3
forks around. All of them come basically from the same code base, and
almost all of them not maintained very well. This code pulls these together
and addresses a number of open issues in those.
What makes this different from other CPython bytecode decompilers? Its
ability to deparse just fragments and give source-code information
around a given bytecode offset.
I using this to deparse fragments of code inside my trepan_
debuggers_. For that, I need to record text fragements for all
byte-code offsets (of interest). This purpose although largely
I use this to deparse fragments of code inside my trepan_
debuggers_. For that, I need to record text fragments for all
bytecode offsets (of interest). This purpose although largely
compatible with the original intention is yet a little bit different.
See this_ for more information.
@@ -35,7 +42,7 @@ information.
Other parts of the library can be used inside Python for various
bytecode-related tasks. For example you can read in bytecode,
i.e. perform a version-independent `marshal.loads()`, and disassemble
the bytecode using version of Python different from the one used to
the bytecode using a version of Python different from the one used to
compile the bytecode.
@@ -46,6 +53,8 @@ This uses setup.py, so it follows the standard Python routine:
::
pip install -r requirements.txt
pip install -r requirements-dev.txt
python setup.py install # may need sudo
# or if you have pyenv:
python setup.py develop
@@ -75,28 +84,36 @@ Run
::
./bin/uncompyle6 -h
./bin/pydisassemble -y
./bin/pydisassemble -h
for usage help
for usage help.
Known Bugs/Restrictions
-----------------------
Python 3 deparsing is getting there, but not solid. Using Python 2 to
deparse Python 3 is problematic, especilly for versions 3.4 and
greater.
Python 2 deparsing decompiles about the first 140 or so of the Python
2.7.10 and 2.7.11 standard library files and all but less that 10%
verify. So as such, it is probably a little better than uncompyle2.
Other Python 2 versions do worse.
Python 3 deparsing before 3.5 is okay, but even there, more work is needed to
decompile all of its library. Python 3.5 is missing some of new
opcodes and idioms added, but it still often works.
There is lots to do, so please dig in and help.
See Also
--------
* https://github.com/zrax/pycdc
* https://github.com/Mysterie/uncompyle2
* https://github.com/DarkFenX/uncompyle3
* https://code.google.com/p/unpyc3/
* https://github.com/zrax/pycdc : supports all versions of Python and is written in C++
* https://code.google.com/archive/p/unpyc3/ : supports Python 3.2 only
The above projects use a different decompiling technique what is used here.
The HISTORY file.
.. |downloads| image:: https://img.shields.io/pypi/dd/uncompyle6.svg
.. _trepan: https://pypi.python.org/pypi/trepan
.. _debuggers: https://pypi.python.org/pypi/trepan3k
.. _remake: https://bashdb.sf.net/remake

View File

@@ -9,13 +9,20 @@
# Things that change more often go here.
copyright = """
Copyright (C) 2015 Rocky Bernstein <rb@dustyfeet.com>.
Copyright (C) 2015, 2016 Rocky Bernstein <rb@dustyfeet.com>.
"""
classifiers = ['Development Status :: 3 - Alpha',
classifiers = ['Development Status :: 4 - Beta',
'Intended Audience :: Developers',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Topic :: Software Development :: Debuggers',
'Topic :: Software Development :: Libraries :: Python Modules',
]
@@ -23,31 +30,34 @@ classifiers = ['Development Status :: 3 - Alpha',
# The rest in alphabetic order
author = "Rocky Bernstein, Hartmut Goebel, John Aycock, and others"
author_email = "rb@dustyfeet.com"
entry_points={
'console_scripts': [
'uncompyle6=uncompyle6.bin.uncompile:main_bin',
'pydisassemble=uncompyle6.bin.pydisassemble:main',
]}
ftp_url = None
# license = 'BSDish'
install_requires = ['spark-parser >= 1.2.1']
license = 'MIT'
mailing_list = 'python-debugger@googlegroups.com'
modname = 'uncompyle6'
packages = ['uncompyle6', 'uncompyle6.opcodes']
py_modules = None
short_desc = 'Python byte-code disassembler and source-code converter'
scripts = ['bin/uncompyle6', 'bin/pydisassemble']
import os.path
def get_srcdir():
filename = os.path.normcase(os.path.dirname(os.path.abspath(__file__)))
return os.path.realpath(filename)
ns = {}
version = '2.0.0'
web = 'https://github.com/rocky/python-uncompyle6/'
# tracebacks in zip files are funky and not debuggable
zip_safe = True
def read(*rnames):
return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
import os.path
def get_srcdir():
filename = os.path.normcase(os.path.dirname(os.path.abspath(__file__)))
return os.path.realpath(filename)
srcdir = get_srcdir()
def read(*rnames):
return open(os.path.join(srcdir, *rnames)).read()
# Get info from files; set: long_description and VERSION
long_description = ( read("README.rst") + '\n' )
exec(read('uncompyle6/version.py'))

View File

@@ -1,77 +1,3 @@
#!/usr/bin/env python
# Mode: -*- python -*-
#
# Copyright (c) 2015 by Rocky Bernstein <rb@dustyfeet.com>
#
from __future__ import print_function
import sys, os, getopt
program = os.path.basename(__file__)
__doc__ = """
Usage: %s [OPTIONS]... FILE
Examples:
%s foo.pyc
%s foo.py
%s -o foo.pydis foo.pyc
%s -o /tmp foo.pyc
Options:
-o <path> output decompiled files to this path:
if multiple input files are decompiled, the common prefix
is stripped from these names and the remainder appended to
<path>
--help show this message
""" % ((program,) * 5)
Usage_short = \
"%s [--help] [--verify] [--showasm] [--showast] [-o <path>] FILE|DIR..." % program
from uncompyle6 import check_python_version
from uncompyle6.disas import disassemble_files
check_python_version(program)
outfile = '-'
out_base = None
try:
opts, files = getopt.getopt(sys.argv[1:], 'ho:', ['help'])
except getopt.GetoptError as e:
print('%s: %s' % (os.path.basename(sys.argv[0]), e), file=sys.stderr)
sys.exit(-1)
for opt, val in opts:
if opt in ('-h', '--help'):
print(__doc__)
sys.exit(0)
elif opt == '-o':
outfile = val
else:
print(opt)
print(Usage_short)
sys.exit(1)
# argl, commonprefix works on strings, not on path parts,
# thus we must handle the case with files in 'some/classes'
# and 'some/cmds'
src_base = os.path.commonprefix(files)
if src_base[-1:] != os.sep:
src_base = os.path.dirname(src_base)
if src_base:
sb_len = len( os.path.join(src_base, '') )
files = [f[sb_len:] for f in files]
del sb_len
if outfile == '-':
outfile = None # use stdout
elif outfile and os.path.isdir(outfile):
out_base = outfile; outfile = None
elif outfile and len(files) > 1:
out_base = outfile; outfile = None
disassemble_files(src_base, out_base, files, outfile)
from uncompyle6.bin.pydisassemble import main
main()

View File

@@ -1,213 +1,3 @@
#!/usr/bin/env python
# Mode: -*- python -*-
#
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
# Copyright (c) 2015 by Rocky Bernstein
"""
Usage: uncompyle6 [OPTIONS]... [ FILE | DIR]...
Examples:
uncompyle6 foo.pyc bar.pyc # decompile foo.pyc, bar.pyc to stdout
uncompyle6 -o . foo.pyc bar.pyc # decompile to ./foo.pyc_dis and ./bar.pyc_dis
uncompyle6 -o /tmp /usr/lib/python1.5 # decompile whole library
Options:
-o <path> output decompiled files to this path:
if multiple input files are decompiled, the common prefix
is stripped from these names and the remainder appended to
<path>
uncompyle6 -o /tmp bla/fasel.pyc bla/foo.pyc
-> /tmp/fasel.pyc_dis, /tmp/foo.pyc_dis
uncompyle6 -o /tmp bla/fasel.pyc bar/foo.pyc
-> /tmp/bla/fasel.pyc_dis, /tmp/bar/foo.pyc_dis
uncompyle6 -o /tmp /usr/lib/python1.5
-> /tmp/smtplib.pyc_dis ... /tmp/lib-tk/FixTk.pyc_dis
-c <file> attempts a disassembly after compiling <file>
-d print timestamps
-p <integer> use <integer> number of processes
-r recurse directories looking for .pyc and .pyo files
--verify compare generated source with input byte-code
(requires -o)
--help show this message
Debugging Options:
--asm -a include byte-code (disables --verify)
--grammar -g show matching grammar
--treee -t include syntax tree (disables --verify)
Extensions of generated files:
'.pyc_dis' '.pyo_dis' successfully decompiled (and verified if --verify)
+ '_unverified' successfully decompile but --verify failed
+ '_failed' decompile failed (contact author for enhancement)
"""
from __future__ import print_function
import sys, os, getopt, time
program = os.path.basename(__file__)
from uncompyle6 import verify, check_python_version
from uncompyle6.main import main, status_msg
def usage():
print("""usage:
%s [--help] [--verify] [--asm] [--tree] [--grammar] [-o <path>] FILE|DIR...
""" % program)
sys.exit(1)
check_python_version(program)
showasm = showast = do_verify = recurse_dirs = False
numproc = 0
outfile = '-'
out_base = None
codes = []
timestamp = False
timestampfmt = "# %Y.%m.%d %H:%M:%S %Z"
try:
opts, files = getopt.getopt(sys.argv[1:], 'hagtdro:c:p:',
'help asm grammar recurse timestamp tree verify '
'showgrammar'.split(' '))
except getopt.GetoptError as e:
print('%s: %s' % (os.path.basename(sys.argv[0]), e), file=sys.stderr)
sys.exit(-1)
options = {}
for opt, val in opts:
if opt in ('-h', '--help'):
print(__doc__)
sys.exit(0)
elif opt == '--verify':
options['do_verify'] = True
elif opt in ('--asm', '-a'):
options['showasm'] = True
options['do_verify'] = False
elif opt in ('--tree', '-t'):
options['showast'] = True
options['do_verify'] = False
elif opt in ('--grammar', '-g'):
options['showgrammar'] = True
elif opt == '-o':
outfile = val
elif opt == ('--timestamp', '-d'):
timestamp = True
elif opt == '-c':
codes.append(val)
elif opt == '-p':
numproc = int(val)
elif opt == ('--recurse', '-r'):
recurse_dirs = True
else:
print(opt, file=sys.stderr)
usage()
# expand directory if specified
if recurse_dirs:
expanded_files = []
for f in files:
if os.path.isdir(f):
for root, _, dir_files in os.walk(f):
for df in dir_files:
if df.endswith('.pyc') or df.endswith('.pyo'):
expanded_files.append(os.path.join(root, df))
files = expanded_files
# argl, commonprefix works on strings, not on path parts,
# thus we must handle the case with files in 'some/classes'
# and 'some/cmds'
src_base = os.path.commonprefix(files)
if src_base[-1:] != os.sep:
src_base = os.path.dirname(src_base)
if src_base:
sb_len = len( os.path.join(src_base, '') )
files = [f[sb_len:] for f in files]
del sb_len
if not files:
print("No files given", file=sys.stderr)
usage()
if outfile == '-':
outfile = None # use stdout
elif outfile and os.path.isdir(outfile):
out_base = outfile; outfile = None
elif outfile and len(files) > 1:
out_base = outfile; outfile = None
if timestamp:
print(time.strftime(timestampfmt))
if numproc <= 1:
try:
result = main(src_base, out_base, files, codes, outfile,
**options)
if len(files) > 1:
mess = status_msg(do_verify, *result)
print('# ' + mess)
pass
except (KeyboardInterrupt):
pass
except verify.VerifyCmpError:
raise
else:
from multiprocessing import Process, Queue
try:
from Queue import Empty
except ImportError:
from Queue import Empty
fqueue = Queue(len(files)+numproc)
for f in files:
fqueue.put(f)
for i in range(numproc):
fqueue.put(None)
rqueue = Queue(numproc)
def process_func():
try:
(tot_files, okay_files, failed_files, verify_failed_files) = (0, 0, 0, 0)
while 1:
f = fqueue.get()
if f is None:
break
(t, o, f, v) = \
main(src_base, out_base, [f], codes, outfile, **options)
tot_files += t
okay_files += o
failed_files += f
verify_failed_files += v
except (Empty, KeyboardInterrupt):
pass
rqueue.put((tot_files, okay_files, failed_files, verify_failed_files))
rqueue.close()
try:
procs = [Process(target=process_func) for i in range(numproc)]
for p in procs:
p.start()
for p in procs:
p.join()
try:
(tot_files, okay_files, failed_files, verify_failed_files) = (0, 0, 0, 0)
while True:
(t, o, f, v) = rqueue.get(False)
tot_files += t
okay_files += o
failed_files += f
verify_failed_files += v
except Empty:
pass
print('# decompiled %i files: %i okay, %i failed, %i verify failed' %
(tot_files, okay_files, failed_files, verify_failed_files))
except (KeyboardInterrupt, OSError):
pass
if timestamp:
print(time.strftime(timestampfmt))
from uncompyle6.bin.uncompile import main_bin
main_bin()

View File

@@ -6,7 +6,8 @@ machine:
dependencies:
override:
- pip install -r test-requirements.txt
- pip install -r requirements.txt
- pip install -r requirements-dev.txt
test:
override:
- python ./setup.py develop && make check-2.7

41
pytest/test_fjt.py Normal file
View File

@@ -0,0 +1,41 @@
#!/usr/bin/env python
from uncompyle6 import PYTHON_VERSION
from uncompyle6.scanner import get_scanner
from array import array
def bug(state, slotstate):
if state:
if slotstate is not None:
for key, value in slotstate.items():
setattr(state, key, 2)
def test_if_in_for():
code = bug.__code__
scan = get_scanner(PYTHON_VERSION)
print(PYTHON_VERSION)
if 2.7 <= PYTHON_VERSION <= 3.0:
n = scan.setup_code(code)
scan.build_lines_data(code, n)
scan.build_prev_op(n)
fjt = scan.find_jump_targets()
assert {15: [3], 69: [66], 63: [18]} == fjt
print(scan.structs)
assert scan.structs == \
[{'start': 0, 'end': 72, 'type': 'root'},
{'start': 18, 'end': 66, 'type': 'if-then'},
{'start': 31, 'end': 59, 'type': 'for-loop'},
{'start': 62, 'end': 63, 'type': 'for-else'}]
elif 3.2 < PYTHON_VERSION <= 3.4:
scan.code = array('B', code.co_code)
scan.build_lines_data(code)
scan.build_prev_op()
fjt = scan.find_jump_targets()
assert {69: [66], 63: [18]} == fjt
assert scan.structs == \
[{'end': 72, 'type': 'root', 'start': 0},
{'end': 66, 'type': 'if-then', 'start': 6},
{'end': 63, 'type': 'if-then', 'start': 18},
{'end': 59, 'type': 'for-loop', 'start': 31},
{'end': 63, 'type': 'for-else', 'start': 62}]
else:
assert True, "FIXME: should note fixed"
return

View File

@@ -1,10 +1,13 @@
import sys
import os, sys
from uncompyle6.load import load_file, check_object_path, load_module
def test_load():
"""Basic test of load_file, check_object_path and load_module"""
co = load_file(__file__)
obj_path = check_object_path(__file__)
version, timestamp, magic_int, co2 = load_module(obj_path)
assert sys.version[0:3] == str(version)
assert co == co2
if os.path.exists(obj_path):
version, timestamp, magic_int, co2 = load_module(obj_path)
assert sys.version[0:3] == str(version)
assert co == co2
else:
assert True, "Skipped because we can't find %s" % obj_path

20
pytest/test_marsh.py Normal file
View File

@@ -0,0 +1,20 @@
#!/usr/bin/env python
import os.path
from uncompyle6.load import load_module
def get_srcdir():
filename = os.path.normcase(os.path.dirname(os.path.abspath(__file__)))
return os.path.realpath(filename)
srcdir = get_srcdir()
def test_load_module():
"""Tests uncompile6.load.load_module"""
# We deliberately pick a bytecode that we aren't likely to be running against
mod_file = os.path.join(get_srcdir(), '..', 'test', 'bytecode_2.5',
'02_complex.pyc')
version, timestamp, magic_int, co = load_module(mod_file)
assert version == 2.5, "Should have picked up Python version properly"
assert co.co_consts == (5j, None), "Code should have a complex constant"

View File

@@ -0,0 +1,21 @@
import pytest
from uncompyle6 import PYTHON_VERSION, PYTHON3, deparse_code
def test_single_mode():
single_expressions = (
'i = 1',
'i and (j or k)',
'i += 1',
'i = j % 4',
'i = {}',
'i = []',
'while i < 1 or stop:\n i\n',
'while i < 1 or stop:\n print%s\n' % ('(i)' if PYTHON3 else ' 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'

View File

@@ -1,13 +1,11 @@
# Python 2.7
# Embedded file name: simple_source/branching/05_if.py
6 0 LOAD_NAME 'True'
3 POP_JUMP_IF_FALSE '15'
7 6 LOAD_NAME 'False'
9 STORE_NAME 'b'
12 JUMP_FORWARD '15'
15_0 COME_FROM '12'
15 LOAD_CONST ''
18 RETURN_VALUE ''
6 0 LOAD_NAME 0 'True'
3 POP_JUMP_IF_FALSE 15 '15'
7 6 LOAD_NAME 1 'False'
9 STORE_NAME 2 'b'
12 JUMP_FORWARD 0 '15'
15 LOAD_CONST 0 ''
18 RETURN_VALUE ''

View File

@@ -1,16 +1,14 @@
# Python 2.7
# Embedded file name: simple_source/branching/05_ifelse.py
3 0 LOAD_NAME 'True'
3 POP_JUMP_IF_FALSE '15'
3 0 LOAD_NAME 0 'True'
3 POP_JUMP_IF_FALSE 15 '15'
4 6 LOAD_CONST 1
9 STORE_NAME 'b'
12 JUMP_FORWARD '21'
6 15 LOAD_CONST 2
18 STORE_NAME 'd'
21_0 COME_FROM '12'
21 LOAD_CONST ''
24 RETURN_VALUE ''
4 6 LOAD_CONST 0 1
9 STORE_NAME 1 'b'
12 JUMP_FORWARD 6 '21'
6 15 LOAD_CONST 1 2
18 STORE_NAME 2 'd'
21 LOAD_CONST 2 ''
24 RETURN_VALUE ''

View File

@@ -1 +1,2 @@
pytest
flake8

1
requirements.txt Normal file
View File

@@ -0,0 +1 @@
spark-parser >= 1.2.1

View File

@@ -6,3 +6,6 @@ doc_files = README
# USAGE.txt
# doc/
# examples/
[bdist_wheel]
universal=1

View File

@@ -1,39 +1,29 @@
#! python
#!/usr/bin/env python
"""Setup script for the 'uncompyle6' distribution."""
from distutils.core import setup, Extension
# Get the package information used in setup().
# from __pkginfo__ import \
# author, author_email, classifiers, \
# install_requires, license, long_description, \
# modname, packages, py_modules, \
# short_desc, version, web, zip_safe
from __pkginfo__ import \
author, author_email, \
long_description, \
modname, packages, py_modules, scripts, \
short_desc, version, web, zip_safe
__import__('pkg_resources')
from setuptools import setup
author, author_email, install_requires, \
license, long_description, classifiers, \
entry_points, modname, py_modules, \
short_desc, VERSION, web, \
zip_safe
from setuptools import setup, find_packages
setup(
author = author,
author_email = author_email,
# classifiers = classifiers,
classifiers = classifiers,
description = short_desc,
# install_requires = install_requires,
# license = license,
entry_points = entry_points,
install_requires = install_requires,
license = license,
long_description = long_description,
py_modules = py_modules,
name = modname,
packages = packages,
packages = find_packages(),
py_modules = py_modules,
test_suite = 'nose.collector',
url = web,
setup_requires = ['nose>=1.0'],
scripts = scripts,
version = version,
version = VERSION,
zip_safe = zip_safe)

View File

@@ -19,28 +19,45 @@ check:
@$(PYTHON) -V && PYTHON_VERSION=`$(PYTHON) -V 2>&1 | cut -d ' ' -f 2 | cut -d'.' -f1,2`; \
$(MAKE) check-$$PYTHON_VERSION
#: Run working tests from Python 2.6
check-2.6: check-bytecode-2.5 check-bytecode-2.7
#: Run working tests from Python 2.6 or 2.7
check-2.6 check-2.7: check-bytecode check-2.7-ok
#: Run working tests from Python 2.7
check-2.7: check-bytecode check-2.7-ok
#: Run working tests from Python 3.2
check-3.2: check-bytecode
$(PYTHON) test_pythonlib.py --bytecode-3.2 --verify $(COMPILE)
#: Run working tests from Python 3.3
check-3.3: check-bytecode
$(PYTHON) test_pythonlib.py --bytecode-3.3 --verify $(COMPILE)
#: Run working tests from Python 3.5
check-3.5: check-bytecode
#: Run working tests from Python 3.4
check-3.4: check-bytecode check-bytecode-3.4
$(PYTHON) test_pythonlib.py --bytecode-3.4
check-3.4: check-bytecode check-3.4-ok check-2.7-ok
$(PYTHON) test_pythonlib.py --bytecode-3.4 --verify $(COMPILE)
#: Check deparsing only, but from a different Python version
check-disasm:
$(PYTHON) dis-compare.py
#: Check deparsing bytecode only
check-bytecode-2:
$(PYTHON) test_pythonlib.py --bytecode-2.5 --bytecode-2.6 --bytecode-2.7
#: Check deparsing bytecode only
check-bytecode:
$(PYTHON) test_pythonlib.py --bytecode-2.5 --bytecode-2.7 --bytecode-3.2
$(PYTHON) test_pythonlib.py --bytecode-2.5 --bytecode-2.6 --bytecode-2.7 \
--bytecode-3.2 --bytecode-3.3 --bytecode-3.4 --bytecode-3.5
#: Check deparsing Python 2.5
check-bytecode-2.5:
$(PYTHON) test_pythonlib.py --bytecode-2.5
#: Check deparsing Python 2.6
check-bytecode-2.6:
$(PYTHON) test_pythonlib.py --bytecode-2.6
#: Check deparsing Python 2.7
check-bytecode-2.7:
$(PYTHON) test_pythonlib.py --bytecode-2.7
@@ -49,10 +66,18 @@ check-bytecode-2.7:
check-bytecode-3.2:
$(PYTHON) test_pythonlib.py --bytecode-3.2
#: Check deparsing Python 3.3
check-bytecode-3.3:
$(PYTHON) test_pythonlib.py --bytecode-3.3
#: Check deparsing Python 3.4
check-bytecode-3.4:
$(PYTHON) test_pythonlib.py --bytecode-3.4
#: Check deparsing Python 3.5
check-bytecode-3.5:
$(PYTHON) test_pythonlib.py --bytecode-3.5
#: short tests for bytecodes only for this version of Python
check-native-short:
$(PYTHON) test_pythonlib.py --bytecode-$(PYTHON_VERSION) --verify $(COMPILE)
@@ -61,6 +86,14 @@ check-native-short:
check-2.7-ok:
$(PYTHON) test_pythonlib.py --ok-2.7 --verify $(COMPILE)
#: Run longer Python 3.2's lib files known to be okay
check-3.2-ok:
$(PYTHON) test_pythonlib.py --ok-3.2 --verify $(COMPILE)
#: Run longer Python 3.4's lib files known to be okay
check-3.4-ok:
$(PYTHON) test_pythonlib.py --ok-3.4 --verify $(COMPILE)
clean: clean-py-dis clean-dis clean-unverified
clean-dis:

View File

@@ -1,77 +0,0 @@
#!/usr/bin/env python
from __future__ import print_function
"""
compile_tests -- compile test patterns for the decompyle test suite
"""
import py_compile, os, sys, getopt
work_dir = os.path.dirname(sys.argv[0])
src_dir = work_dir
opts, args = getopt.getopt(sys.argv[1:], 's:w:')
for opt, val in opts:
if opt == '-s':
src_dir = val
if opt == '-w':
work_dir = val
else:
raise "Unknown Option '%s'" % opt
if args:
raise 'This tool does not want any arguments'
print("Using files in dir %s" % src_dir)
print("Compiling into dir %s" % work_dir)
tests = {}
tests['1.5'] = ["class", "del", "docstring", 'empty', "exec",
"exceptions", "expressions", "functions", "global",
"globals", "import", "integers", "lambda", "loops",
"misc", "nested_elif", "prettyprint", "print",
'single_stmt', "slices", "tuple_params", 'tuples']
tests['1.6'] = ["applyEquiv", ] + tests['1.5']
tests['2.0'] = ["augmentedAssign", "extendedImport", "extendedPrint",
"import_as", "listComprehensions", 'print_to'] + \
tests['1.6'] # [ "--extendedarg", ]
tests['2.1'] = ['loops2', 'nested_scopes'] + tests['2.0']
tests['2.2'] = ['divide_future', 'divide_no_future', 'iterators',
'yield'] + tests['2.1']
tests['2.3'] = tests['2.2']
tests['2.5'] = tests['2.3']
tests['2.6'] = tests['2.5']
tests['2.7'] = ['mine'] + tests['2.6']
tests['3.4'] = ['mine']
total_tests = len(tests['2.7'])
#tests['2.2'].sort(); print tests['2.2']
extension = '.py' + (__debug__ and 'c' or 'o')
def compile(file, target_dir):
sfile = os.path.join(src_dir, 'test_%s.py' % file)
cfile = os.path.join(target_dir, 'test_%s%s' % (file, extension) )
py_compile.compile(sfile, cfile=cfile)
def compile_for_version(version):
target_dir = os.path.join(work_dir, 'bytecode_' + version)
if not os.path.exists(target_dir):
os.mkdir(target_dir)
for file in tests[version]:
compile(file, target_dir)
try:
version = '%i.%i' % sys.version_info[:2]
except AttributeError:
version = sys.version[:3]
print('Compiling test files for Python', version)
print('(%i/%i files)' % (len(tests[version]), total_tests))
compile_for_version(version)
print('Done.')

View File

@@ -1,23 +0,0 @@
def kwfunc(**kwargs):
print kwargs.items()
def argsfunc(*args):
print args
def no_apply(*args, **kwargs):
print args
print kwargs.items()
argsfunc(34)
foo = argsfunc(*args)
argsfunc(*args)
argsfunc(34, *args)
kwfunc(**kwargs)
kwfunc(x=11, **kwargs)
no_apply(*args, **kwargs)
no_apply(34, *args, **kwargs)
no_apply(x=11, *args, **kwargs)
no_apply(34, x=11, *args, **kwargs)
no_apply(42, 34, x=11, *args, **kwargs)
no_apply(1,2,4,8,a=2,b=3,c=5)

View File

@@ -1,45 +0,0 @@
raise "This program can't be run"
a = 1
b = 2
a += b; print a # a = a+b = 3
a -= b; print a # a = a-b = 1
a *= b; print a # a = a*b = 2
a -= a; print a # a = a-a = 0
a += 7*3; print a # == 21
l= [1,2,3]
l[1] *= 3; print l[1]; # 6
l[1][2][3] = 7
l[1][2][3] *= 3;
l[:] += [9]; print l
l[:2] += [9]; print l
l[1:] += [9]; print l
l[1:4] += [9]; print l
l += [42,43]; print l
a.value = 1
a.value += 1;
a.b.val = 1
a.b.val += 1;
l = []
for i in range(3):
lj = []
for j in range(3):
lk = []
for k in range(3):
lk.append(0)
lj.append(lk)
l.append(lj)
i = j = k = 1
def f():
global i
i += 1
return i
l[i][j][k] = 1
i = 1
l[f()][j][k] += 1
print i, l

View File

@@ -1,34 +0,0 @@
class A:
class A1:
def __init__(self):
print 'A1.__init__'
def foo(self):
print 'A1.foo'
def __init__(self):
print 'A.__init__'
def foo(self):
print 'A.foo'
class B:
def __init__(self):
print 'B.__init__'
def bar(self):
print 'B.bar'
class C(A,B):
def foobar(self):
print 'C.foobar'
c = C()
c.foo()
c.bar()
c.foobar()

View File

@@ -1,24 +0,0 @@
raise "This program can't be run"
print 0
a = b[5]
print 1
del a
print 2
del b[5]
print 3
del testme[1]
print 4
del testme[:]
print '4a'
del testme[:42]
print '4b'
del testme[40:42]
print 5
del testme[2:1024:10]
print '5a'
del testme[40,41,42]
print 6
del testme[:42, ..., :24:, 24, 100]
print 7

View File

@@ -1,6 +0,0 @@
from __future__ import division
print ' 1 // 2 =', 1 // 2
print '1.0 // 2.0 =', 1.0 // 2.0
print ' 1 / 2 =', 1 / 2
print '1.0 / 2.0 =', 1.0 / 2.0

View File

@@ -1,6 +0,0 @@
#from __future__ import division
print ' 1 // 2 =', 1 // 2
print '1.0 // 2.0 =', 1.0 // 2.0
print ' 1 / 2 =', 1 / 2
print '1.0 / 2.0 =', 1.0 / 2.0

View File

@@ -1,34 +0,0 @@
'''
This is a doc string
'''
def Doc_Test():
"""This has to be present"""
class XXX:
def __init__(self):
"""__init__: This has to be present"""
self.a = 1
def XXX22():
"""XXX22: This has to be present"""
pass
def XXX11():
"""XXX22: This has to be present"""
pass
def XXX12():
foo = """XXX22: This has to be present"""
pass
def XXX13():
pass
def Y11():
def Y22():
def Y33():
pass
print __doc__

View File

@@ -1,107 +0,0 @@
import dis
def x11():
try:
a = 'try except'
except:
a = 2
b = '--------'
def x12():
try:
a = 'try except else(pass)'
except:
a = 2
b = '--------'
def x13():
try:
a = 'try except else(a=3)'
except:
a = 2
else:
a = 3
b = '--------'
def x21():
try:
a = 'try KeyError'
except KeyError:
a = 8
b = '--------'
def x22():
try:
a = 'try (IdxErr, KeyError) else(pass)'
except (IndexError, KeyError):
a = 8
b = '--------'
def x23():
try:
a = 'try KeyError else(a=9)'
except KeyError:
a = 8
else:
a = 9
b = '--------'
def x31():
try:
a = 'try KeyError IndexError'
except KeyError:
a = 8
except IndexError:
a = 9
b = '--------'
def x32():
try:
a = 'try KeyError IndexError else(pass)'
except KeyError:
a = 8
except IndexError:
a = 9
b = '--------'
def x33():
try:
a = 'try KeyError IndexError else(a=9)'
except KeyError:
a = 8
except IndexError:
a = 9
else:
a = 9
b = '#################'
def x41():
if (a == 1):
a = 1
elif (b == 1):
b = 1
else:
c = 1
b = '#################'
def x42():
if (a == 1):
a = 1
elif (b == 1):
b = 1
else:
c = 1
xxx = 'mmm'
if (__name__ == '__main__'):
dis.dis(xx)

View File

@@ -1,5 +0,0 @@
testcode = 'a = 12'
exec testcode
exec testcode in globals()
exec testcode in globals(), locals()

View File

@@ -1,10 +0,0 @@
def _lsbStrToInt(str):
return ord(str[0]) + \
(ord(str[1]) << 8) + \
(ord(str[2]) << 16) + \
(ord(str[3]) << 24)
def test(x):
return x
test(a == b == c == 1)

View File

@@ -1,10 +0,0 @@
import os, sys as System, time
import sys
from rfc822 import Message as Msg822
from mimetools import Message as MimeMsg, decode, choose_boundary as MimeBoundary
import test.test_StringIO as StringTest
for k, v in globals().items():
print `k`, v

View File

@@ -1,6 +0,0 @@
import sys
print >> sys.stdout, "Hello World"
print >> sys.stdout, 1,2,3
print >> sys.stdout, 1,2,3,
print >> sys.stdout

File diff suppressed because it is too large Load Diff

View File

@@ -1,58 +0,0 @@
def x0():
pass
def x1(arg1):
pass
def x2(arg1,arg2):
pass
def x3a(*args):
pass
def x3b(**kwargs):
pass
def x3c(*args, **kwargs):
pass
def x4a(foo, bar=1, bla=2, *args):
pass
def x4b(foo, bar=1, bla=2, **kwargs):
pass
def x4c(foo, bar=1, bla=2, *args, **kwargs):
pass
def func_with_tuple_args((a,b)):
print a
print b
def func_with_tuple_args2((a,b), (c,d)):
print a
print c
def func_with_tuple_args3((a,b), (c,d), *args):
print a
print c
def func_with_tuple_args4((a,b), (c,d), **kwargs):
print a
print c
def func_with_tuple_args5((a,b), (c,d), *args, **kwargs):
print a
print c
def func_with_tuple_args6((a,b), (c,d)=(2,3), *args, **kwargs):
print a
print c
def func_ret1():
return 1 < 2 < 3
def read(size=0):
if size > 0 and size <= x - cur:
return 0
return 0

View File

@@ -1,16 +0,0 @@
i = 1; j = 7
def a():
def b():
def c():
k = 34
global i
i = i+k
l = 42
c()
global j
j = j+l
b()
print i, j # should print 35, 49
a()
print i, j

View File

@@ -1,10 +0,0 @@
def f():
print x # would result in a 'NameError' or 'UnboundLocalError'
x = x+1
print x
raise "This program can't be run"
x = 1
f()
print x

View File

@@ -1,11 +0,0 @@
import sys
import os, sys, BaseHTTPServer
import test.test_MimeWriter
from rfc822 import Message
from mimetools import Message, decode, choose_boundary
from os import *
for k, v in globals().items():
print `k`, v

View File

@@ -1,13 +0,0 @@
import sys as SYS
import os as OS, sys as SYSTEM, BaseHTTPServer as HTTPServ
import test.test_MimeWriter as Mime_Writer
from rfc822 import Message as MSG
from mimetools import Message as mimeMsg, decode, \
choose_boundary as mimeBoundry
print '---' * 20
for k, v in globals().items():
print k, repr(v)

View File

@@ -1,22 +0,0 @@
import sys
#raise "This program can't be run"
i = 1
i = 42
i = -1
i = -42
i = sys.maxint
minint = -sys.maxint-1
print sys.maxint
print minint
print long(minint)-1
print
i = -2147483647 # == -maxint
print i, repr(i)
i = i-1
print i, repr(i)
i = -2147483648L # == minint == -maxint-1
print i, repr(i)
i = -2147483649L # == minint-1 == -maxint-2
print i, repr(i)

View File

@@ -1,11 +0,0 @@
for i in range(20):
print i,
print
for i in range(10):
print i,
#if i == 10: break
else:
print 'The End'

View File

@@ -1,8 +0,0 @@
palette = map(lambda a: (a,a,a), range(256))
palette = map(lambda (r,g,b): chr(r)+chr(g)+chr(b), palette)
palette = map(lambda r: r, palette)
palette = lambda (r,g,b,): r
palette = lambda (r): r
palette = lambda r: r
palette = lambda (r): r, palette

View File

@@ -1,30 +0,0 @@
XXX = range(4)
print [i for i in XXX]
print
print [i for i in (1,2,3,4,)]
print
print [i for i in [1,2,3,4,]]
print
print [(i,1) for i in XXX]
print
print [i*2 for i in range(4)]
print
print [i*j for i in range(4)
for j in range(7)]
print [i*2 for i in range(4) if i == 0 ]
print [(i,i**2) for i in range(4) if (i % 2) == 0 ]
print [i*j for i in range(4)
if i == 2
for j in range(7)
if (i+i % 2) == 0 ]
seq1 = 'abc'
seq2 = (1,2,3)
[ (x,y) for x in seq1 for y in seq2 ]
def flatten1(seq):
return [x for subseq in seq for x in subseq]
print flatten1([[0], [1,2,3], [4,5], [6,7,8,9], []])

View File

@@ -1,58 +0,0 @@
for i in range(10):
if i == 3:
continue
if i == 5:
break
print i,
else:
print 'Else'
print
for i in range(10):
if i == 3:
continue
print i,
else:
print 'Else'
i = 0
while i < 10:
i = i+1
if i == 3:
continue
if i == 5:
break
print i,
else:
print 'Else'
print
i = 0
while i < 10:
i = i+1
if i == 3:
continue
print i,
else:
print 'Else'
for x, y in [(1,2),(3,4)]:
if x in ['==', '>=', '>']:
if '0' in y:
print
for x in (1, 2, 3):
if x == 1:
print x
i = 0
while i < 10:
i+=1
for x in (1,2,3):
for y in (1,2,3):
if x == y and x == 1:
while i < 10:
print x
break

View File

@@ -1,10 +0,0 @@
# This is a seperate test pattern, since 'continue' within 'try'
# was not allowed till Python 2.1
for term in args:
try:
print
continue
print
except:
pass

View File

@@ -1,5 +0,0 @@
sum(i*i for i in range(10))
sum(x*y for x,y in zip(xvec, yvec))

View File

@@ -1,23 +0,0 @@
raise "This program can't be run"
class A:
def __init__(self, num):
self.num = num
def __repr__(self):
return str(self.num)
b = []
for i in range(10):
b.append(A(i))
for i in ('CALL_FUNCTION', 'CALL_FUNCTION_VAR',
'CALL_FUNCTION_VAR_KW', 'CALL_FUNCTION_KW'):
print i, '\t', len(i), len(i)-len('CALL_FUNCTION'),
print (len(i)-len('CALL_FUNCTION')) / 3,
print i[len('CALL_FUNCTION'):]
p2 = (0, 0, None)
if p2[2]:
print 'has value'
else:
print ' no value'

View File

@@ -1,81 +0,0 @@
a = None
if a == 1:
print '1'
elif a == 2:
print '2'
if a == 1:
print '1'
elif a == 2:
print '2'
else:
print 'other'
if a == 1:
print '1'
elif a == 2:
print '2'
elif a == 3:
print '3'
else:
print 'other'
if a == 1:
print '1'
elif a == 2:
print '2'
elif a == 3:
print '3'
if a == 1:
print '1'
else:
if a == 2:
print '2'
else:
if a == 3:
print '3'
else:
print 'other'
if a == 1:
print '1'
else:
if a == 2:
print '2'
else:
print 'more'
if a == 3:
print '3'
else:
print 'other'
if a == 1:
print '1'
else:
print 'more'
if a == 2:
print '2'
else:
if a == 3:
print '3'
else:
print 'other'
if a == 1:
print '1'
else:
print 'more'
if a == 2:
print '2'
else:
print 'more'
if a == 3:
print '3'
elif a == 4:
print '4'
elif a == 4:
print '4'
else:
print 'other'

View File

@@ -1,87 +0,0 @@
from __future__ import nested_scopes
blurb = 1
def k0():
def l0(m=1):
print
l0()
def x0():
def y0():
print
y0()
def x1():
def y1():
print 'y-blurb =', blurb
y1()
def x2():
def y2():
print
blurb = 2
y2()
def x3a():
def y3a(x):
print 'y-blurb =', blurb, flurb
print
blurb = 3
flurb = 7
y3a(1)
print 'x3a-blurb =', blurb
def x3():
def y3(x):
def z():
blurb = 25
print 'z-blurb =', blurb,
z()
print 'y-blurb =', blurb,
print
blurb = 3
y3(1)
print 'x3-blurb =', blurb
def x3b():
def y3b(x):
def z():
print 'z-blurb =', blurb,
blurb = 25
z()
print 'y-blurb =', blurb,
print
blurb = 3
y3b(1)
print 'x3-blurb =', blurb
def x4():
def y4(x):
def z():
print 'z-blurb =', blurb
z()
global blurb
blurb = 3
y4(1)
def x():
def y(x):
print 'y-blurb =', blurb
blurb = 2
y(1)
def func_with_tuple_args6((a,b), (c,d)=(2,3), *args, **kwargs):
def y(x):
print 'y-a =', a
print c
def find(self, name):
# This is taken from 'What's new in Python 2.1' by amk
L = filter(lambda x, name: x == name, self.list_attribute)
x0(); x1(); x2();
x3(); x3a(); x3b();
x4(); x()
print 'blurb =', blurb

View File

@@ -1,128 +0,0 @@
import pprint
aa = 'aa'
dict0 = {
'a': 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
'b': 1234,
'd': aa,
aa: aa
}
dict = {
'a': 'aaa',
'b': 1234,
'c': { 'ca': 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
'cb': 1234,
'cc': None
},
'd': aa,
aa: aa,
'eee': { 'ca': 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
'cb': 1234,
'cc': None
},
'ff': aa,
}
list1 = [ '1aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
aa,
'1bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
'1ccccccccccccccccccccccccccccccccccccccccccc' ]
list2 = [ '2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
[ '22aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
aa,
'22bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
'22ccccccccccccccccccccccccccccccccccccccccccc' ],
'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
'ccccccccccccccccccccccccccccccccccccccccccc' ]
tuple1 = ( '1aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
aa,
'1bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
'1ccccccccccccccccccccccccccccccccccccccccccc' )
tuple2 = ( '2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
( '22aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
aa,
'22bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
'22ccccccccccccccccccccccccccccccccccccccccccc' ),
'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
'ccccccccccccccccccccccccccccccccccccccccccc' )
def funcA():
dict = {
'a': 'aaa',
'b': 1234,
'c': { 'ca': 'aaa',
'cb': 1234,
'cc': None
},
'd': aa,
aa: aa
}
list1 = [ '1aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
'1bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
aa,
'1ccccccccccccccccccccccccccccccccccccccccccc' ]
list2 = [ '2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
[ '22aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
aa,
'22bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
'22ccccccccccccccccccccccccccccccccccccccccccc' ],
'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
'ccccccccccccccccccccccccccccccccccccccccccc' ]
tuple1 = ( '1aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
'1bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
aa,
'1ccccccccccccccccccccccccccccccccccccccccccc' )
tuple2 = ( '2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
( '22aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
aa,
'22bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
'22ccccccccccccccccccccccccccccccccccccccccccc' ),
'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
'ccccccccccccccccccccccccccccccccccccccccccc' )
def funcAB():
dict = {
'a': 'aaa',
'b': 1234,
'c': { 'ca': 'aaa',
'cb': 1234,
'cc': None
},
'd': aa,
aa: aa
}
list1 = [ '1aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
'1bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
'1ccccccccccccccccccccccccccccccccccccccccccc' ]
list2 = [ '2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
[ '22aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
'22bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
'22ccccccccccccccccccccccccccccccccccccccccccc' ],
'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
'ccccccccccccccccccccccccccccccccccccccccccc' ]
tuple1 = ( '1aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
'1bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
'1ccccccccccccccccccccccccccccccccccccccccccc' )
tuple2 = ( '2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
( '22aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
'22bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
'22ccccccccccccccccccccccccccccccccccccccccccc' ),
'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
'ccccccccccccccccccccccccccccccccccccccccccc' )
pprint.pprint(dict0)
print
pprint.pprint(dict)
print
pprint = pprint.PrettyPrinter(indent=2)
pprint.pprint(dict0)
print
pprint.pprint(dict)
print
pprint.pprint(list1)
print
pprint.pprint(list2)

View File

@@ -1,9 +0,0 @@
print 1,2,3,4,5
a = b + 5
print 1,2,3,4,5
print 1,2,3,4,5
print
print
print 1,2,3,4,5
print

View File

@@ -1,13 +0,0 @@
import sys
print >>sys.stdout, 1,2,3,4,5
print >>sys.stdout, 1,2,3,4,5,
print >>sys.stdout
print >>sys.stdout, 1,2,3,4,5,
print >>sys.stdout, 1,2,3,4,5,
print >>sys.stdout
print >>sys.stdout

View File

@@ -1 +0,0 @@
print 5

View File

@@ -1,32 +0,0 @@
raise "This program can't be run"
testme[1]
testme[1] = 1
del testme[1]
testme[:42]
testme[:42] = "The Answer"
del testme[:42]
testme[2:1024:]
testme[:1024:10]
testme[::]
testme[2:1024:10]
testme[2:1024:10] = "A lot"
del testme[2:1024:10]
testme[:42, ..., :24:, 24, 100]
testme[:42, ..., :24:, 24, 100] = "Strange"
del testme[:42, ..., :24:, 24, 100]
testme[:]
testme[:] = 'Take all'
del testme[:]
testme[40:42]
testme[40:42] = 'Three'
del testme[40:42]
testme[40,41,42]
testme[40,41,42] = 'Another Three'
del testme[40,41,42]

View File

@@ -1,14 +0,0 @@
def A(a,b,(x,y,z),c):
pass
def B(a,b=42,(x,y,z)=(1,2,3),c=17):
pass
def C((x,y,z)):
pass
def D((x,)):
pass
def E((x)):
pass

View File

@@ -1,20 +0,0 @@
a = (1,)
b = (2,3)
a,b = (1,2)
a,b = ( (1,2), (3,4,5) )
x = {}
try:
x[1,2,3]
except:
pass
x[1,2,3] = 42
print x[1,2,3]
print x[(1,2,3)]
assert x[(1,2,3)] == x[1,2,3]
del x[1,2,3]
x=[1,2,3]
b=(1 for i in x if i)
b=(e for i in range(4) if i == 2)

View File

@@ -1,22 +0,0 @@
from __future__ import generators
def inorder(t):
if t:
for x in inorder(t.left):
yield x
yield t.label
for x in inorder(t.right):
yield x
def generate_ints(n):
for i in range(n):
yield i*2
for i in generate_ints(5):
print i,
print
gen = generate_ints(3)
print gen.next(),
print gen.next(),
print gen.next(),
print gen.next()

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.

BIN
test/bytecode_2.6/05_if.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.

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.

Binary file not shown.

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