blob: 3f121c8679663cd99b46789f54545de282bde770 [file] [log] [blame] [edit]
-- 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