(builder: IRBuilder, t: TryStmt)
| 1046 | |
| 1047 | |
| 1048 | def transform_try_stmt(builder: IRBuilder, t: TryStmt) -> None: |
| 1049 | # Our compilation strategy for try/except/else/finally is to |
| 1050 | # treat try/except/else and try/finally as separate language |
| 1051 | # constructs that we compile separately. When we have a |
| 1052 | # try/except/else/finally, we treat the try/except/else as the |
| 1053 | # body of a try/finally block. |
| 1054 | if t.is_star: |
| 1055 | builder.error("Exception groups and except* cannot be compiled yet", t.line) |
| 1056 | |
| 1057 | # Check if we're in an async function with a finally block that contains await |
| 1058 | use_async_version = False |
| 1059 | if t.finally_body and builder.fn_info.is_coroutine: |
| 1060 | detector = AwaitDetector() |
| 1061 | t.finally_body.accept(detector) |
| 1062 | |
| 1063 | if detector.has_await: |
| 1064 | # Use the async version that handles exceptions correctly |
| 1065 | use_async_version = True |
| 1066 | |
| 1067 | if t.finally_body: |
| 1068 | |
| 1069 | def transform_try_body() -> None: |
| 1070 | if t.handlers: |
| 1071 | transform_try_except_stmt(builder, t) |
| 1072 | else: |
| 1073 | builder.accept(t.body) |
| 1074 | |
| 1075 | body = t.finally_body |
| 1076 | |
| 1077 | if use_async_version: |
| 1078 | transform_try_finally_stmt_async( |
| 1079 | builder, transform_try_body, lambda: builder.accept(body), t.line |
| 1080 | ) |
| 1081 | else: |
| 1082 | transform_try_finally_stmt( |
| 1083 | builder, transform_try_body, lambda: builder.accept(body), t.line |
| 1084 | ) |
| 1085 | else: |
| 1086 | transform_try_except_stmt(builder, t) |
| 1087 | |
| 1088 | |
| 1089 | def get_sys_exc_info(builder: IRBuilder) -> list[Value]: |
no test coverage detected
searching dependent graphs…