You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-02 16:44:46 +08:00
Part of the decompye3 loop "continue" fixes
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
""" Trivial helper program to byte compile and run an uncompyle6 on the bytecode file.
|
||||
""" Trivial helper program to byte compile and uncompile the bytecode file.
|
||||
"""
|
||||
import os, sys, py_compile
|
||||
from xdis.version_info import version_tuple_to_str, PYTHON_VERSION_TRIPLE
|
||||
@@ -8,6 +8,9 @@ if len(sys.argv) < 2:
|
||||
print("Usage: add-test.py [--run] *python-source*... [optimize-level]")
|
||||
sys.exit(1)
|
||||
|
||||
assert 2 <= len(sys.argv) <= 4
|
||||
version = sys.version[0:3]
|
||||
vers = sys.version_info[:2]
|
||||
if sys.argv[1] in ("--run", "-r"):
|
||||
suffix = "_run"
|
||||
assert sys.argv >= 3
|
||||
@@ -28,6 +31,8 @@ except:
|
||||
|
||||
for path in py_source:
|
||||
short = os.path.basename(path)
|
||||
if short.endswith(".py"):
|
||||
short = short[: -len(".py")]
|
||||
if hasattr(sys, "pypy_version_info"):
|
||||
version = version_tuple_to_str(end=2, delimiter="")
|
||||
bytecode = "bytecode_pypy%s%s/%spy%s.pyc" % (version, suffix, short, version)
|
||||
|
BIN
test/bytecode_3.8/03_loop_try_break.pyc
Normal file
BIN
test/bytecode_3.8/03_loop_try_break.pyc
Normal file
Binary file not shown.
62
test/simple_source/bug38/03_loop_try_break.py
Normal file
62
test/simple_source/bug38/03_loop_try_break.py
Normal file
@@ -0,0 +1,62 @@
|
||||
# From uncompyle issue #295 on 3.8
|
||||
# In 3.8 BREAK_LOOP and CONTINUE_LOOP no longer exist.
|
||||
# The bug is that the "break" is turned into:
|
||||
# POP_BLOCK
|
||||
# JUMP_ABSOLUTE
|
||||
while True:
|
||||
try:
|
||||
x = 1
|
||||
break
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
while True:
|
||||
try:
|
||||
x -= 1
|
||||
except Exception:
|
||||
break
|
||||
|
||||
# Issue #25 https://github.com/rocky/python-decompile3/issues/25
|
||||
# Same as above using "for".
|
||||
for i in range(5):
|
||||
try:
|
||||
x = 1
|
||||
break
|
||||
except Exception:
|
||||
if i == 4:
|
||||
raise
|
||||
|
||||
# From 3.8.1 _osx_support.py
|
||||
# Bug was handling a "break" inside a "try".
|
||||
# In 3.8 POP_EXCEPT is moved before "JUMP_ABSOLUTE" of
|
||||
# the break.
|
||||
# FIXME:
|
||||
# def compiler_fixup(compiler_so, cc_args, index):
|
||||
# if index:
|
||||
# while True:
|
||||
# try:
|
||||
# index = 1
|
||||
# except:
|
||||
# index = 2
|
||||
# break
|
||||
|
||||
|
||||
# Bug was returning an IfExp inside "with":
|
||||
# the return value is mixed in with the "with"
|
||||
# code finalization.
|
||||
# FIXME:
|
||||
# def _read_output(x, a):
|
||||
# with x as fp:
|
||||
# return fp if a else None
|
||||
|
||||
|
||||
# In 3.8 the CONTINUE_LOOP disappears,
|
||||
# and this makes it harder to detect continue
|
||||
# inside a loop with a continue in the except clause.
|
||||
def connect_ws_with_retry(f1, f2):
|
||||
while True:
|
||||
try:
|
||||
f1()
|
||||
except Exception:
|
||||
f2()
|
||||
continue
|
@@ -49,6 +49,7 @@ class Python38Parser(Python37Parser):
|
||||
stmt ::= whilestmt38
|
||||
stmt ::= whileTruestmt38
|
||||
stmt ::= call_stmt
|
||||
stmt ::= continue
|
||||
|
||||
call_stmt ::= call
|
||||
break ::= POP_BLOCK BREAK_LOOP
|
||||
@@ -56,6 +57,12 @@ class Python38Parser(Python37Parser):
|
||||
break ::= POP_TOP BREAK_LOOP
|
||||
break ::= POP_EXCEPT BREAK_LOOP
|
||||
|
||||
# The "continue" rule is a weird one. In 3.8, CONTINUE_LOOP was removed.
|
||||
# Inside an loop we can have this, which can only appear in side a try/except
|
||||
# And it can also appear at the end of the try except.
|
||||
continue ::= POP_EXCEPT JUMP_BACK
|
||||
|
||||
|
||||
# FIXME: this should be restricted to being inside a try block
|
||||
stmt ::= except_ret38
|
||||
stmt ::= except_ret38a
|
||||
|
Reference in New Issue
Block a user