| -- Test cases for reference count insertion. | |
| [case testReturnLiteral] | |
| def f() -> int: | |
| return 1 | |
| [out] | |
| def f(): | |
| L0: | |
| return 2 | |
| [case testReturnLocal] | |
| def f() -> int: | |
| x = 1 | |
| return x | |
| [out] | |
| def f(): | |
| x :: int | |
| L0: | |
| x = 2 | |
| return x | |
| [case testLocalVars] | |
| def f() -> int: | |
| x = 1 | |
| y = x | |
| x = y | |
| return x | |
| [out] | |
| def f(): | |
| x, y :: int | |
| L0: | |
| x = 2 | |
| y = x | |
| x = y | |
| return x | |
| [case testLocalVars2] | |
| def f() -> int: | |
| x = 1 | |
| y = x | |
| z = x | |
| return y + z | |
| [out] | |
| def f(): | |
| x, y, z, r0 :: int | |
| L0: | |
| x = 2 | |
| inc_ref x :: int | |
| y = x | |
| z = x | |
| r0 = CPyTagged_Add(y, z) | |
| dec_ref y :: int | |
| dec_ref z :: int | |
| return r0 | |
| [case testFreeAtReturn] | |
| def f() -> int: | |
| x = 1 | |
| y = 2 | |
| if x == 1: | |
| return x | |
| return y | |
| [out] | |
| def f(): | |
| x, y :: int | |
| r0 :: bit | |
| L0: | |
| x = 2 | |
| y = 4 | |
| r0 = int_eq x, 2 | |
| if r0 goto L3 else goto L4 :: bool | |
| L1: | |
| return x | |
| L2: | |
| return y | |
| L3: | |
| dec_ref y :: int | |
| goto L1 | |
| L4: | |
| dec_ref x :: int | |
| goto L2 | |
| [case testArgumentsInOps] | |
| def f(a: int, b: int) -> int: | |
| x = a + 1 | |
| y = x + a | |
| return y | |
| [out] | |
| def f(a, b): | |
| a, b, r0, x, r1, y :: int | |
| L0: | |
| r0 = CPyTagged_Add(a, 2) | |
| x = r0 | |
| r1 = CPyTagged_Add(x, a) | |
| dec_ref x :: int | |
| y = r1 | |
| return y | |
| [case testArgumentsInAssign] | |
| def f(a: int) -> int: | |
| x = a | |
| y = a | |
| x = 1 | |
| return x + y | |
| [out] | |
| def f(a): | |
| a, x, y, r0 :: int | |
| L0: | |
| inc_ref a :: int | |
| x = a | |
| dec_ref x :: int | |
| inc_ref a :: int | |
| y = a | |
| x = 2 | |
| r0 = CPyTagged_Add(x, y) | |
| dec_ref x :: int | |
| dec_ref y :: int | |
| return r0 | |
| [case testAssignToArgument1] | |
| def f(a: int) -> int: | |
| a = 1 | |
| y = a | |
| return y | |
| [out] | |
| def f(a): | |
| a, y :: int | |
| L0: | |
| a = 2 | |
| y = a | |
| return y | |
| [case testAssignToArgument2] | |
| def f(a: int) -> int: | |
| a = 1 | |
| a = 2 | |
| a = 3 | |
| return a | |
| [out] | |
| def f(a): | |
| a :: int | |
| L0: | |
| a = 2 | |
| dec_ref a :: int | |
| a = 4 | |
| dec_ref a :: int | |
| a = 6 | |
| return a | |
| [case testAssignToArgument3] | |
| def f(a: int) -> int: | |
| x = 1 | |
| a = x | |
| y = x | |
| return a | |
| [out] | |
| def f(a): | |
| a, x, y :: int | |
| L0: | |
| x = 2 | |
| inc_ref x :: int | |
| a = x | |
| y = x | |
| dec_ref y :: int | |
| return a | |
| [case testReturnArgument] | |
| def f(a: int) -> int: | |
| return a | |
| [out] | |
| def f(a): | |
| a :: int | |
| L0: | |
| inc_ref a :: int | |
| return a | |
| [case testConditionalAssignToArgument1] | |
| def f(a: int) -> int: | |
| if a == a: | |
| a = 1 | |
| else: | |
| x = 2 | |
| y = a + 1 | |
| return y | |
| [out] | |
| def f(a): | |
| a :: int | |
| r0 :: bit | |
| x, r1, y :: int | |
| L0: | |
| r0 = int_eq a, a | |
| if r0 goto L1 else goto L2 :: bool | |
| L1: | |
| a = 2 | |
| goto L3 | |
| L2: | |
| x = 4 | |
| dec_ref x :: int | |
| goto L4 | |
| L3: | |
| r1 = CPyTagged_Add(a, 2) | |
| dec_ref a :: int | |
| y = r1 | |
| return y | |
| L4: | |
| inc_ref a :: int | |
| goto L3 | |
| [case testConditionalAssignToArgument2] | |
| def f(a: int) -> int: | |
| if a == a: | |
| x = 2 | |
| else: | |
| a = 1 | |
| y = a + 1 | |
| return y | |
| [out] | |
| def f(a): | |
| a :: int | |
| r0 :: bit | |
| x, r1, y :: int | |
| L0: | |
| r0 = int_eq a, a | |
| if r0 goto L1 else goto L2 :: bool | |
| L1: | |
| x = 4 | |
| dec_ref x :: int | |
| goto L4 | |
| L2: | |
| a = 2 | |
| L3: | |
| r1 = CPyTagged_Add(a, 2) | |
| dec_ref a :: int | |
| y = r1 | |
| return y | |
| L4: | |
| inc_ref a :: int | |
| goto L3 | |
| [case testConditionalAssignToArgument3] | |
| def f(a: int) -> int: | |
| if a == a: | |
| a = 1 | |
| return a | |
| [out] | |
| def f(a): | |
| a :: int | |
| r0 :: bit | |
| L0: | |
| r0 = int_eq a, a | |
| if r0 goto L1 else goto L3 :: bool | |
| L1: | |
| a = 2 | |
| L2: | |
| return a | |
| L3: | |
| inc_ref a :: int | |
| goto L2 | |
| [case testAssignRegisterToItself] | |
| def f(a: int) -> int: | |
| a = a | |
| x = 1 | |
| x = x | |
| return x + a | |
| -- This is correct but bad code | |
| [out] | |
| def f(a): | |
| a, x, r0 :: int | |
| L0: | |
| inc_ref a :: int | |
| a = a | |
| x = 2 | |
| inc_ref x :: int | |
| dec_ref x :: int | |
| x = x | |
| r0 = CPyTagged_Add(x, a) | |
| dec_ref x :: int | |
| dec_ref a :: int | |
| return r0 | |
| [case testIncrement1] | |
| def f(a: int) -> int: | |
| a = a + 1 | |
| x = 1 | |
| x = x + 1 | |
| return a + x | |
| [out] | |
| def f(a): | |
| a, r0, x, r1, r2 :: int | |
| L0: | |
| r0 = CPyTagged_Add(a, 2) | |
| a = r0 | |
| x = 2 | |
| r1 = CPyTagged_Add(x, 2) | |
| dec_ref x :: int | |
| x = r1 | |
| r2 = CPyTagged_Add(a, x) | |
| dec_ref a :: int | |
| dec_ref x :: int | |
| return r2 | |
| [case testIncrement2] | |
| def f() -> None: | |
| x = 1 | |
| x = x + 1 | |
| [out] | |
| def f(): | |
| x, r0 :: int | |
| L0: | |
| x = 2 | |
| r0 = CPyTagged_Add(x, 2) | |
| dec_ref x :: int | |
| x = r0 | |
| dec_ref x :: int | |
| return 1 | |
| [case testAdd1] | |
| def f() -> None: | |
| y = 1 | |
| x = y + 1 | |
| [out] | |
| def f(): | |
| y, r0, x :: int | |
| L0: | |
| y = 2 | |
| r0 = CPyTagged_Add(y, 2) | |
| dec_ref y :: int | |
| x = r0 | |
| dec_ref x :: int | |
| return 1 | |
| [case testAdd2] | |
| def f(a: int) -> int: | |
| a = a + a | |
| x = a | |
| x = x + x | |
| return x | |
| [out] | |
| def f(a): | |
| a, r0, x, r1 :: int | |
| L0: | |
| r0 = CPyTagged_Add(a, a) | |
| a = r0 | |
| x = a | |
| r1 = CPyTagged_Add(x, x) | |
| dec_ref x :: int | |
| x = r1 | |
| return x | |
| [case testAdd3] | |
| def f(a: int) -> int: | |
| x = a + a | |
| y = x + x | |
| return y | |
| [out] | |
| def f(a): | |
| a, r0, x, r1, y :: int | |
| L0: | |
| r0 = CPyTagged_Add(a, a) | |
| x = r0 | |
| r1 = CPyTagged_Add(x, x) | |
| dec_ref x :: int | |
| y = r1 | |
| return y | |
| [case testAdd4] | |
| def f(a: int) -> None: | |
| x = a + a | |
| y = 1 | |
| z = y + y | |
| [out] | |
| def f(a): | |
| a, r0, x, y, r1, z :: int | |
| L0: | |
| r0 = CPyTagged_Add(a, a) | |
| x = r0 | |
| dec_ref x :: int | |
| y = 2 | |
| r1 = CPyTagged_Add(y, y) | |
| dec_ref y :: int | |
| z = r1 | |
| dec_ref z :: int | |
| return 1 | |
| [case testAdd5] | |
| def f(a: int) -> None: | |
| a = a + a | |
| x = 1 | |
| x = x + x | |
| [out] | |
| def f(a): | |
| a, r0, x, r1 :: int | |
| L0: | |
| r0 = CPyTagged_Add(a, a) | |
| a = r0 | |
| dec_ref a :: int | |
| x = 2 | |
| r1 = CPyTagged_Add(x, x) | |
| dec_ref x :: int | |
| x = r1 | |
| dec_ref x :: int | |
| return 1 | |
| [case testReturnInMiddleOfFunction] | |
| def f() -> int: | |
| x = 1 | |
| y = 2 | |
| z = 3 | |
| if z == z: | |
| return z | |
| a = 1 | |
| return x + y - a | |
| [out] | |
| def f(): | |
| x, y, z :: int | |
| r0 :: bit | |
| a, r1, r2 :: int | |
| L0: | |
| x = 2 | |
| y = 4 | |
| z = 6 | |
| r0 = int_eq z, z | |
| if r0 goto L3 else goto L4 :: bool | |
| L1: | |
| return z | |
| L2: | |
| a = 2 | |
| r1 = CPyTagged_Add(x, y) | |
| dec_ref x :: int | |
| dec_ref y :: int | |
| r2 = CPyTagged_Subtract(r1, a) | |
| dec_ref r1 :: int | |
| dec_ref a :: int | |
| return r2 | |
| L3: | |
| dec_ref x :: int | |
| dec_ref y :: int | |
| goto L1 | |
| L4: | |
| dec_ref z :: int | |
| goto L2 | |
| [case testLoop] | |
| def f(a: int) -> int: | |
| sum = 0 | |
| i = 0 | |
| while i <= a: | |
| sum = sum + i | |
| i = i + 1 | |
| return sum | |
| [out] | |
| def f(a): | |
| a, sum, i :: int | |
| r0 :: bit | |
| r1, r2 :: int | |
| L0: | |
| sum = 0 | |
| i = 0 | |
| L1: | |
| r0 = int_le i, a | |
| if r0 goto L2 else goto L4 :: bool | |
| L2: | |
| r1 = CPyTagged_Add(sum, i) | |
| dec_ref sum :: int | |
| sum = r1 | |
| r2 = CPyTagged_Add(i, 2) | |
| dec_ref i :: int | |
| i = r2 | |
| goto L1 | |
| L3: | |
| return sum | |
| L4: | |
| dec_ref i :: int | |
| goto L3 | |
| [case testCall] | |
| def f(a: int) -> int: | |
| return f(a + 1) | |
| [out] | |
| def f(a): | |
| a, r0, r1 :: int | |
| L0: | |
| r0 = CPyTagged_Add(a, 2) | |
| r1 = f(r0) | |
| dec_ref r0 :: int | |
| return r1 | |
| [case testError] | |
| def f(x: List[int]) -> None: pass # E: Name "List" is not defined \ | |
| # N: Did you forget to import it from "typing"? (Suggestion: "from typing import List") | |
| [case testNewList] | |
| def f() -> int: | |
| a = [0, 1] | |
| return 0 | |
| [out] | |
| def f(): | |
| r0 :: list | |
| r1, r2 :: object | |
| r3 :: ptr | |
| a :: list | |
| L0: | |
| r0 = PyList_New(2) | |
| r1 = object 0 | |
| r2 = object 1 | |
| r3 = list_items r0 | |
| inc_ref r1 | |
| buf_init_item r3, 0, r1 | |
| inc_ref r2 | |
| buf_init_item r3, 1, r2 | |
| a = r0 | |
| dec_ref a | |
| return 0 | |
| [case testListSet] | |
| from typing import List | |
| def f(a: List[int], b: List[int]) -> None: | |
| a[0] = b[0] | |
| [out] | |
| def f(a, b): | |
| a, b :: list | |
| r0 :: object | |
| r1 :: int | |
| r2 :: object | |
| r3 :: bit | |
| L0: | |
| r0 = CPyList_GetItemShort(b, 0) | |
| r1 = unbox(int, r0) | |
| dec_ref r0 | |
| r2 = box(int, r1) | |
| r3 = CPyList_SetItem(a, 0, r2) | |
| return 1 | |
| [case testTupleRefcount] | |
| from typing import Tuple | |
| def f(x: Tuple[Tuple[int, bool], bool]) -> int: | |
| return x[0][0] | |
| [out] | |
| def f(x): | |
| x :: tuple[tuple[int, bool], bool] | |
| r0 :: tuple[int, bool] | |
| r1 :: int | |
| L0: | |
| r0 = x[0] | |
| r1 = r0[0] | |
| dec_ref r0 | |
| return r1 | |
| [case testUserClassRefCount] | |
| class C: | |
| x: 'C' | |
| def f() -> None: | |
| c = C() | |
| c.x = C() | |
| [out] | |
| def f(): | |
| r0, c, r1 :: __main__.C | |
| r2 :: bool | |
| L0: | |
| r0 = C() | |
| c = r0 | |
| r1 = C() | |
| c.x = r1; r2 = is_error | |
| dec_ref c | |
| return 1 | |
| [case testCastRefCount] | |
| class C: pass | |
| def f() -> None: | |
| a = [C()] | |
| d = a[0] | |
| [out] | |
| def f(): | |
| r0 :: __main__.C | |
| r1 :: list | |
| r2 :: ptr | |
| a :: list | |
| r3 :: object | |
| r4, d :: __main__.C | |
| L0: | |
| r0 = C() | |
| r1 = PyList_New(1) | |
| r2 = list_items r1 | |
| buf_init_item r2, 0, r0 | |
| a = r1 | |
| r3 = CPyList_GetItemShort(a, 0) | |
| dec_ref a | |
| r4 = cast(__main__.C, r3) | |
| d = r4 | |
| dec_ref d | |
| return 1 | |
| [case testBorrowListObjectWithLiteralIndex_nogil] | |
| from typing import cast | |
| def f() -> str: | |
| o = cast(object, []) | |
| return cast(list[str], o)[0] | |
| [out] | |
| def f(): | |
| r0 :: list | |
| o :: object | |
| r1 :: list | |
| r2 :: object | |
| r3 :: str | |
| L0: | |
| r0 = PyList_New(0) | |
| o = r0 | |
| r1 = borrow cast(list, o) | |
| r2 = CPyList_GetItemShort(r1, 0) | |
| r3 = cast(str, r2) | |
| dec_ref o | |
| return r3 | |
| [case testUnaryBranchSpecialCase] | |
| def f(x: bool) -> int: | |
| if x: | |
| return 1 | |
| return 2 | |
| [out] | |
| def f(x): | |
| x :: bool | |
| L0: | |
| if x goto L1 else goto L2 :: bool | |
| L1: | |
| return 2 | |
| L2: | |
| return 4 | |
| [case testReturnTuple] | |
| from typing import Tuple | |
| class C: pass | |
| def f() -> Tuple[C, C]: | |
| a = C() | |
| b = C() | |
| return a, b | |
| [out] | |
| def f(): | |
| r0, a, r1, b, r2, r3 :: __main__.C | |
| r4 :: tuple[__main__.C, __main__.C] | |
| L0: | |
| r0 = C() | |
| a = r0 | |
| r1 = C() | |
| b = r1 | |
| r2 = a | |
| r3 = b | |
| r4 = (r2, r3) | |
| return r4 | |
| [case testDecomposeTuple_withgil] | |
| from typing import Tuple | |
| class C: | |
| a: int | |
| def f() -> int: | |
| x, y = g() | |
| return x.a + y.a | |
| def g() -> Tuple[C, C]: | |
| return C(), C() | |
| [out] | |
| def f(): | |
| r0 :: tuple[__main__.C, __main__.C] | |
| r1, r2, r3, x, r4, y :: __main__.C | |
| r5, r6, r7 :: int | |
| L0: | |
| r0 = g() | |
| r1 = borrow r0[0] | |
| r2 = borrow r0[1] | |
| r3 = unborrow r1 | |
| x = r3 | |
| r4 = unborrow r2 | |
| y = r4 | |
| r5 = borrow x.a | |
| r6 = borrow y.a | |
| r7 = CPyTagged_Add(r5, r6) | |
| dec_ref x | |
| dec_ref y | |
| return r7 | |
| def g(): | |
| r0, r1 :: __main__.C | |
| r2 :: tuple[__main__.C, __main__.C] | |
| L0: | |
| r0 = C() | |
| r1 = C() | |
| r2 = (r0, r1) | |
| return r2 | |
| [case testUnicodeLiteral] | |
| def f() -> str: | |
| return "some string" | |
| [out] | |
| def f(): | |
| r0 :: str | |
| L0: | |
| r0 = 'some string' | |
| inc_ref r0 | |
| return r0 | |
| [case testPyMethodCall] | |
| def g(x: str) -> int: | |
| return int(x, base=2) | |
| [out] | |
| def g(x): | |
| x :: str | |
| r0, r1 :: object | |
| r2 :: object[2] | |
| r3 :: object_ptr | |
| r4, r5 :: object | |
| r6 :: int | |
| L0: | |
| r0 = load_address PyLong_Type | |
| r1 = object 2 | |
| r2 = [x, r1] | |
| r3 = load_address r2 | |
| r4 = ('base',) | |
| r5 = PyObject_Vectorcall(r0, r3, 1, r4) | |
| r6 = unbox(int, r5) | |
| dec_ref r5 | |
| return r6 | |
| [case testListAppend] | |
| from typing import List | |
| def f(a: List[int], x: int) -> None: | |
| a.append(x) | |
| [out] | |
| def f(a, x): | |
| a :: list | |
| x :: int | |
| r0 :: object | |
| r1 :: i32 | |
| r2 :: bit | |
| L0: | |
| inc_ref x :: int | |
| r0 = box(int, x) | |
| r1 = PyList_Append(a, r0) | |
| dec_ref r0 | |
| r2 = r1 >= 0 :: signed | |
| return 1 | |
| [case testForDict] | |
| from typing import Dict | |
| def f(d: Dict[int, int]) -> None: | |
| for key in d: | |
| d[key] | |
| [out] | |
| def f(d): | |
| d :: dict | |
| r0 :: short_int | |
| r1 :: native_int | |
| r2 :: object | |
| r3 :: tuple[bool, short_int, object] | |
| r4 :: short_int | |
| r5 :: bool | |
| r6 :: object | |
| r7, key :: int | |
| r8, r9 :: object | |
| r10 :: int | |
| r11, r12 :: bit | |
| L0: | |
| r0 = 0 | |
| r1 = PyDict_Size(d) | |
| r2 = CPyDict_GetKeysIter(d) | |
| L1: | |
| r3 = CPyDict_NextKey(r2, r0) | |
| r4 = r3[1] | |
| r0 = r4 | |
| r5 = r3[0] | |
| if r5 goto L2 else goto L6 :: bool | |
| L2: | |
| r6 = r3[2] | |
| dec_ref r3 | |
| r7 = unbox(int, r6) | |
| dec_ref r6 | |
| key = r7 | |
| r8 = box(int, key) | |
| r9 = CPyDict_GetItem(d, r8) | |
| dec_ref r8 | |
| r10 = unbox(int, r9) | |
| dec_ref r9 | |
| dec_ref r10 :: int | |
| L3: | |
| r11 = CPyDict_CheckSize(d, r1) | |
| goto L1 | |
| L4: | |
| r12 = CPy_NoErrOccurred() | |
| L5: | |
| return 1 | |
| L6: | |
| dec_ref r2 | |
| dec_ref r3 | |
| goto L4 | |
| [case testBorrowRefs] | |
| def make_garbage(arg: object) -> None: | |
| b = True | |
| while b: | |
| arg = None | |
| b = False | |
| [out] | |
| def make_garbage(arg): | |
| arg :: object | |
| b :: bool | |
| r0 :: object | |
| L0: | |
| b = 1 | |
| L1: | |
| if b goto L2 else goto L3 :: bool | |
| L2: | |
| r0 = box(None, 1) | |
| inc_ref r0 | |
| arg = r0 | |
| dec_ref arg | |
| b = 0 | |
| goto L1 | |
| L3: | |
| return 1 | |
| [case testTupleUnpackUnused] | |
| from typing import Tuple | |
| def f(x: Tuple[str, int]) -> int: | |
| a, xi = x | |
| return 0 | |
| [out] | |
| def f(x): | |
| x :: tuple[str, int] | |
| r0 :: str | |
| r1 :: int | |
| r2, a :: str | |
| r3, xi :: int | |
| L0: | |
| r0 = borrow x[0] | |
| r1 = borrow x[1] | |
| inc_ref x | |
| r2 = unborrow r0 | |
| a = r2 | |
| dec_ref a | |
| r3 = unborrow r1 | |
| xi = r3 | |
| dec_ref xi :: int | |
| return 0 | |
| [case testGetElementPtrLifeTime] | |
| from typing import List | |
| def f() -> int: | |
| x: List[str] = [] | |
| return len(x) | |
| [out] | |
| def f(): | |
| r0, x :: list | |
| r1 :: native_int | |
| r2 :: short_int | |
| L0: | |
| r0 = PyList_New(0) | |
| x = r0 | |
| r1 = var_object_size x | |
| dec_ref x | |
| r2 = r1 << 1 | |
| return r2 | |
| [case testSometimesUninitializedVariable] | |
| def f(x: bool) -> int: | |
| if x: | |
| y = 1 | |
| else: | |
| z = 2 | |
| return y + z | |
| [out] | |
| def f(x): | |
| x :: bool | |
| r0, y, r1, z :: int | |
| r2, r3 :: bool | |
| r4 :: int | |
| L0: | |
| r0 = <error> :: int | |
| y = r0 | |
| r1 = <error> :: int | |
| z = r1 | |
| if x goto L8 else goto L9 :: bool | |
| L1: | |
| y = 2 | |
| goto L3 | |
| L2: | |
| z = 4 | |
| L3: | |
| if is_error(y) goto L10 else goto L5 | |
| L4: | |
| r2 = raise UnboundLocalError('local variable "y" referenced before assignment') | |
| unreachable | |
| L5: | |
| if is_error(z) goto L11 else goto L7 | |
| L6: | |
| r3 = raise UnboundLocalError('local variable "z" referenced before assignment') | |
| unreachable | |
| L7: | |
| r4 = CPyTagged_Add(y, z) | |
| xdec_ref y :: int | |
| xdec_ref z :: int | |
| return r4 | |
| L8: | |
| xdec_ref y :: int | |
| goto L1 | |
| L9: | |
| xdec_ref z :: int | |
| goto L2 | |
| L10: | |
| xdec_ref z :: int | |
| goto L4 | |
| L11: | |
| xdec_ref y :: int | |
| goto L6 | |
| [case testVectorcall] | |
| from typing import Any | |
| def call(f: Any, x: int) -> int: | |
| return f(x) | |
| [out] | |
| def call(f, x): | |
| f :: object | |
| x :: int | |
| r0 :: object | |
| r1 :: object[1] | |
| r2 :: object_ptr | |
| r3 :: object | |
| r4 :: int | |
| L0: | |
| inc_ref x :: int | |
| r0 = box(int, x) | |
| r1 = [r0] | |
| r2 = load_address r1 | |
| r3 = PyObject_Vectorcall(f, r2, 1, 0) | |
| dec_ref r0 | |
| r4 = unbox(int, r3) | |
| dec_ref r3 | |
| return r4 | |
| [case testVectorcallMethod_64bit] | |
| from typing import Any | |
| def call(o: Any, x: int) -> int: | |
| return o.m(x) | |
| [out] | |
| def call(o, x): | |
| o :: object | |
| x :: int | |
| r0 :: str | |
| r1 :: object | |
| r2 :: object[2] | |
| r3 :: object_ptr | |
| r4 :: object | |
| r5 :: int | |
| L0: | |
| r0 = 'm' | |
| inc_ref x :: int | |
| r1 = box(int, x) | |
| r2 = [o, r1] | |
| r3 = load_address r2 | |
| r4 = PyObject_VectorcallMethod(r0, r3, 9223372036854775810, 0) | |
| dec_ref r1 | |
| r5 = unbox(int, r4) | |
| dec_ref r4 | |
| return r5 | |
| [case testBorrowAttribute_withgil] | |
| def g() -> int: | |
| d = D() | |
| return d.c.x | |
| def f(d: D) -> int: | |
| return d.c.x | |
| class C: | |
| x: int | |
| class D: | |
| c: C | |
| [out] | |
| def g(): | |
| r0, d :: __main__.D | |
| r1 :: __main__.C | |
| r2 :: int | |
| L0: | |
| r0 = D() | |
| d = r0 | |
| r1 = borrow d.c | |
| r2 = r1.x | |
| dec_ref d | |
| return r2 | |
| def f(d): | |
| d :: __main__.D | |
| r0 :: __main__.C | |
| r1 :: int | |
| L0: | |
| r0 = borrow d.c | |
| r1 = r0.x | |
| return r1 | |
| [case testBorrowAttribute_nogil] | |
| from typing import Final | |
| def g() -> int: | |
| d = D(C(1)) | |
| return d.c.x | |
| def f(d: D) -> int: | |
| return d.c.x | |
| class C: | |
| def __init__(self, x: int) -> None: | |
| self.x: Final = x | |
| class D: | |
| def __init__(self, c: C) -> None: | |
| self.c: Final = c | |
| [out] | |
| def g(): | |
| r0 :: __main__.C | |
| r1, d :: __main__.D | |
| r2 :: __main__.C | |
| r3 :: int | |
| L0: | |
| r0 = C(2) | |
| r1 = D(r0) | |
| dec_ref r0 | |
| d = r1 | |
| r2 = borrow d.c | |
| r3 = r2.x | |
| dec_ref d | |
| return r3 | |
| def f(d): | |
| d :: __main__.D | |
| r0 :: __main__.C | |
| r1 :: int | |
| L0: | |
| r0 = borrow d.c | |
| r1 = r0.x | |
| return r1 | |
| def C.__init__(self, x): | |
| self :: __main__.C | |
| x :: int | |
| L0: | |
| inc_ref x :: int | |
| self.x = x | |
| return 1 | |
| def D.__init__(self, c): | |
| self :: __main__.D | |
| c :: __main__.C | |
| L0: | |
| inc_ref c | |
| self.c = c | |
| return 1 | |
| [case testBorrowInheritedFinalAttribute_nogil] | |
| from typing import Final | |
| def f(d: D) -> int: | |
| return d.c.x | |
| class B: | |
| def __init__(self, x: int) -> None: | |
| self.x: Final = x | |
| class C(B): | |
| pass | |
| class D: | |
| def __init__(self, c: C) -> None: | |
| self.c: Final = c | |
| [out] | |
| def f(d): | |
| d :: __main__.D | |
| r0 :: __main__.C | |
| r1 :: int | |
| L0: | |
| r0 = borrow d.c | |
| r1 = r0.x | |
| return r1 | |
| def B.__init__(self, x): | |
| self :: __main__.B | |
| x :: int | |
| L0: | |
| inc_ref x :: int | |
| self.x = x | |
| return 1 | |
| def D.__init__(self, c): | |
| self :: __main__.D | |
| c :: __main__.C | |
| L0: | |
| inc_ref c | |
| self.c = c | |
| return 1 | |
| [case testBorrowAttributeTwice_withgil] | |
| def f(e: E) -> int: | |
| return e.d.c.x | |
| class C: | |
| x: int | |
| class D: | |
| c: C | |
| class E: | |
| d: D | |
| [out] | |
| def f(e): | |
| e :: __main__.E | |
| r0 :: __main__.D | |
| r1 :: __main__.C | |
| r2 :: int | |
| L0: | |
| r0 = borrow e.d | |
| r1 = borrow r0.c | |
| r2 = r1.x | |
| return r2 | |
| [case testBorrowAttributeIsNone_withgil] | |
| from typing import Optional | |
| def f(c: C) -> bool: | |
| return c.x is not None | |
| def g(c: C) -> bool: | |
| return c.x is None | |
| class C: | |
| x: Optional[str] | |
| [out] | |
| def f(c): | |
| c :: __main__.C | |
| r0 :: union[str, None] | |
| r1 :: object | |
| r2 :: bit | |
| L0: | |
| r0 = borrow c.x | |
| r1 = load_address _Py_NoneStruct | |
| r2 = r0 != r1 | |
| return r2 | |
| def g(c): | |
| c :: __main__.C | |
| r0 :: union[str, None] | |
| r1 :: object | |
| r2 :: bit | |
| L0: | |
| r0 = borrow c.x | |
| r1 = load_address _Py_NoneStruct | |
| r2 = r0 == r1 | |
| return r2 | |
| [case testBorrowAttributeNarrowOptional_withgil] | |
| from typing import Optional | |
| def f(c: C) -> bool: | |
| if c.x is not None: | |
| return c.x.b | |
| return False | |
| class C: | |
| x: Optional[D] | |
| class D: | |
| b: bool | |
| [out] | |
| def f(c): | |
| c :: __main__.C | |
| r0 :: union[__main__.D, None] | |
| r1 :: object | |
| r2 :: bit | |
| r3 :: union[__main__.D, None] | |
| r4 :: __main__.D | |
| r5 :: bool | |
| L0: | |
| r0 = borrow c.x | |
| r1 = load_address _Py_NoneStruct | |
| r2 = r0 != r1 | |
| if r2 goto L1 else goto L2 :: bool | |
| L1: | |
| r3 = borrow c.x | |
| r4 = borrow cast(__main__.D, r3) | |
| r5 = r4.b | |
| return r5 | |
| L2: | |
| return 0 | |
| [case testBorrowLenArgument_withgil] | |
| from typing import List | |
| def f(x: C) -> int: | |
| return len(x.a) | |
| class C: | |
| a: List[str] | |
| [out] | |
| def f(x): | |
| x :: __main__.C | |
| r0 :: list | |
| r1 :: native_int | |
| r2 :: short_int | |
| L0: | |
| r0 = borrow x.a | |
| r1 = var_object_size r0 | |
| r2 = r1 << 1 | |
| return r2 | |
| [case testBorrowIsinstanceArgument_withgil] | |
| from typing import List | |
| def f(x: C) -> bool: | |
| if isinstance(x.a, D): | |
| return x.a.b | |
| else: | |
| return True | |
| class C: | |
| a: object | |
| class D: | |
| b: bool | |
| [out] | |
| def f(x): | |
| x :: __main__.C | |
| r0, r1 :: object | |
| r2 :: ptr | |
| r3 :: object | |
| r4 :: bit | |
| r5 :: object | |
| r6 :: __main__.D | |
| r7 :: bool | |
| L0: | |
| r0 = borrow x.a | |
| r1 = __main__.D :: type | |
| r2 = get_element_ptr r0 ob_type :: PyObject | |
| r3 = borrow load_mem r2 :: builtins.object* | |
| r4 = r3 == r1 | |
| if r4 goto L1 else goto L2 :: bool | |
| L1: | |
| r5 = borrow x.a | |
| r6 = borrow cast(__main__.D, r5) | |
| r7 = r6.b | |
| return r7 | |
| L2: | |
| return 1 | |
| [case testBorrowListGetItem1_withgil] | |
| from typing import List | |
| def literal_index(x: C) -> str: | |
| return x.a[0] | |
| def negative_index(x: C) -> str: | |
| return x.a[-1] | |
| def lvar_index(x: C, n: int) -> str: | |
| return x.a[n] | |
| class C: | |
| a: List[str] | |
| [out] | |
| def literal_index(x): | |
| x :: __main__.C | |
| r0 :: list | |
| r1 :: object | |
| r2 :: str | |
| L0: | |
| r0 = borrow x.a | |
| r1 = CPyList_GetItemShort(r0, 0) | |
| r2 = cast(str, r1) | |
| return r2 | |
| def negative_index(x): | |
| x :: __main__.C | |
| r0 :: list | |
| r1 :: object | |
| r2 :: str | |
| L0: | |
| r0 = borrow x.a | |
| r1 = CPyList_GetItemShort(r0, -2) | |
| r2 = cast(str, r1) | |
| return r2 | |
| def lvar_index(x, n): | |
| x :: __main__.C | |
| n :: int | |
| r0 :: list | |
| r1 :: object | |
| r2 :: str | |
| L0: | |
| r0 = borrow x.a | |
| r1 = CPyList_GetItem(r0, n) | |
| r2 = cast(str, r1) | |
| return r2 | |
| [case testBorrowListGetItem1_nogil] | |
| from typing import List | |
| def literal_index(x: C) -> str: | |
| return x.a[0] | |
| def negative_index(x: C) -> str: | |
| return x.a[-1] | |
| def lvar_index(x: C, n: int) -> str: | |
| return x.a[n] | |
| class C: | |
| a: List[str] | |
| [out] | |
| def literal_index(x): | |
| x :: __main__.C | |
| r0 :: list | |
| r1 :: object | |
| r2 :: str | |
| L0: | |
| r0 = x.a | |
| r1 = CPyList_GetItemShort(r0, 0) | |
| dec_ref r0 | |
| r2 = cast(str, r1) | |
| return r2 | |
| def negative_index(x): | |
| x :: __main__.C | |
| r0 :: list | |
| r1 :: object | |
| r2 :: str | |
| L0: | |
| r0 = x.a | |
| r1 = CPyList_GetItemShort(r0, -2) | |
| dec_ref r0 | |
| r2 = cast(str, r1) | |
| return r2 | |
| def lvar_index(x, n): | |
| x :: __main__.C | |
| n :: int | |
| r0 :: list | |
| r1 :: object | |
| r2 :: str | |
| L0: | |
| r0 = x.a | |
| r1 = CPyList_GetItem(r0, n) | |
| dec_ref r0 | |
| r2 = cast(str, r1) | |
| return r2 | |
| [case testBorrowListGetItem2_withgil] | |
| from typing import List | |
| def attr_before_index(x: C) -> str: | |
| return x.a[x.n] | |
| def attr_after_index(a: List[C], i: int) -> int: | |
| return a[i].n | |
| def attr_after_index_literal(a: List[C]) -> int: | |
| return a[0].n | |
| class C: | |
| a: List[str] | |
| n: int | |
| [out] | |
| def attr_before_index(x): | |
| x :: __main__.C | |
| r0 :: list | |
| r1 :: int | |
| r2 :: object | |
| r3 :: str | |
| L0: | |
| r0 = borrow x.a | |
| r1 = borrow x.n | |
| r2 = CPyList_GetItem(r0, r1) | |
| r3 = cast(str, r2) | |
| return r3 | |
| def attr_after_index(a, i): | |
| a :: list | |
| i :: int | |
| r0 :: object | |
| r1 :: __main__.C | |
| r2 :: int | |
| L0: | |
| r0 = CPyList_GetItemBorrow(a, i) | |
| r1 = borrow cast(__main__.C, r0) | |
| r2 = r1.n | |
| return r2 | |
| def attr_after_index_literal(a): | |
| a :: list | |
| r0 :: object | |
| r1 :: __main__.C | |
| r2 :: int | |
| L0: | |
| r0 = CPyList_GetItemShortBorrow(a, 0) | |
| r1 = borrow cast(__main__.C, r0) | |
| r2 = r1.n | |
| return r2 | |
| [case testBorrowListGetItem2_nogil] | |
| from typing import List | |
| def attr_before_index(x: C) -> str: | |
| return x.a[x.n] | |
| def attr_after_index(a: List[C], i: int) -> int: | |
| return a[i].n | |
| def attr_after_index_literal(a: List[C]) -> int: | |
| return a[0].n | |
| class C: | |
| a: List[str] | |
| n: int | |
| [out] | |
| def attr_before_index(x): | |
| x :: __main__.C | |
| r0 :: list | |
| r1 :: int | |
| r2 :: object | |
| r3 :: str | |
| L0: | |
| r0 = x.a | |
| r1 = x.n | |
| r2 = CPyList_GetItem(r0, r1) | |
| dec_ref r0 | |
| dec_ref r1 :: int | |
| r3 = cast(str, r2) | |
| return r3 | |
| def attr_after_index(a, i): | |
| a :: list | |
| i :: int | |
| r0 :: object | |
| r1 :: __main__.C | |
| r2 :: int | |
| L0: | |
| r0 = CPyList_GetItem(a, i) | |
| r1 = cast(__main__.C, r0) | |
| r2 = r1.n | |
| dec_ref r1 | |
| return r2 | |
| def attr_after_index_literal(a): | |
| a :: list | |
| r0 :: object | |
| r1 :: __main__.C | |
| r2 :: int | |
| L0: | |
| r0 = CPyList_GetItemShort(a, 0) | |
| r1 = cast(__main__.C, r0) | |
| r2 = r1.n | |
| dec_ref r1 | |
| return r2 | |
| [case testCannotBorrowListGetItem] | |
| from typing import List | |
| def func_index(x: C) -> str: | |
| return x.a[f()] | |
| def f() -> int: return 0 | |
| class C: | |
| a: List[str] | |
| [out] | |
| def func_index(x): | |
| x :: __main__.C | |
| r0 :: list | |
| r1 :: int | |
| r2 :: object | |
| r3 :: str | |
| L0: | |
| r0 = x.a | |
| r1 = f() | |
| r2 = CPyList_GetItem(r0, r1) | |
| dec_ref r0 | |
| dec_ref r1 :: int | |
| r3 = cast(str, r2) | |
| return r3 | |
| def f(): | |
| L0: | |
| return 0 | |
| [case testBorrowListGetItemKeepAlive_withgil] | |
| from typing import List | |
| def f() -> str: | |
| a = [C()] | |
| return a[0].s | |
| class C: | |
| s: str | |
| [out] | |
| def f(): | |
| r0 :: __main__.C | |
| r1 :: list | |
| r2 :: ptr | |
| a :: list | |
| r3 :: object | |
| r4 :: __main__.C | |
| r5 :: str | |
| L0: | |
| r0 = C() | |
| r1 = PyList_New(1) | |
| r2 = list_items r1 | |
| buf_init_item r2, 0, r0 | |
| a = r1 | |
| r3 = CPyList_GetItemShortBorrow(a, 0) | |
| r4 = borrow cast(__main__.C, r3) | |
| r5 = r4.s | |
| dec_ref a | |
| return r5 | |
| [case testBorrowSetAttrObject_withgil] | |
| from typing import Optional | |
| def f(x: Optional[C]) -> None: | |
| if x is not None: | |
| x.b = True | |
| def g(x: D) -> None: | |
| x.c.b = False | |
| class C: | |
| b: bool | |
| class D: | |
| c: C | |
| [out] | |
| def f(x): | |
| x :: union[__main__.C, None] | |
| r0 :: object | |
| r1 :: bit | |
| r2 :: __main__.C | |
| r3 :: bool | |
| L0: | |
| r0 = load_address _Py_NoneStruct | |
| r1 = x != r0 | |
| if r1 goto L1 else goto L2 :: bool | |
| L1: | |
| r2 = borrow cast(__main__.C, x) | |
| r2.b = 1; r3 = is_error | |
| L2: | |
| return 1 | |
| def g(x): | |
| x :: __main__.D | |
| r0 :: __main__.C | |
| r1 :: bool | |
| L0: | |
| r0 = borrow x.c | |
| r0.b = 0; r1 = is_error | |
| return 1 | |
| [case testBorrowIntEquality_withgil] | |
| def add(c: C) -> bool: | |
| return c.x == c.y | |
| class C: | |
| x: int | |
| y: int | |
| [out] | |
| def add(c): | |
| c :: __main__.C | |
| r0, r1 :: int | |
| r2 :: bit | |
| L0: | |
| r0 = borrow c.x | |
| r1 = borrow c.y | |
| r2 = int_eq r0, r1 | |
| return r2 | |
| [case testBorrowIntLessThan_withgil] | |
| def add(c: C) -> bool: | |
| return c.x < c.y | |
| class C: | |
| x: int | |
| y: int | |
| [out] | |
| def add(c): | |
| c :: __main__.C | |
| r0, r1 :: int | |
| r2 :: bit | |
| L0: | |
| r0 = borrow c.x | |
| r1 = borrow c.y | |
| r2 = int_lt r0, r1 | |
| return r2 | |
| [case testBorrowIntCompareFinal_withgil] | |
| from typing import Final | |
| X: Final = 10 | |
| def add(c: C) -> bool: | |
| return c.x == X | |
| class C: | |
| x: int | |
| [out] | |
| def add(c): | |
| c :: __main__.C | |
| r0 :: int | |
| r1 :: bit | |
| L0: | |
| r0 = borrow c.x | |
| r1 = int_eq r0, 20 | |
| return r1 | |
| [case testBorrowIntArithmetic_withgil] | |
| def add(c: C) -> int: | |
| return c.x + c.y | |
| def sub(c: C) -> int: | |
| return c.x - c.y | |
| class C: | |
| x: int | |
| y: int | |
| [out] | |
| def add(c): | |
| c :: __main__.C | |
| r0, r1, r2 :: int | |
| L0: | |
| r0 = borrow c.x | |
| r1 = borrow c.y | |
| r2 = CPyTagged_Add(r0, r1) | |
| return r2 | |
| def sub(c): | |
| c :: __main__.C | |
| r0, r1, r2 :: int | |
| L0: | |
| r0 = borrow c.x | |
| r1 = borrow c.y | |
| r2 = CPyTagged_Subtract(r0, r1) | |
| return r2 | |
| [case testBorrowIntArithmetic_nogil] | |
| def add(c: C) -> int: | |
| return c.x + c.y | |
| def sub(c: C) -> int: | |
| return c.x - c.y | |
| class C: | |
| x: int | |
| y: int | |
| [out] | |
| def add(c): | |
| c :: __main__.C | |
| r0, r1, r2 :: int | |
| L0: | |
| r0 = c.x | |
| r1 = c.y | |
| r2 = CPyTagged_Add(r0, r1) | |
| dec_ref r0 :: int | |
| dec_ref r1 :: int | |
| return r2 | |
| def sub(c): | |
| c :: __main__.C | |
| r0, r1, r2 :: int | |
| L0: | |
| r0 = c.x | |
| r1 = c.y | |
| r2 = CPyTagged_Subtract(r0, r1) | |
| dec_ref r0 :: int | |
| dec_ref r1 :: int | |
| return r2 | |
| [case testBorrowIntComparisonInIf_withgil] | |
| def add(c: C, n: int) -> bool: | |
| if c.x == c.y: | |
| return True | |
| return False | |
| class C: | |
| x: int | |
| y: int | |
| [out] | |
| def add(c, n): | |
| c :: __main__.C | |
| n, r0, r1 :: int | |
| r2 :: bit | |
| L0: | |
| r0 = borrow c.x | |
| r1 = borrow c.y | |
| r2 = int_eq r0, r1 | |
| if r2 goto L1 else goto L2 :: bool | |
| L1: | |
| return 1 | |
| L2: | |
| return 0 | |
| [case testBorrowIntInPlaceOp_withgil] | |
| def add(c: C, n: int) -> None: | |
| c.x += n | |
| def sub(c: C, n: int) -> None: | |
| c.x -= c.y | |
| class C: | |
| x: int | |
| y: int | |
| [out] | |
| def add(c, n): | |
| c :: __main__.C | |
| n, r0, r1 :: int | |
| r2 :: bool | |
| L0: | |
| r0 = borrow c.x | |
| r1 = CPyTagged_Add(r0, n) | |
| c.x = r1; r2 = is_error | |
| return 1 | |
| def sub(c, n): | |
| c :: __main__.C | |
| n, r0, r1, r2 :: int | |
| r3 :: bool | |
| L0: | |
| r0 = borrow c.x | |
| r1 = borrow c.y | |
| r2 = CPyTagged_Subtract(r0, r1) | |
| c.x = r2; r3 = is_error | |
| return 1 | |
| [case testCoerceIntToI64_64bit] | |
| from mypy_extensions import i64 | |
| def f(x: int) -> i64: | |
| # TODO: On the fast path we shouldn't have a decref. Once we have high-level IR, | |
| # coercion from int to i64 can be a single op, which makes it easier to | |
| # generate optimal refcount handling for this case. | |
| return x + 1 | |
| [out] | |
| def f(x): | |
| x, r0 :: int | |
| r1 :: native_int | |
| r2 :: bit | |
| r3, r4 :: i64 | |
| r5 :: ptr | |
| r6 :: c_ptr | |
| r7 :: i64 | |
| L0: | |
| r0 = CPyTagged_Add(x, 2) | |
| r1 = r0 & 1 | |
| r2 = r1 == 0 | |
| if r2 goto L1 else goto L2 :: bool | |
| L1: | |
| r3 = r0 >> 1 | |
| dec_ref r0 :: int | |
| r4 = r3 | |
| goto L3 | |
| L2: | |
| r5 = r0 ^ 1 | |
| r6 = r5 | |
| r7 = CPyLong_AsInt64(r6) | |
| r4 = r7 | |
| dec_ref r0 :: int | |
| L3: | |
| return r4 | |
| [case testVecTSetItem_64bit] | |
| from librt.vecs import vec | |
| from mypy_extensions import i64 | |
| def f(v: vec[str], i: i64, x: str) -> None: | |
| v[i] = x | |
| [out] | |
| def f(v, i, x): | |
| v :: vec[str] | |
| i :: i64 | |
| x :: str | |
| r0 :: native_int | |
| r1 :: bit | |
| r2 :: i64 | |
| r3 :: bit | |
| r4 :: bool | |
| r5 :: i64 | |
| r6 :: ptr | |
| r7 :: i64 | |
| r8 :: ptr | |
| r9 :: str | |
| L0: | |
| r0 = v.len | |
| r1 = i < r0 :: unsigned | |
| if r1 goto L4 else goto L1 :: bool | |
| L1: | |
| r2 = i + r0 | |
| r3 = r2 < r0 :: unsigned | |
| if r3 goto L3 else goto L2 :: bool | |
| L2: | |
| r4 = raise IndexError | |
| unreachable | |
| L3: | |
| r5 = r2 | |
| goto L5 | |
| L4: | |
| r5 = i | |
| L5: | |
| r6 = v.items | |
| r7 = r5 * 8 | |
| r8 = r6 + r7 | |
| r9 = borrow load_mem r8 :: builtins.str* | |
| dec_ref r9 | |
| inc_ref x | |
| set_mem r8, x :: builtins.str* | |
| return 1 | |
| [case testVecTConstructFromListMultiply_64bit] | |
| from typing import Optional | |
| from librt.vecs import vec | |
| from mypy_extensions import i64 | |
| def f(n: i64) -> vec[Optional[str]]: | |
| return vec[Optional[str]]([None] * n) | |
| [out] | |
| def f(n): | |
| n :: i64 | |
| r0, r1 :: object | |
| r2, r3 :: ptr | |
| r4 :: vec[str | None] | |
| r5 :: ptr | |
| r6 :: i64 | |
| r7, r8 :: ptr | |
| r9 :: bit | |
| r10 :: ptr | |
| L0: | |
| r0 = box(None, 1) | |
| r1 = load_address PyUnicode_Type | |
| r2 = r1 | |
| r3 = r2 | 1 | |
| r4 = VecTApi.alloc(n, n, r3) | |
| r5 = r4.items | |
| r6 = n * 8 | |
| r7 = r5 + r6 | |
| r8 = r5 | |
| L1: | |
| r9 = r8 < r7 :: unsigned | |
| if r9 goto L2 else goto L3 :: bool | |
| L2: | |
| inc_ref r0 | |
| set_mem r8, r0 :: union* | |
| r10 = r8 + 8 | |
| r8 = r10 | |
| goto L1 | |
| L3: | |
| return r4 | |
| [case testVecTForLoop_64bit] | |
| from librt.vecs import vec | |
| from mypy_extensions import i64 | |
| def f(v: vec[str]) -> i64: | |
| t: i64 = 0 | |
| for s in v: | |
| g(s) | |
| return t | |
| def g(s: str) -> None: pass | |
| [out] | |
| def f(v): | |
| v :: vec[str] | |
| t :: i64 | |
| r0, r1 :: native_int | |
| r2 :: bit | |
| r3, s :: str | |
| r4 :: None | |
| r5 :: native_int | |
| L0: | |
| t = 0 | |
| r0 = 0 | |
| L1: | |
| r1 = v.len | |
| r2 = r0 < r1 :: signed | |
| if r2 goto L2 else goto L4 :: bool | |
| L2: | |
| r3 = vec_get_item_unsafe[str] v, r0 | |
| s = r3 | |
| r4 = g(s) | |
| dec_ref s | |
| L3: | |
| r5 = r0 + 1 | |
| r0 = r5 | |
| goto L1 | |
| L4: | |
| return t | |
| def g(s): | |
| s :: str | |
| L0: | |
| return 1 | |
| [case testVecTConstructFromListExpr_64bit] | |
| from librt.vecs import vec | |
| def f() -> vec[str]: | |
| return vec[str](['x', 'y']) | |
| [out] | |
| def f(): | |
| r0, r1 :: str | |
| r2 :: object | |
| r3 :: ptr | |
| r4 :: vec[str] | |
| r5, r6, r7 :: ptr | |
| L0: | |
| r0 = 'x' | |
| r1 = 'y' | |
| r2 = load_address PyUnicode_Type | |
| r3 = r2 | |
| r4 = VecTApi.alloc(2, 2, r3) | |
| r5 = r4.items | |
| inc_ref r0 | |
| set_mem r5, r0 :: builtins.str* | |
| r6 = r5 + 8 | |
| inc_ref r1 | |
| set_mem r6, r1 :: builtins.str* | |
| r7 = r6 + 8 | |
| return r4 | |
| [case testVecI64GetItemBorrowVec_64bit] | |
| from librt.vecs import vec | |
| from mypy_extensions import i64 | |
| class C: | |
| v: vec[i64] | |
| def f(self, x: i64) -> i64: | |
| return self.v[x] | |
| [out] | |
| def C.f(self, x): | |
| self :: __main__.C | |
| x :: i64 | |
| r0 :: vec[i64] | |
| r1 :: native_int | |
| r2 :: bit | |
| r3 :: i64 | |
| r4 :: bit | |
| r5 :: bool | |
| r6, r7 :: i64 | |
| L0: | |
| r0 = borrow self.v | |
| r1 = r0.len | |
| r2 = x < r1 :: unsigned | |
| if r2 goto L4 else goto L1 :: bool | |
| L1: | |
| r3 = x + r1 | |
| r4 = r3 < r1 :: unsigned | |
| if r4 goto L3 else goto L2 :: bool | |
| L2: | |
| r5 = raise IndexError | |
| unreachable | |
| L3: | |
| r6 = r3 | |
| goto L5 | |
| L4: | |
| r6 = x | |
| L5: | |
| r7 = vec_get_item_unsafe[i64] r0, r6 | |
| return r7 | |
| [case testVecI64LenBorrowVec_64bit] | |
| from librt.vecs import vec | |
| from mypy_extensions import i64 | |
| class C: | |
| v: vec[i64] | |
| def f(self, x: i64) -> i64: | |
| return len(self.v) | |
| [out] | |
| def C.f(self, x): | |
| self :: __main__.C | |
| x :: i64 | |
| r0 :: vec[i64] | |
| r1 :: native_int | |
| L0: | |
| r0 = borrow self.v | |
| r1 = r0.len | |
| return r1 | |
| [case testVecNestedAppend] | |
| from librt.vecs import vec, append | |
| def f(vv: vec[vec[str]], v: vec[str]) -> vec[vec[str]]: | |
| return append(vv, v) | |
| [out] | |
| def f(vv, v): | |
| vv :: vec[vec[str]] | |
| v :: vec[str] | |
| r0 :: native_int | |
| r1 :: ptr | |
| r2, r3 :: VecNestedBufItem{len:native_int, items:ptr} | |
| r4 :: vec[vec[str]] | |
| L0: | |
| r0 = v.len | |
| r1 = v.items | |
| r2 = set_element undef VecNestedBufItem, len, r0 | |
| r3 = set_element r2, items, r1 | |
| inc_ref vv | |
| r4 = VecNestedApi.append(vv, r3) | |
| return r4 | |
| [case testVecTGetItem_64bit] | |
| from librt.vecs import vec | |
| from mypy_extensions import i64 | |
| def f(v: vec[str], n: i64) -> str: | |
| return v[n] | |
| [out] | |
| def f(v, n): | |
| v :: vec[str] | |
| n :: i64 | |
| r0 :: native_int | |
| r1 :: bit | |
| r2 :: i64 | |
| r3 :: bit | |
| r4 :: bool | |
| r5 :: i64 | |
| r6 :: str | |
| L0: | |
| r0 = v.len | |
| r1 = n < r0 :: unsigned | |
| if r1 goto L4 else goto L1 :: bool | |
| L1: | |
| r2 = n + r0 | |
| r3 = r2 < r0 :: unsigned | |
| if r3 goto L3 else goto L2 :: bool | |
| L2: | |
| r4 = raise IndexError | |
| unreachable | |
| L3: | |
| r5 = r2 | |
| goto L5 | |
| L4: | |
| r5 = n | |
| L5: | |
| r6 = vec_get_item_unsafe[str] v, r5 | |
| return r6 | |
| [case testVecNestedGetItem_64bit] | |
| from librt.vecs import vec | |
| from mypy_extensions import i64 | |
| def f(v: vec[vec[str]], n: i64) -> None: | |
| vv = vec[vec[str]]()[n] | |
| [out] | |
| def f(v, n): | |
| v :: vec[vec[str]] | |
| n :: i64 | |
| r0 :: object | |
| r1 :: ptr | |
| r2 :: vec[vec[str]] | |
| r3 :: native_int | |
| r4 :: bit | |
| r5 :: i64 | |
| r6 :: bit | |
| r7 :: bool | |
| r8 :: i64 | |
| r9, vv :: vec[str] | |
| L0: | |
| r0 = load_address PyUnicode_Type | |
| r1 = r0 | |
| r2 = VecNestedApi.alloc(0, 0, r1, 1) | |
| r3 = r2.len | |
| r4 = n < r3 :: unsigned | |
| if r4 goto L4 else goto L1 :: bool | |
| L1: | |
| r5 = n + r3 | |
| r6 = r5 < r3 :: unsigned | |
| if r6 goto L3 else goto L6 :: bool | |
| L2: | |
| r7 = raise IndexError | |
| unreachable | |
| L3: | |
| r8 = r5 | |
| goto L5 | |
| L4: | |
| r8 = n | |
| L5: | |
| r9 = vec_get_item_unsafe[vec[str]] r2, r8 | |
| dec_ref r2 | |
| vv = r9 | |
| dec_ref vv | |
| return 1 | |
| L6: | |
| dec_ref r2 | |
| goto L2 | |
| [case testVecNestedGetItemBorrow_64bit] | |
| from librt.vecs import vec | |
| from mypy_extensions import i64 | |
| def f(v: vec[vec[i64]], n: i64, m: i64) -> i64: | |
| return v[n][m] | |
| [out] | |
| def f(v, n, m): | |
| v :: vec[vec[i64]] | |
| n, m :: i64 | |
| r0 :: native_int | |
| r1 :: bit | |
| r2 :: i64 | |
| r3 :: bit | |
| r4 :: bool | |
| r5 :: i64 | |
| r6 :: vec[i64] | |
| r7 :: native_int | |
| r8 :: bit | |
| r9 :: i64 | |
| r10 :: bit | |
| r11 :: bool | |
| r12, r13 :: i64 | |
| L0: | |
| r0 = v.len | |
| r1 = n < r0 :: unsigned | |
| if r1 goto L4 else goto L1 :: bool | |
| L1: | |
| r2 = n + r0 | |
| r3 = r2 < r0 :: unsigned | |
| if r3 goto L3 else goto L2 :: bool | |
| L2: | |
| r4 = raise IndexError | |
| unreachable | |
| L3: | |
| r5 = r2 | |
| goto L5 | |
| L4: | |
| r5 = n | |
| L5: | |
| r6 = vec_get_item_unsafe_borrow[vec[i64]] v, r5 | |
| r7 = r6.len | |
| r8 = m < r7 :: unsigned | |
| if r8 goto L9 else goto L6 :: bool | |
| L6: | |
| r9 = m + r7 | |
| r10 = r9 < r7 :: unsigned | |
| if r10 goto L8 else goto L7 :: bool | |
| L7: | |
| r11 = raise IndexError | |
| unreachable | |
| L8: | |
| r12 = r9 | |
| goto L10 | |
| L9: | |
| r12 = m | |
| L10: | |
| r13 = vec_get_item_unsafe[i64] r6, r12 | |
| return r13 | |
| [case testVecPop] | |
| from librt.vecs import vec, pop, append | |
| from mypy_extensions import i64 | |
| def f() -> vec[i64]: | |
| v = vec[i64]() | |
| v = append(v, 7) | |
| v, x = pop(v) | |
| return v | |
| [out] | |
| def f(): | |
| r0, v, r1 :: vec[i64] | |
| r2 :: tuple[vec[i64], i64] | |
| r3 :: vec[i64] | |
| r4 :: i64 | |
| r5 :: vec[i64] | |
| r6, x :: i64 | |
| L0: | |
| r0 = VecI64Api.alloc(0, 0) | |
| v = r0 | |
| r1 = VecI64Api.append(v, 7) | |
| v = r1 | |
| r2 = VecI64Api.pop(v, -1) | |
| r3 = borrow r2[0] | |
| r4 = borrow r2[1] | |
| r5 = unborrow r3 | |
| v = r5 | |
| r6 = unborrow r4 | |
| x = r6 | |
| return v | |
| [case testVecNestedPop] | |
| from librt.vecs import vec, pop | |
| def f(v: vec[vec[str]]) -> vec[str]: | |
| vv, x = pop(v) | |
| return x | |
| [out] | |
| def f(v): | |
| v :: vec[vec[str]] | |
| r0 :: tuple[vec[vec[str]], VecNestedBufItem{len:native_int, items:ptr}] | |
| r1, r2 :: vec[vec[str]] | |
| r3, r4 :: VecNestedBufItem{len:native_int, items:ptr} | |
| r5 :: native_int | |
| r6 :: ptr | |
| r7, r8 :: vec[str] | |
| r9 :: tuple[vec[vec[str]], vec[str]] | |
| r10 :: vec[vec[str]] | |
| r11 :: vec[str] | |
| r12, vv :: vec[vec[str]] | |
| r13, x :: vec[str] | |
| L0: | |
| inc_ref v | |
| r0 = VecNestedApi.pop(v, -1) | |
| r1 = borrow r0[0] | |
| r2 = unborrow r1 | |
| r3 = borrow r0[1] | |
| r4 = unborrow r3 | |
| r5 = r4.len | |
| r6 = r4.items | |
| r7 = set_element undef vec[str], len, r5 | |
| r8 = set_element r7, items, r6 | |
| r9 = (r2, r8) | |
| r10 = borrow r9[0] | |
| r11 = borrow r9[1] | |
| r12 = unborrow r10 | |
| vv = r12 | |
| dec_ref vv | |
| r13 = unborrow r11 | |
| x = r13 | |
| return x | |
| [case testPropertySetterCallWithRefcountedObject] | |
| class Foo: | |
| def __init__(self) -> None: | |
| self.attr = "unmodified" | |
| class A: | |
| def __init__(self) -> None: | |
| self._foo = Foo() | |
| @property | |
| def foo(self) -> Foo: | |
| return self._foo | |
| @foo.setter | |
| def foo(self, val : Foo) -> None: | |
| self._foo = val | |
| def f(a: A): | |
| a.foo = Foo() | |
| [out] | |
| def Foo.__init__(self): | |
| self :: __main__.Foo | |
| r0 :: str | |
| L0: | |
| r0 = 'unmodified' | |
| inc_ref r0 | |
| self.attr = r0 | |
| return 1 | |
| def A.__init__(self): | |
| self :: __main__.A | |
| r0 :: __main__.Foo | |
| L0: | |
| r0 = Foo() | |
| self._foo = r0 | |
| return 1 | |
| def A.foo(self): | |
| self :: __main__.A | |
| r0 :: __main__.Foo | |
| L0: | |
| r0 = self._foo | |
| return r0 | |
| def A.__mypyc_setter__foo(self, val): | |
| self :: __main__.A | |
| val :: __main__.Foo | |
| r0 :: bool | |
| L0: | |
| inc_ref val | |
| self._foo = val; r0 = is_error | |
| return 1 | |
| def f(a): | |
| a :: __main__.A | |
| r0 :: __main__.Foo | |
| r1 :: bool | |
| r2 :: object | |
| L0: | |
| r0 = Foo() | |
| a.foo = r0; r1 = is_error | |
| dec_ref r0 | |
| r2 = box(None, 1) | |
| inc_ref r2 | |
| return r2 | |
| [case testPropertySetterCallWithNonRefcountedObject_64bit] | |
| from mypy_extensions import i64 | |
| class A: | |
| def __init__(self) -> None: | |
| self._foo = i64(0) | |
| @property | |
| def foo(self) -> i64: | |
| return self._foo | |
| @foo.setter | |
| def foo(self, val : i64) -> None: | |
| self._foo = val | |
| def f(a: A, i: int): | |
| a.foo = i64(i) | |
| [out] | |
| def A.__init__(self): | |
| self :: __main__.A | |
| L0: | |
| self._foo = 0 | |
| return 1 | |
| def A.foo(self): | |
| self :: __main__.A | |
| r0 :: i64 | |
| L0: | |
| r0 = self._foo | |
| return r0 | |
| def A.__mypyc_setter__foo(self, val): | |
| self :: __main__.A | |
| val :: i64 | |
| r0 :: bool | |
| L0: | |
| self._foo = val; r0 = is_error | |
| return 1 | |
| def f(a, i): | |
| a :: __main__.A | |
| i :: int | |
| r0 :: native_int | |
| r1 :: bit | |
| r2, r3 :: i64 | |
| r4 :: ptr | |
| r5 :: c_ptr | |
| r6 :: i64 | |
| r7 :: bool | |
| r8 :: object | |
| L0: | |
| r0 = i & 1 | |
| r1 = r0 == 0 | |
| if r1 goto L1 else goto L2 :: bool | |
| L1: | |
| r2 = i >> 1 | |
| r3 = r2 | |
| goto L3 | |
| L2: | |
| r4 = i ^ 1 | |
| r5 = r4 | |
| r6 = CPyLong_AsInt64(r5) | |
| r3 = r6 | |
| L3: | |
| a.foo = r3; r7 = is_error | |
| r8 = box(None, 1) | |
| inc_ref r8 | |
| return r8 | |
| [case testBytesConcatRefcount] | |
| def f(a: bytes, b: bytes) -> bytes: | |
| return b"1" + a + b | |
| [out] | |
| def f(a, b): | |
| a, b, r0, r1, r2 :: bytes | |
| L0: | |
| r0 = b'1' | |
| r1 = CPyBytes_Concat(r0, a) | |
| r2 = CPyBytes_Concat(r1, b) | |
| dec_ref r1 | |
| return r2 | |
| [case testChainedBytesConcatRefcount] | |
| def f(a: bytes, b: bytes, c: bytes) -> bytes: | |
| return b"1" + a + b + c | |
| [out] | |
| def f(a, b, c): | |
| a, b, c, r0, r1, r2, r3 :: bytes | |
| L0: | |
| r0 = b'1' | |
| r1 = CPyBytes_Concat(r0, a) | |
| r2 = CPyBytes_Concat(r1, b) | |
| dec_ref r1 | |
| r3 = CPyBytes_Concat(r2, c) | |
| dec_ref r2 | |
| return r3 | |
| [case testBorrowedFinalAttribute] | |
| from typing import Final | |
| class C: | |
| def __init__(self, s: str) -> None: | |
| self.s: Final = s | |
| def f(c: C, b: bool) -> str: | |
| a = c.s if b else "x" | |
| return a | |
| def g(c: C) -> C: | |
| return C(c.s) | |
| [out] | |
| def C.__init__(self, s): | |
| self :: __main__.C | |
| s :: str | |
| L0: | |
| inc_ref s | |
| self.s = s | |
| return 1 | |
| def f(c, b): | |
| c :: __main__.C | |
| b :: bool | |
| r0, r1, r2, a :: str | |
| L0: | |
| if b goto L1 else goto L2 :: bool | |
| L1: | |
| r0 = borrow c.s | |
| inc_ref r0 | |
| r1 = r0 | |
| goto L3 | |
| L2: | |
| r2 = 'x' | |
| inc_ref r2 | |
| r1 = r2 | |
| L3: | |
| a = r1 | |
| return a | |
| def g(c): | |
| c :: __main__.C | |
| r0 :: str | |
| r1 :: __main__.C | |
| L0: | |
| r0 = borrow c.s | |
| r1 = C(r0) | |
| return r1 | |
| [case testBorrowedFinalAttribute2_withgil] | |
| from typing import Final | |
| class C: | |
| def __init__(self, s: str) -> None: | |
| self.s: Final = s | |
| def g(c: C, n: int) -> str: | |
| a = [c] | |
| return a[n].s + "a" | |
| [out] | |
| def C.__init__(self, s): | |
| self :: __main__.C | |
| s :: str | |
| L0: | |
| inc_ref s | |
| self.s = s | |
| return 1 | |
| def g(c, n): | |
| c :: __main__.C | |
| n :: int | |
| r0 :: list | |
| r1 :: ptr | |
| a :: list | |
| r2 :: object | |
| r3 :: __main__.C | |
| r4, r5, r6 :: str | |
| L0: | |
| r0 = PyList_New(1) | |
| r1 = list_items r0 | |
| inc_ref c | |
| buf_init_item r1, 0, c | |
| a = r0 | |
| r2 = CPyList_GetItemBorrow(a, n) | |
| r3 = borrow cast(__main__.C, r2) | |
| r4 = r3.s | |
| dec_ref a | |
| r5 = 'a' | |
| r6 = PyUnicode_Concat(r4, r5) | |
| dec_ref r4 | |
| return r6 | |
| [case testBorrowedFinalAttribute3_withgil] | |
| from typing import Final | |
| class C: | |
| def __init__(self, d: D) -> None: | |
| self.d = d | |
| class CC: | |
| def __init__(self, d: D) -> None: | |
| self.d: Final = d | |
| class D: | |
| def __init__(self, s: str) -> None: | |
| self.f: Final = s | |
| def f() -> str: | |
| c = C(D("x")) | |
| return c.d.f + "a" | |
| def g(d: D) -> str: | |
| c = CC(d) | |
| return c.d.f + "a" | |
| [out] | |
| def C.__init__(self, d): | |
| self :: __main__.C | |
| d :: __main__.D | |
| L0: | |
| inc_ref d | |
| self.d = d | |
| return 1 | |
| def CC.__init__(self, d): | |
| self :: __main__.CC | |
| d :: __main__.D | |
| L0: | |
| inc_ref d | |
| self.d = d | |
| return 1 | |
| def D.__init__(self, s): | |
| self :: __main__.D | |
| s :: str | |
| L0: | |
| inc_ref s | |
| self.f = s | |
| return 1 | |
| def f(): | |
| r0 :: str | |
| r1 :: __main__.D | |
| r2, c :: __main__.C | |
| r3 :: __main__.D | |
| r4, r5, r6 :: str | |
| L0: | |
| r0 = 'x' | |
| r1 = D(r0) | |
| r2 = C(r1) | |
| dec_ref r1 | |
| c = r2 | |
| r3 = borrow c.d | |
| r4 = r3.f | |
| dec_ref c | |
| r5 = 'a' | |
| r6 = PyUnicode_Concat(r4, r5) | |
| dec_ref r4 | |
| return r6 | |
| def g(d): | |
| d :: __main__.D | |
| r0, c :: __main__.CC | |
| r1 :: __main__.D | |
| r2, r3, r4 :: str | |
| L0: | |
| r0 = CC(d) | |
| c = r0 | |
| r1 = borrow c.d | |
| r2 = borrow r1.f | |
| r3 = 'a' | |
| r4 = PyUnicode_Concat(r2, r3) | |
| dec_ref c | |
| return r4 | |
| [case testBorrowedFinalAttribute4] | |
| from typing import Final | |
| class C: | |
| def __init__(self, d: D) -> None: | |
| self.d: Final = d | |
| def method(self) -> int: | |
| return self.d.foo() | |
| class D: | |
| def foo(self) -> int: | |
| return 1 | |
| [out] | |
| def C.__init__(self, d): | |
| self :: __main__.C | |
| d :: __main__.D | |
| L0: | |
| inc_ref d | |
| self.d = d | |
| return 1 | |
| def C.method(self): | |
| self :: __main__.C | |
| r0 :: __main__.D | |
| r1 :: int | |
| L0: | |
| r0 = borrow self.d | |
| r1 = r0.foo() | |
| return r1 | |
| def D.foo(self): | |
| self :: __main__.D | |
| L0: | |
| return 2 | |
| [case testBorrowedFinalAttribute5_64bit] | |
| from typing import Final | |
| from librt.vecs import vec | |
| from mypy_extensions import i64 | |
| class C: | |
| def __init__(self, s: str) -> None: | |
| self.s: Final = s | |
| def g(c: C, n: i64) -> str: | |
| a = vec[C]([c]) | |
| return a[n].s + "a" | |
| [out] | |
| def C.__init__(self, s): | |
| self :: __main__.C | |
| s :: str | |
| L0: | |
| inc_ref s | |
| self.s = s | |
| return 1 | |
| def g(c, n): | |
| c :: __main__.C | |
| n :: i64 | |
| r0 :: object | |
| r1 :: ptr | |
| r2 :: vec[__main__.C] | |
| r3, r4 :: ptr | |
| a :: vec[__main__.C] | |
| r5 :: native_int | |
| r6 :: bit | |
| r7 :: i64 | |
| r8 :: bit | |
| r9 :: bool | |
| r10 :: i64 | |
| r11 :: __main__.C | |
| r12, r13, r14 :: str | |
| L0: | |
| r0 = __main__.C :: type | |
| r1 = r0 | |
| r2 = VecTApi.alloc(1, 1, r1) | |
| r3 = r2.items | |
| inc_ref c | |
| set_mem r3, c :: __main__.C* | |
| r4 = r3 + 8 | |
| a = r2 | |
| r5 = a.len | |
| r6 = n < r5 :: unsigned | |
| if r6 goto L4 else goto L1 :: bool | |
| L1: | |
| r7 = n + r5 | |
| r8 = r7 < r5 :: unsigned | |
| if r8 goto L3 else goto L6 :: bool | |
| L2: | |
| r9 = raise IndexError | |
| unreachable | |
| L3: | |
| r10 = r7 | |
| goto L5 | |
| L4: | |
| r10 = n | |
| L5: | |
| r11 = vec_get_item_unsafe_borrow[__main__.C] a, r10 | |
| r12 = r11.s | |
| dec_ref a | |
| r13 = 'a' | |
| r14 = PyUnicode_Concat(r12, r13) | |
| dec_ref r12 | |
| return r14 | |
| L6: | |
| dec_ref a | |
| goto L2 | |
| [case testBorrowedFinalAttributeReassignViaWalrus] | |
| from typing import Final | |
| class C: | |
| def __init__(self, s: str) -> None: | |
| self.s: Final = s | |
| def f(c: C, d: C) -> str: | |
| return c.s + (c := d).s | |
| [out] | |
| def C.__init__(self, s): | |
| self :: __main__.C | |
| s :: str | |
| L0: | |
| inc_ref s | |
| self.s = s | |
| return 1 | |
| def f(c, d): | |
| c, d :: __main__.C | |
| r0, r1, r2 :: str | |
| L0: | |
| r0 = c.s | |
| inc_ref d | |
| c = d | |
| dec_ref c | |
| r1 = borrow d.s | |
| r2 = PyUnicode_Concat(r0, r1) | |
| dec_ref r0 | |
| return r2 | |
| [case testBorrowedFinalAttributeConditionalMerge] | |
| from typing import Final | |
| class C: | |
| def __init__(self, s: str) -> None: | |
| self.s: Final = s | |
| def f(b: bool) -> str: | |
| return (C("x").s if b else "y") + "z" | |
| [out] | |
| def C.__init__(self, s): | |
| self :: __main__.C | |
| s :: str | |
| L0: | |
| inc_ref s | |
| self.s = s | |
| return 1 | |
| def f(b): | |
| b :: bool | |
| r0 :: str | |
| r1 :: __main__.C | |
| r2, r3, r4, r5, r6 :: str | |
| L0: | |
| if b goto L1 else goto L2 :: bool | |
| L1: | |
| r0 = 'x' | |
| r1 = C(r0) | |
| r2 = borrow r1.s | |
| inc_ref r2 | |
| r3 = r2 | |
| dec_ref r1 | |
| goto L3 | |
| L2: | |
| r4 = 'y' | |
| inc_ref r4 | |
| r3 = r4 | |
| L3: | |
| r5 = 'z' | |
| r6 = PyUnicode_Concat(r3, r5) | |
| dec_ref r3 | |
| return r6 | |
| [case testBorrowedFinalAttributeAndMerge] | |
| from typing import Final | |
| class C: | |
| def __init__(self, s: str) -> None: | |
| self.s: Final = s | |
| def f(s: str) -> str: | |
| return (s and C("x").s) + "z" | |
| [out] | |
| def C.__init__(self, s): | |
| self :: __main__.C | |
| s :: str | |
| L0: | |
| inc_ref s | |
| self.s = s | |
| return 1 | |
| def f(s): | |
| s :: str | |
| r0 :: bit | |
| r1, r2 :: str | |
| r3 :: __main__.C | |
| r4, r5, r6 :: str | |
| L0: | |
| r0 = CPyStr_IsTrue(s) | |
| if r0 goto L2 else goto L1 :: bool | |
| L1: | |
| inc_ref s | |
| r1 = s | |
| goto L3 | |
| L2: | |
| r2 = 'x' | |
| r3 = C(r2) | |
| r4 = borrow r3.s | |
| inc_ref r4 | |
| r1 = r4 | |
| dec_ref r3 | |
| L3: | |
| r5 = 'z' | |
| r6 = PyUnicode_Concat(r1, r5) | |
| dec_ref r1 | |
| return r6 | |
| [case testBorrowedFinalAttributeOrMerge] | |
| from typing import Final | |
| class C: | |
| def __init__(self, s: str) -> None: | |
| self.s: Final = s | |
| def f(s: str) -> str: | |
| return (s or C("x").s) + "z" | |
| [out] | |
| def C.__init__(self, s): | |
| self :: __main__.C | |
| s :: str | |
| L0: | |
| inc_ref s | |
| self.s = s | |
| return 1 | |
| def f(s): | |
| s :: str | |
| r0 :: bit | |
| r1, r2 :: str | |
| r3 :: __main__.C | |
| r4, r5, r6 :: str | |
| L0: | |
| r0 = CPyStr_IsTrue(s) | |
| if r0 goto L1 else goto L2 :: bool | |
| L1: | |
| inc_ref s | |
| r1 = s | |
| goto L3 | |
| L2: | |
| r2 = 'x' | |
| r3 = C(r2) | |
| r4 = borrow r3.s | |
| inc_ref r4 | |
| r1 = r4 | |
| dec_ref r3 | |
| L3: | |
| r5 = 'z' | |
| r6 = PyUnicode_Concat(r1, r5) | |
| dec_ref r1 | |
| return r6 | |
| [case testBorrowedFinalAttributeChainedComparisonMerge] | |
| from typing import Final | |
| class C: | |
| def __init__(self, s: str) -> None: | |
| self.s: Final = s | |
| def f(s: str) -> bool: | |
| return s == "x" == C("x").s | |
| [out] | |
| def C.__init__(self, s): | |
| self :: __main__.C | |
| s :: str | |
| L0: | |
| inc_ref s | |
| self.s = s | |
| return 1 | |
| def f(s): | |
| s, r0 :: str | |
| r1, r2 :: bool | |
| r3 :: str | |
| r4 :: __main__.C | |
| r5 :: str | |
| r6 :: bool | |
| L0: | |
| r0 = 'x' | |
| r1 = CPyStr_EqualLiteral(s, r0, 1) | |
| if r1 goto L2 else goto L1 :: bool | |
| L1: | |
| r2 = r1 | |
| goto L3 | |
| L2: | |
| r3 = 'x' | |
| r4 = C(r3) | |
| r5 = borrow r4.s | |
| r6 = CPyStr_EqualLiteral(r5, r0, 1) | |
| r2 = r6 | |
| dec_ref r4 | |
| L3: | |
| return r2 | |
| [case testBorrowedFinalInListComprehension_withgil] | |
| from typing import Final | |
| class C: | |
| def __init__(self, s: str) -> None: | |
| self.s: Final = s | |
| def f(a: list[C]) -> list[str]: | |
| return [x.s for x in a] | |
| [out] | |
| def C.__init__(self, s): | |
| self :: __main__.C | |
| s :: str | |
| L0: | |
| inc_ref s | |
| self.s = s | |
| return 1 | |
| def f(a): | |
| a :: list | |
| r0 :: native_int | |
| r1 :: list | |
| r2, r3 :: native_int | |
| r4 :: bit | |
| r5 :: object | |
| r6, x :: __main__.C | |
| r7 :: str | |
| r8 :: native_int | |
| L0: | |
| r0 = var_object_size a | |
| r1 = PyList_New(r0) | |
| r2 = 0 | |
| L1: | |
| r3 = var_object_size a | |
| r4 = r2 < r3 :: signed | |
| if r4 goto L2 else goto L4 :: bool | |
| L2: | |
| r5 = list_get_item_unsafe a, r2 | |
| r6 = cast(__main__.C, r5) | |
| x = r6 | |
| r7 = x.s | |
| dec_ref x | |
| CPyList_SetItemUnsafe(r1, r2, r7) | |
| L3: | |
| r8 = r2 + 1 | |
| r2 = r8 | |
| goto L1 | |
| L4: | |
| return r1 | |
| [case testBorrowedFinalInSetComprehension_withgil] | |
| from typing import Final | |
| class C: | |
| def __init__(self, d: D) -> None: | |
| self.d: Final = d | |
| class D: | |
| def __init__(self, s: str) -> None: | |
| self.s: Final = s | |
| def use(s: str) -> bool: | |
| return True | |
| def f(a: list[C]) -> set[C]: | |
| return {x for x in a if use(x.d.s)} | |
| [out] | |
| def C.__init__(self, d): | |
| self :: __main__.C | |
| d :: __main__.D | |
| L0: | |
| inc_ref d | |
| self.d = d | |
| return 1 | |
| def D.__init__(self, s): | |
| self :: __main__.D | |
| s :: str | |
| L0: | |
| inc_ref s | |
| self.s = s | |
| return 1 | |
| def use(s): | |
| s :: str | |
| L0: | |
| return 1 | |
| def f(a): | |
| a :: list | |
| r0 :: set | |
| r1, r2 :: native_int | |
| r3 :: bit | |
| r4 :: object | |
| r5, x :: __main__.C | |
| r6 :: __main__.D | |
| r7 :: str | |
| r8 :: bool | |
| r9 :: i32 | |
| r10 :: bit | |
| r11 :: native_int | |
| L0: | |
| r0 = PySet_New(0) | |
| r1 = 0 | |
| L1: | |
| r2 = var_object_size a | |
| r3 = r1 < r2 :: signed | |
| if r3 goto L2 else goto L5 :: bool | |
| L2: | |
| r4 = list_get_item_unsafe a, r1 | |
| r5 = cast(__main__.C, r4) | |
| x = r5 | |
| r6 = borrow x.d | |
| r7 = borrow r6.s | |
| r8 = use(r7) | |
| if r8 goto L3 else goto L6 :: bool | |
| L3: | |
| r9 = PySet_Add(r0, x) | |
| dec_ref x | |
| r10 = r9 >= 0 :: signed | |
| L4: | |
| r11 = r1 + 1 | |
| r1 = r11 | |
| goto L1 | |
| L5: | |
| return r0 | |
| L6: | |
| dec_ref x | |
| goto L4 | |
| [case testBorrowedFinalAttributeThroughCast] | |
| from typing import Final, cast | |
| class C: | |
| def __init__(self, x: object) -> None: | |
| self.x: Final = x | |
| def make() -> object: | |
| return C(1) | |
| def g(a: object) -> object: | |
| return a | |
| def h() -> object: | |
| return g(cast(C, make()).x) | |
| [out] | |
| def C.__init__(self, x): | |
| self :: __main__.C | |
| x :: object | |
| L0: | |
| inc_ref x | |
| self.x = x | |
| return 1 | |
| def make(): | |
| r0 :: object | |
| r1 :: __main__.C | |
| L0: | |
| r0 = object 1 | |
| r1 = C(r0) | |
| return r1 | |
| def g(a): | |
| a :: object | |
| L0: | |
| inc_ref a | |
| return a | |
| def h(): | |
| r0 :: object | |
| r1 :: __main__.C | |
| r2, r3 :: object | |
| L0: | |
| r0 = make() | |
| r1 = borrow cast(__main__.C, r0) | |
| r2 = borrow r1.x | |
| r3 = g(r2) | |
| dec_ref r0 | |
| return r3 | |
| [case testBorrowedFinalAttributeCastChain] | |
| from typing import Final, cast | |
| class Inner: | |
| def __init__(self, x: object) -> None: | |
| self.x: Final = x | |
| class Outer: | |
| def __init__(self, inner: object) -> None: | |
| self.inner: Final = inner | |
| def g(a: object) -> object: | |
| return a | |
| def make() -> object: | |
| return Outer(Inner(1)) | |
| def h() -> object: | |
| # cast( Inner, <cast(Outer, make()).inner> ).x | |
| o = cast(Outer, make()) | |
| return g(cast(Inner, o.inner).x) | |
| [out] | |
| def Inner.__init__(self, x): | |
| self :: __main__.Inner | |
| x :: object | |
| L0: | |
| inc_ref x | |
| self.x = x | |
| return 1 | |
| def Outer.__init__(self, inner): | |
| self :: __main__.Outer | |
| inner :: object | |
| L0: | |
| inc_ref inner | |
| self.inner = inner | |
| return 1 | |
| def g(a): | |
| a :: object | |
| L0: | |
| inc_ref a | |
| return a | |
| def make(): | |
| r0 :: object | |
| r1 :: __main__.Inner | |
| r2 :: __main__.Outer | |
| L0: | |
| r0 = object 1 | |
| r1 = Inner(r0) | |
| r2 = Outer(r1) | |
| dec_ref r1 | |
| return r2 | |
| def h(): | |
| r0 :: object | |
| r1, o :: __main__.Outer | |
| r2 :: object | |
| r3 :: __main__.Inner | |
| r4, r5 :: object | |
| L0: | |
| r0 = make() | |
| r1 = cast(__main__.Outer, r0) | |
| o = r1 | |
| r2 = borrow o.inner | |
| r3 = borrow cast(__main__.Inner, r2) | |
| r4 = borrow r3.x | |
| r5 = g(r4) | |
| dec_ref o | |
| return r5 |