You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 00:45:53 +08:00
Compare commits
1124 Commits
release-3.
...
3.8.0
Author | SHA1 | Date | |
---|---|---|---|
|
470d203b40 | ||
|
4911d85237 | ||
|
93a218a8b1 | ||
|
32c4b84458 | ||
|
9cf345d446 | ||
|
c164df2795 | ||
|
3ad63071ac | ||
|
d0ca7b0363 | ||
|
ea26084e6d | ||
|
fa203af665 | ||
|
51ac72ba1f | ||
|
d5bf7626af | ||
|
7387e5094b | ||
|
1bcd21a6f4 | ||
|
71fe1e6c2c | ||
|
40a40b0bad | ||
|
528a2b0c22 | ||
|
e3369edaed | ||
|
0a9dc57cc9 | ||
|
48bd832e7c | ||
|
29a91fc015 | ||
|
3e5f963c64 | ||
|
c7ebdb344b | ||
|
438c3b8d1d | ||
|
aa1d7abfdc | ||
|
d3e30cf0e0 | ||
|
36efc1fc8a | ||
|
f00080317b | ||
|
162423895e | ||
|
f2750cff50 | ||
|
256aaf0ef9 | ||
|
41314f95bb | ||
|
0645738775 | ||
|
ceb7c659bd | ||
|
8ac7a75372 | ||
|
15efaffe8d | ||
|
e8e006bb8c | ||
|
c68b74a9c6 | ||
|
f4bb0c44fe | ||
|
8d81f4ab27 | ||
|
e0a56d4739 | ||
|
054364cb22 | ||
|
83c8313a8e | ||
|
184bda1b03 | ||
|
f374485e93 | ||
|
fe7df87288 | ||
|
cfbb25df3d | ||
|
d4174832a1 | ||
|
345de81d06 | ||
|
dd8f22e698 | ||
|
96b1e435c2 | ||
|
971757e997 | ||
|
2b154e0b88 | ||
|
5d35a75743 | ||
|
fc38e23d8f | ||
|
5c16c73a6c | ||
|
3f665b939d | ||
|
f2f49104ea | ||
|
c2ee564e11 | ||
|
f95db091bc | ||
|
78dbc8ae0f | ||
|
70b7e51df6 | ||
|
1164cd90dc | ||
|
4bbdbe3894 | ||
|
28855767fb | ||
|
8eb4d6a576 | ||
|
b4db22d525 | ||
|
8879708da7 | ||
|
67c45467c3 | ||
|
33bff4dc47 | ||
|
71c17c4e53 | ||
|
a5cfd81805 | ||
|
64f19bf188 | ||
|
ff08f8a977 | ||
|
3ae4fda292 | ||
|
6cb6e45789 | ||
|
024a81c053 | ||
|
a0f93f7ad9 | ||
|
d3d67441d1 | ||
|
a215ee2f00 | ||
|
f62512dd65 | ||
|
0f80c38530 | ||
|
bd07de5172 | ||
|
e36945e2d9 | ||
|
25df0bdb76 | ||
|
29ceb3fe05 | ||
|
fd7e04fa5d | ||
|
5079164db2 | ||
|
815ae2c5cd | ||
|
54932d36fa | ||
|
fa1d7e4af4 | ||
|
bfd4b4cd68 | ||
|
430fd2fa85 | ||
|
ef59b9c304 | ||
|
084e183577 | ||
|
7c14cf2d66 | ||
|
1d3fdbb4cd | ||
|
b21e8b8b57 | ||
|
4007b8b702 | ||
|
598b58796d | ||
|
f7bad891a4 | ||
|
357f28dd89 | ||
|
5cc572147a | ||
|
11be90758f | ||
|
e3720515ae | ||
|
7dec354a47 | ||
|
2a8daca25d | ||
|
7799819cad | ||
|
c6c50b5dfb | ||
|
d357898bbf | ||
|
c4e7ddf90a | ||
|
02f502c40a | ||
|
de4fbb08f2 | ||
|
e14675c2dc | ||
|
3449be024b | ||
|
8b50b15f0a | ||
|
e2e925679d | ||
|
7deeee8502 | ||
|
acdd025162 | ||
|
9acb3cf068 | ||
|
40a653cd3b | ||
|
3ac3979535 | ||
|
7eba933cfa | ||
|
ad5d3333da | ||
|
e046323b31 | ||
|
e80c13170a | ||
|
889417caeb | ||
|
5a83c7c643 | ||
|
31db2f3e04 | ||
|
7fa851765d | ||
|
d7c3b8454b | ||
|
3fb8d90407 | ||
|
ff43565981 | ||
|
4365022f40 | ||
|
d343384db7 | ||
|
87a891ca54 | ||
|
b94c649776 | ||
|
f34375ba99 | ||
|
81b704f597 | ||
|
5233a0716b | ||
|
a810ed1280 | ||
|
ab54caae34 | ||
|
d3cf87e2d9 | ||
|
c5228dbdc4 | ||
|
a72163f6f9 | ||
|
3e1300eb23 | ||
|
a4eaeea5b2 | ||
|
1141dfefc2 | ||
|
302a5d53d4 | ||
|
698a3073d0 | ||
|
e6adf822cc | ||
|
8c5acef792 | ||
|
7578253f7d | ||
|
9e193fd7cb | ||
|
ab6b12be56 | ||
|
5bd97aa756 | ||
|
5237d704fa | ||
|
a01285e4a9 | ||
|
1d7e8f1617 | ||
|
ced33a8f0b | ||
|
dc7f1ed0cc | ||
|
fc00d394ec | ||
|
e2baccb4e5 | ||
|
c99cf7a653 | ||
|
999eee4b5f | ||
|
9ca94717e0 | ||
|
b77efec36c | ||
|
17d07eaf00 | ||
|
538c2e7efd | ||
|
ebc22e32e6 | ||
|
4796fb9e70 | ||
|
ea81ac7202 | ||
|
2fd61b1016 | ||
|
ebd0eaa609 | ||
|
badfe5456f | ||
|
f117feb585 | ||
|
204b07c996 | ||
|
869e48877c | ||
|
7ed40d5f6e | ||
|
5c6365d8a1 | ||
|
42d3c4db61 | ||
|
f3b102600e | ||
|
f6a13302fb | ||
|
e8e7d2086d | ||
|
1367709399 | ||
|
3dcc20f6d7 | ||
|
5c83de830f | ||
|
451f0b55bb | ||
|
a5704cd462 | ||
|
52fbf1d6a7 | ||
|
0a3f951682 | ||
|
7b4059820f | ||
|
9caac7fc84 | ||
|
ceb26d29fd | ||
|
9ec1c420e7 | ||
|
a616e1e1c7 | ||
|
b839abcfe7 | ||
|
e2d349f781 | ||
|
af8add9df4 | ||
|
3afc5a599a | ||
|
663bc06bb9 | ||
|
63d6054640 | ||
|
1c8805ecc9 | ||
|
5fde4f2e05 | ||
|
b030a5ac2b | ||
|
01ea45a3f5 | ||
|
2b2e7d3242 | ||
|
2448f24764 | ||
|
299fd93125 | ||
|
d9b2d66843 | ||
|
d070a28635 | ||
|
092874f8b5 | ||
|
5a6a41a608 | ||
|
201635de7b | ||
|
81899a82c3 | ||
|
76085a3040 | ||
|
35127452f5 | ||
|
970cad7cc7 | ||
|
69064f4c23 | ||
|
28ef04d141 | ||
|
fd36c77d2d | ||
|
534afb3f6e | ||
|
874d196e5c | ||
|
dca2224520 | ||
|
e90455dcb8 | ||
|
6dd97568f6 | ||
|
aa6849a570 | ||
|
749493631c | ||
|
7b3c91d23a | ||
|
bd0fdd0002 | ||
|
c62daaf0b7 | ||
|
66d8526d7f | ||
|
66db4cc862 | ||
|
bf288b1871 | ||
|
d2f6223e14 | ||
|
9d5a4c822e | ||
|
05e0a5661a | ||
|
76287162da | ||
|
d64fa6ba50 | ||
|
b76f7f905c | ||
|
c31384ef81 | ||
|
727dabff6a | ||
|
946d74ad36 | ||
|
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 | ||
|
8fe6309650 | ||
|
4c4aa393df | ||
|
a8b8c2908c | ||
|
cb406e2581 | ||
|
20b16c44ff | ||
|
3abe8d11d3 | ||
|
26140934da | ||
|
b62752eca1 | ||
|
9db446d928 | ||
|
46acb74745 | ||
|
44e1288e2f | ||
|
ce9270dda0 | ||
|
3d732db3cc | ||
|
009a74da7d | ||
|
251eb6da1b | ||
|
8b5e0f49f8 | ||
|
1cc08d9598 | ||
|
d99e78d46d | ||
|
b94cce7b12 | ||
|
fe786b2b95 | ||
|
bf56fbeeec | ||
|
6d8d9fd83b | ||
|
78ca6a0c1f | ||
|
86dd321256 | ||
|
4db364f701 | ||
|
c03b039714 | ||
|
d97509495e | ||
|
4d793ba1b2 | ||
|
590d2f44f1 | ||
|
e875b79a75 | ||
|
b57ca392a2 | ||
|
a132e2ace6 | ||
|
b05500dd49 | ||
|
65307f257c | ||
|
8909fe8d37 | ||
|
733a44e22f | ||
|
f2f17740ee | ||
|
393e5c9303 | ||
|
8c611476fe | ||
|
6df65a87bc | ||
|
bb94c7f5bc | ||
|
8e9ce0be31 | ||
|
bc49469704 | ||
|
5905cce1de | ||
|
af816c9e60 | ||
|
82a3419eb2 | ||
|
46ca21596f | ||
|
6e753b8743 | ||
|
0007abf827 | ||
|
7ecfb74e9a | ||
|
2813e2212f | ||
|
e2c5a79346 | ||
|
293e7b0367 | ||
|
32bc017e2e | ||
|
ce7015f382 | ||
|
4cc53f2307 | ||
|
257bbc892f | ||
|
fac365f216 | ||
|
f54cf20d9d | ||
|
03d23328eb | ||
|
c074107504 | ||
|
a981db884c | ||
|
c5d7944e65 | ||
|
43dbf9b878 | ||
|
efa964f7c9 | ||
|
5c58a4816f | ||
|
132a9acdb4 | ||
|
9186a3fc44 | ||
|
05db6194ec | ||
|
3730946a1a | ||
|
f1b69a8a28 | ||
|
0e5eb954b2 | ||
|
7d9286b353 | ||
|
0de99e5d44 | ||
|
52af2ba32a | ||
|
bd0db6c539 | ||
|
8663b4ca52 | ||
|
b2dd58a85e | ||
|
97cb193a71 | ||
|
e6e60cb49d | ||
|
2ea8c3b1b1 | ||
|
701d2af54e | ||
|
8a4189bc0e | ||
|
0c4ab699b5 | ||
|
8e11c53064 | ||
|
b4c66d4307 | ||
|
53968e535f | ||
|
d2381fbe11 | ||
|
d413ebe0e1 | ||
|
f96522e18e | ||
|
50d50af2ee | ||
|
4dc2897cdc | ||
|
47fb80494d | ||
|
830e19e3e6 | ||
|
c5cfd36a61 | ||
|
9b550b9dda | ||
|
400943bb6a | ||
|
f89ba40147 | ||
|
32c611a315 | ||
|
5d91e96358 | ||
|
44edf1d7db | ||
|
a891aa0706 | ||
|
5e1340a2fc | ||
|
94eff282f8 | ||
|
7f65a8a6dd | ||
|
cfe7feed4d | ||
|
b3a20896b2 | ||
|
1425476018 | ||
|
59c77f103d | ||
|
726045a05e | ||
|
49e354375e | ||
|
f3d86e0708 | ||
|
820283827f | ||
|
8b65cc7275 | ||
|
1e47f47527 | ||
|
19a95be3ef | ||
|
5a6550b353 | ||
|
82fb9426af | ||
|
98b91db8e6 | ||
|
ce3f815b08 | ||
|
c447b9cfa9 | ||
|
053270483c | ||
|
4a354269bc | ||
|
cd64156708 | ||
|
3d49b499fb | ||
|
dcad6cf6ce | ||
|
bfceeac6c8 | ||
|
47448e7ce4 | ||
|
e1628d4d3a | ||
|
3328ed494e | ||
|
0c5f0dfc7a | ||
|
138b2ac5ee | ||
|
ceae035c70 | ||
|
763c599c16 | ||
|
14111d9341 | ||
|
739ba48f61 | ||
|
9f1a7fa7ff | ||
|
fb117713cf | ||
|
43646b3c71 | ||
|
9a14db567b | ||
|
a97d4003c7 | ||
|
acb96deba5 | ||
|
6cbaef4ba5 | ||
|
7c9691b5a7 | ||
|
0fa45301fa | ||
|
3b43801067 | ||
|
e41ef897d1 | ||
|
d0dc26caf7 | ||
|
df105fbfb2 | ||
|
fbf51a0ae3 | ||
|
5d99322078 | ||
|
1a70f75ffc | ||
|
37750814b9 | ||
|
a2321773d7 | ||
|
acd0e5fea6 | ||
|
d443295df6 | ||
|
296a2129eb | ||
|
84e8542248 | ||
|
fe9beb2fd1 | ||
|
7de893730d | ||
|
a7ceedb62c | ||
|
49999b2633 | ||
|
ffad6ae6d5 | ||
|
d250d38b39 | ||
|
4a76a4f591 | ||
|
f5448b371c | ||
|
55a73d5a29 | ||
|
dc0b243938 | ||
|
99fc7f9873 | ||
|
3b7c8cf092 | ||
|
5abfe7c85a | ||
|
7fa21d0db4 | ||
|
d422f28d2e | ||
|
f3cd1ee3f3 | ||
|
de6dec6ecd | ||
|
fbcf91954e | ||
|
350a16cfa2 | ||
|
5a7024d2a3 | ||
|
e16138527a | ||
|
2362045c84 | ||
|
a29afd6832 | ||
|
1bcf0d54f7 | ||
|
4c6bdd58ab | ||
|
7898fa157b | ||
|
bbdb238ddb | ||
|
ec42ee540c | ||
|
616e5c82f6 | ||
|
1cb31a85fd | ||
|
7d1ecf957c | ||
|
c96e796ff5 | ||
|
f14e1dd62f | ||
|
5f1667988f | ||
|
19ec52eb63 | ||
|
c3e722ad51 | ||
|
31de342528 | ||
|
70f25d5f8d | ||
|
1b71cfef07 | ||
|
e7845ed2e4 | ||
|
f4a1e9e40f | ||
|
b9e8e619f6 | ||
|
5c88f804c1 | ||
|
35834b06d4 | ||
|
27febca918 | ||
|
37b917ed7c | ||
|
82499b50bb | ||
|
c6b3e20b47 | ||
|
93e889e82a | ||
|
4cbd136635 | ||
|
488a14488c | ||
|
44321fcedf | ||
|
1e0a6d528e | ||
|
40fa379fd9 | ||
|
34ec41f274 | ||
|
3daf3732c3 | ||
|
988efa3693 | ||
|
bc16cc93d6 | ||
|
8d1bd6d5b5 | ||
|
c148e49670 | ||
|
fb31fe1f35 | ||
|
fa5da2b1ef | ||
|
f331deb864 | ||
|
1350f4c899 | ||
|
6fd8d2556b | ||
|
276fb77e71 | ||
|
f547ec9291 | ||
|
4f994b4cae | ||
|
98cd06d6e0 | ||
|
a3b6806c33 | ||
|
66ebb15d42 | ||
|
8955788990 | ||
|
9415ad34ff | ||
|
476db9ad1d | ||
|
9ba0b1bad2 | ||
|
b7942bc5f2 | ||
|
3ac4f1ee61 | ||
|
55d2df04f7 | ||
|
6d529d3cee | ||
|
201e5b18b1 | ||
|
ac2bbfc65a | ||
|
3b8e6635e2 | ||
|
7e172b63d1 | ||
|
c01eb554ed | ||
|
d32e67891b | ||
|
78b8d1cd06 | ||
|
600e56b1d7 | ||
|
170504c518 | ||
|
e3d918df3d | ||
|
e7b62a722f | ||
|
92d63ac598 | ||
|
79bed3419f | ||
|
0353b74a7a | ||
|
67910e7d8e | ||
|
61fa4fe391 | ||
|
a8cdcc4d85 | ||
|
f0176add7a |
75
.circleci/config.yml
Normal file
75
.circleci/config.yml
Normal file
@@ -0,0 +1,75 @@
|
||||
version: 2
|
||||
filters:
|
||||
branches:
|
||||
only: master
|
||||
jobs:
|
||||
build:
|
||||
working_directory: ~/rocky/python-uncompyle6
|
||||
parallelism: 1
|
||||
shell: /bin/bash --login
|
||||
# CircleCI 2.0 does not support environment variables that refer to each other the same way as 1.0 did.
|
||||
# If any of these refer to each other, rewrite them so that they don't or see https://circleci.com/docs/2.0/env-vars/#interpolating-environment-variables-to-set-other-environment-variables .
|
||||
environment:
|
||||
CIRCLE_ARTIFACTS: /tmp/circleci-artifacts
|
||||
CIRCLE_TEST_REPORTS: /tmp/circleci-test-results
|
||||
COMPILE: --compile
|
||||
# To see the list of pre-built images that CircleCI provides for most common languages see
|
||||
# https://circleci.com/docs/2.0/circleci-images/
|
||||
docker:
|
||||
- image: circleci/python:3.6.9
|
||||
steps:
|
||||
# Machine Setup
|
||||
# If you break your build into multiple jobs with workflows, you will probably want to do the parts of this that are relevant in each
|
||||
# The following `checkout` command checks out your code to your working directory. In 1.0 we did this implicitly. In 2.0 you can choose where in the course of a job your code should be checked out.
|
||||
- checkout
|
||||
# Prepare for artifact and test results collection equivalent to how it was done on 1.0.
|
||||
# In many cases you can simplify this from what is generated here.
|
||||
# 'See docs on artifact collection here https://circleci.com/docs/2.0/artifacts/'
|
||||
- run: mkdir -p $CIRCLE_ARTIFACTS $CIRCLE_TEST_REPORTS
|
||||
# This is based on your 1.0 configuration file or project settings
|
||||
- run:
|
||||
working_directory: ~/rocky/python-uncompyle6
|
||||
command: pip install --user virtualenv && pip install --user nose && pip install --user pep8
|
||||
# Dependencies
|
||||
# This would typically go in either a build or a build-and-test job when using workflows
|
||||
# Restore the dependency cache
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v2-dependencies-{{ .Branch }}-
|
||||
# fallback to using the latest cache if no exact match is found
|
||||
- v2-dependencies-
|
||||
|
||||
- run:
|
||||
command: | # Use pip to install dependengcies
|
||||
pip install --user --upgrade setuptools
|
||||
pip install --user -e .
|
||||
pip install --user -r requirements-dev.txt
|
||||
|
||||
# Save dependency cache
|
||||
- save_cache:
|
||||
key: v2-dependencies-{{ .Branch }}-{{ epoch }}
|
||||
paths:
|
||||
# This is a broad list of cache paths to include many possible development environments
|
||||
# You can probably delete some of these entries
|
||||
- vendor/bundle
|
||||
- ~/virtualenvs
|
||||
- ~/.m2
|
||||
- ~/.ivy2
|
||||
- ~/.bundle
|
||||
- ~/.cache/bower
|
||||
|
||||
# Test
|
||||
# This would typically be a build job when using workflows, possibly combined with build
|
||||
# This is based on your 1.0 configuration file or project settings
|
||||
- run: sudo python ./setup.py develop && make check-3.6
|
||||
- run: cd ./test/stdlib && bash ./runtests.sh 'test_[p-z]*.py'
|
||||
# Teardown
|
||||
# If you break your build into multiple jobs with workflows, you will probably want to do the parts of this that are relevant in each
|
||||
# Save test results
|
||||
- store_test_results:
|
||||
path: /tmp/circleci-test-results
|
||||
# Save artifacts
|
||||
- store_artifacts:
|
||||
path: /tmp/circleci-artifacts
|
||||
- store_artifacts:
|
||||
path: /tmp/circleci-test-results
|
28
.editorconfig
Normal file
28
.editorconfig
Normal file
@@ -0,0 +1,28 @@
|
||||
# THis is an EditorConfig file
|
||||
# https://EditorConfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
charset = utf-8
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
insert_final_newline = true
|
||||
|
||||
[*.yml]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
|
||||
[*.py]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
|
||||
# Tab indentation (no size specified)
|
||||
[Makefile]
|
||||
indent_style = tab
|
12
.github/FUNDING.yml
vendored
Normal file
12
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: [rocky]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
89
.github/ISSUE_TEMPLATE/bug-report.md
vendored
Normal file
89
.github/ISSUE_TEMPLATE/bug-report.md
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Tell us about uncompyle6 bugs
|
||||
|
||||
---
|
||||
|
||||
<!-- __Note:__ Bugs are not for asking questions about a problem you
|
||||
are trying to solve that involve the use of uncompyle6 along the way,
|
||||
although I may be more tolerent of this if you sponsor the project.
|
||||
|
||||
Also, the unless you are a sponsor of the project, it may take a
|
||||
while, maybe a week or so, before the bug report is noticed, let alone
|
||||
acted upon.
|
||||
|
||||
To set expectations, some legitimate bugs can take years
|
||||
to fix, but they eventually do get fixed. Funding the project was
|
||||
added to address the problem that there are lots of people seeking
|
||||
help and reporting bugs, but few people who are willing or capable of
|
||||
providing help or fixing bugs.
|
||||
|
||||
Finally, have you read https://github.com/rocky/python-uncompyle6/blob/master/HOW-TO-REPORT-A-BUG.md
|
||||
?
|
||||
|
||||
|
||||
Please remove any of the optional sections if they are not applicable.
|
||||
|
||||
Prerequisites/Caveats
|
||||
|
||||
* Make sure the bytecode you have can be disassembled with a
|
||||
disassembler and produces valid results.
|
||||
* Don't put bytecode and corresponding source code on any service that
|
||||
requires registration to download.
|
||||
* When you open a bug report there is no privacy. If you need privacy, then
|
||||
contact me by email and explain who you are and the need for privacy.
|
||||
But be mindful that you may be asked to sponsor the project for the
|
||||
personal and private help that you are requesting.
|
||||
* If the legitimacy of the activity is deemed suspicous, I may flag it as suspicious,
|
||||
making the issue even more easy to detect.
|
||||
|
||||
Bug reports that violate the above may be discarded.
|
||||
|
||||
-->
|
||||
|
||||
## Description
|
||||
|
||||
<!-- Add a clear and concise description of the bug. -->
|
||||
|
||||
## How to Reproduce
|
||||
|
||||
<!-- Please show both the *input* you gave and the
|
||||
output you got in describing how to reproduce the bug:
|
||||
|
||||
or give a complete console log with input and output
|
||||
|
||||
```console
|
||||
$ uncompyle6 <command-line-options>
|
||||
...
|
||||
$
|
||||
```
|
||||
|
||||
Provide links to the Python bytecode. For example you can create a
|
||||
gist with the information. If you have the correct source code, you
|
||||
can add that too.
|
||||
|
||||
-->
|
||||
|
||||
## Expected behavior
|
||||
|
||||
<!-- Add a clear and concise description of what you expected to happen. -->
|
||||
|
||||
## Environment
|
||||
|
||||
<!-- _This section sometimes is optional but helpful to us._
|
||||
|
||||
Please modify for your setup
|
||||
|
||||
- Uncompyle6 version: output from `uncompyle6 --version` or `pip show uncompyle6`
|
||||
- Python version 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]
|
||||
|
||||
-->
|
||||
|
||||
## Additional Environment or Context
|
||||
|
||||
<!-- _This section is optional._
|
||||
|
||||
Add any other context about the problem here or special environment setup.
|
||||
|
||||
-->
|
22
.github/ISSUE_TEMPLATE/feature-request.md
vendored
Normal file
22
.github/ISSUE_TEMPLATE/feature-request.md
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
name: Feature Request
|
||||
about: Tell us about a new feature that you would like to see in uncompyle6
|
||||
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- Add a short description of the feature. This might
|
||||
include same input and output. -->
|
||||
|
||||
## Background
|
||||
|
||||
<!-- Add any additional background for the
|
||||
feature, for example: user scenarios, or the value of the feature. -->
|
||||
|
||||
## Tests
|
||||
<!-- _This section is optional._
|
||||
|
||||
Add text with suggestions on how to test the feature,
|
||||
if it is not obvious.
|
||||
-->
|
31
.github/workflows/osx.yml
vendored
Normal file
31
.github/workflows/osx.yml
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
name: uncompyle6 (osx)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: macos-latest
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macOS]
|
||||
python-version: [3.6, 3.7, 3.8]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
# Until the next xdis release
|
||||
pip install git+git://github.com/rocky/python-xdis.git#egg=xdis
|
||||
pip install -e .
|
||||
pip install -r requirements-dev.txt
|
||||
- name: Test uncompyle6
|
||||
run: |
|
||||
make check
|
30
.github/workflows/ubuntu.yml
vendored
Normal file
30
.github/workflows/ubuntu.yml
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
name: uncompyle6 (ubuntu)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.6, 3.7, 3.8]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
# Until the next xdis release
|
||||
pip install git+git://github.com/rocky/python-xdis.git#egg=xdis
|
||||
pip install -e .
|
||||
pip install -r requirements-dev.txt
|
||||
- name: Test uncompyle6
|
||||
run: |
|
||||
make check
|
31
.github/workflows/windows.yml
vendored
Normal file
31
.github/workflows/windows.yml
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
name: uncompyle6 (windows)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: macos-latest
|
||||
strategy:
|
||||
matrix:
|
||||
os: [windows]
|
||||
python-version: [3.6, 3.7, 3.8]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
# Until the next xdis release
|
||||
pip install git+git://github.com/rocky/python-xdis.git#egg=xdis
|
||||
pip install -e .
|
||||
pip install -r requirements-dev.txt
|
||||
- name: Test uncompyle6
|
||||
run: |
|
||||
make check
|
2
.gitignore
vendored
2
.gitignore
vendored
@@ -6,9 +6,11 @@
|
||||
/.eggs
|
||||
/.hypothesis
|
||||
/.idea
|
||||
/.mypy_cache
|
||||
/.pytest_cache
|
||||
/.python-version
|
||||
/.tox
|
||||
.mypy_cache
|
||||
/.venv*
|
||||
/README
|
||||
/__pkginfo__.pyc
|
||||
|
19
.travis.yml
19
.travis.yml
@@ -1,17 +1,20 @@
|
||||
language: python
|
||||
|
||||
sudo: false
|
||||
|
||||
python:
|
||||
- '3.5'
|
||||
- '2.7'
|
||||
- '2.6'
|
||||
- '3.3'
|
||||
- '3.4'
|
||||
- '3.2'
|
||||
# - '3.5'
|
||||
# - '2.7'
|
||||
# - '3.4'
|
||||
- '3.6'
|
||||
- '3.8'
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- python: '3.7'
|
||||
dist: xenial # required for Python >= 3.7 (travis-ci/travis-ci#9069)
|
||||
|
||||
install:
|
||||
# Remove the next line when xdis 6.0.0 is released
|
||||
# - pip install git://github.com/rocky/python-xdis.git#egg=xdis
|
||||
- pip install -e .
|
||||
- pip install -r requirements-dev.txt
|
||||
|
||||
|
@@ -115,7 +115,7 @@ mechanisms and addressed problems and extensions by some other means.
|
||||
Specifically, in `uncompyle`, decompilation of python bytecode 2.5 &
|
||||
2.6 is done by transforming the byte code into a pseudo-2.7 Python
|
||||
bytecode and is based on code from Eloi Vanderbeken. A bit of this
|
||||
could have bene easily added by modifying grammar rules.
|
||||
could have been easily added by modifying grammar rules.
|
||||
|
||||
This project, `uncompyle6`, abandons that approach for various
|
||||
reasons. Having a grammar per Python version is much cleaner and it
|
||||
|
@@ -1,53 +1,41 @@
|
||||
# How to report a Bug
|
||||
<!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc-refresh-toc -->
|
||||
**Table of Contents**
|
||||
|
||||
## The difficulty of the problem
|
||||
- [The difficulty of the problem](#the-difficulty-of-the-problem)
|
||||
- [Is it really a bug?](#is-it-really-a-bug)
|
||||
- [Do you have valid bytecode?](#do-you-have-valid-bytecode)
|
||||
- [Semantic equivalence vs. exact source code](#semantic-equivalence-vs-exact-source-code)
|
||||
- [What to send (minimum requirements)](#what-to-send-minimum-requirements)
|
||||
- [What to send (additional helpful information)](#what-to-send-additional-helpful-information)
|
||||
- [But I don't *have* the source code!](#but-i-dont-have-the-source-code)
|
||||
- [But I don't *have* the source code and am incapable of figuring how how to do a hand disassembly!](#but-i-dont-have-the-source-code-and-am-incapable-of-figuring-how-how-to-do-a-hand-disassembly)
|
||||
- [Narrowing the problem](#narrowing-the-problem)
|
||||
- [Karma](#karma)
|
||||
- [Confidentiality of Bug Reports](#confidentiality-of-bug-reports)
|
||||
- [Ethics](#ethics)
|
||||
|
||||
<!-- markdown-toc end -->
|
||||
# The difficulty of the problem
|
||||
|
||||
This decompiler is a constant work in progress: Python keeps
|
||||
changing, and so does its code generation.
|
||||
|
||||
There is no Python decompiler yet that I know about that will
|
||||
decompile everything. Overall, I think this one probably does the best
|
||||
job of *any* Python decompiler that handles such a wide range of
|
||||
versions.
|
||||
There is no Python decompiler yet that I know about that will decompile everything. Overall, I think this one probably does the best job of *any* Python decompiler that handles such a wide range of versions.
|
||||
|
||||
But at any given time, there are a number of valid Python bytecode
|
||||
files that I know of that will cause problems. See, for example, the
|
||||
list in
|
||||
But at any given time, there are a number of valid Python bytecode files that I know of that will cause problems. See, for example, the list in
|
||||
[`test/stdlib/runtests.sh`](https://github.com/rocky/python-uncompyle6/blob/master/test/stdlib/runtests.sh).
|
||||
|
||||
But I understand: you would the bugs _you_ encounter addressed before
|
||||
all the other known bugs.
|
||||
There are far more bug reporters than there are bug fixers.
|
||||
|
||||
From my standpoint, the good thing about the bugs listed in
|
||||
`runtests.sh` is that each test case is small and isolated to a single
|
||||
kind of problem. And I'll tend to fix easier, more isolated cases than
|
||||
generic "something's wrong" kinds of bugs where I'd have to do a bit
|
||||
of work to figure out what's up, if not use some sort of mind reading,
|
||||
make some guesses, and perform some experiments to see if the guesses
|
||||
are correct. I can't read minds, nor am I into guessing games; I'd
|
||||
rather devote the effort spent instead towards fixing bugs that are
|
||||
precisely defined.
|
||||
Unless you are a sponsor of this project, it may take a while, maybe a week or so, before the bug report is noticed, let alone acted upon. Things eventually get fixed, but it may take years.
|
||||
|
||||
And it often turns out that by just fixing the well-defined and
|
||||
prescribed cases, the ill-defined amorphous cases as well will get
|
||||
handled as well.
|
||||
|
||||
In sum, you may need to do some work to have the bug you have found
|
||||
handled before the hundreds of other bugs, and things I could be
|
||||
doing.
|
||||
|
||||
No one is getting paid to work to work on this project, let alone the
|
||||
bugs you may have an interest in. If you require decompiling bytecode
|
||||
immediately, consider using a decompilation service, listed further
|
||||
down in this document.
|
||||
|
||||
## Is it really a bug?
|
||||
# Is it really a bug?
|
||||
|
||||
|
||||
### Do you have valid bytecode?
|
||||
## Do you have valid bytecode?
|
||||
|
||||
As mentioned in README.rst, this project doesn't handle obfuscated
|
||||
code. See README.rst for suggestions for how to remove some kinds of
|
||||
code or release candidates. See README.rst for suggestions for how to remove some kinds of
|
||||
obfuscation.
|
||||
|
||||
Checking if bytecode is valid is pretty simple: disassemble the code.
|
||||
@@ -55,11 +43,11 @@ Python comes with a disassembly module called `dis`. A prerequisite
|
||||
module for this package, `xdis` has a cross-python version
|
||||
disassembler called `pydisasm`.
|
||||
|
||||
### Semantic equivalence vs. exact source code
|
||||
## Semantic equivalence vs. exact source code
|
||||
|
||||
Consider how Python compiles something like "(x*y) + 5". Early on
|
||||
Python creates an "abstract syntax tree" (AST) for this. And this is
|
||||
"abstract" in the sense that unimportant, redundant or unnecceary
|
||||
"abstract" in the sense that unimportant, redundant or unnecessary
|
||||
items have been removed. Here, this means that any notion that you
|
||||
wrote "x+y" in parenthesis is lost, since in this context they are
|
||||
unneeded. Also lost is the fact that the multiplication didn't have
|
||||
@@ -129,10 +117,9 @@ if False:
|
||||
|
||||
Python will eliminate the entire "if" statement.
|
||||
|
||||
So just because the text isn't the same, does not
|
||||
necessarily mean there's a bug.
|
||||
So just because the text isn't the same, this does not necessarily mean there's a bug.
|
||||
|
||||
## What to send (minimum requirements)
|
||||
# What to send (minimum requirements)
|
||||
|
||||
The basic requirement is pretty simple:
|
||||
|
||||
@@ -146,7 +133,7 @@ sending is too large.
|
||||
|
||||
Also try to narrow the bug. See below.
|
||||
|
||||
## What to send (additional helpful information)
|
||||
# What to send (additional helpful information)
|
||||
|
||||
Some kind folks also give the invocation they used and the output
|
||||
which usually includes an error message produced. This is
|
||||
@@ -159,32 +146,20 @@ provide the input command and the output from that, please give:
|
||||
* Python interpreter version used
|
||||
|
||||
|
||||
### But I don't *have* the source code!
|
||||
## But I don't *have* the source code!
|
||||
|
||||
Sure, I get it. No problem. There is Python assembly code on parse
|
||||
errors, so simply by hand decompile that. To get a full disassembly,
|
||||
use `pydisasm` from the [xdis](https://pypi.python.org/pypi/xdis)
|
||||
package. Opcodes are described in the documentation for
|
||||
the [dis](https://docs.python.org/3.6/library/dis.html) module.
|
||||
There is Python assembly code on parse errors, so simply by hand decompile that. To get a full disassembly, use `pydisasm` from the [xdis](https://pypi.python.org/pypi/xdis) package. Opcodes are described in the documentation for the [dis](https://docs.python.org/3.6/library/dis.html) module.
|
||||
|
||||
### But I don't *have* the source code and am incapable of figuring how how to do a hand disassembly!
|
||||
### But I don't *have* the source code and am incapable of figuring how to do a hand disassembly!
|
||||
|
||||
Well, you could learn. No one is born into this world knowing how to
|
||||
disassemble Python bytecode. And as Richard Feynman once said, "What
|
||||
one fool can learn, so can another."
|
||||
Well, you could learn. No one is born into this world knowing how to disassemble Python bytecode. And as Richard Feynman once said, "What one fool can learn, so can another."
|
||||
|
||||
If this is too difficult, or too time consuming, or not of interest to
|
||||
you, then perhaps what require is a decompilation service. [Crazy
|
||||
Compilers](http://www.crazy-compilers.com/decompyle/) offers a
|
||||
byte-code decompiler service for versions of Python up to 2.6. (If
|
||||
there are others around let me know and I'll list them here.)
|
||||
If this is too difficult, or too time consuming, or not of interest to you, then you might consider [sponsoring](https://github.com/sponsors/rocky) the project. [Crazy
|
||||
Compilers](http://www.crazy-compilers.com/decompyle/) offers a byte-code decompiler service for versions of Python up to 2.6. (If there are others around let me know and I'll list them here.)
|
||||
|
||||
## Narrowing the problem
|
||||
# Narrowing the problem
|
||||
|
||||
I don't need or want the entire source code base for the file(s) or
|
||||
module(s) can't be decompiled. I just need those file(s) or module(s).
|
||||
If there are problems in several files, file a bug report for each
|
||||
file.
|
||||
I don't need or want the entire source code base for the file(s) or module(s) can't be decompiled. I just need those file(s) or module(s). If there are problems in several files, file a bug report for each file.
|
||||
|
||||
Python modules can get quite large, and usually decompilation problems
|
||||
occur in a single function or maybe the main-line code but not any of
|
||||
@@ -197,22 +172,44 @@ what doesn't. That is useful. Or maybe the same file will decompile
|
||||
properly on a neighboring version of Python. That is helpful too.
|
||||
|
||||
In sum, the more you can isolate or narrow the problem, the more
|
||||
likley the problem will be fixed and fixed sooner.
|
||||
likely the problem will be fixed and fixed sooner.
|
||||
|
||||
## Confidentiality of Bug Reports
|
||||
# Karma
|
||||
|
||||
I realize that following the instructions given herein puts a bit of
|
||||
burden on the bug reporter. This is justified as attempts to balance somewhat the burden and effort needed to fix the bug and the attempts to balance number of would-be bug reporters with the number of bug fixers. Better bug reporters are more likely to move
|
||||
in the category of bug fixers.
|
||||
|
||||
The barrier to reporting a big is pretty small: all you really need is
|
||||
a github account, and the ability to type something after clicking
|
||||
some buttons. So the reality is that many people just don't bother to
|
||||
read these instructions, let alone follow it to any simulacrum.
|
||||
|
||||
That said, bugs sometimes get fixed even though these instructions are not followed.
|
||||
|
||||
I may take into consideration is the bug reporter's karma.
|
||||
|
||||
* Have you demonstrably contributed to open source? I may look at your github profile to see what contributions you have made, how popular those contributions are, or how popular you are.
|
||||
* How appreciative are you? Have you starred this project that you are seeking help from? Have you starred _any_ github project? And the above two kind of feed into ...
|
||||
* Attitude. Some people feel that they are doing me and the world a great favor by just pointing out that there is a problem whose solution would greatly benefit them. (This might account partially those that have this attitude often don't read or follow instructions such as those given here.)
|
||||
|
||||
|
||||
# Confidentiality of Bug Reports
|
||||
|
||||
When you report a bug, you are giving up confidentiality to the source
|
||||
code and the byte code. However, I would imagine that if you have
|
||||
narrowed the problem sufficiently, confidentiality of the little that
|
||||
remains would not be an issue.
|
||||
|
||||
However feel free to remove any commments, and modify variable names
|
||||
However feel free to remove any comments, and modify variable names
|
||||
or constants in the source code.
|
||||
|
||||
## Ethics
|
||||
If there is some legitimate reason to keep confidentiality, you can contact me by email to explain the extenuating circumstances. However I tend to discard without reading anonymous email.
|
||||
|
||||
# Ethics
|
||||
|
||||
I do not condone using this program for unethical or illegal purposes.
|
||||
More detestful, at least to me, is asking for help to assist you in
|
||||
More detestable, at least to me, is asking for help to assist you in
|
||||
something that might not legitimate.
|
||||
|
||||
Don't use the issue tracker for such solicitations. To try to stave
|
||||
|
11
Makefile
11
Makefile
@@ -40,12 +40,19 @@ check-3.0 check-3.1 check-3.2 check-3.6:
|
||||
check-3.7: pytest
|
||||
$(MAKE) -C test check
|
||||
|
||||
check-3.8:
|
||||
$(MAKE) -C test check
|
||||
|
||||
#:PyPy 2.6.1 PyPy 5.0.1, or PyPy 5.8.0-beta0
|
||||
# Skip for now
|
||||
2.6 5.0 5.3 5.6 5.8:
|
||||
|
||||
#:PyPy pypy3-2.4.0 Python 3:
|
||||
pypy-3.2 2.4:
|
||||
#:PyPy pypy3-2.4.0 Python 3.6.1:
|
||||
7.1 pypy-3.2 2.4:
|
||||
$(MAKE) -C test $@
|
||||
|
||||
#:PyPy pypy3-2.4.0 Python 3.6.9:
|
||||
7.2:
|
||||
$(MAKE) -C test $@
|
||||
|
||||
#: Run py.test tests
|
||||
|
626
NEWS
626
NEWS
@@ -1,626 +0,0 @@
|
||||
uncompyle6 3.2.1 2018-06-04 MF
|
||||
|
||||
- Python 1.4 and 1.5 bug fixes
|
||||
|
||||
uncompyle6 3.2.0 2018-05-19 Rocket Scientist
|
||||
|
||||
- Add rudimentary 1.4 support (still a bit buggy)
|
||||
- add --tree+ option to show formatting rule, when it is constant
|
||||
- Python 2.7.15candidate1 support (via xdis)
|
||||
- bug fixes, especially for 3.7 (but 2.7 and 3.6 and others as well)
|
||||
|
||||
uncompyle6 3.1.3 2018-04-16
|
||||
|
||||
- Add some Python 3.7 rules, such as for handling LOAD_METHOD (not complete)
|
||||
- Fix some fragment bugs
|
||||
- small doc changes
|
||||
|
||||
uncompyle6 3.1.2 2018-04-08 Eastern Orthodox Easter
|
||||
|
||||
- Python 3.x subclass and call parsing fixes
|
||||
- Allow/note running on Python 3.1
|
||||
- improve 3.5+ BUILD_MAP_UNPACK
|
||||
- DRY instruction building code between 2.x and 3.x
|
||||
- expand testing
|
||||
|
||||
uncompyle6 3.1.1 2018-04-01 Easter April Fool's
|
||||
|
||||
Jesus on Friday's New York Times puzzle: "I'm stuck on 2A"
|
||||
|
||||
- fill out 3.5+ BUILD_MAP_UNPACK (more work is needed)
|
||||
- fill out 3.4+ CALL_FUNCTION_... (more work is needed)
|
||||
- fill out 3.5 MAKE_FUNCTION (more work is needed)
|
||||
- reduce 3.5, 3.6 control-flow bugs
|
||||
- reduce ambiguity in rules that lead to long (exponential?) parses
|
||||
- limit/isolate some 2.6/2.7,3.x grammar rules
|
||||
- more runtime testing of decompiled code
|
||||
- more removal of parenthesis around calls via setting precidence
|
||||
|
||||
uncompyle6 3.1.0 2018-03-21 Equinox
|
||||
|
||||
- Add code_deparse_with_offset() fragment function.
|
||||
- Correct paramenter call fragment deparse_code()
|
||||
- Lots of 3.6, 3.x, and 2.7 bug fixes
|
||||
About 5% of 3.6 fail parsing now. But
|
||||
semantics still needs much to be desired.
|
||||
|
||||
uncompyle6 3.0.1 2018-02-17
|
||||
|
||||
- All Python 2.6.9 standard library files weakly verify
|
||||
- Many 3.6 fixes. 84% of the first 200 standard library files weakly compile.
|
||||
One more big push is needed to get the remaining to compile
|
||||
- Many decompilation fixes for other Python versions
|
||||
- Add more to the test framework
|
||||
- And more add tests target previous existing bugs more completely
|
||||
- sync recent license changes in metadata
|
||||
|
||||
uncompyle6 3.0.0 2018-02-17
|
||||
|
||||
- deparse_code() and lookalikes from the various semantic actions are
|
||||
now deprecated. Instead use new API code_deparse() which makes the
|
||||
version optional and bundles debug options into a dictionary.
|
||||
- License changed to GPL3.
|
||||
- Many Python 3.6 fixes, especially around handling EXTENDED_ARGS
|
||||
Due to the reduction in operand size for JUMP's there are many
|
||||
more EXTENDED_ARGS instructions which can be the targets
|
||||
of jumps, and messes up the peephole-like analysis that is
|
||||
done for control flow since we don't have something better in place.
|
||||
- Code has been reorganized to be more instruction nametuple based where it
|
||||
has been more bytecode array based. There was and still is code that had
|
||||
had magic numbers to advance instructions or to pick out operands.
|
||||
- Bug fixes in numerous other Python versions
|
||||
- Instruction display improved
|
||||
- Keep global statements in fixed order (from wangym5106)
|
||||
|
||||
A bit more work is still needed for 3.6 especially in the area of
|
||||
function calls and definitions.
|
||||
|
||||
|
||||
uncompyle6 2.16.0 2018-02-17
|
||||
|
||||
- API additions:
|
||||
- add fragments.op_at_code_loc() and
|
||||
- fragments.deparsed_find()_
|
||||
- Better 2.7 end_if and COME_FROM determination
|
||||
- Fix up 3.6+ CALL_FUNCTION_EX
|
||||
- Misc pydisasm fixes
|
||||
- Weird comprehension bug seen via new loctraceback
|
||||
- Fix Python 3.5+ CALL_FUNCTION_VAR and BUILD_LIST_UNPACK in call; with this
|
||||
we can can handle 3.5+ f(a, b, *c, *d, *e) now
|
||||
|
||||
uncompyle6 2.15.1 2018-02-05
|
||||
|
||||
- More bug fixes and revert an improper bug fix in 2.15.0
|
||||
|
||||
uncompyle6 2.15.0 2018-02-05 pycon2018.co
|
||||
|
||||
- Bug fixes
|
||||
- Code fragment improvements
|
||||
- Code cleanups
|
||||
- Expand testing
|
||||
|
||||
uncompyle6 2.15.1 2018-01-27
|
||||
|
||||
- Add --linemap option to give line correspondences
|
||||
between original source lines and reconstructed line sources.
|
||||
It is far from perfect, but it is a start
|
||||
- Add a new class of tests: tests which when decompiled check themselves
|
||||
- Split off Python version semantic action customizations into its own file
|
||||
- Fix 2.7 bug in ifelse loop statement
|
||||
- Handle 3.6+ EXTENDED_ARGs for POP_JUMP_IF... instructions
|
||||
- Correct 3.6+ calls with kwargs
|
||||
- Describe the difficulty of 3.6 in README
|
||||
|
||||
uncompyle6 2.14.3 2018-01-19
|
||||
|
||||
- Fix bug in 3.5+ await stmt
|
||||
- Better version to magic handling; handle 3.5.2 .. 3.5.4 versions
|
||||
- Improve/correct test_pyenvlib.py status messages
|
||||
- Fix some 2.7 and 2.6 parser bugs
|
||||
- Fix whilelse parsing bugs
|
||||
- Correct 2.5- decorator parsing
|
||||
- grammar for decorators matches AST a little more
|
||||
- better tests in setup.py for running the right version of Python
|
||||
- Fix 2.6- parsing of "for .. try/else" ... with "continue" inside
|
||||
|
||||
uncompyle6 2.14.2 2018-01-09 Samish
|
||||
|
||||
Decompilation bug fixes, mostly 3.6 and pre 2.7
|
||||
|
||||
- 3.6 FUNCTION_EX (somewhat)
|
||||
- 3.6 FUNCTION_EX_KW fixes
|
||||
- 3.6 MAKE_FUNCTION fixes
|
||||
- correct 3.5 CALL_FUNCTION_VAR
|
||||
- stronger 3.x "while 1" testing
|
||||
- Fix bug in if's with "pass" bodies. Fixes #104
|
||||
- try/else and try/finally fixes on 2.6-
|
||||
- limit pypy customization to pypy
|
||||
- Add addr fields in COME_FROMS
|
||||
- Allow use of full instructions in parser reduction routines
|
||||
- Reduce grammar in Python 3 by specialization more to specific
|
||||
Python versions
|
||||
- Match Python AST names more closely when possible
|
||||
|
||||
uncompyle6 2.14.1 2017-12-10 Dr. Gecko
|
||||
|
||||
- Many decompilation bugfixes
|
||||
- Grammar rule reduction and version isolation
|
||||
- Match higher-level nonterminal names more closely
|
||||
with Python AST
|
||||
- Start automated Python stdlib testing - full round trip
|
||||
|
||||
uncompyle6 2.14.0 2017-11-26 johnnybamazing
|
||||
|
||||
- Start to isolate grammar rules between versions
|
||||
and remove used grammar rules
|
||||
- Fix a number of bytecode decompile problems
|
||||
(many more remain)
|
||||
- Add stdlib/runtests.sh for even more rigorous testing
|
||||
|
||||
uncompyle6 2.13.3 2017-11-13
|
||||
|
||||
Overall: better 3.6 decompiling and some much needed code refactoring and cleanup
|
||||
|
||||
|
||||
- Start noting names in for template-action names; these are
|
||||
used to check/assert we have the right node type
|
||||
- Simplify <import_from> rule
|
||||
- Pypy 5.80-beta testing tolerance
|
||||
- Start to clean up instruction mangling phase by using 3.6-style instructions
|
||||
rather trying to parse the bytecode array. This largely been done in for versions 3.x;
|
||||
3.0 custom mangling code has been reduced;
|
||||
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
|
||||
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.
|
||||
- Refactor find_jump_targets() with via working of of instructions rather the bytecode array.
|
||||
- use --weak-verify more and additional fuzzing on verify()
|
||||
- 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,
|
||||
well, *fragments*.
|
||||
- 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
|
||||
- reinstate some bytecode tests since decompiling has gotten better
|
||||
- Revise how to report a bug
|
||||
|
||||
uncompyle6 2.13.2 2017-10-12
|
||||
|
||||
- Re-release using a more automated approach
|
||||
|
||||
uncompyle6 2.13.1 2017-10-11
|
||||
|
||||
- Re-release because Python 2.4 source uploaded rather than 2.6-3.6
|
||||
|
||||
uncompyle6 2.13.0 2017-10-10
|
||||
|
||||
- Fixes in deparsing lambda expressions
|
||||
- Improve table-semantics descriptions
|
||||
- Document hacky customize arg count better (until we can remove it)
|
||||
- Update to use xdis 3.7.0 or greater
|
||||
|
||||
uncompyle6 2.12.0 2017-09-26
|
||||
|
||||
- Use xdis 3.6.0 or greater now
|
||||
- Small semantic table cleanups
|
||||
- Python 3.4's terms a little names better
|
||||
- Slightly more Python 3.7, but still failing a lot
|
||||
- Cross Python 2/3 compatibility with annotation arguments
|
||||
|
||||
uncompyle6 2.11.5 2017-08-31
|
||||
|
||||
- Skeletal support for Python 3.7
|
||||
|
||||
uncompyle6 2.11.4 2017-08-15
|
||||
|
||||
* scanner and parser now allow 3-part version string lookups,
|
||||
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.
|
||||
* some routines here moved to xdis. Use the xdis version
|
||||
* README.rst: Link typo Name is trepan2 now not trepan
|
||||
* xdis-forced change adjust for COMPARE_OP "is-not" in
|
||||
semanatic routines. We need "is not".
|
||||
* Some PyPy tolerance in validate testing.
|
||||
* Some pyston tolerance
|
||||
|
||||
uncompyle6 2.11.3 2017-08-09
|
||||
|
||||
Very minor changes
|
||||
|
||||
- RsT doc fixes and updates
|
||||
- use newer xdis, but not too new; 3.5.2 breaks uncompyle6
|
||||
- use xdis opcode sets
|
||||
- xdis "exception match" is now "exception-match"
|
||||
|
||||
uncompyle6 2.11.2 2017-07-09
|
||||
|
||||
- Start supporting Pypy 3.5 (5.7.1-beta)
|
||||
- use xdis 3.5.0's opcode sets and require xdis 3.5.0
|
||||
- Correct some Python 2.4-2.6 loop detection
|
||||
- guard against badly formatted bytecode
|
||||
|
||||
uncompyle6 2.11.1 2017-06-25
|
||||
|
||||
- Python 3.x annotation and function signature fixes
|
||||
- Bump xdis version
|
||||
- Small pysource bug fixes
|
||||
|
||||
uncompyle6 2.11.0 2017-06-18 Fleetwood
|
||||
- Major improvements in fragment tracking
|
||||
* Add nonterminal node in extractInfo
|
||||
* tag more offsets in expressions
|
||||
* tag array subscripts
|
||||
* set YIELD value offset in a <yield> expr
|
||||
* 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
|
||||
- Fix bug in snowflake Python 3.5 *args kwargs
|
||||
|
||||
uncompyle6 2.10.1 2017-06-3 Marylin Frankel
|
||||
|
||||
- fix some fragments parsing bugs
|
||||
- was returning the wrong type sometimes in deparse_code_around_offset()
|
||||
- capture function name in offsets
|
||||
- track changes to ifelstrmtr node from pysource into fragments
|
||||
|
||||
uncompyle6 2.10.0 2017-05-30 Elaine Gordon
|
||||
|
||||
- Add fuzzy offset deparse look up
|
||||
- 3.6 bug fixes
|
||||
- fix EXTENDED_ARGS handling (and in 2.6 and others)
|
||||
- semantic routine make_function fragments.py
|
||||
- MAKE_FUNCTION handling
|
||||
- CALL_FUNCTION_EX handling
|
||||
- async property on defs
|
||||
- support for CALL_FUNCTION_KW (moagstar)
|
||||
- 3.5+ UNMAP_PACK and BUILD_UNMAP_PACK handling
|
||||
- 3.5 FUNCTION_VAR bug
|
||||
- 3.x pass statement insdie while True
|
||||
- Improve 3.2 decompilation
|
||||
- Fixed -o argument processing (grkov90)
|
||||
- Reduce scope of LOAD_ASSERT as expr to 3.4+
|
||||
- "await" statement fixes
|
||||
- 2.3, 2.4 "if 1 .." fixes
|
||||
- 3.x annotation fixes
|
||||
|
||||
uncompyle6 2.9.11 2017-04-06
|
||||
|
||||
- Better support for Python 3.5+ BUILD_MAP_UNPACK
|
||||
- Start 3.6 CALL_FUNCTION_EX support
|
||||
- Many decompilation bug fixes. (Many more remain). See ChangeLog
|
||||
|
||||
uncompyle6 2.9.10 2017-02-25
|
||||
|
||||
- Python grammar rule fixes
|
||||
- Add ability to get grammar coverage on runs
|
||||
- Handle Python 3.6 opcode BUILD_CONST_KEYMAP
|
||||
|
||||
uncompyle6 2.9.9 2016-12-16
|
||||
|
||||
- Remaining Python 3.5 ops handled
|
||||
(this also means more Python 3.6 ops are handled)
|
||||
- Python 3.5 and 3.6 async and await handled
|
||||
- Python 3.0 decompilation improved
|
||||
- Python 3 annotations fixed
|
||||
- Better control-flow detection
|
||||
- Code cleanups and misc bug fixes
|
||||
|
||||
uncompyle6 2.9.8 2016-12-16
|
||||
|
||||
- Better control-flow detection
|
||||
- pseudo instruction THEN in 2.x
|
||||
to disambiguate if from and
|
||||
- fix bug in --verify option
|
||||
- DRY (a little) control-flow detection
|
||||
- fix syntax in tuples with one element
|
||||
- if AST rule inheritance in Python 2.5
|
||||
- NAME_MODULE removal for Python <= 2.4
|
||||
- verify call fixes for Python <= 2.4
|
||||
- more Python lint
|
||||
|
||||
uncompyle6 2.9.7 2016-12-16
|
||||
|
||||
- Start to handle 3.5/3.6 build_map_unpack_with_call
|
||||
- Some Python 3.6 bytecode to wordcode conversion fixes
|
||||
- option -g: show start-end range when possible
|
||||
- track print_docstring move to help (used in python 3.1)
|
||||
- verify: allow RETURN_VALUE to match RETURN_END_IF
|
||||
- some 3.2 compatibility
|
||||
- Better Python 3 control flow detection by adding Pseudo ELSE opcodes
|
||||
|
||||
uncompyle6 2.9.6 2016-12-04
|
||||
|
||||
- Shorten Python3 grammars with + and *
|
||||
this requires spark parser 1.5.1
|
||||
- Add some AST reduction checks to improve
|
||||
decompile accuracy. This too requires
|
||||
spark parser 1.5.1
|
||||
|
||||
uncompyle6 2.9.6 2016-11-20
|
||||
|
||||
- Correct MANIFEST.in
|
||||
- More AST grammar checking
|
||||
- --linemapping option or linenumbers.line_number_mapping()
|
||||
Shows correspondence of lines between source
|
||||
and decompiled source
|
||||
- Some control flow adjustments in code for 2.x.
|
||||
This is probably an improvement in 2.6 and before.
|
||||
For 2.7 things are just shuffled around a little. Sigh.
|
||||
Overall I think we are getting more precise in
|
||||
or analysis even if it is not always reflected
|
||||
in the results.
|
||||
- better control flow debugging output
|
||||
- Python 2 and 3 detect structure code is more similar
|
||||
- Handle Docstrings with embedded triple quotes (""")
|
||||
|
||||
uncompyle6 2.9.5 2016-11-13
|
||||
|
||||
- Fix Python 3 bugs:
|
||||
* improper while 1 else
|
||||
* docstring indent
|
||||
* 3.3 default values in lambda expressions
|
||||
* start 3.0 decompilation (needs newer xdis)
|
||||
- Start grammar misparse checking
|
||||
|
||||
|
||||
uncompyle6 2.9.4 2016-11-02
|
||||
|
||||
- Handle Python 3.x function annotations
|
||||
- track def keyword-parameter line-splitting in source code better
|
||||
- bump min xdis version to mask previous xdis bug
|
||||
|
||||
uncompyle6 2.9.3 2016-10-26
|
||||
|
||||
Release forced by incompatibility change in xdis 3.2.0.
|
||||
|
||||
- Python 3.1 bugs:
|
||||
* handle "with ... as"
|
||||
* handle "with"
|
||||
* Start handling def (...) -> yy (has bugs still)
|
||||
|
||||
- DRY Python 3.x via inheritance
|
||||
- Python 3.6 work (from Daniel Bradburn)
|
||||
* Handle 3.6 buildstring
|
||||
* Handle 3.6 handle single and multiple fstring better
|
||||
|
||||
|
||||
uncompyle6 2.9.2 2016-10-15
|
||||
|
||||
- use source-code line breaks to assist in where to break
|
||||
in tuples and maps
|
||||
- Fix Python 1.5 decompyle bugs
|
||||
- Fix some Python 2.6 and below bugs
|
||||
- DRY fragments.py code a little
|
||||
|
||||
uncompyle6 2.9.1 2016-10-09
|
||||
|
||||
- Improved Python 1.5 decompiling
|
||||
- Handle old-style pre Python 2.2 classes
|
||||
|
||||
uncompyle6 2.9.0 2016-10-09
|
||||
|
||||
- Use xdis 3.0.0 protocol load_module.
|
||||
this Forces change in requirements.txt and _pkg_info_.py
|
||||
- Start Python 1.5 decompiling; another round of work is needed to
|
||||
remove bugs
|
||||
- Simplify python 2.1 grammar
|
||||
- Fix bug with -t ... Wasn't showing source text when -t option was given
|
||||
- Fix 2.1-2.6 bug in list comprehension
|
||||
|
||||
uncompyle6 2.8.4 2016-10-08
|
||||
|
||||
- Python 3 disassembly bug fixes
|
||||
- Python 3.6 fstring bug fixes (from moagstar)
|
||||
- Python 2.1 disassembly
|
||||
- COME_FROM suffixes added in Python3
|
||||
- use .py extension in verification disassembly
|
||||
|
||||
uncompyle6 2.8.3 2016-09-11 live from NYC!
|
||||
|
||||
NOTE: this is possibly the last release before a major reworking of
|
||||
control-flow structure detection is done.
|
||||
|
||||
- Lots of bug fixes in decompilation:
|
||||
* 3.0 .. 3.4 whileTrue bug
|
||||
* 3.x function declaration deparsing:
|
||||
. 3.0 .. 3.2 *args processing
|
||||
. 3.0 .. 3.2 call name and kwargs bug
|
||||
. 3.0 .. getting parameter of *
|
||||
. 3.0 .. handling variable number of args
|
||||
. 3.0 .. "if" structure bugs
|
||||
* 3.5+ if/else bugs
|
||||
* 2.2-2.6 bugs
|
||||
. try/except control flow
|
||||
. a == b == c -like detection
|
||||
. generator detection
|
||||
. "while .. and" statement bugs
|
||||
. handle "except <cond>, <var>"
|
||||
. use older raise format in 2.x
|
||||
- scanner "disassemble" is now "ingest". True disassembly is done by xdis
|
||||
- Start accepting Python 3.1 bytecode
|
||||
- Add --weak-verify option on test_pyenvlib and test_pythonlib. This
|
||||
catches more bugs more easily
|
||||
- bump xdis requirement so we can deparse dropbox 2.5 code
|
||||
- Added H. Goebel's changes before 2.4 in DECOMPYLE-2.4-CHANGELOG.txt
|
||||
|
||||
uncompyle6 2.8.2 2016-08-29
|
||||
|
||||
- Handle Python 3.6 format string conversions !r, !s, !a
|
||||
- Start to handle 3.1 bytecode
|
||||
- Fix some PyPy translation bugs
|
||||
- We now only handle 3.6.0a3+ since that is incompatible with 3.6 before that
|
||||
|
||||
uncompyle6 2.8.1 2016-08-20
|
||||
|
||||
- Add Python 2.2 decompilation
|
||||
|
||||
- Fix bugs
|
||||
* PyPy LOOKUP_METHOD bug
|
||||
* Python 3.6 FORMAT_VALUE handles expressions now
|
||||
|
||||
uncompyle6 2.8.0 2016-08-03
|
||||
|
||||
- Start Python 3.6 support (moagstar)
|
||||
more work on PEP 498 needed
|
||||
- tidy bytecode/word output
|
||||
- numerous decompiling bugs fixed
|
||||
- grammar testing started
|
||||
- show magic number in deparsed output
|
||||
- better grammar and semantic action segregation based
|
||||
on python bytecode version
|
||||
|
||||
uncompyle6 2.7.1 2016-07-26
|
||||
|
||||
- PyPy bytecodes for 2.7 and 3.2 added
|
||||
- Instruction formatting improved slightly
|
||||
- 2.7 bytecode "continue" bug fixed
|
||||
|
||||
uncompyle6 2.7.0 2016-07-15
|
||||
|
||||
- Many Syntax and verification bugs removed
|
||||
tested on standard libraries from 2.3.7 to 3.5.1
|
||||
and they all decompile and verify fine.
|
||||
I'm sure there are more bugs though.
|
||||
|
||||
uncompyle6 2.6.2 2016-07-11 Manhattenhenge
|
||||
|
||||
- Extend bytecodes back to 2.3
|
||||
- Fix bugs:
|
||||
* 3.x and 2.7 set comprehensions,
|
||||
* while1 loops
|
||||
* continue statements
|
||||
- DRY and segregate grammar more
|
||||
|
||||
uncompyle6 2.6.1 2016-07-08
|
||||
|
||||
- Go over Python 2.5 bytecode deparsing
|
||||
all library programs now deparse
|
||||
- Fix a couple bugs in 2.6 deparsing
|
||||
|
||||
uncompyle6 2.6.0 2016-07-07
|
||||
|
||||
- Improve Python 2.6 bytecode deparsing:
|
||||
stdlib now will deparse something
|
||||
- Better <2.6 vs. 2.7 grammar separation
|
||||
- Fix some 2.7 deparsing bugs
|
||||
- Fix bug in installing uncompyle6 script
|
||||
- Doc improvements
|
||||
|
||||
uncompyle6 2.5.0 2016-06-22 Summer Solstice
|
||||
|
||||
- Much better Python 3.2-3.5 coverage.
|
||||
3.4.6 is probably the best;3.2 and 3.5 are weaker
|
||||
- Better AST printing with -t
|
||||
- Better error reporting
|
||||
- Better fragment offset tracking
|
||||
- Some (much-needed) code refactoring
|
||||
|
||||
uncompyle6 2.4.0 2016-05-18 (in memory of Lewis Bernstein)
|
||||
|
||||
- Many Python 3 bugs fixed:
|
||||
* Python 3.2 to 3.5 libraries largely
|
||||
uncompyle and most verify
|
||||
- pydisassembler:
|
||||
* disassembles all code objects in a file
|
||||
* can select showing bytecode before
|
||||
or after uncompyle mangling, option -U
|
||||
- DRY scanner code (but more is desired)
|
||||
- Some code cleanup (but more is desired)
|
||||
- Misc Bugs fixed:
|
||||
* handle complex number unmarshaling
|
||||
* Running on Python 2 to works on Python 3.5 bytecodes now
|
||||
|
||||
uncompyle6 2.3.5 and 2.3.6 2016-05-14
|
||||
|
||||
- Python 2 class decorator fix (thanks to Tey)
|
||||
- Fix fragment parsing bugs
|
||||
- Fix some Python 3 parsing bugs:
|
||||
* Handling single in * parameter
|
||||
* "while True"
|
||||
* escape from for inside if
|
||||
* yield expressions
|
||||
- Correct history based on info from Dan Pascu
|
||||
- Fix up pip packaging, ugh.
|
||||
|
||||
uncompyle6 2.3.4 2016-05-5
|
||||
|
||||
- More Python 3.5 parsing bugs addressed
|
||||
- decompiling Python 3.5 from other Python versions works
|
||||
- test from Python 3.2
|
||||
- remove "__module__ = __name__" in 3.0 <= Python 3.2
|
||||
|
||||
uncompyle6 2.3.3 2016-05-3
|
||||
|
||||
- Fix bug in running uncompyle6 script on Python 3
|
||||
- Speed up performance on deparsing long lists by grouping in chunks of 32 and 256 items
|
||||
- DRY Python expressions between Python 2 and 3
|
||||
|
||||
uncompyle6 2.3.2 2016-05-1
|
||||
|
||||
- Add --version option standalone scripts
|
||||
- Correct License information in package
|
||||
- expose fns uncompyle_file, load_file, and load_module
|
||||
- Start to DRY Python2 and Python3 grammars Separate out 3.2, and 3.5+
|
||||
specific grammar code
|
||||
- Fix bug in 3.5+ constant map parsing
|
||||
|
||||
uncompyle6 2.3.0, 2.3.1 2016-04-30
|
||||
|
||||
- Require spark_parser >= 1.1.0
|
||||
|
||||
uncompyle6 2.2.0 2016-04-30
|
||||
|
||||
- Spark is no longer here but pulled separate package spark_parse
|
||||
- Python 3 parsing fixes
|
||||
- More tests
|
||||
|
||||
uncompyle6 2.2.0 2016-04-02
|
||||
|
||||
- Support single-mode (in addition to exec-mode) compilation
|
||||
- Start to DRY Python 2 and Python 3 grammars
|
||||
- Fix bug in if else ternary construct
|
||||
- Fix bug in uncomplye6 -d and -r options (via lelicopter)
|
||||
|
||||
|
||||
uncompyle6 2.1.3 2016-01-02
|
||||
|
||||
- Limited support for decompiling Python 3.5
|
||||
- Improve Python 3 class deparsing
|
||||
- Handle MAKE_CLOSURE opcode
|
||||
- Start to DRY opcode code.
|
||||
- increase test coverage
|
||||
- fix misc small bugs and some improvements
|
||||
|
||||
uncompyle6 2.1.2 2015-12-31
|
||||
|
||||
- Fix cross-version Marshal loading
|
||||
- Handle Python 3.3 . dotted class names
|
||||
- Limited 3.5 support: allows deparsing other versions
|
||||
- Refactor code more, misc bug fixes
|
||||
|
||||
uncompyle6 2.1.1 2015-12-27
|
||||
|
||||
- packaging issues
|
||||
|
||||
uncompyle6 2.1.0 2015-12-27
|
||||
|
||||
- Python 3.x deparsing much more solid
|
||||
- Better cross-version deparsing
|
||||
|
||||
Some bugs squashed while other run rampant. Some code cleanup while
|
||||
much more is yet needed. More tests added, but many more are needed.
|
||||
|
||||
|
||||
uncompyle6 2.0.0 2015-12-11
|
||||
|
||||
Changes from uncompyle2
|
||||
|
||||
- Can give code fragments given an instruction offset. See
|
||||
https://github.com/rocky/python-uncompyle6/wiki/Deparsing-technology-and-its-use-in-exact-location-reporting
|
||||
- Runs under Python3. Decompiles Python 2.5-2.7 and some Python 3.2-3.4
|
||||
- Allows for multiple Python grammars, specifically Python2 vs Python 3
|
||||
- Add a cross-version Python disassembler command-line utility
|
||||
- Add some py.test and start reorganizing tests
|
||||
|
||||
SPARK:
|
||||
add option to show grammar rules applied
|
||||
allow Python-style # comments in grammar
|
||||
Runs on Python 3 and Python 2
|
239
README.rst
239
README.rst
@@ -1,4 +1,6 @@
|
||||
|buildstatus|
|
||||
|buildstatus| |Pypi Installs| |Latest Version| |Supported Python Versions|
|
||||
|
||||
|packagestatus|
|
||||
|
||||
uncompyle6
|
||||
==========
|
||||
@@ -11,8 +13,9 @@ Introduction
|
||||
------------
|
||||
|
||||
*uncompyle6* translates Python bytecode back into equivalent Python
|
||||
source code. It accepts bytecodes from Python version 1.5, and 2.1 to
|
||||
3.7 or so, including PyPy bytecode and Dropbox's Python 2.5 bytecode.
|
||||
source code. It accepts bytecodes from Python version 1.0 to version
|
||||
3.8, spanning over 24 years of Python releases. We include Dropbox's
|
||||
Python 2.5 bytecode and some PyPy bytecodes.
|
||||
|
||||
Why this?
|
||||
---------
|
||||
@@ -29,11 +32,11 @@ CPython bytecode decompilers is the ability to deparse just
|
||||
*fragments* of source code and give source-code information around a
|
||||
given bytecode offset.
|
||||
|
||||
I use the tree fragments to deparse fragments of code inside my
|
||||
trepan_ debuggers_. For that, bytecode offsets are recorded and
|
||||
associated with fragments of the source code. This purpose, although
|
||||
compatible with the original intention, is yet a little bit different.
|
||||
See this_ for more information.
|
||||
I use the tree fragments to deparse fragments of code *at run time*
|
||||
inside my trepan_ debuggers_. For that, bytecode offsets are recorded
|
||||
and associated with fragments of the source code. This purpose,
|
||||
although compatible with the original intention, is yet a little bit
|
||||
different. See this_ for more information.
|
||||
|
||||
Python fragment deparsing given an instruction offset is useful in
|
||||
showing stack traces and can be encorporated into any program that
|
||||
@@ -43,14 +46,15 @@ not exist and there is just bytecode. Again, my debuggers make use of
|
||||
this.
|
||||
|
||||
There were (and still are) a number of decompyle, uncompyle,
|
||||
uncompyle2, uncompyle3 forks around. Almost all of them come basically
|
||||
from the same code base, and (almost?) all of them are no longer
|
||||
actively maintained. One was really good at decompiling Python 1.5-2.3
|
||||
or so, another really good at Python 2.7, but that only. Another
|
||||
handles Python 3.2 only; another patched that and handled only 3.3.
|
||||
You get the idea. This code pulls all of these forks together and
|
||||
*moves forward*. There is some serious refactoring and cleanup in this
|
||||
code base over those old forks.
|
||||
uncompyle2, uncompyle3 forks around. Many of them come basically from
|
||||
the same code base, and (almost?) all of them are no longer actively
|
||||
maintained. One was really good at decompiling Python 1.5-2.3, another
|
||||
really good at Python 2.7, but that only. Another handles Python 3.2
|
||||
only; another patched that and handled only 3.3. You get the
|
||||
idea. This code pulls all of these forks together and *moves
|
||||
forward*. There is some serious refactoring and cleanup in this code
|
||||
base over those old forks. Even more experimental refactoring is going
|
||||
on in decompyle3_.
|
||||
|
||||
This demonstrably does the best in decompiling Python across all
|
||||
Python versions. And even when there is another project that only
|
||||
@@ -58,25 +62,24 @@ provides decompilation for subset of Python versions, we generally do
|
||||
demonstrably better for those as well.
|
||||
|
||||
How can we tell? By taking Python bytecode that comes distributed with
|
||||
that version of Python and decompiling these. Among htose that
|
||||
that version of Python and decompiling these. Among those that
|
||||
successfully decompile, we can then make sure the resulting programs
|
||||
are syntactically correct by running the Python interpreter for that
|
||||
bytecode version. Finally, in cases where the program has a test for
|
||||
itself, we can run the check on the decompiled code.
|
||||
|
||||
We are serious about testing, and use automated processes to find
|
||||
bugs. In the issue trackers for other decompilers, you will find a
|
||||
number of bugs we've found along the way. Very few to none of them are
|
||||
fixed in the other decompilers.
|
||||
We use an automated processes to find bugs. In the issue trackers for
|
||||
other decompilers, you will find a number of bugs we've found along
|
||||
the way. Very few to none of them are fixed in the other decompilers.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
The code here can be run on Python versions 2.6 or later, PyPy 3-2.4,
|
||||
or PyPy-5.0.1. Python versions 2.4-2.7 are supported in the
|
||||
python-2.4 branch. The bytecode files it can read have been tested on
|
||||
Python bytecodes from versions 1.5, 2.1-2.7, and 3.0-3.6 and the
|
||||
above-mentioned PyPy versions.
|
||||
The code here can be run on Python versions 2.6 or later, PyPy 3-2.4
|
||||
and later. Python versions 2.4-2.7 are supported in the python-2.4
|
||||
branch. The bytecode files it can read have been tested on Python
|
||||
bytecodes from versions 1.4, 2.1-2.7, and 3.0-3.8 and later PyPy
|
||||
versions.
|
||||
|
||||
Installation
|
||||
------------
|
||||
@@ -85,15 +88,15 @@ This uses setup.py, so it follows the standard Python routine:
|
||||
|
||||
::
|
||||
|
||||
pip install -e . # set up to run from source tree
|
||||
# Or if you want to install instead
|
||||
python setup.py install # may need sudo
|
||||
$ pip install -e . # set up to run from source tree
|
||||
# Or if you want to install instead
|
||||
$ python setup.py install # may need sudo
|
||||
|
||||
A GNU makefile is also provided so :code:`make install` (possibly as root or
|
||||
sudo) will do the steps above.
|
||||
|
||||
Testing
|
||||
-------
|
||||
Running Tests
|
||||
-------------
|
||||
|
||||
::
|
||||
|
||||
@@ -121,16 +124,39 @@ For usage help:
|
||||
|
||||
$ uncompyle6 -h
|
||||
|
||||
If you want strong verification of the correctness of the
|
||||
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.
|
||||
Verification
|
||||
------------
|
||||
|
||||
You can also cross compare the results with pycdc_ . Since they work
|
||||
differently, bugs here often aren't in that, and vice versa.
|
||||
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 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
|
||||
-----------------------
|
||||
@@ -145,92 +171,117 @@ All of the Python decompilers that I have looked at have problems
|
||||
decompiling Python's control flow. In some cases we can detect an
|
||||
erroneous decompilation and report that.
|
||||
|
||||
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.
|
||||
Python support is pretty good for Python 2
|
||||
|
||||
There is a kind of *weak 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
|
||||
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
|
||||
decompiler from that era has been preserved (and Python compilation in
|
||||
that era was minimal)
|
||||
|
||||
There is some work to do on the lower end Python versions which is
|
||||
more difficult for us to handle since we don't have a Python
|
||||
interpreter for versions 1.5, 1.6, and 2.0.
|
||||
On the lower end of Python versions, decompilation seems pretty good although
|
||||
we don't have any automated testing in place for Python's distributed tests.
|
||||
Also, we don't have a Python interpreter for versions 1.6, and 2.0.
|
||||
|
||||
In the Python 3 series, Python support is is strongest around 3.4 or
|
||||
3.3 and drops off as you move further away from those versions. Python
|
||||
3.6 changes things drastically by using word codes rather than byte
|
||||
codes. As a result, the jump offset field in a jump instruction
|
||||
argument has been reduced. This makes the `EXTENDED_ARG` instructions
|
||||
are now more prevalent in jump instruction; previously they had been
|
||||
rare. Perhaps to compensate for the additional `EXTENDED_ARG`
|
||||
instructions, additional jump optimization has been added. So in sum
|
||||
handling control flow by ad hoc means as is currently done is worse.
|
||||
3.0 is weird in that it in some ways resembles 2.6 more than it does
|
||||
3.1 or 2.7. Python 3.6 changes things drastically by using word codes
|
||||
rather than byte codes. As a result, the jump offset field in a jump
|
||||
instruction argument has been reduced. This makes the :code:`EXTENDED_ARG`
|
||||
instructions are now more prevalent in jump instruction; previously
|
||||
they had been rare. Perhaps to compensate for the additional
|
||||
:code:`EXTENDED_ARG` instructions, additional jump optimization has been
|
||||
added. So in sum handling control flow by ad hoc means as is currently
|
||||
done is worse.
|
||||
|
||||
Also, between Python 3.5, 3.6 and 3.7 there have been major changes to the
|
||||
`MAKE_FUNCTION` and `CALL_FUNCTION` instructions.
|
||||
Between Python 3.5, 3.6, 3.7 there have been major changes to the
|
||||
:code:`MAKE_FUNCTION` and :code:`CALL_FUNCTION` instructions.
|
||||
|
||||
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
|
||||
some versions of Python, notably Python 3.6, the magic number has
|
||||
changes several times within a version. We support only the released
|
||||
magic. There are also customized Python interpreters, notably Dropbox,
|
||||
which use their own magic and encrypt bytcode. With the exception of
|
||||
changes several times within a version.
|
||||
|
||||
**We support only released versions, not candidate versions.** Note
|
||||
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,
|
||||
which use their own magic and encrypt bytecode. With the exception of
|
||||
the Dropbox's old Python 2.5 interpreter this kind of thing is not
|
||||
handled.
|
||||
|
||||
We also don't handle PJOrion_ obfuscated code. For that try: PJOrion
|
||||
Deobfuscator_ to unscramble the bytecode to get valid bytecode before
|
||||
trying this tool. This program can't decompile Microsoft Windows EXE
|
||||
files created by Py2EXE_, although we can probably decompile the code
|
||||
after you extract the bytecode properly. For situations like this, you
|
||||
might want to consider a decompilation service like `Crazy Compilers
|
||||
<http://www.crazy-compilers.com/decompyle/>`_. Handling
|
||||
pathologically long lists of expressions or statements is slow.
|
||||
We also don't handle PJOrion_ or otherwise obfuscated code. For
|
||||
PJOrion try: PJOrion Deobfuscator_ to unscramble the bytecode to get
|
||||
valid bytecode before trying this tool. This program can't decompile
|
||||
Microsoft Windows EXE files created by Py2EXE_, although we can
|
||||
probably decompile the code after you extract the bytecode
|
||||
properly. Handling pathologically long lists of expressions or
|
||||
statements is slow. We don't handle Cython_ or MicroPython which don't
|
||||
use bytecode.
|
||||
|
||||
There are numerous bugs in decompilation. And that's true for every
|
||||
other CPython decompiler I have encountered, even the ones that
|
||||
claimed to be "perfect" on some particular version like 2.4.
|
||||
|
||||
There is lots to do, so please dig in and help.
|
||||
As Python progresses decompilation also gets harder because the
|
||||
compilation is more sophisticated and the language itself is more
|
||||
sophisticated. I suspect that attempts there will be fewer ad-hoc
|
||||
attempts like unpyc37_ (which is based on a 3.3 decompiler) simply
|
||||
because it is harder to do so. The good news, at least from my
|
||||
standpoint, is that I think I understand what's needed to address the
|
||||
problems in a more robust way. But right now until such time as
|
||||
project is better funded, I do not intend to make any serious effort
|
||||
to support Python versions 3.8 or 3.9, including bugs that might come
|
||||
in. I imagine at some point I may be interested in it.
|
||||
|
||||
You can easily find bugs by running the tests against the standard
|
||||
test suite that Python uses to check itself. At any given time, there are
|
||||
dozens of known problems that are pretty well isolated and that could
|
||||
be solved if one were to put in the time to do so. The problem is that
|
||||
there aren't that many people who have been working on bug fixing.
|
||||
|
||||
Some of the bugs in 3.7 and 3.8 are simply a matter of back-porting
|
||||
the fixes in decompyle3.
|
||||
|
||||
You may run across a bug, that you want to report. Please do so. But
|
||||
be aware that it might not get my attention for a while. If you
|
||||
sponsor or support the project in some way, I'll prioritize your
|
||||
issues above the queue of other things I might be doing instead.
|
||||
|
||||
See Also
|
||||
--------
|
||||
|
||||
* https://github.com/zrax/pycdc : supports all versions of Python and is written in C++. Support for Python 3 is a bit lacking though.
|
||||
* https://code.google.com/archive/p/unpyc3/ : supports Python 3.2 only. The above projects use a different decompiling technique than what is used here.
|
||||
* https://github.com/figment/unpyc3/ : fork of above, but supports Python 3.3 only. Includes some fixes like supporting function annotations
|
||||
* The HISTORY_ file.
|
||||
* https://github.com/rocky/python-decompile3 : Much smaller and more modern code, focusing on 3.7+. Changes in that will get migrated back here.
|
||||
* https://code.google.com/archive/p/unpyc3/ : supports Python 3.2 only. The above projects use a different decompiling technique than what is used here. Currently unmaintained.
|
||||
* https://github.com/figment/unpyc3/ : fork of above, but supports Python 3.3 only. Includes some fixes like supporting function annotations. Currently unmaintained.
|
||||
* https://github.com/wibiti/uncompyle2 : supports Python 2.7 only, but does that fairly well. There are situations where :code:`uncompyle6` results are incorrect while :code:`uncompyle2` results are not, but more often uncompyle6 is correct when uncompyle2 is not. Because :code:`uncompyle6` adheres to accuracy over idiomatic Python, :code:`uncompyle2` can produce more natural-looking code when it is correct. Currently :code:`uncompyle2` is lightly maintained. See its issue `tracker <https://github.com/wibiti/uncompyle2/issues>`_ for more details
|
||||
* `How to report a bug <https://github.com/rocky/python-uncompyle6/blob/master/HOW-TO-REPORT-A-BUG.md>`_
|
||||
* The HISTORY_ file.
|
||||
* https://github.com/rocky/python-xdis : Cross Python version disassembler
|
||||
* https://github.com/rocky/python-xasm : Cross Python version assembler
|
||||
* https://github.com/rocky/python-uncompyle6/wiki : Wiki Documents which describe the code and aspects of it in more detail
|
||||
* 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/trepan2
|
||||
.. _Cython: https://en.wikipedia.org/wiki/Cython
|
||||
.. _trepan: https://pypi.python.org/pypi/trepan2g
|
||||
.. _compiler: https://pypi.python.org/pypi/spark_parser
|
||||
.. _HISTORY: https://github.com/rocky/python-uncompyle6/blob/master/HISTORY.md
|
||||
.. _debuggers: https://pypi.python.org/pypi/trepan3k
|
||||
.. _remake: https://bashdb.sf.net/remake
|
||||
.. _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
|
||||
.. |buildstatus| image:: https://travis-ci.org/rocky/python-uncompyle6.svg
|
||||
:target: https://travis-ci.org/rocky/python-uncompyle6
|
||||
.. |packagestatus| image:: https://repology.org/badge/vertical-allrepos/python:uncompyle6.svg
|
||||
:target: https://repology.org/project/python:uncompyle6/versions
|
||||
.. _PJOrion: http://www.koreanrandom.com/forum/topic/15280-pjorion-%D1%80%D0%B5%D0%B4%D0%B0%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D0%BA%D0%BE%D0%BC%D0%BF%D0%B8%D0%BB%D1%8F%D1%86%D0%B8%D1%8F-%D0%B4%D0%B5%D0%BA%D0%BE%D0%BC%D0%BF%D0%B8%D0%BB%D1%8F%D1%86%D0%B8%D1%8F-%D0%BE%D0%B1%D1%84
|
||||
.. _Deobfuscator: https://github.com/extremecoders-re/PjOrion-Deobfuscator
|
||||
.. _Py2EXE: https://en.wikipedia.org/wiki/Py2exe
|
||||
.. |Supported Python Versions| image:: https://img.shields.io/pypi/pyversions/uncompyle6.svg
|
||||
.. |Latest Version| image:: https://badge.fury.io/py/uncompyle6.svg
|
||||
:target: https://badge.fury.io/py/uncompyle6
|
||||
.. |Pypi Installs| image:: https://pepy.tech/badge/uncompyle6/month
|
||||
|
106
__pkginfo__.py
106
__pkginfo__.py
@@ -1,4 +1,4 @@
|
||||
# Copyright (C) 2018 Rocky Bernstein <rocky@gnu.org>
|
||||
# Copyright (C) 2018, 2020-2021 Rocky Bernstein <rocky@gnu.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -21,64 +21,88 @@
|
||||
# less elegant than having it here with reduced code, albeit there
|
||||
# still is some room for improvement.
|
||||
|
||||
# Python-version | package | last-version |
|
||||
# -----------------------------------------
|
||||
# 2.5 | pip | 1.1 |
|
||||
# 2.6 | pip | 1.5.6 |
|
||||
# 2.7 | pip | 19.2.3 |
|
||||
# 2.7 | pip | 1.2.1 |
|
||||
# 3.1 | pip | 1.5.6 |
|
||||
# 3.2 | pip | 7.1.2 |
|
||||
# 3.3 | pip | 10.0.1 |
|
||||
# 3.4 | pip | 19.1.1 |
|
||||
|
||||
# Things that change more often go here.
|
||||
copyright = """
|
||||
Copyright (C) 2015-2018 Rocky Bernstein <rb@dustyfeet.com>.
|
||||
copyright = """
|
||||
Copyright (C) 2015-2021 Rocky Bernstein <rb@dustyfeet.com>.
|
||||
"""
|
||||
|
||||
classifiers = ['Development Status :: 5 - Production/Stable',
|
||||
'Intended Audience :: Developers',
|
||||
'License :: OSI Approved :: GNU General Public License v3 (GPLv3)',
|
||||
'Operating System :: OS Independent',
|
||||
'Programming Language :: Python',
|
||||
'Programming Language :: Python :: 2.4',
|
||||
'Programming Language :: Python :: 2.5',
|
||||
'Programming Language :: Python :: 2.6',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3.1',
|
||||
'Programming Language :: Python :: 3.2',
|
||||
'Programming Language :: Python :: 3.3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Topic :: Software Development :: Debuggers',
|
||||
'Topic :: Software Development :: Libraries :: Python Modules',
|
||||
]
|
||||
classifiers = [
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"Intended Audience :: Developers",
|
||||
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
|
||||
"Operating System :: OS Independent",
|
||||
"Programming Language :: Python",
|
||||
"Programming Language :: Python :: 2",
|
||||
"Programming Language :: Python :: 2.4",
|
||||
"Programming Language :: Python :: 2.5",
|
||||
"Programming Language :: Python :: 2.6",
|
||||
"Programming Language :: Python :: 2.7",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.0",
|
||||
"Programming Language :: Python :: 3.1",
|
||||
"Programming Language :: Python :: 3.2",
|
||||
"Programming Language :: Python :: 3.3",
|
||||
"Programming Language :: Python :: 3.4",
|
||||
"Programming Language :: Python :: 3.5",
|
||||
"Programming Language :: Python :: 3.6",
|
||||
"Programming Language :: Python :: 3.7",
|
||||
"Programming Language :: Python :: 3.8",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: Implementation :: PyPy",
|
||||
"Topic :: Software Development :: Debuggers",
|
||||
"Topic :: Software Development :: Libraries :: Python Modules",
|
||||
]
|
||||
|
||||
# The rest in alphabetic order
|
||||
author = "Rocky Bernstein, Hartmut Goebel, John Aycock, and others"
|
||||
author_email = "rb@dustyfeet.com"
|
||||
entry_points = {
|
||||
'console_scripts': [
|
||||
'uncompyle6=uncompyle6.bin.uncompile:main_bin',
|
||||
'pydisassemble=uncompyle6.bin.pydisassemble:main',
|
||||
]}
|
||||
ftp_url = None
|
||||
install_requires = ['spark-parser >= 1.8.5, < 1.9.0',
|
||||
'xdis >= 3.8.2, < 3.9.0', 'six']
|
||||
author = "Rocky Bernstein, Hartmut Goebel, John Aycock, and others"
|
||||
author_email = "rb@dustyfeet.com"
|
||||
entry_points = {
|
||||
"console_scripts": [
|
||||
"uncompyle6=uncompyle6.bin.uncompile:main_bin",
|
||||
"pydisassemble=uncompyle6.bin.pydisassemble:main",
|
||||
]
|
||||
}
|
||||
ftp_url = None
|
||||
install_requires = ["spark-parser >= 1.8.9, < 1.9.0", "xdis >= 6.0.2, < 6.1.0"]
|
||||
|
||||
license = 'GPL3'
|
||||
mailing_list = 'python-debugger@googlegroups.com'
|
||||
modname = 'uncompyle6'
|
||||
py_modules = None
|
||||
short_desc = 'Python cross-version byte-code decompiler'
|
||||
web = 'https://github.com/rocky/python-uncompyle6/'
|
||||
license = "GPL3"
|
||||
mailing_list = "python-debugger@googlegroups.com"
|
||||
modname = "uncompyle6"
|
||||
py_modules = None
|
||||
short_desc = "Python cross-version byte-code decompiler"
|
||||
web = "https://github.com/rocky/python-uncompyle6/"
|
||||
|
||||
# tracebacks in zip files are funky and not debuggable
|
||||
zip_safe = True
|
||||
|
||||
|
||||
import os.path
|
||||
|
||||
|
||||
def get_srcdir():
|
||||
filename = os.path.normcase(os.path.dirname(os.path.abspath(__file__)))
|
||||
return os.path.realpath(filename)
|
||||
|
||||
|
||||
srcdir = get_srcdir()
|
||||
|
||||
|
||||
def read(*rnames):
|
||||
return open(os.path.join(srcdir, *rnames)).read()
|
||||
|
||||
# Get info from files; set: long_description and VERSION
|
||||
long_description = ( read("README.rst") + '\n' )
|
||||
exec(read('uncompyle6/version.py'))
|
||||
|
||||
# Get info from files; set: long_description and __version__
|
||||
long_description = read("README.rst") + "\n"
|
||||
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
|
||||
|
||||
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
|
||||
|
@@ -6,7 +6,7 @@ owd=$(pwd)
|
||||
trap finish EXIT
|
||||
|
||||
cd $(dirname ${BASH_SOURCE[0]})
|
||||
if ! source ./pyenv-older-versions ; then
|
||||
if ! source ./pyenv-2.4-2.7-versions ; then
|
||||
exit $?
|
||||
fi
|
||||
if ! source ./setup-python-2.4.sh ; then
|
||||
@@ -15,6 +15,7 @@ fi
|
||||
|
||||
cd ..
|
||||
for version in $PYVERSIONS; do
|
||||
echo --- $version ---
|
||||
if ! pyenv local $version ; then
|
||||
exit $?
|
||||
fi
|
||||
@@ -22,4 +23,5 @@ for version in $PYVERSIONS; do
|
||||
if ! make check ; then
|
||||
exit $?
|
||||
fi
|
||||
echo === $version ===
|
||||
done
|
@@ -8,7 +8,7 @@ owd=$(pwd)
|
||||
trap finish EXIT
|
||||
|
||||
cd $(dirname ${BASH_SOURCE[0]})
|
||||
if ! source ./pyenv-newer-versions ; then
|
||||
if ! source ./pyenv-newest-versions ; then
|
||||
exit $?
|
||||
fi
|
||||
if ! source ./setup-master.sh ; then
|
||||
@@ -16,11 +16,14 @@ if ! source ./setup-master.sh ; then
|
||||
fi
|
||||
cd ..
|
||||
for version in $PYVERSIONS; do
|
||||
echo --- $version ---
|
||||
if ! pyenv local $version ; then
|
||||
exit $?
|
||||
fi
|
||||
make clean && pip install -e .
|
||||
if ! make check; then
|
||||
if ! make check-short; then
|
||||
exit $?
|
||||
fi
|
||||
echo === $version ===
|
||||
done
|
||||
make check
|
@@ -2,17 +2,17 @@
|
||||
**Table of Contents**
|
||||
|
||||
- [Get latest sources:](#get-latest-sources)
|
||||
- [Change version in uncompyle6/version.py](#change-version-in-uncompyle6versionpy)
|
||||
- [Change version in uncompyle6/version.py:](#change-version-in-uncompyle6versionpy)
|
||||
- [Update ChangeLog:](#update-changelog)
|
||||
- [Update NEWS from ChangeLog:](#update-news-from-changelog)
|
||||
- [Update NEWS.md from ChangeLog:](#update-newsmd-from-changelog)
|
||||
- [Make sure pyenv is running and check newer versions](#make-sure-pyenv-is-running-and-check-newer-versions)
|
||||
- [Switch to python-2.4, sync that up and build that first since it creates a tarball which we don't want.](#switch-to-python-24-sync-that-up-and-build-that-first-since-it-creates-a-tarball-which-we-dont-want)
|
||||
- [Update NEWS from master branch](#update-news-from-master-branch)
|
||||
- [Check against all versions](#check-against-all-versions)
|
||||
- [Check against older versions](#check-against-older-versions)
|
||||
- [Make packages and tag](#make-packages-and-tag)
|
||||
- [Upload single package and look at Rst Formating](#upload-single-package-and-look-at-rst-formating)
|
||||
- [Upload rest of versions](#upload-rest-of-versions)
|
||||
- [Push tags:](#push-tags)
|
||||
- [Check package on github](#check-package-on-github)
|
||||
- [Release on Github](#release-on-github)
|
||||
- [Get onto PyPI](#get-onto-pypi)
|
||||
- [Update tags:](#update-tags)
|
||||
|
||||
<!-- markdown-toc end -->
|
||||
# Get latest sources:
|
||||
@@ -30,16 +30,16 @@
|
||||
|
||||
$ make ChangeLog
|
||||
|
||||
# Update NEWS from ChangeLog:
|
||||
# Update NEWS.md from ChangeLog:
|
||||
|
||||
$ emacs NEWS
|
||||
$ emacs NEWS.md
|
||||
$ make check
|
||||
$ git commit --amend .
|
||||
$ git push # get CI testing going early
|
||||
|
||||
# Make sure pyenv is running and check newer versions
|
||||
|
||||
$ pyenv local && source admin-tools/check-newer-versions.sh
|
||||
$ admin-tools/check-newer-versions.sh
|
||||
|
||||
# Switch to python-2.4, sync that up and build that first since it creates a tarball which we don't want.
|
||||
|
||||
@@ -50,34 +50,51 @@
|
||||
|
||||
# Check against older versions
|
||||
|
||||
$ source admin-tools/check-older-versions.sh
|
||||
$ admin-tools/check-older-versions.sh
|
||||
|
||||
# Make packages and tag
|
||||
|
||||
$ . ./admin-tools/make-dist-older.sh
|
||||
$ pyenv local 3.8.5
|
||||
$ twine check dist/uncompyle6-$VERSION*
|
||||
$ git tag release-python-2.4-$VERSION
|
||||
$ ./admin-tools/make-dist-newer.sh
|
||||
$ twine check dist/uncompyle6-$VERSION*
|
||||
|
||||
$ . ./admin-tools/make-dist-newer.sh
|
||||
$ git tag release-$VERSION
|
||||
# Check package on github
|
||||
|
||||
# Upload single package and look at Rst Formating
|
||||
$ [[ ! -d /tmp/gittest ]] && mkdir /tmp/gittest; pushd /tmp/gittest
|
||||
$ pyenv local 3.8.3
|
||||
$ pip install -e git://github.com/rocky/python-uncompyle6.git#egg=uncompyle6
|
||||
$ uncompyle6 --help
|
||||
$ pip uninstall uncompyle6
|
||||
$ popd
|
||||
|
||||
$ twine upload dist/uncompyle6-${VERSION}-py3.3.egg
|
||||
# Release on Github
|
||||
|
||||
# Upload rest of versions
|
||||
Goto https://github.com/rocky/python-uncompyle6/releases
|
||||
|
||||
Now check the *tagged* release. (Checking the untagged release was previously done).
|
||||
|
||||
Todo: turn this into a script in `admin-tools`
|
||||
|
||||
$ pushd /tmp/gittest
|
||||
$ pip install -e git://github.com/rocky/python-uncompyle6.git@$VERSION#egg=uncompyle6
|
||||
$ uncompyle6 --help
|
||||
$ pip uninstall uncompyle6
|
||||
$ popd
|
||||
|
||||
|
||||
# Get onto PyPI
|
||||
|
||||
$ twine upload dist/uncompyle6-${VERSION}*
|
||||
|
||||
# Push tags:
|
||||
|
||||
# Update tags:
|
||||
|
||||
$ git push --tags
|
||||
$ git pull --tags
|
||||
|
||||
# Check on a VM
|
||||
# Move dist files to uploaded
|
||||
|
||||
$ cd /virtual/vagrant/virtual/vagrant/ubuntu-zesty
|
||||
$ vagrant up
|
||||
$ vagrant ssh
|
||||
$ pyenv local 3.5.2
|
||||
$ pip install --upgrade uncompyle6
|
||||
$ exit
|
||||
$ vagrant halt
|
||||
$ mv -v dist/uncompyle6-${VERSION}* dist/uploaded
|
||||
|
@@ -9,7 +9,7 @@ owd=$(pwd)
|
||||
trap finish EXIT
|
||||
|
||||
cd $(dirname ${BASH_SOURCE[0]})
|
||||
if ! source ./pyenv-older-versions ; then
|
||||
if ! source ./pyenv-2.4-2.7-versions ; then
|
||||
exit $?
|
||||
fi
|
||||
if ! source ./setup-python-2.4.sh ; then
|
||||
@@ -18,7 +18,7 @@ fi
|
||||
|
||||
cd ..
|
||||
source $PACKAGE/version.py
|
||||
echo $VERSION
|
||||
echo $__version__
|
||||
|
||||
for pyversion in $PYVERSIONS; do
|
||||
if ! pyenv local $pyversion ; then
|
||||
@@ -29,11 +29,15 @@ for pyversion in $PYVERSIONS; do
|
||||
python setup.py bdist_egg
|
||||
done
|
||||
|
||||
pyenv local 2.7.18
|
||||
python setup.py bdist_wheel
|
||||
mv -v dist/${PACKAGE}-$__version__-py2{.py3,}-none-any.whl
|
||||
|
||||
# Pypi can only have one source tarball.
|
||||
# Tarballs can get created from the above setup, so make sure to remove them since we want
|
||||
# the tarball from master.
|
||||
|
||||
tarball=dist/${PACKAGE}-$VERSION-tar.gz
|
||||
tarball=dist/${PACKAGE}-${__version_}_-tar.gz
|
||||
if [[ -f $tarball ]]; then
|
||||
rm -v dist/${PACKAGE}-$VERSION-tar.gz
|
||||
rm -v dist/${PACKAGE}-${__version__}-tar.gz
|
||||
fi
|
38
admin-tools/make-dist-3.3-3.5.sh
Executable file
38
admin-tools/make-dist-3.3-3.5.sh
Executable file
@@ -0,0 +1,38 @@
|
||||
#!/bin/bash
|
||||
PACKAGE=uncompyle6
|
||||
|
||||
# FIXME put some of the below in a common routine
|
||||
function finish {
|
||||
cd $owd
|
||||
}
|
||||
|
||||
cd $(dirname ${BASH_SOURCE[0]})
|
||||
owd=$(pwd)
|
||||
trap finish EXIT
|
||||
|
||||
if ! source ./pyenv-3.3-3.5-versions ; then
|
||||
exit $?
|
||||
fi
|
||||
if ! source ./setup-python-3.3.sh ; then
|
||||
exit $?
|
||||
fi
|
||||
|
||||
cd ..
|
||||
source $PACKAGE/version.py
|
||||
echo $__version__
|
||||
|
||||
for pyversion in $PYVERSIONS; do
|
||||
if ! pyenv local $pyversion ; then
|
||||
exit $?
|
||||
fi
|
||||
# pip bdist_egg create too-general wheels. So
|
||||
# we narrow that by moving the generated wheel.
|
||||
|
||||
# Pick out first two number of version, e.g. 3.5.1 -> 35
|
||||
first_two=$(echo $pyversion | cut -d'.' -f 1-2 | sed -e 's/\.//')
|
||||
rm -fr build
|
||||
python setup.py bdist_egg bdist_wheel
|
||||
mv -v dist/${PACKAGE}-$__version__-{py2.py3,py$first_two}-none-any.whl
|
||||
done
|
||||
|
||||
python ./setup.py sdist
|
@@ -10,7 +10,7 @@ cd $(dirname ${BASH_SOURCE[0]})
|
||||
owd=$(pwd)
|
||||
trap finish EXIT
|
||||
|
||||
if ! source ./pyenv-newer-versions ; then
|
||||
if ! source ./pyenv-newest-versions ; then
|
||||
exit $?
|
||||
fi
|
||||
if ! source ./setup-master.sh ; then
|
||||
@@ -19,7 +19,7 @@ fi
|
||||
|
||||
cd ..
|
||||
source $PACKAGE/version.py
|
||||
echo $VERSION
|
||||
echo $__version__
|
||||
|
||||
for pyversion in $PYVERSIONS; do
|
||||
if ! pyenv local $pyversion ; then
|
||||
@@ -32,7 +32,7 @@ for pyversion in $PYVERSIONS; do
|
||||
first_two=$(echo $pyversion | cut -d'.' -f 1-2 | sed -e 's/\.//')
|
||||
rm -fr build
|
||||
python setup.py bdist_egg bdist_wheel
|
||||
mv -v dist/${PACKAGE}-$VERSION-{py2.py3,py$first_two}-none-any.whl
|
||||
mv -v dist/${PACKAGE}-$__version__-{py2.py3,py$first_two}-none-any.whl
|
||||
done
|
||||
|
||||
python ./setup.py sdist
|
9
admin-tools/pyenv-2.4-2.7-versions
Normal file
9
admin-tools/pyenv-2.4-2.7-versions
Normal file
@@ -0,0 +1,9 @@
|
||||
# -*- shell-script -*-
|
||||
# Sets PYVERSIONS to be pyenv versions that
|
||||
# we can use in the python-2.4-to-2.7 branch.
|
||||
|
||||
if [[ $0 == ${BASH_SOURCE[0]} ]] ; then
|
||||
echo "This script should be *sourced* rather than run directly through bash"
|
||||
exit 1
|
||||
fi
|
||||
export PYVERSIONS='2.4.6 2.5.6 2.6.9 2.7.18'
|
@@ -6,4 +6,4 @@ if [[ $0 == ${BASH_SOURCE[0]} ]] ; then
|
||||
echo "This script should be *sourced* rather than run directly through bash"
|
||||
exit 1
|
||||
fi
|
||||
export PYVERSIONS='2.4.6 2.5.6'
|
||||
export PYVERSIONS='3.1.5 3.2.6'
|
8
admin-tools/pyenv-3.3-3.5-versions
Normal file
8
admin-tools/pyenv-3.3-3.5-versions
Normal file
@@ -0,0 +1,8 @@
|
||||
# -*- shell-script -*-
|
||||
# Sets PYVERSIONS to be pyenv versions that
|
||||
# we can use in the python-3.3-to-3.5 branch.
|
||||
if [[ $0 == ${BASH_SOURCE[0]} ]] ; then
|
||||
echo "This script should be *sourced* rather than run directly through bash"
|
||||
exit 1
|
||||
fi
|
||||
export PYVERSIONS='3.5.10 3.3.7 3.4.10'
|
@@ -5,4 +5,4 @@ if [[ $0 == ${BASH_SOURCE[0]} ]] ; then
|
||||
echo "This script should be *sourced* rather than run directly through bash"
|
||||
exit 1
|
||||
fi
|
||||
export PYVERSIONS='3.5.5 3.6.5 2.6.9 3.3.7 2.7.14 3.2.6 3.1.5 3.4.8'
|
||||
export PYVERSIONS='3.6.15 3.7.12 pyston-2.3 3.8.11 3.9.7 3.10.0'
|
8
admin-tools/pyenv-versions
Normal file
8
admin-tools/pyenv-versions
Normal file
@@ -0,0 +1,8 @@
|
||||
# -*- shell-script -*-
|
||||
# Sets PYVERSIONS to be pyenv versions that
|
||||
# we can use in the master branch.
|
||||
if [[ $0 == ${BASH_SOURCE[0]} ]] ; then
|
||||
echo "This script should be *sourced* rather than run directly through bash"
|
||||
exit 1
|
||||
fi
|
||||
export PYVERSIONS='3.7.11 3.8.12 3.9.7 3.10.0'
|
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
PYTHON_VERSION=3.6.5
|
||||
PYTHON_VERSION=3.7.12
|
||||
|
||||
# FIXME put some of the below in a common routine
|
||||
function finish {
|
||||
@@ -20,3 +20,4 @@ cd $fulldir/..
|
||||
(cd ../python-xdis && git checkout master && pyenv local $PYTHON_VERSION) && git pull && \
|
||||
git checkout master && pyenv local $PYTHON_VERSION && git pull
|
||||
cd $owd
|
||||
rm -v */.python-version >/dev/null 2>&1 || true
|
||||
|
@@ -11,6 +11,8 @@ mydir=$(dirname $bs)
|
||||
fulldir=$(readlink -f $mydir)
|
||||
cd $fulldir/..
|
||||
(cd ../python-spark && 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 && \
|
||||
(cd ../python-xdis && . ./admin-tools/setup-python-2.4.sh) && \
|
||||
git checkout python-2.4 && pyenv local $PYTHON_VERSION && git pull
|
||||
cd $owd
|
||||
rm -v */.python-version || true
|
||||
pyenv local $PYTHON_VERSION
|
||||
|
15
admin-tools/setup-python-3.3.sh
Executable file
15
admin-tools/setup-python-3.3.sh
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
PYTHON_VERSION=3.3.7
|
||||
pyenv local $PYTHON_VERSION
|
||||
|
||||
owd=$(pwd)
|
||||
bs=${BASH_SOURCE[0]}
|
||||
|
||||
mydir=$(dirname $bs)
|
||||
fulldir=$(readlink -f $mydir)
|
||||
cd $fulldir/..
|
||||
(cd ../python-xdis && ./admin-tools/setup-python-3.3.sh)
|
||||
cd $owd
|
||||
rm -v */.python-version || true
|
||||
|
||||
git checkout python-3.3-to-3.5 && git pull && pyenv local $PYTHON_VERSION
|
78
appveyor.yml
78
appveyor.yml
@@ -1,78 +0,0 @@
|
||||
environment:
|
||||
global:
|
||||
# SDK v7.0 MSVC Express 2008's SetEnv.cmd script will fail if the
|
||||
# /E:ON and /V:ON options are not enabled in the batch script intepreter
|
||||
# See: http://stackoverflow.com/a/13751649/163740
|
||||
CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\appveyor\\run_with_env.cmd"
|
||||
|
||||
matrix:
|
||||
|
||||
# Pre-installed Python versions, which Appveyor may upgrade to
|
||||
# a later point release.
|
||||
# See: http://www.appveyor.com/docs/installed-software#python
|
||||
|
||||
# - PYTHON: "C:\\Python27"
|
||||
# PYTHON_VERSION: "2.7.x"
|
||||
# PYTHON_ARCH: "32"
|
||||
|
||||
- PYTHON: "C:\\Python27-x64"
|
||||
PYTHON_VERSION: "2.7.x"
|
||||
PYTHON_ARCH: "64"
|
||||
|
||||
# - PYTHON: "C:\\Python26"
|
||||
# PYTHON_VERSION: "2.6.x"
|
||||
# PYTHON_ARCH: "32"
|
||||
|
||||
# - PYTHON: "C:\\Python26-x64"
|
||||
# PYTHON_VERSION: "2.6.x"
|
||||
# PYTHON_ARCH: "64"
|
||||
|
||||
install:
|
||||
# We need wheel installed to build wheels
|
||||
- "%PYTHON%\\python.exe -m pip install wheel"
|
||||
|
||||
# Install Python (from the official .msi of http://python.org) and pip when
|
||||
# not already installed.
|
||||
- ps: if (-not(Test-Path($env:PYTHON))) { & appveyor\install.ps1 }
|
||||
|
||||
# Prepend newly installed Python to the PATH of this build (this cannot be
|
||||
# done from inside the powershell script as it would require to restart
|
||||
# the parent CMD process).
|
||||
- "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
|
||||
- "SET HOME=."
|
||||
|
||||
# Check that we have the expected version and architecture for Python
|
||||
- "python --version"
|
||||
- "python -c \"import struct; print(struct.calcsize('P') * 8)\""
|
||||
|
||||
# Upgrade to the latest version of pip to avoid it displaying warnings
|
||||
# about it being out of date.
|
||||
- "%PYTHON%\\python.exe -m pip install --disable-pip-version-check --user --upgrade pip"
|
||||
|
||||
# Install the build dependencies of the project. If some dependencies contain
|
||||
# compiled extensions and are not provided as pre-built wheel packages,
|
||||
# pip will build them from source using the MSVC compiler matching the
|
||||
# target Python version and architecture
|
||||
- "%CMD_IN_ENV% pip install -r requirements.txt"
|
||||
|
||||
build_script:
|
||||
# Build the compiled extension
|
||||
- "%CMD_IN_ENV% python setup.py build"
|
||||
|
||||
test_script:
|
||||
# Run the project tests
|
||||
- "%CMD_IN_ENV% python test/test_pyenvlib.py --native --weak-verify"
|
||||
|
||||
after_test:
|
||||
# If tests are successful, create binary packages for the project.
|
||||
- "%CMD_IN_ENV% python setup.py bdist_wininst"
|
||||
- "%CMD_IN_ENV% python setup.py bdist_msi"
|
||||
- ps: "ls dist"
|
||||
|
||||
artifacts:
|
||||
# Archive the generated packages in the ci.appveyor.com build report.
|
||||
- path: dist\*
|
||||
|
||||
#on_success:
|
||||
# - TODO: upload the content of dist/*.whl to a public wheelhouse
|
||||
#
|
15
circle.yml
15
circle.yml
@@ -1,15 +0,0 @@
|
||||
machine:
|
||||
python:
|
||||
version: 2.7.10
|
||||
environment:
|
||||
COMPILE: --compile
|
||||
|
||||
dependencies:
|
||||
override:
|
||||
- pip install --upgrade setuptools
|
||||
- pip install -e .
|
||||
- pip install pytest==3.2.5 hypothesis
|
||||
test:
|
||||
override:
|
||||
- python ./setup.py develop && make check-2.7
|
||||
- cd ./test/stdlib && pyenv local 2.7.10 && bash ./runtests.sh 'test_[p-z]*.py'
|
@@ -1,7 +1,11 @@
|
||||
PHONY=check test pytest
|
||||
SHELL=/bin/bash
|
||||
|
||||
PYTHON ?= python
|
||||
|
||||
#: Run all tests
|
||||
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,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
from uncompyle6 import PYTHON_VERSION, IS_PYPY
|
||||
from xdis.version_info import PYTHON_VERSION_TRIPLE, IS_PYPY, version_tuple_to_str
|
||||
from uncompyle6.scanner import get_scanner
|
||||
def bug(state, slotstate):
|
||||
if state:
|
||||
@@ -21,8 +21,8 @@ def bug_loop(disassemble, tb=None):
|
||||
|
||||
def test_if_in_for():
|
||||
code = bug.__code__
|
||||
scan = get_scanner(PYTHON_VERSION)
|
||||
if 2.7 <= PYTHON_VERSION <= 3.0 and not IS_PYPY:
|
||||
scan = get_scanner(PYTHON_VERSION_TRIPLE)
|
||||
if (2, 7) <= PYTHON_VERSION_TRIPLE < (3, 1) and not IS_PYPY:
|
||||
scan.build_instructions(code)
|
||||
fjt = scan.find_jump_targets(False)
|
||||
|
||||
@@ -51,7 +51,7 @@ def test_if_in_for():
|
||||
# previous bug was not mistaking while-loop for if-then
|
||||
{'start': 48, 'end': 67, 'type': 'while-loop'}]
|
||||
|
||||
elif 3.2 < PYTHON_VERSION <= 3.4:
|
||||
elif (3, 2) < PYTHON_VERSION_TRIPLE <= (3, 4):
|
||||
scan.build_instructions(code)
|
||||
fjt = scan.find_jump_targets(False)
|
||||
assert {69: [66], 63: [18]} == fjt
|
||||
@@ -62,6 +62,6 @@ def test_if_in_for():
|
||||
{'end': 59, 'type': 'for-loop', 'start': 31},
|
||||
{'end': 63, 'type': 'for-else', 'start': 62}]
|
||||
else:
|
||||
print("FIXME: should fix for %s" % PYTHON_VERSION)
|
||||
print("FIXME: should fix for %s" % version_tuple_to_str())
|
||||
assert True
|
||||
return
|
||||
|
@@ -1,150 +0,0 @@
|
||||
# std
|
||||
import os
|
||||
# test
|
||||
import pytest
|
||||
import hypothesis
|
||||
from hypothesis import strategies as st
|
||||
# uncompyle6
|
||||
from uncompyle6 import PYTHON_VERSION, deparse_code
|
||||
|
||||
|
||||
@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 at least python 3.6')
|
||||
@hypothesis.given(format_specifiers())
|
||||
def test_format_specifiers(format_specifier):
|
||||
"""Verify that format_specifiers generates valid specifiers"""
|
||||
try:
|
||||
exec('"{:' + format_specifier + '}".format(0)')
|
||||
except ValueError as e:
|
||||
if 'Unknown format code' not in str(e):
|
||||
raise
|
||||
|
||||
|
||||
def run_test(text):
|
||||
hypothesis.assume(len(text))
|
||||
hypothesis.assume("f'{" in text)
|
||||
expr = text + '\n'
|
||||
code = compile(expr, '<string>', 'single')
|
||||
deparsed = deparse_code(PYTHON_VERSION, code, compile_mode='single')
|
||||
recompiled = compile(deparsed.text, '<string>', 'single')
|
||||
if recompiled != code:
|
||||
assert 'dis(' + deparsed.text.strip('\n') + ')' == 'dis(' + expr.strip('\n') + ')'
|
||||
|
||||
|
||||
@pytest.mark.skipif(PYTHON_VERSION < 3.6, reason='need at least python 3.6')
|
||||
@hypothesis.given(fstrings())
|
||||
def test_uncompyle_fstring(fstring):
|
||||
"""Verify uncompyling fstring bytecode"""
|
||||
run_test(fstring)
|
||||
|
||||
|
||||
@pytest.mark.skipif(PYTHON_VERSION < 3.6, reason='need at least python 3.6')
|
||||
@pytest.mark.parametrize('fstring', [
|
||||
"f'{abc}{abc!s}'",
|
||||
"f'{abc}0'",
|
||||
])
|
||||
def test_uncompyle_direct(fstring):
|
||||
"""useful for debugging"""
|
||||
run_test(fstring)
|
@@ -1,184 +0,0 @@
|
||||
# std
|
||||
import string
|
||||
# 3rd party
|
||||
from hypothesis import given, assume, example, settings, strategies as st
|
||||
import pytest
|
||||
# uncompyle
|
||||
from validate import validate_uncompyle
|
||||
from test_fstring import expressions
|
||||
from uncompyle6 import PYTHON_VERSION
|
||||
|
||||
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,105 +1,147 @@
|
||||
import re
|
||||
from uncompyle6 import PYTHON_VERSION, PYTHON3, IS_PYPY # , PYTHON_VERSION
|
||||
from uncompyle6.parser import get_python_parser, python_parser
|
||||
from uncompyle6.scanner import get_scanner
|
||||
from xdis.version_info import PYTHON_VERSION_TRIPLE, PYTHON3, IS_PYPY
|
||||
|
||||
|
||||
def test_grammar():
|
||||
|
||||
def check_tokens(tokens, opcode_set):
|
||||
remain_tokens = set(tokens) - opcode_set
|
||||
remain_tokens = set([re.sub('_\d+$','', t) for t in remain_tokens])
|
||||
remain_tokens = set([re.sub('_CONT$','', t) for t in remain_tokens])
|
||||
remain_tokens = set([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("LOAD_CODE$", "", t) for t in remain_tokens])
|
||||
remain_tokens = set(remain_tokens) - opcode_set
|
||||
assert remain_tokens == set([]), \
|
||||
"Remaining tokens %s\n====\n%s" % (remain_tokens, p.dump_grammar())
|
||||
assert remain_tokens == set([]), "Remaining tokens %s\n====\n%s" % (
|
||||
remain_tokens,
|
||||
p.dump_grammar(),
|
||||
)
|
||||
|
||||
p = get_python_parser(PYTHON_VERSION, is_pypy=IS_PYPY)
|
||||
(lhs, rhs, tokens,
|
||||
right_recursive, dup_rhs) = p.check_sets()
|
||||
p = get_python_parser(PYTHON_VERSION_TRIPLE, is_pypy=IS_PYPY)
|
||||
(lhs, rhs, tokens, right_recursive, dup_rhs) = p.check_sets()
|
||||
|
||||
# We have custom rules that create the below
|
||||
expect_lhs = set(['pos_arg', 'get_iter', 'attribute'])
|
||||
expect_lhs = set(["pos_arg"])
|
||||
|
||||
unused_rhs = set(['list', 'mkfunc',
|
||||
'mklambda',
|
||||
'unpack',])
|
||||
expect_right_recursive = set([('designList',
|
||||
('store', 'DUP_TOP', 'designList'))])
|
||||
if PYTHON_VERSION_TRIPLE < (3, 8):
|
||||
if PYTHON_VERSION_TRIPLE < (3, 7):
|
||||
expect_lhs.add("attribute")
|
||||
|
||||
if PYTHON_VERSION != 3.7:
|
||||
unused_rhs.add('call')
|
||||
expect_lhs.add("get_iter")
|
||||
|
||||
if PYTHON_VERSION > 2.6:
|
||||
expect_lhs.add('kvlist')
|
||||
expect_lhs.add('kv3')
|
||||
unused_rhs.add('dict')
|
||||
if PYTHON_VERSION_TRIPLE >= (3, 8) or PYTHON_VERSION_TRIPLE < (3, 0):
|
||||
expect_lhs.add("stmts_opt")
|
||||
else:
|
||||
expect_lhs.add("async_with_as_stmt")
|
||||
expect_lhs.add("async_with_stmt")
|
||||
|
||||
unused_rhs = set(["list", "mkfunc", "mklambda", "unpack"])
|
||||
|
||||
expect_right_recursive = set([("designList", ("store", "DUP_TOP", "designList"))])
|
||||
|
||||
if PYTHON_VERSION_TRIPLE[:2] <= (3, 6):
|
||||
unused_rhs.add("call")
|
||||
|
||||
if PYTHON_VERSION_TRIPLE >= (2, 7):
|
||||
expect_lhs.add("kvlist")
|
||||
expect_lhs.add("kv3")
|
||||
unused_rhs.add("dict")
|
||||
|
||||
if PYTHON_VERSION_TRIPLE < (3, 7) and PYTHON_VERSION_TRIPLE[:2] != (2, 7):
|
||||
# NOTE: this may disappear
|
||||
expect_lhs.add("except_handler_else")
|
||||
|
||||
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
|
||||
""".split()))
|
||||
if PYTHON_VERSION >= 3.0:
|
||||
expect_lhs.add("annotate_arg")
|
||||
expect_lhs.add("annotate_tuple")
|
||||
unused_rhs.add("mkfunc_annotate")
|
||||
""".split()
|
||||
)
|
||||
)
|
||||
if PYTHON_VERSION_TRIPLE >= (3, 0):
|
||||
if PYTHON_VERSION_TRIPLE < (3, 7):
|
||||
expect_lhs.add("annotate_arg")
|
||||
expect_lhs.add("annotate_tuple")
|
||||
unused_rhs.add("mkfunc_annotate")
|
||||
|
||||
unused_rhs.add("dict_comp")
|
||||
unused_rhs.add("classdefdeco1")
|
||||
if PYTHON_VERSION != 3.6:
|
||||
if PYTHON_VERSION in (3.5, 3.7):
|
||||
expect_right_recursive.add((('l_stmts',
|
||||
('lastl_stmt', 'come_froms', 'l_stmts'))))
|
||||
pass
|
||||
pass
|
||||
else:
|
||||
expect_right_recursive.add((('l_stmts',
|
||||
('lastl_stmt', 'COME_FROM', 'l_stmts'))))
|
||||
unused_rhs.add("tryelsestmtl")
|
||||
if PYTHON_VERSION_TRIPLE >= (3, 5):
|
||||
expect_right_recursive.add(
|
||||
(("l_stmts", ("lastl_stmt", "come_froms", "l_stmts")))
|
||||
)
|
||||
pass
|
||||
pass
|
||||
pass
|
||||
else:
|
||||
expect_lhs.add('kwarg')
|
||||
expect_lhs.add("kwarg")
|
||||
|
||||
# FIXME
|
||||
if PYTHON_VERSION_TRIPLE < (3, 8):
|
||||
assert expect_lhs == set(lhs)
|
||||
assert unused_rhs == set(rhs)
|
||||
|
||||
assert expect_lhs == set(lhs)
|
||||
assert unused_rhs == set(rhs)
|
||||
assert expect_right_recursive == right_recursive
|
||||
|
||||
expect_dup_rhs = frozenset([('COME_FROM',), ('CONTINUE',), ('JUMP_ABSOLUTE',),
|
||||
('LOAD_CONST',),
|
||||
('JUMP_BACK',), ('JUMP_FORWARD',)])
|
||||
expect_dup_rhs = frozenset(
|
||||
[
|
||||
("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)
|
||||
for k in reduced_dup_rhs:
|
||||
print(k, reduced_dup_rhs[k])
|
||||
if reduced_dup_rhs:
|
||||
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
|
||||
|
||||
s = get_scanner(PYTHON_VERSION, IS_PYPY)
|
||||
s = get_scanner(PYTHON_VERSION_TRIPLE, IS_PYPY)
|
||||
ignore_set = set(
|
||||
"""
|
||||
"""
|
||||
JUMP_BACK CONTINUE
|
||||
COME_FROM COME_FROM_EXCEPT
|
||||
COME_FROM_EXCEPT_CLAUSE
|
||||
COME_FROM_LOOP COME_FROM_WITH
|
||||
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
|
||||
RETURN_END_IF RETURN_END_IF_LAMBDA RETURN_VALUE_LAMBDA RETURN_LAST
|
||||
""".split())
|
||||
if 2.6 <= PYTHON_VERSION <= 2.7:
|
||||
""".split()
|
||||
)
|
||||
|
||||
if (2, 6) <= PYTHON_VERSION_TRIPLE <= (2, 7):
|
||||
opcode_set = set(s.opc.opname).union(ignore_set)
|
||||
if PYTHON_VERSION == 2.6:
|
||||
if PYTHON_VERSION_TRIPLE[:2] == (2, 6):
|
||||
opcode_set.add("THEN")
|
||||
check_tokens(tokens, opcode_set)
|
||||
elif PYTHON_VERSION == 3.4:
|
||||
ignore_set.add('LOAD_CLASSNAME')
|
||||
ignore_set.add('STORE_LOCALS')
|
||||
elif PYTHON_VERSION_TRIPLE[:2] == (3, 4):
|
||||
ignore_set.add("LOAD_CLASSNAME")
|
||||
ignore_set.add("STORE_LOCALS")
|
||||
opcode_set = set(s.opc.opname).union(ignore_set)
|
||||
check_tokens(tokens, opcode_set)
|
||||
|
||||
|
||||
def test_dup_rule():
|
||||
import inspect
|
||||
python_parser(PYTHON_VERSION, inspect.currentframe().f_code,
|
||||
is_pypy=IS_PYPY,
|
||||
parser_debug={
|
||||
'dups': True, 'transition': False, 'reduce': False,
|
||||
'rules': False, 'errorstack': None, 'context': True})
|
||||
|
||||
python_parser(
|
||||
PYTHON_VERSION_TRIPLE,
|
||||
inspect.currentframe().f_code,
|
||||
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):
|
||||
return d.iteritems()
|
||||
|
||||
from uncompyle6.semantics.pysource import SourceWalker as SourceWalker
|
||||
from uncompyle6.semantics.pysource import (SourceWalker, deparse_code2str)
|
||||
|
||||
def test_template_engine():
|
||||
s = StringIO()
|
||||
@@ -127,11 +127,17 @@ def test_tables():
|
||||
"Full entry: %s" %
|
||||
(name, k, arg, typ, entry[arg], type(entry[arg]), entry)
|
||||
)
|
||||
assert len(tup) == 2
|
||||
assert 2 <= len(tup) <= 3
|
||||
for j, x in enumerate(tup):
|
||||
assert isinstance(x, int), (
|
||||
"%s[%s][%d][%d] type '%s' is '%s should be an int but is %s. Full entry: %s" %
|
||||
(name, k, arg, j, typ, x, type(x), entry)
|
||||
if len(tup) == 3 and j == 1:
|
||||
assert isinstance(x, str), (
|
||||
"%s[%s][%d][%d] type '%s' is '%s should be an string but is %s. Full entry: %s" %
|
||||
(name, k, arg, j, typ, x, type(x), entry)
|
||||
)
|
||||
else:
|
||||
assert isinstance(x, int), (
|
||||
"%s[%s][%d][%d] type '%s' is '%s should be an int but is %s. Full entry: %s" %
|
||||
(name, k, arg, j, typ, x, type(x), entry)
|
||||
)
|
||||
pass
|
||||
arg += 1
|
||||
@@ -179,3 +185,11 @@ def test_tables():
|
||||
assert arg == len(entry), (
|
||||
"%s[%s] arg %d should be length of entry %d. Full entry: %s" %
|
||||
(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,21 +1,22 @@
|
||||
import pytest
|
||||
from uncompyle6 import PYTHON_VERSION, deparse_code
|
||||
from uncompyle6 import PYTHON_VERSION, code_deparse
|
||||
pytestmark = pytest.mark.skip(PYTHON_VERSION < 2.7,
|
||||
reason="need at least Python 2.7")
|
||||
|
||||
@pytest.mark.skip(PYTHON_VERSION < 2.7,
|
||||
reason="need at least Python 2.7")
|
||||
def test_single_mode():
|
||||
single_expressions = (
|
||||
'i = 1',
|
||||
'i and (j or k)',
|
||||
'i += 1',
|
||||
'i = j % 4',
|
||||
'i = {}',
|
||||
'i = []',
|
||||
'for i in range(10):\n i\n',
|
||||
'for i in range(10):\n for j in range(10):\n i + j\n',
|
||||
'try:\n i\nexcept Exception:\n j\nelse:\n k\n'
|
||||
)
|
||||
if PYTHON_VERSION > 2.6:
|
||||
def test_single_mode():
|
||||
single_expressions = (
|
||||
'i = 1',
|
||||
'i and (j or k)',
|
||||
'i += 1',
|
||||
'i = j % 4',
|
||||
'i = {}',
|
||||
'i = []',
|
||||
'for i in range(10):\n i\n',
|
||||
'for i in range(10):\n for j in range(10):\n i + j\n',
|
||||
'try:\n i\nexcept Exception:\n j\nelse:\n k\n'
|
||||
)
|
||||
|
||||
for expr in single_expressions:
|
||||
code = compile(expr + '\n', '<string>', 'single')
|
||||
assert deparse_code(PYTHON_VERSION, code, compile_mode='single').text == expr + '\n'
|
||||
for expr in single_expressions:
|
||||
code = compile(expr + '\n', '<string>', 'single')
|
||||
assert code_deparse(code, compile_mode='single').text == expr + '\n'
|
||||
|
@@ -1,23 +1,24 @@
|
||||
from uncompyle6.scanners.tok import Token
|
||||
|
||||
|
||||
def test_token():
|
||||
# Test token formatting of: LOAD_CONST None
|
||||
t = Token('LOAD_CONST', offset=0, attr=None, pattr=None, has_arg=True)
|
||||
expect = ' 0 LOAD_CONST None'
|
||||
t = Token("LOAD_CONST", offset=0, attr=None, pattr=None, has_arg=True)
|
||||
expect = "0 LOAD_CONST None"
|
||||
# print(t.format())
|
||||
assert t
|
||||
assert t.format() == expect
|
||||
assert t.format().strip() == expect.strip()
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
# Make sure formatting of: LOAD_CONST False. We assume False is the 0th index
|
||||
# of co_consts.
|
||||
t = Token('LOAD_CONST', offset=1, attr=False, pattr=False, has_arg=True)
|
||||
expect = ' 1 LOAD_CONST 0 False'
|
||||
assert t.format() == expect
|
||||
t = Token("LOAD_CONST", offset=1, attr=False, pattr=False, has_arg=True)
|
||||
expect = "1 LOAD_CONST False"
|
||||
assert t.format().strip() == expect.strip()
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
if __name__ == "__main__":
|
||||
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
|
||||
# Embedded file name: simple_source/branching/05_if.py
|
||||
|
||||
6 0 LOAD_NAME 0 'True'
|
||||
3 POP_JUMP_IF_FALSE 15 'to 15'
|
||||
L. 6 0 LOAD_NAME 0 'True'
|
||||
3 POP_JUMP_IF_FALSE 15 'to 15'
|
||||
|
||||
7 6 LOAD_NAME 1 'False'
|
||||
9 STORE_NAME 2 'b'
|
||||
12 JUMP_FORWARD 0 'to 15'
|
||||
15_0 COME_FROM 12 '12'
|
||||
15 LOAD_CONST 0 None
|
||||
18 RETURN_VALUE
|
||||
L. 7 6 LOAD_NAME 1 'False'
|
||||
9 STORE_NAME 2 'b'
|
||||
12 JUMP_FORWARD 0 'to 15'
|
||||
15_0 COME_FROM 12 '12'
|
||||
15 LOAD_CONST None
|
||||
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
|
||||
# Embedded file name: simple_source/branching/05_ifelse.py
|
||||
|
||||
3 0 LOAD_NAME 0 'True'
|
||||
3 POP_JUMP_IF_FALSE 15 'to 15'
|
||||
L. 3 0 LOAD_NAME 0 'True'
|
||||
3 POP_JUMP_IF_FALSE 15 'to 15'
|
||||
|
||||
4 6 LOAD_CONST 0 1
|
||||
9 STORE_NAME 1 'b'
|
||||
12 JUMP_FORWARD 6 'to 21'
|
||||
L. 4 6 LOAD_CONST 1
|
||||
9 STORE_NAME 1 'b'
|
||||
12 JUMP_FORWARD 6 'to 21'
|
||||
|
||||
6 15 LOAD_CONST 1 2
|
||||
18 STORE_NAME 2 'd'
|
||||
21_0 COME_FROM 12 '12'
|
||||
21 LOAD_CONST 2 None
|
||||
24 RETURN_VALUE
|
||||
L. 6 15 LOAD_CONST 2
|
||||
18 STORE_NAME 2 'd'
|
||||
21_0 COME_FROM 12 '12'
|
||||
21 LOAD_CONST None
|
||||
24 RETURN_VALUE
|
||||
|
@@ -1,20 +1,28 @@
|
||||
# future
|
||||
from __future__ import print_function
|
||||
|
||||
# std
|
||||
import os
|
||||
import difflib
|
||||
import subprocess
|
||||
import tempfile
|
||||
import functools
|
||||
# compatability
|
||||
import six
|
||||
|
||||
# uncompyle6 / xdis
|
||||
from uncompyle6 import PYTHON_VERSION, IS_PYPY, deparse_code
|
||||
from uncompyle6 import code_deparse
|
||||
from xdis.version_info import PYTHON_VERSION_TRIPLE, PYTHON3, IS_PYPY
|
||||
|
||||
# TODO : I think we can get xdis to support the dis api (python 3 version) by doing something like this there
|
||||
from xdis.bytecode import Bytecode
|
||||
from xdis.main import get_opcode
|
||||
opc = get_opcode(PYTHON_VERSION, IS_PYPY)
|
||||
from xdis import Bytecode, get_opcode
|
||||
|
||||
opc = get_opcode(PYTHON_VERSION_TRIPLE, IS_PYPY)
|
||||
Bytecode = functools.partial(Bytecode, opc=opc)
|
||||
import six
|
||||
|
||||
if PYTHON3:
|
||||
from io import StringIO
|
||||
else:
|
||||
from StringIO import StringIO
|
||||
|
||||
|
||||
def _dis_to_text(co):
|
||||
@@ -30,36 +38,32 @@ def print_diff(original, uncompyled):
|
||||
:param original: Text describing the original code object.
|
||||
:param uncompyled: Text describing the uncompyled code object.
|
||||
"""
|
||||
original_lines = original.split('\n')
|
||||
uncompyled_lines = uncompyled.split('\n')
|
||||
args = original_lines, uncompyled_lines, 'original', 'uncompyled'
|
||||
original_lines = original.split("\n")
|
||||
uncompyled_lines = uncompyled.split("\n")
|
||||
args = original_lines, uncompyled_lines, "original", "uncompyled"
|
||||
try:
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
diff = difflib.HtmlDiff().make_file(*args)
|
||||
diff = BeautifulSoup(diff, "html.parser")
|
||||
diff.select_one('table[summary="Legends"]').extract()
|
||||
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)
|
||||
|
||||
with tempfile.NamedTemporaryFile(delete=False) as f:
|
||||
f.write(str(diff).encode('utf-8'))
|
||||
f.write(str(diff).encode("utf-8"))
|
||||
|
||||
try:
|
||||
print()
|
||||
html = subprocess.check_output([
|
||||
'elinks',
|
||||
'-dump',
|
||||
'-no-references',
|
||||
'-dump-color-mode',
|
||||
'1',
|
||||
f.name,
|
||||
]).decode('utf-8')
|
||||
html = subprocess.check_output(
|
||||
["elinks", "-dump", "-no-references", "-dump-color-mode", "1", f.name]
|
||||
).decode("utf-8")
|
||||
print(html)
|
||||
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)
|
||||
print('\n'.join(diff))
|
||||
print("\n".join(diff))
|
||||
finally:
|
||||
os.unlink(f.name)
|
||||
|
||||
@@ -77,18 +81,19 @@ def are_instructions_equal(i1, i2):
|
||||
|
||||
:return: True if the two instructions are approximately equal, otherwise False.
|
||||
"""
|
||||
result = (1==1
|
||||
result = (
|
||||
1 == 1
|
||||
and i1.opname == i2.opname
|
||||
and i1.opcode == i2.opcode
|
||||
and i1.arg == i2.arg
|
||||
# ignore differences due to code objects
|
||||
# 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
|
||||
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
|
||||
# ignore differences in line numbers
|
||||
#and i1.starts_line
|
||||
# and i1.starts_line
|
||||
and i1.is_jump_target == i2.is_jump_target
|
||||
)
|
||||
return result
|
||||
@@ -112,22 +117,21 @@ def are_code_objects_equal(co1, co2):
|
||||
return True
|
||||
|
||||
|
||||
def validate_uncompyle(text, mode='exec'):
|
||||
def validate_uncompyle(text, mode="exec"):
|
||||
"""
|
||||
Validate decompilation of the given source code.
|
||||
|
||||
: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_text = text
|
||||
|
||||
deparsed = deparse_code(PYTHON_VERSION, original_code,
|
||||
compile_mode=mode,
|
||||
out=six.StringIO(),
|
||||
is_pypy=IS_PYPY)
|
||||
deparsed = code_deparse(
|
||||
original_code, out=six.StringIO(), version=PYTHON_VERSION_TRIPLE, compile_mode=mode
|
||||
)
|
||||
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):
|
||||
|
||||
@@ -135,15 +139,17 @@ def validate_uncompyle(text, mode='exec'):
|
||||
|
||||
def output(text, dis):
|
||||
width = 60
|
||||
return '\n\n'.join([
|
||||
' SOURCE CODE '.center(width, '#'),
|
||||
text.strip(),
|
||||
' BYTECODE '.center(width, '#'),
|
||||
dis
|
||||
])
|
||||
return "\n\n".join(
|
||||
[
|
||||
" SOURCE CODE ".center(width, "#"),
|
||||
text.strip(),
|
||||
" BYTECODE ".center(width, "#"),
|
||||
dis,
|
||||
]
|
||||
)
|
||||
|
||||
original = output(original_text, original_dis)
|
||||
uncompyled = output(uncompyled_text, uncompyled_dis)
|
||||
print_diff(original, uncompyled)
|
||||
|
||||
assert 'original' == 'uncompyled'
|
||||
assert "original" == "uncompyled"
|
||||
|
@@ -1,3 +1,3 @@
|
||||
pytest>=3.0.0,<=3.0.1
|
||||
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
|
||||
|
@@ -1,2 +1,4 @@
|
||||
# Pick up stuff from setup.py
|
||||
hypothesis==2.0.0
|
||||
pytest
|
||||
-e .
|
||||
|
56
setup.cfg
56
setup.cfg
@@ -1,11 +1,57 @@
|
||||
[bdist_rpm]
|
||||
release = 1
|
||||
packager = Mysterie <kajusska@gmail.com>
|
||||
doc_files = README
|
||||
# CHANGES.txt
|
||||
# USAGE.txt
|
||||
release = 0
|
||||
packager = rocky <rb@dustyfeet.com
|
||||
doc_files = README.rst
|
||||
ChangeLog
|
||||
COPYING
|
||||
DECOMPYLE-2.4-CHANGELOG.txt
|
||||
HISTORY.md
|
||||
HOW-TO_REPORT-A-BUG.md
|
||||
NEWS.md
|
||||
# doc/
|
||||
# examples/
|
||||
|
||||
[bdist_wheel]
|
||||
universal=1
|
||||
|
||||
[metadata]
|
||||
description_file = README.rst
|
||||
|
||||
[flake8]
|
||||
# max-line-length setting: NO we do not want everyone writing 120-character lines!
|
||||
# We are setting the maximum line length big here because there are longer
|
||||
# lines allowed by black in some cases that are forbidden by flake8. Since
|
||||
# black has the final say about code formatting issues, this setting is here to
|
||||
# make sure that flake8 doesn't fail the build on longer lines allowed by
|
||||
# black.
|
||||
max-line-length = 120
|
||||
max-complexity = 12
|
||||
select = E,F,W,C,B,B9
|
||||
ignore =
|
||||
# E123 closing bracket does not match indentation of opening bracket's line
|
||||
E123
|
||||
# E203 whitespace before ':' (Not PEP8 compliant, Python Black)
|
||||
E203
|
||||
# E501 line too long (82 > 79 characters) (replaced by B950 from flake8-bugbear,
|
||||
# https://github.com/PyCQA/flake8-bugbear)
|
||||
E501
|
||||
# W503 line break before binary operator (Not PEP8 compliant, Python Black)
|
||||
W503
|
||||
# W504 line break after binary operator (Not PEP8 compliant, Python Black)
|
||||
W504
|
||||
# C901 function too complex - since many of zz9 functions are too complex with a lot
|
||||
# of if branching
|
||||
C901
|
||||
# module level import not at top of file. This is too restrictive. Can't even have a
|
||||
# docstring higher.
|
||||
E402
|
||||
per-file-ignores =
|
||||
# These are config files. The `c` variable them is injected not defined.
|
||||
pow/ansible/roles/jupyterhub/templates/jupyterhub_config*.py:F821
|
||||
# Ignore some errors in files that are stolen from other projects to avoid lots
|
||||
# of merge problems later .
|
||||
pow/ansible/roles/webtier/files/supervisor_httpgroupok.py:E126,E128,E222,E225,E226,E261,E301,E302,E305,F841,E201,E202
|
||||
silhouette/src/silhouette/gprof2dot.py:E711,E713,E741,F401
|
||||
# Ignore undefined name errors in "expectation" test Python code.
|
||||
# These files get exec'd in an environment that defines the variables.
|
||||
server/tests/files/expectations/*.py:F821
|
||||
|
80
setup.py
80
setup.py
@@ -4,39 +4,59 @@ import sys
|
||||
"""Setup script for the 'uncompyle6' distribution."""
|
||||
|
||||
SYS_VERSION = sys.version_info[0:2]
|
||||
if not ((2, 6) <= SYS_VERSION <= (3, 7)) or ((3, 0) <= SYS_VERSION <= (3, 0)):
|
||||
mess = "Python Release 2.6 .. 3.7 excluding 3.0 are supported in this code branch."
|
||||
if ((2, 4) <= SYS_VERSION <= (2, 7)):
|
||||
mess += ("\nFor your Python, version %s, use the python-2.4 code/branch." %
|
||||
sys.version[0:3])
|
||||
elif SYS_VERSION < (2, 4) or (3, 0) <= SYS_VERSION:
|
||||
mess += ("\nThis package is not supported for Python version %s."
|
||||
% sys.version[0:3])
|
||||
if not ((2, 4) <= SYS_VERSION < (3, 11)):
|
||||
mess = "Python Release 2.6 .. 3.10 are supported in this code branch."
|
||||
if (2, 4) <= SYS_VERSION <= (2, 7):
|
||||
mess += (
|
||||
"\nFor your Python, version %s, use the python-2.4 code/branch."
|
||||
% sys.version[0:3]
|
||||
)
|
||||
if (3, 3) <= SYS_VERSION < (3, 6):
|
||||
mess += (
|
||||
"\nFor your Python, version %s, use the python-3.3-to-3.5 code/branch."
|
||||
% sys.version[0:3]
|
||||
)
|
||||
elif SYS_VERSION < (2, 4):
|
||||
mess += (
|
||||
"\nThis package is not supported for Python version %s." % sys.version[0:3]
|
||||
)
|
||||
print(mess)
|
||||
raise Exception(mess)
|
||||
|
||||
from __pkginfo__ import \
|
||||
author, author_email, install_requires, \
|
||||
license, long_description, classifiers, \
|
||||
entry_points, modname, py_modules, \
|
||||
short_desc, VERSION, web, \
|
||||
zip_safe
|
||||
from __pkginfo__ import (
|
||||
author,
|
||||
author_email,
|
||||
install_requires,
|
||||
license,
|
||||
long_description,
|
||||
classifiers,
|
||||
entry_points,
|
||||
modname,
|
||||
py_modules,
|
||||
short_desc,
|
||||
__version__,
|
||||
web,
|
||||
zip_safe,
|
||||
)
|
||||
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
setup(
|
||||
author = author,
|
||||
author_email = author_email,
|
||||
classifiers = classifiers,
|
||||
description = short_desc,
|
||||
entry_points = entry_points,
|
||||
install_requires = install_requires,
|
||||
license = license,
|
||||
long_description = long_description,
|
||||
name = modname,
|
||||
packages = find_packages(),
|
||||
py_modules = py_modules,
|
||||
test_suite = 'nose.collector',
|
||||
url = web,
|
||||
tests_require = ['nose>=1.0'],
|
||||
version = VERSION,
|
||||
zip_safe = zip_safe)
|
||||
author=author,
|
||||
author_email=author_email,
|
||||
classifiers=classifiers,
|
||||
description=short_desc,
|
||||
entry_points=entry_points,
|
||||
install_requires=install_requires,
|
||||
license=license,
|
||||
long_description=long_description,
|
||||
long_description_content_type="text/x-rst",
|
||||
name=modname,
|
||||
packages=find_packages(),
|
||||
py_modules=py_modules,
|
||||
test_suite="nose.collector",
|
||||
url=web,
|
||||
tests_require=["nose>=1.0"],
|
||||
version=__version__,
|
||||
zip_safe=zip_safe,
|
||||
)
|
||||
|
7
test/.gitignore
vendored
7
test/.gitignore
vendored
@@ -1 +1,8 @@
|
||||
/.coverage
|
||||
/.python-version
|
||||
/nohup.out
|
||||
/pycdc
|
||||
/test_pycdc_tests.sh
|
||||
/test_uncompyle2.py
|
||||
/test_unpy33.py
|
||||
/test_unpy37.py
|
||||
|
158
test/Makefile
158
test/Makefile
@@ -1,6 +1,7 @@
|
||||
PHONY=check clean dist distclean test test-unit test-functional rmChangeLog clean_pyc nosetests \
|
||||
check-bytecode-1 check-bytecode-1.4 check-bytecode-1.5 \
|
||||
check-bytecode-2 check-bytecode-3 \
|
||||
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.2 check-byteocde-2.3 check-bytecode-2.4 \
|
||||
check-short check-2.6 check-2.7 check-3.0 check-3.1 check-3.2 check-3.3 \
|
||||
check-3.4 check-3.5 check-3.6 check-3.7 check-5.6 5.6 5.8 \
|
||||
@@ -12,7 +13,7 @@ PHONY=check clean dist distclean test test-unit test-functional rmChangeLog clea
|
||||
GIT2CL ?= git2cl
|
||||
PYTHON ?= python
|
||||
|
||||
PYTHON_VERSION = $(shell $(PYTHON) -V 2>&1 | cut -d ' ' -f 2 | cut -d'.' -f1,2)
|
||||
PYTHON_VERSION = $(shell $(PYTHON) -V 2>&1 | cut -d ' ' -f 2 | cut -d'.' -f1,2 | head -1)
|
||||
NATIVE_CHECK = check-$(PYTHON_VERSION)
|
||||
|
||||
# Set COMPILE='--compile' to force compilation before check
|
||||
@@ -21,8 +22,8 @@ COVER_DIR=../tmp/grammar-cover
|
||||
|
||||
# Run short tests
|
||||
check-short:
|
||||
@$(PYTHON) -V && PYTHON_VERSION=`$(PYTHON) -V 2>&1 | cut -d ' ' -f 2 | cut -d'.' -f1,2`; \
|
||||
$(MAKE) check-bytecode
|
||||
@$(PYTHON) -V && PYTHON_VERSION=`$(PYTHON) -V 2>&1 | cut -d ' ' -f 2 | cut -d'.' -f1,2` | head -1; \
|
||||
$(MAKE) check-bytecode-${PYTHON_VERSION}
|
||||
|
||||
# Run all tests
|
||||
check:
|
||||
@@ -33,43 +34,57 @@ check-2.6 check-2.7: check-bytecode-2 check-bytecode-3 check-bytecode-1 check-na
|
||||
|
||||
#: Run working tests from Python 3.0
|
||||
check-3.0: check-bytecode
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.0 --weak-verify $(COMPILE)
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.0-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.0 --syntax-verify $(COMPILE)
|
||||
|
||||
#: Run working tests from Python 3.1
|
||||
check-3.1: check-bytecode
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.1 --weak-verify $(COMPILE)
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.1-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.1 --syntax-verify $(COMPILE)
|
||||
|
||||
#: Run working tests from Python 3.2
|
||||
check-3.2: check-bytecode
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.2 --weak-verify $(COMPILE)
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.2-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.2 --syntax-verify $(COMPILE)
|
||||
|
||||
#: Run working tests from Python 3.3
|
||||
check-3.3: check-bytecode
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.3 --weak-verify $(COMPILE)
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.3-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.3 --syntax-verify $(COMPILE)
|
||||
|
||||
#: Run working tests from Python 3.4
|
||||
check-3.4: check-bytecode check-3.4-ok check-2.7-ok
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.4 --weak-verify $(COMPILE)
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.4-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.4 --syntax-verify $(COMPILE)
|
||||
|
||||
#: Run working tests from Python 3.5
|
||||
check-3.5: check-bytecode
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.5 --weak-verify $(COMPILE)
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.5-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.5 --syntax-verify $(COMPILE)
|
||||
|
||||
#: Run working tests from Python 3.6
|
||||
check-3.6: check-bytecode
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.6 --weak-verify $(COMPILE)
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.6-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.6 --syntax-verify $(COMPILE)
|
||||
|
||||
#: Run working tests from Python 3.7
|
||||
check-3.7: check-bytecode
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.7 --weak-verify $(COMPILE)
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.7-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.7 --syntax-verify $(COMPILE)
|
||||
|
||||
#: Run working tests from Python 3.8
|
||||
check-3.8: check-bytecode
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.8-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.8 --syntax-verify $(COMPILE)
|
||||
|
||||
check-3.9: check-bytecode
|
||||
@echo "Note that we do not support decompiling Python 3.9 bytecode - no 3.9 tests run"
|
||||
|
||||
check-3.10: check-bytecode
|
||||
@echo "Note that we do not support decompiling Python 3.10 bytecode - no 3.10 tests run"
|
||||
|
||||
# FIXME
|
||||
#: this is called when running under pypy3.5-5.8.0 or pypy2-5.6.0
|
||||
#: this is called when running under pypy3.5-5.8.0, pypy2-5.6.0, or pypy3.6-7.3.0
|
||||
5.8 5.6:
|
||||
|
||||
#: Check deparsing only, but from a different Python version
|
||||
@@ -77,7 +92,7 @@ check-disasm:
|
||||
$(PYTHON) dis-compare.py
|
||||
|
||||
#: 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-bytecode-2:
|
||||
@@ -86,21 +101,58 @@ check-bytecode-2:
|
||||
--bytecode-2.5 --bytecode-2.6 --bytecode-2.7 --bytecode-pypy2.7
|
||||
|
||||
#: Check deparsing bytecode 3.x only
|
||||
check-bytecode-3:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.0 \
|
||||
--bytecode-3.1 --bytecode-3.2 --bytecode-3.3 \
|
||||
--bytecode-3.4 --bytecode-3.5 --bytecode-3.6 --bytecode-pypy3.2
|
||||
# check-bytecode-3:
|
||||
# $(PYTHON) test_pythonlib.py \
|
||||
# --bytecode-3.0 \
|
||||
# --bytecode-3.1 --bytecode-3.2 --bytecode-3.3 \
|
||||
# --bytecode-3.4 --bytecode-3.5 --bytecode-3.6 \
|
||||
# --bytecode-3.7 \
|
||||
# --bytecode-pypy3.2 --bytecode-pypy3.6 --bytecode-3.8
|
||||
|
||||
#: Check deparsing bytecode that works running Python 2 and Python 3
|
||||
# FIXME: Until we shaked out problems with xdis...
|
||||
check-bytecode-3:
|
||||
$(PYTHON) test_pythonlib.py \
|
||||
--bytecode-3.4 --bytecode-3.5 --bytecode-3.6 \
|
||||
--bytecode-3.7 --bytecode-3.8
|
||||
|
||||
#: Check deparsing on selected bytecode 3.x
|
||||
check-bytecode-3-short:
|
||||
$(PYTHON) test_pythonlib.py \
|
||||
--bytecode-3.4 --bytecode-3.5 --bytecode-3.6
|
||||
|
||||
#: Check deparsing bytecode on all Python 2 and Python 3 versions
|
||||
check-bytecode: check-bytecode-3
|
||||
$(PYTHON) test_pythonlib.py \
|
||||
--bytecode-1.4 --bytecode-1.5 \
|
||||
--bytecode-1.0 --bytecode-1.1 --bytecode-1.2 \
|
||||
--bytecode-1.3 --bytecode-1.4 --bytecode-1.5 \
|
||||
--bytecode-2.2 --bytecode-2.3 --bytecode-2.4 \
|
||||
--bytecode-2.1 --bytecode-2.2 --bytecode-2.3 --bytecode-2.4 \
|
||||
--bytecode-2.5 --bytecode-2.6 --bytecode-2.7 \
|
||||
--bytecode-pypy2.7
|
||||
|
||||
|
||||
#: Check deparsing bytecode on selected Python 2 and Python 3 versions
|
||||
check-bytecode-short: check-bytecode-3-short
|
||||
$(PYTHON) test_pythonlib.py \
|
||||
--bytecode-2.6 --bytecode-2.7 --bytecode-pypy2.7
|
||||
|
||||
|
||||
#: Check deparsing bytecode 1.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-bytecode-1.3:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-1.3
|
||||
|
||||
#: Check deparsing bytecode 1.4 only
|
||||
check-bytecode-1.4:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-1.4
|
||||
@@ -109,6 +161,10 @@ check-bytecode-1.4:
|
||||
check-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-bytecode-2.1:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-2.1
|
||||
@@ -151,7 +207,7 @@ grammar-coverage-2.6:
|
||||
grammar-coverage-2.7:
|
||||
-rm $(COVER_DIR)/spark-grammar-2.7.cover || true
|
||||
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-2.7.cover $(PYTHON) test_pythonlib.py --bytecode-2.7
|
||||
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-2.7.cover $(PYTHON) test_pyenvlib.py --2.7.14 --max=600
|
||||
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
|
||||
grammar-coverage-3.0:
|
||||
@@ -194,76 +250,88 @@ grammar-coverage-3.5:
|
||||
grammar-coverage-3.6:
|
||||
rm $(COVER_DIR)/spark-grammar-3.6.cover || /bin/true
|
||||
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-3.6.cover $(PYTHON) test_pythonlib.py --bytecode-3.6
|
||||
SPARK_PARSER_COVERAGE=$(COVER_DIR)/spark-grammar-3.6.cover $(PYTHON) test_pyenvlib.py --3.6.4 --max=280
|
||||
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-bytecode-2.6:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-2.6 --weak-verify
|
||||
$(PYTHON) test_pythonlib.py --bytecode-2.6-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-2.6 --syntax-verify
|
||||
|
||||
#: Check deparsing Python 2.7
|
||||
check-bytecode-2.7:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-2.7 --weak-verify
|
||||
$(PYTHON) test_pythonlib.py --bytecode-2.7-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-2.7 --syntax-verify
|
||||
|
||||
#: Check deparsing Python 3.0
|
||||
check-bytecode-3.0:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.0 --weak-verify
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.0-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.0 --syntax-verify
|
||||
|
||||
#: Check deparsing Python 3.1
|
||||
check-bytecode-3.1:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.1 --weak-verify
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.1-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.1 --syntax-verify
|
||||
|
||||
#: Check deparsing Python 3.2
|
||||
check-bytecode-3.2:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.2 --weak-verify
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.2-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.2 --syntax-verify
|
||||
|
||||
#: Check deparsing Python 3.3
|
||||
check-bytecode-3.3:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.3 --weak-verify
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.3-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.3 --syntax-verify
|
||||
|
||||
#: Check deparsing Python 3.4
|
||||
check-bytecode-3.4:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.4 --weak-verify
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.4-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.4 --syntax-verify
|
||||
|
||||
#: Check deparsing Python 3.5
|
||||
check-bytecode-3.5:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.5 --weak-verify
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.5-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.5 --syntax-verify
|
||||
|
||||
#: Check deparsing Python 3.6
|
||||
check-bytecode-3.6:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.6 --weak-verify
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.6-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.6 --syntax-verify
|
||||
|
||||
#: Check deparsing Python 3.7
|
||||
check-bytecode-3.7:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.7 --weak-verify
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.7-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.7 --syntax-verify
|
||||
|
||||
#: Check deparsing Python 3.8
|
||||
check-bytecode-3.8:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.8-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.8 --syntax-verify
|
||||
|
||||
#: short tests for bytecodes only for this version of Python
|
||||
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)
|
||||
|
||||
#: Run longer Python 2.6's lib files known to be okay
|
||||
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
|
||||
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
|
||||
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
|
||||
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]
|
||||
# Skip for now
|
||||
@@ -277,6 +345,20 @@ pypy-2.7 5.0 5.3 6.0:
|
||||
pypy-3.2 2.4:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-pypy3.2 --verify
|
||||
|
||||
#: PyPy 5.0.x with Python 3.6.1 ...
|
||||
check-bytecode-pypy3.6: 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.3
|
||||
7.3 7.2:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-pypy3.6-run --verify-run
|
||||
$(PYTHON) test_pythonlib.py --bytecode-pypy3.6 --verify
|
||||
|
||||
|
||||
|
||||
clean: clean-py-dis clean-dis clean-unverified
|
||||
|
||||
clean-dis:
|
||||
|
@@ -2,15 +2,35 @@
|
||||
""" Trivial helper program to bytecompile and run an uncompile
|
||||
"""
|
||||
import os, sys, py_compile
|
||||
assert len(sys.argv) >= 2
|
||||
|
||||
assert (2 <= len(sys.argv) <= 4)
|
||||
version = sys.version[0:3]
|
||||
for path in sys.argv[1:]:
|
||||
vers = sys.version_info[:2]
|
||||
if sys.argv[1] in ("--run", "-r"):
|
||||
suffix = "_run"
|
||||
py_source = sys.argv[2:]
|
||||
i = 2
|
||||
else:
|
||||
suffix = ""
|
||||
py_source = sys.argv[1:]
|
||||
i = 1
|
||||
try:
|
||||
optimize = int(sys.argv[-1])
|
||||
py_source = sys.argv[i:-1]
|
||||
except:
|
||||
optimize = 2
|
||||
|
||||
for path in py_source:
|
||||
short = os.path.basename(path)
|
||||
if hasattr(sys, 'pypy_version_info'):
|
||||
cfile = "bytecode_pypy%s/%s" % (version, short) + 'c'
|
||||
if hasattr(sys, "pypy_version_info"):
|
||||
cfile = "bytecode_pypy%s%s/%s" % (version, suffix, short) + "c"
|
||||
else:
|
||||
cfile = "bytecode_%s/%s" % (version, short) + 'c'
|
||||
cfile = "bytecode_%s%s/%s" % (version, suffix, short) + "c"
|
||||
print("byte-compiling %s to %s" % (path, cfile))
|
||||
py_compile.compile(path, cfile)
|
||||
if isinstance(version, str) or version >= (2, 6, 0):
|
||||
os.system("../bin/uncompyle6 -a -t %s" % cfile)
|
||||
optimize = optimize
|
||||
if vers > (3, 1):
|
||||
py_compile.compile(path, cfile, optimize=optimize)
|
||||
else:
|
||||
py_compile.compile(path, cfile)
|
||||
if vers >= (2, 6):
|
||||
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.3/test_builtin.pyc
Normal file
BIN
test/bytecode_1.3/test_builtin.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_1.3/test_exceptions.pyc
Normal file
BIN
test/bytecode_1.3/test_exceptions.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_1.3/test_operations.pyc
Normal file
BIN
test/bytecode_1.3/test_operations.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_1.3/testall.pyc
Normal file
BIN
test/bytecode_1.3/testall.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_1.4/addpack.pyc
Normal file
BIN
test/bytecode_1.4/addpack.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_1.4/anydbm.pyc
Normal file
BIN
test/bytecode_1.4/anydbm.pyc
Normal file
Binary file not shown.
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.
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/03_iftrue.pyc
Normal file
BIN
test/bytecode_2.4/03_iftrue.pyc
Normal file
Binary file not shown.
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.
BIN
test/bytecode_2.4_run/01_for_else_try_else.pyc
Normal file
BIN
test/bytecode_2.4_run/01_for_else_try_else.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
test/bytecode_2.6/04_lastc_with_loops.pyc
Normal file
BIN
test/bytecode_2.6/04_lastc_with_loops.pyc
Normal file
Binary file not shown.
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/01_lambda_call.pyc
Normal file
BIN
test/bytecode_2.6_run/01_lambda_call.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_2.6_run/01_triple_compare.pyc
Normal file
BIN
test/bytecode_2.6_run/01_triple_compare.pyc
Normal file
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.
BIN
test/bytecode_2.6_run/02_ifelse_comprehension.pyc
Normal file
BIN
test/bytecode_2.6_run/02_ifelse_comprehension.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
test/bytecode_2.6_run/04_and_del.pyc
Normal file
BIN
test/bytecode_2.6_run/04_and_del.pyc
Normal file
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.
BIN
test/bytecode_2.6_run/04_ifelse_parens.pyc
Normal file
BIN
test/bytecode_2.6_run/04_ifelse_parens.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
test/bytecode_2.7/01_module_doc.pyc
Normal file
BIN
test/bytecode_2.7/01_module_doc.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_2.7/05_while_elif.pyc
Normal file
BIN
test/bytecode_2.7/05_while_elif.pyc
Normal file
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.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user