517 lines
9.5 KiB
Plaintext
517 lines
9.5 KiB
Plaintext
-- 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 :: object
|
|
r1, r2 :: int
|
|
L0:
|
|
r0 = CPyList_GetItemShort(x, 0)
|
|
if is_error(r0) goto L3 (error at f:3) else goto L1
|
|
L1:
|
|
r1 = unbox(int, r0)
|
|
dec_ref r0
|
|
if is_error(r1) goto L3 (error at f:3) else goto L2
|
|
L2:
|
|
return r1
|
|
L3:
|
|
r2 = <error> :: int
|
|
return r2
|
|
|
|
[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 :: int32
|
|
r2 :: bit
|
|
r3 :: object
|
|
r4 :: bit
|
|
r5 :: None
|
|
L0:
|
|
inc_ref y :: int
|
|
r0 = box(int, y)
|
|
r1 = PyList_Append(x, r0)
|
|
dec_ref r0
|
|
r2 = r1 >= 0 :: signed
|
|
if not r2 goto L3 (error at f:3) else goto L1 :: bool
|
|
L1:
|
|
inc_ref z :: int
|
|
r3 = box(int, z)
|
|
r4 = CPyList_SetItem(x, y, r3)
|
|
if not r4 goto L3 (error at f:4) else goto L2 :: bool
|
|
L2:
|
|
return 1
|
|
L3:
|
|
r5 = <error> :: None
|
|
return r5
|
|
|
|
[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 :: object
|
|
r1 :: bit
|
|
r2 :: __main__.A
|
|
r3 :: object
|
|
r4 :: bit
|
|
r5 :: int
|
|
L0:
|
|
r0 = load_address _Py_NoneStruct
|
|
r1 = x == r0
|
|
if r1 goto L1 else goto L2 :: bool
|
|
L1:
|
|
return 2
|
|
L2:
|
|
r2 = borrow cast(__main__.A, x)
|
|
if is_error(r2) goto L6 (error at f:8) else goto L3
|
|
L3:
|
|
r3 = load_address _Py_NoneStruct
|
|
r4 = r2 != r3
|
|
if r4 goto L4 else goto L5 :: bool
|
|
L4:
|
|
return 4
|
|
L5:
|
|
return 6
|
|
L6:
|
|
r5 = <error> :: int
|
|
return r5
|
|
|
|
[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, sum, i :: int
|
|
r0 :: native_int
|
|
r1 :: bit
|
|
r2 :: native_int
|
|
r3, r4, r5 :: bit
|
|
r6 :: object
|
|
r7, r8, r9, r10 :: int
|
|
L0:
|
|
sum = 0
|
|
i = 0
|
|
L1:
|
|
r0 = i & 1
|
|
r1 = r0 != 0
|
|
if r1 goto L3 else goto L2 :: bool
|
|
L2:
|
|
r2 = l & 1
|
|
r3 = r2 != 0
|
|
if r3 goto L3 else goto L4 :: bool
|
|
L3:
|
|
r4 = CPyTagged_IsLt_(i, l)
|
|
if r4 goto L5 else goto L10 :: bool
|
|
L4:
|
|
r5 = i < l :: signed
|
|
if r5 goto L5 else goto L10 :: bool
|
|
L5:
|
|
r6 = CPyList_GetItemBorrow(a, i)
|
|
if is_error(r6) goto L11 (error at sum:6) else goto L6
|
|
L6:
|
|
r7 = unbox(int, r6)
|
|
if is_error(r7) goto L11 (error at sum:6) else goto L7
|
|
L7:
|
|
r8 = CPyTagged_Add(sum, r7)
|
|
dec_ref sum :: int
|
|
dec_ref r7 :: int
|
|
sum = r8
|
|
r9 = CPyTagged_Add(i, 2)
|
|
dec_ref i :: int
|
|
i = r9
|
|
goto L1
|
|
L8:
|
|
return sum
|
|
L9:
|
|
r10 = <error> :: int
|
|
return r10
|
|
L10:
|
|
dec_ref i :: int
|
|
goto L8
|
|
L11:
|
|
dec_ref sum :: int
|
|
dec_ref i :: int
|
|
goto L9
|
|
|
|
[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 :: bit
|
|
r11 :: None
|
|
L0:
|
|
L1:
|
|
r0 = builtins :: module
|
|
r1 = 'object'
|
|
r2 = CPyObject_GetAttr(r0, r1)
|
|
if is_error(r2) goto L3 (error at g:3) else goto L2
|
|
L2:
|
|
r3 = PyObject_CallFunctionObjArgs(r2, 0)
|
|
dec_ref r2
|
|
if is_error(r3) goto L3 (error at g:3) else goto L10
|
|
L3:
|
|
r4 = CPy_CatchError()
|
|
r5 = 'weeee'
|
|
r6 = builtins :: module
|
|
r7 = 'print'
|
|
r8 = CPyObject_GetAttr(r6, r7)
|
|
if is_error(r8) goto L6 (error at g:5) else goto L4
|
|
L4:
|
|
r9 = PyObject_CallFunctionObjArgs(r8, r5, 0)
|
|
dec_ref r8
|
|
if is_error(r9) goto L6 (error at g:5) else goto L11
|
|
L5:
|
|
CPy_RestoreExcInfo(r4)
|
|
dec_ref r4
|
|
goto L8
|
|
L6:
|
|
CPy_RestoreExcInfo(r4)
|
|
dec_ref r4
|
|
r10 = CPy_KeepPropagating()
|
|
if not r10 goto L9 else goto L7 :: bool
|
|
L7:
|
|
unreachable
|
|
L8:
|
|
return 1
|
|
L9:
|
|
r11 = <error> :: None
|
|
return r11
|
|
L10:
|
|
dec_ref r3
|
|
goto L8
|
|
L11:
|
|
dec_ref r9
|
|
goto L5
|
|
|
|
[case testGenopsTryFinally]
|
|
def a() -> str:
|
|
try:
|
|
print()
|
|
return 'hi'
|
|
finally:
|
|
print('goodbye!')
|
|
[out]
|
|
def a():
|
|
r0 :: object
|
|
r1 :: str
|
|
r2, r3 :: object
|
|
r4, r5 :: str
|
|
r6, r7 :: tuple[object, object, object]
|
|
r8 :: str
|
|
r9 :: tuple[object, object, object]
|
|
r10 :: str
|
|
r11 :: object
|
|
r12 :: str
|
|
r13, r14 :: object
|
|
r15 :: bit
|
|
r16 :: str
|
|
L0:
|
|
L1:
|
|
r0 = builtins :: module
|
|
r1 = 'print'
|
|
r2 = CPyObject_GetAttr(r0, r1)
|
|
if is_error(r2) goto L5 (error at a:3) else goto L2
|
|
L2:
|
|
r3 = PyObject_CallFunctionObjArgs(r2, 0)
|
|
dec_ref r2
|
|
if is_error(r3) goto L5 (error at a:3) else goto L19
|
|
L3:
|
|
r4 = 'hi'
|
|
inc_ref r4
|
|
r5 = r4
|
|
L4:
|
|
r6 = <error> :: tuple[object, object, object]
|
|
r7 = r6
|
|
goto L6
|
|
L5:
|
|
r8 = <error> :: str
|
|
r5 = r8
|
|
r9 = CPy_CatchError()
|
|
r7 = r9
|
|
L6:
|
|
r10 = 'goodbye!'
|
|
r11 = builtins :: module
|
|
r12 = 'print'
|
|
r13 = CPyObject_GetAttr(r11, r12)
|
|
if is_error(r13) goto L20 (error at a:6) else goto L7
|
|
L7:
|
|
r14 = PyObject_CallFunctionObjArgs(r13, r10, 0)
|
|
dec_ref r13
|
|
if is_error(r14) goto L20 (error at a:6) else goto L21
|
|
L8:
|
|
if is_error(r7) goto L11 else goto L22
|
|
L9:
|
|
CPy_Reraise()
|
|
if not 0 goto L13 else goto L23 :: bool
|
|
L10:
|
|
unreachable
|
|
L11:
|
|
if is_error(r5) goto L17 else goto L12
|
|
L12:
|
|
return r5
|
|
L13:
|
|
if is_error(r7) goto L15 else goto L14
|
|
L14:
|
|
CPy_RestoreExcInfo(r7)
|
|
xdec_ref r7
|
|
L15:
|
|
r15 = CPy_KeepPropagating()
|
|
if not r15 goto L18 else goto L16 :: bool
|
|
L16:
|
|
unreachable
|
|
L17:
|
|
unreachable
|
|
L18:
|
|
r16 = <error> :: str
|
|
return r16
|
|
L19:
|
|
dec_ref r3
|
|
goto L3
|
|
L20:
|
|
xdec_ref r5
|
|
goto L13
|
|
L21:
|
|
dec_ref r14
|
|
goto L8
|
|
L22:
|
|
xdec_ref r5
|
|
goto L9
|
|
L23:
|
|
xdec_ref r7
|
|
goto L10
|
|
|
|
[case testDocstring1]
|
|
def lol() -> None:
|
|
"""Hello"""
|
|
pass
|
|
[out]
|
|
def lol():
|
|
L0:
|
|
return 1
|
|
|
|
[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
|
|
L0:
|
|
L1:
|
|
r0 = 'foo'
|
|
r1 = CPyObject_GetAttr(x, r0)
|
|
if is_error(r1) goto L3 (error at lol:4) else goto L2
|
|
L2:
|
|
st = r1
|
|
goto L4
|
|
L3:
|
|
r2 = CPy_CatchError()
|
|
r3 = ''
|
|
CPy_RestoreExcInfo(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, r0, a, r1, b :: object
|
|
r2 :: str
|
|
r3 :: object
|
|
r4 :: str
|
|
r5 :: object
|
|
r6 :: tuple[object, object, object]
|
|
r7, r8 :: bool
|
|
r9, r10 :: object
|
|
L0:
|
|
r0 = <error> :: object
|
|
a = r0
|
|
r1 = <error> :: object
|
|
b = r1
|
|
L1:
|
|
r2 = 'foo'
|
|
r3 = CPyObject_GetAttr(x, r2)
|
|
if is_error(r3) goto L4 (error at lol:4) else goto L15
|
|
L2:
|
|
a = r3
|
|
r4 = 'bar'
|
|
r5 = CPyObject_GetAttr(x, r4)
|
|
if is_error(r5) goto L4 (error at lol:5) else goto L16
|
|
L3:
|
|
b = r5
|
|
goto L6
|
|
L4:
|
|
r6 = CPy_CatchError()
|
|
L5:
|
|
CPy_RestoreExcInfo(r6)
|
|
dec_ref r6
|
|
L6:
|
|
if is_error(a) goto L17 else goto L9
|
|
L7:
|
|
r7 = 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:
|
|
r8 = raise UnboundLocalError('local variable "b" referenced before assignment')
|
|
if not r8 goto L14 (error at lol:9) else goto L11 :: bool
|
|
L11:
|
|
unreachable
|
|
L12:
|
|
r9 = PyNumber_Add(a, b)
|
|
xdec_ref a
|
|
xdec_ref b
|
|
if is_error(r9) goto L14 (error at lol:9) else goto L13
|
|
L13:
|
|
return r9
|
|
L14:
|
|
r10 = <error> :: object
|
|
return r10
|
|
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, v, r1, u, r2 :: str
|
|
r3, r4 :: bit
|
|
r5 :: object
|
|
r6 :: str
|
|
r7 :: object
|
|
r8 :: bool
|
|
r9 :: object
|
|
r10 :: None
|
|
L0:
|
|
r0 = <error> :: str
|
|
v = r0
|
|
r1 = 'a'
|
|
inc_ref r1
|
|
u = r1
|
|
L1:
|
|
if b goto L10 else goto L11 :: bool
|
|
L2:
|
|
r2 = 'b'
|
|
inc_ref r2
|
|
v = r2
|
|
r3 = v == u
|
|
r4 = r3 ^ 1
|
|
if r4 goto L11 else goto L1 :: bool
|
|
L3:
|
|
r5 = builtins :: module
|
|
r6 = 'print'
|
|
r7 = CPyObject_GetAttr(r5, r6)
|
|
if is_error(r7) goto L12 (error at f:7) else goto L4
|
|
L4:
|
|
if is_error(v) goto L13 else goto L7
|
|
L5:
|
|
r8 = raise UnboundLocalError('local variable "v" referenced before assignment')
|
|
if not r8 goto L9 (error at f:7) else goto L6 :: bool
|
|
L6:
|
|
unreachable
|
|
L7:
|
|
r9 = PyObject_CallFunctionObjArgs(r7, v, 0)
|
|
dec_ref r7
|
|
xdec_ref v
|
|
if is_error(r9) goto L9 (error at f:7) else goto L14
|
|
L8:
|
|
return 1
|
|
L9:
|
|
r10 = <error> :: None
|
|
return r10
|
|
L10:
|
|
xdec_ref v
|
|
goto L2
|
|
L11:
|
|
dec_ref u
|
|
goto L3
|
|
L12:
|
|
xdec_ref v
|
|
goto L9
|
|
L13:
|
|
dec_ref r7
|
|
goto L5
|
|
L14:
|
|
dec_ref r9
|
|
goto L8
|