You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 08:49:51 +08:00
Compare commits
626 Commits
release-py
...
3.6.4
Author | SHA1 | Date | |
---|---|---|---|
|
ebad4e2a9a | ||
|
e342ef89e3 | ||
|
57d59aa481 | ||
|
6545d9a03b | ||
|
8ac35ad8ce | ||
|
8836444be2 | ||
|
339b4c56ee | ||
|
6cbb631aa6 | ||
|
5355cb5404 | ||
|
8495d208fb | ||
|
e1758a8730 | ||
|
c1a825fbbb | ||
|
8f2e408da2 | ||
|
e2504c2421 | ||
|
1d7085e5d2 | ||
|
65707fa0f8 | ||
|
b0931275a2 | ||
|
7c73536b4a | ||
|
946d46a574 | ||
|
2b50cb56d7 | ||
|
6d5fb21363 | ||
|
bd7d74fa5d | ||
|
c93a7a728b | ||
|
26a554c5c7 | ||
|
cb35ad906c | ||
|
278af38df6 | ||
|
7fb50918cd | ||
|
6525ade805 | ||
|
73951840b6 | ||
|
3438e76865 | ||
|
7480af33d9 | ||
|
88b2be70d2 | ||
|
73de86728a | ||
|
f743639bb6 | ||
|
321c7906cd | ||
|
06b281d1d8 | ||
|
a99d8da0b4 | ||
|
73e6409594 | ||
|
e93628d2dd | ||
|
e41cd9be84 | ||
|
9166fb54a1 | ||
|
3120de0c02 | ||
|
68c9de60a5 | ||
|
621bc96e8a | ||
|
6f4ec21ae2 | ||
|
83e27bc427 | ||
|
9aae8f85c7 | ||
|
04f8619cf1 | ||
|
610994277c | ||
|
6fff0fc5a2 | ||
|
e4a196278a | ||
|
6e5666c001 | ||
|
38e2b8a10b | ||
|
5d1bf2dd9b | ||
|
de1e7d423c | ||
|
16a51961c3 | ||
|
0798078d7e | ||
|
db3c687784 | ||
|
0fafb38d35 | ||
|
f426101000 | ||
|
cf505545c0 | ||
|
45c725feae | ||
|
4dc64063d1 | ||
|
cdc5642715 | ||
|
4f4850d9f7 | ||
|
451b18ee57 | ||
|
2d1ea6b02b | ||
|
f279cc2d70 | ||
|
cb1b2a8759 | ||
|
d64158b299 | ||
|
2ea8a2ef7f | ||
|
258fac3201 | ||
|
7c012ebdfc | ||
|
f27b72ab05 | ||
|
be022b3416 | ||
|
41f1d1ec09 | ||
|
89c2805c27 | ||
|
e639a30157 | ||
|
ee2a1f62c6 | ||
|
db46e096b4 | ||
|
ea48944fff | ||
|
31714d3420 | ||
|
6466d30e2e | ||
|
ef61f3a92a | ||
|
fdf4496a2d | ||
|
b548910e57 | ||
|
c5f939e90d | ||
|
6bbafcc8dd | ||
|
7fc4ccf75a | ||
|
dff3611d16 | ||
|
13ca1117ad | ||
|
e80e72e6ab | ||
|
b893a9ae21 | ||
|
24657961d6 | ||
|
71e9b0d96d | ||
|
466b894ed4 | ||
|
1fff81736f | ||
|
49df216c67 | ||
|
118e21b2cd | ||
|
ba47a8d009 | ||
|
33918bd9d2 | ||
|
7721fbd276 | ||
|
b5a5a128b5 | ||
|
64100bd0c9 | ||
|
1c172f3962 | ||
|
382a3b1483 | ||
|
584d663394 | ||
|
a02f490889 | ||
|
d43972313a | ||
|
dac277f1fa | ||
|
a50263518a | ||
|
73fb9f6b96 | ||
|
c772972227 | ||
|
f3228162dd | ||
|
66b3e35a5b | ||
|
58f2e19539 | ||
|
f6f2d8dd05 | ||
|
13b1ec7ad8 | ||
|
c90ff5176c | ||
|
72b053acef | ||
|
09195c09fd | ||
|
10695d882e | ||
|
5c31fdc362 | ||
|
5616f56442 | ||
|
dab7915404 | ||
|
4067a30573 | ||
|
7e91daf043 | ||
|
e76e9b7ab6 | ||
|
1b96402732 | ||
|
0421863cd3 | ||
|
e0f5cb2bd2 | ||
|
28a80a0132 | ||
|
eeb48818f3 | ||
|
0f4b791502 | ||
|
96c9058cc1 | ||
|
5951f974d5 | ||
|
29715bb8bf | ||
|
31481de209 | ||
|
e17d9c806a | ||
|
c1cde68da8 | ||
|
018583069b | ||
|
dcf7ca1061 | ||
|
ed64e7b443 | ||
|
5d64664857 | ||
|
e07f799cdd | ||
|
bc50825460 | ||
|
c6069eb7f8 | ||
|
d2f59189dd | ||
|
03b5fbaeab | ||
|
b91df57a82 | ||
|
412a811ddb | ||
|
73eab178ae | ||
|
f4e6382cc1 | ||
|
67c37f1a03 | ||
|
beac1d3567 | ||
|
e466e826b3 | ||
|
eacc3f5cc7 | ||
|
af7b05922f | ||
|
7a6511307f | ||
|
26a4577cdb | ||
|
7263b6b15f | ||
|
e06f0990f8 | ||
|
b333d7afc2 | ||
|
4510aa932c | ||
|
d9bc5a345b | ||
|
af76218abf | ||
|
273c4bcbf0 | ||
|
7ec1d0e17b | ||
|
027c9a7dc0 | ||
|
6d368d2b30 | ||
|
549c33113b | ||
|
39459168b0 | ||
|
a532aa5b0e | ||
|
bad40eb63f | ||
|
172239f50b | ||
|
e0f0741c8e | ||
|
af1fe8f176 | ||
|
0677ddc8fb | ||
|
3fbe0b90e3 | ||
|
546269271f | ||
|
968f86011b | ||
|
5cdf057a47 | ||
|
3c2dafe74c | ||
|
585dcfb8ce | ||
|
84e9b75e78 | ||
|
5f230fa177 | ||
|
e2cbf5f4bd | ||
|
bb8c5ac5a0 | ||
|
cbd45a93ab | ||
|
0706f18b1d | ||
|
73937ffeb4 | ||
|
a918055a31 | ||
|
ec3a9978fc | ||
|
491f81902d | ||
|
0a63a66f55 | ||
|
b8413d2c23 | ||
|
84fe813f0a | ||
|
7f2f3bd76c | ||
|
c046aa3b9b | ||
|
d575e57e31 | ||
|
02e0377ce1 | ||
|
a5c987d853 | ||
|
cbd8b6d458 | ||
|
54f4806021 | ||
|
de282af05d | ||
|
f56ad56021 | ||
|
d8990c89ae | ||
|
fe9a8c9dfe | ||
|
540fde898d | ||
|
fd35f045b7 | ||
|
4f0e8d8ab4 | ||
|
58d8e29905 | ||
|
b61170657c | ||
|
2f1802873a | ||
|
9f6138ccc0 | ||
|
a4e114f64f | ||
|
52c5d07d95 | ||
|
ac0b0ff7b6 | ||
|
316bf7f0e0 | ||
|
258db3da20 | ||
|
8fda09459c | ||
|
021c5cad2a | ||
|
b84c89e817 | ||
|
aaba4ecb2b | ||
|
aaf8729772 | ||
|
322c0f67bc | ||
|
9c45794144 | ||
|
e6bade66c0 | ||
|
ccb8b81cc0 | ||
|
56ec47f7ad | ||
|
651170db9a | ||
|
9eda8926a3 | ||
|
89e7eaf695 | ||
|
b1101311f0 | ||
|
2949b55163 | ||
|
0ece75f8ae | ||
|
7af6b6bc06 | ||
|
ff92ca8586 | ||
|
061da83863 | ||
|
c3d7ba6dad | ||
|
6cef42f6c7 | ||
|
eba8f04e29 | ||
|
d1bc30e2f1 | ||
|
fd2b551661 | ||
|
505946d747 | ||
|
07f16fa040 | ||
|
5a3aaa9688 | ||
|
69105825bd | ||
|
ef437d191d | ||
|
fedd5e0ba5 | ||
|
7bcebf8656 | ||
|
8b74d8f855 | ||
|
fee02e0aa0 | ||
|
a99a4cead4 | ||
|
d31478f56a | ||
|
788cd8dc80 | ||
|
508331e743 | ||
|
68c82f9d4e | ||
|
e0e4aed591 | ||
|
158b145394 | ||
|
d1d9219d48 | ||
|
778c8d6003 | ||
|
5fc54015e4 | ||
|
14f889561b | ||
|
7dee584a46 | ||
|
7c03cc466d | ||
|
086ceaf176 | ||
|
30d8830957 | ||
|
199fb532bf | ||
|
b0d931b760 | ||
|
6f6ef19e0a | ||
|
7b76d55e55 | ||
|
7d24910b3c | ||
|
a98bc444f7 | ||
|
13d9bcaaa9 | ||
|
24f59546fe | ||
|
d8628e79fb | ||
|
c0a907f436 | ||
|
8afd9cdaf5 | ||
|
c65e5cde70 | ||
|
95bc0f1fbc | ||
|
eb3dac062d | ||
|
65e3e5fe5b | ||
|
8c5873333f | ||
|
9a77dfaf95 | ||
|
14468fe8c9 | ||
|
19cac525ee | ||
|
8e2c290e96 | ||
|
a3beccc874 | ||
|
839eb6fe0b | ||
|
078cca335a | ||
|
63a88b8eea | ||
|
67c047df75 | ||
|
444bab760b | ||
|
2e0c0f8245 | ||
|
3c5ad58e25 | ||
|
962c503133 | ||
|
4f545c5bfa | ||
|
bbfdb814bf | ||
|
d088e7ef11 | ||
|
6646d18c7a | ||
|
716e097654 | ||
|
dba95c5200 | ||
|
d5df411c7a | ||
|
077f192711 | ||
|
498df35a6c | ||
|
7e71ce3260 | ||
|
825add1af7 | ||
|
1a901bde8f | ||
|
732b5165c2 | ||
|
7bd81efe9b | ||
|
c42e16fafe | ||
|
6de57249ed | ||
|
faf6ea9630 | ||
|
566143b515 | ||
|
b2e1edb434 | ||
|
62c249d6b2 | ||
|
db2fdb30fd | ||
|
37301ab49e | ||
|
97e3a7eb02 | ||
|
f98f7372c3 | ||
|
f88df747b8 | ||
|
6be3656ceb | ||
|
8b48f62fc8 | ||
|
868721595d | ||
|
9f270dce4a | ||
|
bffbd0b352 | ||
|
50fbea1a06 | ||
|
ddffc2c078 | ||
|
d9318e9bed | ||
|
c078048fb0 | ||
|
6a82b1045e | ||
|
3ea73cf977 | ||
|
f3bec73840 | ||
|
8f4343ef22 | ||
|
d50834193c | ||
|
fa7ff89a32 | ||
|
28d9e66a53 | ||
|
e39c6c7f0a | ||
|
8470bded59 | ||
|
01b2b46757 | ||
|
aa398423a3 | ||
|
41bcf3387d | ||
|
89e7a0a246 | ||
|
179fcafaba | ||
|
e56a3c86d5 | ||
|
f527fdbdcd | ||
|
d39169dbda | ||
|
996719688a | ||
|
af9f6b05fa | ||
|
39cbddccaf | ||
|
75b3aaa86d | ||
|
e93b70bcce | ||
|
0eaeb82d48 | ||
|
0ae9612c7c | ||
|
09f232700e | ||
|
bfde66c5e1 | ||
|
4773ca4e5b | ||
|
62a3fcc9d5 | ||
|
bc7d7ddf12 | ||
|
41b6e91286 | ||
|
56bf3e3125 | ||
|
805ec7dbfc | ||
|
668141662e | ||
|
cc55fa1de1 | ||
|
6f51f8910c | ||
|
bc614cf3fb | ||
|
05f3dad32c | ||
|
fb3761e4f3 | ||
|
9b2e22cbaf | ||
|
cea2c7e1dc | ||
|
79c38441b5 | ||
|
3e3dd87c3b | ||
|
edbbefb57d | ||
|
6546bbdaf9 | ||
|
825ed3fef9 | ||
|
7d9c4ce8ca | ||
|
fdac1e3c46 | ||
|
daab1e8610 | ||
|
b8f4dca505 | ||
|
99b8a99ffa | ||
|
8c879c02de | ||
|
d11a9ea126 | ||
|
4926474efc | ||
|
eba5226a04 | ||
|
8d0ff367d8 | ||
|
c6ddefcef5 | ||
|
301464d646 | ||
|
d5b52d44e0 | ||
|
322f491c83 | ||
|
2987d6a72b | ||
|
7609165967 | ||
|
655162a05e | ||
|
ca7f483dbb | ||
|
e713169bdf | ||
|
cc856e2b95 | ||
|
d696443eb2 | ||
|
a5e7eb19c6 | ||
|
6659fffc0d | ||
|
1868b566a1 | ||
|
791274c45d | ||
|
4327ee98e6 | ||
|
2717a5e302 | ||
|
77dd3b8d50 | ||
|
2cfc60fbd7 | ||
|
daa424cf0c | ||
|
7b68c9c838 | ||
|
df5df9364c | ||
|
f1496cad4d | ||
|
a3a15414d3 | ||
|
9874553fb4 | ||
|
d21d93fd84 | ||
|
dbf2729f76 | ||
|
047e27c966 | ||
|
6a81a752a7 | ||
|
44f0ba0efb | ||
|
bc8907e752 | ||
|
4e9d8783d1 | ||
|
47c847644e | ||
|
af2ed31871 | ||
|
49de5b5c9d | ||
|
c8252ca9cb | ||
|
0441fbc616 | ||
|
1b4335edf1 | ||
|
2e36551c02 | ||
|
fff6f82dd7 | ||
|
7c8f3cc9ec | ||
|
78a595c8cf | ||
|
cda0154594 | ||
|
d852f23962 | ||
|
065fd13b81 | ||
|
659f37585b | ||
|
bc18fcf7fa | ||
|
144f52da8e | ||
|
9f250b49ee | ||
|
4abdffecb9 | ||
|
1419acf019 | ||
|
bdc24d7f51 | ||
|
07ec8fa1fb | ||
|
04c2240d63 | ||
|
96dcdfd744 | ||
|
82ea77c592 | ||
|
4f0e580438 | ||
|
09cc0d775a | ||
|
2da5a5649f | ||
|
373916f57c | ||
|
1c0c54991e | ||
|
5de5d2357f | ||
|
6d296f11c9 | ||
|
0ae4acff9e | ||
|
40c2f2962c | ||
|
dae195e36e | ||
|
2c503d5a14 | ||
|
eed4c1025b | ||
|
86c1d12e69 | ||
|
61a367b0ae | ||
|
dba6d24361 | ||
|
0b111f1568 | ||
|
c666e2dc3d | ||
|
0a5fcc51d8 | ||
|
ade9f7a182 | ||
|
d41ef3e5dc | ||
|
ebb0342b38 | ||
|
f17ebf42a9 | ||
|
85dcce4ff2 | ||
|
bc9a16eaac | ||
|
d08d183fc8 | ||
|
0b3d6b8add | ||
|
5cb46c2ed3 | ||
|
163e47fb49 | ||
|
0cf32f1b70 | ||
|
f0f9676f52 | ||
|
be610aa6b3 | ||
|
1494bb2049 | ||
|
d62dc3daac | ||
|
5ad51707e3 | ||
|
f28c255804 | ||
|
315965300f | ||
|
9bd85fe5a0 | ||
|
c6e3168c31 | ||
|
7969b19c2b | ||
|
f8bfde4a8e | ||
|
e2b309fa30 | ||
|
1ebfde6927 | ||
|
73619de3f5 | ||
|
600cd0b8ee | ||
|
90a2ed2c9e | ||
|
8728cb6a99 | ||
|
8daedaf063 | ||
|
4a4a20995e | ||
|
c923ce9afe | ||
|
88901c6901 | ||
|
31f7d14eab | ||
|
388d1da970 | ||
|
66294d54f7 | ||
|
55783c2712 | ||
|
fd580f3c60 | ||
|
a781006ff1 | ||
|
0be3d5a530 | ||
|
bc3cd0102b | ||
|
6e6d590268 | ||
|
71bdc8dc6a | ||
|
71735ca7ef | ||
|
9f121ef00c | ||
|
2e01f42f65 | ||
|
3f9a862277 | ||
|
cc531cf90a | ||
|
c7124ad9ca | ||
|
44a4aab0a7 | ||
|
2a52982d52 | ||
|
56e5e8dcef | ||
|
ecab7d7b09 | ||
|
e39a902e56 | ||
|
e2914ed552 | ||
|
f425db33b7 | ||
|
68c5b2338f | ||
|
e55a0410c9 | ||
|
0fe8961418 | ||
|
8cd331a32b | ||
|
4c76931807 | ||
|
7b7f794913 | ||
|
50e46531ce | ||
|
67ef34977f | ||
|
32c7b8f23d | ||
|
2f06d1eeb0 | ||
|
999f1fb0f9 | ||
|
76eef9a149 | ||
|
c8b945fb56 | ||
|
a1e7c16dbe | ||
|
35f14e4357 | ||
|
49d1a50354 | ||
|
0dc19a8fdd | ||
|
f6aa8b2baf | ||
|
887a006849 | ||
|
e26c7407a0 | ||
|
69823af553 | ||
|
e96498eaf0 | ||
|
9d6d6a355d | ||
|
04c53c1086 | ||
|
96866f94a7 | ||
|
d371839c99 | ||
|
24afe072b7 | ||
|
e2d7f01298 | ||
|
b39112b601 | ||
|
20b513fc81 | ||
|
d369017122 | ||
|
6675ea2cd0 | ||
|
4b82806d6c | ||
|
3c06b82931 | ||
|
c680416f92 | ||
|
58c8fe5a66 | ||
|
aea1adeb85 | ||
|
c871a4ecc5 | ||
|
cd9eca7bff | ||
|
002720988c | ||
|
08f23567a6 | ||
|
43348d7d24 | ||
|
164e9d4b5c | ||
|
37e4754268 | ||
|
c3257a9b79 | ||
|
70b0704967 | ||
|
76dcaf9bf0 | ||
|
21fd506fbb | ||
|
efe0914814 | ||
|
5981c7eae9 | ||
|
36ef1607af | ||
|
b2d97f9847 | ||
|
24ba5d7f40 | ||
|
eae3f0d77b | ||
|
a54fba7993 | ||
|
719d2d7232 | ||
|
e82cabc278 | ||
|
9ab086b207 | ||
|
4022e80d6d | ||
|
9811c5bc42 | ||
|
354796fffd | ||
|
ab696b316a | ||
|
2f99da8199 | ||
|
fd5f4fa5b8 | ||
|
8e4168674d | ||
|
c8fc6a704c | ||
|
622d6f849c | ||
|
10d8aed4c0 | ||
|
86fd5dbf7a | ||
|
9fe1752359 | ||
|
48ae7a6964 | ||
|
117b4ff4f1 | ||
|
e9002038f8 | ||
|
9d47b99932 | ||
|
59b012df6f | ||
|
44d7cbcf6f | ||
|
9bae73679f | ||
|
ceebe9ab60 | ||
|
b7e22b4530 | ||
|
c7b20edba0 | ||
|
64e35b09db | ||
|
a0d4daf5ff | ||
|
afa6a00db8 | ||
|
d8f0d31475 | ||
|
dd76a6f253 | ||
|
cb40caa73c | ||
|
fd59879510 | ||
|
c9cae2d09e | ||
|
af209dc142 | ||
|
ad419e0ed9 | ||
|
ee5c7da790 | ||
|
39c12704a8 | ||
|
3b3fc09b60 | ||
|
f7697ccd7b | ||
|
e364499bb9 | ||
|
9db59f1b80 | ||
|
a5cdb50154 | ||
|
792ef5b5b8 | ||
|
47ed0795b2 | ||
|
cccf33573b | ||
|
3c3e5c82fc | ||
|
436260dc9a | ||
|
8f0674706b | ||
|
01cc184716 | ||
|
2771cb46ab | ||
|
9ed4326f7e | ||
|
e3b10b62d7 | ||
|
59b8f18486 | ||
|
bcf6939312 | ||
|
3b7f49c01d | ||
|
ae976e991a |
@@ -1,11 +1,3 @@
|
|||||||
# This configuration was automatically generated from a CircleCI 1.0 config.
|
|
||||||
# It should include any build commands you had along with commands that CircleCI
|
|
||||||
# inferred from your project structure. We strongly recommend you read all the
|
|
||||||
# comments in this file to understand the structure of CircleCI 2.0, as the idiom
|
|
||||||
# for configuration has changed substantially in 2.0 to allow arbitrary jobs rather
|
|
||||||
# than the prescribed lifecycle of 1.0. In general, we recommend using this generated
|
|
||||||
# configuration as a reference rather than using it in production, though in most
|
|
||||||
# cases it should duplicate the execution of your original 1.0 config.
|
|
||||||
version: 2
|
version: 2
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
@@ -18,18 +10,10 @@ jobs:
|
|||||||
CIRCLE_ARTIFACTS: /tmp/circleci-artifacts
|
CIRCLE_ARTIFACTS: /tmp/circleci-artifacts
|
||||||
CIRCLE_TEST_REPORTS: /tmp/circleci-test-results
|
CIRCLE_TEST_REPORTS: /tmp/circleci-test-results
|
||||||
COMPILE: --compile
|
COMPILE: --compile
|
||||||
# In CircleCI 1.0 we used a pre-configured image with a large number of languages and other packages.
|
|
||||||
# In CircleCI 2.0 you can now specify your own image, or use one of our pre-configured images.
|
|
||||||
# The following configuration line tells CircleCI to use the specified docker image as the runtime environment for you job.
|
|
||||||
# We have selected a pre-built image that mirrors the build environment we use on
|
|
||||||
# the 1.0 platform, but we recommend you choose an image more tailored to the needs
|
|
||||||
# of each job. For more information on choosing an image (or alternatively using a
|
|
||||||
# VM instead of a container) see https://circleci.com/docs/2.0/executor-types/
|
|
||||||
# To see the list of pre-built images that CircleCI provides for most common languages see
|
# To see the list of pre-built images that CircleCI provides for most common languages see
|
||||||
# https://circleci.com/docs/2.0/circleci-images/
|
# https://circleci.com/docs/2.0/circleci-images/
|
||||||
docker:
|
docker:
|
||||||
- image: circleci/build-image:ubuntu-14.04-XXL-upstart-1189-5614f37
|
- image: circleci/python:3.6.9
|
||||||
command: /sbin/init
|
|
||||||
steps:
|
steps:
|
||||||
# Machine Setup
|
# Machine Setup
|
||||||
# If you break your build into multiple jobs with workflows, you will probably want to do the parts of this that are relevant in each
|
# If you break your build into multiple jobs with workflows, you will probably want to do the parts of this that are relevant in each
|
||||||
@@ -42,25 +26,24 @@ jobs:
|
|||||||
# This is based on your 1.0 configuration file or project settings
|
# This is based on your 1.0 configuration file or project settings
|
||||||
- run:
|
- run:
|
||||||
working_directory: ~/rocky/python-uncompyle6
|
working_directory: ~/rocky/python-uncompyle6
|
||||||
command: pyenv local 2.7.11 && pyenv rehash && pip install virtualenv && pip install nose && pip install pep8 && pip install six && pyenv rehash
|
command: pip install --user virtualenv && pip install --user nose && pip install --user pep8
|
||||||
# Dependencies
|
# Dependencies
|
||||||
# This would typically go in either a build or a build-and-test job when using workflows
|
# This would typically go in either a build or a build-and-test job when using workflows
|
||||||
# Restore the dependency cache
|
# Restore the dependency cache
|
||||||
- restore_cache:
|
- restore_cache:
|
||||||
keys:
|
keys:
|
||||||
# This branch if available
|
- v2-dependencies-{{ .Branch }}-
|
||||||
- v1-dep-{{ .Branch }}-
|
# fallback to using the latest cache if no exact match is found
|
||||||
# Default branch if not
|
- v2-dependencies-
|
||||||
- v1-dep-master-
|
|
||||||
# Any branch if there are none on the default branch - this should be unnecessary if you have your default branch configured correctly
|
|
||||||
- v1-dep-
|
|
||||||
# This is based on your 1.0 configuration file or project settings
|
# This is based on your 1.0 configuration file or project settings
|
||||||
- run: pip install --upgrade setuptools
|
- run: pip install --user --upgrade setuptools
|
||||||
- run: pip install -e .
|
- run: pip install --user -e .
|
||||||
- run: pip install pytest==3.2.5 hypothesis==3.0.0
|
- run: pip install --user -r requirements-dev.txt
|
||||||
|
|
||||||
# Save dependency cache
|
# Save dependency cache
|
||||||
- save_cache:
|
- save_cache:
|
||||||
key: v1-dep-{{ .Branch }}-{{ epoch }}
|
key: v2-dependencies-{{ .Branch }}-{{ epoch }}
|
||||||
paths:
|
paths:
|
||||||
# This is a broad list of cache paths to include many possible development environments
|
# This is a broad list of cache paths to include many possible development environments
|
||||||
# You can probably delete some of these entries
|
# You can probably delete some of these entries
|
||||||
@@ -69,14 +52,13 @@ jobs:
|
|||||||
- ~/.m2
|
- ~/.m2
|
||||||
- ~/.ivy2
|
- ~/.ivy2
|
||||||
- ~/.bundle
|
- ~/.bundle
|
||||||
- ~/.go_workspace
|
|
||||||
- ~/.gradle
|
|
||||||
- ~/.cache/bower
|
- ~/.cache/bower
|
||||||
|
|
||||||
# Test
|
# Test
|
||||||
# This would typically be a build job when using workflows, possibly combined with build
|
# This would typically be a build job when using workflows, possibly combined with build
|
||||||
# This is based on your 1.0 configuration file or project settings
|
# This is based on your 1.0 configuration file or project settings
|
||||||
- run: python ./setup.py develop && make check-2.7
|
- run: sudo python ./setup.py develop && make check-3.6
|
||||||
- run: cd ./test/stdlib && pyenv local 2.7.11 && bash ./runtests.sh 'test_[p-z]*.py'
|
- run: cd ./test/stdlib && bash ./runtests.sh 'test_[p-z]*.py'
|
||||||
# Teardown
|
# Teardown
|
||||||
# If you break your build into multiple jobs with workflows, you will probably want to do the parts of this that are relevant in each
|
# If you break your build into multiple jobs with workflows, you will probably want to do the parts of this that are relevant in each
|
||||||
# Save test results
|
# Save test results
|
||||||
|
6
.github/ISSUE_TEMPLATE/bug-report.md
vendored
6
.github/ISSUE_TEMPLATE/bug-report.md
vendored
@@ -11,7 +11,7 @@ Please remove any of the optional sections if they are not applicable.
|
|||||||
Prerequisites
|
Prerequisites
|
||||||
|
|
||||||
* Make sure the bytecode you have can be disassembled with a
|
* Make sure the bytecode you have can be disassembled with a
|
||||||
disassembler.
|
disassembler and produces valid results.
|
||||||
* Don't put bytecode and corresponding source code on any service that
|
* Don't put bytecode and corresponding source code on any service that
|
||||||
requires registration to download.
|
requires registration to download.
|
||||||
* When you open a bug report there is no privacy. If the legitimacy of
|
* When you open a bug report there is no privacy. If the legitimacy of
|
||||||
@@ -35,7 +35,7 @@ decompiler service for versions of Python up to 2.6.
|
|||||||
|
|
||||||
## How to Reproduce
|
## How to Reproduce
|
||||||
|
|
||||||
<!-- Please show both the input you gave and the
|
<!-- Please show both the *input* you gave and the
|
||||||
output you got in describing how to reproduce the bug:
|
output you got in describing how to reproduce the bug:
|
||||||
|
|
||||||
or give a complete console log with input and output
|
or give a complete console log with input and output
|
||||||
@@ -63,7 +63,7 @@ can add that too.
|
|||||||
Please modify for your setup
|
Please modify for your setup
|
||||||
|
|
||||||
- Uncompyle6 version: output from `uncompyle6 --version` or `pip show uncompyle6`
|
- Uncompyle6 version: output from `uncompyle6 --version` or `pip show uncompyle6`
|
||||||
- Python version: `python -V`
|
- Python version for the version of Python the byte-compiled the file: `python -c "import sys; print(sys.version)"` where `python` is the correct Cpython or Pypy binary.
|
||||||
- OS and Version: [e.g. Ubuntu bionic]
|
- OS and Version: [e.g. Ubuntu bionic]
|
||||||
|
|
||||||
-->
|
-->
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -6,6 +6,7 @@
|
|||||||
/.eggs
|
/.eggs
|
||||||
/.hypothesis
|
/.hypothesis
|
||||||
/.idea
|
/.idea
|
||||||
|
/.mypy_cache
|
||||||
/.pytest_cache
|
/.pytest_cache
|
||||||
/.python-version
|
/.python-version
|
||||||
/.tox
|
/.tox
|
||||||
|
@@ -3,9 +3,9 @@ language: python
|
|||||||
python:
|
python:
|
||||||
- '3.5'
|
- '3.5'
|
||||||
- '2.7'
|
- '2.7'
|
||||||
- '2.6'
|
|
||||||
- '3.4'
|
- '3.4'
|
||||||
- '3.6'
|
- '3.6'
|
||||||
|
- '3.8'
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
|
8
Makefile
8
Makefile
@@ -47,8 +47,12 @@ check-3.8:
|
|||||||
# Skip for now
|
# Skip for now
|
||||||
2.6 5.0 5.3 5.6 5.8:
|
2.6 5.0 5.3 5.6 5.8:
|
||||||
|
|
||||||
#:PyPy pypy3-2.4.0 Python 3:
|
#:PyPy pypy3-2.4.0 Python 3.6.1:
|
||||||
pypy-3.2 2.4:
|
7.1 pypy-3.2 2.4:
|
||||||
|
$(MAKE) -C test $@
|
||||||
|
|
||||||
|
#:PyPy pypy3-2.4.0 Python 3.6.9:
|
||||||
|
7.2:
|
||||||
$(MAKE) -C test $@
|
$(MAKE) -C test $@
|
||||||
|
|
||||||
#: Run py.test tests
|
#: Run py.test tests
|
||||||
|
423
NEWS.md
423
NEWS.md
@@ -1,21 +1,267 @@
|
|||||||
|
3.6.4: 2020-2-9 Plateau
|
||||||
|
=======================
|
||||||
|
|
||||||
|
The main focus in this release was fix some of the more glaring problems creapt in from the last release due to that refactor.
|
||||||
|
|
||||||
|
`uncompyle6` code is at a plateau where what is most needed is a code refactoring. In doing this, until everything refactored and replaced, decomplation may get worse.
|
||||||
|
Therefore, this release largely serves as a checkpoint before more major upheaval.
|
||||||
|
|
||||||
|
The upheaval, in started last release, I believe the pinnicle was around c90ff51 which wasn't a release. I suppose I should tag that.
|
||||||
|
|
||||||
|
After c90ff5, I started down the road of redoing control flow in a more comprehensible, debuggable, and scalable way. See [The Control Flow Mess](https://github.com/rocky/python-uncompyle6/wiki/The-Control-Flow-Mess)
|
||||||
|
|
||||||
|
The bulk of the refactoring going on in the [decompyle3](https://github.com/rocky/python-decompil3) project, but I try to trickle down the changes.
|
||||||
|
|
||||||
|
It is tricky because the changes are large and I have to figure decompose things so that little testable pieces can be done. And there is also the problem that what is in decompyle3 is incomplete as well.
|
||||||
|
|
||||||
|
Other than control flow, another change that will probably happen in the next release is to redo the grammar for lambda expressions. Right now, we treat them as Python statements, you know, things with compound statements in them. But lambda aren't that. And so there is hackery to paper over difference making a statement out of an expression the wrong thing to do. For example, a return of an "and" expression can be expressed as nested "if" statements with return inside them, but the "if" variant of the bytecode is not valid in a lambda.
|
||||||
|
|
||||||
|
In the decompyle3 code, I've gone down the road making the grammar goal symbol be an expression. This also offers the opportunity to split the grammar making parsing inside lambda not only more reliable because the wrong choices don't exist, but also simpler and faster because all those rules just need don't need to exist in parsing.
|
||||||
|
|
||||||
|
I cringe in thinking about how the code has lived for so long without noticing such a simple stupidity, and lapse of sufficient thought.
|
||||||
|
|
||||||
|
Some stats from testing. The below give numbers of decompiled tests from Python's test suite which succesfully ran
|
||||||
|
|
||||||
|
```
|
||||||
|
Version test-suites passing
|
||||||
|
------- -------------------
|
||||||
|
2.4.6 243
|
||||||
|
2.5.6 265
|
||||||
|
2.6.9 305
|
||||||
|
3.3.7 300
|
||||||
|
3.4.10 304
|
||||||
|
3.5.9 260
|
||||||
|
3.6.10 236
|
||||||
|
3.7.6 306
|
||||||
|
3.8.1 114
|
||||||
|
```
|
||||||
|
|
||||||
|
Decompiled bytecode files distributed with Python (syntax check only):
|
||||||
|
|
||||||
|
```
|
||||||
|
2.7.17 647 files: 0 failed
|
||||||
|
3.2.6 900 files: 0 failed
|
||||||
|
3.3.7 1256 files: 0 failed
|
||||||
|
3.4.10 800 files: 0 failed
|
||||||
|
3.5.9 900 files: 0 failed
|
||||||
|
3.6.10 1300 files: 28 failed
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
3.6.3: 2020-1-26 Martin and Susanne
|
||||||
|
===================================
|
||||||
|
|
||||||
|
Of late, every release fixes major gaps and embarrassments of the last release....
|
||||||
|
|
||||||
|
And in some cases, like this one, exposes lacuna and rot.
|
||||||
|
|
||||||
|
I now have [control] flow under control, even if it isn't the most optimal way.
|
||||||
|
|
||||||
|
I now have greatly expanded automated testing.
|
||||||
|
|
||||||
|
On the most recent Python versions I regularly decompile thousands of Python programs that are distributed with Python. when it is possible, I then decompile Python's standard test suite distributed with Python and run the decompiled source code which basically checks itself. This amounts to about 250 test programs per version. This is in addition to the 3 CI testing services which do different things.
|
||||||
|
|
||||||
|
Does this mean the decompiler works perfectly? No. There are still a dozen or so failing programs, although the actual number of bugs is probably smaller though.
|
||||||
|
|
||||||
|
However, in perparation of a more major refactoring of the parser grammar, this release was born.
|
||||||
|
|
||||||
|
In many cases, decompilation is better. But there are some cases where decompilation has gotten worse. For lack of time (and interest) 3.0 bytecode suffered a hit. Possibly some code in the 3.x range did too. In time and with cleaner refactored code, this will come back.
|
||||||
|
|
||||||
|
Commit c90ff51 was a local maxiumum before, I started reworking the grammar to separate productions that were specific to loops versus those that are not in loops.
|
||||||
|
In the middle of that I added another grammar simplication to remove singleton productions of the form `sstmts-> stmts`. These were always was a bit ugly, and complicated output.
|
||||||
|
|
||||||
|
At any rate if decompilation fails, you can try c90ff51. Or another decompiler. `unpyc37` is pretty good for 3.7. wibiti `uncompyle2` is great for 2.7. `pycdc` is mediocre for Python before 3.5 or so, and not that good for the most recent Python. Geerally these programs will give some sort of answer even if it isn't correct.
|
||||||
|
|
||||||
|
decompyle3 isn't that good for 3.7 and worse for 3.8, but right now it does things no other Python decompiler like `unpyc37` or `pycdc` does. For example, `decompyle3` handles variable annotations. As always, the issue trackers for the various programs will give you a sense for what needs to be done. For now, I've given up on reporting issues in the other decompilers because there are already enough issues reported, and they are just not getting fixed anyway.
|
||||||
|
|
||||||
|
|
||||||
|
3.6.2: 2020-1-5 Samish
|
||||||
|
======================
|
||||||
|
|
||||||
|
Yet again the focus has been on just fixing bugs, mostly geared in the
|
||||||
|
later 3.x range. To get some sense what sill needs fixing, consult
|
||||||
|
test/stdlib/runtests.sh. And that only has a portion of what's known.
|
||||||
|
|
||||||
|
`make_function.py` has gotten so complex that it was split out into 3 parts
|
||||||
|
to handle different version ranges: Python <3, Python 3.0..3.6 and Python 3.7+.
|
||||||
|
|
||||||
|
An important fix is that we had been dropping docstrings in Python 3 code as a result
|
||||||
|
of a incomplete merge from the decompile3 base with respect to the transform phase.
|
||||||
|
|
||||||
|
Also important (at least to me) is that we can now handle 3.6+
|
||||||
|
variable type annotations. Some of the decompile3 code uses that in
|
||||||
|
its source code, and I now use variable annotations in conjunction
|
||||||
|
with mypy in some of my other Python projects
|
||||||
|
|
||||||
|
Code generation for imports, especially where the import is dotted
|
||||||
|
changed a bit in 3.7; with this release are just now tracking that
|
||||||
|
change better. For this I've added pseudo instruction
|
||||||
|
`IMPORT_NAME_ATTR`, derived from the `IMPORT_NAME` instruction, to
|
||||||
|
indicate when an import contains a dotted import. Similarly, code for
|
||||||
|
3.7 `import .. as ` is basically the same as `from .. import`, the
|
||||||
|
only difference is the target of the name changes to an "alias" in the
|
||||||
|
former. As a result, the disambiguation is now done on the semantic
|
||||||
|
action side, rathero than in parsing grammar rules.
|
||||||
|
|
||||||
|
Some small specific fixes:
|
||||||
|
|
||||||
|
* 3.7+ some chained compare parsing has been fixed. Other remain.
|
||||||
|
* better if/else rule checking in the 3.4 and below range.
|
||||||
|
* 3.4+ keyword-only parameter handling was fixed more generally
|
||||||
|
* 3.3 .. 3.5 keyword-only parameter args in lambda was fixed
|
||||||
|
|
||||||
|
|
||||||
|
3.6.1: 2019-12-10 Christmas Hannukah
|
||||||
|
====================================
|
||||||
|
|
||||||
|
Overall, as in the past, the focus has been on just fixing bugs, more geared
|
||||||
|
in the later 3.x range. Handling "async for/with" in 3.8+ works better.
|
||||||
|
|
||||||
|
Numerous bugs around handling `lambda` with keyword-only and `*` args in the
|
||||||
|
3.0-3.8 have been fixed. However many still remain.
|
||||||
|
|
||||||
|
`binary_expr` and `unary_expr` have been renamed to `bin_op` and
|
||||||
|
`unary_op` to better correspond the Python AST names.
|
||||||
|
|
||||||
|
Some work was done Python 3.7+ to handle `and` better; less was done
|
||||||
|
along the lines of handling `or`. Much more is needed to improve
|
||||||
|
parsing stability of 3.7+. More of what was done with `and` needs to
|
||||||
|
be done with `or` and this will happen first in the "decompyle3"
|
||||||
|
project.
|
||||||
|
|
||||||
|
Later this will probably be extended backwards to handle the 3.6-
|
||||||
|
versions better. This however comes with a big decompilation speed
|
||||||
|
penalty. When we redo control flow this should go back to normal, but
|
||||||
|
for now, accuracy is more important than speed.
|
||||||
|
|
||||||
|
Another `assert` transform rule was added. Parser rules to distingish
|
||||||
|
`try/finally` in 3.8 were added and we are more stringent about what
|
||||||
|
can be turned into an `assert`. There was some grammar cleanup here
|
||||||
|
too.
|
||||||
|
|
||||||
|
A number of small bugs were fixed, and some administrative changes to
|
||||||
|
make `make check-short` really be short, but check more throughly what
|
||||||
|
it checks. minimum xdis version needed was bumped to include in the
|
||||||
|
newer 3.6-3.9 releases. See the `ChangeLog` for details.
|
||||||
|
|
||||||
|
|
||||||
|
3.6.0: 2019-12-10 gecko gecko
|
||||||
|
=============================
|
||||||
|
|
||||||
|
The main focus in this release was more accurate decompilation especially
|
||||||
|
for 3.7 and 3.8. However there are some improvments to Python 2.x as well,
|
||||||
|
including one of the long-standing problems of detecting the difference between
|
||||||
|
`try ... ` and `try else ...`.
|
||||||
|
|
||||||
|
With this release we now rebase Python 3.7 on off of a 3.7 base; This
|
||||||
|
is also as it is (now) in decompyle3. This facilitates removing some of the
|
||||||
|
cruft in control-flow detection in the 2.7 uncompyle2 base.
|
||||||
|
|
||||||
|
Alas, decompilation speed for 3.7 on is greatly increased. Hopefull
|
||||||
|
this is temporary (cough, cough) until we can do a static control flow
|
||||||
|
pass.
|
||||||
|
|
||||||
|
Finally, runing in 3.9-dev is tolerated. We can disassemble, but no parse tables yet.
|
||||||
|
|
||||||
|
|
||||||
|
3.5.1 2019-11-17 JNC
|
||||||
|
====================
|
||||||
|
|
||||||
|
- Pypy 3.3, 3.5, 3.6, and 3.6.9 support
|
||||||
|
- bump xdis version to handle newer Python releases, e.g. 2.7.17, 3.5.8, and 3.5.9
|
||||||
|
- Improve 3.0 decompilation
|
||||||
|
- no parse errors on stlib bytecode. However accurate translation in
|
||||||
|
control-flow and and/or detection needs work
|
||||||
|
- Remove extraneous iter() in "for" of list comprehension Fixes #272
|
||||||
|
- "for" block without a `POP_BLOCK `and confusing `JUMP_BACK` for `CONTINUE`. Fixes #293
|
||||||
|
- Fix unmarshal incompletness detected in Pypy 3.6
|
||||||
|
- Miscellaneous bugs fixed
|
||||||
|
|
||||||
|
3.5.0 2019-10-12 Stony Brook Ride
|
||||||
|
=================================
|
||||||
|
|
||||||
|
- Fix fragment bugs
|
||||||
|
* missing `RETURN_LAST` introduced when adding transformation layer
|
||||||
|
* more parent entries on tokens
|
||||||
|
- Preliminary support for decompiling Python 1.0, 1.1, 1.2, and 1.6
|
||||||
|
* Newer _xdis_ version needed
|
||||||
|
|
||||||
|
3.4.1 2019-10-02
|
||||||
|
================
|
||||||
|
|
||||||
|
- Correct assert{,2} transforms Fixes #289
|
||||||
|
- Fragment parsing fixes:
|
||||||
|
* Wasn't handling 3-arg `%p`
|
||||||
|
* fielding error in `code_deparse()`
|
||||||
|
- Use newer _xdis_ to better track Python 3.8.0
|
||||||
|
|
||||||
|
|
||||||
|
3.4.0 2019-08-24 Totoro
|
||||||
|
=======================
|
||||||
|
|
||||||
|
The main change is to add a tree-transformation phase. This simplifies the
|
||||||
|
code a little and allows us to turn `if ...: raise AssertionError` into
|
||||||
|
`assert`, and many `if ..: else if ...` into `if ... elif ..`
|
||||||
|
|
||||||
|
Use options `--show=before` and `--show=after` to see the before the tree transformation phase and after the tree transformation phase.
|
||||||
|
|
||||||
|
Most of the heavy lifting for this was done by x0ret.
|
||||||
|
|
||||||
|
Other changes:
|
||||||
|
|
||||||
|
- Fix issue #275, #283 (process to fix this bug is documented on wiki), #284
|
||||||
|
- blacken more code
|
||||||
|
- CircleCI adjustments for a changing CircleCi
|
||||||
|
- Require more recent `xdis` for Python 3.8
|
||||||
|
- Fix bugs in code using `BUILD_LIST_UNPACK` and variants
|
||||||
|
|
||||||
|
3.3.5 2019-07-03 Pre Independence Day
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Again, most of the work in this is release is thanks to x0ret.
|
||||||
|
|
||||||
|
- Handle annotation arguments in Python 3.x
|
||||||
|
- Fix _vararg_ and function signatures in 3.x
|
||||||
|
- Some 3.x < 3.6 `while` (1)/`if` fixes — others remain
|
||||||
|
- Start reinstating `else if` -> `elif`
|
||||||
|
- `LOAD_CONST` -> `LOAD_CODE` where appropriate
|
||||||
|
- option `--weak-verify` is now `--syntax-verify`
|
||||||
|
- code cleanups, start using [black](https://github.com/python/black) to reformat text
|
||||||
|
|
||||||
|
|
||||||
|
3.3.4 2019-06-19 Fleetwood at 65
|
||||||
|
================================
|
||||||
|
|
||||||
|
Most of the work in this is release is thanks to x0ret.
|
||||||
|
|
||||||
|
- Major work was done by x0ret to correct function signatures and include annotation types
|
||||||
|
- Handle Python 3.6 `STORE_ANNOTATION` [#58](https://github.com/rocky/python-uncompyle6/issues/58)
|
||||||
|
- Friendlier assembly output
|
||||||
|
- `LOAD_CONST` replaced by `LOAD_STR` where appropriate to simplify parsing and improve clarity
|
||||||
|
- remove unneeded parenthesis in a generator expression when it is the single argument to the function [#247](https://github.com/rocky/python-uncompyle6/issues/246)
|
||||||
|
- Bug in noting an async function [#246](https://github.com/rocky/python-uncompyle6/issues/246)
|
||||||
|
- Handle Unicode docstrings and fix docstring bugs [#241](https://github.com/rocky/python-uncompyle6/issues/241)
|
||||||
|
- Add short option -T as an alternate for --tree+
|
||||||
|
- Some grammar cleanup
|
||||||
|
|
||||||
3.3.3 2019-05-19 Henry and Lewis
|
3.3.3 2019-05-19 Henry and Lewis
|
||||||
================================
|
================================
|
||||||
|
|
||||||
As before, decomplation bugs fixed. The focus has primarily been on
|
As before, decomplation bugs fixed. The focus has primarily been on
|
||||||
Python 3.7. But with this release, releases will be put on hold,as a
|
Python 3.7. But with this release, releases will be put on hold,as a
|
||||||
better control-flow detection is worked on . Tis has been needed for a
|
better control-flow detection is worked on . This has been needed for a
|
||||||
while, and is long overdue. It will probably also take a while to get
|
while, and is long overdue. It will probably also take a while to get
|
||||||
done as good as what we have now.
|
done as good as what we have now.
|
||||||
|
|
||||||
However this work will be done in a new project
|
However this work will be done in a new project
|
||||||
[decompyle3](https://github.com/rocky/python-decompile3). In contrast
|
[decompyle3](https://github.com/rocky/python-decompile3). In contrast
|
||||||
to _uncompyle6_ the code wil be written assuming a modern Python 3,
|
to _uncompyle6_ the code will be written assuming a modern Python 3,
|
||||||
e.g. 3.7. It is originally intended to decompile Python version 3.7
|
e.g. 3.7. It is originally intended to decompile Python version 3.7
|
||||||
and greater.
|
and greater.
|
||||||
|
|
||||||
* A number of Python 3.7+ chained comparisons were fixed
|
* A number of Python 3.7+ chained comparisons were fixed
|
||||||
* Revise Python 3.6ish format string handling
|
* Revise Python 3.6ish format string handling
|
||||||
* Go over operator precedence, e.g. for AST IfExp
|
* Go over operator precedence, e.g. for AST `IfExp`
|
||||||
|
|
||||||
Reported Bug Fixes
|
Reported Bug Fixes
|
||||||
------------------
|
------------------
|
||||||
@@ -38,7 +284,7 @@ some span back as far as 2.x
|
|||||||
But as before, many more remain in the 3.7 and 3.8 range which will
|
But as before, many more remain in the 3.7 and 3.8 range which will
|
||||||
get addressed in future releases
|
get addressed in future releases
|
||||||
|
|
||||||
Pypy 3.6 support was started. Pypy 3.x detection fixed (via xdis)
|
Pypy 3.6 support was started. Pypy 3.x detection fixed (via `xdis`)
|
||||||
|
|
||||||
3.3.1 2019-04-19 Good Friday
|
3.3.1 2019-04-19 Good Friday
|
||||||
==========================
|
==========================
|
||||||
@@ -47,7 +293,7 @@ Lots of decomplation bugs, especially in the 3.x series fixed. Don't worry thoug
|
|||||||
|
|
||||||
* Add annotation return values in 3.6+
|
* Add annotation return values in 3.6+
|
||||||
* Fix 3.6+ lambda parameter handling decompilation
|
* Fix 3.6+ lambda parameter handling decompilation
|
||||||
* Fix 3.7+ chained comparision decompilation
|
* Fix 3.7+ chained comparison decompilation
|
||||||
* split out semantic-action customization into more separate files
|
* split out semantic-action customization into more separate files
|
||||||
* Add 3.8 try/else
|
* Add 3.8 try/else
|
||||||
* Fix 2.7 generator decompilation
|
* Fix 2.7 generator decompilation
|
||||||
@@ -57,8 +303,7 @@ Lots of decomplation bugs, especially in the 3.x series fixed. Don't worry thoug
|
|||||||
3.3.0 2019-04-14 Holy Week
|
3.3.0 2019-04-14 Holy Week
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
* First cut at Python 3.8 (many bugs remain)
|
* First cut at Python 3.8 (many bug remain)
|
||||||
* Reinstate -c | --compile (compile before disassembly) option
|
|
||||||
* The usual smattering of bug and doc fixes
|
* The usual smattering of bug and doc fixes
|
||||||
|
|
||||||
3.2.6 2019-03-23 Mueller Report
|
3.2.6 2019-03-23 Mueller Report
|
||||||
@@ -80,14 +325,14 @@ Bug Fixes
|
|||||||
Pull Requests
|
Pull Requests
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
* [#202: Better "assert" statement detemination in Python 2.7](https://github.com/rocky/python-uncompyle6/pull/211)
|
* [#202: Better "assert" statement determination in Python 2.7](https://github.com/rocky/python-uncompyle6/pull/211)
|
||||||
* [#204: Python 3.7 testing](https://github.com/rocky/python-uncompyle6/pull/204)
|
* [#204: Python 3.7 testing](https://github.com/rocky/python-uncompyle6/pull/204)
|
||||||
* [#205: Run more f-string tests on Python 3.7](https://github.com/rocky/python-uncompyle6/pull/205)
|
* [#205: Run more f-string tests on Python 3.7](https://github.com/rocky/python-uncompyle6/pull/205)
|
||||||
* [#211: support utf-8 chars in Python 3 sourcecode](https://github.com/rocky/python-uncompyle6/pull/202)
|
* [#211: support utf-8 chars in Python 3 sourcecode](https://github.com/rocky/python-uncompyle6/pull/202)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
3.2.5 2018-12-30 Clearout sale
|
3.2.5 2018-12-30 Clear-out sale
|
||||||
======================================
|
======================================
|
||||||
|
|
||||||
- 3.7.2 Remove deprecation warning on regexp string that isn't raw
|
- 3.7.2 Remove deprecation warning on regexp string that isn't raw
|
||||||
@@ -122,7 +367,7 @@ Pull Requests
|
|||||||
|
|
||||||
- Add rudimentary 1.4 support (still a bit buggy)
|
- Add rudimentary 1.4 support (still a bit buggy)
|
||||||
- add --tree+ option to show formatting rule, when it is constant
|
- add --tree+ option to show formatting rule, when it is constant
|
||||||
- Python 2.7.15candidate1 support (via xdis)
|
- Python 2.7.15candidate1 support (via `xdis`)
|
||||||
- bug fixes, especially for 3.7 (but 2.7 and 3.6 and others as well)
|
- bug fixes, especially for 3.7 (but 2.7 and 3.6 and others as well)
|
||||||
|
|
||||||
3.1.3 2018-04-16
|
3.1.3 2018-04-16
|
||||||
@@ -152,14 +397,14 @@ Jesus on Friday's New York Times puzzle: "I'm stuck on 2A"
|
|||||||
- reduce 3.5, 3.6 control-flow bugs
|
- reduce 3.5, 3.6 control-flow bugs
|
||||||
- reduce ambiguity in rules that lead to long (exponential?) parses
|
- reduce ambiguity in rules that lead to long (exponential?) parses
|
||||||
- limit/isolate some 2.6/2.7,3.x grammar rules
|
- limit/isolate some 2.6/2.7,3.x grammar rules
|
||||||
- more runtime testing of decompiled code
|
- more run-time testing of decompiled code
|
||||||
- more removal of parenthesis around calls via setting precidence
|
- more removal of parenthesis around calls via setting precedence
|
||||||
|
|
||||||
3.1.0 2018-03-21 Equinox
|
3.1.0 2018-03-21 Equinox
|
||||||
==============================
|
==============================
|
||||||
|
|
||||||
- Add code_deparse_with_offset() fragment function.
|
- Add code_deparse_with_offset() fragment function.
|
||||||
- Correct paramenter call fragment deparse_code()
|
- Correct parameter call fragment deparse_code()
|
||||||
- Lots of 3.6, 3.x, and 2.7 bug fixes
|
- Lots of 3.6, 3.x, and 2.7 bug fixes
|
||||||
About 5% of 3.6 fail parsing now. But
|
About 5% of 3.6 fail parsing now. But
|
||||||
semantics still needs much to be desired.
|
semantics still needs much to be desired.
|
||||||
@@ -227,24 +472,24 @@ function calls and definitions.
|
|||||||
2.15.1 2018-01-27
|
2.15.1 2018-01-27
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
- Add --linemap option to give line correspondences
|
- Add `--linemap` option to give line correspondences
|
||||||
between original source lines and reconstructed line sources.
|
between original source lines and reconstructed line sources.
|
||||||
It is far from perfect, but it is a start
|
It is far from perfect, but it is a start
|
||||||
- Add a new class of tests: tests which when decompiled check themselves
|
- Add a new class of tests: tests which when decompiled check themselves
|
||||||
- Split off Python version semantic action customizations into its own file
|
- Split off Python version semantic action customizations into its own file
|
||||||
- Fix 2.7 bug in ifelse loop statement
|
- Fix 2.7 bug in `if`/`else` loop statement
|
||||||
- Handle 3.6+ EXTENDED_ARGs for POP_JUMP_IF... instructions
|
- Handle 3.6+ `EXTENDED_ARG`s for `POP_JUMP_IF..` instructions
|
||||||
- Correct 3.6+ calls with kwargs
|
- Correct 3.6+ calls with `kwargs`
|
||||||
- Describe the difficulty of 3.6 in README
|
- Describe the difficulty of 3.6 in README
|
||||||
|
|
||||||
2.14.3 2018-01-19
|
2.14.3 2018-01-19
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
- Fix bug in 3.5+ await stmt
|
- Fix bug in 3.5+ `await` statement
|
||||||
- Better version to magic handling; handle 3.5.2 .. 3.5.4 versions
|
- Better version to magic handling; handle 3.5.2 .. 3.5.4 versions
|
||||||
- Improve/correct test_pyenvlib.py status messages
|
- Improve/correct test_pyenvlib.py status messages
|
||||||
- Fix some 2.7 and 2.6 parser bugs
|
- Fix some 2.7 and 2.6 parser bugs
|
||||||
- Fix whilelse parsing bugs
|
- Fix `whilelse` parsing bugs
|
||||||
- Correct 2.5- decorator parsing
|
- Correct 2.5- decorator parsing
|
||||||
- grammar for decorators matches AST a little more
|
- grammar for decorators matches AST a little more
|
||||||
- better tests in setup.py for running the right version of Python
|
- better tests in setup.py for running the right version of Python
|
||||||
@@ -255,15 +500,15 @@ function calls and definitions.
|
|||||||
|
|
||||||
Decompilation bug fixes, mostly 3.6 and pre 2.7
|
Decompilation bug fixes, mostly 3.6 and pre 2.7
|
||||||
|
|
||||||
- 3.6 FUNCTION_EX (somewhat)
|
- 3.6 `FUNCTION_EX` (somewhat)
|
||||||
- 3.6 FUNCTION_EX_KW fixes
|
- 3.6 `FUNCTION_EX_KW` fixes
|
||||||
- 3.6 MAKE_FUNCTION fixes
|
- 3.6 `MAKE_FUNCTION` fixes
|
||||||
- correct 3.5 CALL_FUNCTION_VAR
|
- correct 3.5 `CALL_FUNCTION_VAR`
|
||||||
- stronger 3.x "while 1" testing
|
- stronger 3.x "while 1" testing
|
||||||
- Fix bug in if's with "pass" bodies. Fixes #104
|
- Fix bug in if's with "pass" bodies. Fixes #104
|
||||||
- try/else and try/finally fixes on 2.6-
|
- try/else and try/finally fixes on 2.6-
|
||||||
- limit pypy customization to pypy
|
- limit pypy customization to pypy
|
||||||
- Add addr fields in COME_FROMS
|
- Add addr fields in `COME_FROM`S
|
||||||
- Allow use of full instructions in parser reduction routines
|
- Allow use of full instructions in parser reduction routines
|
||||||
- Reduce grammar in Python 3 by specialization more to specific
|
- Reduce grammar in Python 3 by specialization more to specific
|
||||||
Python versions
|
Python versions
|
||||||
@@ -272,11 +517,11 @@ Decompilation bug fixes, mostly 3.6 and pre 2.7
|
|||||||
2.14.1 2017-12-10 Dr. Gecko
|
2.14.1 2017-12-10 Dr. Gecko
|
||||||
===================================
|
===================================
|
||||||
|
|
||||||
- Many decompilation bugfixes
|
- Many decompilation bug fixes
|
||||||
- Grammar rule reduction and version isolation
|
- Grammar rule reduction and version isolation
|
||||||
- Match higher-level nonterminal names more closely
|
- Match higher-level nonterminal names more closely
|
||||||
with Python AST
|
with Python AST
|
||||||
- Start automated Python stdlib testing - full round trip
|
- Start automated Python _stdlib_ testing — full round trip
|
||||||
|
|
||||||
2.14.0 2017-11-26 johnnybamazing
|
2.14.0 2017-11-26 johnnybamazing
|
||||||
=========================================
|
=========================================
|
||||||
@@ -285,7 +530,7 @@ Decompilation bug fixes, mostly 3.6 and pre 2.7
|
|||||||
and remove used grammar rules
|
and remove used grammar rules
|
||||||
- Fix a number of bytecode decompile problems
|
- Fix a number of bytecode decompile problems
|
||||||
(many more remain)
|
(many more remain)
|
||||||
- Add stdlib/runtests.sh for even more rigorous testing
|
- Add `stdlib/runtests.sh` for even more rigorous testing
|
||||||
|
|
||||||
2.13.3 2017-11-13
|
2.13.3 2017-11-13
|
||||||
=====================
|
=====================
|
||||||
@@ -301,16 +546,16 @@ Overall: better 3.6 decompiling and some much needed code refactoring and cleanu
|
|||||||
rather trying to parse the bytecode array. This largely been done in for versions 3.x;
|
rather trying to parse the bytecode array. This largely been done in for versions 3.x;
|
||||||
3.0 custom mangling code has been reduced;
|
3.0 custom mangling code has been reduced;
|
||||||
some 2.x conversion has been done, but more is desired. This make it possible to...
|
some 2.x conversion has been done, but more is desired. This make it possible to...
|
||||||
- Handle EXTENDED_ARGS better. While relevant to all Python versions it is most noticeable in
|
- Handle `EXTENDED_ARGS` better. While relevant to all Python versions it is most noticeable in
|
||||||
version 3.6+ where in switching to wordcodes the size of operands has been reduced from 2**16
|
version 3.6+ where in switching to wordcodes the size of operands has been reduced from 2^16
|
||||||
to 2**8. JUMP instruction then often need EXTENDED_ARGS.
|
to 2^8. `JUMP` instruction then often need EXTENDED_ARGS.
|
||||||
- Refactor find_jump_targets() with via working of of instructions rather the bytecode array.
|
- Refactor find_jump_targets() with via working of of instructions rather the bytecode array.
|
||||||
- use --weak-verify more and additional fuzzing on verify()
|
- use `--weak-verify` more and additional fuzzing on verify()
|
||||||
- fragment parser now ignores errors in nested function definitions; an parameter was
|
- fragment parser now ignores errors in nested function definitions; an parameter was
|
||||||
added to assist here. Ignoring errors may be okay because the fragment parser often just needs,
|
added to assist here. Ignoring errors may be okay because the fragment parser often just needs,
|
||||||
well, *fragments*.
|
well, *fragments*.
|
||||||
- Distinguish RETURN_VALUE from RETURN_END_IF in exception bodies better in 3.6
|
- Distinguish `RETURN_VALUE` from `RETURN_END_IF` in exception bodies better in 3.6
|
||||||
- bug in 3.x language changes: import queue via import Queue
|
- bug in 3.x language changes: import queue via `import Queue`
|
||||||
- reinstate some bytecode tests since decompiling has gotten better
|
- reinstate some bytecode tests since decompiling has gotten better
|
||||||
- Revise how to report a bug
|
- Revise how to report a bug
|
||||||
|
|
||||||
@@ -330,12 +575,12 @@ Overall: better 3.6 decompiling and some much needed code refactoring and cleanu
|
|||||||
- Fixes in deparsing lambda expressions
|
- Fixes in deparsing lambda expressions
|
||||||
- Improve table-semantics descriptions
|
- Improve table-semantics descriptions
|
||||||
- Document hacky customize arg count better (until we can remove it)
|
- Document hacky customize arg count better (until we can remove it)
|
||||||
- Update to use xdis 3.7.0 or greater
|
- Update to use `xdis` 3.7.0 or greater
|
||||||
|
|
||||||
2.12.0 2017-09-26
|
2.12.0 2017-09-26
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
- Use xdis 3.6.0 or greater now
|
- Use `xdis` 3.6.0 or greater now
|
||||||
- Small semantic table cleanups
|
- Small semantic table cleanups
|
||||||
- Python 3.4's terms a little names better
|
- Python 3.4's terms a little names better
|
||||||
- Slightly more Python 3.7, but still failing a lot
|
- Slightly more Python 3.7, but still failing a lot
|
||||||
@@ -349,13 +594,13 @@ Overall: better 3.6 decompiling and some much needed code refactoring and cleanu
|
|||||||
2.11.4 2017-08-15
|
2.11.4 2017-08-15
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
* scanner and parser now allow 3-part version string lookups,
|
* scanner and parser now allow 3-part version string look ups,
|
||||||
e.g. 2.7.1 We allow a float here, but if passed a string like '2.7'. or
|
e.g. 2.7.1 We allow a float here, but if passed a string like '2.7'. or
|
||||||
* unpin 3.5.1. xdis 3.5.4 has been release and fixes the problems we had. Use that.
|
* unpin 3.5.1. `xdis` 3.5.4 has been release and fixes the problems we had. Use that.
|
||||||
* some routines here moved to xdis. Use the xdis version
|
* some routines here moved to `xdis`. Use the `xdis` version
|
||||||
* README.rst: Link typo Name is trepan2 now not trepan
|
* `README.rst`: Link typo Name is _trepan2_ now not _trepan_
|
||||||
* xdis-forced change adjust for COMPARE_OP "is-not" in
|
* xdis-forced change adjust for `COMPARE_OP` "is-not" in
|
||||||
semanatic routines. We need "is not".
|
semantic routines. We need "is not".
|
||||||
* Some PyPy tolerance in validate testing.
|
* Some PyPy tolerance in validate testing.
|
||||||
* Some pyston tolerance
|
* Some pyston tolerance
|
||||||
|
|
||||||
@@ -365,15 +610,15 @@ Overall: better 3.6 decompiling and some much needed code refactoring and cleanu
|
|||||||
Very minor changes
|
Very minor changes
|
||||||
|
|
||||||
- RsT doc fixes and updates
|
- RsT doc fixes and updates
|
||||||
- use newer xdis, but not too new; 3.5.2 breaks uncompyle6
|
- use newer `xdis`, but not too new; 3.5.2 breaks uncompyle6
|
||||||
- use xdis opcode sets
|
- use `xdis` opcode sets
|
||||||
- xdis "exception match" is now "exception-match"
|
- `xdis` "exception match" is now "exception-match"
|
||||||
|
|
||||||
2.11.2 2017-07-09
|
2.11.2 2017-07-09
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
- Start supporting Pypy 3.5 (5.7.1-beta)
|
- Start supporting Pypy 3.5 (5.7.1-beta)
|
||||||
- use xdis 3.5.0's opcode sets and require xdis 3.5.0
|
- use `xdis` 3.5.0's opcode sets and require `xdis` 3.5.0
|
||||||
- Correct some Python 2.4-2.6 loop detection
|
- Correct some Python 2.4-2.6 loop detection
|
||||||
- guard against badly formatted bytecode
|
- guard against badly formatted bytecode
|
||||||
|
|
||||||
@@ -381,55 +626,55 @@ Very minor changes
|
|||||||
=====================
|
=====================
|
||||||
|
|
||||||
- Python 3.x annotation and function signature fixes
|
- Python 3.x annotation and function signature fixes
|
||||||
- Bump xdis version
|
- Bump `xdis` version
|
||||||
- Small pysource bug fixes
|
- Small `pysource.py` bug fixes
|
||||||
|
|
||||||
2.11.0 2017-06-18 Fleetwood
|
2.11.0 2017-06-18 Fleetwood
|
||||||
==================================
|
==================================
|
||||||
|
|
||||||
- Major improvements in fragment tracking
|
- Major improvements in fragment tracking
|
||||||
* Add nonterminal node in extractInfo
|
* Add nonterminal node in `extractInfo()`
|
||||||
* tag more offsets in expressions
|
* tag more offsets in expressions
|
||||||
* tag array subscripts
|
* tag array subscripts
|
||||||
* set YIELD value offset in a <yield> expr
|
* set `YIELD` value offset in a _yield expr_
|
||||||
* fix a long-standing bug in not adjusting final AST when melding other deparse ASTs
|
* fix a long-standing bug in not adjusting final AST when melding other deparse ASTs
|
||||||
- Fixes yet again for make_function node handling; document what's up here
|
- Fixes yet again for make_function node handling; document what's up here
|
||||||
- Fix bug in snowflake Python 3.5 *args kwargs
|
- Fix bug in snowflake Python 3.5 `*args`, `kwargs`
|
||||||
|
|
||||||
2.10.1 2017-06-3 Marylin Frankel
|
2.10.1 2017-06-3 Marylin Frankel
|
||||||
========================================
|
========================================
|
||||||
|
|
||||||
- fix some fragments parsing bugs
|
- fix some fragments parsing bugs
|
||||||
- was returning the wrong type sometimes in deparse_code_around_offset()
|
- was returning the wrong type sometimes in `deparse_code_around_offset()`
|
||||||
- capture function name in offsets
|
- capture function name in offsets
|
||||||
- track changes to ifelstrmtr node from pysource into fragments
|
- track changes to `ifelstrmtr` node from `pysource.py` into fragments
|
||||||
|
|
||||||
2.10.0 2017-05-30 Elaine Gordon
|
2.10.0 2017-05-30 Elaine Gordon
|
||||||
=======================================
|
=======================================
|
||||||
|
|
||||||
- Add fuzzy offset deparse look up
|
- Add fuzzy offset deparse look up
|
||||||
- 3.6 bug fixes
|
- 3.6 bug fixes
|
||||||
- fix EXTENDED_ARGS handling (and in 2.6 and others)
|
- fix `EXTENDED_ARGS` handling (and in 2.6 and others)
|
||||||
- semantic routine make_function fragments.py
|
- semantic routine make_function fragments.py
|
||||||
- MAKE_FUNCTION handling
|
- `MAKE_FUNCTION` handling
|
||||||
- CALL_FUNCTION_EX handling
|
- `CALL_FUNCTION_EX` handling
|
||||||
- async property on defs
|
- `async` property on `defs`
|
||||||
- support for CALL_FUNCTION_KW (moagstar)
|
- support for `CALL_FUNCTION_KW` (moagstar)
|
||||||
- 3.5+ UNMAP_PACK and BUILD_UNMAP_PACK handling
|
- 3.5+ `UNMAP_PACK` and` BUILD_UNMAP_PACK` handling
|
||||||
- 3.5 FUNCTION_VAR bug
|
- 3.5 FUNCTION_VAR bug
|
||||||
- 3.x pass statement insdie while True
|
- 3.x pass statement inside `while True`
|
||||||
- Improve 3.2 decompilation
|
- Improve 3.2 decompilation
|
||||||
- Fixed -o argument processing (grkov90)
|
- Fixed `-o` argument processing (grkov90)
|
||||||
- Reduce scope of LOAD_ASSERT as expr to 3.4+
|
- Reduce scope of LOAD_ASSERT as expr to 3.4+
|
||||||
- "await" statement fixes
|
- `await` statement fixes
|
||||||
- 2.3, 2.4 "if 1 .." fixes
|
- 2.3, 2.4 "if 1 .." fixes
|
||||||
- 3.x annotation fixes
|
- 3.x annotation fixes
|
||||||
|
|
||||||
2.9.11 2017-04-06
|
2.9.11 2017-04-06
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
- Better support for Python 3.5+ BUILD_MAP_UNPACK
|
- Better support for Python 3.5+ `BUILD_MAP_UNPACK`
|
||||||
- Start 3.6 CALL_FUNCTION_EX support
|
- Start 3.6 `CALL_FUNCTION_EX` support
|
||||||
- Many decompilation bug fixes. (Many more remain). See ChangeLog
|
- Many decompilation bug fixes. (Many more remain). See ChangeLog
|
||||||
|
|
||||||
2.9.10 2017-02-25
|
2.9.10 2017-02-25
|
||||||
@@ -437,7 +682,7 @@ Very minor changes
|
|||||||
|
|
||||||
- Python grammar rule fixes
|
- Python grammar rule fixes
|
||||||
- Add ability to get grammar coverage on runs
|
- Add ability to get grammar coverage on runs
|
||||||
- Handle Python 3.6 opcode BUILD_CONST_KEYMAP
|
- Handle Python 3.6 opcode `BUILD_CONST_KEYMAP`
|
||||||
|
|
||||||
2.9.9 2016-12-16
|
2.9.9 2016-12-16
|
||||||
|
|
||||||
@@ -453,13 +698,13 @@ Very minor changes
|
|||||||
====================
|
====================
|
||||||
|
|
||||||
- Better control-flow detection
|
- Better control-flow detection
|
||||||
- pseudo instruction THEN in 2.x
|
- pseudo instruction `THEN` in 2.x
|
||||||
to disambiguate if from and
|
to disambiguate if from and
|
||||||
- fix bug in --verify option
|
- fix bug in `--verify` option
|
||||||
- DRY (a little) control-flow detection
|
- DRY (a little) control-flow detection
|
||||||
- fix syntax in tuples with one element
|
- fix syntax in tuples with one element
|
||||||
- if AST rule inheritance in Python 2.5
|
- if AST rule inheritance in Python 2.5
|
||||||
- NAME_MODULE removal for Python <= 2.4
|
- `NAME_MODULE` removal for Python <= 2.4
|
||||||
- verify call fixes for Python <= 2.4
|
- verify call fixes for Python <= 2.4
|
||||||
- more Python lint
|
- more Python lint
|
||||||
|
|
||||||
@@ -470,9 +715,9 @@ Very minor changes
|
|||||||
- Some Python 3.6 bytecode to wordcode conversion fixes
|
- Some Python 3.6 bytecode to wordcode conversion fixes
|
||||||
- option -g: show start-end range when possible
|
- option -g: show start-end range when possible
|
||||||
- track print_docstring move to help (used in python 3.1)
|
- track print_docstring move to help (used in python 3.1)
|
||||||
- verify: allow RETURN_VALUE to match RETURN_END_IF
|
- verify: allow `RETURN_VALUE` to match `RETURN_END_IF`
|
||||||
- some 3.2 compatibility
|
- some 3.2 compatibility
|
||||||
- Better Python 3 control flow detection by adding Pseudo ELSE opcodes
|
- Better Python 3 control flow detection by adding Pseudo `ELSE` opcodes
|
||||||
|
|
||||||
2.9.6 2016-12-04
|
2.9.6 2016-12-04
|
||||||
====================
|
====================
|
||||||
@@ -488,7 +733,7 @@ Very minor changes
|
|||||||
|
|
||||||
- Correct MANIFEST.in
|
- Correct MANIFEST.in
|
||||||
- More AST grammar checking
|
- More AST grammar checking
|
||||||
- --linemapping option or linenumbers.line_number_mapping()
|
- `--linemapping` option or _linenumbers.line_number_mapping()_
|
||||||
Shows correspondence of lines between source
|
Shows correspondence of lines between source
|
||||||
and decompiled source
|
and decompiled source
|
||||||
- Some control flow adjustments in code for 2.x.
|
- Some control flow adjustments in code for 2.x.
|
||||||
@@ -508,7 +753,7 @@ Very minor changes
|
|||||||
* improper while 1 else
|
* improper while 1 else
|
||||||
* docstring indent
|
* docstring indent
|
||||||
* 3.3 default values in lambda expressions
|
* 3.3 default values in lambda expressions
|
||||||
* start 3.0 decompilation (needs newer xdis)
|
* start 3.0 decompilation (needs newer `xdis`)
|
||||||
- Start grammar misparse checking
|
- Start grammar misparse checking
|
||||||
|
|
||||||
|
|
||||||
@@ -522,12 +767,12 @@ Very minor changes
|
|||||||
2.9.3 2016-10-26
|
2.9.3 2016-10-26
|
||||||
====================
|
====================
|
||||||
|
|
||||||
Release forced by incompatibility change in xdis 3.2.0.
|
Release forced by incompatibility change in` xdis` 3.2.0.
|
||||||
|
|
||||||
- Python 3.1 bugs:
|
- Python 3.1 bugs:
|
||||||
* handle "with ... as"
|
* handle `with`... `as`
|
||||||
* handle "with"
|
* handle `with`
|
||||||
* Start handling def (...) -> yy (has bugs still)
|
* Start handling `def` (...) -> _yy_ (has bugs still)
|
||||||
|
|
||||||
- DRY Python 3.x via inheritance
|
- DRY Python 3.x via inheritance
|
||||||
- Python 3.6 work (from Daniel Bradburn)
|
- Python 3.6 work (from Daniel Bradburn)
|
||||||
@@ -553,12 +798,12 @@ Release forced by incompatibility change in xdis 3.2.0.
|
|||||||
2.9.0 2016-10-09
|
2.9.0 2016-10-09
|
||||||
====================
|
====================
|
||||||
|
|
||||||
- Use xdis 3.0.0 protocol load_module.
|
- Use `xdis` 3.0.0 protocol `load_module`.
|
||||||
this Forces change in requirements.txt and _pkg_info_.py
|
this Forces change in requirements.txt and _pkg_info_.py
|
||||||
- Start Python 1.5 decompiling; another round of work is needed to
|
- Start Python 1.5 decompiling; another round of work is needed to
|
||||||
remove bugs
|
remove bugs
|
||||||
- Simplify python 2.1 grammar
|
- Simplify python 2.1 grammar
|
||||||
- Fix bug with -t ... Wasn't showing source text when -t option was given
|
- Fix bug with `-t` ... Wasn't showing source text when `-t` option was given
|
||||||
- Fix 2.1-2.6 bug in list comprehension
|
- Fix 2.1-2.6 bug in list comprehension
|
||||||
|
|
||||||
2.8.4 2016-10-08
|
2.8.4 2016-10-08
|
||||||
@@ -567,8 +812,8 @@ Release forced by incompatibility change in xdis 3.2.0.
|
|||||||
- Python 3 disassembly bug fixes
|
- Python 3 disassembly bug fixes
|
||||||
- Python 3.6 fstring bug fixes (from moagstar)
|
- Python 3.6 fstring bug fixes (from moagstar)
|
||||||
- Python 2.1 disassembly
|
- Python 2.1 disassembly
|
||||||
- COME_FROM suffixes added in Python3
|
- `COME_FROM` suffixes added in Python3
|
||||||
- use .py extension in verification disassembly
|
- use `.py` extension in verification disassembly
|
||||||
|
|
||||||
2.8.3 2016-09-11 live from NYC!
|
2.8.3 2016-09-11 live from NYC!
|
||||||
=======================================
|
=======================================
|
||||||
@@ -613,8 +858,8 @@ control-flow structure detection is done.
|
|||||||
- Add Python 2.2 decompilation
|
- Add Python 2.2 decompilation
|
||||||
|
|
||||||
- Fix bugs
|
- Fix bugs
|
||||||
* PyPy LOOKUP_METHOD bug
|
* PyPy `LOOKUP_METHOD` bug
|
||||||
* Python 3.6 FORMAT_VALUE handles expressions now
|
* Python 3.6 `FORMAT_VALUE` handles expressions now
|
||||||
|
|
||||||
2.8.0 2016-08-03
|
2.8.0 2016-08-03
|
||||||
====================
|
====================
|
||||||
@@ -664,7 +909,7 @@ control-flow structure detection is done.
|
|||||||
====================
|
====================
|
||||||
|
|
||||||
- Improve Python 2.6 bytecode deparsing:
|
- Improve Python 2.6 bytecode deparsing:
|
||||||
stdlib now will deparse something
|
_stdlib_ now will deparse something
|
||||||
- Better <2.6 vs. 2.7 grammar separation
|
- Better <2.6 vs. 2.7 grammar separation
|
||||||
- Fix some 2.7 deparsing bugs
|
- Fix some 2.7 deparsing bugs
|
||||||
- Fix bug in installing uncompyle6 script
|
- Fix bug in installing uncompyle6 script
|
||||||
@@ -727,9 +972,9 @@ control-flow structure detection is done.
|
|||||||
2.3.2 2016-05-1
|
2.3.2 2016-05-1
|
||||||
===================
|
===================
|
||||||
|
|
||||||
- Add --version option standalone scripts
|
- Add `--version` option standalone scripts
|
||||||
- Correct License information in package
|
- Correct License information in package
|
||||||
- expose fns uncompyle_file, load_file, and load_module
|
- expose functions `uncompyle_file()`, `load_file()`, and `load_module()`
|
||||||
- Start to DRY Python2 and Python3 grammars Separate out 3.2, and 3.5+
|
- Start to DRY Python2 and Python3 grammars Separate out 3.2, and 3.5+
|
||||||
specific grammar code
|
specific grammar code
|
||||||
- Fix bug in 3.5+ constant map parsing
|
- Fix bug in 3.5+ constant map parsing
|
||||||
@@ -737,12 +982,12 @@ control-flow structure detection is done.
|
|||||||
2.3.0, 2.3.1 2016-04-30
|
2.3.0, 2.3.1 2016-04-30
|
||||||
=============================
|
=============================
|
||||||
|
|
||||||
- Require spark_parser >= 1.1.0
|
- Require `spark_parser` >= 1.1.0
|
||||||
|
|
||||||
2.2.0 2016-04-30
|
2.2.0 2016-04-30
|
||||||
====================
|
====================
|
||||||
|
|
||||||
- Spark is no longer here but pulled separate package spark_parse
|
- Spark is no longer here but pulled separate package [spark_parser](https://pypi.org/project/spark_parser/)
|
||||||
- Python 3 parsing fixes
|
- Python 3 parsing fixes
|
||||||
- More tests
|
- More tests
|
||||||
|
|
||||||
@@ -752,7 +997,7 @@ control-flow structure detection is done.
|
|||||||
- Support single-mode (in addition to exec-mode) compilation
|
- Support single-mode (in addition to exec-mode) compilation
|
||||||
- Start to DRY Python 2 and Python 3 grammars
|
- Start to DRY Python 2 and Python 3 grammars
|
||||||
- Fix bug in if else ternary construct
|
- Fix bug in if else ternary construct
|
||||||
- Fix bug in uncomplye6 -d and -r options (via lelicopter)
|
- Fix bug in uncomplye6 `-d` and `-r` options (via lelicopter)
|
||||||
|
|
||||||
|
|
||||||
2.1.3 2016-01-02
|
2.1.3 2016-01-02
|
||||||
@@ -760,7 +1005,7 @@ control-flow structure detection is done.
|
|||||||
|
|
||||||
- Limited support for decompiling Python 3.5
|
- Limited support for decompiling Python 3.5
|
||||||
- Improve Python 3 class deparsing
|
- Improve Python 3 class deparsing
|
||||||
- Handle MAKE_CLOSURE opcode
|
- Handle `MAKE_CLOSURE` opcode
|
||||||
- Start to DRY opcode code.
|
- Start to DRY opcode code.
|
||||||
- increase test coverage
|
- increase test coverage
|
||||||
- fix misc small bugs and some improvements
|
- fix misc small bugs and some improvements
|
||||||
@@ -802,5 +1047,5 @@ Changes from uncompyle2
|
|||||||
|
|
||||||
SPARK:
|
SPARK:
|
||||||
add option to show grammar rules applied
|
add option to show grammar rules applied
|
||||||
allow Python-style # comments in grammar
|
allow Python-style `#` comments in grammar
|
||||||
Runs on Python 3 and Python 2
|
Runs on Python 3 and Python 2
|
||||||
|
136
README.rst
136
README.rst
@@ -1,4 +1,6 @@
|
|||||||
|buildstatus| |Latest Version| |Supported Python Versions|
|
|buildstatus| |Pypi Installs| |Latest Version| |Supported Python Versions|
|
||||||
|
|
||||||
|
|packagestatus|
|
||||||
|
|
||||||
uncompyle6
|
uncompyle6
|
||||||
==========
|
==========
|
||||||
@@ -11,9 +13,9 @@ Introduction
|
|||||||
------------
|
------------
|
||||||
|
|
||||||
*uncompyle6* translates Python bytecode back into equivalent Python
|
*uncompyle6* translates Python bytecode back into equivalent Python
|
||||||
source code. It accepts bytecodes from Python version 1.3 to version
|
source code. It accepts bytecodes from Python version 1.0 to version
|
||||||
3.8, spanning over 24 years of Python releases. We include Dropbox's
|
3.8, spanning over 24 years of Python releases. We include Dropbox's
|
||||||
Python 2.5 bytecode and some PyPy bytecode.
|
Python 2.5 bytecode and some PyPy bytecodes.
|
||||||
|
|
||||||
Why this?
|
Why this?
|
||||||
---------
|
---------
|
||||||
@@ -44,14 +46,15 @@ not exist and there is just bytecode. Again, my debuggers make use of
|
|||||||
this.
|
this.
|
||||||
|
|
||||||
There were (and still are) a number of decompyle, uncompyle,
|
There were (and still are) a number of decompyle, uncompyle,
|
||||||
uncompyle2, uncompyle3 forks around. Almost all of them come basically
|
uncompyle2, uncompyle3 forks around. Many of them come basically from
|
||||||
from the same code base, and (almost?) all of them are no longer
|
the same code base, and (almost?) all of them are no longer actively
|
||||||
actively maintained. One was really good at decompiling Python 1.5-2.3
|
maintained. One was really good at decompiling Python 1.5-2.3, another
|
||||||
or so, another really good at Python 2.7, but that only. Another
|
really good at Python 2.7, but that only. Another handles Python 3.2
|
||||||
handles Python 3.2 only; another patched that and handled only 3.3.
|
only; another patched that and handled only 3.3. You get the
|
||||||
You get the idea. This code pulls all of these forks together and
|
idea. This code pulls all of these forks together and *moves
|
||||||
*moves forward*. There is some serious refactoring and cleanup in this
|
forward*. There is some serious refactoring and cleanup in this code
|
||||||
code base over those old forks.
|
base over those old forks. Even more experimental refactoring is going
|
||||||
|
on in decompyle3_.
|
||||||
|
|
||||||
This demonstrably does the best in decompiling Python across all
|
This demonstrably does the best in decompiling Python across all
|
||||||
Python versions. And even when there is another project that only
|
Python versions. And even when there is another project that only
|
||||||
@@ -73,11 +76,11 @@ fixed in the other decompilers.
|
|||||||
Requirements
|
Requirements
|
||||||
------------
|
------------
|
||||||
|
|
||||||
The code here can be run on Python versions 2.6 or later, PyPy 3-2.4,
|
The code here can be run on Python versions 2.6 or later, PyPy 3-2.4
|
||||||
or PyPy-5.0.1. Python versions 2.4-2.7 are supported in the
|
and later. Python versions 2.4-2.7 are supported in the python-2.4
|
||||||
python-2.4 branch. The bytecode files it can read have been tested on
|
branch. The bytecode files it can read have been tested on Python
|
||||||
Python bytecodes from versions 1.4, 2.1-2.7, and 3.0-3.8 and the
|
bytecodes from versions 1.4, 2.1-2.7, and 3.0-3.8 and later PyPy
|
||||||
above-mentioned PyPy versions.
|
versions.
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
------------
|
------------
|
||||||
@@ -86,15 +89,15 @@ This uses setup.py, so it follows the standard Python routine:
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
pip install -e . # set up to run from source tree
|
$ pip install -e . # set up to run from source tree
|
||||||
# Or if you want to install instead
|
# Or if you want to install instead
|
||||||
python setup.py install # may need sudo
|
$ python setup.py install # may need sudo
|
||||||
|
|
||||||
A GNU makefile is also provided so :code:`make install` (possibly as root or
|
A GNU makefile is also provided so :code:`make install` (possibly as root or
|
||||||
sudo) will do the steps above.
|
sudo) will do the steps above.
|
||||||
|
|
||||||
Testing
|
Running Tests
|
||||||
-------
|
-------------
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
@@ -122,16 +125,39 @@ For usage help:
|
|||||||
|
|
||||||
$ uncompyle6 -h
|
$ uncompyle6 -h
|
||||||
|
|
||||||
If you want strong verification of the correctness of the
|
Verification
|
||||||
decompilation process, add the `--verify` option. But there are
|
------------
|
||||||
situations where this will indicate a failure, although the generated
|
|
||||||
program is semantically equivalent. Using option `--weak-verify` will
|
|
||||||
tell you if there is something definitely wrong. Generally, large
|
|
||||||
swaths of code are decompiled correctly, if not the entire program.
|
|
||||||
|
|
||||||
You can also cross compare the results with pycdc_ . Since they work
|
In older versions of Python it was possible to verify bytecode by
|
||||||
differently, bugs here often aren't in that, and vice versa.
|
decompiling bytecode, and then compiling using the Python interpreter
|
||||||
|
for that bytecode version. Having done this the bytecode produced
|
||||||
|
could be compared with the original bytecode. However as Python's code
|
||||||
|
generation got better, this no longer was feasible.
|
||||||
|
|
||||||
|
If you want Python syntax verification of the correctness of the
|
||||||
|
decompilation process, add the :code:`--syntax-verify` option. However since
|
||||||
|
Python syntax changes, you should use this option if the bytecode is
|
||||||
|
the right bytecode for the Python interpreter that will be checking
|
||||||
|
the syntax.
|
||||||
|
|
||||||
|
You can also cross compare the results with either another version of
|
||||||
|
`uncompyle6` since there are are sometimes regressions in decompiling
|
||||||
|
specific bytecode as the overall quality improves.
|
||||||
|
|
||||||
|
For Python 3.7 and above, the code in decompyle3_ is generally
|
||||||
|
better.
|
||||||
|
|
||||||
|
Or try specific another python decompiler like uncompyle2_, unpyc37_,
|
||||||
|
or pycdc_. Since the later two work differently, bugs here often
|
||||||
|
aren't in that, and vice versa.
|
||||||
|
|
||||||
|
There is an interesting class of these programs that is readily
|
||||||
|
available give stronger verification: those programs that when run
|
||||||
|
test themselves. Our test suite includes these.
|
||||||
|
|
||||||
|
And Python comes with another a set of programs like this: its test
|
||||||
|
suite for the standard library. We have some code in :code:`test/stdlib` to
|
||||||
|
facilitate this kind of checking too.
|
||||||
|
|
||||||
Known Bugs/Restrictions
|
Known Bugs/Restrictions
|
||||||
-----------------------
|
-----------------------
|
||||||
@@ -146,27 +172,6 @@ All of the Python decompilers that I have looked at have problems
|
|||||||
decompiling Python's control flow. In some cases we can detect an
|
decompiling Python's control flow. In some cases we can detect an
|
||||||
erroneous decompilation and report that.
|
erroneous decompilation and report that.
|
||||||
|
|
||||||
In older versions of Python it was possible to verify bytecode by
|
|
||||||
decompiling bytecode, and then compiling using the Python interpreter
|
|
||||||
for that bytecode version. Having done this the bytecode produced
|
|
||||||
could be compared with the original bytecode. However as Python's code
|
|
||||||
generation got better, this is no longer feasible.
|
|
||||||
|
|
||||||
The verification that we use that doesn't check bytecode for
|
|
||||||
equivalence but does check to see if the resulting decompiled source
|
|
||||||
is a valid Python program by running the Python interpreter. Because
|
|
||||||
the Python language has changed so much, for best results you should
|
|
||||||
use the same Python version in checking as was used in creating the
|
|
||||||
bytecode.
|
|
||||||
|
|
||||||
There are however an interesting class of these programs that is
|
|
||||||
readily available give stronger verification: those programs that
|
|
||||||
when run check some computation, or even better themselves.
|
|
||||||
|
|
||||||
And already Python has a set of programs like this: the test suite
|
|
||||||
for the standard library that comes with Python. We have some
|
|
||||||
code in `test/stdlib` to facilitate this kind of checking.
|
|
||||||
|
|
||||||
Python support is strongest in Python 2 for 2.7 and drops off as you
|
Python support is strongest in Python 2 for 2.7 and drops off as you
|
||||||
get further away from that. Support is also probably pretty good for
|
get further away from that. Support is also probably pretty good for
|
||||||
python 2.3-2.4 since a lot of the goodness of early the version of the
|
python 2.3-2.4 since a lot of the goodness of early the version of the
|
||||||
@@ -182,22 +187,28 @@ In the Python 3 series, Python support is is strongest around 3.4 or
|
|||||||
3.0 is weird in that it in some ways resembles 2.6 more than it does
|
3.0 is weird in that it in some ways resembles 2.6 more than it does
|
||||||
3.1 or 2.7. Python 3.6 changes things drastically by using word codes
|
3.1 or 2.7. Python 3.6 changes things drastically by using word codes
|
||||||
rather than byte codes. As a result, the jump offset field in a jump
|
rather than byte codes. As a result, the jump offset field in a jump
|
||||||
instruction argument has been reduced. This makes the `EXTENDED_ARG`
|
instruction argument has been reduced. This makes the :code:`EXTENDED_ARG`
|
||||||
instructions are now more prevalent in jump instruction; previously
|
instructions are now more prevalent in jump instruction; previously
|
||||||
they had been rare. Perhaps to compensate for the additional
|
they had been rare. Perhaps to compensate for the additional
|
||||||
`EXTENDED_ARG` instructions, additional jump optimization has been
|
:code:`EXTENDED_ARG` instructions, additional jump optimization has been
|
||||||
added. So in sum handling control flow by ad hoc means as is currently
|
added. So in sum handling control flow by ad hoc means as is currently
|
||||||
done is worse.
|
done is worse.
|
||||||
|
|
||||||
Between Python 3.5, 3.6 and 3.7 there have been major changes to the
|
Between Python 3.5, 3.6, 3.7 there have been major changes to the
|
||||||
`MAKE_FUNCTION` and `CALL_FUNCTION` instructions.
|
:code:`MAKE_FUNCTION` and :code:`CALL_FUNCTION` instructions. Python
|
||||||
|
|
||||||
|
Python 3.8 removes :code:`SETUP_LOOP`, :code:`SETUP_EXCEPT`,
|
||||||
|
:code:`BREAK_LOOP`, and :code:`CONTINUE_LOOP`, instructions which may
|
||||||
|
make control-flow detection harder, lacking the more sophisticated
|
||||||
|
control-flow analysis that is planned. We'll see.
|
||||||
|
|
||||||
Currently not all Python magic numbers are supported. Specifically in
|
Currently not all Python magic numbers are supported. Specifically in
|
||||||
some versions of Python, notably Python 3.6, the magic number has
|
some versions of Python, notably Python 3.6, the magic number has
|
||||||
changes several times within a version.
|
changes several times within a version.
|
||||||
|
|
||||||
**We support only released versions, not candidate versions.** Note however
|
**We support only released versions, not candidate versions.** Note
|
||||||
that the magic of a released version is usually the same as the *last* candidate version prior to release.
|
however that the magic of a released version is usually the same as
|
||||||
|
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 bytcode. With the exception of
|
||||||
@@ -219,15 +230,16 @@ There is lots to do, so please dig in and help.
|
|||||||
See Also
|
See Also
|
||||||
--------
|
--------
|
||||||
|
|
||||||
* https://github.com/zrax/pycdc : purports to support all versions of Python. It is written in C++ and is most accurate for Python versions around 2.7 and 3.3 when the code was more actively developed. Accuracy for more recent versions of Python 3 and early versions of Python are especially lacking. See its `issue tracker <https://github.com/zrax/pycdc/issues>`_ for details. Currently lightly maintained.
|
* https://github.com/rocky/python-decompile3 : Much smaller and more modern code, focusing on 3.7+. Changes in that will get migrated back ehre.
|
||||||
* 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 situtations where `uncompyle6` results are incorrect while `uncompyle2` results are not, but more often uncompyle6 is correct when uncompyle2 is not. Because `uncompyle6` adheres to accuracy over idiomatic Python, `uncompyle2` can produce more natural-looking code when it is correct. Currently `uncompyle2` is lightly maintained. See its issue `tracker <https://github.com/wibiti/uncompyle2/issues>`_ for more details
|
* 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
|
||||||
* `How to report a bug <https://github.com/rocky/python-uncompyle6/blob/master/HOW-TO-REPORT-A-BUG.md>`_
|
* `How to report a bug <https://github.com/rocky/python-uncompyle6/blob/master/HOW-TO-REPORT-A-BUG.md>`_
|
||||||
* The HISTORY_ file.
|
* The HISTORY_ file.
|
||||||
* https://github.com/rocky/python-xdis : Cross Python version disassembler
|
* https://github.com/rocky/python-xdis : Cross Python version disassembler
|
||||||
* https://github.com/rocky/python-xasm : Cross Python version assembler
|
* https://github.com/rocky/python-xasm : Cross Python version assembler
|
||||||
* https://github.com/rocky/python-uncompyle6/wiki : Wiki Documents which describe the code and aspects of it in more detail
|
* https://github.com/rocky/python-uncompyle6/wiki : Wiki Documents which describe the code and aspects of it in more detail
|
||||||
|
* https://github.com/zrax/pycdc : The README for this C++ code says it aims to support all versions of Python. It is best for Python versions around 2.7 and 3.3 when the code was initially developed. Accuracy for current versions of Python3 and early versions of Python is lacking. Without major effort, it is unlikely it can be made to support current Python 3. See its `issue tracker <https://github.com/zrax/pycdc/issues>`_ for details. Currently lightly maintained.
|
||||||
|
|
||||||
|
|
||||||
.. _trepan: https://pypi.python.org/pypi/trepan2g
|
.. _trepan: https://pypi.python.org/pypi/trepan2g
|
||||||
@@ -236,12 +248,18 @@ See Also
|
|||||||
.. _debuggers: https://pypi.python.org/pypi/trepan3k
|
.. _debuggers: https://pypi.python.org/pypi/trepan3k
|
||||||
.. _remake: https://bashdb.sf.net/remake
|
.. _remake: https://bashdb.sf.net/remake
|
||||||
.. _pycdc: https://github.com/zrax/pycdc
|
.. _pycdc: https://github.com/zrax/pycdc
|
||||||
|
.. _decompyle3: https://github.com/rocky/python-decompile3
|
||||||
|
.. _uncompyle2: https://github.com/wibiti/uncompyle2
|
||||||
|
.. _unpyc37: https://github.com/andrew-tavera/unpyc37
|
||||||
.. _this: https://github.com/rocky/python-uncompyle6/wiki/Deparsing-technology-and-its-use-in-exact-location-reporting
|
.. _this: https://github.com/rocky/python-uncompyle6/wiki/Deparsing-technology-and-its-use-in-exact-location-reporting
|
||||||
.. |buildstatus| image:: https://travis-ci.org/rocky/python-uncompyle6.svg
|
.. |buildstatus| image:: https://travis-ci.org/rocky/python-uncompyle6.svg
|
||||||
:target: https://travis-ci.org/rocky/python-uncompyle6
|
:target: https://travis-ci.org/rocky/python-uncompyle6
|
||||||
|
.. |packagestatus| image:: https://repology.org/badge/vertical-allrepos/python:uncompyle6.svg
|
||||||
|
:target: https://repology.org/project/python:uncompyle6/versions
|
||||||
.. _PJOrion: http://www.koreanrandom.com/forum/topic/15280-pjorion-%D1%80%D0%B5%D0%B4%D0%B0%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D0%BA%D0%BE%D0%BC%D0%BF%D0%B8%D0%BB%D1%8F%D1%86%D0%B8%D1%8F-%D0%B4%D0%B5%D0%BA%D0%BE%D0%BC%D0%BF%D0%B8%D0%BB%D1%8F%D1%86%D0%B8%D1%8F-%D0%BE%D0%B1%D1%84
|
.. _PJOrion: http://www.koreanrandom.com/forum/topic/15280-pjorion-%D1%80%D0%B5%D0%B4%D0%B0%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D0%BA%D0%BE%D0%BC%D0%BF%D0%B8%D0%BB%D1%8F%D1%86%D0%B8%D1%8F-%D0%B4%D0%B5%D0%BA%D0%BE%D0%BC%D0%BF%D0%B8%D0%BB%D1%8F%D1%86%D0%B8%D1%8F-%D0%BE%D0%B1%D1%84
|
||||||
.. _Deobfuscator: https://github.com/extremecoders-re/PjOrion-Deobfuscator
|
.. _Deobfuscator: https://github.com/extremecoders-re/PjOrion-Deobfuscator
|
||||||
.. _Py2EXE: https://en.wikipedia.org/wiki/Py2exe
|
.. _Py2EXE: https://en.wikipedia.org/wiki/Py2exe
|
||||||
.. |Supported Python Versions| image:: https://img.shields.io/pypi/pyversions/uncompyle6.svg
|
.. |Supported Python Versions| image:: https://img.shields.io/pypi/pyversions/uncompyle6.svg
|
||||||
.. |Latest Version| image:: https://badge.fury.io/py/uncompyle6.svg
|
.. |Latest Version| image:: https://badge.fury.io/py/uncompyle6.svg
|
||||||
:target: https://badge.fury.io/py/uncompyle6
|
:target: https://badge.fury.io/py/uncompyle6
|
||||||
|
.. |Pypi Installs| image:: https://pepy.tech/badge/uncompyle6/month
|
||||||
|
@@ -26,46 +26,46 @@ copyright = """
|
|||||||
Copyright (C) 2015-2019 Rocky Bernstein <rb@dustyfeet.com>.
|
Copyright (C) 2015-2019 Rocky Bernstein <rb@dustyfeet.com>.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
classifiers = ['Development Status :: 5 - Production/Stable',
|
classifiers = ["Development Status :: 5 - Production/Stable",
|
||||||
'Intended Audience :: Developers',
|
"Intended Audience :: Developers",
|
||||||
'License :: OSI Approved :: GNU General Public License v3 (GPLv3)',
|
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
|
||||||
'Operating System :: OS Independent',
|
"Operating System :: OS Independent",
|
||||||
'Programming Language :: Python',
|
"Programming Language :: Python",
|
||||||
'Programming Language :: Python :: 2.4',
|
"Programming Language :: Python :: 2.4",
|
||||||
'Programming Language :: Python :: 2.5',
|
"Programming Language :: Python :: 2.5",
|
||||||
'Programming Language :: Python :: 2.6',
|
"Programming Language :: Python :: 2.6",
|
||||||
'Programming Language :: Python :: 2.7',
|
"Programming Language :: Python :: 2.7",
|
||||||
'Programming Language :: Python :: 3.0',
|
"Programming Language :: Python :: 3.0",
|
||||||
'Programming Language :: Python :: 3.1',
|
"Programming Language :: Python :: 3.1",
|
||||||
'Programming Language :: Python :: 3.2',
|
"Programming Language :: Python :: 3.2",
|
||||||
'Programming Language :: Python :: 3.3',
|
"Programming Language :: Python :: 3.3",
|
||||||
'Programming Language :: Python :: 3.4',
|
"Programming Language :: Python :: 3.4",
|
||||||
'Programming Language :: Python :: 3.5',
|
"Programming Language :: Python :: 3.5",
|
||||||
'Programming Language :: Python :: 3.6',
|
"Programming Language :: Python :: 3.6",
|
||||||
'Programming Language :: Python :: 3.7',
|
"Programming Language :: Python :: 3.7",
|
||||||
'Programming Language :: Python :: 3.8',
|
"Programming Language :: Python :: 3.8",
|
||||||
'Topic :: Software Development :: Debuggers',
|
"Topic :: Software Development :: Debuggers",
|
||||||
'Topic :: Software Development :: Libraries :: Python Modules',
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
||||||
]
|
]
|
||||||
|
|
||||||
# The rest in alphabetic order
|
# The rest in alphabetic order
|
||||||
author = "Rocky Bernstein, Hartmut Goebel, John Aycock, and others"
|
author = "Rocky Bernstein, Hartmut Goebel, John Aycock, and others"
|
||||||
author_email = "rb@dustyfeet.com"
|
author_email = "rb@dustyfeet.com"
|
||||||
entry_points = {
|
entry_points = {
|
||||||
'console_scripts': [
|
"console_scripts": [
|
||||||
'uncompyle6=uncompyle6.bin.uncompile:main_bin',
|
"uncompyle6=uncompyle6.bin.uncompile:main_bin",
|
||||||
'pydisassemble=uncompyle6.bin.pydisassemble:main',
|
"pydisassemble=uncompyle6.bin.pydisassemble:main",
|
||||||
]}
|
]}
|
||||||
ftp_url = None
|
ftp_url = None
|
||||||
install_requires = ['spark-parser >= 1.8.7, < 1.9.0',
|
install_requires = ["spark-parser >= 1.8.9, < 1.9.0",
|
||||||
'xdis >= 4.0.1, < 4.1.0']
|
"xdis >= 4.2.2, < 4.3.0"]
|
||||||
|
|
||||||
license = 'GPL3'
|
license = "GPL3"
|
||||||
mailing_list = 'python-debugger@googlegroups.com'
|
mailing_list = "python-debugger@googlegroups.com"
|
||||||
modname = 'uncompyle6'
|
modname = "uncompyle6"
|
||||||
py_modules = None
|
py_modules = None
|
||||||
short_desc = 'Python cross-version byte-code decompiler'
|
short_desc = "Python cross-version byte-code decompiler"
|
||||||
web = 'https://github.com/rocky/python-uncompyle6/'
|
web = "https://github.com/rocky/python-uncompyle6/"
|
||||||
|
|
||||||
# tracebacks in zip files are funky and not debuggable
|
# tracebacks in zip files are funky and not debuggable
|
||||||
zip_safe = True
|
zip_safe = True
|
||||||
@@ -82,5 +82,5 @@ def read(*rnames):
|
|||||||
return open(os.path.join(srcdir, *rnames)).read()
|
return open(os.path.join(srcdir, *rnames)).read()
|
||||||
|
|
||||||
# Get info from files; set: long_description and VERSION
|
# Get info from files; set: long_description and VERSION
|
||||||
long_description = ( read("README.rst") + '\n' )
|
long_description = ( read("README.rst") + "\n" )
|
||||||
exec(read('uncompyle6/version.py'))
|
exec(read("uncompyle6/version.py"))
|
||||||
|
@@ -8,4 +8,15 @@ They are customized to my environment:
|
|||||||
- I have git repos for xdis, and spark parser at the same level as uncompyle6
|
- I have git repos for xdis, and spark parser at the same level as uncompyle6
|
||||||
|
|
||||||
There may be other rocky-specific things that need customization.
|
There may be other rocky-specific things that need customization.
|
||||||
how-to-make-a-release.txt has overall how I make a release
|
how-to-make-a-release.md has overall how I make a release
|
||||||
|
|
||||||
|
Since this project uses python over a wide variety of release, some versions
|
||||||
|
of projects that should be used for specific Python versions
|
||||||
|
|
||||||
|
for 3.2.6:
|
||||||
|
pytest==2.9.2
|
||||||
|
|
||||||
|
for 3.1.5
|
||||||
|
pytset==2.1.0
|
||||||
|
py=1.8.0 and comment out line 10 of _builtin.py # callable = callable
|
||||||
|
six==1.10.0
|
||||||
|
@@ -21,8 +21,9 @@ for version in $PYVERSIONS; do
|
|||||||
exit $?
|
exit $?
|
||||||
fi
|
fi
|
||||||
make clean && pip install -e .
|
make clean && pip install -e .
|
||||||
if ! make check; then
|
if ! make check-short; then
|
||||||
exit $?
|
exit $?
|
||||||
fi
|
fi
|
||||||
echo === $version ===
|
echo === $version ===
|
||||||
done
|
done
|
||||||
|
make check
|
||||||
|
@@ -56,19 +56,21 @@
|
|||||||
|
|
||||||
$ . ./admin-tools/make-dist-older.sh
|
$ . ./admin-tools/make-dist-older.sh
|
||||||
$ git tag release-python-2.4-$VERSION
|
$ git tag release-python-2.4-$VERSION
|
||||||
|
$ twine check dist/uncompyle6-$VERSION*
|
||||||
$ . ./admin-tools/make-dist-newer.sh
|
$ . ./admin-tools/make-dist-newer.sh
|
||||||
|
$ twine check dist/uncompyle6-$VERSION*
|
||||||
Goto https://github.com/rocky/python-uncompyle6/releases
|
|
||||||
|
|
||||||
# Upload single package and look at Rst Formating
|
# Upload single package and look at Rst Formating
|
||||||
|
|
||||||
|
$ twine check dist/uncompyle6-${VERSION}*
|
||||||
$ twine upload dist/uncompyle6-${VERSION}-py3.3.egg
|
$ twine upload dist/uncompyle6-${VERSION}-py3.3.egg
|
||||||
|
|
||||||
# Upload rest of versions
|
# Upload rest of versions
|
||||||
|
|
||||||
$ twine upload dist/uncompyle6-${VERSION}*
|
$ twine upload dist/uncompyle6-${VERSION}*
|
||||||
|
|
||||||
|
Goto https://github.com/rocky/python-uncompyle6/releases
|
||||||
|
|
||||||
# Push tags:
|
# Push tags:
|
||||||
|
|
||||||
$ git push --tags
|
$ git push --tags
|
||||||
|
@@ -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.6.8 3.7.3 2.6.9 3.3.7 2.7.16 3.2.6 3.1.5 3.4.8'
|
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'
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
PYTHON_VERSION=3.6.8
|
PYTHON_VERSION=3.7.6
|
||||||
|
|
||||||
# FIXME put some of the below in a common routine
|
# FIXME put some of the below in a common routine
|
||||||
function finish {
|
function finish {
|
||||||
@@ -20,3 +20,4 @@ cd $fulldir/..
|
|||||||
(cd ../python-xdis && git checkout master && pyenv local $PYTHON_VERSION) && git pull && \
|
(cd ../python-xdis && git checkout master && pyenv local $PYTHON_VERSION) && git pull && \
|
||||||
git checkout master && pyenv local $PYTHON_VERSION && git pull
|
git checkout master && pyenv local $PYTHON_VERSION && git pull
|
||||||
cd $owd
|
cd $owd
|
||||||
|
rm -v */.python-version || true
|
||||||
|
@@ -14,3 +14,4 @@ cd $fulldir/..
|
|||||||
(cd ../python-xdis && git checkout python-2.4 && pyenv local $PYTHON_VERSION) && git pull && \
|
(cd ../python-xdis && git checkout python-2.4 && pyenv local $PYTHON_VERSION) && git pull && \
|
||||||
git checkout python-2.4 && pyenv local $PYTHON_VERSION && git pull
|
git checkout python-2.4 && pyenv local $PYTHON_VERSION && git pull
|
||||||
cd $owd
|
cd $owd
|
||||||
|
rm -v */.python-version || true
|
||||||
|
@@ -61,7 +61,7 @@ build_script:
|
|||||||
|
|
||||||
test_script:
|
test_script:
|
||||||
# Run the project tests
|
# Run the project tests
|
||||||
- "%CMD_IN_ENV% python test/test_pyenvlib.py --native --weak-verify"
|
- "%CMD_IN_ENV% python test/test_pyenvlib.py --native --syntax-verify"
|
||||||
|
|
||||||
after_test:
|
after_test:
|
||||||
# If tests are successful, create binary packages for the project.
|
# If tests are successful, create binary packages for the project.
|
||||||
|
@@ -1,7 +1,11 @@
|
|||||||
PHONY=check test pytest
|
PHONY=check test pytest
|
||||||
|
SHELL=/bin/bash
|
||||||
|
|
||||||
PYTHON ?= python
|
PYTHON ?= python
|
||||||
|
|
||||||
#: Run all tests
|
#: Run all tests
|
||||||
test check pytest:
|
test check pytest:
|
||||||
py.test
|
@PYTHON_VERSION=`$(PYTHON) -V 2>&1 | cut -d ' ' -f 2 | cut -d'.' -f1,2`; \
|
||||||
|
if [[ $$PYTHON_VERSION > 3.2 ]] || [[ $$PYTHON_VERSION == 2.7 ]] || [[ $$PYTHON_VERSION == 2.6 ]]; then \
|
||||||
|
py.test; \
|
||||||
|
fi
|
||||||
|
@@ -1,78 +0,0 @@
|
|||||||
import sys
|
|
||||||
from uncompyle6 import PYTHON3
|
|
||||||
if PYTHON3:
|
|
||||||
from io import StringIO
|
|
||||||
minint = -sys.maxsize-1
|
|
||||||
maxint = sys.maxsize
|
|
||||||
else:
|
|
||||||
from StringIO import StringIO
|
|
||||||
minint = -sys.maxint-1
|
|
||||||
maxint = sys.maxint
|
|
||||||
from uncompyle6.semantics.helper import print_docstring
|
|
||||||
|
|
||||||
class PrintFake():
|
|
||||||
def __init__(self):
|
|
||||||
self.pending_newlines = 0
|
|
||||||
self.f = StringIO()
|
|
||||||
|
|
||||||
def write(self, *data):
|
|
||||||
if (len(data) == 0) or (len(data) == 1 and data[0] == ''):
|
|
||||||
return
|
|
||||||
out = ''.join((str(j) for j in data))
|
|
||||||
n = 0
|
|
||||||
for i in out:
|
|
||||||
if i == '\n':
|
|
||||||
n += 1
|
|
||||||
if n == len(out):
|
|
||||||
self.pending_newlines = max(self.pending_newlines, n)
|
|
||||||
return
|
|
||||||
elif n:
|
|
||||||
self.pending_newlines = max(self.pending_newlines, n)
|
|
||||||
out = out[n:]
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
|
|
||||||
if self.pending_newlines > 0:
|
|
||||||
self.f.write('\n'*self.pending_newlines)
|
|
||||||
self.pending_newlines = 0
|
|
||||||
|
|
||||||
for i in out[::-1]:
|
|
||||||
if i == '\n':
|
|
||||||
self.pending_newlines += 1
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
|
|
||||||
if self.pending_newlines:
|
|
||||||
out = out[:-self.pending_newlines]
|
|
||||||
self.f.write(out)
|
|
||||||
def println(self, *data):
|
|
||||||
if data and not(len(data) == 1 and data[0] == ''):
|
|
||||||
self.write(*data)
|
|
||||||
self.pending_newlines = max(self.pending_newlines, 1)
|
|
||||||
return
|
|
||||||
pass
|
|
||||||
|
|
||||||
def test_docstring():
|
|
||||||
|
|
||||||
for doc, expect in (
|
|
||||||
("Now is the time",
|
|
||||||
' """Now is the time"""'),
|
|
||||||
("""
|
|
||||||
Now is the time
|
|
||||||
""",
|
|
||||||
''' """
|
|
||||||
Now is the time
|
|
||||||
"""''')
|
|
||||||
|
|
||||||
# (r'''func placeholder - ' and with ("""\nstring\n """)''',
|
|
||||||
# """ r'''func placeholder - ' and with (\"\"\"\nstring\n\"\"\")'''"""),
|
|
||||||
# (r"""func placeholder - ' and with ('''\nstring\n''') and \"\"\"\nstring\n\"\"\" """,
|
|
||||||
# """ r\"\"\"func placeholder - ' and with ('''\nstring\n''') and \"\"\"\nstring\n\"\"\" \"\"\"""")
|
|
||||||
):
|
|
||||||
|
|
||||||
o = PrintFake()
|
|
||||||
# print(doc)
|
|
||||||
# print(expect)
|
|
||||||
print_docstring(o, ' ', doc)
|
|
||||||
assert expect == o.f.getvalue()
|
|
@@ -1,158 +0,0 @@
|
|||||||
# std
|
|
||||||
# test
|
|
||||||
from uncompyle6 import PYTHON_VERSION, deparse_code
|
|
||||||
import pytest
|
|
||||||
pytestmark = pytest.mark.skipif(PYTHON_VERSION <= 2.6,
|
|
||||||
reason='hypothesis needs 2.7 or later')
|
|
||||||
if PYTHON_VERSION > 2.6:
|
|
||||||
|
|
||||||
import hypothesis
|
|
||||||
from hypothesis import strategies as st
|
|
||||||
|
|
||||||
# uncompyle6
|
|
||||||
|
|
||||||
|
|
||||||
@st.composite
|
|
||||||
def expressions(draw):
|
|
||||||
# todo : would be nice to generate expressions using hypothesis however
|
|
||||||
# this is pretty involved so for now just use a corpus of expressions
|
|
||||||
# from which to select.
|
|
||||||
return draw(st.sampled_from((
|
|
||||||
'abc',
|
|
||||||
'len(items)',
|
|
||||||
'x + 1',
|
|
||||||
'lineno',
|
|
||||||
'container',
|
|
||||||
'self.attribute',
|
|
||||||
'self.method()',
|
|
||||||
# These expressions are failing, I think these are control
|
|
||||||
# flow problems rather than problems with FORMAT_VALUE,
|
|
||||||
# however I need to confirm this...
|
|
||||||
#'sorted(items, key=lambda x: x.name)',
|
|
||||||
#'func(*args, **kwargs)',
|
|
||||||
#'text or default',
|
|
||||||
#'43 if life_the_universe and everything else None'
|
|
||||||
)))
|
|
||||||
|
|
||||||
|
|
||||||
@st.composite
|
|
||||||
def format_specifiers(draw):
|
|
||||||
"""
|
|
||||||
Generate a valid format specifier using the rules:
|
|
||||||
|
|
||||||
format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]
|
|
||||||
fill ::= <any character>
|
|
||||||
align ::= "<" | ">" | "=" | "^"
|
|
||||||
sign ::= "+" | "-" | " "
|
|
||||||
width ::= integer
|
|
||||||
precision ::= integer
|
|
||||||
type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"
|
|
||||||
|
|
||||||
See https://docs.python.org/2/library/string.html
|
|
||||||
|
|
||||||
:param draw: Let hypothesis draw from other strategies.
|
|
||||||
|
|
||||||
:return: An example format_specifier.
|
|
||||||
"""
|
|
||||||
alphabet_strategy = st.characters(min_codepoint=ord('a'), max_codepoint=ord('z'))
|
|
||||||
fill = draw(st.one_of(alphabet_strategy, st.none()))
|
|
||||||
align = draw(st.sampled_from(list('<>=^')))
|
|
||||||
fill_align = (fill + align or '') if fill else ''
|
|
||||||
|
|
||||||
type_ = draw(st.sampled_from('bcdeEfFgGnosxX%'))
|
|
||||||
can_have_sign = type_ in 'deEfFgGnoxX%'
|
|
||||||
can_have_comma = type_ in 'deEfFgG%'
|
|
||||||
can_have_precision = type_ in 'fFgG'
|
|
||||||
can_have_pound = type_ in 'boxX%'
|
|
||||||
can_have_zero = type_ in 'oxX'
|
|
||||||
|
|
||||||
sign = draw(st.sampled_from(list('+- ') + [''])) if can_have_sign else ''
|
|
||||||
pound = draw(st.sampled_from(('#', '',))) if can_have_pound else ''
|
|
||||||
zero = draw(st.sampled_from(('0', '',))) if can_have_zero else ''
|
|
||||||
|
|
||||||
int_strategy = st.integers(min_value=1, max_value=1000)
|
|
||||||
|
|
||||||
width = draw(st.one_of(int_strategy, st.none()))
|
|
||||||
width = str(width) if width is not None else ''
|
|
||||||
|
|
||||||
comma = draw(st.sampled_from((',', '',))) if can_have_comma else ''
|
|
||||||
if can_have_precision:
|
|
||||||
precision = draw(st.one_of(int_strategy, st.none()))
|
|
||||||
precision = '.' + str(precision) if precision else ''
|
|
||||||
else:
|
|
||||||
precision = ''
|
|
||||||
|
|
||||||
return ''.join((fill_align, sign, pound, zero, width, comma, precision, type_,))
|
|
||||||
|
|
||||||
|
|
||||||
@st.composite
|
|
||||||
def fstrings(draw):
|
|
||||||
"""
|
|
||||||
Generate a valid f-string.
|
|
||||||
See https://www.python.org/dev/peps/pep-0498/#specification
|
|
||||||
|
|
||||||
:param draw: Let hypothsis draw from other strategies.
|
|
||||||
|
|
||||||
:return: A valid f-string.
|
|
||||||
"""
|
|
||||||
character_strategy = st.characters(
|
|
||||||
blacklist_characters='\r\n\'\\s{}',
|
|
||||||
min_codepoint=1,
|
|
||||||
max_codepoint=1000,
|
|
||||||
)
|
|
||||||
is_raw = draw(st.booleans())
|
|
||||||
integer_strategy = st.integers(min_value=0, max_value=3)
|
|
||||||
expression_count = draw(integer_strategy)
|
|
||||||
content = []
|
|
||||||
for _ in range(expression_count):
|
|
||||||
expression = draw(expressions())
|
|
||||||
conversion = draw(st.sampled_from(('', '!s', '!r', '!a',)))
|
|
||||||
has_specifier = draw(st.booleans())
|
|
||||||
specifier = ':' + draw(format_specifiers()) if has_specifier else ''
|
|
||||||
content.append('{{{}{}}}'.format(expression, conversion, specifier))
|
|
||||||
content.append(draw(st.text(character_strategy)))
|
|
||||||
content = ''.join(content)
|
|
||||||
return "f{}'{}'".format('r' if is_raw else '', content)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(PYTHON_VERSION != 3.6, reason='need Python 3.6')
|
|
||||||
@hypothesis.given(format_specifiers())
|
|
||||||
def test_format_specifiers(format_specifier):
|
|
||||||
"""Verify that format_specifiers generates valid specifiers"""
|
|
||||||
try:
|
|
||||||
exec('"{:' + format_specifier + '}".format(0)')
|
|
||||||
except ValueError as e:
|
|
||||||
if 'Unknown format code' not in str(e):
|
|
||||||
raise
|
|
||||||
|
|
||||||
|
|
||||||
def run_test(text):
|
|
||||||
hypothesis.assume(len(text))
|
|
||||||
hypothesis.assume("f'{" in text)
|
|
||||||
expr = text + '\n'
|
|
||||||
code = compile(expr, '<string>', 'single')
|
|
||||||
deparsed = deparse_code(PYTHON_VERSION, code, compile_mode='single')
|
|
||||||
recompiled = compile(deparsed.text, '<string>', 'single')
|
|
||||||
if recompiled != code:
|
|
||||||
print(recompiled)
|
|
||||||
print('================')
|
|
||||||
print(code)
|
|
||||||
print('----------------')
|
|
||||||
assert 'dis(' + deparsed.text.strip('\n') + ')' == 'dis(' + expr.strip('\n') + ')'
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(PYTHON_VERSION != 3.6, reason='need Python 3.6')
|
|
||||||
@hypothesis.given(fstrings())
|
|
||||||
def test_uncompyle_fstring(fstring):
|
|
||||||
"""Verify uncompyling fstring bytecode"""
|
|
||||||
run_test(fstring)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(PYTHON_VERSION != 3.6, reason='need Python 3.6+')
|
|
||||||
@pytest.mark.parametrize('fstring', [
|
|
||||||
"f'{abc}{abc!s}'",
|
|
||||||
"f'{abc}0'",
|
|
||||||
])
|
|
||||||
def test_uncompyle_direct(fstring):
|
|
||||||
"""useful for debugging"""
|
|
||||||
run_test(fstring)
|
|
@@ -1,185 +0,0 @@
|
|||||||
import string
|
|
||||||
from uncompyle6 import PYTHON_VERSION
|
|
||||||
import pytest
|
|
||||||
pytestmark = pytest.mark.skip(PYTHON_VERSION < 2.7,
|
|
||||||
reason="need at least Python 2.7")
|
|
||||||
|
|
||||||
if PYTHON_VERSION > 2.6:
|
|
||||||
from hypothesis import given, assume, example, settings, strategies as st
|
|
||||||
from validate import validate_uncompyle
|
|
||||||
from test_fstring import expressions
|
|
||||||
|
|
||||||
alpha = st.sampled_from(string.ascii_lowercase)
|
|
||||||
numbers = st.sampled_from(string.digits)
|
|
||||||
alphanum = st.sampled_from(string.ascii_lowercase + string.digits)
|
|
||||||
|
|
||||||
|
|
||||||
@st.composite
|
|
||||||
def function_calls(draw,
|
|
||||||
min_keyword_args=0, max_keyword_args=5,
|
|
||||||
min_positional_args=0, max_positional_args=5,
|
|
||||||
min_star_args=0, max_star_args=1,
|
|
||||||
min_double_star_args=0, max_double_star_args=1):
|
|
||||||
"""
|
|
||||||
Strategy factory for generating function calls.
|
|
||||||
|
|
||||||
:param draw: Callable which draws examples from other strategies.
|
|
||||||
|
|
||||||
:return: The function call text.
|
|
||||||
"""
|
|
||||||
st_positional_args = st.lists(
|
|
||||||
alpha,
|
|
||||||
min_size=min_positional_args,
|
|
||||||
max_size=max_positional_args
|
|
||||||
)
|
|
||||||
st_keyword_args = st.lists(
|
|
||||||
alpha,
|
|
||||||
min_size=min_keyword_args,
|
|
||||||
max_size=max_keyword_args
|
|
||||||
)
|
|
||||||
st_star_args = st.lists(
|
|
||||||
alpha,
|
|
||||||
min_size=min_star_args,
|
|
||||||
max_size=max_star_args
|
|
||||||
)
|
|
||||||
st_double_star_args = st.lists(
|
|
||||||
alpha,
|
|
||||||
min_size=min_double_star_args,
|
|
||||||
max_size=max_double_star_args
|
|
||||||
)
|
|
||||||
|
|
||||||
positional_args = draw(st_positional_args)
|
|
||||||
keyword_args = draw(st_keyword_args)
|
|
||||||
st_values = st.lists(
|
|
||||||
expressions(),
|
|
||||||
min_size=len(keyword_args),
|
|
||||||
max_size=len(keyword_args)
|
|
||||||
)
|
|
||||||
keyword_args = [
|
|
||||||
x + '=' + e
|
|
||||||
for x, e in
|
|
||||||
zip(keyword_args, draw(st_values))
|
|
||||||
]
|
|
||||||
star_args = ['*' + x for x in draw(st_star_args)]
|
|
||||||
double_star_args = ['**' + x for x in draw(st_double_star_args)]
|
|
||||||
|
|
||||||
arguments = positional_args + keyword_args + star_args + double_star_args
|
|
||||||
draw(st.randoms()).shuffle(arguments)
|
|
||||||
arguments = ','.join(arguments)
|
|
||||||
|
|
||||||
function_call = 'fn({arguments})'.format(arguments=arguments)
|
|
||||||
try:
|
|
||||||
# TODO: Figure out the exact rules for ordering of positional, keyword,
|
|
||||||
# star args, double star args and in which versions the various
|
|
||||||
# types of arguments are supported so we don't need to check that the
|
|
||||||
# expression compiles like this.
|
|
||||||
compile(function_call, '<string>', 'single')
|
|
||||||
except:
|
|
||||||
assume(False)
|
|
||||||
return function_call
|
|
||||||
|
|
||||||
|
|
||||||
def test_function_no_args():
|
|
||||||
validate_uncompyle("fn()")
|
|
||||||
|
|
||||||
@pytest.mark.skipif(PYTHON_VERSION < 2.7,
|
|
||||||
reason="need at least Python 2.7")
|
|
||||||
def isolated_function_calls(which):
|
|
||||||
"""
|
|
||||||
Returns a strategy for generating function calls, but isolated to
|
|
||||||
particular types of arguments, for example only positional arguments.
|
|
||||||
|
|
||||||
This can help reason about debugging errors in specific types of function
|
|
||||||
calls.
|
|
||||||
|
|
||||||
:param which: One of 'keyword', 'positional', 'star', 'double_star'
|
|
||||||
|
|
||||||
:return: Strategy for generating an function call isolated to specific
|
|
||||||
argument types.
|
|
||||||
"""
|
|
||||||
kwargs = dict(
|
|
||||||
max_keyword_args=0,
|
|
||||||
max_positional_args=0,
|
|
||||||
max_star_args=0,
|
|
||||||
max_double_star_args=0,
|
|
||||||
)
|
|
||||||
kwargs['_'.join(('min', which, 'args'))] = 1
|
|
||||||
kwargs['_'.join(('max', which, 'args'))] = 5 if 'star' not in which else 1
|
|
||||||
return function_calls(**kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
with settings(max_examples=25):
|
|
||||||
|
|
||||||
@pytest.mark.skipif(PYTHON_VERSION < 2.7,
|
|
||||||
reason="need at least Python 2.7")
|
|
||||||
@given(isolated_function_calls('positional'))
|
|
||||||
@example("fn(0)")
|
|
||||||
def test_function_positional_only(expr):
|
|
||||||
validate_uncompyle(expr)
|
|
||||||
|
|
||||||
@pytest.mark.skipif(PYTHON_VERSION < 2.7,
|
|
||||||
reason="need at least Python 2.7")
|
|
||||||
@given(isolated_function_calls('keyword'))
|
|
||||||
@example("fn(a=0)")
|
|
||||||
def test_function_call_keyword_only(expr):
|
|
||||||
validate_uncompyle(expr)
|
|
||||||
|
|
||||||
@pytest.mark.skipif(PYTHON_VERSION < 2.7,
|
|
||||||
reason="need at least Python 2.7")
|
|
||||||
@given(isolated_function_calls('star'))
|
|
||||||
@example("fn(*items)")
|
|
||||||
def test_function_call_star_only(expr):
|
|
||||||
validate_uncompyle(expr)
|
|
||||||
|
|
||||||
@pytest.mark.skipif(PYTHON_VERSION < 2.7,
|
|
||||||
reason="need at least Python 2.7")
|
|
||||||
@given(isolated_function_calls('double_star'))
|
|
||||||
@example("fn(**{})")
|
|
||||||
def test_function_call_double_star_only(expr):
|
|
||||||
validate_uncompyle(expr)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail()
|
|
||||||
def test_BUILD_CONST_KEY_MAP_BUILD_MAP_UNPACK_WITH_CALL_BUILD_TUPLE_CALL_FUNCTION_EX():
|
|
||||||
validate_uncompyle("fn(w=0,m=0,**v)")
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail()
|
|
||||||
def test_BUILD_MAP_BUILD_MAP_UNPACK_WITH_CALL_BUILD_TUPLE_CALL_FUNCTION_EX():
|
|
||||||
validate_uncompyle("fn(a=0,**g)")
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail()
|
|
||||||
def test_CALL_FUNCTION_EX():
|
|
||||||
validate_uncompyle("fn(*g,**j)")
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail()
|
|
||||||
def test_BUILD_MAP_CALL_FUNCTION_EX():
|
|
||||||
validate_uncompyle("fn(*z,u=0)")
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail()
|
|
||||||
def test_BUILD_TUPLE_CALL_FUNCTION_EX():
|
|
||||||
validate_uncompyle("fn(**a)")
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail()
|
|
||||||
def test_BUILD_MAP_BUILD_TUPLE_BUILD_TUPLE_UNPACK_WITH_CALL_CALL_FUNCTION_EX():
|
|
||||||
validate_uncompyle("fn(b,b,b=0,*a)")
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail()
|
|
||||||
def test_BUILD_TUPLE_BUILD_TUPLE_UNPACK_WITH_CALL_CALL_FUNCTION_EX():
|
|
||||||
validate_uncompyle("fn(*c,v)")
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail()
|
|
||||||
def test_BUILD_CONST_KEY_MAP_CALL_FUNCTION_EX():
|
|
||||||
validate_uncompyle("fn(i=0,y=0,*p)")
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skip(reason='skipping property based test until all individual tests are passing')
|
|
||||||
@given(function_calls())
|
|
||||||
def test_function_call(function_call):
|
|
||||||
validate_uncompyle(function_call)
|
|
@@ -1,112 +1,146 @@
|
|||||||
import re
|
import re
|
||||||
from uncompyle6 import PYTHON_VERSION, PYTHON3, IS_PYPY # , PYTHON_VERSION
|
from uncompyle6 import PYTHON_VERSION, PYTHON3, IS_PYPY # , PYTHON_VERSION
|
||||||
from uncompyle6.parser import get_python_parser, python_parser
|
from uncompyle6.parser import get_python_parser, python_parser
|
||||||
from uncompyle6.scanner import get_scanner
|
from uncompyle6.scanner import get_scanner
|
||||||
|
|
||||||
def test_grammar():
|
|
||||||
|
|
||||||
|
def test_grammar():
|
||||||
def check_tokens(tokens, opcode_set):
|
def check_tokens(tokens, opcode_set):
|
||||||
remain_tokens = set(tokens) - opcode_set
|
remain_tokens = set(tokens) - opcode_set
|
||||||
remain_tokens = set([re.sub(r'_\d+$','', t) for t in remain_tokens])
|
remain_tokens = set([re.sub(r"_\d+$", "", t) for t in remain_tokens])
|
||||||
remain_tokens = set([re.sub('_CONT$','', t) for t in remain_tokens])
|
remain_tokens = set([re.sub("_CONT$", "", t) for t in remain_tokens])
|
||||||
|
remain_tokens = set([re.sub("LOAD_CODE$", "", t) for t in remain_tokens])
|
||||||
remain_tokens = set(remain_tokens) - opcode_set
|
remain_tokens = set(remain_tokens) - opcode_set
|
||||||
assert remain_tokens == set([]), \
|
assert remain_tokens == set([]), "Remaining tokens %s\n====\n%s" % (
|
||||||
"Remaining tokens %s\n====\n%s" % (remain_tokens, p.dump_grammar())
|
remain_tokens,
|
||||||
|
p.dump_grammar(),
|
||||||
|
)
|
||||||
|
|
||||||
p = get_python_parser(PYTHON_VERSION, is_pypy=IS_PYPY)
|
p = get_python_parser(PYTHON_VERSION, is_pypy=IS_PYPY)
|
||||||
(lhs, rhs, tokens,
|
(lhs, rhs, tokens, right_recursive, dup_rhs) = p.check_sets()
|
||||||
right_recursive, dup_rhs) = p.check_sets()
|
|
||||||
|
|
||||||
# We have custom rules that create the below
|
# We have custom rules that create the below
|
||||||
expect_lhs = set(['pos_arg', 'attribute'])
|
expect_lhs = set(["pos_arg"])
|
||||||
|
|
||||||
if PYTHON_VERSION < 3.8:
|
if PYTHON_VERSION < 3.8:
|
||||||
expect_lhs.add('get_iter')
|
if PYTHON_VERSION < 3.7:
|
||||||
|
expect_lhs.add("attribute")
|
||||||
|
|
||||||
|
expect_lhs.add("get_iter")
|
||||||
|
|
||||||
unused_rhs = set(['list', 'mkfunc',
|
if PYTHON_VERSION > 3.7 or PYTHON_VERSION < 3.0:
|
||||||
'mklambda',
|
expect_lhs.add("stmts_opt")
|
||||||
'unpack',])
|
else:
|
||||||
|
expect_lhs.add("async_with_as_stmt")
|
||||||
|
expect_lhs.add("async_with_stmt")
|
||||||
|
|
||||||
expect_right_recursive = set([('designList',
|
unused_rhs = set(["list", "mkfunc", "mklambda", "unpack"])
|
||||||
('store', 'DUP_TOP', 'designList'))])
|
|
||||||
|
|
||||||
if PYTHON_VERSION < 3.7:
|
expect_right_recursive = set([("designList", ("store", "DUP_TOP", "designList"))])
|
||||||
unused_rhs.add('call')
|
|
||||||
|
if PYTHON_VERSION <= 3.6:
|
||||||
|
unused_rhs.add("call")
|
||||||
|
|
||||||
if PYTHON_VERSION > 2.6:
|
if PYTHON_VERSION > 2.6:
|
||||||
expect_lhs.add('kvlist')
|
expect_lhs.add("kvlist")
|
||||||
expect_lhs.add('kv3')
|
expect_lhs.add("kv3")
|
||||||
unused_rhs.add('dict')
|
unused_rhs.add("dict")
|
||||||
|
|
||||||
|
if PYTHON_VERSION < 3.7 and PYTHON_VERSION != 2.7:
|
||||||
|
# NOTE: this may disappear
|
||||||
|
expect_lhs.add("except_handler_else")
|
||||||
|
|
||||||
if PYTHON3:
|
if PYTHON3:
|
||||||
expect_lhs.add('load_genexpr')
|
expect_lhs.add("load_genexpr")
|
||||||
|
|
||||||
unused_rhs = unused_rhs.union(set("""
|
unused_rhs = unused_rhs.union(
|
||||||
|
set(
|
||||||
|
"""
|
||||||
except_pop_except generator_exp
|
except_pop_except generator_exp
|
||||||
""".split()))
|
""".split()
|
||||||
|
)
|
||||||
|
)
|
||||||
if PYTHON_VERSION >= 3.0:
|
if PYTHON_VERSION >= 3.0:
|
||||||
expect_lhs.add("annotate_arg")
|
if PYTHON_VERSION < 3.7:
|
||||||
expect_lhs.add("annotate_tuple")
|
expect_lhs.add("annotate_arg")
|
||||||
unused_rhs.add("mkfunc_annotate")
|
expect_lhs.add("annotate_tuple")
|
||||||
|
unused_rhs.add("mkfunc_annotate")
|
||||||
|
|
||||||
unused_rhs.add("dict_comp")
|
unused_rhs.add("dict_comp")
|
||||||
unused_rhs.add("classdefdeco1")
|
unused_rhs.add("classdefdeco1")
|
||||||
unused_rhs.add("tryelsestmtl")
|
unused_rhs.add("tryelsestmtl")
|
||||||
if PYTHON_VERSION >= 3.5:
|
if PYTHON_VERSION >= 3.5:
|
||||||
expect_right_recursive.add((('l_stmts',
|
expect_right_recursive.add(
|
||||||
('lastl_stmt', 'come_froms', 'l_stmts'))))
|
(("l_stmts", ("lastl_stmt", "come_froms", "l_stmts")))
|
||||||
pass
|
)
|
||||||
elif 3.0 < PYTHON_VERSION < 3.3:
|
|
||||||
expect_right_recursive.add((('l_stmts',
|
|
||||||
('lastl_stmt', 'COME_FROM', 'l_stmts'))))
|
|
||||||
pass
|
pass
|
||||||
pass
|
pass
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
expect_lhs.add('kwarg')
|
expect_lhs.add("kwarg")
|
||||||
|
|
||||||
assert expect_lhs == set(lhs)
|
|
||||||
|
|
||||||
# FIXME
|
# FIXME
|
||||||
if PYTHON_VERSION != 3.8:
|
if PYTHON_VERSION < 3.8:
|
||||||
|
assert expect_lhs == set(lhs)
|
||||||
assert unused_rhs == set(rhs)
|
assert unused_rhs == set(rhs)
|
||||||
|
|
||||||
assert expect_right_recursive == right_recursive
|
assert expect_right_recursive == right_recursive
|
||||||
|
|
||||||
expect_dup_rhs = frozenset([('COME_FROM',), ('CONTINUE',), ('JUMP_ABSOLUTE',),
|
expect_dup_rhs = frozenset(
|
||||||
('LOAD_CONST',),
|
[
|
||||||
('JUMP_BACK',), ('JUMP_FORWARD',)])
|
("COME_FROM",),
|
||||||
|
("CONTINUE",),
|
||||||
|
("JUMP_ABSOLUTE",),
|
||||||
|
("LOAD_CONST",),
|
||||||
|
("JUMP_BACK",),
|
||||||
|
("JUMP_FORWARD",),
|
||||||
|
]
|
||||||
|
)
|
||||||
reduced_dup_rhs = dict((k, dup_rhs[k]) for k in dup_rhs if k not in expect_dup_rhs)
|
reduced_dup_rhs = dict((k, dup_rhs[k]) for k in dup_rhs if k not in expect_dup_rhs)
|
||||||
for k in reduced_dup_rhs:
|
if reduced_dup_rhs:
|
||||||
print(k, reduced_dup_rhs[k])
|
print("\nPossible duplicate RHS that might be folded, into one of the LHS symbols")
|
||||||
|
for k in reduced_dup_rhs:
|
||||||
|
print(k, reduced_dup_rhs[k])
|
||||||
# assert not reduced_dup_rhs, reduced_dup_rhs
|
# assert not reduced_dup_rhs, reduced_dup_rhs
|
||||||
|
|
||||||
s = get_scanner(PYTHON_VERSION, IS_PYPY)
|
s = get_scanner(PYTHON_VERSION, IS_PYPY)
|
||||||
ignore_set = set(
|
ignore_set = set(
|
||||||
"""
|
"""
|
||||||
JUMP_BACK CONTINUE
|
JUMP_BACK CONTINUE
|
||||||
COME_FROM COME_FROM_EXCEPT
|
COME_FROM COME_FROM_EXCEPT
|
||||||
COME_FROM_EXCEPT_CLAUSE
|
COME_FROM_EXCEPT_CLAUSE
|
||||||
COME_FROM_LOOP COME_FROM_WITH
|
COME_FROM_LOOP COME_FROM_WITH
|
||||||
COME_FROM_FINALLY ELSE
|
COME_FROM_FINALLY ELSE
|
||||||
LOAD_GENEXPR LOAD_ASSERT LOAD_SETCOMP LOAD_DICTCOMP
|
LOAD_GENEXPR LOAD_ASSERT LOAD_SETCOMP LOAD_DICTCOMP LOAD_STR LOAD_CODE
|
||||||
LAMBDA_MARKER
|
LAMBDA_MARKER
|
||||||
RETURN_END_IF RETURN_END_IF_LAMBDA RETURN_VALUE_LAMBDA RETURN_LAST
|
RETURN_END_IF RETURN_END_IF_LAMBDA RETURN_VALUE_LAMBDA RETURN_LAST
|
||||||
""".split())
|
""".split()
|
||||||
|
)
|
||||||
if 2.6 <= PYTHON_VERSION <= 2.7:
|
if 2.6 <= PYTHON_VERSION <= 2.7:
|
||||||
opcode_set = set(s.opc.opname).union(ignore_set)
|
opcode_set = set(s.opc.opname).union(ignore_set)
|
||||||
if PYTHON_VERSION == 2.6:
|
if PYTHON_VERSION == 2.6:
|
||||||
opcode_set.add("THEN")
|
opcode_set.add("THEN")
|
||||||
check_tokens(tokens, opcode_set)
|
check_tokens(tokens, opcode_set)
|
||||||
elif PYTHON_VERSION == 3.4:
|
elif PYTHON_VERSION == 3.4:
|
||||||
ignore_set.add('LOAD_CLASSNAME')
|
ignore_set.add("LOAD_CLASSNAME")
|
||||||
ignore_set.add('STORE_LOCALS')
|
ignore_set.add("STORE_LOCALS")
|
||||||
opcode_set = set(s.opc.opname).union(ignore_set)
|
opcode_set = set(s.opc.opname).union(ignore_set)
|
||||||
check_tokens(tokens, opcode_set)
|
check_tokens(tokens, opcode_set)
|
||||||
|
|
||||||
|
|
||||||
def test_dup_rule():
|
def test_dup_rule():
|
||||||
import inspect
|
import inspect
|
||||||
python_parser(PYTHON_VERSION, inspect.currentframe().f_code,
|
|
||||||
is_pypy=IS_PYPY,
|
python_parser(
|
||||||
parser_debug={
|
PYTHON_VERSION,
|
||||||
'dups': True, 'transition': False, 'reduce': False,
|
inspect.currentframe().f_code,
|
||||||
'rules': False, 'errorstack': None, 'context': True})
|
is_pypy=IS_PYPY,
|
||||||
|
parser_debug={
|
||||||
|
"dups": True,
|
||||||
|
"transition": False,
|
||||||
|
"reduce": False,
|
||||||
|
"rules": False,
|
||||||
|
"errorstack": None,
|
||||||
|
"context": True,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
@@ -15,7 +15,7 @@ else:
|
|||||||
def iteritems(d):
|
def iteritems(d):
|
||||||
return d.iteritems()
|
return d.iteritems()
|
||||||
|
|
||||||
from uncompyle6.semantics.pysource import SourceWalker as SourceWalker
|
from uncompyle6.semantics.pysource import (SourceWalker, deparse_code2str)
|
||||||
|
|
||||||
def test_template_engine():
|
def test_template_engine():
|
||||||
s = StringIO()
|
s = StringIO()
|
||||||
@@ -185,3 +185,11 @@ def test_tables():
|
|||||||
assert arg == len(entry), (
|
assert arg == len(entry), (
|
||||||
"%s[%s] arg %d should be length of entry %d. Full entry: %s" %
|
"%s[%s] arg %d should be length of entry %d. Full entry: %s" %
|
||||||
(name, k, arg, len(entry), entry))
|
(name, k, arg, len(entry), entry))
|
||||||
|
|
||||||
|
def test_deparse_code2str():
|
||||||
|
def deparse_test(co):
|
||||||
|
"This is a docstring"
|
||||||
|
s = deparse_code2str(co, debug_opts={"asm": "after", "tree": True})
|
||||||
|
assert s
|
||||||
|
return
|
||||||
|
deparse_test(deparse_test.__code__)
|
@@ -1,23 +1,25 @@
|
|||||||
|
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() == expect
|
||||||
|
|
||||||
# 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)
|
||||||
assert t2 == t
|
assert t2 == t
|
||||||
|
|
||||||
|
|
||||||
# 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 0 False'
|
expect = " 1 LOAD_CONST False"
|
||||||
assert t.format() == expect
|
assert t.format() == expect
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
|
if __name__ == "__main__":
|
||||||
test_token()
|
test_token()
|
||||||
|
16
pytest/testdata/if-2.7.right
vendored
16
pytest/testdata/if-2.7.right
vendored
@@ -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'
|
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'
|
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 0 None
|
15 LOAD_CONST None
|
||||||
18 RETURN_VALUE
|
18 RETURN_VALUE
|
||||||
|
20
pytest/testdata/ifelse-2.7.right
vendored
20
pytest/testdata/ifelse-2.7.right
vendored
@@ -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'
|
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 0 1
|
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 1 2
|
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 2 None
|
21 LOAD_CONST None
|
||||||
24 RETURN_VALUE
|
24 RETURN_VALUE
|
||||||
|
@@ -1,16 +1,20 @@
|
|||||||
# future
|
# future
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
# std
|
# std
|
||||||
import os
|
import os
|
||||||
import difflib
|
import difflib
|
||||||
import subprocess
|
import subprocess
|
||||||
import tempfile
|
import tempfile
|
||||||
import functools
|
import functools
|
||||||
|
|
||||||
# uncompyle6 / xdis
|
# uncompyle6 / xdis
|
||||||
from uncompyle6 import PYTHON_VERSION, PYTHON3, IS_PYPY, deparse_code
|
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.bytecode import Bytecode
|
||||||
from xdis.main import 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)
|
||||||
import six
|
import six
|
||||||
@@ -20,6 +24,7 @@ if PYTHON3:
|
|||||||
else:
|
else:
|
||||||
from StringIO import StringIO
|
from StringIO import StringIO
|
||||||
|
|
||||||
|
|
||||||
def _dis_to_text(co):
|
def _dis_to_text(co):
|
||||||
return Bytecode(co).dis()
|
return Bytecode(co).dis()
|
||||||
|
|
||||||
@@ -33,36 +38,32 @@ def print_diff(original, uncompyled):
|
|||||||
:param original: Text describing the original code object.
|
:param original: Text describing the original code object.
|
||||||
:param uncompyled: Text describing the uncompyled code object.
|
:param uncompyled: Text describing the uncompyled code object.
|
||||||
"""
|
"""
|
||||||
original_lines = original.split('\n')
|
original_lines = original.split("\n")
|
||||||
uncompyled_lines = uncompyled.split('\n')
|
uncompyled_lines = uncompyled.split("\n")
|
||||||
args = original_lines, uncompyled_lines, 'original', 'uncompyled'
|
args = original_lines, uncompyled_lines, "original", "uncompyled"
|
||||||
try:
|
try:
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
|
|
||||||
diff = difflib.HtmlDiff().make_file(*args)
|
diff = difflib.HtmlDiff().make_file(*args)
|
||||||
diff = BeautifulSoup(diff, "html.parser")
|
diff = BeautifulSoup(diff, "html.parser")
|
||||||
diff.select_one('table[summary="Legends"]').extract()
|
diff.select_one('table[summary="Legends"]').extract()
|
||||||
except ImportError:
|
except ImportError:
|
||||||
print('\nTo display diff highlighting run:\n pip install BeautifulSoup4')
|
print("\nTo display diff highlighting run:\n pip install BeautifulSoup4")
|
||||||
diff = difflib.HtmlDiff().make_table(*args)
|
diff = difflib.HtmlDiff().make_table(*args)
|
||||||
|
|
||||||
with tempfile.NamedTemporaryFile(delete=False) as f:
|
with tempfile.NamedTemporaryFile(delete=False) as f:
|
||||||
f.write(str(diff).encode('utf-8'))
|
f.write(str(diff).encode("utf-8"))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
print()
|
print()
|
||||||
html = subprocess.check_output([
|
html = subprocess.check_output(
|
||||||
'elinks',
|
["elinks", "-dump", "-no-references", "-dump-color-mode", "1", f.name]
|
||||||
'-dump',
|
).decode("utf-8")
|
||||||
'-no-references',
|
|
||||||
'-dump-color-mode',
|
|
||||||
'1',
|
|
||||||
f.name,
|
|
||||||
]).decode('utf-8')
|
|
||||||
print(html)
|
print(html)
|
||||||
except:
|
except:
|
||||||
print('\nFor side by side diff install elinks')
|
print("\nFor side by side diff install elinks")
|
||||||
diff = difflib.Differ().compare(original_lines, uncompyled_lines)
|
diff = difflib.Differ().compare(original_lines, uncompyled_lines)
|
||||||
print('\n'.join(diff))
|
print("\n".join(diff))
|
||||||
finally:
|
finally:
|
||||||
os.unlink(f.name)
|
os.unlink(f.name)
|
||||||
|
|
||||||
@@ -80,18 +81,19 @@ def are_instructions_equal(i1, i2):
|
|||||||
|
|
||||||
:return: True if the two instructions are approximately equal, otherwise False.
|
:return: True if the two instructions are approximately equal, otherwise False.
|
||||||
"""
|
"""
|
||||||
result = (1 == 1
|
result = (
|
||||||
|
1 == 1
|
||||||
and i1.opname == i2.opname
|
and i1.opname == i2.opname
|
||||||
and i1.opcode == i2.opcode
|
and i1.opcode == i2.opcode
|
||||||
and i1.arg == i2.arg
|
and i1.arg == i2.arg
|
||||||
# ignore differences due to code objects
|
# ignore differences due to code objects
|
||||||
# TODO : Better way of ignoring address
|
# TODO : Better way of ignoring address
|
||||||
and (i1.argval == i2.argval or '<code object' in str(i1.argval))
|
and (i1.argval == i2.argval or "<code object" in str(i1.argval))
|
||||||
# TODO : Should probably recurse to check code objects
|
# TODO : Should probably recurse to check code objects
|
||||||
and (i1.argrepr == i2.argrepr or '<code object' in i1.argrepr)
|
and (i1.argrepr == i2.argrepr or "<code object" in i1.argrepr)
|
||||||
and i1.offset == i2.offset
|
and i1.offset == i2.offset
|
||||||
# ignore differences in line numbers
|
# ignore differences in line numbers
|
||||||
#and i1.starts_line
|
# and i1.starts_line
|
||||||
and i1.is_jump_target == i2.is_jump_target
|
and i1.is_jump_target == i2.is_jump_target
|
||||||
)
|
)
|
||||||
return result
|
return result
|
||||||
@@ -115,22 +117,21 @@ def are_code_objects_equal(co1, co2):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def validate_uncompyle(text, mode='exec'):
|
def validate_uncompyle(text, mode="exec"):
|
||||||
"""
|
"""
|
||||||
Validate decompilation of the given source code.
|
Validate decompilation of the given source code.
|
||||||
|
|
||||||
:param text: Source to validate decompilation of.
|
:param text: Source to validate decompilation of.
|
||||||
"""
|
"""
|
||||||
original_code = compile(text, '<string>', mode)
|
original_code = compile(text, "<string>", mode)
|
||||||
original_dis = _dis_to_text(original_code)
|
original_dis = _dis_to_text(original_code)
|
||||||
original_text = text
|
original_text = text
|
||||||
|
|
||||||
deparsed = deparse_code(PYTHON_VERSION, original_code,
|
deparsed = code_deparse(
|
||||||
compile_mode=mode,
|
original_code, out=six.StringIO(), version=PYTHON_VERSION, compile_mode=mode
|
||||||
out=six.StringIO(),
|
)
|
||||||
is_pypy=IS_PYPY)
|
|
||||||
uncompyled_text = deparsed.text
|
uncompyled_text = deparsed.text
|
||||||
uncompyled_code = compile(uncompyled_text, '<string>', 'exec')
|
uncompyled_code = compile(uncompyled_text, "<string>", "exec")
|
||||||
|
|
||||||
if not are_code_objects_equal(uncompyled_code, original_code):
|
if not are_code_objects_equal(uncompyled_code, original_code):
|
||||||
|
|
||||||
@@ -138,15 +139,17 @@ def validate_uncompyle(text, mode='exec'):
|
|||||||
|
|
||||||
def output(text, dis):
|
def output(text, dis):
|
||||||
width = 60
|
width = 60
|
||||||
return '\n\n'.join([
|
return "\n\n".join(
|
||||||
' SOURCE CODE '.center(width, '#'),
|
[
|
||||||
text.strip(),
|
" SOURCE CODE ".center(width, "#"),
|
||||||
' BYTECODE '.center(width, '#'),
|
text.strip(),
|
||||||
dis
|
" BYTECODE ".center(width, "#"),
|
||||||
])
|
dis,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
original = output(original_text, original_dis)
|
original = output(original_text, original_dis)
|
||||||
uncompyled = output(uncompyled_text, uncompyled_dis)
|
uncompyled = output(uncompyled_text, uncompyled_dis)
|
||||||
print_diff(original, uncompyled)
|
print_diff(original, uncompyled)
|
||||||
|
|
||||||
assert 'original' == 'uncompyled'
|
assert "original" == "uncompyled"
|
||||||
|
@@ -1,2 +1,3 @@
|
|||||||
flake8
|
flake8
|
||||||
hypothesis<=3.0.0
|
six
|
||||||
|
pytest==3.2.5 # for 2.7 < PYTHON_VERSION <= 3.2 use pytest 2.9.2; for 3.1 2.10
|
||||||
|
12
setup.cfg
12
setup.cfg
@@ -1,11 +1,11 @@
|
|||||||
[bdist_rpm]
|
[bdist_rpm]
|
||||||
release = 1
|
release = 1
|
||||||
packager = Mysterie <kajusska@gmail.com>
|
packager = rocky <rb@dustyfeet.com>
|
||||||
doc_files = README
|
doc_files = README
|
||||||
# CHANGES.txt
|
|
||||||
# USAGE.txt
|
|
||||||
# doc/
|
|
||||||
# examples/
|
|
||||||
|
|
||||||
[bdist_wheel]
|
[bdist_wheel]
|
||||||
universal=1
|
|
||||||
|
[egg_info]
|
||||||
|
tag_build =
|
||||||
|
tag_date = 0
|
||||||
|
|
||||||
|
5
setup.py
5
setup.py
@@ -4,8 +4,8 @@ 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, 8)):
|
if not ((2, 6) <= SYS_VERSION <= (3, 9)):
|
||||||
mess = "Python Release 2.6 .. 3.8 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 += ("\nFor your Python, version %s, use the python-2.4 code/branch." %
|
||||||
sys.version[0:3])
|
sys.version[0:3])
|
||||||
@@ -32,6 +32,7 @@ setup(
|
|||||||
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",
|
||||||
name = modname,
|
name = modname,
|
||||||
packages = find_packages(),
|
packages = find_packages(),
|
||||||
py_modules = py_modules,
|
py_modules = py_modules,
|
||||||
|
2
test/.gitignore
vendored
2
test/.gitignore
vendored
@@ -1 +1,3 @@
|
|||||||
|
/.coverage
|
||||||
|
/.python-version
|
||||||
/nohup.out
|
/nohup.out
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
PHONY=check clean dist distclean test test-unit test-functional rmChangeLog clean_pyc nosetests \
|
PHONY=check clean dist distclean test test-unit test-functional rmChangeLog clean_pyc nosetests \
|
||||||
check-bytecode-1 check-bytecode-1.3 check-bytecode-1.4 check-bytecode-1.5 \
|
check-bytecode-1.0 check-bytecode-1.1 check-bytecode-1.2 check-bytecode-1.3 \
|
||||||
|
check-bytecode-1 check-bytecode-1.4 check-bytecode-1.5 check-bytecode-1.6 \
|
||||||
check-bytecode-2 check-bytecode-3 check-bytecode-3-short \
|
check-bytecode-2 check-bytecode-3 check-bytecode-3-short \
|
||||||
check-bytecode-2.2 check-byteocde-2.3 check-bytecode-2.4 \
|
check-bytecode-2.2 check-byteocde-2.3 check-bytecode-2.4 \
|
||||||
check-short check-2.6 check-2.7 check-3.0 check-3.1 check-3.2 check-3.3 \
|
check-short check-2.6 check-2.7 check-3.0 check-3.1 check-3.2 check-3.3 \
|
||||||
@@ -22,7 +23,7 @@ COVER_DIR=../tmp/grammar-cover
|
|||||||
# Run short tests
|
# Run short tests
|
||||||
check-short:
|
check-short:
|
||||||
@$(PYTHON) -V && PYTHON_VERSION=`$(PYTHON) -V 2>&1 | cut -d ' ' -f 2 | cut -d'.' -f1,2`; \
|
@$(PYTHON) -V && PYTHON_VERSION=`$(PYTHON) -V 2>&1 | cut -d ' ' -f 2 | cut -d'.' -f1,2`; \
|
||||||
$(MAKE) check-bytecode-short
|
$(MAKE) check-bytecode-$${PYTHON_VERSION}
|
||||||
|
|
||||||
# Run all tests
|
# Run all tests
|
||||||
check:
|
check:
|
||||||
@@ -34,47 +35,47 @@ check-2.6 check-2.7: check-bytecode-2 check-bytecode-3 check-bytecode-1 check-na
|
|||||||
#: Run working tests from Python 3.0
|
#: Run working tests from Python 3.0
|
||||||
check-3.0: check-bytecode
|
check-3.0: check-bytecode
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.0-run --verify-run
|
$(PYTHON) test_pythonlib.py --bytecode-3.0-run --verify-run
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.0 --weak-verify $(COMPILE)
|
$(PYTHON) test_pythonlib.py --bytecode-3.0 --syntax-verify $(COMPILE)
|
||||||
|
|
||||||
#: Run working tests from Python 3.1
|
#: Run working tests from Python 3.1
|
||||||
check-3.1: check-bytecode
|
check-3.1: check-bytecode
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.1-run --verify-run
|
$(PYTHON) test_pythonlib.py --bytecode-3.1-run --verify-run
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.1 --weak-verify $(COMPILE)
|
$(PYTHON) test_pythonlib.py --bytecode-3.1 --syntax-verify $(COMPILE)
|
||||||
|
|
||||||
#: Run working tests from Python 3.2
|
#: Run working tests from Python 3.2
|
||||||
check-3.2: check-bytecode
|
check-3.2: check-bytecode
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.2-run --verify-run
|
$(PYTHON) test_pythonlib.py --bytecode-3.2-run --verify-run
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.2 --weak-verify $(COMPILE)
|
$(PYTHON) test_pythonlib.py --bytecode-3.2 --syntax-verify $(COMPILE)
|
||||||
|
|
||||||
#: Run working tests from Python 3.3
|
#: Run working tests from Python 3.3
|
||||||
check-3.3: check-bytecode
|
check-3.3: check-bytecode
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.3-run --verify-run
|
$(PYTHON) test_pythonlib.py --bytecode-3.3-run --verify-run
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.3 --weak-verify $(COMPILE)
|
$(PYTHON) test_pythonlib.py --bytecode-3.3 --syntax-verify $(COMPILE)
|
||||||
|
|
||||||
#: Run working tests from Python 3.4
|
#: Run working tests from Python 3.4
|
||||||
check-3.4: check-bytecode check-3.4-ok check-2.7-ok
|
check-3.4: check-bytecode check-3.4-ok check-2.7-ok
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.4-run --verify-run
|
$(PYTHON) test_pythonlib.py --bytecode-3.4-run --verify-run
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.4 --weak-verify $(COMPILE)
|
$(PYTHON) test_pythonlib.py --bytecode-3.4 --syntax-verify $(COMPILE)
|
||||||
|
|
||||||
#: Run working tests from Python 3.5
|
#: Run working tests from Python 3.5
|
||||||
check-3.5: check-bytecode
|
check-3.5: check-bytecode
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.5-run --verify-run
|
$(PYTHON) test_pythonlib.py --bytecode-3.5-run --verify-run
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.5 --weak-verify $(COMPILE)
|
$(PYTHON) test_pythonlib.py --bytecode-3.5 --syntax-verify $(COMPILE)
|
||||||
|
|
||||||
#: Run working tests from Python 3.6
|
#: Run working tests from Python 3.6
|
||||||
check-3.6: check-bytecode
|
check-3.6: check-bytecode
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.6-run --verify-run
|
$(PYTHON) test_pythonlib.py --bytecode-3.6-run --verify-run
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.6 --weak-verify $(COMPILE)
|
$(PYTHON) test_pythonlib.py --bytecode-3.6 --syntax-verify $(COMPILE)
|
||||||
|
|
||||||
#: Run working tests from Python 3.7
|
#: Run working tests from Python 3.7
|
||||||
check-3.7: check-bytecode
|
check-3.7: check-bytecode
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.7-run --verify-run
|
$(PYTHON) test_pythonlib.py --bytecode-3.7-run --verify-run
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.7 --weak-verify $(COMPILE)
|
$(PYTHON) test_pythonlib.py --bytecode-3.7 --syntax-verify $(COMPILE)
|
||||||
|
|
||||||
#: Run working tests from Python 3.8
|
#: Run working tests from Python 3.8
|
||||||
check-3.8: check-bytecode
|
check-3.8: check-bytecode
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.8-run --verify-run
|
$(PYTHON) test_pythonlib.py --bytecode-3.8-run --verify-run
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.8 --weak-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 or pypy2-5.6.0
|
||||||
@@ -85,7 +86,7 @@ check-disasm:
|
|||||||
$(PYTHON) dis-compare.py
|
$(PYTHON) dis-compare.py
|
||||||
|
|
||||||
#: Check deparsing bytecode 1.x only
|
#: Check deparsing bytecode 1.x only
|
||||||
check-bytecode-1: check-bytecode-1.4 check-bytecode-1.5
|
check-bytecode-1: check-bytecode-1.0 check-bytecode-1.1 check-bytecode-1.2 check-bytecode-1.3 check-bytecode-1.4 check-bytecode-1.5 check-bytecode-1.6
|
||||||
|
|
||||||
#: Check deparsing bytecode 2.x only
|
#: Check deparsing bytecode 2.x only
|
||||||
check-bytecode-2:
|
check-bytecode-2:
|
||||||
@@ -98,8 +99,8 @@ check-bytecode-3:
|
|||||||
$(PYTHON) test_pythonlib.py --bytecode-3.0 \
|
$(PYTHON) test_pythonlib.py --bytecode-3.0 \
|
||||||
--bytecode-3.1 --bytecode-3.2 --bytecode-3.3 \
|
--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.8 \
|
--bytecode-3.7 \
|
||||||
--bytecode-pypy3.2
|
--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:
|
||||||
@@ -109,6 +110,7 @@ check-bytecode-3-short:
|
|||||||
#: Check deparsing bytecode on all Python 2 and Python 3 versions
|
#: Check deparsing bytecode on all Python 2 and Python 3 versions
|
||||||
check-bytecode: check-bytecode-3
|
check-bytecode: check-bytecode-3
|
||||||
$(PYTHON) test_pythonlib.py \
|
$(PYTHON) test_pythonlib.py \
|
||||||
|
--bytecode-1.0 --bytecode-1.1 --bytecode-1.2 \
|
||||||
--bytecode-1.3 --bytecode-1.4 --bytecode-1.5 \
|
--bytecode-1.3 --bytecode-1.4 --bytecode-1.5 \
|
||||||
--bytecode-2.2 --bytecode-2.3 --bytecode-2.4 \
|
--bytecode-2.2 --bytecode-2.3 --bytecode-2.4 \
|
||||||
--bytecode-2.1 --bytecode-2.2 --bytecode-2.3 --bytecode-2.4 \
|
--bytecode-2.1 --bytecode-2.2 --bytecode-2.3 --bytecode-2.4 \
|
||||||
@@ -122,6 +124,18 @@ check-bytecode-short: check-bytecode-3-short
|
|||||||
--bytecode-2.6 --bytecode-2.7 --bytecode-pypy2.7
|
--bytecode-2.6 --bytecode-2.7 --bytecode-pypy2.7
|
||||||
|
|
||||||
|
|
||||||
|
#: Check deparsing bytecode 1.0 only
|
||||||
|
check-bytecode-1.0:
|
||||||
|
$(PYTHON) test_pythonlib.py --bytecode-1.0
|
||||||
|
|
||||||
|
#: Check deparsing bytecode 1.1 only
|
||||||
|
check-bytecode-1.1:
|
||||||
|
$(PYTHON) test_pythonlib.py --bytecode-1.1
|
||||||
|
|
||||||
|
#: Check deparsing bytecode 1.2 only
|
||||||
|
check-bytecode-1.2:
|
||||||
|
$(PYTHON) test_pythonlib.py --bytecode-1.2
|
||||||
|
|
||||||
#: Check deparsing bytecode 1.3 only
|
#: Check deparsing bytecode 1.3 only
|
||||||
check-bytecode-1.3:
|
check-bytecode-1.3:
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-1.3
|
$(PYTHON) test_pythonlib.py --bytecode-1.3
|
||||||
@@ -134,6 +148,10 @@ check-bytecode-1.4:
|
|||||||
check-bytecode-1.5:
|
check-bytecode-1.5:
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-1.5
|
$(PYTHON) test_pythonlib.py --bytecode-1.5
|
||||||
|
|
||||||
|
#: Check deparsing bytecode 1.6 only
|
||||||
|
check-bytecode-1.6:
|
||||||
|
$(PYTHON) test_pythonlib.py --bytecode-1.6
|
||||||
|
|
||||||
#: Check deparsing Python 2.1
|
#: Check deparsing Python 2.1
|
||||||
check-bytecode-2.1:
|
check-bytecode-2.1:
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-2.1
|
$(PYTHON) test_pythonlib.py --bytecode-2.1
|
||||||
@@ -176,7 +194,7 @@ grammar-coverage-2.6:
|
|||||||
grammar-coverage-2.7:
|
grammar-coverage-2.7:
|
||||||
-rm $(COVER_DIR)/spark-grammar-2.7.cover || true
|
-rm $(COVER_DIR)/spark-grammar-2.7.cover || true
|
||||||
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-2.7.cover $(PYTHON) test_pythonlib.py --bytecode-2.7
|
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-2.7.cover $(PYTHON) test_pythonlib.py --bytecode-2.7
|
||||||
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-2.7.cover $(PYTHON) test_pyenvlib.py --2.7.14 --max=600
|
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-2.7.cover $(PYTHON) test_pyenvlib.py --2.7.16 --max=600
|
||||||
|
|
||||||
#: Get grammar coverage for Python 3.0
|
#: Get grammar coverage for Python 3.0
|
||||||
grammar-coverage-3.0:
|
grammar-coverage-3.0:
|
||||||
@@ -219,83 +237,88 @@ grammar-coverage-3.5:
|
|||||||
grammar-coverage-3.6:
|
grammar-coverage-3.6:
|
||||||
rm $(COVER_DIR)/spark-grammar-3.6.cover || /bin/true
|
rm $(COVER_DIR)/spark-grammar-3.6.cover || /bin/true
|
||||||
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-3.6.cover $(PYTHON) test_pythonlib.py --bytecode-3.6
|
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-3.6.cover $(PYTHON) test_pythonlib.py --bytecode-3.6
|
||||||
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-3.6.cover $(PYTHON) test_pyenvlib.py --3.6.4 --max=280
|
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-3.6.cover $(PYTHON) test_pyenvlib.py --3.6.8 --max=280
|
||||||
|
|
||||||
|
#: Get grammar coverage for Python 3.7
|
||||||
|
grammar-coverage-3.7:
|
||||||
|
rm $(COVER_DIR)/spark-grammar-3.7.cover || /bin/true
|
||||||
|
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-3.7.cover $(PYTHON) test_pyenvlib.py --3.7.3 --max=500
|
||||||
|
|
||||||
#: Check deparsing Python 2.6
|
#: Check deparsing Python 2.6
|
||||||
check-bytecode-2.6:
|
check-bytecode-2.6:
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-2.6-run --verify-run
|
$(PYTHON) test_pythonlib.py --bytecode-2.6-run --verify-run
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-2.6 --weak-verify
|
$(PYTHON) test_pythonlib.py --bytecode-2.6 --syntax-verify
|
||||||
|
|
||||||
#: Check deparsing Python 2.7
|
#: Check deparsing Python 2.7
|
||||||
check-bytecode-2.7:
|
check-bytecode-2.7:
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-2.7-run --verify-run
|
$(PYTHON) test_pythonlib.py --bytecode-2.7-run --verify-run
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-2.7 --weak-verify
|
$(PYTHON) test_pythonlib.py --bytecode-2.7 --syntax-verify
|
||||||
|
|
||||||
#: Check deparsing Python 3.0
|
#: Check deparsing Python 3.0
|
||||||
check-bytecode-3.0:
|
check-bytecode-3.0:
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.0-run --verify-run
|
$(PYTHON) test_pythonlib.py --bytecode-3.0-run --verify-run
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.0 --weak-verify
|
$(PYTHON) test_pythonlib.py --bytecode-3.0 --syntax-verify
|
||||||
|
|
||||||
#: Check deparsing Python 3.1
|
#: Check deparsing Python 3.1
|
||||||
check-bytecode-3.1:
|
check-bytecode-3.1:
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.1-run --verify-run
|
$(PYTHON) test_pythonlib.py --bytecode-3.1-run --verify-run
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.1 --weak-verify
|
$(PYTHON) test_pythonlib.py --bytecode-3.1 --syntax-verify
|
||||||
|
|
||||||
#: Check deparsing Python 3.2
|
#: Check deparsing Python 3.2
|
||||||
check-bytecode-3.2:
|
check-bytecode-3.2:
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.2-run --verify-run
|
$(PYTHON) test_pythonlib.py --bytecode-3.2-run --verify-run
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.2 --weak-verify
|
$(PYTHON) test_pythonlib.py --bytecode-3.2 --syntax-verify
|
||||||
|
|
||||||
#: Check deparsing Python 3.3
|
#: Check deparsing Python 3.3
|
||||||
check-bytecode-3.3:
|
check-bytecode-3.3:
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.3-run --verify-run
|
$(PYTHON) test_pythonlib.py --bytecode-3.3-run --verify-run
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.3 --weak-verify
|
$(PYTHON) test_pythonlib.py --bytecode-3.3 --syntax-verify
|
||||||
|
|
||||||
#: Check deparsing Python 3.4
|
#: Check deparsing Python 3.4
|
||||||
check-bytecode-3.4:
|
check-bytecode-3.4:
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.4-run --verify-run
|
$(PYTHON) test_pythonlib.py --bytecode-3.4-run --verify-run
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.4 --weak-verify
|
$(PYTHON) test_pythonlib.py --bytecode-3.4 --syntax-verify
|
||||||
|
|
||||||
#: Check deparsing Python 3.5
|
#: Check deparsing Python 3.5
|
||||||
check-bytecode-3.5:
|
check-bytecode-3.5:
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.5-run --verify-run
|
$(PYTHON) test_pythonlib.py --bytecode-3.5-run --verify-run
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.5 --weak-verify
|
$(PYTHON) test_pythonlib.py --bytecode-3.5 --syntax-verify
|
||||||
|
|
||||||
#: Check deparsing Python 3.6
|
#: Check deparsing Python 3.6
|
||||||
check-bytecode-3.6:
|
check-bytecode-3.6:
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.6-run --verify-run
|
$(PYTHON) test_pythonlib.py --bytecode-3.6-run --verify-run
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.6 --weak-verify
|
$(PYTHON) test_pythonlib.py --bytecode-3.6 --syntax-verify
|
||||||
|
|
||||||
#: Check deparsing Python 3.7
|
#: Check deparsing Python 3.7
|
||||||
check-bytecode-3.7:
|
check-bytecode-3.7:
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.7-run --verify-run
|
$(PYTHON) test_pythonlib.py --bytecode-3.7-run --verify-run
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.7 --weak-verify
|
$(PYTHON) test_pythonlib.py --bytecode-3.7 --syntax-verify
|
||||||
|
|
||||||
#: Check deparsing Python 3.8
|
#: Check deparsing Python 3.8
|
||||||
check-bytecode-3.8:
|
check-bytecode-3.8:
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.8-run --verify-run
|
$(PYTHON) test_pythonlib.py --bytecode-3.8-run --verify-run
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-3.8 --weak-verify
|
$(PYTHON) test_pythonlib.py --bytecode-3.8 --syntax-verify
|
||||||
|
|
||||||
#: short tests for bytecodes only for this version of Python
|
#: short tests for bytecodes only for this version of Python
|
||||||
check-native-short:
|
check-native-short:
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-$(PYTHON_VERSION) --weak-verify $(COMPILE)
|
$(PYTHON) test_pythonlib.py --bytecode-$(PYTHON_VERSION) --syntax-verify $(COMPILE)
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-$(PYTHON_VERSION)-run --verify-run $(COMPILE)
|
$(PYTHON) test_pythonlib.py --bytecode-$(PYTHON_VERSION)-run --verify-run $(COMPILE)
|
||||||
|
|
||||||
#: Run longer Python 2.6's lib files known to be okay
|
#: Run longer Python 2.6's lib files known to be okay
|
||||||
check-2.6-ok:
|
check-2.6-ok:
|
||||||
$(PYTHON) test_pythonlib.py --ok-2.6 --weak-verify $(COMPILE)
|
$(PYTHON) test_pythonlib.py --ok-2.6 --syntax-verify $(COMPILE)
|
||||||
|
|
||||||
#: Run longer Python 2.7's lib files known to be okay
|
#: Run longer Python 2.7's lib files known to be okay
|
||||||
check-2.7-ok:
|
check-2.7-ok:
|
||||||
$(PYTHON) test_pythonlib.py --ok-2.7 --weak-verify $(COMPILE)
|
$(PYTHON) test_pythonlib.py --ok-2.7 --syntax-verify $(COMPILE)
|
||||||
|
|
||||||
#: Run longer Python 3.2's lib files known to be okay
|
#: Run longer Python 3.2's lib files known to be okay
|
||||||
check-3.2-ok:
|
check-3.2-ok:
|
||||||
$(PYTHON) test_pythonlib.py --ok-3.2 --weak-verify $(COMPILE)
|
$(PYTHON) test_pythonlib.py --ok-3.2 --syntax-verify $(COMPILE)
|
||||||
|
|
||||||
#: Run longer Python 3.4's lib files known to be okay
|
#: Run longer Python 3.4's lib files known to be okay
|
||||||
check-3.4-ok:
|
check-3.4-ok:
|
||||||
$(PYTHON) test_pythonlib.py --ok-3.4 --weak-verify $(COMPILE)
|
$(PYTHON) test_pythonlib.py --ok-3.4 --syntax-verify $(COMPILE)
|
||||||
|
|
||||||
#: PyPy of some sort. E.g. [PyPy 5.0.1 with GCC 4.8.4]
|
#: PyPy of some sort. E.g. [PyPy 5.0.1 with GCC 4.8.4]
|
||||||
# Skip for now
|
# Skip for now
|
||||||
@@ -309,8 +332,16 @@ pypy-2.7 5.0 5.3 6.0:
|
|||||||
pypy-3.2 2.4:
|
pypy-3.2 2.4:
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-pypy3.2 --verify
|
$(PYTHON) test_pythonlib.py --bytecode-pypy3.2 --verify
|
||||||
|
|
||||||
#: PyPy 5.0.x with Python 3.6 ...
|
#: PyPy 5.0.x with Python 3.6.1 ...
|
||||||
|
check-bytecode-pypy3.6: 7.1
|
||||||
7.1:
|
7.1:
|
||||||
|
$(PYTHON) test_pythonlib.py --bytecode-pypy3.6-run --verify-run
|
||||||
|
$(PYTHON) test_pythonlib.py --bytecode-pypy3.6 --verify
|
||||||
|
|
||||||
|
#: PyPy 5.0.x with Python 3.6.9
|
||||||
|
check-bytecode-pypy3.6: 7.2
|
||||||
|
7.2:
|
||||||
|
$(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
|
||||||
|
|
||||||
|
|
||||||
|
@@ -2,22 +2,23 @@
|
|||||||
""" Trivial helper program to bytecompile and run an uncompile
|
""" Trivial helper program to bytecompile and run an uncompile
|
||||||
"""
|
"""
|
||||||
import os, sys, py_compile
|
import os, sys, py_compile
|
||||||
|
|
||||||
assert len(sys.argv) >= 2
|
assert len(sys.argv) >= 2
|
||||||
version = sys.version[0:3]
|
version = sys.version[0:3]
|
||||||
if sys.argv[1] == '--run':
|
if sys.argv[1] in ("--run", "-r"):
|
||||||
suffix = '_run'
|
suffix = "_run"
|
||||||
py_source = sys.argv[2:]
|
py_source = sys.argv[2:]
|
||||||
else:
|
else:
|
||||||
suffix = ''
|
suffix = ""
|
||||||
py_source = sys.argv[1:]
|
py_source = sys.argv[1:]
|
||||||
|
|
||||||
for path in py_source:
|
for path in py_source:
|
||||||
short = os.path.basename(path)
|
short = os.path.basename(path)
|
||||||
if hasattr(sys, 'pypy_version_info'):
|
if hasattr(sys, "pypy_version_info"):
|
||||||
cfile = "bytecode_pypy%s%s/%s" % (version, suffix, short) + 'c'
|
cfile = "bytecode_pypy%s%s/%s" % (version, suffix, short) + "c"
|
||||||
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)
|
py_compile.compile(path, cfile)
|
||||||
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)
|
||||||
|
BIN
test/bytecode_1.0/simple_const.pyc
Normal file
BIN
test/bytecode_1.0/simple_const.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_1.0/unpack_assign.pyc
Normal file
BIN
test/bytecode_1.0/unpack_assign.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_1.1/simple_const.pyc
Normal file
BIN
test/bytecode_1.1/simple_const.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_1.2/simple_const.pyc
Normal file
BIN
test/bytecode_1.2/simple_const.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_1.3/simple_const.pyc
Normal file
BIN
test/bytecode_1.3/simple_const.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_1.6/simple_const.pyc
Normal file
BIN
test/bytecode_1.6/simple_const.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_2.4/02_except_as.pyc
Normal file
BIN
test/bytecode_2.4/02_except_as.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_2.4_run/00_docstring.pyc
Normal file
BIN
test/bytecode_2.4_run/00_docstring.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
test/bytecode_2.6_run/00_generator.pyc
Normal file
BIN
test/bytecode_2.6_run/00_generator.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_2.6_run/01_if_while_return.pyc
Normal file
BIN
test/bytecode_2.6_run/01_if_while_return.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
test/bytecode_2.6_run/02_decorator.pyc
Normal file
BIN
test/bytecode_2.6_run/02_decorator.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
test/bytecode_2.6_run/04_if_and_bug.pyc
Normal file
BIN
test/bytecode_2.6_run/04_if_and_bug.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
test/bytecode_2.7_run/00_docstring.pyc
Normal file
BIN
test/bytecode_2.7_run/00_docstring.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
test/bytecode_2.7_run/05_control_flow_bugs.pyc
Normal file
BIN
test/bytecode_2.7_run/05_control_flow_bugs.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_2.7_run/15_mixed_expressions.pyc
Normal file
BIN
test/bytecode_2.7_run/15_mixed_expressions.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
test/bytecode_3.0/03_ifelse.pyc
Normal file
BIN
test/bytecode_3.0/03_ifelse.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.0/07_withstmt_fn.pyc
Normal file
BIN
test/bytecode_3.0/07_withstmt_fn.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
test/bytecode_3.0_run/04_and_del.pyc-notyet
Normal file
BIN
test/bytecode_3.0_run/04_and_del.pyc-notyet
Normal file
Binary file not shown.
BIN
test/bytecode_3.0_run/04_def_annotate.pyc
Normal file
BIN
test/bytecode_3.0_run/04_def_annotate.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.0_run/04_lambda_star_default.pyc
Normal file
BIN
test/bytecode_3.0_run/04_lambda_star_default.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.0_run/05_block_fallback.pyc
Normal file
BIN
test/bytecode_3.0_run/05_block_fallback.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
test/bytecode_3.0_run/06_listcomp.pyc-notyet
Normal file
BIN
test/bytecode_3.0_run/06_listcomp.pyc-notyet
Normal file
Binary file not shown.
BIN
test/bytecode_3.0_run/15_mixed_expressions.pyc
Normal file
BIN
test/bytecode_3.0_run/15_mixed_expressions.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
test/bytecode_3.1_run/04_def_annotate.pyc
Normal file
BIN
test/bytecode_3.1_run/04_def_annotate.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.1_run/04_lambda_star_default.pyc
Normal file
BIN
test/bytecode_3.1_run/04_lambda_star_default.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
test/bytecode_3.1_run/10_complex.pyc
Normal file
BIN
test/bytecode_3.1_run/10_complex.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.1_run/15_mixed_expressions.pyc
Normal file
BIN
test/bytecode_3.1_run/15_mixed_expressions.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
test/bytecode_3.2_run/04_def_annotate.pyc
Normal file
BIN
test/bytecode_3.2_run/04_def_annotate.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.2_run/04_lambda_star_default.pyc
Normal file
BIN
test/bytecode_3.2_run/04_lambda_star_default.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.2_run/10_for_if_loopback.pyc
Normal file
BIN
test/bytecode_3.2_run/10_for_if_loopback.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
test/bytecode_3.3/09_yield_from.pyc
Normal file
BIN
test/bytecode_3.3/09_yield_from.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.3_run/00_docstring.pyc
Normal file
BIN
test/bytecode_3.3_run/00_docstring.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
test/bytecode_3.3_run/02_pos_args.pyc
Normal file
BIN
test/bytecode_3.3_run/02_pos_args.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.3_run/04_def_annotate.pyc
Normal file
BIN
test/bytecode_3.3_run/04_def_annotate.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.3_run/04_lambda_star_default.pyc
Normal file
BIN
test/bytecode_3.3_run/04_lambda_star_default.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.3_run/08_while_if.pyc
Normal file
BIN
test/bytecode_3.3_run/08_while_if.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.3_run/10_complex.pyc
Normal file
BIN
test/bytecode_3.3_run/10_complex.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
test/bytecode_3.4/09_yield_from.pyc
Normal file
BIN
test/bytecode_3.4/09_yield_from.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.4_run/04_def_annotate.pyc
Normal file
BIN
test/bytecode_3.4_run/04_def_annotate.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.4_run/04_lambda_star_default.pyc
Normal file
BIN
test/bytecode_3.4_run/04_lambda_star_default.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.4_run/08_while_if.pyc
Normal file
BIN
test/bytecode_3.4_run/08_while_if.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.5/02_async.pyc
Normal file
BIN
test/bytecode_3.5/02_async.pyc
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user