| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713 |
- -- 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 :: i32
- 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
- [case testExceptionWithOverlappingErrorValue]
- from mypy_extensions import i64
- def f() -> i64:
- return 0
- def g() -> i64:
- return f()
- [out]
- def f():
- L0:
- return 0
- def g():
- r0 :: i64
- r1 :: bit
- r2 :: object
- r3 :: i64
- L0:
- r0 = f()
- r1 = r0 == -113
- if r1 goto L2 else goto L1 :: bool
- L1:
- return r0
- L2:
- r2 = PyErr_Occurred()
- if not is_error(r2) goto L3 (error at g:7) else goto L1
- L3:
- r3 = <error> :: i64
- return r3
- [case testExceptionWithNativeAttributeGetAndSet]
- class C:
- def __init__(self, x: int) -> None:
- self.x = x
- def foo(c: C, x: int) -> None:
- c.x = x - c.x
- [out]
- def C.__init__(self, x):
- self :: __main__.C
- x :: int
- L0:
- inc_ref x :: int
- self.x = x
- return 1
- def foo(c, x):
- c :: __main__.C
- x, r0, r1 :: int
- r2 :: bool
- L0:
- r0 = borrow c.x
- r1 = CPyTagged_Subtract(x, r0)
- c.x = r1
- return 1
- [case testExceptionWithOverlappingFloatErrorValue]
- def f() -> float:
- return 0.0
- def g() -> float:
- return f()
- [out]
- def f():
- L0:
- return 0.0
- def g():
- r0 :: float
- r1 :: bit
- r2 :: object
- r3 :: float
- L0:
- r0 = f()
- r1 = r0 == -113.0
- if r1 goto L2 else goto L1 :: bool
- L1:
- return r0
- L2:
- r2 = PyErr_Occurred()
- if not is_error(r2) goto L3 (error at g:5) else goto L1
- L3:
- r3 = <error> :: float
- return r3
- [case testExceptionWithLowLevelIntAttribute]
- from mypy_extensions import i32, i64
- class C:
- def __init__(self, x: i32, y: i64) -> None:
- self.x = x
- self.y = y
- def f(c: C) -> None:
- c.x
- c.y
- [out]
- def C.__init__(self, x, y):
- self :: __main__.C
- x :: i32
- y :: i64
- L0:
- self.x = x
- self.y = y
- return 1
- def f(c):
- c :: __main__.C
- r0 :: i32
- r1 :: i64
- L0:
- r0 = c.x
- r1 = c.y
- return 1
- [case testConditionallyUndefinedI64]
- from mypy_extensions import i64
- def f(x: i64) -> i64:
- if x:
- y: i64 = 2
- return y
- [out]
- def f(x):
- x, r0, y :: i64
- __locals_bitmap0 :: u32
- r1 :: bit
- r2, r3 :: u32
- r4 :: bit
- r5 :: bool
- r6 :: i64
- L0:
- r0 = <error> :: i64
- y = r0
- __locals_bitmap0 = 0
- r1 = x != 0
- if r1 goto L1 else goto L2 :: bool
- L1:
- y = 2
- r2 = __locals_bitmap0 | 1
- __locals_bitmap0 = r2
- L2:
- r3 = __locals_bitmap0 & 1
- r4 = r3 == 0
- if r4 goto L3 else goto L5 :: bool
- L3:
- r5 = raise UnboundLocalError('local variable "y" referenced before assignment')
- if not r5 goto L6 (error at f:-1) else goto L4 :: bool
- L4:
- unreachable
- L5:
- return y
- L6:
- r6 = <error> :: i64
- return r6
- [case testExceptionWithFloatAttribute]
- class C:
- def __init__(self, x: float, y: float) -> None:
- self.x = x
- if x:
- self.y = y
- def f(c: C) -> float:
- return c.x + c.y
- [out]
- def C.__init__(self, x, y):
- self :: __main__.C
- x, y :: float
- r0 :: bit
- L0:
- self.x = x
- r0 = x != 0.0
- if r0 goto L1 else goto L2 :: bool
- L1:
- self.y = y
- L2:
- return 1
- def f(c):
- c :: __main__.C
- r0, r1 :: float
- r2 :: bit
- r3 :: float
- r4 :: object
- r5 :: float
- L0:
- r0 = c.x
- r1 = c.y
- r2 = r1 == -113.0
- if r2 goto L2 else goto L1 :: bool
- L1:
- r3 = r0 + r1
- return r3
- L2:
- r4 = PyErr_Occurred()
- if not is_error(r4) goto L3 (error at f:8) else goto L1
- L3:
- r5 = <error> :: float
- return r5
|