[case testTryExcept1]
def g() -> None:
    try:
        object()
    except:
        print("weeee")
[out]
def g():
    r0 :: object
    r1 :: str
    r2, r3 :: object
    r4 :: tuple[object, object, object]
    r5 :: str
    r6 :: object
    r7 :: str
    r8, r9 :: object
    r10 :: bit
L0:
L1:
    r0 = builtins :: module
    r1 = 'object'
    r2 = CPyObject_GetAttr(r0, r1)
    r3 = PyObject_CallFunctionObjArgs(r2, 0)
    goto L5
L2: (handler for L1)
    r4 = CPy_CatchError()
    r5 = 'weeee'
    r6 = builtins :: module
    r7 = 'print'
    r8 = CPyObject_GetAttr(r6, r7)
    r9 = PyObject_CallFunctionObjArgs(r8, r5, 0)
L3:
    CPy_RestoreExcInfo(r4)
    goto L5
L4: (handler for L2)
    CPy_RestoreExcInfo(r4)
    r10 = CPy_KeepPropagating()
    unreachable
L5:
    return 1

[case testTryExcept2]
def g(b: bool) -> None:
    try:
        if b:
            object()
        else:
            str('hi')
    except:
        print("weeee")
[out]
def g(b):
    b :: bool
    r0 :: object
    r1 :: str
    r2, r3 :: object
    r4, r5 :: str
    r6 :: tuple[object, object, object]
    r7 :: str
    r8 :: object
    r9 :: str
    r10, r11 :: object
    r12 :: bit
L0:
L1:
    if b goto L2 else goto L3 :: bool
L2:
    r0 = builtins :: module
    r1 = 'object'
    r2 = CPyObject_GetAttr(r0, r1)
    r3 = PyObject_CallFunctionObjArgs(r2, 0)
    goto L4
L3:
    r4 = 'hi'
    r5 = PyObject_Str(r4)
L4:
    goto L8
L5: (handler for L1, L2, L3, L4)
    r6 = CPy_CatchError()
    r7 = 'weeee'
    r8 = builtins :: module
    r9 = 'print'
    r10 = CPyObject_GetAttr(r8, r9)
    r11 = PyObject_CallFunctionObjArgs(r10, r7, 0)
L6:
    CPy_RestoreExcInfo(r6)
    goto L8
L7: (handler for L5)
    CPy_RestoreExcInfo(r6)
    r12 = CPy_KeepPropagating()
    unreachable
L8:
    return 1

[case testTryExcept3]
def g() -> None:
    try:
        print('a')
        try:
            object()
        except AttributeError as e:
            print('b', e)
    except:
        print("weeee")
[out]
def g():
    r0 :: str
    r1 :: object
    r2 :: str
    r3, r4, r5 :: object
    r6 :: str
    r7, r8 :: object
    r9 :: tuple[object, object, object]
    r10 :: object
    r11 :: str
    r12 :: object
    r13 :: bit
    r14, e :: object
    r15 :: str
    r16 :: object
    r17 :: str
    r18, r19 :: object
    r20 :: bit
    r21 :: tuple[object, object, object]
    r22 :: str
    r23 :: object
    r24 :: str
    r25, r26 :: object
    r27 :: bit
L0:
L1:
    r0 = 'a'
    r1 = builtins :: module
    r2 = 'print'
    r3 = CPyObject_GetAttr(r1, r2)
    r4 = PyObject_CallFunctionObjArgs(r3, r0, 0)
L2:
    r5 = builtins :: module
    r6 = 'object'
    r7 = CPyObject_GetAttr(r5, r6)
    r8 = PyObject_CallFunctionObjArgs(r7, 0)
    goto L8
L3: (handler for L2)
    r9 = CPy_CatchError()
    r10 = builtins :: module
    r11 = 'AttributeError'
    r12 = CPyObject_GetAttr(r10, r11)
    r13 = CPy_ExceptionMatches(r12)
    if r13 goto L4 else goto L5 :: bool
L4:
    r14 = CPy_GetExcValue()
    e = r14
    r15 = 'b'
    r16 = builtins :: module
    r17 = 'print'
    r18 = CPyObject_GetAttr(r16, r17)
    r19 = PyObject_CallFunctionObjArgs(r18, r15, e, 0)
    goto L6
L5:
    CPy_Reraise()
    unreachable
L6:
    CPy_RestoreExcInfo(r9)
    goto L8
L7: (handler for L3, L4, L5)
    CPy_RestoreExcInfo(r9)
    r20 = CPy_KeepPropagating()
    unreachable
L8:
    goto L12
L9: (handler for L1, L6, L7, L8)
    r21 = CPy_CatchError()
    r22 = 'weeee'
    r23 = builtins :: module
    r24 = 'print'
    r25 = CPyObject_GetAttr(r23, r24)
    r26 = PyObject_CallFunctionObjArgs(r25, r22, 0)
L10:
    CPy_RestoreExcInfo(r21)
    goto L12
L11: (handler for L9)
    CPy_RestoreExcInfo(r21)
    r27 = CPy_KeepPropagating()
    unreachable
L12:
    return 1

[case testTryExcept4]
def g() -> None:
    try:
        pass
    except KeyError:
        print("weeee")
    except IndexError:
        print("yo")
[out]
def g():
    r0 :: tuple[object, object, object]
    r1 :: object
    r2 :: str
    r3 :: object
    r4 :: bit
    r5 :: str
    r6 :: object
    r7 :: str
    r8, r9, r10 :: object
    r11 :: str
    r12 :: object
    r13 :: bit
    r14 :: str
    r15 :: object
    r16 :: str
    r17, r18 :: object
    r19 :: bit
L0:
L1:
    goto L9
L2: (handler for L1)
    r0 = CPy_CatchError()
    r1 = builtins :: module
    r2 = 'KeyError'
    r3 = CPyObject_GetAttr(r1, r2)
    r4 = CPy_ExceptionMatches(r3)
    if r4 goto L3 else goto L4 :: bool
L3:
    r5 = 'weeee'
    r6 = builtins :: module
    r7 = 'print'
    r8 = CPyObject_GetAttr(r6, r7)
    r9 = PyObject_CallFunctionObjArgs(r8, r5, 0)
    goto L7
L4:
    r10 = builtins :: module
    r11 = 'IndexError'
    r12 = CPyObject_GetAttr(r10, r11)
    r13 = CPy_ExceptionMatches(r12)
    if r13 goto L5 else goto L6 :: bool
L5:
    r14 = 'yo'
    r15 = builtins :: module
    r16 = 'print'
    r17 = CPyObject_GetAttr(r15, r16)
    r18 = PyObject_CallFunctionObjArgs(r17, r14, 0)
    goto L7
L6:
    CPy_Reraise()
    unreachable
L7:
    CPy_RestoreExcInfo(r0)
    goto L9
L8: (handler for L2, L3, L4, L5, L6)
    CPy_RestoreExcInfo(r0)
    r19 = CPy_KeepPropagating()
    unreachable
L9:
    return 1

[case testTryFinally]
def a(b: bool) -> None:
    try:
        if b:
            raise Exception('hi')
    finally:
        print('finally')
[out]
def a(b):
    b :: bool
    r0 :: str
    r1 :: object
    r2 :: str
    r3, r4 :: object
    r5, r6, r7 :: tuple[object, object, object]
    r8 :: str
    r9 :: object
    r10 :: str
    r11, r12 :: object
    r13 :: bit
L0:
L1:
    if b goto L2 else goto L3 :: bool
L2:
    r0 = 'hi'
    r1 = builtins :: module
    r2 = 'Exception'
    r3 = CPyObject_GetAttr(r1, r2)
    r4 = PyObject_CallFunctionObjArgs(r3, r0, 0)
    CPy_Raise(r4)
    unreachable
L3:
L4:
L5:
    r5 = <error> :: tuple[object, object, object]
    r6 = r5
    goto L7
L6: (handler for L1, L2, L3)
    r7 = CPy_CatchError()
    r6 = r7
L7:
    r8 = 'finally'
    r9 = builtins :: module
    r10 = 'print'
    r11 = CPyObject_GetAttr(r9, r10)
    r12 = PyObject_CallFunctionObjArgs(r11, r8, 0)
    if is_error(r6) goto L9 else goto L8
L8:
    CPy_Reraise()
    unreachable
L9:
    goto L13
L10: (handler for L7, L8)
    if is_error(r6) goto L12 else goto L11
L11:
    CPy_RestoreExcInfo(r6)
L12:
    r13 = CPy_KeepPropagating()
    unreachable
L13:
    return 1

[case testWith]
from typing import Any
def foo(x: Any) -> None:
    with x() as y:
        print('hello')
[out]
def foo(x):
    x, r0, r1 :: object
    r2 :: str
    r3 :: object
    r4 :: str
    r5, r6 :: object
    r7 :: bool
    y :: object
    r8 :: str
    r9 :: object
    r10 :: str
    r11, r12 :: object
    r13, r14 :: tuple[object, object, object]
    r15, r16, r17, r18 :: object
    r19 :: i32
    r20 :: bit
    r21 :: bool
    r22 :: bit
    r23, r24, r25 :: tuple[object, object, object]
    r26, r27 :: object
    r28 :: bit
L0:
    r0 = PyObject_CallFunctionObjArgs(x, 0)
    r1 = PyObject_Type(r0)
    r2 = '__exit__'
    r3 = CPyObject_GetAttr(r1, r2)
    r4 = '__enter__'
    r5 = CPyObject_GetAttr(r1, r4)
    r6 = PyObject_CallFunctionObjArgs(r5, r0, 0)
    r7 = 1
L1:
L2:
    y = r6
    r8 = 'hello'
    r9 = builtins :: module
    r10 = 'print'
    r11 = CPyObject_GetAttr(r9, r10)
    r12 = PyObject_CallFunctionObjArgs(r11, r8, 0)
    goto L8
L3: (handler for L2)
    r13 = CPy_CatchError()
    r7 = 0
    r14 = CPy_GetExcInfo()
    r15 = r14[0]
    r16 = r14[1]
    r17 = r14[2]
    r18 = PyObject_CallFunctionObjArgs(r3, r0, r15, r16, r17, 0)
    r19 = PyObject_IsTrue(r18)
    r20 = r19 >= 0 :: signed
    r21 = truncate r19: i32 to builtins.bool
    if r21 goto L5 else goto L4 :: bool
L4:
    CPy_Reraise()
    unreachable
L5:
L6:
    CPy_RestoreExcInfo(r13)
    goto L8
L7: (handler for L3, L4, L5)
    CPy_RestoreExcInfo(r13)
    r22 = CPy_KeepPropagating()
    unreachable
L8:
L9:
L10:
    r23 = <error> :: tuple[object, object, object]
    r24 = r23
    goto L12
L11: (handler for L1, L6, L7, L8)
    r25 = CPy_CatchError()
    r24 = r25
L12:
    if r7 goto L13 else goto L14 :: bool
L13:
    r26 = load_address _Py_NoneStruct
    r27 = PyObject_CallFunctionObjArgs(r3, r0, r26, r26, r26, 0)
L14:
    if is_error(r24) goto L16 else goto L15
L15:
    CPy_Reraise()
    unreachable
L16:
    goto L20
L17: (handler for L12, L13, L14, L15)
    if is_error(r24) goto L19 else goto L18
L18:
    CPy_RestoreExcInfo(r24)
L19:
    r28 = CPy_KeepPropagating()
    unreachable
L20:
    return 1

[case testWithNativeSimple]
class DummyContext:
    def __enter__(self) -> None:
        pass
    def __exit__(self, exc_type, exc_val, exc_tb) -> None:
        pass

def foo(x: DummyContext) -> None:
    with x:
        print('hello')
[out]
def DummyContext.__enter__(self):
    self :: __main__.DummyContext
L0:
    return 1
def DummyContext.__exit__(self, exc_type, exc_val, exc_tb):
    self :: __main__.DummyContext
    exc_type, exc_val, exc_tb :: object
L0:
    return 1
def foo(x):
    x :: __main__.DummyContext
    r0 :: None
    r1 :: bool
    r2 :: str
    r3 :: object
    r4 :: str
    r5, r6 :: object
    r7, r8 :: tuple[object, object, object]
    r9, r10, r11 :: object
    r12 :: None
    r13 :: object
    r14 :: i32
    r15 :: bit
    r16 :: bool
    r17 :: bit
    r18, r19, r20 :: tuple[object, object, object]
    r21 :: object
    r22 :: None
    r23 :: bit
L0:
    r0 = x.__enter__()
    r1 = 1
L1:
L2:
    r2 = 'hello'
    r3 = builtins :: module
    r4 = 'print'
    r5 = CPyObject_GetAttr(r3, r4)
    r6 = PyObject_CallFunctionObjArgs(r5, r2, 0)
    goto L8
L3: (handler for L2)
    r7 = CPy_CatchError()
    r1 = 0
    r8 = CPy_GetExcInfo()
    r9 = r8[0]
    r10 = r8[1]
    r11 = r8[2]
    r12 = x.__exit__(r9, r10, r11)
    r13 = box(None, r12)
    r14 = PyObject_IsTrue(r13)
    r15 = r14 >= 0 :: signed
    r16 = truncate r14: i32 to builtins.bool
    if r16 goto L5 else goto L4 :: bool
L4:
    CPy_Reraise()
    unreachable
L5:
L6:
    CPy_RestoreExcInfo(r7)
    goto L8
L7: (handler for L3, L4, L5)
    CPy_RestoreExcInfo(r7)
    r17 = CPy_KeepPropagating()
    unreachable
L8:
L9:
L10:
    r18 = <error> :: tuple[object, object, object]
    r19 = r18
    goto L12
L11: (handler for L1, L6, L7, L8)
    r20 = CPy_CatchError()
    r19 = r20
L12:
    if r1 goto L13 else goto L14 :: bool
L13:
    r21 = load_address _Py_NoneStruct
    r22 = x.__exit__(r21, r21, r21)
L14:
    if is_error(r19) goto L16 else goto L15
L15:
    CPy_Reraise()
    unreachable
L16:
    goto L20
L17: (handler for L12, L13, L14, L15)
    if is_error(r19) goto L19 else goto L18
L18:
    CPy_RestoreExcInfo(r19)
L19:
    r23 = CPy_KeepPropagating()
    unreachable
L20:
    return 1
