Compare commits

..

132 Commits
3.6.4 ... 3.7.1

Author SHA1 Message Date
rocky
02f502c40a New grammar rule often imples expanded reduce rule 2020-06-12 21:12:02 -04:00
rocky
de4fbb08f2 Get ready for release 3.7.1 2020-06-12 20:20:58 -04:00
rocky
e14675c2dc Handle 3.7+ "else" branch removal...
As seen in _cmp() of python3.8/distutils/version.py with optimization -O2
2020-06-12 13:18:33 -04:00
rocky
3449be024b CI take 3. 2020-06-10 22:18:28 -04:00
rocky
8b50b15f0a CI update take 2 2020-06-10 22:17:13 -04:00
rocky
e2e925679d Update CI to use git xdis 2020-06-10 22:15:55 -04:00
rocky
7deeee8502 Push "with" grammar improvements back to 3.6 2020-06-04 05:53:21 -04:00
rocky
acdd025162 ast-check "for" is a loop; sync "withas" test ..
with decompyle3.
2020-06-04 05:34:19 -04:00
rocky
9acb3cf068 Fix bug in 3.8 with .. as 2020-06-04 05:24:22 -04:00
rocky
40a653cd3b Bump min xdis version...
it fixes a bug in stdlib testing
2020-05-31 03:17:09 -04:00
rocky
3ac3979535 With a newer xdis, some stdlib test work now 2020-05-31 03:10:52 -04:00
rocky
7eba933cfa More excludes 2020-05-24 21:25:07 -04:00
rocky
ad5d3333da A regression regarding "and"/"or" with "continue" 2020-05-19 10:20:08 -04:00
rocky
e046323b31 Some typos 2020-05-19 01:35:50 -04:00
rocky
e80c13170a Administrivia 2020-05-19 01:29:09 -04:00
rocky
889417caeb Get ready for release 3.7.0 2020-05-19 01:17:58 -04:00
rocky
5a83c7c643 Simplify imports again using xdis 4.6.0 2020-05-19 00:53:53 -04:00
rocky
31db2f3e04 Small typo 2020-05-18 23:29:33 -04:00
rocky
7fa851765d Regularize "or" so args are in 1..2 and ...
correct "return None" semantic action
2020-05-18 22:55:26 -04:00
rocky
d7c3b8454b 3.8 needs call_stmt -> call
Simplify/regularize how "return" works
2020-05-18 22:26:18 -04:00
rocky
3fb8d90407 Revise for xdis 3.6.0 ...
Simplify xdis imports where we can.
Blacken (most) of those buffers too
2020-05-18 21:49:16 -04:00
rocky
ff43565981 3.4-3.4 mixed "and"/"or" parsing ...
Fix by limiting more the bogus come from.
2020-05-18 05:33:57 -04:00
rocky
4365022f40 Adapt decompyle3's 3.8 try/return grammar rules 2020-05-17 10:18:10 -04:00
rocky
d343384db7 A runnable "async" and "async with" test 2020-05-16 07:55:51 -04:00
rocky
87a891ca54 Skip 2.6 test until I can get around to it. 2020-05-14 23:50:55 -04:00
rocky
b94c649776 3.7 change rule to match op "or" expr's 2020-05-14 21:32:45 -04:00
R. Bernstein
f34375ba99 Create FUNDING.yml 2020-05-14 12:12:18 -04:00
rocky
81b704f597 Simpify an import, blacken a file. 2020-05-09 09:32:44 -04:00
rocky
5233a0716b Correct wong class names in super() 2020-05-08 05:59:20 -04:00
rocky
a810ed1280 Merge branch 'master' of github.com:rocky/python-uncompyle6 2020-05-05 22:18:22 -04:00
rocky
ab54caae34 Runtest.sh improvements 2020-05-05 22:18:15 -04:00
rocky
d3cf87e2d9 Start marking test suite since this is going to be copied 2020-05-04 11:43:16 -04:00
rocky
c5228dbdc4 Small test doc typo 2020-05-01 23:19:31 -04:00
rocky
a72163f6f9 lint 2020-04-30 18:00:04 -04:00
rocky
3e1300eb23 Bugs in nested async for...
* Generalize asyc_for rule
 Fix bug in picking out comprehension iterator in async for
* fix bug in getting expression in such a comprehension
* Add %[n]{%x} pattern to template_engine()
2020-04-29 10:12:54 -04:00
rocky
a4eaeea5b2 See above. 2020-04-27 23:05:05 -04:00
rocky
1141dfefc2 Typo in appveyor config 2020-04-27 23:03:46 -04:00
rocky
302a5d53d4 Get ready for release 3.6.7 2020-04-27 22:52:39 -04:00
R. Bernstein
698a3073d0 Merge pull request #313 from rocky/task/separate-dis
Task/separate dis
2020-04-24 02:29:52 -04:00
rocky
e6adf822cc Bump xdis version now that this is released 2020-04-24 02:25:07 -04:00
rocky
8c5acef792 Appveyor needs to install xdis from github 2020-04-21 23:03:00 -04:00
rocky
7578253f7d CI from xdis *branch* 2020-04-21 22:49:14 -04:00
rocky
9e193fd7cb Track branch changes in xdis 2020-04-21 22:42:57 -04:00
rocky
ab6b12be56 Small fixes in fragment parser 2020-04-21 19:58:03 -04:00
rocky
5bd97aa756 lint 2020-04-21 13:49:05 -04:00
rocky
5237d704fa Remove stray debug stmt 2020-04-20 23:13:06 -04:00
rocky
a01285e4a9 Get ready for release 3.6.6 2020-04-20 22:23:58 -04:00
rocky
1d7e8f1617 Update to use xdis 4.4.0 ...
with more correct SipHash and other needed bug fixes.
2020-04-20 10:47:34 -04:00
rocky
ced33a8f0b 3.8 "and" detection is failing. Works on decompyle3 though 2020-04-18 23:47:32 -04:00
rocky
dc7f1ed0cc Final remnants of xdis fixes?
Restore the last of the excluded bytecode.
2020-04-18 23:24:56 -04:00
rocky
fc00d394ec And restore a 3.7 test 2020-04-18 23:21:00 -04:00
rocky
e2baccb4e5 Reinstate 3.5 tests 2020-04-18 23:18:24 -04:00
rocky
c99cf7a653 Try reinstating one more bytecode file 2020-04-18 23:11:42 -04:00
rocky
999eee4b5f More xdis upgrade fixes...
LOAD_CONST of unicode in 2.7- is the same thing as LOAD_STR.

I guess previously there was no unicode.
2020-04-18 22:26:24 -04:00
rocky
9ca94717e0 Yet another workaround 2020-04-18 19:53:04 -04:00
rocky
b77efec36c git commit -m'Adjust "or" offset check ...
for Python < 3.6 hopefully it doesn't break Python 3.6+
2020-04-18 19:21:59 -04:00
rocky
17d07eaf00 continuing xdis refactor aftermath...
Both 2.7 bytecode broken from the refactor have now been reinstated, but
two 3.5 and 3.6 bytecode have moved into the "todo" category.
2020-04-18 18:47:06 -04:00
rocky
538c2e7efd More regressions with some fixes 2020-04-17 00:06:39 -04:00
rocky
ebc22e32e6 TravisCI: try to get xdis from github 2020-04-16 23:53:44 -04:00
rocky
4796fb9e70 "or" rule regularization + regressions from xdis 2020-04-16 23:45:39 -04:00
rocky
ea81ac7202 Reinstate previously failing tests 2020-04-16 17:16:38 -04:00
rocky
2fd61b1016 Add 3.7ish "or" check 2020-04-16 16:35:27 -04:00
rocky
ebd0eaa609 Bug minimum xdis version 2020-04-16 15:48:28 -04:00
rocky
badfe5456f Track "or" grammar changes...
Remove re deprecation warning
2020-04-16 15:25:42 -04:00
rocky
f117feb585 Use new xdis...
Sadly there are some regressions that need to be fixed.

Deal with later.
2020-04-16 11:01:12 -04:00
rocky
204b07c996 Bump for botched xdis release 2020-04-16 10:10:54 -04:00
rocky
869e48877c Convert to use xdis 4.3.0 or greater 2020-04-16 08:41:53 -04:00
rocky
7ed40d5f6e Adjust _mklambda vs. yield precedence 2020-04-11 09:54:03 -04:00
rocky
5c6365d8a1 Go over "yield" and other precedence 2020-04-09 20:27:07 -04:00
rocky
42d3c4db61 3.8 Excludes 2020-04-05 12:09:48 -04:00
rocky
f3b102600e Linging bug from HEAD~ changes 2020-04-04 10:33:21 -04:00
rocky
f6a13302fb Bugs introduced in last commit 2020-04-04 10:26:46 -04:00
rocky
e8e7d2086d whileelse in 3.6 sometimes has come froms...
also remove extra "L. " in token printing
2020-04-04 10:12:12 -04:00
rocky
1367709399 Scale back 3.6.10 pyenvlib testing...
fails on _pyio.cpython-36.opt-1.pyc
2020-04-04 05:21:24 -04:00
rocky
3dcc20f6d7 Small spelling typo...
Fixes #311
2020-04-04 02:38:32 -04:00
rocky
5c83de830f Merge branch 'master' of github.com:rocky/python-uncompyle6 2020-04-04 02:34:08 -04:00
rocky
451f0b55bb Merge branch 'master' of https://github.com/rocky/python-uncompyle6 2020-04-01 12:44:07 -04:00
rocky
a5704cd462 3.8 excludes 2020-04-01 12:43:28 -04:00
rocky
52fbf1d6a7 Typos 2020-04-01 11:48:58 -04:00
rocky
0a3f951682 Administrivia 2020-04-01 11:35:50 -04:00
rocky
7b4059820f Get ready for release 3.6.5 2020-04-01 11:18:20 -04:00
rocky
9caac7fc84 Small tweaks ...
* Remove unneeded Makefile
* sync n_ifelsesmt transform with decompyle3
2020-04-01 11:00:25 -04:00
rocky
ceb26d29fd 3.5- doesn't do format strings 2020-04-01 10:03:10 -04:00
rocky
9ec1c420e7 Merge branch 'master' of github.com:rocky/python-uncompyle6 2020-04-01 09:49:11 -04:00
rocky
a616e1e1c7 "withstmt" -> "with" and fix async for 2020-04-01 09:48:34 -04:00
rocky
b839abcfe7 run-and-email.sh seemed borked 2020-04-01 09:33:18 -04:00
rocky
e2d349f781 Handle nested async for in for...
and Better async comprehension detection.

Still more work is needed. See commented-out section in
test/simple_source/bug37/02_async_for_generator.py
2020-03-31 12:05:39 -04:00
rocky
af8add9df4 Bug in finding annotation in fn with docstring 2020-03-31 11:13:12 -04:00
rocky
3afc5a599a Fix one more call to ParseError 2020-03-31 10:46:00 -04:00
rocky
663bc06bb9 Fix one more call to ParseError 2020-03-31 10:44:52 -04:00
rocky
63d6054640 One more ParserError() upgrade 2020-03-31 10:29:52 -04:00
rocky
1c8805ecc9 Merge branch 'master' of github.com:rocky/python-uncompyle6 2020-03-31 10:14:27 -04:00
rocky
5fde4f2e05 Show token number in parser error listing...
But only if -g is given
2020-03-31 10:12:52 -04:00
rocky
b030a5ac2b pypy 3.6 7.3.0 tolerance...
more work is need on the tests though
2020-03-28 19:53:07 -04:00
rocky
01ea45a3f5 Administrivia - bump versions 2020-03-25 10:58:37 -04:00
rocky
2b2e7d3242 Bump xdis and pyenv versions, 2020-03-16 16:44:34 -04:00
rocky
2448f24764 Exclude a test on POWER7 2020-02-20 10:46:32 -05:00
rocky
299fd93125 One more excluded test 2020-02-16 21:55:47 -05:00
rocky
d9b2d66843 Runtests tweak 2020-02-16 19:53:03 -05:00
rocky
d070a28635 More run-and-email.sh tweaks 2020-02-16 18:26:21 -05:00
rocky
092874f8b5 Go over runtests.sh excludes 2020-02-16 17:49:56 -05:00
rocky
5a6a41a608 run-and-email tweaks 2020-02-16 17:35:57 -05:00
rocky
201635de7b run-and-email message tweak 2020-02-16 12:06:42 -05:00
rocky
81899a82c3 Allow inverted test names in "stdlib/runtests.sh" 2020-02-15 12:00:38 -05:00
rocky
76085a3040 Better runtsts BATCH variable handling 2020-02-15 09:26:45 -05:00
rocky
35127452f5 Bug found by 2.4 sre_parse.py testing 2020-02-15 08:06:58 -05:00
rocky
970cad7cc7 More 3.x runtests excludes 2020-02-15 06:01:57 -05:00
rocky
69064f4c23 runtests.sh exclude test_cmath.py in 3.x for now 2020-02-15 05:26:49 -05:00
rocky
28ef04d141 More bugs found via sre_parse.py decompilation 2020-02-15 05:10:11 -05:00
rocky
fd36c77d2d Bugs found in 2.4 branch testing 2020-02-14 10:54:37 -05:00
rocky
534afb3f6e run-and-email tweaks 2020-02-13 21:14:36 -05:00
rocky
874d196e5c 3.x ifelsestmtc reduction rule fix 2020-02-13 05:41:15 -05:00
rocky
dca2224520 Go over 3.3 and 3.4 runtest exclusions 2020-02-13 04:37:11 -05:00
rocky
e90455dcb8 transform ifelseif bugs 2020-02-13 04:31:16 -05:00
rocky
6dd97568f6 More information run-and-email.sh scripts...
Log status for each version.
2020-02-11 14:27:10 -05:00
rocky
aa6849a570 Add host to email on failure 2020-02-10 21:19:15 -05:00
rocky
749493631c cd not chdir for POSIX shell 2020-02-10 21:15:32 -05:00
rocky
7b3c91d23a Another 3.7 runtest exclude 2020-02-10 20:21:58 -05:00
rocky
bd0fdd0002 Start older-python testing 2020-02-10 18:24:33 -05:00
rocky
c62daaf0b7 3.5 exclusions 2020-02-10 18:07:35 -05:00
rocky
66d8526d7f Show host in subject; set BATCH explicitly 2020-02-10 17:38:50 -05:00
rocky
66db4cc862 2.7 runtest exclusion 2020-02-10 17:17:15 -05:00
rocky
bf288b1871 Fix bug introduced by ast "tranform" change 2020-02-10 16:13:57 -05:00
rocky
d2f6223e14 3.x exclusions 2020-02-10 12:35:24 -05:00
rocky
9d5a4c822e Runtests excludes 2020-02-10 12:09:25 -05:00
rocky
05e0a5661a runtest 3.6 excludes 2020-02-10 11:26:44 -05:00
rocky
76287162da Fix ifelif transformation for earlier Pythons 2020-02-10 11:16:32 -05:00
rocky
d64fa6ba50 3.6 runtests excludes 2020-02-10 10:59:03 -05:00
rocky
b76f7f905c 3.6 runtest exclude 2020-02-10 10:19:18 -05:00
rocky
c31384ef81 3.6 runtests exclusions 2020-02-10 09:40:33 -05:00
rocky
727dabff6a is_docsting needs to test for sstmts 2020-02-10 09:19:03 -05:00
rocky
946d74ad36 Fix bug in 3.0 name module detection 2020-02-10 08:58:48 -05:00
131 changed files with 2714 additions and 1458 deletions

View File

@@ -36,10 +36,11 @@ jobs:
# fallback to using the latest cache if no exact match is found # fallback to using the latest cache if no exact match is found
- v2-dependencies- - v2-dependencies-
# This is based on your 1.0 configuration file or project settings - run:
- run: pip install --user --upgrade setuptools command: | # Use pip to install dependengcies
- run: pip install --user -e . pip install --user --upgrade setuptools
- run: pip install --user -r requirements-dev.txt pip install --user -e .
pip install --user -r requirements-dev.txt
# Save dependency cache # Save dependency cache
- save_cache: - save_cache:

12
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,12 @@
# These are supported funding model platforms
github: [rocky]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

1
.gitignore vendored
View File

@@ -10,6 +10,7 @@
/.pytest_cache /.pytest_cache
/.python-version /.python-version
/.tox /.tox
.mypy_cache
/.venv* /.venv*
/README /README
/__pkginfo__.pyc /__pkginfo__.pyc

View File

@@ -1,9 +1,9 @@
language: python language: python
python: python:
- '3.5' # - '3.5'
- '2.7' # - '2.7'
- '3.4' # - '3.4'
- '3.6' - '3.6'
- '3.8' - '3.8'

47
NEWS.md
View File

@@ -1,3 +1,50 @@
3.7.1: 2020-6-12 Fleetwood66
====================================================
Released to pick up new xdis version which has fixes to read bytestings better on 3.x
* Handle 3.7+ "else" branch removal adAs seen in `_cmp()` of `python3.8/distutils/version.py` with optimization `-O2`
* 3.6+ "with" and "with .. as" grammar improvements
* ast-check for "for" loop was missing some grammar rules
3.7.0: 2020-5-19 Primidi 1st Prairial - Alfalfa - HF
====================================================
The main impetus for this release is to pull in the recent changes from xdis.
We simplify imports using xdis 4.6.0.
There were some bugfixes to Python 3.4-3.8. See the ChangeLog for details
3.6.7: 2020-4-27 xdis again
===========================
More upheaval in xdis which we need to track here.
3.6.6: 2020-4-20 Love in the time of Cholera
============================================
The main reason for this release is an incompatablity bump in xdis which handles
3.7 SipHash better.
* Go over "yield" as an expression precidence
* Some small alignment with code in decompyle3 for "or" and "and" was done
3.6.5: 2020-4-1 April Fool
==========================
Back port some of the changes in decompile3 here which mostly helps 3.7 and 3.8 decompilation, although this may also help 3.6ish versions too.
- Handle nested `async for in for...` and better async comprehension detection via `xdis`. Still more work is needed.
- include token number in listings when `-g` and there is a parser error
- remove unneeded `Makefile`s now that remake 4.3+1.5dbg is a thing that has `-c`
- Bug in finding annotations in functions with docstrings
- Fix bug found by 2.4 sre_parse.py testing
- Fix `transform` module's `ifelseif` bugs
- Fix bug in 3.0 name module detection
- Fix docstring detection
3.6.4: 2020-2-9 Plateau 3.6.4: 2020-2-9 Plateau
======================= =======================

View File

@@ -211,7 +211,7 @@ however that the magic of a released version is usually the same as
the *last* candidate version prior to release. the *last* candidate version prior to release.
There are also customized Python interpreters, notably Dropbox, There are also customized Python interpreters, notably Dropbox,
which use their own magic and encrypt bytcode. With the exception of which use their own magic and encrypt bytecode. With the exception of
the Dropbox's old Python 2.5 interpreter this kind of thing is not the Dropbox's old Python 2.5 interpreter this kind of thing is not
handled. handled.
@@ -230,7 +230,7 @@ There is lots to do, so please dig in and help.
See Also See Also
-------- --------
* https://github.com/rocky/python-decompile3 : Much smaller and more modern code, focusing on 3.7+. Changes in that will get migrated back ehre. * https://github.com/rocky/python-decompile3 : Much smaller and more modern code, focusing on 3.7+. Changes in that will get migrated back here.
* https://code.google.com/archive/p/unpyc3/ : supports Python 3.2 only. The above projects use a different decompiling technique than what is used here. Currently unmaintained. * https://code.google.com/archive/p/unpyc3/ : supports Python 3.2 only. The above projects use a different decompiling technique than what is used here. Currently unmaintained.
* https://github.com/figment/unpyc3/ : fork of above, but supports Python 3.3 only. Includes some fixes like supporting function annotations. Currently unmaintained. * https://github.com/figment/unpyc3/ : fork of above, but supports Python 3.3 only. Includes some fixes like supporting function annotations. Currently unmaintained.
* https://github.com/wibiti/uncompyle2 : supports Python 2.7 only, but does that fairly well. There are situations where :code:`uncompyle6` results are incorrect while :code:`uncompyle2` results are not, but more often uncompyle6 is correct when uncompyle2 is not. Because :code:`uncompyle6` adheres to accuracy over idiomatic Python, :code:`uncompyle2` can produce more natural-looking code when it is correct. Currently :code:`uncompyle2` is lightly maintained. See its issue `tracker <https://github.com/wibiti/uncompyle2/issues>`_ for more details * https://github.com/wibiti/uncompyle2 : supports Python 2.7 only, but does that fairly well. There are situations where :code:`uncompyle6` results are incorrect while :code:`uncompyle2` results are not, but more often uncompyle6 is correct when uncompyle2 is not. Because :code:`uncompyle6` adheres to accuracy over idiomatic Python, :code:`uncompyle2` can produce more natural-looking code when it is correct. Currently :code:`uncompyle2` is lightly maintained. See its issue `tracker <https://github.com/wibiti/uncompyle2/issues>`_ for more details

View File

@@ -1,4 +1,4 @@
# Copyright (C) 2018 Rocky Bernstein <rocky@gnu.org> # Copyright (C) 2018, 2020 Rocky Bernstein <rocky@gnu.org>
# #
# This program is free software: you can redistribute it and/or modify # 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 # it under the terms of the GNU General Public License as published by
@@ -21,9 +21,20 @@
# less elegant than having it here with reduced code, albeit there # less elegant than having it here with reduced code, albeit there
# still is some room for improvement. # still is some room for improvement.
# Python-version | package | last-version |
# -----------------------------------------
# 2.5 | pip | 1.1 |
# 2.6 | pip | 1.5.6 |
# 2.7 | pip | 19.2.3 |
# 2.7 | pip | 1.2.1 |
# 3.1 | pip | 1.5.6 |
# 3.2 | pip | 7.1.2 |
# 3.3 | pip | 10.0.1 |
# 3.4 | pip | 19.1.1 |
# Things that change more often go here. # Things that change more often go here.
copyright = """ copyright = """
Copyright (C) 2015-2019 Rocky Bernstein <rb@dustyfeet.com>. Copyright (C) 2015-2020 Rocky Bernstein <rb@dustyfeet.com>.
""" """
classifiers = ["Development Status :: 5 - Production/Stable", classifiers = ["Development Status :: 5 - Production/Stable",
@@ -58,7 +69,7 @@ entry_points = {
]} ]}
ftp_url = None ftp_url = None
install_requires = ["spark-parser >= 1.8.9, < 1.9.0", install_requires = ["spark-parser >= 1.8.9, < 1.9.0",
"xdis >= 4.2.2, < 4.3.0"] "xdis >= 4.6.1, < 4.8.0"]
license = "GPL3" license = "GPL3"
mailing_list = "python-debugger@googlegroups.com" mailing_list = "python-debugger@googlegroups.com"

View File

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

View File

@@ -5,4 +5,4 @@ if [[ $0 == ${BASH_SOURCE[0]} ]] ; then
echo "This script should be *sourced* rather than run directly through bash" echo "This script should be *sourced* rather than run directly through bash"
exit 1 exit 1
fi fi
export PYVERSIONS='3.5.9 3.6.10 2.6.9 3.3.7 2.7.17 3.2.6 3.1.5 3.4.10 3.7.6 3.8.1' export PYVERSIONS='3.5.9 3.6.10 2.6.9 3.3.7 2.7.18 3.2.6 3.1.5 3.4.10 3.7.7 3.8.3'

View File

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

View File

@@ -53,6 +53,7 @@ install:
# compiled extensions and are not provided as pre-built wheel packages, # compiled extensions and are not provided as pre-built wheel packages,
# pip will build them from source using the MSVC compiler matching the # pip will build them from source using the MSVC compiler matching the
# target Python version and architecture # target Python version and architecture
- "%CMD_IN_ENV% pip install git+git://github.com/rocky/python-uncompyle6.git#egg=uncompyle6-3.6.6"
- "%CMD_IN_ENV% pip install -r requirements.txt" - "%CMD_IN_ENV% pip install -r requirements.txt"
build_script: build_script:

View File

@@ -1,14 +1,13 @@
from uncompyle6 import PYTHON_VERSION
from uncompyle6.scanners.tok import Token from uncompyle6.scanners.tok import Token
def test_token(): def test_token():
# Test token formatting of: LOAD_CONST None # Test token formatting of: LOAD_CONST None
t = Token("LOAD_CONST", offset=0, attr=None, pattr=None, has_arg=True) t = Token("LOAD_CONST", offset=0, attr=None, pattr=None, has_arg=True)
expect = " 0 LOAD_CONST None" expect = "0 LOAD_CONST None"
# print(t.format()) # print(t.format())
assert t assert t
assert t.format() == expect assert t.format().strip() == expect.strip()
# Make sure equality testing of tokens ignores offset # Make sure equality testing of tokens ignores offset
t2 = Token("LOAD_CONST", offset=2, attr=None, pattr=None, has_arg=True) t2 = Token("LOAD_CONST", offset=2, attr=None, pattr=None, has_arg=True)
@@ -17,8 +16,8 @@ def test_token():
# Make sure formatting of: LOAD_CONST False. We assume False is the 0th index # Make sure formatting of: LOAD_CONST False. We assume False is the 0th index
# of co_consts. # of co_consts.
t = Token("LOAD_CONST", offset=1, attr=False, pattr=False, has_arg=True) t = Token("LOAD_CONST", offset=1, attr=False, pattr=False, has_arg=True)
expect = " 1 LOAD_CONST False" expect = "1 LOAD_CONST False"
assert t.format() == expect assert t.format().strip() == expect.strip()
if __name__ == "__main__": if __name__ == "__main__":

View File

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

View File

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

View File

@@ -12,8 +12,7 @@ import functools
from uncompyle6 import PYTHON_VERSION, PYTHON3, IS_PYPY, code_deparse from uncompyle6 import PYTHON_VERSION, PYTHON3, IS_PYPY, code_deparse
# TODO : I think we can get xdis to support the dis api (python 3 version) by doing something like this there # TODO : I think we can get xdis to support the dis api (python 3 version) by doing something like this there
from xdis.bytecode import Bytecode from xdis import Bytecode, get_opcode
from xdis.main import get_opcode
opc = get_opcode(PYTHON_VERSION, IS_PYPY) opc = get_opcode(PYTHON_VERSION, IS_PYPY)
Bytecode = functools.partial(Bytecode, opc=opc) Bytecode = functools.partial(Bytecode, opc=opc)

View File

@@ -4,40 +4,54 @@ import sys
"""Setup script for the 'uncompyle6' distribution.""" """Setup script for the 'uncompyle6' distribution."""
SYS_VERSION = sys.version_info[0:2] SYS_VERSION = sys.version_info[0:2]
if not ((2, 6) <= SYS_VERSION <= (3, 9)): if not ((2, 6) <= SYS_VERSION <= (3, 9)):
mess = "Python Release 2.6 .. 3.9 are supported in this code branch." mess = "Python Release 2.6 .. 3.9 are supported in this code branch."
if ((2, 4) <= SYS_VERSION <= (2, 7)): if (2, 4) <= SYS_VERSION <= (2, 7):
mess += ("\nFor your Python, version %s, use the python-2.4 code/branch." % mess += (
sys.version[0:3]) "\nFor your Python, version %s, use the python-2.4 code/branch."
% sys.version[0:3]
)
elif SYS_VERSION < (2, 4): elif SYS_VERSION < (2, 4):
mess += ("\nThis package is not supported for Python version %s." mess += (
% sys.version[0:3]) "\nThis package is not supported for Python version %s." % sys.version[0:3]
)
print(mess) print(mess)
raise Exception(mess) raise Exception(mess)
from __pkginfo__ import \ from __pkginfo__ import (
author, author_email, install_requires, \ author,
license, long_description, classifiers, \ author_email,
entry_points, modname, py_modules, \ install_requires,
short_desc, VERSION, web, \ license,
zip_safe long_description,
classifiers,
entry_points,
modname,
py_modules,
short_desc,
VERSION,
web,
zip_safe,
)
from setuptools import setup, find_packages from setuptools import setup, find_packages
setup( setup(
author = author, author=author,
author_email = author_email, author_email=author_email,
classifiers = classifiers, classifiers=classifiers,
description = short_desc, description=short_desc,
entry_points = entry_points, entry_points=entry_points,
install_requires = install_requires, install_requires=install_requires,
license = license, license=license,
long_description = long_description, long_description=long_description,
long_description_content_type = "text/x-rst", long_description_content_type="text/x-rst",
name = modname, name=modname,
packages = find_packages(), packages=find_packages(),
py_modules = py_modules, py_modules=py_modules,
test_suite = 'nose.collector', test_suite="nose.collector",
url = web, url=web,
tests_require = ['nose>=1.0'], tests_require=["nose>=1.0"],
version = VERSION, version=VERSION,
zip_safe = zip_safe) zip_safe=zip_safe,
)

5
test/.gitignore vendored
View File

@@ -1,3 +1,8 @@
/.coverage /.coverage
/.python-version /.python-version
/nohup.out /nohup.out
/pycdc
/test_pycdc_tests.sh
/test_uncompyle2.py
/test_unpy33.py
/test_unpy37.py

View File

@@ -78,7 +78,7 @@ check-3.8: check-bytecode
$(PYTHON) test_pythonlib.py --bytecode-3.8 --syntax-verify $(COMPILE) $(PYTHON) test_pythonlib.py --bytecode-3.8 --syntax-verify $(COMPILE)
# FIXME # FIXME
#: this is called when running under pypy3.5-5.8.0 or pypy2-5.6.0 #: this is called when running under pypy3.5-5.8.0, pypy2-5.6.0, or pypy3.6-7.3.0
5.8 5.6: 5.8 5.6:
#: Check deparsing only, but from a different Python version #: Check deparsing only, but from a different Python version
@@ -95,12 +95,19 @@ check-bytecode-2:
--bytecode-2.5 --bytecode-2.6 --bytecode-2.7 --bytecode-pypy2.7 --bytecode-2.5 --bytecode-2.6 --bytecode-2.7 --bytecode-pypy2.7
#: Check deparsing bytecode 3.x only #: Check deparsing bytecode 3.x only
# 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.8
# FIXME: Until we shaked out problems with xdis...
check-bytecode-3: check-bytecode-3:
$(PYTHON) test_pythonlib.py --bytecode-3.0 \ $(PYTHON) test_pythonlib.py \
--bytecode-3.1 --bytecode-3.2 --bytecode-3.3 \
--bytecode-3.4 --bytecode-3.5 --bytecode-3.6 \ --bytecode-3.4 --bytecode-3.5 --bytecode-3.6 \
--bytecode-3.7 \ --bytecode-3.7 --bytecode-3.8
--bytecode-pypy3.2 --bytecode-pypy3.6 --bytecode-3.8
#: Check deparsing on selected bytecode 3.x #: Check deparsing on selected bytecode 3.x
check-bytecode-3-short: check-bytecode-3-short:
@@ -339,8 +346,8 @@ check-bytecode-pypy3.6: 7.1
$(PYTHON) test_pythonlib.py --bytecode-pypy3.6 --verify $(PYTHON) test_pythonlib.py --bytecode-pypy3.6 --verify
#: PyPy 5.0.x with Python 3.6.9 #: PyPy 5.0.x with Python 3.6.9
check-bytecode-pypy3.6: 7.2 check-bytecode-pypy3.6: 7.2 7.3
7.2: 7.3 7.2:
$(PYTHON) test_pythonlib.py --bytecode-pypy3.6-run --verify-run $(PYTHON) test_pythonlib.py --bytecode-pypy3.6-run --verify-run
$(PYTHON) test_pythonlib.py --bytecode-pypy3.6 --verify $(PYTHON) test_pythonlib.py --bytecode-pypy3.6 --verify

View File

@@ -19,6 +19,7 @@ for path in py_source:
else: else:
cfile = "bytecode_%s%s/%s" % (version, suffix, short) + "c" cfile = "bytecode_%s%s/%s" % (version, suffix, short) + "c"
print("byte-compiling %s to %s" % (path, cfile)) print("byte-compiling %s to %s" % (path, cfile))
py_compile.compile(path, cfile) optimize = 2
py_compile.compile(path, cfile, optimize=optimize)
if isinstance(version, str) or version >= (2, 6, 0): if isinstance(version, str) or version >= (2, 6, 0):
os.system("../bin/uncompyle6 -a -T %s" % cfile) os.system("../bin/uncompyle6 -a -T %s" % cfile)

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

@@ -3,32 +3,55 @@
function displaytime { function displaytime {
printf "ran in " printf "ran in "
local T=$1 local T=$1
local D=$((T/60/60/24)) ((D=T/60/60/24))
local H=$((T/60/60%24)) ((H=T/60/60%24))
local M=$((T/60%60)) ((M=T/60%60))
local S=$((T%60)) ((S=T%60))
(( $D > 0 )) && printf '%d days ' $D (( D > 0 )) && printf '%d days ' $D
(( $H > 0 )) && printf '%d hours ' $H (( H > 0 )) && printf '%d hours ' $H
(( $M > 0 )) && printf '%d minutes ' $M (( M > 0 )) && printf '%d minutes ' $M
(( $D > 0 || $H > 0 || $M > 0 )) && printf 'and ' (( D > 0 || H > 0 || M > 0 )) && printf 'and '
printf '%d seconds\n' $S printf '%d seconds\n' $S
} }
. ../admin-tools/pyenv-newer-versions bs=${BASH_SOURCE[0]}
if [[ $0 != $bs ]] ; then
echo "This script should not be *sourced* but run through bash"
exit 1
fi
mydir=$(dirname $bs)
cd $mydir
branch=$(cat ../.git/HEAD | cut -d'/' -f 3)
if [[ $branch == 'python-2.4' ]]; then
. ../admin-tools/pyenv-older-versions
elif [[ $branch == 'master' ]]; then
. ../admin-tools/pyenv-newer-versions
else
echo &1>2 "Error git branch should either be 'master' or 'python-2.4'; got: '$branch'"
exit 1
fi
MAIN="test_pyenvlib.py"
USER=${USER:-rocky} USER=${USER:-rocky}
EMAIL=${EMAIL:-rb@dustyfeet.com} EMAIL=${EMAIL:-rb@dustyfeet.com}
WHAT="uncompyle6 ${MAIN}"
MAX_TESTS=${MAX_TESTS:-800} MAX_TESTS=${MAX_TESTS:-800}
export BATCH=1
typeset -i RUN_STARTTIME=$(date +%s) typeset -i RUN_STARTTIME=$(date +%s)
# PYVERSIONS="3.5.6" # PYVERSIONS="3.5.6"
actual_versions="" MAILBODY=/tmp/${MAIN}-mailbody-$$.txt
# for VERSION in 3.3.7 ; do
for VERSION in $PYVERSIONS ; do for VERSION in $PYVERSIONS ; do
typeset -i rc=0 typeset -i rc=0
LOGFILE=/tmp/pyenvlib-$VERSION-$$.log LOGFILE=/tmp/${MAIN}-$VERSION-$$.log
case "$VERSION" in case "$VERSION" in
3.7.6 | 3.8.1 | 3.1.5 | 3.0.1 ) 3.7.7 | 3.8.2 | 3.1.5 | 3.0.1 )
continue continue
;; ;;
3.5.9 ) 3.5.9 )
@@ -44,7 +67,15 @@ for VERSION in $PYVERSIONS ; do
MAX_TESTS=800 MAX_TESTS=800
;; ;;
3.6.10 ) 3.6.10 )
MAX_TESTS=1300 # about 2139 exist # MAX_TESTS=1300 # about 2139 exist
# fails on _pyio.cpython-36.opt-1.pyc
MAX_TESTS=34
;;
2.4.6 )
MAX_TESTS=600
;;
2.5.6 )
MAX_TESTS=600
;; ;;
2.6.9 ) 2.6.9 )
MAX_TESTS=1300 MAX_TESTS=1300
@@ -58,11 +89,13 @@ for VERSION in $PYVERSIONS ; do
if ! pyenv local $VERSION ; then if ! pyenv local $VERSION ; then
rc=1 rc=1
mailbody_line="pyenv local $VERSION not installed"
echo $mailbody_line >> $MAILBODY
else else
echo Python Version $(pyenv local) > $LOGFILE echo Python Version $(pyenv local) > $LOGFILE
echo "" >> $LOGFILE echo "" >> $LOGFILE
typeset -i ALL_FILES_STARTTIME=$(date +%s) typeset -i ALL_FILES_STARTTIME=$(date +%s)
cmd="python ./test_pyenvlib.py --max ${MAX_TESTS} --syntax-verify --$VERSION" cmd="python ./${MAIN} --max ${MAX_TESTS} --syntax-verify --$VERSION"
echo "$cmd" >>$LOGFILE 2>&1 echo "$cmd" >>$LOGFILE 2>&1
$cmd >>$LOGFILE 2>&1 $cmd >>$LOGFILE 2>&1
rc=$? rc=$?
@@ -72,20 +105,25 @@ for VERSION in $PYVERSIONS ; do
typeset -i ALL_FILES_ENDTIME=$(date +%s) typeset -i ALL_FILES_ENDTIME=$(date +%s)
(( time_diff = ALL_FILES_ENDTIME - ALL_FILES_STARTTIME)) (( time_diff = ALL_FILES_ENDTIME - ALL_FILES_STARTTIME))
displaytime $time_diff >> $LOGFILE time_str=$(displaytime $time_diff)
echo ${time_str}. >> $LOGFILE
fi fi
SUBJECT_PREFIX="pyenv weak verify (max $MAX_TESTS) for" SUBJECT_PREFIX="$WHAT (max $MAX_TESTS) for"
if ((rc == 0)); then if ((rc == 0)); then
mailbody_line="Python $VERSION ok; ${time_str}."
tail -v $LOGFILE | mail -s "$SUBJECT_PREFIX $VERSION ok" ${USER}@localhost tail -v $LOGFILE | mail -s "$SUBJECT_PREFIX $VERSION ok" ${USER}@localhost
else else
mailbody_line="Python $VERSION failed; ${time_str}."
tail -v $LOGFILE | mail -s "$SUBJECT_PREFIX $VERSION not ok" ${USER}@localhost tail -v $LOGFILE | mail -s "$SUBJECT_PREFIX $VERSION not ok" ${USER}@localhost
tail -v $LOGFILE | mail -s "$SUBJECT_PREFIX $VERSION not ok" ${EMAIL} tail -v $LOGFILE | mail -s "$HOST $SUBJECT_PREFIX $VERSION not ok" ${EMAIL}
fi fi
echo $mailbody_line >> $MAILBODY
rm .python-version rm .python-version
done done
typeset -i RUN_ENDTIME=$(date +%s) typeset -i RUN_ENDTIME=$(date +%s)
(( time_diff = RUN_ENDTIME - RUN_STARTTIME)) (( time_diff = RUN_ENDTIME - RUN_STARTTIME))
elapsed_time=$(displaytime $time_diff) elapsed_time=$(displaytime $time_diff)
echo "Run complete $elapsed_time for versions $actual_versions" | mail -s "pyenv weak verify in $elapsed_time" ${EMAIL} echo "${WHAT} complete; ${elapsed_time}." >> $MAILBODY
cat $MAILBODY | mail -s "$HOST $WHAT ${elapsed_time}." ${EMAIL}

View File

@@ -3,7 +3,7 @@
from __future__ import print_function from __future__ import print_function
from uncompyle6.main import decompile from uncompyle6.main import decompile
from xdis.magics import sysinfo2float from xdis import sysinfo2float
import sys, inspect import sys, inspect
def uncompyle_test(): def uncompyle_test():

View File

@@ -66,6 +66,14 @@ def div(a: dict(type=float, help='the dividend'),
"""Divide a by b""" """Divide a by b"""
return a / b return a / b
# From 3.7.6 functools.py
# Bug is in picking up the annotation.
def f(a:"This is a new annotation"):
"""This is a test"""
assert f.__annotations__['a'] == "This is a new annotation"
f(5)
class TestSignatureObject1(): class TestSignatureObject1():
def test_signature_on_wkwonly(self): def test_signature_on_wkwonly(self):
def test(*, a:float, b:str, c:str = 'test', **kwargs: int) -> int: def test(*, a:float, b:str, c:str = 'test', **kwargs: int) -> int:

View File

@@ -1,6 +1,8 @@
# Python 3.3+
#
# From Python 3.3.6 hmac.py # From Python 3.3.6 hmac.py
# Problem was getting wrong placement of positional args. # Problem was getting wrong placement of positional args.
# In 3.6+ paramter handling changes # In 3.6+ parameter handling changes
# RUNNABLE! # RUNNABLE!

View File

@@ -2,6 +2,7 @@
# Bug was code not knowing which Python versions # Bug was code not knowing which Python versions
# have kwargs coming before positional args in code. # have kwargs coming before positional args in code.
"""This program is self-checking!"""
# RUNNABLE! # RUNNABLE!
def tometadata(self, metadata, schema, Table, args, name=None): def tometadata(self, metadata, schema, Table, args, name=None):

View File

@@ -1,6 +1,9 @@
# 3.6+ type annotations on variables # 3.6+ type annotations on variables
from typing import List from typing import List
# This test program is part of the uncompyle6 test suite
# tests STORE_ANNOTATION and SETUP_ANOTATIONS
# RUNNABLE! # RUNNABLE!
y = 2 y = 2
x: bool x: bool

View File

@@ -6,3 +6,11 @@ def make_arange(n):
async def run(m): async def run(m):
return [i async for i in m] return [i async for i in m]
# From 3.7.6 test_coroutines.py
async def run_list(pair, f):
return [i for pair in p async for i in f]
# FIXME: add this. It works in decompyle3
# async def run_gen():
# return (i async for i in f if 0 < i < 4)

View File

@@ -0,0 +1,12 @@
# From python3.8/distutils/version.py with optimization -O2
# The bug was that the other "else" constant propagated removed.
# NOTE: this program needs to be compile with optimization
def _cmp (b, c):
if b:
if c:
return 0
else:
return 1
else:
assert False, "never get here"

View File

@@ -1,23 +0,0 @@
# from 3.7 test_contextlib_async.py
# Bugs were not adding "async" when a function is a decorator,
# and a misaligment when using "async with as".
@_async_test
async def test_enter(self):
self.assertIs(await manager.__aenter__(), manager)
async with manager as context:
async with woohoo() as x:
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

@@ -0,0 +1,87 @@
# From test_grammar.py
# RUNNABLE!
def check_syntax_error(statement):
try:
compile(statement, '<test string>', 'exec')
except SyntaxError:
return
assert False
def test_yield():
# Requires parentheses as call argument
def g():
f((yield 1), 1)
def g():
f((yield from ()))
def g():
f((yield from ()), 1)
def g():
f((yield 1))
# Allowed as standalone statement
def g():
yield 1
def g():
yield from ()
# Allowed as RHS of assignment
def g():
x = yield 1
def g():
x = yield from ()
# Ordinary yield accepts implicit tuples
def g():
yield 1, 1
def g():
x = yield 1, 1
# 'yield from' does not
check_syntax_error("def g(): yield from (), 1")
check_syntax_error("def g(): x = yield from (), 1")
# Requires parentheses as subexpression
def g():
1, (yield 1)
def g():
1, (yield from ())
check_syntax_error("def g(): 1, yield 1")
check_syntax_error("def g(): 1, yield from ()")
# Requires parentheses as call argument
def g():
f((yield 1))
def g():
f((yield 1), 1)
def g():
f((yield from ()))
def g():
f((yield from ()), 1)
check_syntax_error("def g(): f(yield 1)")
check_syntax_error("def g(): f(yield 1, 1)")
check_syntax_error("def g(): f(yield from ())")
check_syntax_error("def g(): f(yield from (), 1)")
# Not allowed at top level
check_syntax_error("yield")
check_syntax_error("yield from")
# Not allowed at class scope
check_syntax_error("class foo:yield 1")
check_syntax_error("class foo:yield from ()")
# Check annotation refleak on SyntaxError
check_syntax_error("def g(a:(yield)): pass")
test_yield()
# From test_types.py
# Bug was needing parens around (yield 2)
def gen_func():
yield 1
return (yield 2)
gen = gen_func()

View File

@@ -0,0 +1,70 @@
# from 3.7 test_contextlib_async.py
# Bugs were not adding "async" when a function is a decorator,
# and a misaligment when using "async with ... as".
"""This program is self-checking!"""
import asyncio
from contextlib import asynccontextmanager, AbstractAsyncContextManager
import functools
def _async_test(func):
"""Decorator to turn an async function into a test case."""
@functools.wraps(func)
def wrapper(*args, **kwargs):
coro = func(*args, **kwargs)
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
try:
return loop.run_until_complete(coro)
finally:
loop.close()
asyncio.set_event_loop(None)
return wrapper
state = []
@asynccontextmanager
async def woohoo():
state.append(1)
yield 42
state.append(999)
@_async_test
async def test_enter():
class DefaultEnter(AbstractAsyncContextManager):
async def __aexit__(*args):
return
# await super().__aexit__(*args)
manager = DefaultEnter()
got_manager = await manager.__aenter__()
# print(got_manager, manager)
assert got_manager is manager
async with manager as context:
async with woohoo() as x:
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
test_enter()

View File

@@ -17,9 +17,9 @@ def ybug(g):
# From 3.5.1 _wakrefset.py # From 3.5.1 _wakrefset.py
# #
# 3.5: # 3.5:
# withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt # with ::= expr SETUP_WITH POP_TOP suite_stmts_opt
# POP_BLOCK LOAD_CONST COME_FROM # POP_BLOCK LOAD_CONST COME_FROM
# WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY # WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY
def __iter__(self, IterationGuard): def __iter__(self, IterationGuard):

View File

@@ -7,3 +7,40 @@ def readline (self):
continue continue
return return
# From 2.4.6 sre.py
# Bug has to do with "break" not being recognized
# and is a JUMP_FORWARD.
def _parse(a, b, source, state):
while 1:
if b:
while 1:
break
else:
raise
def _parse2(source, state):
while 1:
if a:
if b:
while 1:
this = 1
break
continue
while 1:
if b:
break
x = 3
# Bug was in 2.3 decompilation
def _parse3(source, state):
while 1:
if a:
if b:
x = 1
while 1:
if a:
break
raise

View File

@@ -1,11 +1,13 @@
# 2.6.9 symbols.py # 2.6.9 symbols.py
# Bug in 2.6 is having multple COME_FROMs due to the # Bug in 2.6 is having multple COME_FROMs due to the
# "and" in the "if" clause # "and" in the "if" clause
# RUNNABLE
if __name__: if __name__:
if __file__ and __name__: if __file__ and __name__:
pass pass
elif __name__: elif not __name__:
pass assert False
# 2.6.9 transformer.py # 2.6.9 transformer.py
# Bug in 2.6 is multple COME_FROMs as a result # Bug in 2.6 is multple COME_FROMs as a result
@@ -21,3 +23,20 @@ elif __file__:
assert __name__ or __file__ assert __name__ or __file__
else: else:
pass pass
# From 3.3.7 test_binop.py
# Bug was in ifelsestmt(c) ensuring b+=5 is not in "else"
# Also note: ifelsetmtc should not have been used since this
# this is not in a loop!
def __floordiv__(a, b):
if a:
b += 1
elif not b:
return a
b += 5
return b
assert __floordiv__(1, 1) == 7
assert __floordiv__(1, 0) == 6
assert __floordiv__(0, 3) == 8
assert __floordiv__(0, 0) == 0

View File

@@ -16,3 +16,25 @@ def withas_bug(self, nested, a, b):
with self.assertRaises(ZeroDivisionError): with self.assertRaises(ZeroDivisionError):
with nested(a(), b()) as (x, y): with nested(a(), b()) as (x, y):
1 // 0 1 // 0
# From 3.7.7 test_functools.py
# Bug is a unreachable code after "return"
def test_invalid_registrations(x):
return
with x:
x = 1
# From 3.7.7 test_re.py
# Bug was hooking in c_with.
def test_re_tests(tests):
for t in tests:
with a:
continue
# Adapted from 3.8 distutils/command/config.py
# In 3.8 the problem was in handling "with .. as" code
def _gen_temp_sourcefile(x, a, headers, lang):
with x as y:
if a:
y = 2
return 5

View File

@@ -1 +1,3 @@
/.python-version /.python-version
/runun33.sh
/runun7.sh

View File

@@ -81,6 +81,6 @@ SKIP_TESTS=(
) )
# About 265 tests in 14 minutes # About 265 tests in 14 minutes
if (( batch )) ; then if (( BATCH )) ; then
SKIP_TESTS[test_doctest.py]=1 # Fails on ppc64le SKIP_TESTS[test_doctest.py]=1 # Fails on ppc64le
fi fi

View File

@@ -1,4 +1,12 @@
SKIP_TESTS=( SKIP_TESTS=(
# ifelsestmt is borked in:
# if filename == 'srcfile':
# return srcfile
# if filename == 'destfile':
# return destfile
# assert 0 # shouldn't reach here.
[test_shutil.py]=1
[test___all__.py]=1 # it fails on its own [test___all__.py]=1 # it fails on its own
[test___all__.py]=1 # it fails on its own [test___all__.py]=1 # it fails on its own
@@ -59,6 +67,7 @@ SKIP_TESTS=(
[test_scriptpackages.py]=1 # it fails on its own [test_scriptpackages.py]=1 # it fails on its own
[test_select.py]=1 # test takes too long to run: 11 seconds [test_select.py]=1 # test takes too long to run: 11 seconds
[test_socket.py]=1 # test takes too long to run: 12 seconds [test_socket.py]=1 # test takes too long to run: 12 seconds
[test_startfile.py]=1 # it fails on its own [test_startfile.py]=1 # it fails on its own
[test_structmembers.py]=1 # it fails on its own [test_structmembers.py]=1 # it fails on its own
@@ -85,7 +94,7 @@ SKIP_TESTS=(
) )
# About 305 unit-test files in about 12 minutes # About 305 unit-test files in about 12 minutes
if (( batch )) ; then if (( BATCH )) ; then
# Fails in crontab environment? # Fails in crontab environment?
# Figure out what's up here # Figure out what's up here
SKIP_TESTS[test_aifc.py]=1 SKIP_TESTS[test_aifc.py]=1

View File

@@ -1,4 +1,6 @@
SKIP_TESTS=( SKIP_TESTS=(
[test_cgi.py]=1 # FIXME: Works on c90ff51
[test_bsddb3.py]=1 # test takes too long to run: 110 seconds [test_bsddb3.py]=1 # test takes too long to run: 110 seconds
[test_compile.py]=1 # Code introspects on co_consts in a non-decompilable way [test_compile.py]=1 # Code introspects on co_consts in a non-decompilable way
[test_curses.py]=1 # Possibly fails on its own but not detected [test_curses.py]=1 # Possibly fails on its own but not detected
@@ -25,6 +27,7 @@ SKIP_TESTS=(
[test_ssl.py]=1 # [test_ssl.py]=1 #
[test_subprocess.py]=1 # Runs ok but takes 22 seconds [test_subprocess.py]=1 # Runs ok but takes 22 seconds
[test_sys_settrace.py]=1 # Line numbers are expected to be different [test_sys_settrace.py]=1 # Line numbers are expected to be different
[test_tokenize.py]=1 # test takes too long to run: 19 seconds [test_tokenize.py]=1 # test takes too long to run: 19 seconds
[test_traceback.py]=1 # Line numbers change - duh. [test_traceback.py]=1 # Line numbers change - duh.
[test_unicode.py]=1 # Too long to run 11 seconds [test_unicode.py]=1 # Too long to run 11 seconds
@@ -34,7 +37,7 @@ SKIP_TESTS=(
) )
# 334 unit-test files in about 15 minutes # 334 unit-test files in about 15 minutes
if (( batch )) ; then if (( BATCH )) ; then
# Fails in crontab environment? # Fails in crontab environment?
# Figure out what's up here # Figure out what's up here
SKIP_TESTS[test_array.py]=1 SKIP_TESTS[test_array.py]=1
@@ -43,6 +46,7 @@ if (( batch )) ; then
SKIP_TESTS[test_doctest2.py]=1 # a POWER thing? SKIP_TESTS[test_doctest2.py]=1 # a POWER thing?
SKIP_TESTS[test_httplib.py]=1 # Ok, but POWER has problems with this SKIP_TESTS[test_httplib.py]=1 # Ok, but POWER has problems with this
SKIP_TESTS[test_pdb.py]=1 # Ok, but POWER has problems with this SKIP_TESTS[test_pdb.py]=1 # Ok, but POWER has problems with this
SKIP_TESTS[test_tarfile.py]=1 # test can take over 15 seconds to run on an overloaded POWER7 system
# SyntaxError: Non-ASCII character '\xdd' in file test_base64.py on line 153, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details # SyntaxError: Non-ASCII character '\xdd' in file test_base64.py on line 153, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details
SKIP_TESTS[test_base64.py]=1 SKIP_TESTS[test_base64.py]=1

View File

@@ -17,8 +17,6 @@ SKIP_TESTS=(
[test_peepholer.py]=1 [test_peepholer.py]=1
[test_pep352.py]=1 [test_pep352.py]=1
[test_quopri.py]=1 # TypeError: Can't convert 'bytes' object to str implicitly
[test_runpy.py]=1 [test_runpy.py]=1
[test_ssl.py]=1 # too installation specific [test_ssl.py]=1 # too installation specific
@@ -31,9 +29,8 @@ SKIP_TESTS=(
) )
if (( batch )) ; then if (( BATCH )) ; then
# Fails in crontab environment? # Fails in crontab environment?
# Figure out what's up here # Figure out what's up here
SKIP_TESTS[test_exception_variations.py]=1 SKIP_TESTS[test_exception_variations.py]=1
SKIP_TESTS[test_quopri.py]=1
fi fi

View File

@@ -1,7 +1,19 @@
SKIP_TESTS=( SKIP_TESTS=(
[test_atexit.py]=1 # The atexit test starting at 3.3 looks for specific comments in error lines # FIXME: Did this work sometime in the past ?
# for elem in g(s):
# if not tgt and isOdd(elem): continue
# is erroneously:
# for elem in g(s):
# if tgt or isOdd(elem):
# pass
# else:
# tgt.append(elem)
[test_itertools.py]=1
[test_buffer.py]=1 # parse error [test_buffer.py]=1 # FIXME: Works on c90ff51
[test_cmath.py]=1 # FIXME: Works on c90ff51
[test_atexit.py]=1 # The atexit test starting at 3.3 looks for specific comments in error lines
[test_cmd_line.py]=1 # too long? [test_cmd_line.py]=1 # too long?
[test_concurrent_futures.py]=1 # too long? [test_concurrent_futures.py]=1 # too long?
@@ -30,6 +42,7 @@ SKIP_TESTS=(
[test_nntplib.py]=1 [test_nntplib.py]=1
[test_pep352.py]=1 # test failures
[test_peepholer.py]=1 [test_peepholer.py]=1
[test_poll.py]=1 # test takes too long to run: 11 seconds [test_poll.py]=1 # test takes too long to run: 11 seconds
[test_pty.py]=1 # FIXME: Needs grammar loop isolation separation [test_pty.py]=1 # FIXME: Needs grammar loop isolation separation
@@ -57,7 +70,7 @@ SKIP_TESTS=(
) )
# About 300 unit-test files in about 20 minutes # About 300 unit-test files in about 20 minutes
if (( batch )) ; then if (( BATCH )) ; then
SKIP_TESTS[test_ftplib.py]=1 # Runs too long on POWER; over 15 seconds SKIP_TESTS[test_ftplib.py]=1 # Runs too long on POWER; over 15 seconds
SKIP_TESTS[test_idle.py]=1 # No tk SKIP_TESTS[test_idle.py]=1 # No tk
SKIP_TESTS[test_pep352.py]=1 # UnicodeDecodeError may be funny on weird environments SKIP_TESTS[test_pep352.py]=1 # UnicodeDecodeError may be funny on weird environments

View File

@@ -1,11 +1,29 @@
SKIP_TESTS=( SKIP_TESTS=(
# FIXME: Did this work sometime in the past ?
# for elem in g(s):
# if not tgt and isOdd(elem): continue
# is erroneously:
# for elem in g(s):
# if tgt or isOdd(elem):
# pass
# else:
# tgt.append(elem)
[test_itertools.py]=1
[test_buffer.py]=1 # FIXME: Works on c90ff51
[test_cmath.py]=1 # FIXME: Works on c90ff51
[test_strftime.py]=1 # FIXME: Works on c90ff51
[test___all__.py]=1 # it fails on its own [test___all__.py]=1 # it fails on its own
[test_atexit.py]=1 # The atexit test looks for specific comments in error lines [test_atexit.py]=1 # The atexit test looks for specific comments in error lines
[test_cmd_line.py]=1 # takes too long to run [test_cmd_line.py]=1 # takes too long to run
[test_concurrent_futures.py]=1 # too long? [test_concurrent_futures.py]=1 # too long?
[test_configparser.py]=1 # Doesn't terminate [test_configparser.py]=1 # Doesn't terminate
[test_ctypes.py]=1 # it fails on its own [test_ctypes.py]=1 # it fails on its own
[test_curses.py]=1 # Investigate [test_curses.py]=1 # Investigate
[test_dbm_gnu.py]=1 # fails on its own [test_dbm_gnu.py]=1 # fails on its own
[test_devpoll.py]=1 # it fails on its own [test_devpoll.py]=1 # it fails on its own
[test_descr.py]=1 # test assertion errors [test_descr.py]=1 # test assertion errors
@@ -14,33 +32,44 @@ SKIP_TESTS=(
[test_doctest2.py]=1 [test_doctest2.py]=1
[test_doctest.py]=1 # test assert failures [test_doctest.py]=1 # test assert failures
[test_docxmlrpc.py]=1 [test_docxmlrpc.py]=1
[test_enum.py]=1 # compile syntax? [test_enum.py]=1 # compile syntax?
[test_exceptions.py]=1 [test_exceptions.py]=1
[test_faulthandler.py]=1 [test_faulthandler.py]=1
[test_file_eintr.py]=1 # parse error [test_file_eintr.py]=1 # parse error
[test_fork1.py]=1 # too long [test_fork1.py]=1 # too long
[test_gdb.py]=1 # it fails on its own [test_gdb.py]=1 # it fails on its own
[test_grammar.py]=1 # parse error [test_grammar.py]=1 # parse error
[test_httplib.py]=1 # it fails on its own [test_httplib.py]=1 # it fails on its own
[test_import.py]=1 # it fails on its own [test_import.py]=1 # it fails on its own
[test_io.py]=1 [test_io.py]=1
[test_ioctl.py]=1 # it fails on its own [test_ioctl.py]=1 # it fails on its own
[test_inspect.py]=1 # Syntax error Investigate [test_inspect.py]=1 # Syntax error Investigate
[test_logging.py]=1 # Too long to run [test_logging.py]=1 # Too long to run
[test_long.py]=1 # FIXME: Works on c90ff51 [test_long.py]=1 # FIXME: Works on c90ff51
[test_modulefinder.py]=1 # test assertion error [test_modulefinder.py]=1 # test assertion error
[test_multiprocessing_fork.py]=1 # doesn't terminate [test_multiprocessing_fork.py]=1 # doesn't terminate
[test_multiprocessing_forkserver.py]=1 # doesn't terminate [test_multiprocessing_forkserver.py]=1 # doesn't terminate
[test_multiprocessing_main_handling.py]=1 # doesn't terminate [test_multiprocessing_main_handling.py]=1 # doesn't terminate
[test_multiprocessing_spawn.py]=1 # doesn't terminate [test_multiprocessing_spawn.py]=1 # doesn't terminate
[test_nntplib.py]=1 # too long to run [test_nntplib.py]=1 # too long to run
[test_peepholer.py]=1 # control flow? [test_peepholer.py]=1 # control flow?
[test_pep352.py]=1 # test assert failures [test_pep352.py]=1 # test assert failures
[test_pickle.py]=1 # test assert failures [test_pickle.py]=1 # test assert failures
[test_pkgimport.py]=1 # long [test_pkgimport.py]=1 # long
[test_poll.py]=1 # Too long to run: 11 seconds [test_poll.py]=1 # Too long to run: 11 seconds
[test_pydoc.py]=1 # test assertion failures [test_pydoc.py]=1 # test assertion failures
[test_runpy.py]=1 # Too long: [test_runpy.py]=1 # Too long:
[test_select.py]=1 # Too long: 11 seconds [test_select.py]=1 # Too long: 11 seconds
[test_selectors.py]=1 # Too long: 11 seconds [test_selectors.py]=1 # Too long: 11 seconds
[test_signal.py]=1 # Too long: 22 seconds [test_signal.py]=1 # Too long: 22 seconds
@@ -50,12 +79,15 @@ SKIP_TESTS=(
[test_subprocess.py]=1 # Too long [test_subprocess.py]=1 # Too long
[test_symtable.py]=1 # Investigate bad output [test_symtable.py]=1 # Investigate bad output
[test_sys_settrace.py]=1 # test assert failures [test_sys_settrace.py]=1 # test assert failures
[test_tcl.py]=1 # May be implementation specific. On POWER though it fails [test_tcl.py]=1 # May be implementation specific. On POWER though it fails
[test_threading.py]=1 # Too long [test_threading.py]=1 # Too long
[test_threadsignals.py]=1 # Too long to run: 12 seconds [test_threadsignals.py]=1 # Too long to run: 12 seconds
[test_timeout.py]=1 # Too long to run: 19 seconds [test_timeout.py]=1 # Too long to run: 19 seconds
[test_traceback.py]=1 # introspects on code [test_traceback.py]=1 # introspects on code
[test_urllib2net.py]=1 # Doesn't terminate [test_urllib2net.py]=1 # Doesn't terminate
[test_zipfile64.py]=1 [test_zipfile64.py]=1
[test_zlib.py]=1 [test_zlib.py]=1
) )
@@ -66,5 +98,4 @@ if (( batch )) ; then
# Figure out what's up here # Figure out what's up here
SKIP_TESTS[test_exception_variations.py]=1 SKIP_TESTS[test_exception_variations.py]=1
SKIP_TESTS[test_mailbox.py]=1 # Takes to long on POWER; over 15 secs SKIP_TESTS[test_mailbox.py]=1 # Takes to long on POWER; over 15 secs
SKIP_TESTS[test_quopri.py]=1
fi fi

View File

@@ -1,11 +1,7 @@
SKIP_TESTS=( SKIP_TESTS=(
[test_buffer.py]=1 # FIXME: Works on c90ff51 [test_buffer.py]=1 # FIXME: Works on c90ff51
[test_decorators.py]=1 # FIXME: Works on c90ff51 [test_platform.py]=1 # FIXME: Works on c90ff51
[test_platform.py]=1 # FIXME: Works on c90ff51 [test_pyclbr.py]=1 # FIXME: Works on c90ff51
[test_pyclbr.py]=1 # FIXME: Works on c90ff51
[test_tempfile.py]=1 # FIXME: Works on c90ff51
[test_uu.py]=1 # FIXME: Works on c90ff51
[test_ftplib.py]=1 # FIXME: Works on c90ff51
[test___all__.py]=1 # it fails on its own [test___all__.py]=1 # it fails on its own
[test_aifc.py]=1 # [test_aifc.py]=1 #
@@ -100,6 +96,7 @@ SKIP_TESTS=(
[test_sys_settrace.py]=1 # test assert fail [test_sys_settrace.py]=1 # test assert fail
[test_tcl.py]=1 # it fails on its own [test_tcl.py]=1 # it fails on its own
[test_tempfile.py]=1 # test assertion failures
[test_thread.py]=1 [test_thread.py]=1
[test_threading.py]=1 [test_threading.py]=1
[test_timeout.py]=1 [test_timeout.py]=1
@@ -115,6 +112,7 @@ SKIP_TESTS=(
[test_urllib2net.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_urllibnet.py]=1 # it fails on its own
[test_urlparse.py]=1 # test assert error [test_urlparse.py]=1 # test assert error
[test_uu.py]=1 # test assert error
[test_winreg.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
@@ -129,7 +127,7 @@ SKIP_TESTS=(
) )
# About 260 unit-test in about 16 minutes # About 260 unit-test in about 16 minutes
if (( batch )) ; then if (( BATCH )) ; then
SKIP_TESTS[test_asyncore.py]=1 # Ok, but takes more than 15 seconds to run SKIP_TESTS[test_asyncore.py]=1 # Ok, but takes more than 15 seconds to run
SKIP_TESTS[test_bisect.py]=1 SKIP_TESTS[test_bisect.py]=1
SKIP_TESTS[test_compileall.py]=1 # Something weird on POWER SKIP_TESTS[test_compileall.py]=1 # Something weird on POWER
@@ -137,10 +135,10 @@ if (( batch )) ; then
SKIP_TESTS[test_distutils.py]=1 SKIP_TESTS[test_distutils.py]=1
SKIP_TESTS[test_exception_variations.py]=1 SKIP_TESTS[test_exception_variations.py]=1
SKIP_TESTS[test_ioctl.py]=1 # it fails on its own
SKIP_TESTS[test_poplib.py]=1 # May be a result of POWER installation SKIP_TESTS[test_poplib.py]=1 # May be a result of POWER installation
SKIP_TESTS[test_quopri.py]=1 SKIP_TESTS[test_sysconfig.py]=1 # POWER extension fails
SKIP_TESTS[test_ioctl.py]=1 # it fails on its own
SKIP_TESTS[test_tarfile.py]=1 # too long to run on POWER 15 secs SKIP_TESTS[test_tarfile.py]=1 # too long to run on POWER 15 secs
SKIP_TESTS[test_venv.py]=1 # takes too long 11 seconds SKIP_TESTS[test_venv.py]=1 # takes too long 11 seconds
fi fi

View File

@@ -1,13 +1,12 @@
SKIP_TESTS=( SKIP_TESTS=(
[test_ast.py]=1 # FIXME: Works on c90ff51 [test_ast.py]=1 # FIXME: Works on c90ff51
[test_binop.py]=1 # FIXME: Works on c90ff51 [test_cmath.py]=1 # FIXME: Works on c90ff51
[test_complex.py]=1 # FIXME: Works on c90ff51
[test_format.py]=1 # FIXME: Works on c90ff51 [test_format.py]=1 # FIXME: Works on c90ff51
[test_ftplib.py]=1 # FIXME: Works on c90ff51 [test_ftplib.py]=1 # FIXME: Works on c90ff51
[test_slice.py]=1 # FIXME: Works on c90ff51 [test_slice.py]=1 # FIXME: Works on c90ff51
[test_sort.py]=1 # FIXME: Works on c90ff51 [test_sort.py]=1 # FIXME: Works on c90ff51
[test_timeit.py]=1 # FIXME: Works on c90ff51 [test_timeit.py]=1 # FIXME: Works on c90ff51
[test_os.py]=1 # FIXME: Works on c90ff51 [test_os.py]=1 # parse error FIXME: Works on c90ff51
[test___all__.py]=1 # it fails on its own [test___all__.py]=1 # it fails on its own
[test_aifc.py]=1 # [test_aifc.py]=1 #
@@ -49,6 +48,7 @@ SKIP_TESTS=(
[test_datetime.py]=1 # it fails on its own [test_datetime.py]=1 # it fails on its own
[test_dbm_ndbm.py]=1 # it fails on its own [test_dbm_ndbm.py]=1 # it fails on its own
[test_decimal.py]=1 [test_decimal.py]=1
[test_decorators.py]=1 # control-flow failures
[test_descr.py]=1 # syntax error: Investigate [test_descr.py]=1 # syntax error: Investigate
[test_devpoll.py]=1 # it fails on its own [test_devpoll.py]=1 # it fails on its own
[test_dict.py]=1 # it fails on its own [test_dict.py]=1 # it fails on its own
@@ -106,7 +106,8 @@ SKIP_TESTS=(
[test_nntplib.py]=1 # test takes too long to run: 31 seconds [test_nntplib.py]=1 # test takes too long to run: 31 seconds
[test_normalization.py]=1 # it fails on its own [test_normalization.py]=1 # it fails on its own
[test_ordered_dict.py]= # it fails on its own [test_optparse.py]=1 # test fails
[test_ordered_dict.py]=1 # it fails on its own
[test_ossaudiodev.py]=1 # it fails on its own [test_ossaudiodev.py]=1 # it fails on its own
[test_pdb.py]=1 # Probably introspection [test_pdb.py]=1 # Probably introspection
@@ -122,8 +123,6 @@ SKIP_TESTS=(
[test_pyclbr.py]=1 # it fails on its own [test_pyclbr.py]=1 # it fails on its own
[test_pydoc.py]=1 # it fails on its own [test_pydoc.py]=1 # it fails on its own
[test_quopri.py]=1 # AssertionError: b'123=four' != '123=four'
[test_random.py]=1 # it fails on its own [test_random.py]=1 # it fails on its own
[test_range.py]=1 [test_range.py]=1
[test_regrtest.py]=1 # test takes too long to run: 12 seconds [test_regrtest.py]=1 # test takes too long to run: 12 seconds
@@ -147,6 +146,7 @@ SKIP_TESTS=(
[test_startfile.py]=1 # it fails on its own [test_startfile.py]=1 # it fails on its own
[test_statistics.py]=1 # it fails on its own [test_statistics.py]=1 # it fails on its own
[test_string_literals.py]=1 [test_string_literals.py]=1
[test_strftime.py]=1 # test assertion failures
[test_strtod.py]=1 # it fails on its own [test_strtod.py]=1 # it fails on its own
[test_struct.py]=1 # test assertion errors [test_struct.py]=1 # test assertion errors
[test_subprocess.py]=1 [test_subprocess.py]=1
@@ -200,8 +200,10 @@ SKIP_TESTS=(
) )
# 236 unit-test files in about 13 minutes # 236 unit-test files in about 13 minutes
if (( batch )) ; then if (( BATCH )) ; then
SKIP_TESTS[test_codeccallbacks.py]=1 SKIP_TESTS[test_codeccallbacks.py]=1
SKIP_TESTS[test_complex.py]=1 # Something funky with POWER8
# locale on test machine is probably customized # locale on test machine is probably customized
SKIP_TESTS[test__locale.py]=1 SKIP_TESTS[test__locale.py]=1
fi fi

View File

@@ -1,6 +1,22 @@
SKIP_TESTS=( SKIP_TESTS=(
# FIXME: Did this work sometime in the past ?
# for elem in g(s):
# if not tgt and isOdd(elem): continue
# is erroneously:
# for elem in g(s):
# if tgt or isOdd(elem):
# pass
# else:
# tgt.append(elem)
[test_itertools.py]=1
# Fails on decompyle3 as well.
# complicated control flow and "and/or" expressions
[test_pickle.py]=1
[test_builtin.py]=1 # FIXME works on decompyle6 [test_builtin.py]=1 # FIXME works on decompyle6
[test_context.py]=1 # FIXME works on decompyle6 [test_context.py]=1 # FIXME works on decompyle6
[test_doctest2.py]=1 # FIXME works on decompyle6
[test_format.py]=1 # FIXME works on decompyle6 [test_format.py]=1 # FIXME works on decompyle6
[test_marshal.py]=1 # FIXME works on decompyle6 [test_marshal.py]=1 # FIXME works on decompyle6
[test_normalization.py]=1 # FIXME works on decompyle6 [test_normalization.py]=1 # FIXME works on decompyle6
@@ -9,12 +25,11 @@ SKIP_TESTS=(
[test_slice.py]=1 # FIXME works on decompyle6 [test_slice.py]=1 # FIXME works on decompyle6
[test_sort.py]=1 # FIXME works on decompyle6 [test_sort.py]=1 # FIXME works on decompyle6
[test_statistics.py]=1 # FIXME works on decompyle6 [test_statistics.py]=1 # FIXME works on decompyle6
[test_string_literals.py]=1 # FIXME works on decompyle6
[test_timeit.py]=1 # FIXME works on decompyle6 [test_timeit.py]=1 # FIXME works on decompyle6
[test_urllib2_localnet.py]=1 # FIXME works on decompyle6 [test_urllib2_localnet.py]=1 # FIXME works on decompyle6
[test_urllib2.py]=1 # FIXME: works on uncompyle6 [test_urllib2.py]=1 # FIXME: works on uncompyle6
[test_generators.py]=1 # Investigate improper lamdba with bogus "False" added [test_generators.py]=1 # FIXME: works on uncompyle6 - lambda parsing probably
[test_grammar.py]=1 # investigate: like above: semantic rule missing probably [test_grammar.py]=1 # FIXME: works on uncompyle6 - lambda parsing probably
[test___all__.py]=1 # it fails on its own [test___all__.py]=1 # it fails on its own
[test_argparse.py]=1 #- it fails on its own [test_argparse.py]=1 #- it fails on its own
@@ -133,7 +148,8 @@ SKIP_TESTS=(
) )
# 306 unit-test files in about 19 minutes # 306 unit-test files in about 19 minutes
if (( batch )) ; then if (( BATCH )) ; then
SKIP_TESTS[test_capi.py]=1 # more than 15 secs to run on POWER
SKIP_TESTS[test_dbm_gnu.py]=1 # fails on its own on POWER SKIP_TESTS[test_dbm_gnu.py]=1 # fails on its own on POWER
SKIP_TESTS[test_distutils.py]=1 SKIP_TESTS[test_distutils.py]=1
SKIP_TESTS[test_fileio.py]=1 SKIP_TESTS[test_fileio.py]=1

View File

@@ -1,10 +1,14 @@
SKIP_TESTS=( SKIP_TESTS=(
[test_time.py]=1 # FIXME: works on uncompyle6? [test_mimetypes.py]=1 # parse error. decompile3 works. Release 3.6.4 works?
[test_time.py]=1 # FIXME: parse eror. decompyle3 works. Release 3.6.4 works?
[test_aifc.py]=1 # parse error; decompile3 works
[test_doctest2.py]=1 # test failures release 3.6.4 works?
[test_finalization.py]=1 # test failures release 3.6.4 works?
[test_urllib2.py]=1 # FIXME: works on uncompyle6? [test_urllib2.py]=1 # FIXME: works on uncompyle6?
[test_zipimport.py]=1 # FIXME: works on uncompyle6 [test_zipimport.py]=1 # FIXME: works on uncompyle6
[test___all__.py]=1 # it fails on its own [test___all__.py]=1 # it fails on its own
[test_aifc.py]=1 # parse error
[test_argparse.py]=1 #- it fails on its own [test_argparse.py]=1 #- it fails on its own
[test_array.py]=1 #- parse error [test_array.py]=1 #- parse error
[test_asdl_parser.py]=1 # it fails on its own [test_asdl_parser.py]=1 # it fails on its own
@@ -76,6 +80,7 @@ SKIP_TESTS=(
[test_difflib.py]=1 # parse error [test_difflib.py]=1 # parse error
[test_dis.py]=1 # We change line numbers - duh! [test_dis.py]=1 # We change line numbers - duh!
[test_doctest.py]=1 # parse error [test_doctest.py]=1 # parse error
[test_doctest2.py]=1 # test faiures relesae 3.6.4 works?
[test_docxmlrpc.py]=1 [test_docxmlrpc.py]=1
[test_dtrace.py]=1 # parse error [test_dtrace.py]=1 # parse error
[test_dummy_thread.py]=1 # parse error [test_dummy_thread.py]=1 # parse error
@@ -91,6 +96,7 @@ SKIP_TESTS=(
[test_exceptions.py]=1 # parse error [test_exceptions.py]=1 # parse error
[test_faulthandler.py]=1 # takes too long [test_faulthandler.py]=1 # takes too long
[test_file_eintr.py]=1 # too long to run test; works on 3.7.7
[test_fcntl.py]=1 [test_fcntl.py]=1
[test_filecmp.py]=1 # parse error [test_filecmp.py]=1 # parse error
[test_fileinput.py]=1 [test_fileinput.py]=1
@@ -329,7 +335,7 @@ SKIP_TESTS=(
) )
# 114 test files, Elapsed time about 7 minutes # 114 test files, Elapsed time about 7 minutes
if (( batch )) ; then if (( BATCH )) ; then
SKIP_TESTS[test_idle.py]=1 # Probably installation specific SKIP_TESTS[test_idle.py]=1 # Probably installation specific
SKIP_TESTS[test_tix.py]=1 # fails on its own SKIP_TESTS[test_tix.py]=1 # fails on its own
SKIP_TESTS[test_ttk_textonly.py]=1 # Installation dependent? SKIP_TESTS[test_ttk_textonly.py]=1 # Installation dependent?

View File

@@ -3,28 +3,50 @@
function displaytime { function displaytime {
printf "ran in " printf "ran in "
local T=$1 local T=$1
local D=$((T/60/60/24)) ((D=T/60/60/24))
local H=$((T/60/60%24)) ((H=T/60/60%24))
local M=$((T/60%60)) ((M=T/60%60))
local S=$((T%60)) ((S=T%60))
(( $D > 0 )) && printf '%d days ' $D (( D > 0 )) && printf '%d days ' $D
(( $H > 0 )) && printf '%d hours ' $H (( H > 0 )) && printf '%d hours ' $H
(( $M > 0 )) && printf '%d minutes ' $M (( M > 0 )) && printf '%d minutes ' $M
(( $D > 0 || $H > 0 || $M > 0 )) && printf 'and ' (( D > 0 || H > 0 || M > 0 )) && printf 'and '
printf '%d seconds\n' $S printf '%d seconds\n' $S
} }
. ../../admin-tools/pyenv-newer-versions bs=${BASH_SOURCE[0]}
if [[ $0 != $bs ]] ; then
echo "This script should not be *sourced* but run through bash"
exit 1
fi
mydir=$(dirname $bs)
cd $mydir
branch=$(cat ../../.git/HEAD | cut -d'/' -f 3)
if [[ $branch == 'python-2.4' ]]; then
. ../../admin-tools/pyenv-older-versions
elif [[ $branch == 'master' ]]; then
. ../../admin-tools/pyenv-newer-versions
else
echo &1>2 "Error git branch should either be 'master' or 'python-2.4'; got: '$branch'"
exit 1
fi
MAIN="runtests.sh"
USER=${USER:-rocky} USER=${USER:-rocky}
EMAIL=${EMAIL:-rb@dustyfeet.com} EMAIL=${EMAIL:-rb@dustyfeet.com}
SUBJECT_PREFIX="stdlib unit testing for" WHAT="uncompyle6 ${MAIN}"
export BATCH=1
typeset -i RUN_STARTTIME=$(date +%s) typeset -i RUN_STARTTIME=$(date +%s)
actual_versions=""
DEBUG="" # -x DEBUG="" # -x
MAILBODY=/tmp/${MAIN}-mailbody-$$.txt
for VERSION in $PYVERSIONS ; do for VERSION in $PYVERSIONS ; do
typeset -i rc=0 typeset -i rc=0
LOGFILE=/tmp/runtests-$VERSION-$$.log LOGFILE=/tmp/runtests-$VERSION-$$.log
@@ -34,24 +56,37 @@ for VERSION in $PYVERSIONS ; do
continue continue
;; ;;
esac esac
actual_versions="$actual_versions $VERSION"
if ! pyenv local $VERSION ; then if ! pyenv local $VERSION ; then
rc=1 rc=1
else else
STOP_ONERROR=1 /bin/bash $DEBUG ./runtests.sh >$LOGFILE 2>&1 typeset -i ALL_FILES_STARTTIME=$(date +%s)
rc=$? STOP_ONERROR=1 /bin/bash $DEBUG ./runtests.sh >$LOGFILE 2>&1
rc=$?
echo Python Version $(pyenv local) >> $LOGFILE
echo "" >>$LOGFILE
typeset -i ALL_FILES_ENDTIME=$(date +%s)
(( time_diff = ALL_FILES_ENDTIME - ALL_FILES_STARTTIME))
time_str=$(displaytime $time_diff)
echo ${time_str}. >> $LOGFILE
fi fi
SUBJECT_PREFIX="runtests verify for"
SUBJECT_PREFIX="$WHAT for"
if ((rc == 0)); then if ((rc == 0)); then
mailbody_line="Python $VERSION ok; ${time_str}."
tail -v $LOGFILE | mail -s "$SUBJECT_PREFIX $VERSION ok" ${USER}@localhost tail -v $LOGFILE | mail -s "$SUBJECT_PREFIX $VERSION ok" ${USER}@localhost
else else
mailbody_line="Python $VERSION failed; ${time_str}."
tail -v $LOGFILE | mail -s "$SUBJECT_PREFIX $VERSION not ok" ${USER}@localhost tail -v $LOGFILE | mail -s "$SUBJECT_PREFIX $VERSION not ok" ${USER}@localhost
tail -v $LOGFILE | mail -s "$SUBJECT_PREFIX $VERSION not ok" $EMAIL tail -v $LOGFILE | mail -s "$HOST $SUBJECT_PREFIX $VERSION not ok" $EMAIL
fi fi
echo $mailbody_line >> $MAILBODY
done done
typeset -i RUN_ENDTIME=$(date +%s) typeset -i RUN_ENDTIME=$(date +%s)
(( time_diff = RUN_ENDTIME - RUN_STARTTIME)) (( time_diff = RUN_ENDTIME - RUN_STARTTIME))
elapsed_time=$(displaytime $time_diff) elapsed_time=$(displaytime $time_diff)
echo "Run complete $elapsed_time for versions $actual_versions" | mail -s "runtests in $elapsed_time" ${EMAIL} echo "${WHAT} complete; ${elapsed_time}." >> $MAILBODY
echo "Full results are in ${LOGFILE}." >> $MAILBODY
cat $MAILBODY | mail -s "$HOST $WHAT $elapsed_time" ${EMAIL}

View File

@@ -1,10 +1,12 @@
#!/bin/bash #!/bin/bash
me=${BASH_SOURCE[0]} me=${BASH_SOURCE[0]}
typeset -i batch=1 typeset -i BATCH=${BATCH:-0}
isatty=$(/usr/bin/tty 2>/dev/null) if (( ! BATCH )) ; then
if [[ -n $isatty ]] && [[ "$isatty" != 'not a tty' ]] ; then isatty=$(/usr/bin/tty 2>/dev/null)
batch=0 if [[ -n $isatty ]] && [[ "$isatty" != 'not a tty' ]] ; then
BATCH=0
fi
fi fi
@@ -72,11 +74,10 @@ case $PYVERSION in
[test_dis.py]=1 # We change line numbers - duh! [test_dis.py]=1 # We change line numbers - duh!
[test_fileio.py]=1 [test_fileio.py]=1
) )
if (( batch )) ; then if (( BATCH )) ; then
# Fails in crontab environment? # Fails in crontab environment?
# Figure out what's up here # Figure out what's up here
SKIP_TESTS[test_exception_variations.py]=1 SKIP_TESTS[test_exception_variations.py]=1
SKIP_TESTS[test_quopri.py]=1
fi fi
;; ;;
3.1) 3.1)
@@ -85,11 +86,10 @@ case $PYVERSION in
[test_dis.py]=1 # We change line numbers - duh! [test_dis.py]=1 # We change line numbers - duh!
[test_fileio.py]=1 [test_fileio.py]=1
) )
if (( batch )) ; then if (( BATCH )) ; then
# Fails in crontab environment? # Fails in crontab environment?
# Figure out what's up here # Figure out what's up here
SKIP_TESTS[test_exception_variations.py]=1 SKIP_TESTS[test_exception_variations.py]=1
SKIP_TESTS[test_quopri.py]=1
fi fi
;; ;;
3.2) 3.2)
@@ -129,6 +129,7 @@ fulldir=$(pwd)
# DECOMPILER=uncompyle2 # DECOMPILER=uncompyle2
DECOMPILER=${DECOMPILER:-"$fulldir/../../bin/uncompyle6"} DECOMPILER=${DECOMPILER:-"$fulldir/../../bin/uncompyle6"}
OPTS=${OPTS:-""}
TESTDIR=/tmp/test${PYVERSION} TESTDIR=/tmp/test${PYVERSION}
if [[ -e $TESTDIR ]] ; then if [[ -e $TESTDIR ]] ; then
rm -fr $TESTDIR rm -fr $TESTDIR
@@ -137,6 +138,8 @@ fi
PYENV_ROOT=${PYENV_ROOT:-$HOME/.pyenv} PYENV_ROOT=${PYENV_ROOT:-$HOME/.pyenv}
pyenv_local=$(pyenv local) pyenv_local=$(pyenv local)
echo Python version is $pyenv_local
# pyenv version update # pyenv version update
for dir in ../ ../../ ; do for dir in ../ ../../ ; do
cp -v .python-version $dir cp -v .python-version $dir
@@ -145,18 +148,25 @@ done
mkdir $TESTDIR || exit $? mkdir $TESTDIR || exit $?
cp -r ${PYENV_ROOT}/versions/${PYVERSION}.${MINOR}/lib/python${PYVERSION}/test $TESTDIR cp -r ${PYENV_ROOT}/versions/${PYVERSION}.${MINOR}/lib/python${PYVERSION}/test $TESTDIR
cd $TESTDIR/test if [[ $PYVERSION == 3.2 ]] ; then
cp ${PYENV_ROOT}/versions/${PYVERSION}.${MINOR}/lib/python${PYVERSION}/test/* $TESTDIR
cd $TESTDIR
else
cd $TESTDIR/test
fi
pyenv local $FULLVERSION pyenv local $FULLVERSION
export PYTHONPATH=$TESTDIR export PYTHONPATH=$TESTDIR
export PATH=${PYENV_ROOT}/shims:${PATH} export PATH=${PYENV_ROOT}/shims:${PATH}
DONT_SKIP_TESTS=${DONT_SKIP_TESTS:-0}
# Run tests # Run tests
typeset -i i=0 typeset -i i=0
typeset -i allerrs=0 typeset -i allerrs=0
if [[ -n $1 ]] ; then if [[ -n $1 ]] ; then
files=$1 files=$@
typeset -a files_ary=( $(echo $1) ) typeset -a files_ary=( $(echo $@) )
if (( ${#files_ary[@]} == 1 )) ; then if (( ${#files_ary[@]} == 1 || DONT_SKIP_TESTS == 1 )) ; then
SKIP_TESTS=() SKIP_TESTS=()
fi fi
else else
@@ -166,9 +176,12 @@ fi
typeset -i ALL_FILES_STARTTIME=$(date +%s) typeset -i ALL_FILES_STARTTIME=$(date +%s)
typeset -i skipped=0 typeset -i skipped=0
NOT_INVERTED_TESTS=${NOT_INVERTED_TESTS:-1}
for file in $files; do for file in $files; do
# AIX bash doesn't grok [[ -v SKIP... ]] # AIX bash doesn't grok [[ -v SKIP... ]]
if [[ ${SKIP_TESTS[$file]} == 1 ]] ; then [[ -z ${SKIP_TESTS[$file]} ]] && SKIP_TESTS[$file]=0
if [[ ${SKIP_TESTS[$file]} == ${NOT_INVERTED_TESTS} ]] ; then
((skipped++)) ((skipped++))
continue continue
fi fi
@@ -185,7 +198,7 @@ for file in $files; do
typeset -i ENDTIME=$(date +%s) typeset -i ENDTIME=$(date +%s)
typeset -i time_diff typeset -i time_diff
(( time_diff = ENDTIME - STARTTIME)) (( time_diff = ENDTIME - STARTTIME))
if (( time_diff > 10 )) ; then if (( time_diff > $timeout )) ; then
echo "Skipping test $file -- test takes too long to run: $time_diff seconds" echo "Skipping test $file -- test takes too long to run: $time_diff seconds"
continue continue
fi fi
@@ -197,7 +210,7 @@ for file in $files; do
$fulldir/compile-file.py $file && \ $fulldir/compile-file.py $file && \
mv $file{,.orig} && \ mv $file{,.orig} && \
echo ========== $(date +%X) Decompiling $file =========== echo ========== $(date +%X) Decompiling $file ===========
$DECOMPILER $decompiled_file > $file $DECOMPILER $OPTS $decompiled_file > $file
rc=$? rc=$?
if (( rc == 0 )) ; then if (( rc == 0 )) ; then
echo ========== $(date +%X) Running $file =========== echo ========== $(date +%X) Running $file ===========

View File

@@ -1,7 +0,0 @@
# Whatever it is you want to do, it should be forwarded to the
# to top-level irectories
PHONY=check all
all: check
%:
$(MAKE) -C .. $@

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2015-2016, 2818-2019 by Rocky Bernstein # Copyright (c) 2015-2016, 2818-2020 by Rocky Bernstein
# Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org> # Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org>
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com> # Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
# Copyright (c) 1999 John Aycock # Copyright (c) 1999 John Aycock
@@ -34,8 +34,7 @@ from __future__ import print_function
import sys import sys
from collections import deque from collections import deque
from xdis.code import iscode from xdis import check_object_path, iscode, load_module
from xdis.load import check_object_path, load_module
from uncompyle6.scanner import get_scanner from uncompyle6.scanner import get_scanner
@@ -100,7 +99,9 @@ def disassemble_file(filename, outstream=None):
try to find the corresponding compiled object. try to find the corresponding compiled object.
""" """
filename = check_object_path(filename) filename = check_object_path(filename)
(version, timestamp, magic_int, co, is_pypy, source_size) = load_module(filename) (version, timestamp, magic_int, co, is_pypy, source_size, sip_hash) = load_module(
filename
)
if type(co) == list: if type(co) == list:
for con in co: for con in co:
disco(version, con, outstream) disco(version, con, outstream)

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2015-2016, 2818 by Rocky Bernstein # Copyright (c) 2015-2016, 2818, 2020 by Rocky Bernstein
# #
# This program is free software: you can redistribute it and/or modify # 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 # it under the terms of the GNU General Public License as published by
@@ -15,14 +15,27 @@
from collections import deque from collections import deque
from xdis.code import iscode from xdis import (
from xdis.load import load_file, load_module Bytecode,
from xdis.main import get_opcode iscode,
from xdis.bytecode import Bytecode, findlinestarts, offset2line findlinestarts,
get_opcode,
offset2line,
load_file,
load_module,
)
def line_number_mapping(pyc_filename, src_filename): def line_number_mapping(pyc_filename, src_filename):
(version, timestamp, magic_int, code1, is_pypy, (
source_size) = load_module(pyc_filename) version,
timestamp,
magic_int,
code1,
is_pypy,
source_size,
sip_hash,
) = load_module(pyc_filename)
try: try:
code2 = load_file(src_filename) code2 = load_file(src_filename)
except SyntaxError as e: except SyntaxError as e:
@@ -44,7 +57,10 @@ def number_loop(queue, mappings, opc):
assert code1.co_name == code2.co_name assert code1.co_name == code2.co_name
linestarts_orig = findlinestarts(code1) linestarts_orig = findlinestarts(code1)
linestarts_uncompiled = list(findlinestarts(code2)) linestarts_uncompiled = list(findlinestarts(code2))
mappings += [[line, offset2line(offset, linestarts_uncompiled)] for offset, line in linestarts_orig] mappings += [
[line, offset2line(offset, linestarts_uncompiled)]
for offset, line in linestarts_orig
]
bytecode1 = Bytecode(code1, opc) bytecode1 = Bytecode(code1, opc)
bytecode2 = Bytecode(code2, opc) bytecode2 = Bytecode(code2, opc)
instr2s = bytecode2.get_instructions(code2) instr2s = bytecode2.get_instructions(code2)

View File

@@ -16,8 +16,7 @@ from __future__ import print_function
import datetime, py_compile, os, subprocess, sys, tempfile import datetime, py_compile, os, subprocess, sys, tempfile
from uncompyle6 import verify, IS_PYPY, PYTHON_VERSION from uncompyle6 import verify, IS_PYPY, PYTHON_VERSION
from xdis.code import iscode from xdis import iscode, sysinfo2float
from xdis.magics import sysinfo2float
from uncompyle6.disas import check_object_path from uncompyle6.disas import check_object_path
from uncompyle6.semantics import pysource from uncompyle6.semantics import pysource
from uncompyle6.parser import ParserError from uncompyle6.parser import ParserError
@@ -102,7 +101,7 @@ def decompile(
) )
if PYTHON_VERSION < 3.0 and bytecode_version >= 3.0: if PYTHON_VERSION < 3.0 and bytecode_version >= 3.0:
write( write(
"# Warning: this version has problems handling the Python 3 byte type in contants properly.\n" '# Warning: this version has problems handling the Python 3 "byte" type in constants properly.\n'
) )
if co.co_filename: if co.co_filename:
@@ -183,7 +182,7 @@ def decompile_file(
filename = check_object_path(filename) filename = check_object_path(filename)
code_objects = {} code_objects = {}
(version, timestamp, magic_int, co, is_pypy, source_size) = load_module( (version, timestamp, magic_int, co, is_pypy, source_size, sip_hash) = load_module(
filename, code_objects filename, code_objects
) )

View File

@@ -23,16 +23,16 @@ from __future__ import print_function
import sys import sys
from xdis.code import iscode from xdis import iscode, py_str2float
from xdis.magics import py_str2float
from spark_parser import GenericASTBuilder, DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG from spark_parser import GenericASTBuilder, DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
from uncompyle6.show import maybe_show_asm from uncompyle6.show import maybe_show_asm
class ParserError(Exception): class ParserError(Exception):
def __init__(self, token, offset): def __init__(self, token, offset, debug=PARSER_DEFAULT_DEBUG):
self.token = token self.token = token
self.offset = offset self.offset = offset
self.debug = debug
def __str__(self): def __str__(self):
return "Parse error at or near `%r' instruction at offset %s\n" % ( return "Parse error at or near `%r' instruction at offset %s\n" % (
@@ -206,9 +206,9 @@ class PythonParser(GenericASTBuilder):
else: else:
indent = "-> " indent = "-> "
print("%s%s" % (indent, instructions[i])) print("%s%s" % (indent, instructions[i]))
raise ParserError(err_token, err_token.offset) raise ParserError(err_token, err_token.offset, self.debug["reduce"])
else: else:
raise ParserError(None, -1) raise ParserError(None, -1, self.debug["reduce"])
def get_pos_kw(self, token): def get_pos_kw(self, token):
"""Return then the number of positional parameters and """Return then the number of positional parameters and
@@ -351,7 +351,7 @@ class PythonParser(GenericASTBuilder):
stmt ::= try_except stmt ::= try_except
stmt ::= tryelsestmt stmt ::= tryelsestmt
stmt ::= tryfinallystmt stmt ::= tryfinallystmt
stmt ::= withstmt stmt ::= with
stmt ::= withasstmt stmt ::= withasstmt
stmt ::= del_stmt stmt ::= del_stmt

View File

@@ -7,7 +7,7 @@ from uncompyle6.parsers.parse11 import Python11Parser
class Python10Parser(Python11Parser): class Python10Parser(Python11Parser):
def __init__(self, debug_parser=PARSER_DEFAULT_DEBUG): def __init__(self, debug_parser=PARSER_DEFAULT_DEBUG):
super(Python11Parser, self).__init__(debug_parser) super(Python10Parser, self).__init__(debug_parser)
self.customized = {} self.customized = {}

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2019 Rocky Bernstein # Copyright (c) 2019-2020 Rocky Bernstein
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
from uncompyle6.parser import PythonParserSingle from uncompyle6.parser import PythonParserSingle
@@ -7,7 +7,7 @@ from uncompyle6.parsers.parse12 import Python12Parser
class Python11Parser(Python12Parser): class Python11Parser(Python12Parser):
def __init__(self, debug_parser=PARSER_DEFAULT_DEBUG): def __init__(self, debug_parser=PARSER_DEFAULT_DEBUG):
super(Python12Parser, self).__init__(debug_parser) super(Python11Parser, self).__init__(debug_parser)
self.customized = {} self.customized = {}

View File

@@ -196,8 +196,9 @@ class Python2Parser(PythonParser):
expr ::= slice3 expr ::= slice3
expr ::= unary_convert expr ::= unary_convert
and ::= expr jmp_false expr come_from_opt expr_jt ::= expr jmp_true
or ::= expr jmp_true expr come_from_opt or ::= expr_jt expr come_from_opt
and ::= expr jmp_false expr come_from_opt
unary_convert ::= expr UNARY_CONVERT unary_convert ::= expr UNARY_CONVERT

View File

@@ -8,7 +8,7 @@ from uncompyle6.parsers.parse22 import Python22Parser
class Python21Parser(Python22Parser): class Python21Parser(Python22Parser):
def __init__(self, debug_parser=PARSER_DEFAULT_DEBUG): def __init__(self, debug_parser=PARSER_DEFAULT_DEBUG):
super(Python22Parser, self).__init__(debug_parser) super(Python21Parser, self).__init__(debug_parser)
self.customized = {} self.customized = {}
def p_forstmt21(self, args): def p_forstmt21(self, args):

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2016-2017 Rocky Bernstein # Copyright (c) 2016-2017, 2020 Rocky Bernstein
# Copyright (c) 2000-2002 by hartmut Goebel <hartmut@goebel.noris.de> # Copyright (c) 2000-2002 by hartmut Goebel <hartmut@goebel.noris.de>
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
@@ -8,7 +8,7 @@ from uncompyle6.parsers.parse23 import Python23Parser
class Python22Parser(Python23Parser): class Python22Parser(Python23Parser):
def __init__(self, debug_parser=PARSER_DEFAULT_DEBUG): def __init__(self, debug_parser=PARSER_DEFAULT_DEBUG):
super(Python23Parser, self).__init__(debug_parser) super(Python22Parser, self).__init__(debug_parser)
self.customized = {} self.customized = {}
def p_misc22(self, args): def p_misc22(self, args):

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2016-2018 Rocky Bernstein # Copyright (c) 2016-2018, 2020 Rocky Bernstein
# Copyright (c) 2000-2002 by hartmut Goebel <hartmut@goebel.noris.de> # Copyright (c) 2000-2002 by hartmut Goebel <hartmut@goebel.noris.de>
# Copyright (c) 1999 John Aycock # Copyright (c) 1999 John Aycock
@@ -9,7 +9,7 @@ from uncompyle6.parsers.parse24 import Python24Parser
class Python23Parser(Python24Parser): class Python23Parser(Python24Parser):
def __init__(self, debug_parser=PARSER_DEFAULT_DEBUG): def __init__(self, debug_parser=PARSER_DEFAULT_DEBUG):
super(Python24Parser, self).__init__(debug_parser) super(Python23Parser, self).__init__(debug_parser)
self.customized = {} self.customized = {}
def p_misc23(self, args): def p_misc23(self, args):
@@ -32,8 +32,21 @@ class Python23Parser(Python24Parser):
while1stmt ::= _while1test l_stmts_opt JUMP_BACK while1stmt ::= _while1test l_stmts_opt JUMP_BACK
POP_TOP POP_BLOCK COME_FROM POP_TOP POP_BLOCK COME_FROM
while1stmt ::= _while1test l_stmts_opt JUMP_BACK while1stmt ::= _while1test l_stmts_opt JUMP_BACK COME_FROM
COME_FROM POP_TOP POP_BLOCK COME_FROM POP_TOP POP_BLOCK COME_FROM
# Python 2.3
# The following has no "JUMP_BACK" after l_stmts because
# l_stmts ends in a "break", "return", or "continue"
while1stmt ::= _while1test l_stmts
POP_TOP POP_BLOCK
# The following has a "COME_FROM" at the end which comes from
# a "break" inside "l_stmts".
while1stmt ::= _while1test l_stmts COME_FROM JUMP_BACK
POP_TOP POP_BLOCK COME_FROM
while1stmt ::= _while1test l_stmts JUMP_BACK
POP_TOP POP_BLOCK
list_comp ::= BUILD_LIST_0 DUP_TOP LOAD_ATTR store list_iter del_stmt list_comp ::= BUILD_LIST_0 DUP_TOP LOAD_ATTR store list_iter del_stmt
list_for ::= expr for_iter store list_iter JUMP_BACK come_froms POP_TOP JUMP_BACK list_for ::= expr for_iter store list_iter JUMP_BACK come_froms POP_TOP JUMP_BACK

View File

@@ -38,8 +38,23 @@ class Python24Parser(Python25Parser):
_ifstmts_jump24 ::= c_stmts_opt JUMP_FORWARD POP_TOP _ifstmts_jump24 ::= c_stmts_opt JUMP_FORWARD POP_TOP
# Python 2.5+ omits POP_TOP POP_BLOCK # Python 2.5+ omits POP_TOP POP_BLOCK
while1stmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK POP_TOP POP_BLOCK COME_FROM while1stmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK
while1stmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK POP_TOP POP_BLOCK POP_TOP POP_BLOCK COME_FROM
while1stmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK
POP_TOP POP_BLOCK
continue ::= JUMP_BACK JUMP_ABSOLUTE
# Python 2.4
# The following has no "JUMP_BACK" after l_stmts because
# l_stmts ends in a "break", "return", or "continue"
while1stmt ::= SETUP_LOOP l_stmts
POP_TOP POP_BLOCK
# The following has a "COME_FROM" at the end which comes from
# a "break" inside "l_stmts".
while1stmt ::= SETUP_LOOP l_stmts COME_FROM JUMP_BACK
POP_TOP POP_BLOCK COME_FROM
# Python 2.5+: # Python 2.5+:
# call_stmt ::= expr POP_TOP # call_stmt ::= expr POP_TOP
@@ -73,8 +88,8 @@ class Python24Parser(Python25Parser):
with_cleanup ::= LOAD_FAST DELETE_FAST WITH_CLEANUP END_FINALLY with_cleanup ::= LOAD_FAST DELETE_FAST WITH_CLEANUP END_FINALLY
with_cleanup ::= LOAD_NAME DELETE_NAME WITH_CLEANUP END_FINALLY with_cleanup ::= LOAD_NAME DELETE_NAME WITH_CLEANUP END_FINALLY
withasstmt ::= expr setupwithas store suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM with_cleanup withasstmt ::= expr setupwithas store suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM with_cleanup
withstmt ::= expr setupwith SETUP_FINALLY suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM with_cleanup with ::= expr setupwith SETUP_FINALLY suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM with_cleanup
stmt ::= withstmt stmt ::= with
stmt ::= withasstmt stmt ::= withasstmt
""") """)
super(Python24Parser, self).customize_grammar_rules(tokens, customize) super(Python24Parser, self).customize_grammar_rules(tokens, customize)

View File

@@ -27,7 +27,7 @@ class Python25Parser(Python26Parser):
setup_finally setup_finally
# opcode SETUP_WITH # opcode SETUP_WITH
setupwith ::= DUP_TOP LOAD_ATTR store LOAD_ATTR CALL_FUNCTION_0 POP_TOP setupwith ::= DUP_TOP LOAD_ATTR store LOAD_ATTR CALL_FUNCTION_0 POP_TOP
withstmt ::= expr setupwith SETUP_FINALLY suite_stmts_opt with ::= expr setupwith SETUP_FINALLY suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM with_cleanup POP_BLOCK LOAD_CONST COME_FROM with_cleanup
# Semantic actions want store to be at index 2 # Semantic actions want store to be at index 2
@@ -62,7 +62,7 @@ class Python25Parser(Python26Parser):
# Remove grammar rules inherited from Python 2.6 or Python 2 # Remove grammar rules inherited from Python 2.6 or Python 2
self.remove_rules(""" self.remove_rules("""
setupwith ::= DUP_TOP LOAD_ATTR ROT_TWO LOAD_ATTR CALL_FUNCTION_0 POP_TOP setupwith ::= DUP_TOP LOAD_ATTR ROT_TWO LOAD_ATTR CALL_FUNCTION_0 POP_TOP
withstmt ::= expr setupwith SETUP_FINALLY suite_stmts_opt with ::= expr setupwith SETUP_FINALLY suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM WITH_CLEANUP END_FINALLY POP_BLOCK LOAD_CONST COME_FROM WITH_CLEANUP END_FINALLY
withasstmt ::= expr setupwithas store suite_stmts_opt withasstmt ::= expr setupwithas store suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM WITH_CLEANUP END_FINALLY POP_BLOCK LOAD_CONST COME_FROM WITH_CLEANUP END_FINALLY

View File

@@ -119,8 +119,8 @@ class Python26Parser(Python2Parser):
ifelsestmtc ::= testexpr c_stmts_opt ja_cf_pop else_suitec ifelsestmtc ::= testexpr c_stmts_opt ja_cf_pop else_suitec
# Semantic actions want suite_stmts_opt to be at index 3 # Semantic actions want suite_stmts_opt to be at index 3
withstmt ::= expr setupwith SETUP_FINALLY suite_stmts_opt with ::= expr setupwith SETUP_FINALLY suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM WITH_CLEANUP END_FINALLY POP_BLOCK LOAD_CONST COME_FROM WITH_CLEANUP END_FINALLY
# Semantic actions want store to be at index 2 # Semantic actions want store to be at index 2
withasstmt ::= expr setupwithas store suite_stmts_opt withasstmt ::= expr setupwithas store suite_stmts_opt

View File

@@ -7,6 +7,7 @@ from xdis import next_offset
from uncompyle6.parser import PythonParserSingle, nop_func from uncompyle6.parser import PythonParserSingle, nop_func
from uncompyle6.parsers.parse2 import Python2Parser from uncompyle6.parsers.parse2 import Python2Parser
from uncompyle6.parsers.reducecheck import ( from uncompyle6.parsers.reducecheck import (
or_check,
ifelsestmt, ifelsestmt,
tryelsestmt, tryelsestmt,
) )
@@ -101,8 +102,9 @@ class Python27Parser(Python2Parser):
ret_or ::= expr JUMP_IF_TRUE_OR_POP ret_expr_or_cond COME_FROM ret_or ::= expr JUMP_IF_TRUE_OR_POP ret_expr_or_cond COME_FROM
if_exp_ret ::= expr POP_JUMP_IF_FALSE expr RETURN_END_IF COME_FROM ret_expr_or_cond if_exp_ret ::= expr POP_JUMP_IF_FALSE expr RETURN_END_IF COME_FROM ret_expr_or_cond
or ::= expr JUMP_IF_TRUE_OR_POP expr COME_FROM expr_jitop ::= expr JUMP_IF_TRUE_OR_POP
and ::= expr JUMP_IF_FALSE_OR_POP expr COME_FROM or ::= expr_jitop expr COME_FROM
and ::= expr JUMP_IF_FALSE_OR_POP expr COME_FROM
# compare_chained{1,2} is used exclusively in chained_compare # compare_chained{1,2} is used exclusively in chained_compare
compare_chained1 ::= expr DUP_TOP ROT_THREE COMPARE_OP JUMP_IF_FALSE_OR_POP compare_chained1 ::= expr DUP_TOP ROT_THREE COMPARE_OP JUMP_IF_FALSE_OR_POP
@@ -139,9 +141,11 @@ class Python27Parser(Python2Parser):
# assert condition, expr # assert condition, expr
assert2 ::= assert_expr jmp_true LOAD_ASSERT expr CALL_FUNCTION_1 RAISE_VARARGS_1 assert2 ::= assert_expr jmp_true LOAD_ASSERT expr CALL_FUNCTION_1 RAISE_VARARGS_1
continue ::= JUMP_BACK JUMP_ABSOLUTE
for_block ::= returns _come_froms for_block ::= returns _come_froms
withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt with ::= expr SETUP_WITH POP_TOP suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM_WITH POP_BLOCK LOAD_CONST COME_FROM_WITH
WITH_CLEANUP END_FINALLY WITH_CLEANUP END_FINALLY
@@ -227,6 +231,7 @@ class Python27Parser(Python2Parser):
# FIXME: Put more in this table # FIXME: Put more in this table
self.reduce_check_table = { self.reduce_check_table = {
# "ifelsestmt": ifelsestmt, # "ifelsestmt": ifelsestmt,
"or": or_check,
"tryelsestmt": tryelsestmt, "tryelsestmt": tryelsestmt,
"tryelsestmtl": tryelsestmt, "tryelsestmtl": tryelsestmt,
} }
@@ -237,7 +242,7 @@ class Python27Parser(Python2Parser):
self.check_reduce["except_handler"] = "tokens" self.check_reduce["except_handler"] = "tokens"
self.check_reduce["except_handler_else"] = "tokens" self.check_reduce["except_handler_else"] = "tokens"
# self.check_reduce["or"] = "AST" self.check_reduce["or"] = "AST"
self.check_reduce["raise_stmt1"] = "AST" self.check_reduce["raise_stmt1"] = "AST"
self.check_reduce["iflaststmtl"] = "AST" self.check_reduce["iflaststmtl"] = "AST"
self.check_reduce["ifelsestmt"] = "AST" self.check_reduce["ifelsestmt"] = "AST"

View File

@@ -74,6 +74,7 @@ class Python3Parser(PythonParser):
jb_or_c ::= JUMP_BACK jb_or_c ::= JUMP_BACK
jb_or_c ::= CONTINUE jb_or_c ::= CONTINUE
jb_cfs ::= JUMP_BACK _come_froms
stmt ::= set_comp_func stmt ::= set_comp_func
@@ -269,18 +270,24 @@ class Python3Parser(PythonParser):
jmp_abs ::= JUMP_ABSOLUTE jmp_abs ::= JUMP_ABSOLUTE
jmp_abs ::= JUMP_BACK jmp_abs ::= JUMP_BACK
withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt with ::= expr SETUP_WITH POP_TOP suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM_WITH POP_BLOCK LOAD_CONST COME_FROM_WITH
WITH_CLEANUP END_FINALLY WITH_CLEANUP END_FINALLY
withasstmt ::= expr SETUP_WITH store suite_stmts_opt withasstmt ::= expr SETUP_WITH store suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM_WITH POP_BLOCK LOAD_CONST COME_FROM_WITH
WITH_CLEANUP END_FINALLY WITH_CLEANUP END_FINALLY
expr_jt ::= expr jmp_true
expr_jitop ::= expr JUMP_IF_TRUE_OR_POP
## FIXME: Right now we have erroneous jump targets ## FIXME: Right now we have erroneous jump targets
## This below is probably not correct when the COME_FROM is put in the right place ## This below is probably not correct when the COME_FROM is put in the right place
and ::= expr jmp_false expr COME_FROM and ::= expr jmp_false expr COME_FROM
or ::= expr jmp_true expr COME_FROM or ::= expr_jt expr COME_FROM
or ::= expr_jt expr
or ::= expr_jitop expr COME_FROM
and ::= expr JUMP_IF_FALSE_OR_POP expr COME_FROM
# # something like the below is needed when the jump targets are fixed # # something like the below is needed when the jump targets are fixed
## or ::= expr JUMP_IF_TRUE_OR_POP COME_FROM expr ## or ::= expr JUMP_IF_TRUE_OR_POP COME_FROM expr
@@ -338,9 +345,6 @@ class Python3Parser(PythonParser):
ret_or ::= expr JUMP_IF_TRUE_OR_POP ret_expr_or_cond COME_FROM ret_or ::= expr JUMP_IF_TRUE_OR_POP ret_expr_or_cond COME_FROM
if_exp_ret ::= expr POP_JUMP_IF_FALSE expr RETURN_END_IF COME_FROM ret_expr_or_cond if_exp_ret ::= expr POP_JUMP_IF_FALSE expr RETURN_END_IF COME_FROM ret_expr_or_cond
or ::= expr JUMP_IF_TRUE_OR_POP expr COME_FROM
or ::= expr jmp_true expr
and ::= expr JUMP_IF_FALSE_OR_POP expr COME_FROM
# compare_chained1 is used exclusively in chained_compare # compare_chained1 is used exclusively in chained_compare
compare_chained1 ::= expr DUP_TOP ROT_THREE COMPARE_OP JUMP_IF_FALSE_OR_POP compare_chained1 ::= expr DUP_TOP ROT_THREE COMPARE_OP JUMP_IF_FALSE_OR_POP
@@ -435,10 +439,11 @@ class Python3Parser(PythonParser):
while1elsestmt ::= SETUP_LOOP l_stmts JUMP_BACK while1elsestmt ::= SETUP_LOOP l_stmts JUMP_BACK
else_suitel else_suitel
whileelsestmt ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK POP_BLOCK whileelsestmt ::= SETUP_LOOP testexpr l_stmts_opt jb_cfs POP_BLOCK
else_suitel COME_FROM_LOOP else_suitel COME_FROM_LOOP
whileelsestmt2 ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK POP_BLOCK
whileelsestmt2 ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK POP_BLOCK
else_suitel JUMP_BACK COME_FROM_LOOP else_suitel JUMP_BACK COME_FROM_LOOP
whileTruestmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK POP_BLOCK whileTruestmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK POP_BLOCK
@@ -674,6 +679,7 @@ class Python3Parser(PythonParser):
"RAISE", "RAISE",
"SETUP", "SETUP",
"UNPACK", "UNPACK",
"WITH",
) )
) )

View File

@@ -134,8 +134,9 @@ class Python30Parser(Python31Parser):
jump_except ::= _jump COME_FROM POP_TOP jump_except ::= _jump COME_FROM POP_TOP
expr_jt ::= expr jmp_true
or ::= expr jmp_false expr jmp_true expr or ::= expr jmp_false expr jmp_true expr
or ::= expr jmp_true expr or ::= expr_jt expr
import_from ::= LOAD_CONST LOAD_CONST IMPORT_NAME importlist _come_froms POP_TOP import_from ::= LOAD_CONST LOAD_CONST IMPORT_NAME importlist _come_froms POP_TOP
@@ -212,7 +213,7 @@ class Python30Parser(Python31Parser):
whilestmt ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK POP_BLOCK JUMP_BACK COME_FROM_LOOP whilestmt ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK POP_BLOCK JUMP_BACK COME_FROM_LOOP
whilestmt ::= SETUP_LOOP testexpr returns POP_TOP POP_BLOCK COME_FROM_LOOP whilestmt ::= SETUP_LOOP testexpr returns POP_TOP POP_BLOCK COME_FROM_LOOP
withasstmt ::= expr SETUP_WITH store suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH WITH_CLEANUP END_FINALLY withasstmt ::= expr SETUP_WITH store suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH WITH_CLEANUP END_FINALLY
withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH WITH_CLEANUP END_FINALLY with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH WITH_CLEANUP END_FINALLY
# lc_body ::= LOAD_FAST expr LIST_APPEND # lc_body ::= LOAD_FAST expr LIST_APPEND
# lc_body ::= LOAD_NAME expr LIST_APPEND # lc_body ::= LOAD_NAME expr LIST_APPEND

View File

@@ -15,7 +15,7 @@ class Python31Parser(Python32Parser):
setupwith ::= DUP_TOP LOAD_ATTR store LOAD_ATTR CALL_FUNCTION_0 POP_TOP setupwith ::= DUP_TOP LOAD_ATTR store LOAD_ATTR CALL_FUNCTION_0 POP_TOP
setupwithas ::= DUP_TOP LOAD_ATTR store LOAD_ATTR CALL_FUNCTION_0 store setupwithas ::= DUP_TOP LOAD_ATTR store LOAD_ATTR CALL_FUNCTION_0 store
withstmt ::= expr setupwith SETUP_FINALLY with ::= expr setupwith SETUP_FINALLY
suite_stmts_opt suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM_FINALLY POP_BLOCK LOAD_CONST COME_FROM_FINALLY
load del_stmt WITH_CLEANUP END_FINALLY load del_stmt WITH_CLEANUP END_FINALLY

View File

@@ -50,7 +50,7 @@ class Python35Parser(Python34Parser):
# Python 3.5+ has WITH_CLEANUP_START/FINISH # Python 3.5+ has WITH_CLEANUP_START/FINISH
withstmt ::= expr with ::= expr
SETUP_WITH POP_TOP suite_stmts_opt SETUP_WITH POP_TOP suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM_WITH POP_BLOCK LOAD_CONST COME_FROM_WITH
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY
@@ -138,7 +138,7 @@ class Python35Parser(Python34Parser):
self.remove_rules(""" self.remove_rules("""
yield_from ::= expr GET_ITER LOAD_CONST YIELD_FROM yield_from ::= expr GET_ITER LOAD_CONST YIELD_FROM
yield_from ::= expr expr YIELD_FROM yield_from ::= expr expr YIELD_FROM
withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt with ::= expr SETUP_WITH POP_TOP suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM_WITH POP_BLOCK LOAD_CONST COME_FROM_WITH
WITH_CLEANUP END_FINALLY WITH_CLEANUP END_FINALLY
withasstmt ::= expr SETUP_WITH store suite_stmts_opt withasstmt ::= expr SETUP_WITH store suite_stmts_opt
@@ -209,10 +209,10 @@ class Python35Parser(Python34Parser):
elif opname == 'SETUP_WITH': elif opname == 'SETUP_WITH':
# Python 3.5+ has WITH_CLEANUP_START/FINISH # Python 3.5+ has WITH_CLEANUP_START/FINISH
rules_str = """ rules_str = """
withstmt ::= expr with ::= expr
SETUP_WITH POP_TOP suite_stmts_opt SETUP_WITH POP_TOP suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM_WITH POP_BLOCK LOAD_CONST COME_FROM_WITH
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY
withasstmt ::= expr withasstmt ::= expr
SETUP_WITH store suite_stmts_opt SETUP_WITH store suite_stmts_opt

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2016-2019 Rocky Bernstein # Copyright (c) 2016-2020 Rocky Bernstein
# #
# This program is free software: you can redistribute it and/or modify # 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 # it under the terms of the GNU General Public License as published by
@@ -305,28 +305,25 @@ class Python36Parser(Python35Parser):
self.addRule(rule, nop_func) self.addRule(rule, nop_func)
# Check to combine assignment + annotation into one statement # Check to combine assignment + annotation into one statement
self.check_reduce['assign'] = 'token' self.check_reduce['assign'] = 'token'
elif opname == "WITH_CLEANUP_START":
rules_str = """
stmt ::= with_null
with_null ::= with_suffix
with_suffix ::= WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY
"""
self.addRule(rules_str, nop_func)
elif opname == 'SETUP_WITH': elif opname == 'SETUP_WITH':
rules_str = """ rules_str = """
withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt COME_FROM_WITH with ::= expr SETUP_WITH POP_TOP suite_stmts_opt COME_FROM_WITH
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY with_suffix
# Removes POP_BLOCK LOAD_CONST from 3.6- # Removes POP_BLOCK LOAD_CONST from 3.6-
withasstmt ::= expr SETUP_WITH store suite_stmts_opt COME_FROM_WITH withasstmt ::= expr SETUP_WITH store suite_stmts_opt COME_FROM_WITH
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY with_suffix
with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK
BEGIN_FINALLY COME_FROM_WITH
with_suffix
""" """
if self.version < 3.8:
rules_str += """
withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK
LOAD_CONST
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY
"""
else:
rules_str += """
withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK
BEGIN_FINALLY COME_FROM_WITH
WITH_CLEANUP_START WITH_CLEANUP_FINISH
END_FINALLY
"""
self.addRule(rules_str, nop_func) self.addRule(rules_str, nop_func)
pass pass
pass pass

View File

@@ -94,6 +94,9 @@ class Python37Parser(Python37BaseParser):
else_suitec ::= c_stmts else_suitec ::= c_stmts
else_suitec ::= returns else_suitec ::= returns
else_suite_opt ::= else_suite
else_suite_opt ::= pass
stmt ::= classdef stmt ::= classdef
stmt ::= call_stmt stmt ::= call_stmt
@@ -632,10 +635,19 @@ class Python37Parser(Python37BaseParser):
def p_37conditionals(self, args): def p_37conditionals(self, args):
""" """
expr ::= if_exp37 expr ::= if_exp37
if_exp37 ::= expr expr jf_cfs expr COME_FROM if_exp37 ::= expr expr jf_cfs expr COME_FROM
jf_cfs ::= JUMP_FORWARD _come_froms jf_cfs ::= JUMP_FORWARD _come_froms
ifelsestmt ::= testexpr c_stmts_opt jf_cfs else_suite opt_come_from_except ifelsestmt ::= testexpr c_stmts_opt jf_cfs else_suite opt_come_from_except
# This is probably more realistically an "ifstmt" (with a null else)
# see _cmp() of python3.8/distutils/__pycache__/version.cpython-38.opt-1.pyc
ifelsestmt ::= testexpr stmts jf_cfs else_suite_opt opt_come_from_except
expr_pjit ::= expr POP_JUMP_IF_TRUE
expr_jit ::= expr JUMP_IF_TRUE
expr_jt ::= expr jmp_true
jmp_false37 ::= POP_JUMP_IF_FALSE COME_FROM jmp_false37 ::= POP_JUMP_IF_FALSE COME_FROM
list_if ::= expr jmp_false37 list_iter list_if ::= expr jmp_false37 list_iter
list_iter ::= list_if37 list_iter ::= list_if37
@@ -925,12 +937,14 @@ class Python37Parser(Python37BaseParser):
ret_or ::= expr JUMP_IF_TRUE_OR_POP ret_expr_or_cond COME_FROM ret_or ::= expr JUMP_IF_TRUE_OR_POP ret_expr_or_cond COME_FROM
if_exp_ret ::= expr POP_JUMP_IF_FALSE expr RETURN_END_IF COME_FROM ret_expr_or_cond if_exp_ret ::= expr POP_JUMP_IF_FALSE expr RETURN_END_IF COME_FROM ret_expr_or_cond
jitop_come_from ::= JUMP_IF_TRUE_OR_POP come_froms jitop_come_from_expr ::= JUMP_IF_TRUE_OR_POP come_froms expr
jifop_come_from ::= JUMP_IF_FALSE_OR_POP come_froms jifop_come_from ::= JUMP_IF_FALSE_OR_POP come_froms
or ::= and jitop_come_from expr COME_FROM expr_jitop ::= expr JUMP_IF_TRUE_OR_POP
or ::= expr JUMP_IF_TRUE_OR_POP expr COME_FROM
or ::= expr JUMP_IF_TRUE expr COME_FROM or ::= and jitop_come_from_expr COME_FROM
or ::= expr POP_JUMP_IF_TRUE expr POP_JUMP_IF_FALSE COME_FROM or ::= expr_jitop expr COME_FROM
or ::= expr_jit expr COME_FROM
or ::= expr_pjit expr POP_JUMP_IF_FALSE COME_FROM
testfalse_not_or ::= expr jmp_false expr jmp_false COME_FROM testfalse_not_or ::= expr jmp_false expr jmp_false COME_FROM
testfalse_not_and ::= and jmp_true come_froms testfalse_not_and ::= and jmp_true come_froms
@@ -946,17 +960,17 @@ class Python37Parser(Python37BaseParser):
testexprl ::= testfalsel testexprl ::= testfalsel
testfalsel ::= expr jmp_true testfalsel ::= expr jmp_true
or ::= expr jmp_true expr or ::= expr_jt expr
and ::= expr JUMP_IF_FALSE_OR_POP expr come_from_opt and ::= expr JUMP_IF_FALSE_OR_POP expr come_from_opt
and ::= expr jifop_come_from expr and ::= expr jifop_come_from expr
pjit_come_from ::= POP_JUMP_IF_TRUE COME_FROM expr_pjit_come_from ::= expr POP_JUMP_IF_TRUE COME_FROM
or ::= expr pjit_come_from expr or ::= expr_pjit_come_from expr
## Note that "jmp_false" is what we check on in the "and" reduce rule. ## Note that "jmp_false" is what we check on in the "and" reduce rule.
and ::= expr jmp_false expr COME_FROM and ::= expr jmp_false expr COME_FROM
or ::= expr jmp_true expr COME_FROM or ::= expr_jt expr COME_FROM
# compare_chained1 is used exclusively in chained_compare # compare_chained1 is used exclusively in chained_compare
compare_chained1 ::= expr DUP_TOP ROT_THREE COMPARE_OP JUMP_IF_FALSE_OR_POP compare_chained1 ::= expr DUP_TOP ROT_THREE COMPARE_OP JUMP_IF_FALSE_OR_POP
@@ -1271,7 +1285,7 @@ class Python37Parser(Python37BaseParser):
self.addRule(rule, nop_func) self.addRule(rule, nop_func)
elif opname == "SETUP_WITH": elif opname == "SETUP_WITH":
rules_str = """ rules_str = """
withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt COME_FROM_WITH with ::= expr SETUP_WITH POP_TOP suite_stmts_opt COME_FROM_WITH
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY
# Removes POP_BLOCK LOAD_CONST from 3.6- # Removes POP_BLOCK LOAD_CONST from 3.6-
@@ -1280,13 +1294,13 @@ class Python37Parser(Python37BaseParser):
""" """
if self.version < 3.8: if self.version < 3.8:
rules_str += """ rules_str += """
withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK
LOAD_CONST LOAD_CONST
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY
""" """
else: else:
rules_str += """ rules_str += """
withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK
BEGIN_FINALLY COME_FROM_WITH BEGIN_FINALLY COME_FROM_WITH
WITH_CLEANUP_START WITH_CLEANUP_FINISH WITH_CLEANUP_START WITH_CLEANUP_FINISH
END_FINALLY END_FINALLY

View File

@@ -2,10 +2,10 @@
""" """
Python 3.7 base code. We keep non-custom-generated grammar rules out of this file. Python 3.7 base code. We keep non-custom-generated grammar rules out of this file.
""" """
from uncompyle6.scanners.tok import Token from uncompyle6.parser import ParserError, PythonParser, nop_func
from uncompyle6.parser import PythonParser, PythonParserSingle, nop_func
from uncompyle6.parsers.treenode import SyntaxTree from uncompyle6.parsers.treenode import SyntaxTree
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
from spark_parser.spark import rule2str
from uncompyle6.parsers.reducecheck import ( from uncompyle6.parsers.reducecheck import (
and_check, and_check,
@@ -127,6 +127,7 @@ class Python37BaseParser(PythonParser):
"RAISE", "RAISE",
"SETUP", "SETUP",
"UNPACK", "UNPACK",
"WITH",
) )
) )
@@ -210,41 +211,86 @@ class Python37BaseParser(PythonParser):
if self.version < 3.8: if self.version < 3.8:
rules_str += """ rules_str += """
stmt ::= async_with_stmt SETUP_ASYNC_WITH stmt ::= async_with_stmt SETUP_ASYNC_WITH
async_with_stmt ::= expr c_stmt ::= c_async_with_stmt SETUP_ASYNC_WITH
async_with_stmt ::= expr
async_with_pre
POP_TOP
suite_stmts_opt
POP_BLOCK LOAD_CONST
async_with_post
c_async_with_stmt ::= expr
async_with_pre
POP_TOP
c_suite_stmts_opt
POP_BLOCK LOAD_CONST
async_with_post
async_with_stmt ::= expr
async_with_pre
POP_TOP
suite_stmts_opt
async_with_post
c_async_with_stmt ::= expr
async_with_pre
POP_TOP
c_suite_stmts_opt
async_with_post
async_with_as_stmt ::= expr
async_with_pre
store
suite_stmts_opt
POP_BLOCK LOAD_CONST
async_with_post
c_async_with_as_stmt ::= expr
async_with_pre async_with_pre
POP_TOP store
suite_stmts_opt c_suite_stmts_opt
POP_BLOCK LOAD_CONST POP_BLOCK LOAD_CONST
async_with_post async_with_post
async_with_stmt ::= expr async_with_as_stmt ::= expr
async_with_pre async_with_pre
POP_TOP store
suite_stmts_opt suite_stmts_opt
async_with_post async_with_post
async_with_as_stmt ::= expr c_async_with_as_stmt ::= expr
async_with_pre async_with_pre
store store
suite_stmts_opt suite_stmts_opt
POP_BLOCK LOAD_CONST
async_with_post async_with_post
""" """
else: else:
rules_str += """ rules_str += """
async_with_pre ::= BEFORE_ASYNC_WITH GET_AWAITABLE LOAD_CONST YIELD_FROM SETUP_ASYNC_WITH async_with_pre ::= BEFORE_ASYNC_WITH GET_AWAITABLE LOAD_CONST YIELD_FROM SETUP_ASYNC_WITH
async_with_post ::= BEGIN_FINALLY COME_FROM_ASYNC_WITH async_with_post ::= BEGIN_FINALLY COME_FROM_ASYNC_WITH
WITH_CLEANUP_START GET_AWAITABLE LOAD_CONST YIELD_FROM WITH_CLEANUP_START GET_AWAITABLE LOAD_CONST YIELD_FROM
WITH_CLEANUP_FINISH END_FINALLY WITH_CLEANUP_FINISH END_FINALLY
async_with_stmt ::= expr async_with_stmt ::= expr
async_with_pre
POP_TOP
suite_stmts
POP_TOP POP_BLOCK
async_with_post
c_async_with_stmt ::= expr
async_with_pre
POP_TOP
c_suite_stmts
POP_TOP POP_BLOCK
async_with_post
async_with_stmt ::= expr
async_with_pre
POP_TOP
suite_stmts
POP_BLOCK
BEGIN_FINALLY
WITH_CLEANUP_START GET_AWAITABLE LOAD_CONST YIELD_FROM
WITH_CLEANUP_FINISH POP_FINALLY LOAD_CONST RETURN_VALUE
COME_FROM_ASYNC_WITH
WITH_CLEANUP_START GET_AWAITABLE LOAD_CONST YIELD_FROM
WITH_CLEANUP_FINISH END_FINALLY
c_async_with_stmt ::= expr
async_with_pre async_with_pre
POP_TOP POP_TOP
suite_stmts c_suite_stmts
POP_TOP POP_BLOCK
async_with_post
async_with_stmt ::= expr
async_with_pre
POP_TOP
suite_stmts
POP_BLOCK POP_BLOCK
BEGIN_FINALLY BEGIN_FINALLY
WITH_CLEANUP_START GET_AWAITABLE LOAD_CONST YIELD_FROM WITH_CLEANUP_START GET_AWAITABLE LOAD_CONST YIELD_FROM
@@ -252,15 +298,24 @@ class Python37BaseParser(PythonParser):
COME_FROM_ASYNC_WITH COME_FROM_ASYNC_WITH
WITH_CLEANUP_START GET_AWAITABLE LOAD_CONST YIELD_FROM WITH_CLEANUP_START GET_AWAITABLE LOAD_CONST YIELD_FROM
WITH_CLEANUP_FINISH END_FINALLY WITH_CLEANUP_FINISH END_FINALLY
async_with_as_stmt ::= expr async_with_as_stmt ::= expr
async_with_pre async_with_pre
store suite_stmts store suite_stmts
POP_TOP POP_BLOCK POP_TOP POP_BLOCK
async_with_post async_with_post
async_with_as_stmt ::= expr c_async_with_as_stmt ::= expr
async_with_pre async_with_pre
store suite_stmts store suite_stmts
POP_BLOCK async_with_post POP_TOP POP_BLOCK
async_with_post
async_with_as_stmt ::= expr
async_with_pre
store suite_stmts
POP_BLOCK async_with_post
c_async_with_as_stmt ::= expr
async_with_pre
store suite_stmts
POP_BLOCK async_with_post
""" """
self.addRule(rules_str, nop_func) self.addRule(rules_str, nop_func)
@@ -539,7 +594,7 @@ class Python37BaseParser(PythonParser):
stmt ::= genexpr_func_async stmt ::= genexpr_func_async
func_async_prefix ::= SETUP_EXCEPT GET_ANEXT LOAD_CONST YIELD_FROM func_async_prefix ::= _come_froms SETUP_EXCEPT GET_ANEXT LOAD_CONST YIELD_FROM
func_async_middle ::= POP_BLOCK JUMP_FORWARD COME_FROM_EXCEPT func_async_middle ::= POP_BLOCK JUMP_FORWARD COME_FROM_EXCEPT
DUP_TOP LOAD_GLOBAL COMPARE_OP POP_JUMP_IF_TRUE DUP_TOP LOAD_GLOBAL COMPARE_OP POP_JUMP_IF_TRUE
END_FINALLY COME_FROM END_FINALLY COME_FROM
@@ -548,22 +603,24 @@ class Python37BaseParser(PythonParser):
JUMP_BACK COME_FROM JUMP_BACK COME_FROM
POP_TOP POP_TOP POP_TOP POP_EXCEPT POP_TOP POP_TOP POP_TOP POP_TOP POP_EXCEPT POP_TOP
expr ::= listcomp_async expr ::= list_comp_async
listcomp_async ::= LOAD_LISTCOMP LOAD_STR MAKE_FUNCTION_0 list_comp_async ::= LOAD_LISTCOMP LOAD_STR MAKE_FUNCTION_0
expr GET_AITER CALL_FUNCTION_1 expr GET_AITER CALL_FUNCTION_1
GET_AWAITABLE LOAD_CONST GET_AWAITABLE LOAD_CONST
YIELD_FROM YIELD_FROM
expr ::= listcomp_async expr ::= list_comp_async
listcomp_async ::= BUILD_LIST_0 LOAD_FAST func_async_prefix list_afor2 ::= func_async_prefix
store func_async_middle list_iter store func_async_middle list_iter
JUMP_BACK COME_FROM JUMP_BACK COME_FROM
POP_TOP POP_TOP POP_TOP POP_EXCEPT POP_TOP POP_TOP POP_TOP POP_TOP POP_EXCEPT POP_TOP
list_comp_async ::= BUILD_LIST_0 LOAD_FAST list_afor2
get_aiter ::= expr GET_AITER
list_afor ::= get_aiter list_afor2
list_iter ::= list_afor
""", """,
nop_func, nop_func,
) )
custom_ops_processed.add(opname)
elif opname == "JUMP_IF_NOT_DEBUG": elif opname == "JUMP_IF_NOT_DEBUG":
v = token.attr v = token.attr
self.addRule( self.addRule(
@@ -937,55 +994,70 @@ class Python37BaseParser(PythonParser):
) )
custom_ops_processed.add(opname) custom_ops_processed.add(opname)
elif opname == "WITH_CLEANUP_START":
rules_str = """
stmt ::= with_null
with_null ::= with_suffix
with_suffix ::= WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY
"""
self.addRule(rules_str, nop_func)
elif opname == "SETUP_WITH": elif opname == "SETUP_WITH":
rules_str = """ rules_str = """
stmt ::= withstmt stmt ::= with
stmt ::= withasstmt stmt ::= withasstmt
withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt COME_FROM_WITH with ::= expr
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY SETUP_WITH POP_TOP
suite_stmts_opt
COME_FROM_WITH
with_suffix
withasstmt ::= expr SETUP_WITH store suite_stmts_opt COME_FROM_WITH withasstmt ::= expr SETUP_WITH store suite_stmts_opt COME_FROM_WITH
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY with_suffix
withstmt ::= expr with ::= expr
SETUP_WITH POP_TOP suite_stmts_opt SETUP_WITH POP_TOP
suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM_WITH POP_BLOCK LOAD_CONST COME_FROM_WITH
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY with_suffix
withasstmt ::= expr withasstmt ::= expr
SETUP_WITH store suite_stmts_opt SETUP_WITH store suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM_WITH POP_BLOCK LOAD_CONST COME_FROM_WITH
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY with_suffix
withstmt ::= expr with ::= expr
SETUP_WITH POP_TOP suite_stmts_opt SETUP_WITH POP_TOP suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM_WITH POP_BLOCK LOAD_CONST COME_FROM_WITH
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY with_suffix
withasstmt ::= expr withasstmt ::= expr
SETUP_WITH store suite_stmts_opt SETUP_WITH store suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM_WITH POP_BLOCK LOAD_CONST COME_FROM_WITH
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY with_suffix
""" """
if self.version < 3.8: if self.version < 3.8:
rules_str += """ rules_str += """
withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK
LOAD_CONST LOAD_CONST
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY with_suffix
""" """
else: else:
rules_str += """ rules_str += """
withstmt ::= expr with ::= expr
SETUP_WITH POP_TOP suite_stmts_opt SETUP_WITH POP_TOP suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM_WITH POP_BLOCK LOAD_CONST COME_FROM_WITH
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY with_suffix
withasstmt ::= expr withasstmt ::= expr
SETUP_WITH store suite_stmts_opt SETUP_WITH store suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM_WITH POP_BLOCK LOAD_CONST COME_FROM_WITH
withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK withasstmt ::= expr
SETUP_WITH store suite_stmts
POP_BLOCK BEGIN_FINALLY COME_FROM_WITH with_suffix
with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK
BEGIN_FINALLY COME_FROM_WITH BEGIN_FINALLY COME_FROM_WITH
WITH_CLEANUP_START WITH_CLEANUP_FINISH with_suffix
END_FINALLY
""" """
self.addRule(rules_str, nop_func) self.addRule(rules_str, nop_func)
@@ -1091,8 +1163,8 @@ class Python37BaseParser(PythonParser):
+ token.kind + token.kind
) )
# Note: semantic actions make use of the fact of wheter "args_pos" # Note: Semantic actions make use of whether or not "args_pos"
# zero or not in creating a template rule. # is zero when creating a template rule.
self.add_unique_rule(rule, token.kind, args_pos, customize) self.add_unique_rule(rule, token.kind, args_pos, customize)
else: else:
token.kind = self.call_fn_name(token) token.kind = self.call_fn_name(token)
@@ -1126,10 +1198,28 @@ class Python37BaseParser(PythonParser):
def reduce_is_invalid(self, rule, ast, tokens, first, last): def reduce_is_invalid(self, rule, ast, tokens, first, last):
lhs = rule[0] lhs = rule[0]
n = len(tokens) n = len(tokens)
last = min(last, n-1) last = min(last, n - 1)
fn = self.reduce_check_table.get(lhs, None) fn = self.reduce_check_table.get(lhs, None)
if fn: try:
return fn(self, lhs, n, rule, ast, tokens, first, last) if fn:
return fn(self, lhs, n, rule, ast, tokens, first, last)
except:
import sys, traceback
print(
("Exception in %s %s\n"
+ "rule: %s\n"
+ "offsets %s .. %s")
% (
fn.__name__,
sys.exc_info()[1],
rule2str(rule),
tokens[first].offset,
tokens[last].offset,
)
)
print(traceback.print_tb(sys.exc_info()[2], -1))
raise ParserError(tokens[last], tokens[last].off2int(), self.debug["rules"])
if lhs in ("aug_assign1", "aug_assign2") and ast[0][0] == "and": if lhs in ("aug_assign1", "aug_assign2") and ast[0][0] == "and":
return True return True

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2017-2019 Rocky Bernstein # Copyright (c) 2017-2020 Rocky Bernstein
# #
# This program is free software: you can redistribute it and/or modify # 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 # it under the terms of the GNU General Public License as published by
@@ -39,14 +39,17 @@ class Python38Parser(Python37Parser):
stmt ::= forelselaststmtl38 stmt ::= forelselaststmtl38
stmt ::= tryfinally38stmt stmt ::= tryfinally38stmt
stmt ::= tryfinally38rstmt stmt ::= tryfinally38rstmt
stmt ::= tryfinally38rstmt2
stmt ::= tryfinally38rstmt3
stmt ::= tryfinally38astmt stmt ::= tryfinally38astmt
stmt ::= try_elsestmtl38 stmt ::= try_elsestmtl38
stmt ::= try_except_ret38 stmt ::= try_except_ret38
stmt ::= try_except38 stmt ::= try_except38
stmt ::= whilestmt38 stmt ::= whilestmt38
stmt ::= whileTruestmt38 stmt ::= whileTruestmt38
stmt ::= call stmt ::= call_stmt
call_stmt ::= call
break ::= POP_BLOCK BREAK_LOOP break ::= POP_BLOCK BREAK_LOOP
break ::= POP_BLOCK POP_TOP BREAK_LOOP break ::= POP_BLOCK POP_TOP BREAK_LOOP
break ::= POP_TOP BREAK_LOOP break ::= POP_TOP BREAK_LOOP
@@ -54,15 +57,12 @@ class Python38Parser(Python37Parser):
# FIXME: this should be restricted to being inside a try block # FIXME: this should be restricted to being inside a try block
stmt ::= except_ret38 stmt ::= except_ret38
stmt ::= except_ret38a
# FIXME: this should be added only when seeing GET_AITER or YIELD_FROM # FIXME: this should be added only when seeing GET_AITER or YIELD_FROM
async_for_stmt38 ::= expr async_for ::= GET_AITER _come_froms
GET_AITER SETUP_FINALLY GET_ANEXT LOAD_CONST YIELD_FROM POP_BLOCK
SETUP_FINALLY async_for_stmt38 ::= expr async_for
GET_ANEXT
LOAD_CONST
YIELD_FROM
POP_BLOCK
store for_block store for_block
COME_FROM_FINALLY COME_FROM_FINALLY
END_ASYNC_FOR END_ASYNC_FOR
@@ -81,7 +81,20 @@ class Python38Parser(Python37Parser):
END_ASYNC_FOR END_ASYNC_FOR
else_suite else_suite
return ::= ret_expr ROT_TWO POP_TOP RETURN_VALUE # Seems to be used to discard values before a return in a "for" loop
discard_top ::= ROT_TWO POP_TOP
discard_tops ::= discard_top+
return ::= ret_expr
discard_tops RETURN_VALUE
return ::= popb_return
return ::= pop_return
return ::= pop_ex_return
except_stmt ::= pop_ex_return
pop_return ::= POP_TOP ret_expr RETURN_VALUE
popb_return ::= ret_expr POP_BLOCK RETURN_VALUE
pop_ex_return ::= ret_expr ROT_FOUR POP_EXCEPT RETURN_VALUE
# 3.8 can push a looping JUMP_BACK into into a JUMP_ from a statement that jumps to it # 3.8 can push a looping JUMP_BACK into into a JUMP_ from a statement that jumps to it
lastl_stmt ::= ifpoplaststmtl lastl_stmt ::= ifpoplaststmtl
@@ -128,8 +141,14 @@ class Python38Parser(Python37Parser):
except_handler38 except_handler38
try_except38 ::= SETUP_FINALLY POP_BLOCK POP_TOP suite_stmts_opt try_except38 ::= SETUP_FINALLY POP_BLOCK POP_TOP suite_stmts_opt
except_handler38a except_handler38a
try_except_ret38 ::= SETUP_FINALLY expr POP_BLOCK
RETURN_VALUE except_ret38a # suite_stmts has a return
try_except38 ::= SETUP_FINALLY POP_BLOCK suite_stmts
except_handler38b
try_except_ret38 ::= SETUP_FINALLY returns except_ret38a
try_except_ret38a ::= SETUP_FINALLY returns except_handler38c
END_FINALLY come_from_opt
# Note: there is a suite_stmts_opt which seems # Note: there is a suite_stmts_opt which seems
# to be bookkeeping which is not expressed in source code # to be bookkeeping which is not expressed in source code
@@ -149,19 +168,42 @@ class Python38Parser(Python37Parser):
tryfinallystmt ::= SETUP_FINALLY suite_stmts_opt POP_BLOCK tryfinallystmt ::= SETUP_FINALLY suite_stmts_opt POP_BLOCK
BEGIN_FINALLY COME_FROM_FINALLY suite_stmts_opt BEGIN_FINALLY COME_FROM_FINALLY suite_stmts_opt
END_FINALLY END_FINALLY
tryfinally38rstmt ::= SETUP_FINALLY POP_BLOCK CALL_FINALLY
lc_setup_finally ::= LOAD_CONST SETUP_FINALLY
call_finally_pt ::= CALL_FINALLY POP_TOP
cf_cf_finally ::= come_from_opt COME_FROM_FINALLY
pop_finally_pt ::= POP_FINALLY POP_TOP
ss_end_finally ::= suite_stmts END_FINALLY
sf_pb_call_returns ::= SETUP_FINALLY POP_BLOCK CALL_FINALLY returns
# FIXME: DRY rules below
tryfinally38rstmt ::= sf_pb_call_returns
cf_cf_finally
ss_end_finally
tryfinally38rstmt ::= sf_pb_call_returns
cf_cf_finally END_FINALLY
suite_stmts
tryfinally38rstmt ::= sf_pb_call_returns
cf_cf_finally POP_FINALLY
ss_end_finally
tryfinally38rstmt ::= sf_bp_call_returns
COME_FROM_FINALLY POP_FINALLY
ss_end_finally
tryfinally38rstmt2 ::= lc_setup_finally POP_BLOCK call_finally_pt
returns returns
COME_FROM_FINALLY END_FINALLY suite_stmts cf_cf_finally pop_finally_pt
tryfinally38rstmt ::= SETUP_FINALLY POP_BLOCK CALL_FINALLY ss_end_finally POP_TOP
returns tryfinally38rstmt3 ::= SETUP_FINALLY expr POP_BLOCK CALL_FINALLY RETURN_VALUE
COME_FROM_FINALLY POP_FINALLY returns COME_FROM COME_FROM_FINALLY
END_FINALLY ss_end_finally
tryfinally38stmt ::= SETUP_FINALLY suite_stmts_opt POP_BLOCK
BEGIN_FINALLY COME_FROM_FINALLY
POP_FINALLY suite_stmts_opt END_FINALLY
tryfinally38stmt ::= SETUP_FINALLY suite_stmts_opt POP_BLOCK tryfinally38stmt ::= SETUP_FINALLY suite_stmts_opt POP_BLOCK
BEGIN_FINALLY COME_FROM_FINALLY BEGIN_FINALLY COME_FROM_FINALLY
POP_FINALLY suite_stmts_opt END_FINALLY POP_FINALLY suite_stmts_opt END_FINALLY
tryfinally38astmt ::= LOAD_CONST SETUP_FINALLY suite_stmts_opt POP_BLOCK tryfinally38astmt ::= LOAD_CONST SETUP_FINALLY suite_stmts_opt POP_BLOCK
BEGIN_FINALLY COME_FROM_FINALLY BEGIN_FINALLY COME_FROM_FINALLY
POP_FINALLY POP_TOP suite_stmts_opt END_FINALLY POP_TOP POP_FINALLY POP_TOP suite_stmts_opt END_FINALLY POP_TOP

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