Compare commits

..

88 Commits

Author SHA1 Message Date
rocky
ebad4e2a9a Readme link typo 2020-02-09 13:36:53 -05:00
rocky
e342ef89e3 Get ready for release 3.6.4 2020-02-09 13:26:53 -05:00
rocky
57d59aa481 Update README.rst 2020-02-09 12:44:21 -05:00
rocky
6545d9a03b runtests excludes again 2020-02-09 09:42:38 -05:00
rocky
8ac35ad8ce Need to back off ifelsetesting on 2.7...
until we can more fully untangle if stmts in loops.
Current tests break urllib2.pyc and cgi.pyc
2020-02-09 09:01:32 -05:00
rocky
8836444be2 Correct ifelsestmtc rules for 3.x 2020-02-09 08:14:44 -05:00
rocky
339b4c56ee Typo 2020-02-09 07:38:32 -05:00
rocky
6cbb631aa6 In lambda code we, no stinking bogus yield 2020-02-09 07:32:06 -05:00
rocky
5355cb5404 async with rules back to 3.5 and ...
add precidence on cascaded "await" expressions
2020-02-08 20:31:06 -05:00
rocky
8495d208fb 3.7+ "async with" handling from decompyle3 2020-02-08 19:48:09 -05:00
rocky
e1758a8730 3.5 runtests exclusions 2020-02-08 15:50:12 -05:00
rocky
c1a825fbbb 3.6 runtests exclusions 2020-02-08 15:46:00 -05:00
rocky
8f2e408da2 Another 3.5 runtest exclusion 2020-02-08 15:25:42 -05:00
rocky
e2504c2421 3.7 ifelstmtl reduction rule checking 2020-02-08 13:47:05 -05:00
rocky
1d7085e5d2 Add 3.5 runtest exclusion 2020-02-08 12:07:35 -05:00
rocky
65707fa0f8 FIx bug that snuck in last commit. 2020-02-08 12:01:56 -05:00
rocky
b0931275a2 Need more precise "assert" for 3.8...
Add rule for ifelsestmtl which is needed in 3.8
2020-02-08 11:46:19 -05:00
rocky
7c73536b4a 3.6 "assert" and "or" handling bugs 2020-02-08 07:27:31 -05:00
rocky
946d46a574 Fix Python 3.6 "if" parse failures in loops...
This fixes all the pyenv parse errors that were introduced in the last refactor.
2020-02-08 05:21:42 -05:00
rocky
2b50cb56d7 One more 3.6 runtest exclude 2020-02-07 20:53:31 -05:00
rocky
6d5fb21363 Go over 3.2-3.6 runtests.sh exludes...
Reinstate a lot of tests broken since c90ff51
2020-02-07 20:09:40 -05:00
rocky
bd7d74fa5d 3.7 excludes again 2020-02-07 19:44:24 -05:00
rocky
c93a7a728b Add decompyle3 ifelsestmt reduction rule...
and Go over 3.3 and 3.7 runtests excludes
2020-02-07 19:22:23 -05:00
R. Bernstein
26a554c5c7 Merge pull request #306 from rocky/ifexp_from_conditional
if_exp from conditional
2020-02-07 18:26:12 -05:00
rocky
cb35ad906c One more if_exp use (ret_cond) 2020-02-07 16:34:48 -05:00
rocky
278af38df6 conditional -> if_exp ...
to match Python IfExp AST
2020-02-07 16:17:47 -05:00
rocky
7fb50918cd Bug in "async for" indentation 2020-02-06 23:54:03 -05:00
rocky
6525ade805 Comment tweaks 2020-02-06 20:37:40 -05:00
rocky
73951840b6 Correct last commit 2020-02-06 20:19:29 -05:00
rocky
3438e76865 "return locals()" change to track grammar change 2020-02-06 20:08:00 -05:00
rocky
7480af33d9 CircleCI again 2020-02-06 05:24:02 -05:00
rocky
88b2be70d2 CircleCI again 2020-02-06 05:22:48 -05:00
rocky
73de86728a CircleCI again 2020-02-06 05:21:45 -05:00
rocky
f743639bb6 CircleCI again 2020-02-06 05:20:02 -05:00
rocky
321c7906cd CircleCI again 2020-02-06 05:18:35 -05:00
rocky
06b281d1d8 Try to expand CircleCI testing 2020-02-06 05:14:29 -05:00
rocky
a99d8da0b4 Fix Recent CI bug 2020-02-06 05:10:57 -05:00
rocky
73e6409594 Fix recent CI bug 2020-02-06 05:09:17 -05:00
rocky
e93628d2dd Update CircleCI to test with 3.6.10 2020-02-06 05:04:39 -05:00
rocky
e41cd9be84 hide __qualname__ and name modules again...
due to recent grammar change
2020-02-06 03:19:56 -05:00
rocky
9166fb54a1 Adjust a couple of "assert"s 2020-02-04 22:06:48 -05:00
rocky
3120de0c02 Go over older 2.4 runtests failures 2020-02-04 22:01:49 -05:00
rocky
68c9de60a5 Adjust assert transform for new "if_and" rule 2020-02-04 21:28:08 -05:00
rocky
621bc96e8a Ensure offset is an int in offset test 2020-02-04 20:20:40 -05:00
rocky
6f4ec21ae2 __modname__ and __qualname__ detection...
since grammar has simplified.

May still need work for Python < 3.0
2020-02-02 19:09:50 -05:00
rocky
83e27bc427 Reinstate some 3.0 tests 2020-02-02 17:45:17 -05:00
rocky
9aae8f85c7 Bug introduced by last commit 2020-02-02 13:11:03 -05:00
rocky
04f8619cf1 Better docstring recognition 2020-02-02 13:02:37 -05:00
rocky
610994277c 2.7 ifelsestmt reduction rule futzing 2020-02-02 07:52:08 -05:00
rocky
6fff0fc5a2 More assert transform opportunities 2020-02-02 06:46:48 -05:00
rocky
e4a196278a More control-flow testing based on past failures...
Some of these still cause problems. Sigh.
2020-02-02 06:08:19 -05:00
rocky
6e5666c001 Merge branch 'master' of github.com:rocky/python-uncompyle6 2020-02-02 05:37:37 -05:00
rocky
38e2b8a10b Go over docstring handling 2020-02-02 05:37:07 -05:00
rocky
5d1bf2dd9b adjust "assert" transformation due to grammar ...
simplification
2020-02-01 22:27:17 -05:00
rocky
de1e7d423c A more correct offset2inst_index update. 2020-02-01 21:02:45 -05:00
rocky
16a51961c3 Add tests based on recent runtests.sh failures...
These run quicker and are distilled to simple examples.
2020-02-01 20:32:23 -05:00
rocky
0798078d7e See previous commit msg 2020-02-01 12:30:51 -05:00
rocky
db3c687784 See previous commit msg 2020-02-01 12:27:06 -05:00
rocky
0fafb38d35 Typo 2020-02-01 12:14:34 -05:00
rocky
f426101000 Another runtests.sh exclude for now 2020-02-01 12:11:51 -05:00
rocky
cf505545c0 3.6 iflastlstmt rule checking again 2020-02-01 12:00:08 -05:00
rocky
45c725feae 3.6 iflaststmtl doesn't follow ifstmt rules...
like iflaststmt does. test_dbm_dumb.py shows this
2020-02-01 11:20:58 -05:00
rocky
4dc64063d1 Small change 2020-02-01 11:14:19 -05:00
rocky
cdc5642715 More reduction checks...
Those in reduce check as well as those listed in parse{2,3}.

3.6 iflastsmtl needs ifstmt checking.
2020-02-01 07:10:30 -05:00
rocky
4f4850d9f7 Restrict "and" reduction checking to Python 3.6 2020-02-01 04:42:46 -05:00
rocky
451b18ee57 2.7 tryelse rule check disambiguation. 2020-02-01 04:05:50 -05:00
rocky
2d1ea6b02b See previous commit 2020-01-31 21:12:59 -05:00
rocky
f279cc2d70 ifelsesmt for 2.7 yet again 2020-01-31 21:10:24 -05:00
rocky
cb1b2a8759 Typo in last commit 2020-01-31 19:11:13 -05:00
rocky
d64158b299 No iflastlstmt reduce check for python < 3.6...
just yet
2020-01-31 19:07:28 -05:00
rocky
2ea8a2ef7f was getting testlastl reduce rule from wrong place 2020-01-31 17:37:47 -05:00
rocky
258fac3201 limit 3.x scope of ifelstmt reduction check to 3.6
at least for now. Again, we need major cleanup of this stuff, but that
will be done later.
2020-01-31 16:22:32 -05:00
rocky
7c012ebdfc Remove duplicate stmt 2020-01-31 15:50:46 -05:00
rocky
f27b72ab05 Work around 2.7 phony come-froms in ifelsesmt 2020-01-31 15:49:29 -05:00
rocky
be022b3416 Start ifelsestmt reduce checks in Python 2.7 2020-01-31 13:58:06 -05:00
rocky
41f1d1ec09 Remove dup statement 2020-01-31 13:18:23 -05:00
rocky
89c2805c27 Start to clean up parse3 reduction rule checks...
A lot more work is needed, but this is a start.
2020-01-31 13:10:35 -05:00
rocky
e639a30157 Add some decompyle reduction-check goodness here 2020-01-31 12:20:12 -05:00
rocky
ee2a1f62c6 runtests exclude found recently in 3.6 2020-01-31 04:46:25 -05:00
rocky
db46e096b4 See previous commit message 2020-01-31 03:53:35 -05:00
rocky
ea48944fff reinstate a test fixed recently 2020-01-31 03:08:36 -05:00
rocky
31714d3420 compile-file.py: preserve source file location 2020-01-30 21:09:34 -05:00
rocky
6466d30e2e Adjust "ifelsestmt" rule
Fixes #305
2020-01-30 19:45:32 -05:00
rocky
ef61f3a92a Add a 3.6 runtest exclude due to bad control flow 2020-01-30 18:02:44 -05:00
rocky
fdf4496a2d Track grammar "stmt" simplifications class ...
* NAME_MODULE constant
* QUAL_NAME constant
2020-01-29 15:37:58 -05:00
rocky
b548910e57 IMPORT_NAME -> IMPORT_NAME_ATTR
Fixes #304
2020-01-28 01:43:20 -05:00
R. Bernstein
c5f939e90d Merge pull request #302 from hjung4/spell
fix spelling errors
2020-01-27 20:33:01 -05:00
comet
6bbafcc8dd fix spelling errors 2020-01-27 18:41:55 -06:00
172 changed files with 1525 additions and 986 deletions

View File

@@ -12,9 +12,8 @@ jobs:
COMPILE: --compile
# To see the list of pre-built images that CircleCI provides for most common languages see
# https://circleci.com/docs/2.0/circleci-images/
machine:
python:
version: 2.7.14
docker:
- image: circleci/python:3.6.9
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
@@ -27,7 +26,7 @@ jobs:
# This is based on your 1.0 configuration file or project settings
- run:
working_directory: ~/rocky/python-uncompyle6
command: pyenv install 2.4.6 && pyenv local 2.4.6 && pyenv rehash && easy_install nose && pyenv rehash
command: pip install --user virtualenv && pip install --user nose && pip install --user pep8
# Dependencies
# This would typically go in either a build or a build-and-test job when using workflows
# Restore the dependency cache
@@ -38,8 +37,9 @@ jobs:
- v2-dependencies-
# This is based on your 1.0 configuration file or project settings
- run: easy_install xdis spark-parser
- run: pip install -e .
- run: pip install --user --upgrade setuptools
- run: pip install --user -e .
- run: pip install --user -r requirements-dev.txt
# Save dependency cache
- save_cache:
@@ -57,8 +57,8 @@ jobs:
# 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.4
- run: cd ./test/stdlib && pyenv local 2.4.6 && bash ./runtests.sh 'test_[p-z]*.py'
- run: sudo python ./setup.py develop && make check-3.6
- run: cd ./test/stdlib && 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

View File

@@ -1,7 +1,16 @@
language: python
python:
- 2.7 # this is a cheat here because travis doesn't do 2.4-2.6
- '3.5'
- '2.7'
- '3.4'
- '3.6'
- '3.8'
matrix:
include:
- python: '3.7'
dist: xenial # required for Python >= 3.7 (travis-ci/travis-ci#9069)
install:
- pip install -e .

View File

@@ -40,9 +40,8 @@ check-3.0 check-3.1 check-3.2 check-3.6:
check-3.7: pytest
$(MAKE) -C test check
#:Tests for Python 2.4-2.5 (don't have pytest)
check-2.4 check-2.5:
$(MAKE) -C test $@
check-3.8:
$(MAKE) -C test check
#:PyPy 2.6.1 PyPy 5.0.1, or PyPy 5.8.0-beta0
# Skip for now

50
NEWS.md
View File

@@ -1,3 +1,53 @@
3.6.4: 2020-2-9 Plateau
=======================
The main focus in this release was fix some of the more glaring problems creapt in from the last release due to that refactor.
`uncompyle6` code is at a plateau where what is most needed is a code refactoring. In doing this, until everything refactored and replaced, decomplation may get worse.
Therefore, this release largely serves as a checkpoint before more major upheaval.
The upheaval, in started last release, I believe the pinnicle was around c90ff51 which wasn't a release. I suppose I should tag that.
After c90ff5, I started down the road of redoing control flow in a more comprehensible, debuggable, and scalable way. See [The Control Flow Mess](https://github.com/rocky/python-uncompyle6/wiki/The-Control-Flow-Mess)
The bulk of the refactoring going on in the [decompyle3](https://github.com/rocky/python-decompil3) project, but I try to trickle down the changes.
It is tricky because the changes are large and I have to figure decompose things so that little testable pieces can be done. And there is also the problem that what is in decompyle3 is incomplete as well.
Other than control flow, another change that will probably happen in the next release is to redo the grammar for lambda expressions. Right now, we treat them as Python statements, you know, things with compound statements in them. But lambda aren't that. And so there is hackery to paper over difference making a statement out of an expression the wrong thing to do. For example, a return of an "and" expression can be expressed as nested "if" statements with return inside them, but the "if" variant of the bytecode is not valid in a lambda.
In the decompyle3 code, I've gone down the road making the grammar goal symbol be an expression. This also offers the opportunity to split the grammar making parsing inside lambda not only more reliable because the wrong choices don't exist, but also simpler and faster because all those rules just need don't need to exist in parsing.
I cringe in thinking about how the code has lived for so long without noticing such a simple stupidity, and lapse of sufficient thought.
Some stats from testing. The below give numbers of decompiled tests from Python's test suite which succesfully ran
```
Version test-suites passing
------- -------------------
2.4.6 243
2.5.6 265
2.6.9 305
3.3.7 300
3.4.10 304
3.5.9 260
3.6.10 236
3.7.6 306
3.8.1 114
```
Decompiled bytecode files distributed with Python (syntax check only):
```
2.7.17 647 files: 0 failed
3.2.6 900 files: 0 failed
3.3.7 1256 files: 0 failed
3.4.10 800 files: 0 failed
3.5.9 900 files: 0 failed
3.6.10 1300 files: 28 failed
```
3.6.3: 2020-1-26 Martin and Susanne
===================================

View File

@@ -54,7 +54,7 @@ only; another patched that and handled only 3.3. 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. Even more experimental refactoring is going
on in decompile3_.
on in decompyle3_.
This demonstrably does the best in decompiling Python across all
Python versions. And even when there is another project that only
@@ -89,7 +89,8 @@ This uses setup.py, so it follows the standard Python routine:
::
$ pip install -e . # set up to run from source tree, or...
$ pip install -e . # set up to run from source tree
# Or if you want to install instead
$ python setup.py install # may need sudo
A GNU makefile is also provided so :code:`make install` (possibly as root or
@@ -100,7 +101,7 @@ Running Tests
::
$ make check
make check
A GNU makefile has been added to smooth over setting running the right
command, and running tests from fastest to slowest.
@@ -139,9 +140,16 @@ Python syntax changes, you should use this option if the bytecode is
the right bytecode for the Python interpreter that will be checking
the syntax.
You can also cross compare the results with another python decompiler
like pycdc_ . Since they work differently, bugs here often aren't in
that, and vice versa.
You can also cross compare the results with either another version of
`uncompyle6` since there are are sometimes regressions in decompiling
specific bytecode as the overall quality improves.
For Python 3.7 and above, the code in decompyle3_ is generally
better.
Or try specific another python decompiler like uncompyle2_, unpyc37_,
or pycdc_. Since the later two work differently, bugs here often
aren't in that, and vice versa.
There is an interesting class of these programs that is readily
available give stronger verification: those programs that when run
@@ -240,13 +248,18 @@ See Also
.. _debuggers: https://pypi.python.org/pypi/trepan3k
.. _remake: https://bashdb.sf.net/remake
.. _pycdc: https://github.com/zrax/pycdc
.. _decompile3: https://github.com/rocky/python-decompile3
.. _decompyle3: https://github.com/rocky/python-decompile3
.. _uncompyle2: https://github.com/wibiti/uncompyle2
.. _unpyc37: https://github.com/andrew-tavera/unpyc37
.. _this: https://github.com/rocky/python-uncompyle6/wiki/Deparsing-technology-and-its-use-in-exact-location-reporting
.. |buildstatus| image:: https://travis-ci.org/rocky/python-uncompyle6.svg :target: https://travis-ci.org/rocky/python-uncompyle6
.. |packagestatus| image:: https://repology.org/badge/vertical-allrepos/python:uncompyle6.svg :target: https://repology.org/project/python:uncompyle6/versions
.. |buildstatus| image:: https://travis-ci.org/rocky/python-uncompyle6.svg
:target: https://travis-ci.org/rocky/python-uncompyle6
.. |packagestatus| image:: https://repology.org/badge/vertical-allrepos/python:uncompyle6.svg
:target: https://repology.org/project/python:uncompyle6/versions
.. _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
.. |Latest Version| image:: https://badge.fury.io/py/uncompyle6.svg
:target: https://badge.fury.io/py/uncompyle6
.. |Pypi Installs| image:: https://pepy.tech/badge/uncompyle6/month

View File

@@ -1,4 +1,4 @@
# Copyright (C) 2018, 2020 Rocky Bernstein <rocky@gnu.org>
# Copyright (C) 2018 Rocky Bernstein <rocky@gnu.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -23,7 +23,7 @@
# Things that change more often go here.
copyright = """
Copyright (C) 2015-2020 Rocky Bernstein <rb@dustyfeet.com>.
Copyright (C) 2015-2019 Rocky Bernstein <rb@dustyfeet.com>.
"""
classifiers = ["Development Status :: 5 - Production/Stable",

0
admin-tools/check-newer-versions.sh Normal file → Executable file
View File

3
admin-tools/check-older-versions.sh Normal file → Executable file
View File

@@ -20,9 +20,8 @@ for version in $PYVERSIONS; do
exit $?
fi
make clean && python setup.py develop
if ! make check-short ; then
if ! make check ; then
exit $?
fi
echo === $version ===
done
make check

View File

@@ -55,9 +55,8 @@
# Make packages and tag
$ . ./admin-tools/make-dist-older.sh
$ pyenv local 3.8.1
$ twine check dist/uncompyle6-$VERSION*
$ git tag release-python-2.4-$VERSION
$ twine check dist/uncompyle6-$VERSION*
$ . ./admin-tools/make-dist-newer.sh
$ twine check dist/uncompyle6-$VERSION*

View File

@@ -1,46 +0,0 @@
git pull
Change version in uncompyle6/version.py
source uncompyle6/version.py
echo $VERSION
git commit -m"Get ready for release $VERSION" .
Update ChangeLog:
make ChangeLog
Update NEWS from ChangeLog
make check
git commit --amend .
git push
Make sure pyenv is running
# Pyenv
source admin-tools/check-newer-versions.sh
# Switch to python-2.4 and build that first...
source admin-tools/setup-python-2.4
rm ChangeLog
git merge master
Update NEWS from master branch
git commit -m"Get ready for release $VERSION" .
source admin-tools/check-older-versions.sh
source admin-tools/check-newer-versions.sh
make-dist-older.sh
git tag release-python-2.4-$VERSION
./make-dist-newer.sh
git tag release-$VERSION
twine upload dist/uncompyle6-${VERSION}*

View File

@@ -6,4 +6,4 @@ if [[ $0 == ${BASH_SOURCE[0]} ]] ; then
echo "This script should be *sourced* rather than run directly through bash"
exit 1
fi
export PYVERSIONS='2.4.6 2.5.6'
export PYVERSIONS='2.4.6 2.5.6 2.6.9'

0
admin-tools/setup-master.sh Normal file → Executable file
View File

1
admin-tools/setup-python-2.4.sh Normal file → Executable file
View File

@@ -15,4 +15,3 @@ cd $fulldir/..
git checkout python-2.4 && pyenv local $PYTHON_VERSION && git pull
cd $owd
rm -v */.python-version || true
pyenv local $PYTHON_VERSION

View File

@@ -1,3 +0,0 @@
#!/bin/bash
cd $(dirname ${BASH_SOURCE[0]})/..
git pull

View File

@@ -30,7 +30,7 @@ def list_comp():
[y for y in range(3)]
def get_parsed_for_fn(fn):
code = fn.func_code
code = fn.__code__ if PYTHON3 else fn.func_code
return deparse(code, version=PYTHON_VERSION)
def check_expect(expect, parsed, fn_name):

View File

@@ -20,7 +20,7 @@ def bug_loop(disassemble, tb=None):
disassemble(tb)
def test_if_in_for():
code = bug.func_code
code = bug.__code__
scan = get_scanner(PYTHON_VERSION)
if 2.7 <= PYTHON_VERSION <= 3.0 and not IS_PYPY:
scan.build_instructions(code)

View File

@@ -45,9 +45,6 @@ def test_grammar():
expect_lhs.add("kvlist")
expect_lhs.add("kv3")
unused_rhs.add("dict")
else:
# NOTE: this may disappear
expect_lhs.add("except_handler_else")
if PYTHON_VERSION < 3.7 and PYTHON_VERSION != 2.7:
# NOTE: this may disappear

View File

@@ -8,8 +8,12 @@ from uncompyle6.semantics.consts import (
if PYTHON3:
from io import StringIO
def iteritems(d):
return d.items()
else:
from StringIO import StringIO
def iteritems(d):
return d.iteritems()
from uncompyle6.semantics.pysource import (SourceWalker, deparse_code2str)
@@ -26,7 +30,7 @@ def test_template_engine():
# FIXME: and so on...
from uncompyle6.semantics.consts import (
TABLE_R, TABLE_DIRECT,
TABLE_DIRECT, TABLE_R,
)
from uncompyle6.semantics.fragments import (
@@ -40,7 +44,7 @@ def test_tables():
(TABLE_DIRECT, 'TABLE_DIRECT', False),
(TABLE_R, 'TABLE_R', False),
(TABLE_DIRECT_FRAGMENT, 'TABLE_DIRECT_FRAGMENT', True)):
for k, entry in t.iteritems():
for k, entry in iteritems(t):
if k in skip_for_now:
continue
fmt = entry[0]

View File

@@ -1,4 +1,7 @@
import pytest
from uncompyle6 import PYTHON_VERSION, code_deparse
pytestmark = pytest.mark.skip(PYTHON_VERSION < 2.7,
reason="need at least Python 2.7")
if PYTHON_VERSION > 2.6:
def test_single_mode():

View File

@@ -9,4 +9,4 @@
12 JUMP_FORWARD 0 'to 15'
15_0 COME_FROM 12 '12'
15 LOAD_CONST None
18 RETURN_VALUE
18 RETURN_VALUE

View File

@@ -12,4 +12,4 @@
18 STORE_NAME 2 'd'
21_0 COME_FROM 12 '12'
21 LOAD_CONST None
24 RETURN_VALUE
24 RETURN_VALUE

View File

@@ -1,16 +1,16 @@
#!/usr/bin/env python
"""Setup script for the 'uncompyle6' distribution."""
import sys
"""Setup script for the 'uncompyle6' distribution."""
SYS_VERSION = sys.version_info[0:2]
if not ((2, 4) <= SYS_VERSION <= (2, 7)):
mess = "Python Release 2.4 .. 2.7 are supported in this code branch."
if ((3, 2) <= SYS_VERSION <= (3, 8)):
mess += ("\nFor your Python, version %s, use the master code/branch." %
if not ((2, 6) <= SYS_VERSION <= (3, 9)):
mess = "Python Release 2.6 .. 3.9 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])
else:
mess += ("\nThis package is not supported before Python 2.4. Your Python version is %s."
elif SYS_VERSION < (2, 4):
mess += ("\nThis package is not supported for Python version %s."
% sys.version[0:3])
print(mess)
raise Exception(mess)

View File

@@ -1,55 +0,0 @@
import re
import unittest
from uncompyle6 import PYTHON_VERSION, IS_PYPY # , PYTHON_VERSION
from uncompyle6.parser import get_python_parser, python_parser
class TestGrammar(unittest.TestCase):
def test_grammar(self):
def check_tokens(tokens, opcode_set):
remain_tokens = set(tokens) - opcode_set
remain_tokens = set([re.sub('_\d+$','', t) for t in remain_tokens])
remain_tokens = set([re.sub('_CONT$','', t) for t in remain_tokens])
remain_tokens = set(remain_tokens) - opcode_set
self.assertEqual(remain_tokens, set([]),
"Remaining tokens %s\n====\n%s" % (remain_tokens, p.dump_grammar()))
p = get_python_parser(PYTHON_VERSION, is_pypy=IS_PYPY)
(lhs, rhs, tokens,
right_recursive, dup_rhs) = p.check_sets()
expect_lhs = set(['pos_arg', 'get_iter', 'attribute'])
unused_rhs = set(['list', 'call', 'mkfunc',
'mklambda',
'unpack',])
expect_right_recursive = frozenset([('designList',
('store', 'DUP_TOP', 'designList'))])
expect_lhs.add('kwarg')
self.assertEqual(expect_lhs, set(lhs))
self.assertEqual(unused_rhs, set(rhs))
self.assertEqual(expect_right_recursive, right_recursive)
expect_dup_rhs = frozenset([('COME_FROM',), ('CONTINUE',), ('JUMP_ABSOLUTE',),
('LOAD_CONST',),
('JUMP_BACK',), ('JUMP_FORWARD',)])
reduced_dup_rhs = {}
for k in dup_rhs:
if k not in expect_dup_rhs:
reduced_dup_rhs[k] = dup_rhs[k]
pass
pass
for k in reduced_dup_rhs:
print(k, reduced_dup_rhs[k])
# assert not reduced_dup_rhs, reduced_dup_rhs
def test_dup_rule(self):
import inspect
python_parser(PYTHON_VERSION, inspect.currentframe().f_code,
is_pypy=IS_PYPY,
parser_debug={
'dups': True, 'transition': False, 'reduce': False,
'rules': False, 'errorstack': None, 'context': True})
if __name__ == '__main__':
unittest.main()

1
test/.gitignore vendored
View File

@@ -1,2 +1,3 @@
/.coverage
/.python-version
/nohup.out

View File

@@ -30,7 +30,7 @@ check:
$(MAKE) check-$(PYTHON_VERSION)
#: Run working tests from Python 2.6 or 2.7
check-2.4 check-2.5 check-2.6 check-2.7: check-bytecode-2 check-bytecode-3 check-bytecode-1 check-native-short
check-2.6 check-2.7: check-bytecode-2 check-bytecode-3 check-bytecode-1 check-native-short
#: Run working tests from Python 3.0
check-3.0: check-bytecode
@@ -72,10 +72,10 @@ check-3.7: check-bytecode
$(PYTHON) test_pythonlib.py --bytecode-3.7-run --verify-run
$(PYTHON) test_pythonlib.py --bytecode-3.7 --syntax-verify $(COMPILE)
# #: Run working tests from Python 3.8
# check-3.8: check-bytecode
# $(PYTHON) test_pythonlib.py --bytecode-3.8-run --verify-run
# $(PYTHON) test_pythonlib.py --bytecode-3.8 --syntax-verify $(COMPILE)
#: Run working tests from Python 3.8
check-3.8: check-bytecode
$(PYTHON) test_pythonlib.py --bytecode-3.8-run --verify-run
$(PYTHON) test_pythonlib.py --bytecode-3.8 --syntax-verify $(COMPILE)
# FIXME
#: this is called when running under pypy3.5-5.8.0 or pypy2-5.6.0
@@ -99,8 +99,8 @@ check-bytecode-3:
$(PYTHON) test_pythonlib.py --bytecode-3.0 \
--bytecode-3.1 --bytecode-3.2 --bytecode-3.3 \
--bytecode-3.4 --bytecode-3.5 --bytecode-3.6 \
--bytecode-3.7 \
--bytecode-pypy3.2 --bytecode-pypy3.6
--bytecode-3.7 \
--bytecode-pypy3.2 --bytecode-pypy3.6 --bytecode-3.8
#: Check deparsing on selected bytecode 3.x
check-bytecode-3-short:
@@ -166,7 +166,6 @@ check-bytecode-2.3:
#: Check deparsing Python 2.4
check-bytecode-2.4:
$(PYTHON) test_pythonlib.py --bytecode-2.4-run --verify-run
$(PYTHON) test_pythonlib.py --bytecode-2.4
#: Check deparsing Python 2.5
@@ -295,20 +294,16 @@ check-bytecode-3.7:
$(PYTHON) test_pythonlib.py --bytecode-3.7-run --verify-run
$(PYTHON) test_pythonlib.py --bytecode-3.7 --syntax-verify
# #: Check deparsing Python 3.8
# check-bytecode-3.8:
# $(PYTHON) test_pythonlib.py --bytecode-3.8-run --verify-run
# $(PYTHON) test_pythonlib.py --bytecode-3.8 --syntax-verify
#: Check deparsing Python 3.8
check-bytecode-3.8:
$(PYTHON) test_pythonlib.py --bytecode-3.8-run --verify-run
$(PYTHON) test_pythonlib.py --bytecode-3.8 --syntax-verify
#: short tests for bytecodes only for this version of Python
check-native-short:
$(PYTHON) test_pythonlib.py --bytecode-$(PYTHON_VERSION) --syntax-verify $(COMPILE)
$(PYTHON) test_pythonlib.py --bytecode-$(PYTHON_VERSION)-run --verify-run $(COMPILE)
#: Run longer Python 2.6's lib files known to be okay
check-2.4-ok:
$(PYTHON) test_pythonlib.py --ok-2.4 --verify $(COMPILE)
#: Run longer Python 2.6's lib files known to be okay
check-2.6-ok:
$(PYTHON) test_pythonlib.py --ok-2.6 --syntax-verify $(COMPILE)

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.

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.

View File

@@ -8,7 +8,7 @@ See http://www.goebel-consult.de/decompyle/ for download and
for further information
"""
# This is a seperate test pattern, since 'continue' within 'try'
# This is a separate test pattern, since 'continue' within 'try'
# was not allowed till Python 2.1
for term in args:

View File

@@ -1,8 +1,9 @@
#!/usr/bin/env python
# Mode: -*- python -*-
#
# Copyright (c) 2015, 2017 by Rocky Bernstein <rb@dustyfeet.com>
# Copyright (c) 2015 by Rocky Bernstein <rb@dustyfeet.com>
#
from __future__ import print_function
import dis, os.path

View File

@@ -1,6 +1,7 @@
#!/usr/bin/env python
from uncompyle6 import uncompyle
from __future__ import print_function
from uncompyle6.main import decompile
from xdis.magics import sysinfo2float
import sys, inspect

View File

@@ -22,7 +22,7 @@ assert i[0]('a') == True
assert i[0]('A') == False
# Issue #170. Bug is needing an "conditional_not_lambda" grammar rule
# in addition the the "if_expr_lambda" rule
# in addition the the "if_exp_lambda" rule
j = lambda a: False if not a else True
assert j(True) == True
assert j(False) == False

View File

@@ -1,8 +1,8 @@
# Tests:
# ret_expr_or_cond ::= ret_expr
# ret_cond ::= expr POP_JUMP_IF_FALSE expr RETURN_END_IF ret_expr_or_cond
# ret_expr_or_cond ::= ret_cond
# if_exp_ret ::= expr POP_JUMP_IF_FALSE expr RETURN_END_IF ret_expr_or_cond
# ret_expr_or_cond ::= if_exp_ret
# ret_or ::= expr JUMP_IF_TRUE_OR_POP ret_expr_or_cond COME_FROM
# See https://github.com/rocky/python-uncompyle6/issues/5

View File

@@ -1,7 +0,0 @@
# From 2.4 test_array.py
# In Python 2.4 and earlier "yield" is not valid and instead
# we must use "yield None". Bug was not adding "None"
def yield_bug():
yield None
return

View File

@@ -1,19 +0,0 @@
# From 2.4 test_sax.py
# Bug was distinguishing try from try/else
def verify_empty_attrs():
gvqk = 3
try:
gvk = 1/0
except ZeroDivisionError:
gvk = 1
try:
gvqk = 0
except KeyError:
gvqk = 1
# If try/else was used above the return will be 4
return gvk + gvqk
assert 1 == verify_empty_attrs()

View File

@@ -0,0 +1,4 @@
# From 2.7.17 fractions
"""Rational, infinite-precision, real numbers."""
from __future__ import division

View File

@@ -8,7 +8,7 @@ list(x for x in range(10) if x % 2 if x % 3)
# expresion which evaluates True unconditionally,
# but leave dead code or junk around that we have to match on.
# Tests "if_expr_true" rule
# Tests "if_exp_true" rule
5 if 1 else 2
0 or max(5, 3) if 0 else 3

View File

@@ -1,6 +1,6 @@
# Bug found in 2.7 test_itertools.py
# Bug was erroneously using reduction to if_expr_true
# A proper fix would be to use if_expr_true only when we
# Bug was erroneously using reduction to if_exp_true
# A proper fix would be to use if_exp_true only when we
# can determine there is or was dead code.
from itertools import izip_longest
for args in [['abc', range(6)]]:

View File

@@ -0,0 +1,32 @@
# Adapted from 3.7.6 test_contains
# The bug was in reconstructing something equivalent to
# "while False: yelid None" which is *needed* in __iter__().
# Sheeh!
# RUNNABLE!
def test_block_fallback():
# blocking fallback with __contains__ = None
class ByContains(object):
def __contains__(self, other):
return False
c = ByContains()
class BlockContains(ByContains):
"""Is not a container
This class is a perfectly good iterable (as tested by
list(bc)), as well as inheriting from a perfectly good
container, but __contains__ = None prevents the usual
fallback to iteration in the container protocol. That
is, normally, 0 in bc would fall back to the equivalent
of any(x==0 for x in bc), but here it's blocked from
doing so.
"""
def __iter__(self):
while False:
yield None
__contains__ = None
bc = BlockContains()
assert not (0 in c)
assert not (0 in list(bc))
test_block_fallback()

View File

@@ -1,3 +1,12 @@
async def a(b, c):
async for b in c:
pass
# From 3.7 test_generators.py
# Bug was getting indentation correct for multiple async's
async def foo(X):
async for i in X:
pass
async for i in X:
pass
raise Done

View File

@@ -10,3 +10,14 @@ async def test_enter(self):
x = 1
y = 2
assert manager is context
# From 3.7.6 test_coroutines.py
# Bug was different form of code for "async with" below
class CoroutineTest():
def test_with_8(self):
CNT = 0
async def foo():
nonlocal CNT
async with CM():
CNT += 1
return

View File

@@ -12,3 +12,9 @@ class abstractclassmethod(classmethod):
def __init__(self, callable):
callable.__isabstractmethod__ = True
super().__init__(callable)
# From 2.7.17 test_abc.py
# Bug was handling OldstyleClass correctly without
# a "return locals() but with a "pass"
class OldstyleClass:
pass

View File

@@ -0,0 +1,76 @@
# From 3.6.10 test_binascii.py
# Bug was getting "while c and noise" parsed correclty
# and not put into the "ifelsesmt"
# RUNNABLE!
def addnoise(c, noise):
while c and noise:
if c < 3:
c = 2
else:
c = 3
noise = False
return c
assert addnoise(0, True) == 0
assert addnoise(1, False) == 1
assert addnoise(2, True) == 2
assert addnoise(3, True) == 3
assert addnoise(4, True) == 3
assert addnoise(5, False) == 5
# From 3.6.10 test_dbm_dumb.py
# Bug was getting attaching "else" to the right "if" in the
# presense of a loop.
def test_random(a, r):
x = 0
for dummy in r:
if dummy:
if a:
x += 2
else:
x += 1
return x
assert test_random(True, [1]) == 2
assert test_random(True, [1, 1]) == 4
assert test_random(False, [1]) == 0
assert test_random(False, [1, 1]) == 0
# From 2.7.17 test_frozen.py
# Bug was getting making sure we have "try" not
# "try"/"else"
def test_frozen(a, b):
try:
x = 1 / a
except:
x = 2
try:
x += 3 / b
except:
x += 4
return x
assert test_frozen(1, 1) == 4.0
assert test_frozen(0, 1) == 5.0
assert test_frozen(0.5, 0) == 6.0
assert test_frozen(0, 0.5) == 8.0
# From 3.6.10 test_binop.py
# Bug was getting "other += 3" outside of "if"/"else.
def __floordiv__(a, b):
other = 0
if a:
other = 1
else:
if not b:
return 2
other += 3
return other
assert __floordiv__(True, True) == 4
assert __floordiv__(True, False) == 4
assert __floordiv__(False, True) == 3
assert __floordiv__(False, False) == 2

View File

@@ -0,0 +1,55 @@
SKIP_TESTS=(
[test_aepack.py]=1 # it fails on its own
[test_al.py]=1 # it fails on its own
[test_applesingle.py]=1 # it fails on its own
[test_bsddb185.py]=1 # it fails on its own
[test_bsddb3.py]=1 # it fails on its own
[test_bsddb.py]=1 # it fails on its own
[test_cd.py]=1 # it fails on its own
[test_cl.py]=1 # it fails on its own
[test_codecmaps_cn.py]=1 # it fails on its own
[test_codecmaps_hk.py]=1 # it fails on its own
[test_codecmaps_jp.py]=1 # it fails on its own
[test_codecmaps_kr.py]=1 # it fails on its own
[test_codecmaps_tw.py]=1 # it fails on its own
[test_curses.py]=1 # it fails on its own
[test_dbm.py]=1 # it fails on its own
[test_dl.py]=1 # it fails on its own
[test_gdbm.py]=1 # it fails on its own
[test_gl.py]=1 # it fails on its own
[test_imageop.py]=1 # it fails on its own
[test_imgfile.py]=1 # it fails on its own
[test_linuxaudiodev.py]=1 # it fails on its own
[test_macfs.py]=1 # it fails on its own
[test_macostools.py]=1 # it fails on its own
[test_nis.py]=1 # it fails on its own
[test_normalization.py]=1 # it fails on its own
[test_ossaudiodev.py]=1 # it fails on its own
[test_pep277.py]=1 # it fails on its own
[test_plistlib.py]=1 # it fails on its own
[test_rgbimg.py]=1 # it fails on its own
[test_scriptpackages.py]=1 # it fails on its own
[test_socket_ssl.py]=1 # it fails on its own
[test_sunaudiodev.py]=1 # it fails on its own
[test_support.py]=1 # it fails on its own
[test_tcl.py]=1 # it fails on its own
[test_urllib2net.py]=1 # it fails on its own
[test_urllibnet.py]=1 # it fails on its own
[test_winreg.py]=1 # it fails on its own
[test_winsound.py]=1 # it fails on its own
[test_zlib.py]=1 # it fails on its own
[test_decimal.py]=1 #
[test_dis.py]=1 # We change line numbers - duh!
[test_generators.py]=1 # Investigate
[test_grammar.py]=1 # Too many stmts. Handle large stmts
[test_grp.py]=1 # Long test - might work Control flow?
[test_pep247.py]=1 # Long test - might work? Control flow?
[test_pwd.py]=1 # Long test - might work? Control flow?
[test_socketserver.py]=1 # -- test takes too long to run: 40 seconds
[test_threading.py]=1 # test takes too long to run: 11 seconds
[test_thread.py]=1 # test takes too long to run: 36 seconds
[test_trace.py]=1 # Long test - works
[test_zipfile64.py]=1 # Runs ok but takes 204 seconds
)
# About 243 files, 0 in 19 minutes

View File

@@ -1,4 +1,44 @@
SKIP_TESTS=(
[test_aepack.py]=1 # it fails on its own
[test_al.py]=1 # it fails on its own
[test_applesingle.py]=1 # it fails on its own
[test_bsddb185.py]=1 # it fails on its own
[test_bsddb3.py]=1 # it fails on its own
[test_bsddb.py]=1 # it fails on its own
[test_cd.py]=1 # it fails on its own
[test_cl.py]=1 # it fails on its own
[test_codecmaps_cn.py]=1 # it fails on its own
[test_codecmaps_hk.py]=1 # it fails on its own
[test_codecmaps_jp.py]=1 # it fails on its own
[test_codecmaps_kr.py]=1 # it fails on its own
[test_codecmaps_tw.py]=1 # it fails on its own
[test_curses.py]=1 # it fails on its own
[test_dbm.py]=1 # it fails on its own
[test_dl.py]=1 # it fails on its own
[test_gdbm.py]=1 # it fails on its own
[test_gl.py]=1 # it fails on its own
[test_imageop.py]=1 # it fails on its own
[test_imgfile.py]=1 # it fails on its own
[test_linuxaudiodev.py]=1 # it fails on its own
[test_macfs.py]=1 # it fails on its own
[test_macostools.py]=1 # it fails on its own
[test_nis.py]=1 # it fails on its own
[test_normalization.py]=1 # it fails on its own
[test_ossaudiodev.py]=1 # it fails on its own
[test_pep277.py]=1 # it fails on its own
[test_plistlib.py]=1 # it fails on its own
[test_rgbimg.py]=1 # it fails on its own
[test_scriptpackages.py]=1 # it fails on its own
[test_sunaudiodev.py]=1 # it fails on its own
[test_support.py]=1 # it fails on its own
[test_tcl.py]=1 # it fails on its own
[test_urllib2net.py]=1 # it fails on its own
[test_urllibnet.py]=1 # it fails on its own
[test_winreg.py]=1 # it fails on its own
[test_winsound.py]=1 # it fails on its own
[test_zlib.py]=1 # it fails on its own
[test_coercion.py]=1
[test_decimal.py]=1
[test_dis.py]=1 # We change line numbers - duh!
@@ -28,14 +68,19 @@ SKIP_TESTS=(
[test_struct.py]=1 # "if and" confused for if .. assert and
[test_sunaudiodev.py]=1 # it fails on its own
[test_support.py]=1 # it fails on its own
[test_tcl.py=1] # it fails on its own
[test_tcl.py]=1 # it fails on its own
[test_threading.py]=1 # test takes too long to run: 11 seconds
[test_thread.py]=1 # test takes too long to run: 36 seconds
[test_trace.py]=1 # Line numbers are expected to be different
[test_urllib2net.py]=1 # is interactive?
[test_urllibnet.py]=1 # it fails on its own
[test_winreg.py]=1 # it fails on its own
[test_winsound.py[=1 # it fails on its own
[test_winsound.py]=1 # it fails on its own
[test_zipfile64.py]=1 # Runs ok but takes 204 seconds
[test_zlib]=1 # fails on its own
)
# About 265 tests in 14 minutes
if (( batch )) ; then
SKIP_TESTS[test_doctest.py]=1 # Fails on ppc64le
fi

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