From 521b06dffa3db77191ec8e56ced9191397a19325 Mon Sep 17 00:00:00 2001 From: caandt Date: Fri, 11 Jul 2025 11:06:51 -0500 Subject: [PATCH] formatter --- dev_scripts/cflow.py | 29 +--- .../templates/Conditional.py | 2 +- .../templates/Exception.py | 27 ++- .../control_flow_reconstruction/utils.py | 5 +- pylingual/utils/generate_bytecode.py | 13 +- test/Conditional.py | 38 +++++ test/Generator.py | 22 ++- test/Loop.py | 55 +++++- test/TryExcept.py | 159 ++++++++++++------ test/with.py | 30 ++++ 10 files changed, 264 insertions(+), 116 deletions(-) diff --git a/dev_scripts/cflow.py b/dev_scripts/cflow.py index 5ec54bf..8df7538 100644 --- a/dev_scripts/cflow.py +++ b/dev_scripts/cflow.py @@ -52,7 +52,7 @@ def edit_pyc_lines(pyc: PYCFile, src_lines: list[str]): line_insts[0].starts_line = lno for inst in line_insts[1:]: inst.starts_line = None - if lno is not None and lno + 1 not in lno_bytecodes and pyc.version <= (3, 7) and src_lines[lno - 1].strip().startswith('@'): + if lno is not None and lno + 1 not in lno_bytecodes and pyc.version <= (3, 7) and src_lines[lno - 1].strip().startswith("@"): bc.instructions[line_insts[0].offset // 2 + 1].starts_line = lno + 1 @@ -113,34 +113,17 @@ def print_results(a: Path, b: Path, result: Result, results: list[tuple[bool, st else: console.print(result, style="red bold underline") -def equivalence_report_json( - infilename: Path, result: 'Result', - version: PythonVersion, - results: list[tuple[bool, str]] | Exception) -> dict: + +def equivalence_report_json(infilename: Path, result: "Result", version: PythonVersion, results: list[tuple[bool, str]] | Exception) -> dict: report = [] if isinstance(results, Exception): - report.append({ - "file": str(infilename), - "version": str(version), - "name": result.name, - "status": "error" - }) + report.append({"file": str(infilename), "version": str(version), "name": result.name, "status": "error"}) elif isinstance(results, list) and results: for success, result in results: - report.append({ - "file": str(infilename), - "version": str(version), - "name": result.split(": ")[0], - "status": "true" if success else "false" - }) + report.append({"file": str(infilename), "version": str(version), "name": result.split(": ")[0], "status": "true" if success else "false"}) else: - report.append({ - "file": str(infilename), - "version": str(version), - "name": "error", - "status": "error" - }) + report.append({"file": str(infilename), "version": str(version), "name": "error", "status": "error"}) return {"equivalence_report": report} diff --git a/pylingual/control_flow_reconstruction/templates/Conditional.py b/pylingual/control_flow_reconstruction/templates/Conditional.py index fe2b603..f163981 100644 --- a/pylingual/control_flow_reconstruction/templates/Conditional.py +++ b/pylingual/control_flow_reconstruction/templates/Conditional.py @@ -46,7 +46,7 @@ class IfThen(ControlFlowTemplate): class Assertion(ControlFlowTemplate): template = T( assertion=~N("fail", "tail"), - fail=+N().with_cond(starting_instructions("LOAD_ASSERTION_ERROR"), has_instval("LOAD_GLOBAL", argval = "AssertionError")).with_cond(has_no_lines), + fail=+N().with_cond(starting_instructions("LOAD_ASSERTION_ERROR"), has_instval("LOAD_GLOBAL", argval="AssertionError")).with_cond(has_no_lines), tail=N.tail(), ) diff --git a/pylingual/control_flow_reconstruction/templates/Exception.py b/pylingual/control_flow_reconstruction/templates/Exception.py index 044fcd7..79be386 100644 --- a/pylingual/control_flow_reconstruction/templates/Exception.py +++ b/pylingual/control_flow_reconstruction/templates/Exception.py @@ -280,10 +280,10 @@ class TryFinally3_11(ControlFlowTemplate): def to_indented_source(self, source: SourceContext) -> list[SourceLine]: header = source[self.try_header] body = source[self.try_body, 1] - if isinstance(self.try_header, (Try3_11, TryElse3_11)) and self.members['try_body'] is None: + if isinstance(self.try_header, (Try3_11, TryElse3_11)) and self.members["try_body"] is None: s = header else: - s = chain(header, self.line('try:'), body) + s = chain(header, self.line("try:"), body) if isinstance(self.finally_body, BlockTemplate): i = self.cutoff + 1 @@ -295,7 +295,6 @@ class TryFinally3_11(ControlFlowTemplate): return list(chain(s, self.line("finally:"), in_finally, after)) - class Except3_9(ControlFlowTemplate): @classmethod @@ -309,7 +308,7 @@ class Except3_9(ControlFlowTemplate): return x if isinstance(node, Except3_9): return node - + class Except3_9(ControlFlowTemplate): @classmethod @@ -323,7 +322,7 @@ class Except3_9(ControlFlowTemplate): return x if isinstance(node, Except3_9): return node - + @register_template(0, 0, (3, 9), (3, 10)) class Try3_9(ControlFlowTemplate): @@ -603,7 +602,7 @@ class NamedExc3_6(ExcBody3_6): body=N("normal_cleanup.", None, "exception_cleanup"), normal_cleanup=~N("exception_cleanup."), exception_cleanup=~N("tail.").with_cond(with_instructions("STORE_FAST", "DELETE_FAST"), with_instructions("STORE_NAME", "DELETE_NAME")), - tail=N.tail() + tail=N.tail(), ) try_match = make_try_match({EdgeKind.Fall: "tail"}, "exception_cleanup", "header", "body", "normal_cleanup") @@ -613,10 +612,7 @@ class NamedExc3_6(ExcBody3_6): class ExceptExc3_6(Except3_6): template = T( - except_header=~N("except_body", "no_match").with_cond( - ending_instructions("COMPARE_OP", "POP_JUMP_IF_FALSE"), - ending_instructions("COMPARE_OP", "POP_JUMP_FORWARD_IF_FALSE") - ), + except_header=~N("except_body", "no_match").with_cond(ending_instructions("COMPARE_OP", "POP_JUMP_IF_FALSE"), ending_instructions("COMPARE_OP", "POP_JUMP_FORWARD_IF_FALSE")), except_body=~N("tail.", None).of_subtemplate(ExcBody3_6).with_in_deg(1), no_match=~N.tail().of_subtemplate(Except3_6), tail=N.tail(), @@ -647,7 +643,7 @@ class TryElse3_6(ControlFlowTemplate): template = T( try_header=~N("try_body").with_cond(exact_instructions("SETUP_EXCEPT"), exact_instructions("SETUP_FINALLY")), try_body=N("try_footer.", None, "except_body"), - try_footer=~N("else_body").with_in_deg(1), + try_footer=~N("else_body").with_in_deg(1), except_body=~N("tail.").with_in_deg(1).of_subtemplate(Except3_6).with_cond(without_instructions("RETURN_VALUE")), else_body=~N("tail.").with_in_deg(1), tail=N.tail(), @@ -677,11 +673,12 @@ class TryElse3_6(ControlFlowTemplate): {else_body} """ + @register_template(0, 0, (3, 6), (3, 7), (3, 8)) class ReturnFinally3_6(ControlFlowTemplate): template = T( try_header=~N("try_body").with_cond(exact_instructions("SETUP_FINALLY")), - try_body=N(None, None, "fail_body").with_cond(with_instructions("LOAD_CONST","RETURN_VALUE")), + try_body=N(None, None, "fail_body").with_cond(with_instructions("LOAD_CONST", "RETURN_VALUE")), fail_body=~N("tail."), tail=N.tail(), ) @@ -728,6 +725,7 @@ class BareExcept3_6(Except3_6): {except_body} """ + @register_template(2, 50, (3, 6), (3, 7), (3, 8)) class TryFinally3_6(ControlFlowTemplate): template = T( @@ -741,10 +739,9 @@ class TryFinally3_6(ControlFlowTemplate): try_except=N("finally_tail", None, "fail_body").of_type(TryElse3_6, Try3_6, ReturnFinally3_6), finally_tail=N("finally_body", None, "fail_body"), finally_body=~N("fail_body").with_in_deg(1).with_cond(no_back_edges), - fail_body=N("tail.").with_cond(with_instructions("POP_TOP", "END_FINALLY"),with_instructions("LOAD_CONST", "RETURN_VALUE")), + fail_body=N("tail.").with_cond(with_instructions("POP_TOP", "END_FINALLY"), with_instructions("LOAD_CONST", "RETURN_VALUE")), tail=N.tail(), ) - cutoff: int @@ -777,5 +774,3 @@ class TryFinally3_6(ControlFlowTemplate): after = [] return list(chain(header, self.line("try:"), body, self.line("finally:"), in_finally, after)) - - diff --git a/pylingual/control_flow_reconstruction/utils.py b/pylingual/control_flow_reconstruction/utils.py index f7d08b4..020d7c9 100644 --- a/pylingual/control_flow_reconstruction/utils.py +++ b/pylingual/control_flow_reconstruction/utils.py @@ -116,16 +116,17 @@ def has_incoming_edge_of_categories(*categories: str): if any(kind.value == category for category in categories): return True return False + return check -def has_instval(opname: str, argval : Any): +def has_instval(opname: str, argval: Any): def check_instructions(cfg: CFG, node: ControlFlowTemplate | None) -> bool: for x in node.get_instructions(): if x.opname == opname and x.argval == argval: return True return False - + return check_instructions diff --git a/pylingual/utils/generate_bytecode.py b/pylingual/utils/generate_bytecode.py index 2125938..a55a831 100644 --- a/pylingual/utils/generate_bytecode.py +++ b/pylingual/utils/generate_bytecode.py @@ -18,6 +18,7 @@ class CompileError(Exception): class PyenvError(Exception): pass + def compile_version(py_file, out_file, version): py_file = str(py_file) out_file = str(out_file) @@ -31,7 +32,8 @@ def compile_version(py_file, out_file, version): which_pyenv = shutil.which("pyenv") version_win = None - if platform.system() == "Windows": # workaround for pyenv-win being bugged when passing versions like 3.x not 3.x.y + if platform.system() == "Windows": # workaround for pyenv-win being bugged when passing versions like 3.x not 3.x.y + def try_get_version_patch(version_str) -> int | None: try: return int(version_str.split(".", 2)[2]) @@ -39,6 +41,7 @@ def compile_version(py_file, out_file, version): return None except ValueError: return None + pyenv_versions_cmd = [which_pyenv, *"versions --bare".split()] pyenv_versions_output = subprocess.run(pyenv_versions_cmd, shell=False, capture_output=True, text=True) if pyenv_versions_output.stderr: @@ -46,13 +49,7 @@ def compile_version(py_file, out_file, version): # get lastest pyenv version for the correct major.minor version pyenv_version_strings = list(filter(lambda x: x.startswith(f"{version.as_str()}"), pyenv_versions_output.stdout.splitlines())) if not any(x == version.as_str() for x in pyenv_version_strings): - pyenv_real_versions = list( - filter(lambda x: x is not None, - map(try_get_version_patch, - pyenv_version_strings - ) - ) - ) + pyenv_real_versions = list(filter(lambda x: x is not None, map(try_get_version_patch, pyenv_version_strings))) if len(pyenv_real_versions) == 0: raise PyenvError(f"Could not find pyenv version for {version.as_str()}") version_win = f"{version.as_str()}.{max(pyenv_real_versions)}" diff --git a/test/Conditional.py b/test/Conditional.py index 10064ef..19302fc 100644 --- a/test/Conditional.py +++ b/test/Conditional.py @@ -2,18 +2,21 @@ def a_if(): if a > b: print(1) + def b_elif(): if a > b: print(1) elif a == b: print(2) + def c_else(): if a > b: print(1) else: print(2) + def d_elif_else(): if a > b: print(1) @@ -22,25 +25,30 @@ def d_elif_else(): else: print(3) + def e_oneline(): print(1) if a > b else print(2) if a == b else print(3) + def a1_if_and(): if a > b and c > d: print(1) + def b1_elif_and(): if a > b and c > d: print(1) elif a == b: print(2) + def c1_else_and(): if a > b and c > d: print(1) else: print(2) + def d1_elif_else_and(): if a > b and c > d: print(1) @@ -49,22 +57,26 @@ def d1_elif_else_and(): else: print(3) + def a2_if_or(): if a > b or c > d: print(1) + def b2_elif_or(): if a > b or c > d: print(1) elif a == b: print(2) + def c2_else_or(): if a > b or c > d: print(1) else: print(2) + def d2_elif_else_or(): if a > b or c > d: print(1) @@ -73,22 +85,26 @@ def d2_elif_else_or(): else: print(3) + def a3_if_not(): if not a > b: print(1) + def b3_elif_not(): if not a > b: print(1) elif a == b: print(2) + def c3_else_not(): if not a > b: print(1) else: print(2) + def d3_elif_else_not(): if not a > b: print(1) @@ -97,6 +113,7 @@ def d3_elif_else_not(): else: print(3) + def e_nested_if(): if a > b: print(1) @@ -107,6 +124,7 @@ def e_nested_if(): else: print(4) + def e_nested_else(): if a > b: print(1) @@ -117,6 +135,7 @@ def e_nested_else(): else: print(4) + def f_if_pass(): if a > b: pass @@ -127,6 +146,7 @@ def a_nofallthru_if(): print(1) print("end") + def b_nofallthru_elif(): if a > b: print(1) @@ -134,6 +154,7 @@ def b_nofallthru_elif(): print(2) print("end") + def c_nofallthru_else(): if a > b: print(1) @@ -141,6 +162,7 @@ def c_nofallthru_else(): print(2) print("end") + def d_nofallthru_elif_else(): if a > b: print(1) @@ -150,15 +172,18 @@ def d_nofallthru_elif_else(): print(3) print("end") + def e_nofallthru_oneline(): print(1) if a > b else print(2) if a == b else print(3) print("end") + def a_nofallthru1_if_and(): if a > b and c > d: print(1) print("end") + def b_nofallthru1_elif_and(): if a > b and c > d: print(1) @@ -166,6 +191,7 @@ def b_nofallthru1_elif_and(): print(2) print("end") + def c_nofallthru1_else_and(): if a > b and c > d: print(1) @@ -173,6 +199,7 @@ def c_nofallthru1_else_and(): print(2) print("end") + def d_nofallthru1_elif_else_and(): if a > b and c > d: print(1) @@ -182,11 +209,13 @@ def d_nofallthru1_elif_else_and(): print(3) print("end") + def a_nofallthru2_if_or(): if a > b or c > d: print(1) print("end") + def b_nofallthru2_elif_or(): if a > b or c > d: print(1) @@ -194,6 +223,7 @@ def b_nofallthru2_elif_or(): print(2) print("end") + def c_nofallthru2_else_or(): if a > b or c > d: print(1) @@ -201,6 +231,7 @@ def c_nofallthru2_else_or(): print(2) print("end") + def d_nofallthru2_elif_else_or(): if a > b or c > d: print(1) @@ -210,11 +241,13 @@ def d_nofallthru2_elif_else_or(): print(3) print("end") + def a_nofallthru3_if_not(): if not a > b: print(1) print("end") + def b_nofallthru3_elif_not(): if not a > b: print(1) @@ -222,6 +255,7 @@ def b_nofallthru3_elif_not(): print(2) print("end") + def c_nofallthru3_else_not(): if not a > b: print(1) @@ -229,6 +263,7 @@ def c_nofallthru3_else_not(): print(2) print("end") + def d_nofallthru3_elif_else_not(): if not a > b: print(1) @@ -238,6 +273,7 @@ def d_nofallthru3_elif_else_not(): print(3) print("end") + def e_nofallthru_nested_if(): if a > b: print(1) @@ -249,6 +285,7 @@ def e_nofallthru_nested_if(): print(4) print("end") + def e_nofallthru_nested_else(): if a > b: print(1) @@ -260,6 +297,7 @@ def e_nofallthru_nested_else(): print(4) print("end") + def f_nofallthru_if_pass(): if a > b: pass diff --git a/test/Generator.py b/test/Generator.py index d2777be..4a17dae 100644 --- a/test/Generator.py +++ b/test/Generator.py @@ -1,55 +1,70 @@ import asyncio + # Test 1: Simple async generator async def gen1(): yield 1 yield 2 + # Test 2: Async generator with await async def gen2(): await asyncio.sleep(0) yield "done" + # Test 3: Async generator using a loop async def gen3(): for i in range(3): yield i + # Test 4: Async generator with async for loop (consuming another async generator) async def gen4(): async for x in gen3(): yield x + # Test 5: Async generator with async with class DummyContext: - async def __aenter__(self): return self - async def __aexit__(self, exc_type, exc, tb): pass + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc, tb): + pass + async def gen5(): async with DummyContext(): yield "inside context" + # Test 6: Async generator that returns (implicitly ends) async def gen6(): yield "hello" return # Ends the generator + # Test 7: Nested yield and await async def gen7(): yield await asyncio.sleep(0, result="nested") + # Test 8: Function using 'yield' but not 'async def' (should be a regular generator) def regular_gen(): yield "normal generator" + # Test 9: Coroutine consuming async generator async def consume_gen(): async for item in gen2(): pass + # Test 10: Calling an async generator (should return an async generator object) g = gen1() -assert hasattr(g, '__anext__') # Just to test that it's an async generator object +assert hasattr(g, "__anext__") # Just to test that it's an async generator object + # Test 11: Async generator with try/finally async def gen11(): @@ -58,6 +73,7 @@ async def gen11(): finally: await asyncio.sleep(0) + # Test 12: Async generator with exception handling async def gen12(): try: diff --git a/test/Loop.py b/test/Loop.py index b273d1f..323272e 100644 --- a/test/Loop.py +++ b/test/Loop.py @@ -1,25 +1,30 @@ # FOR LOOP TESTS + def a_for_over_list(): for x in [1, 2, 3]: print("for over list") + def b_for_over_tuples(): for a, b in [(1, 2), (3, 4)]: print("tuples") + def c_for_else(): for i in range(3): print("for body") else: print("for else") + def d_for_with_break(): for x in range(10): if x == 5: print("breaking") break + def e_for_with_continue(): for x in range(5): if x % 2 == 0: @@ -27,11 +32,13 @@ def e_for_with_continue(): continue print("after continue") + def f_nested_for_loops(): for i in range(2): for j in range(3): print(f"nested {i},{j}") + def g_for_with_try_except(): for x in range(2): try: @@ -39,19 +46,24 @@ def g_for_with_try_except(): except Exception: print("except block") + def h_for_with_with_statement(): for _ in range(1): with a: print("inside with") + def i_for_with_function_call_iterable(): def get_items(): return [1, 2, 3] + for item in get_items(): print(f"item: {item}") + def j_for_with_empty_body_ellipsis(): - for _ in range(3): ... + for _ in range(3): + ... def k_while_true_with_break(): @@ -59,6 +71,7 @@ def k_while_true_with_break(): print("while true") break + def l_while_with_else(): i = 0 while i < 3: @@ -67,6 +80,7 @@ def l_while_with_else(): else: print("while else") + def m_while_with_continue(): i = 0 while i < 5: @@ -76,12 +90,14 @@ def m_while_with_continue(): continue print("after continue") + def n_while_with_break(): i = 0 while True: print("break in while") break + def o_nested_while_loops(): i = 0 while i < 2: @@ -91,6 +107,7 @@ def o_nested_while_loops(): j += 1 i += 1 + def p_while_with_try_except(): while True: try: @@ -98,28 +115,29 @@ def p_while_with_try_except(): except: print("except in while") + def q_while_with_with_statement(): while True: with a: print("inside while with") + def r_for_inside_while(): while True: for x in [1, 2]: print("for in while") + def s_while_inside_for(): for _ in range(1): while True: print("while in for") break + def t_while_with_empty_body_ellipsis(): - while True: ... - - - - + while True: + ... def a_nofallthru_for_over_list(): @@ -127,11 +145,13 @@ def a_nofallthru_for_over_list(): print("for over list") print("end") + def b_nofallthru_for_over_tuples(): for a, b in [(1, 2), (3, 4)]: print("tuples") print("end") + def c_nofallthru_for_else(): for i in range(3): print("for body") @@ -139,6 +159,7 @@ def c_nofallthru_for_else(): print("for else") print("end") + def d_nofallthru_for_with_break(): for x in range(10): if x == 5: @@ -146,6 +167,7 @@ def d_nofallthru_for_with_break(): break print("end") + def e_nofallthru_for_with_continue(): for x in range(5): if x % 2 == 0: @@ -154,12 +176,14 @@ def e_nofallthru_for_with_continue(): print("after continue") print("end") + def f_nofallthru_nested_for_loops(): for i in range(2): for j in range(3): print(f"nested {i},{j}") print("end") + def g_nofallthru_for_with_try_except(): for x in range(2): try: @@ -168,21 +192,26 @@ def g_nofallthru_for_with_try_except(): print("except block") print("end") + def h_nofallthru_for_with_with_statement(): for _ in range(1): with a: print("inside with") print("end") + def i_nofallthru_for_with_function_call_iterable(): def g_nofallthruet_items(): return [1, 2, 3] + for item in get_items(): print(f"item: {item}") print("end") + def j_nofallthru_for_with_empty_body_ellipsis(): - for _ in range(3): ... + for _ in range(3): + ... print("end") @@ -192,6 +221,7 @@ def k_nofallthru_while_true_with_break(): break print("end") + def l_nofallthru_while_with_else(): i = 0 while i < 3: @@ -201,6 +231,7 @@ def l_nofallthru_while_with_else(): print("while else") print("end") + def m_nofallthru_while_with_continue(): i = 0 while i < 5: @@ -211,6 +242,7 @@ def m_nofallthru_while_with_continue(): print("after continue") print("end") + def n_nofallthru_while_with_break(): i = 0 while True: @@ -218,6 +250,7 @@ def n_nofallthru_while_with_break(): break print("end") + def o_nofallthru_nested_while_loops(): i = 0 while i < 2: @@ -228,6 +261,7 @@ def o_nofallthru_nested_while_loops(): i += 1 print("end") + def p_nofallthru_while_with_try_except(): while True: try: @@ -236,18 +270,21 @@ def p_nofallthru_while_with_try_except(): print("except in while") print("end") + def q_nofallthru_while_with_with_statement(): while True: with a: print("inside while with") print("end") + def r_nofallthru_for_inside_while(): while True: for x in [1, 2]: print("for in while") print("end") + def s_nofallthru_while_inside_for(): for _ in range(1): while True: @@ -255,6 +292,8 @@ def s_nofallthru_while_inside_for(): break print("end") + def t_nofallthru_while_with_empty_body_ellipsis(): - while True: ... + while True: + ... print("end") diff --git a/test/TryExcept.py b/test/TryExcept.py index ad81ab9..e268fad 100644 --- a/test/TryExcept.py +++ b/test/TryExcept.py @@ -2,9 +2,10 @@ def a_TryExcept(): try: print(1) except: - print(2) + print(2) print(3) + def b_TryExceptBareNested(): try: print(1) @@ -15,6 +16,7 @@ def b_TryExceptBareNested(): except: print(4) + def b1_TryExceptBareNestedFallthrough(): try: print(1) @@ -26,6 +28,7 @@ def b1_TryExceptBareNestedFallthrough(): print(4) print(5) + def b2_TryExceptBareNestedEarlyFallthrough(): try: print(1) @@ -37,6 +40,7 @@ def b2_TryExceptBareNestedEarlyFallthrough(): print(4) print(5) + def b3_TryExceptBareNestedDoubleFallthrough(): try: print(1) @@ -49,6 +53,7 @@ def b3_TryExceptBareNestedDoubleFallthrough(): print(5) print(6) + def c_TryExceptBareMultiNested(): try: print(1) @@ -65,6 +70,7 @@ def c_TryExceptBareMultiNested(): except: print(7) + def c1_TryExceptBareMultiNestedFallthrough(): try: print(1) @@ -82,6 +88,7 @@ def c1_TryExceptBareMultiNestedFallthrough(): except: print(8) + def c2_TryExceptBareMultiNestedFallthrough2(): try: print(1) @@ -100,6 +107,7 @@ def c2_TryExceptBareMultiNestedFallthrough2(): print(8) print(9) + def c3_TryExceptBareMultiNestedEarlyFallthrough(): try: print(1) @@ -117,6 +125,7 @@ def c3_TryExceptBareMultiNestedEarlyFallthrough(): print(7) print(8) + def c4_TryExceptBareMultiNestedAllFallthrough(): try: print(1) @@ -136,6 +145,7 @@ def c4_TryExceptBareMultiNestedAllFallthrough(): print(9) print(10) + def d_TryExceptBareNestedNamed(): try: print(1) @@ -146,6 +156,7 @@ def d_TryExceptBareNestedNamed(): except: print(4) + def d1_TryExceptBareNestedNamedFallthrough(): try: print(1) @@ -157,6 +168,7 @@ def d1_TryExceptBareNestedNamedFallthrough(): print(4) print(5) + def d2_TryExceptBareNestedNamedEarlyFallthrough(): try: print(1) @@ -168,6 +180,7 @@ def d2_TryExceptBareNestedNamedEarlyFallthrough(): print(4) print(5) + def d3_TryExceptBareNestedNamedDoubleFallthrough(): try: print(1) @@ -180,6 +193,7 @@ def d3_TryExceptBareNestedNamedDoubleFallthrough(): print(5) print(6) + def e_TryExceptElseBare(): try: print(1) @@ -189,6 +203,7 @@ def e_TryExceptElseBare(): print(3) print(4) + def f_TryExceptElseFinallyBare(): try: print(1) @@ -200,6 +215,7 @@ def f_TryExceptElseFinallyBare(): print(4) print(5) + def g_TryExceptElseMulti(): try: print(1) @@ -211,6 +227,7 @@ def g_TryExceptElseMulti(): print(4) print(5) + def h_TryExceptElseMultiFallback(): try: print(1) @@ -224,19 +241,21 @@ def h_TryExceptElseMultiFallback(): print(5) print(6) + def i_TryExceptElseMultiNamedAndUnnamed(): try: print(1) except A as a: - print(2) + print(2) except b: - print(3) + print(3) except: - print(4) + print(4) else: print(5) print(6) + def j_TryExceptElseNamed(): try: print(1) @@ -248,6 +267,7 @@ def j_TryExceptElseNamed(): print(4) print(5) + def k_TryExceptFinallyBare(): try: print(1) @@ -256,93 +276,102 @@ def k_TryExceptFinallyBare(): finally: print(3) print(4) - + + def l_TryExceptFinallyBareSpecific(): - try: - print(1) - except a: - print(2) - finally: - print(3) - print(4) + try: + print(1) + except a: + print(2) + finally: + print(3) + print(4) + def m_TryExceptMulti(): try: print(1) except a: - print(2) + print(2) except b: - print(3) + print(3) except c: - print(4) + print(4) print(5) + def n_TryExceptMultiFallback(): try: print(1) except a: - print(2) + print(2) except b: - print(3) + print(3) except: - print(4) + print(4) print(5) + def o_TryExceptMultiFallbackFinally(): - try: - print(1) - except a: - print(2) - except: - print(3) - finally: - print(4) - print(5) + try: + print(1) + except a: + print(2) + except: + print(3) + finally: + print(4) + print(5) + def p_TryExceptMultiNamed(): try: print(1) except A as a: - print(2) + print(2) except B as b: - print(3) + print(3) except C as c: - print(4) + print(4) print(5) + def q_TryExceptMultiNamedAndUnnamed(): try: print(1) except A as a: - print(2) + print(2) except b: - print(3) + print(3) except: - print(4) + print(4) print(5) + def r_TryExceptMultiNamedAndUnnamedFinally(): try: print(1) except A as a: - print(2) + print(2) except b: - print(3) + print(3) except: - print(4) + print(4) finally: print(5) print(6) + def s_TryExceptMultiNamedFallback(): try: print(1) except A as a: - print(2) + print(2) except: - print(3) + print(3) print(4) + def t_TryExceptMultiNamedFallbackFinally(): try: print(1) @@ -354,6 +383,7 @@ def t_TryExceptMultiNamedFallbackFinally(): print(4) print(5) + def u_TryExceptMultiNamedFinally(): try: print(1) @@ -365,16 +395,18 @@ def u_TryExceptMultiNamedFinally(): print(4) print(5) + def v_TryExceptMultiFinally(): - try: - print(1) - except a: - print(2) - except b: - print(3) - finally: - print(4) - print(5) + try: + print(1) + except a: + print(2) + except b: + print(3) + finally: + print(4) + print(5) + def w_TryExceptRaise(): try: @@ -394,6 +426,7 @@ def x_TryExceptRaiseMulti(): print(3) raise Exc + def y_TryExceptRaiseNamed(): try: print(1) @@ -401,6 +434,7 @@ def y_TryExceptRaiseNamed(): print(2) raise Exc + def z_TryExceptReturn(): try: print(1) @@ -408,6 +442,7 @@ def z_TryExceptReturn(): except: print(2) + def z1_TryExceptReturn(): try: print(1) @@ -416,6 +451,7 @@ def z1_TryExceptReturn(): print(2) return 3 + def aa_TryExceptReturnMulti(): try: print(1) @@ -425,6 +461,7 @@ def aa_TryExceptReturnMulti(): except b: print(3) + def aa1_TryExceptReturnMulti(): try: print(1) @@ -435,6 +472,7 @@ def aa1_TryExceptReturnMulti(): except b: print(3) + def ab_TryExceptReturnNamed(): try: print(1) @@ -446,12 +484,14 @@ def ab_TryExceptReturnNamed(): print(3) raise Exc + def TryEmptryFinally(): try: pass finally: print(1) + def TryMultiple(): try: print(1) @@ -463,6 +503,7 @@ def TryMultiple(): except: print(4) + def TryExceptElseTry(): try: print(1) @@ -474,6 +515,7 @@ def TryExceptElseTry(): except: print(4) + def TryFinallyNestedExcept(): try: print(1) @@ -483,38 +525,44 @@ def TryFinallyNestedExcept(): except: print(3) + def TryExceptTuple(): try: print(1) except (A, B): print(2) + def TryFinallyReturn(): try: print(1) finally: return 2 + def TryReturnFinally(): try: return 1 finally: print(2) + def TryReturnFinallyReturn(): try: return 1 finally: return 2 - + + def TryExceptRaise(): try: print(1) return 2 except: raise Exception() - -''' + + +""" def TryExceptReturnFinally(): try: raise Exception() @@ -523,16 +571,16 @@ def TryExceptReturnFinally(): return 2 finally: print(3) -''' - -''' +""" + +""" def TryFinallyRaise(): try: print(1) return 2 finally: raise Exception() -''' +""" def ab1_TryExceptReturnNamed(): @@ -543,6 +591,7 @@ def ab1_TryExceptReturnNamed(): print(2) return 3 + def ac_TryFinallyBareFallthrough(): try: print(1) @@ -550,9 +599,9 @@ def ac_TryFinallyBareFallthrough(): print(2) print(3) + def ad_TryFinallyBare(): try: print(1) finally: print(2) - diff --git a/test/with.py b/test/with.py index d51ccd7..e6359fa 100644 --- a/test/with.py +++ b/test/with.py @@ -2,134 +2,162 @@ def bare_with(): with a: print(1) + def bare_with_fallthrough(): with a: print(1) print(2) + ## Known to fail on 3.10 def multi_with(): with a, b: print(1) + def multi_with_fallthrough(): with a, b: print(1) print(2) + def with_as(): with a as c: print(1) + def with_as_fallthrough(): with a as c: print(1) print(2) + def multi_with_as(): with a, b as c: print(1) + def multi_with_as_fallthrough(): with a, b as c: print(1) print(2) + def with_multi_as(): with a as b, c: print(1) + def with_multi_as_fallthrough(): with a as b, c: print(1) print(2) + def multi_with_multi_as(): with a as b, c as d: print(1) + # Known to fail on 3.10 def multi_with_multi_as_fallthrough(): with a as b, c as d: print(1) print(2) + def multi_with_multi_as_alt(): with a, b as c, d: print(1) + # Known to fail on 3.10 def multi_with_multi_as_fallthrough_alt(): with a, b as c, d: print(1) print(2) + async def bare_async_with(): async with a: print(1) + async def bare_async_with_fallthrough(): async with a: print(1) print(2) + ## Known to fail on 3.10 async def multi_async_with(): async with a, b: print(1) + async def multi_async_with_fallthrough(): async with a, b: print(1) print(2) + async def with_as(): async with a as c: print(1) + async def with_as_fallthrough(): async with a as c: print(1) print(2) + async def multi_async_with_as(): async with a, b as c: print(1) + async def multi_async_with_as_fallthrough(): async with a, b as c: print(1) print(2) + async def with_multi_as(): async with a as b, c: print(1) + async def with_multi_as_fallthrough(): async with a as b, c: print(1) print(2) + async def multi_async_with_multi_as(): async with a as b, c as d: print(1) + # Known to fail on 3.10 async def multi_async_with_multi_as_fallthrough(): async with a as b, c as d: print(1) print(2) + async def multi_async_with_multi_as_alt(): async with a, b as c, d: print(1) + # Known to fail on 3.10 async def multi_async_with_multi_as_fallthrough_alt(): async with a, b as c, d: print(1) print(2) + def try_with_except(): # With statement with outer exception handler try: @@ -139,12 +167,14 @@ def try_with_except(): print(2) print(3) + def with_return(): # With statement with return with a: return 1 print(1) + def with_raise(): # With statement with raise with a: