| -- Test cases for exception handling insertion transform. |
| -- |
| -- The result includes refcount handling since these two transforms interact. |
| |
| [case testListGetAndUnboxError] |
| from typing import List |
| def f(x: List[int]) -> int: |
| return x[0] |
| [out] |
| def f(x): |
| x :: list |
| r0 :: short_int |
| r1 :: object |
| r2, r3 :: int |
| L0: |
| r0 = 0 |
| r1 = x[r0] :: list |
| if is_error(r1) goto L3 (error at f:3) else goto L1 |
| L1: |
| r2 = unbox(int, r1) |
| dec_ref r1 |
| if is_error(r2) goto L3 (error at f:3) else goto L2 |
| L2: |
| return r2 |
| L3: |
| r3 = <error> :: int |
| return r3 |
| |
| [case testListAppendAndSetItemError] |
| from typing import List |
| def f(x: List[int], y: int, z: int) -> None: |
| x.append(y) |
| x[y] = z |
| [out] |
| def f(x, y, z): |
| x :: list |
| y, z :: int |
| r0 :: object |
| r1 :: bool |
| r2 :: None |
| r3 :: object |
| r4 :: bool |
| r5, r6 :: None |
| L0: |
| inc_ref y :: int |
| r0 = box(int, y) |
| r1 = x.append(r0) :: list |
| dec_ref r0 |
| if not r1 goto L3 (error at f:3) else goto L1 :: bool |
| L1: |
| r2 = None |
| inc_ref z :: int |
| r3 = box(int, z) |
| r4 = x.__setitem__(y, r3) :: list |
| if not r4 goto L3 (error at f:4) else goto L2 :: bool |
| L2: |
| r5 = None |
| return r5 |
| L3: |
| r6 = <error> :: None |
| return r6 |
| |
| [case testOptionalHandling] |
| from typing import Optional |
| |
| class A: pass |
| |
| def f(x: Optional[A]) -> int: |
| if x is None: |
| return 1 |
| if x is not None: |
| return 2 |
| return 3 |
| [out] |
| def f(x): |
| x :: union[__main__.A, None] |
| r0 :: None |
| r1 :: object |
| r2 :: bool |
| r3 :: short_int |
| r4 :: __main__.A |
| r5 :: None |
| r6 :: object |
| r7, r8 :: bool |
| r9, r10 :: short_int |
| r11 :: int |
| L0: |
| r0 = None |
| r1 = box(None, r0) |
| r2 = x is r1 |
| if r2 goto L1 else goto L2 :: bool |
| L1: |
| r3 = 1 |
| return r3 |
| L2: |
| inc_ref x |
| r4 = cast(__main__.A, x) |
| if is_error(r4) goto L6 (error at f:8) else goto L3 |
| L3: |
| r5 = None |
| r6 = box(None, r5) |
| r7 = r4 is r6 |
| dec_ref r4 |
| r8 = !r7 |
| if r8 goto L4 else goto L5 :: bool |
| L4: |
| r9 = 2 |
| return r9 |
| L5: |
| r10 = 3 |
| return r10 |
| L6: |
| r11 = <error> :: int |
| return r11 |
| |
| [case testListSum] |
| from typing import List |
| def sum(a: List[int], l: int) -> int: |
| sum = 0 |
| i = 0 |
| while i < l: |
| sum = sum + a[i] |
| i = i + 1 |
| return sum |
| [out] |
| def sum(a, l): |
| a :: list |
| l :: int |
| r0 :: short_int |
| sum :: int |
| r1 :: short_int |
| i :: int |
| r2 :: bool |
| r3 :: object |
| r4, r5 :: int |
| r6 :: short_int |
| r7, r8 :: int |
| L0: |
| r0 = 0 |
| sum = r0 |
| r1 = 0 |
| i = r1 |
| L1: |
| r2 = i < l :: int |
| if r2 goto L2 else goto L7 :: bool |
| L2: |
| r3 = a[i] :: list |
| if is_error(r3) goto L8 (error at sum:6) else goto L3 |
| L3: |
| r4 = unbox(int, r3) |
| dec_ref r3 |
| if is_error(r4) goto L8 (error at sum:6) else goto L4 |
| L4: |
| r5 = sum + r4 :: int |
| dec_ref sum :: int |
| dec_ref r4 :: int |
| sum = r5 |
| r6 = 1 |
| r7 = i + r6 :: int |
| dec_ref i :: int |
| i = r7 |
| goto L1 |
| L5: |
| return sum |
| L6: |
| r8 = <error> :: int |
| return r8 |
| L7: |
| dec_ref i :: int |
| goto L5 |
| L8: |
| dec_ref sum :: int |
| dec_ref i :: int |
| goto L6 |
| |
| [case testTryExcept] |
| 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 :: None |
| r11 :: bool |
| r12, r13 :: None |
| L0: |
| L1: |
| r0 = builtins :: module |
| r1 = unicode_1 :: static ('object') |
| r2 = getattr r0, r1 |
| if is_error(r2) goto L3 (error at g:3) else goto L2 |
| L2: |
| r3 = py_call(r2) |
| dec_ref r2 |
| if is_error(r3) goto L3 (error at g:3) else goto L11 |
| L3: |
| r4 = error_catch |
| r5 = unicode_2 :: static ('weeee') |
| r6 = builtins :: module |
| r7 = unicode_3 :: static ('print') |
| r8 = getattr r6, r7 |
| if is_error(r8) goto L7 (error at g:5) else goto L4 |
| L4: |
| r9 = py_call(r8, r5) |
| dec_ref r8 |
| if is_error(r9) goto L7 (error at g:5) else goto L5 |
| L5: |
| r10 = unbox(None, r9) |
| dec_ref r9 |
| if is_error(r10) goto L7 (error at g:5) else goto L6 |
| L6: |
| restore_exc_info r4 |
| dec_ref r4 |
| goto L9 |
| L7: |
| restore_exc_info r4 |
| dec_ref r4 |
| r11 = keep_propagating |
| if not r11 goto L10 else goto L8 :: bool |
| L8: |
| unreachable |
| L9: |
| r12 = None |
| return r12 |
| L10: |
| r13 = <error> :: None |
| return r13 |
| L11: |
| dec_ref r3 |
| goto L9 |
| |
| [case testGenopsTryFinally] |
| def a() -> str: |
| try: |
| print() |
| return 'hi' |
| finally: |
| print('goodbye!') |
| [out] |
| def a(): |
| r0 :: object |
| r1 :: str |
| r2, r3 :: object |
| r4 :: None |
| r5, r6 :: str |
| r7 :: tuple[object, object, object] |
| r8 :: str |
| r9 :: tuple[object, object, object] |
| r10 :: str |
| r11 :: tuple[object, object, object] |
| r12 :: str |
| r13 :: object |
| r14 :: str |
| r15, r16 :: object |
| r17 :: None |
| r18, r19 :: bool |
| r20 :: str |
| L0: |
| L1: |
| r0 = builtins :: module |
| r1 = unicode_1 :: static ('print') |
| r2 = getattr r0, r1 |
| if is_error(r2) goto L6 (error at a:3) else goto L2 |
| L2: |
| r3 = py_call(r2) |
| dec_ref r2 |
| if is_error(r3) goto L6 (error at a:3) else goto L3 |
| L3: |
| r4 = unbox(None, r3) |
| dec_ref r3 |
| if is_error(r4) goto L6 (error at a:3) else goto L4 |
| L4: |
| r5 = unicode_2 :: static ('hi') |
| inc_ref r5 |
| r6 = r5 |
| L5: |
| r9 = <error> :: tuple[object, object, object] |
| r7 = r9 |
| goto L7 |
| L6: |
| r10 = <error> :: str |
| r6 = r10 |
| r11 = error_catch |
| r7 = r11 |
| L7: |
| r12 = unicode_3 :: static ('goodbye!') |
| r13 = builtins :: module |
| r14 = unicode_1 :: static ('print') |
| r15 = getattr r13, r14 |
| if is_error(r15) goto L15 (error at a:6) else goto L8 |
| L8: |
| r16 = py_call(r15, r12) |
| dec_ref r15 |
| if is_error(r16) goto L15 (error at a:6) else goto L9 |
| L9: |
| r17 = unbox(None, r16) |
| dec_ref r16 |
| if is_error(r17) goto L15 (error at a:6) else goto L10 |
| L10: |
| if is_error(r7) goto L13 else goto L11 |
| L11: |
| reraise_exc; r18 = 0 |
| if not r18 goto L15 else goto L22 :: bool |
| L12: |
| unreachable |
| L13: |
| if is_error(r6) goto L20 else goto L14 |
| L14: |
| return r6 |
| L15: |
| if is_error(r6) goto L16 else goto L23 |
| L16: |
| if is_error(r7) goto L18 else goto L17 |
| L17: |
| restore_exc_info r7 |
| dec_ref r7 |
| L18: |
| r19 = keep_propagating |
| if not r19 goto L21 else goto L19 :: bool |
| L19: |
| unreachable |
| L20: |
| unreachable |
| L21: |
| r20 = <error> :: str |
| return r20 |
| L22: |
| dec_ref r6 |
| dec_ref r7 |
| goto L12 |
| L23: |
| dec_ref r6 |
| goto L16 |
| |
| [case testDocstring1] |
| def lol() -> None: |
| """Hello""" |
| pass |
| [out] |
| def lol(): |
| r0 :: str |
| r1 :: None |
| L0: |
| r0 = unicode_1 :: static ('Hello') |
| r1 = None |
| return r1 |
| |
| [case testExceptUndefined1] |
| from typing import Any |
| def lol(x: Any) -> object: |
| try: |
| st = x.foo |
| except: |
| return '' |
| # No uninit check should be generated, since the exception branch always returns |
| return st |
| [out] |
| def lol(x): |
| x :: object |
| r0 :: str |
| r1, st :: object |
| r2 :: tuple[object, object, object] |
| r3 :: str |
| r4 :: bool |
| r5 :: object |
| L0: |
| L1: |
| r0 = unicode_3 :: static ('foo') |
| r1 = getattr x, r0 |
| if is_error(r1) goto L3 (error at lol:4) else goto L2 |
| L2: |
| st = r1 |
| goto L4 |
| L3: |
| r2 = error_catch |
| r3 = unicode_4 :: static |
| restore_exc_info r2 |
| dec_ref r2 |
| inc_ref r3 |
| return r3 |
| L4: |
| return st |
| |
| [case testExceptUndefined2] |
| from typing import Any |
| def lol(x: Any) -> object: |
| try: |
| a = x.foo |
| b = x.bar |
| except: |
| pass |
| # uninit checks are needed, since the exception can skip initializing the vars |
| return a + b |
| [out] |
| def lol(x): |
| x :: object |
| r0 :: str |
| r1, a :: object |
| r2 :: str |
| r3, b :: object |
| r4 :: tuple[object, object, object] |
| r5 :: bool |
| r6 :: object |
| r7, r8 :: bool |
| r9 :: object |
| L0: |
| L1: |
| r0 = unicode_3 :: static ('foo') |
| r1 = getattr x, r0 |
| if is_error(r1) goto L4 (error at lol:4) else goto L15 |
| L2: |
| a = r1 |
| r2 = unicode_4 :: static ('bar') |
| r3 = getattr x, r2 |
| if is_error(r3) goto L4 (error at lol:5) else goto L16 |
| L3: |
| b = r3 |
| goto L6 |
| L4: |
| r4 = error_catch |
| L5: |
| restore_exc_info r4 |
| dec_ref r4 |
| L6: |
| if is_error(a) goto L17 else goto L9 |
| L7: |
| raise UnboundLocalError("local variable 'a' referenced before assignment") |
| if not r7 goto L14 (error at lol:9) else goto L8 :: bool |
| L8: |
| unreachable |
| L9: |
| if is_error(b) goto L18 else goto L12 |
| L10: |
| raise UnboundLocalError("local variable 'b' referenced before assignment") |
| if not r8 goto L14 (error at lol:9) else goto L11 :: bool |
| L11: |
| unreachable |
| L12: |
| r6 = a + b |
| xdec_ref a |
| xdec_ref b |
| if is_error(r6) goto L14 (error at lol:9) else goto L13 |
| L13: |
| return r6 |
| L14: |
| r9 = <error> :: object |
| return r9 |
| L15: |
| xdec_ref a |
| goto L2 |
| L16: |
| xdec_ref b |
| goto L3 |
| L17: |
| xdec_ref b |
| goto L7 |
| L18: |
| xdec_ref a |
| goto L10 |
| |
| [case testMaybeUninitVarExc] |
| def f(b: bool) -> None: |
| u = 'a' |
| while b: |
| v = 'b' |
| if v is not u: |
| break |
| print(v) |
| [out] |
| def f(b): |
| b :: bool |
| r0, u, r1, v :: str |
| r2, r3 :: bool |
| r4 :: object |
| r5 :: str |
| r6, r7 :: object |
| r8, r9 :: None |
| r10 :: bool |
| r11 :: None |
| L0: |
| r0 = unicode_1 :: static ('a') |
| inc_ref r0 |
| u = r0 |
| L1: |
| if b goto L11 else goto L12 :: bool |
| L2: |
| r1 = unicode_2 :: static ('b') |
| inc_ref r1 |
| v = r1 |
| r2 = v is u |
| r3 = !r2 |
| if r3 goto L12 else goto L1 :: bool |
| L3: |
| r4 = builtins :: module |
| r5 = unicode_3 :: static ('print') |
| r6 = getattr r4, r5 |
| if is_error(r6) goto L13 (error at f:7) else goto L4 |
| L4: |
| if is_error(v) goto L14 else goto L7 |
| L5: |
| raise UnboundLocalError("local variable 'v' referenced before assignment") |
| if not r10 goto L10 (error at f:7) else goto L6 :: bool |
| L6: |
| unreachable |
| L7: |
| r7 = py_call(r6, v) |
| dec_ref r6 |
| xdec_ref v |
| if is_error(r7) goto L10 (error at f:7) else goto L8 |
| L8: |
| r8 = unbox(None, r7) |
| dec_ref r7 |
| if is_error(r8) goto L10 (error at f:7) else goto L9 |
| L9: |
| r9 = None |
| return r9 |
| L10: |
| r11 = <error> :: None |
| return r11 |
| L11: |
| xdec_ref v |
| goto L2 |
| L12: |
| dec_ref u |
| goto L3 |
| L13: |
| xdec_ref v |
| goto L10 |
| L14: |
| dec_ref r6 |
| goto L5 |