incomplete progress on try-except 3.10

This commit is contained in:
Tim Sweet
2025-06-05 13:54:38 -05:00
parent fbcfcb9f6c
commit 130279c2ac
2 changed files with 116 additions and 4 deletions
+4 -3
View File
@@ -72,7 +72,9 @@ def run(file: Path, out_dir: Path, version: PythonVersion, print=False):
edit_pyc_lines(pyc, src_lines) edit_pyc_lines(pyc, src_lines)
cfts = {bc.codeobj: bc_to_cft(bc) for bc in pyc.iter_bytecodes()} cfts = {bc.codeobj: bc_to_cft(bc) for bc in pyc.iter_bytecodes()}
out_src = normalize_source(str(SourceContext(pyc, src_lines, cfts))) out_src = (str(SourceContext(pyc, src_lines, cfts)))
try: out_src = normalize_source(out_src)
except: pass
out_path = out_dir / "b.py" out_path = out_dir / "b.py"
out_path.write_text(out_src, encoding="utf-8") out_path.write_text(out_src, encoding="utf-8")
@@ -158,8 +160,7 @@ def main(input: Path, output: str, version: PythonVersion, graph: str | None, pr
results = run(input, o, version)[0] results = run(input, o, version)[0]
if results in [Result.CompileError, Result.Error]: if results in [Result.CompileError, Result.Error]:
print(results) print(results)
else: print_diff(o / input.stem / "a.py", o / input.stem / "b.py")
print_diff(o / input.stem / "a.py", o / input.stem / "b.py")
else: else:
if not output: if not output:
out_dir = get_unused(prefix / str(version) / input.stem) out_dir = get_unused(prefix / str(version) / input.stem)
@@ -4,7 +4,7 @@ from typing import override
from .Block import BlockTemplate from .Block import BlockTemplate
from .Conditional import IfElse, IfThen from .Conditional import IfElse, IfThen
from ..cft import ControlFlowTemplate, EdgeCategory, EdgeKind, InstTemplate, SourceLine, SourceContext, register_template from ..cft import ControlFlowTemplate, EdgeCategory, EdgeKind, InstTemplate, SourceLine, SourceContext, register_template
from ..utils import E, N, T, condense_mapping, defer_source_to, ending_instructions, exact_instructions, no_back_edges, revert_on_fail, starting_instructions, to_indented_source, make_try_match, versions_from from ..utils import E, N, T, condense_mapping, defer_source_to, ending_instructions, exact_instructions, no_back_edges, revert_on_fail, starting_instructions, to_indented_source, make_try_match, versions_from, hook_template
reraise = +N().with_cond(exact_instructions("COPY", "POP_EXCEPT", "RERAISE")) reraise = +N().with_cond(exact_instructions("COPY", "POP_EXCEPT", "RERAISE"))
@@ -20,6 +20,18 @@ class Except3_11(ControlFlowTemplate):
if x := BareExcept3_11.try_match(cfg, node): if x := BareExcept3_11.try_match(cfg, node):
return x return x
class Except3_10(ControlFlowTemplate):
@classmethod
@override
def try_match(cls, cfg, node) -> ControlFlowTemplate | None:
if [x.opname for x in node.get_instructions()] == ["RERAISE"]:
return node
if x := ExceptExc3_10.try_match(cfg, node):
return x
if x := BareExcept3_10.try_match(cfg, node):
return x
if isinstance(node, Except3_10):
return node
@register_template(0, 0, *versions_from(3, 12)) @register_template(0, 0, *versions_from(3, 12))
class Try3_12(ControlFlowTemplate): class Try3_12(ControlFlowTemplate):
@@ -87,7 +99,106 @@ class TryElse3_12(ControlFlowTemplate):
else: else:
{try_else} {try_else}
""" """
@register_template(0, 0, *versions_from(3, 10))
class Try3_10(ControlFlowTemplate):
template = T(
try_header=N("try_body"),
try_body=N("try_footer.", None, "except_body"),
try_footer=N("tail."),
except_body=N("tail."),
tail=N.tail(),
)
try_match = revert_on_fail(
make_try_match(
{
EdgeKind.Fall: "tail",
},
"try_header",
"try_body",
"except_body",
"try_footer",
)
)
@to_indented_source
def to_indented_source():
"""
{try_header}
try:
{try_body}
{except_body}
"""
class ExcBody3_10(ControlFlowTemplate):
@classmethod
@override
def try_match(cls, cfg, node) -> ControlFlowTemplate | None:
if x := NamedExc3_10.try_match(cfg, node):
return x
return node
class NamedExc3_10(ExcBody3_10):
template = T(
STORE=N("body", None, "reraise").with_cond(exact_instructions("POP_TOP", "STORE_FAST", "POP_TOP", "SETUP_FINALLY")),
body=N("tail.", None, "cleanup"),
cleanup=N(E.exc("reraise")).with_cond(exact_instructions("POP_EXCEPT", "LOAD_CONST", "STORE_FAST", "DELETE_FAST", "LOAD_CONST", "RETURN_VALUE")),
reraise=reraise,
tail=N.tail(),
)
try_match = make_try_match({EdgeKind.Fall: "tail", EdgeKind.Exception: "reraise"}, "STORE", "body", "cleanup")
to_indented_source = defer_source_to("body")
# @register_template(0, 0, *versions_from(3, 10))
class BareExcept3_10(Except3_10):
template = T(
except_body=N("tail.", None).of_type(BlockTemplate),
tail=N.tail(),
)
try_match = make_try_match(
{
EdgeKind.Fall: "tail",
},
"except_body",
)
@to_indented_source
def to_indented_source():
"""
except:
{except_body}
"""
@register_template(0, 0, *versions_from(3, 10))
class ExceptExc3_10(Except3_10):
template = T(
except_header = N("body", "falsejump"),
body = N("tail."),
falsejump = N("tail.").of_subtemplate(ExcBody3_10),
tail = N.tail(),
)
try_match = make_try_match(
{
EdgeKind.Fall: "tail",
#EdgeKind.Exception: "reraise",
},
"body",
"except_header",
"falsejump",
)
@to_indented_source
def to_indented_source():
"""
{except_header}
{body}
{falsejump}
"""
class BareExcept3_11(Except3_11): class BareExcept3_11(Except3_11):
template = T( template = T(