[case testGetAttribute] class A: x: int def f(a: A) -> int: return a.x [out] def f(a): a :: __main__.A r0 :: int L0: r0 = a.x return r0 [case testSetAttribute] class A: x: int def f(a: A) -> None: a.x = 1 [out] def f(a): a :: __main__.A r0 :: bool L0: a.x = 2; r0 = is_error return 1 [case testUserClassInList] class C: x: int def f() -> int: c = C() c.x = 5 a = [c] d = a[0] return d.x + 1 [out] def f(): r0, c :: __main__.C r1 :: bool r2 :: list r3, r4 :: ptr a :: list r5 :: object r6, d :: __main__.C r7, r8 :: int L0: r0 = C() c = r0 c.x = 10; r1 = is_error r2 = PyList_New(1) r3 = get_element_ptr r2 ob_item :: PyListObject r4 = load_mem r3 :: ptr* set_mem r4, c :: builtins.object* keep_alive r2 a = r2 r5 = CPyList_GetItemShort(a, 0) r6 = cast(__main__.C, r5) d = r6 r7 = borrow d.x r8 = CPyTagged_Add(r7, 2) keep_alive d return r8 [case testMethodCall] class A: def f(self, x: int, y: str) -> int: return x + 10 def g(a: A) -> None: a.f(1, 'hi') [out] def A.f(self, x, y): self :: __main__.A x :: int y :: str r0 :: int L0: r0 = CPyTagged_Add(x, 20) return r0 def g(a): a :: __main__.A r0 :: str r1 :: int L0: r0 = 'hi' r1 = a.f(2, r0) return 1 [case testForwardUse] def g(a: A) -> int: return a.n class A: n : int [out] def g(a): a :: __main__.A r0 :: int L0: r0 = a.n return r0 [case testOptionalMember] from typing import Optional class Node: next: Optional[Node] def length(self) -> int: if self.next is not None: return 1 + self.next.length() return 1 [out] def Node.length(self): self :: __main__.Node r0 :: union[__main__.Node, None] r1 :: object r2 :: bit r3 :: union[__main__.Node, None] r4 :: __main__.Node r5, r6 :: int L0: r0 = borrow self.next r1 = load_address _Py_NoneStruct r2 = r0 != r1 keep_alive self if r2 goto L1 else goto L2 :: bool L1: r3 = self.next r4 = cast(__main__.Node, r3) r5 = r4.length() r6 = CPyTagged_Add(2, r5) return r6 L2: return 2 [case testSubclass] class A: def __init__(self) -> None: self.x = 10 class B(A): def __init__(self) -> None: self.x = 20 self.y = 30 [out] def A.__init__(self): self :: __main__.A L0: self.x = 20 return 1 def B.__init__(self): self :: __main__.B L0: self.x = 40 self.y = 60 return 1 [case testAttrLvalue] class O(object): def __init__(self) -> None: self.x = 1 def increment(o: O) -> O: o.x += 1 return o [out] def O.__init__(self): self :: __main__.O L0: self.x = 2 return 1 def increment(o): o :: __main__.O r0, r1 :: int r2 :: bool L0: r0 = borrow o.x r1 = CPyTagged_Add(r0, 2) o.x = r1; r2 = is_error return o [case testSubclassSpecialize2] class A: def foo(self, x: int) -> object: return str(x) class B(A): def foo(self, x: object) -> object: return x class C(B): def foo(self, x: object) -> int: return id(x) def use_a(x: A, y: int) -> object: return x.foo(y) def use_b(x: B, y: object) -> object: return x.foo(y) def use_c(x: C, y: object) -> int: return x.foo(y) [out] def A.foo(self, x): self :: __main__.A x :: int r0 :: str L0: r0 = CPyTagged_Str(x) return r0 def B.foo(self, x): self :: __main__.B x :: object L0: return x def B.foo__A_glue(self, x): self :: __main__.B x :: int r0, r1 :: object L0: r0 = box(int, x) r1 = B.foo(self, r0) return r1 def C.foo(self, x): self :: __main__.C x :: object r0 :: int L0: r0 = CPyTagged_Id(x) return r0 def C.foo__B_glue(self, x): self :: __main__.C x :: object r0 :: int r1 :: object L0: r0 = C.foo(self, x) r1 = box(int, r0) return r1 def C.foo__A_glue(self, x): self :: __main__.C x :: int r0 :: object r1 :: int r2 :: object L0: r0 = box(int, x) r1 = C.foo(self, r0) r2 = box(int, r1) return r2 def use_a(x, y): x :: __main__.A y :: int r0 :: object L0: r0 = x.foo(y) return r0 def use_b(x, y): x :: __main__.B y, r0 :: object L0: r0 = x.foo(y) return r0 def use_c(x, y): x :: __main__.C y :: object r0 :: int L0: r0 = x.foo(y) return r0 [case testSubclass_toplevel] from typing import TypeVar, Generic from mypy_extensions import trait T = TypeVar('T') class C: pass @trait class S: pass class D(C, S, Generic[T]): pass [out] def __top_level__(): r0, r1 :: object r2 :: bit r3 :: str r4 :: object r5 :: dict r6, r7 :: str r8 :: list r9, r10, r11 :: ptr r12 :: str r13 :: object r14, r15, r16 :: str r17 :: object r18 :: str r19 :: int32 r20 :: bit r21, r22, r23 :: str r24 :: object r25 :: str r26 :: int32 r27 :: bit r28 :: dict r29 :: str r30 :: list r31, r32 :: ptr r33 :: str r34 :: object r35, r36, r37 :: str r38 :: object r39 :: str r40 :: int32 r41 :: bit r42 :: str r43 :: dict r44 :: str r45, r46 :: object r47 :: dict r48 :: str r49 :: int32 r50 :: bit r51 :: object r52 :: str r53, r54 :: object r55 :: bool r56 :: str r57 :: tuple r58 :: int32 r59 :: bit r60 :: dict r61 :: str r62 :: int32 r63 :: bit r64 :: object r65 :: str r66, r67 :: object r68 :: str r69 :: tuple r70 :: int32 r71 :: bit r72 :: dict r73 :: str r74 :: int32 r75 :: bit r76, r77 :: object r78 :: dict r79 :: str r80 :: object r81 :: dict r82 :: str r83, r84 :: object r85 :: tuple r86 :: str r87, r88 :: object r89 :: bool r90, r91 :: str r92 :: tuple r93 :: int32 r94 :: bit r95 :: dict r96 :: str r97 :: int32 r98 :: bit L0: r0 = builtins :: module r1 = load_address _Py_NoneStruct r2 = r0 != r1 if r2 goto L2 else goto L1 :: bool L1: r3 = 'builtins' r4 = PyImport_Import(r3) builtins = r4 :: module L2: r5 = __main__.globals :: static r6 = 'TypeVar' r7 = 'Generic' r8 = PyList_New(2) r9 = get_element_ptr r8 ob_item :: PyListObject r10 = load_mem r9 :: ptr* set_mem r10, r6 :: builtins.object* r11 = r10 + WORD_SIZE*1 set_mem r11, r7 :: builtins.object* keep_alive r8 r12 = 'typing' r13 = PyImport_ImportModuleLevelObject(r12, r5, 0, r8, 0) typing = r13 :: module r14 = 'typing' r15 = 'TypeVar' r16 = 'TypeVar' r17 = CPyImport_ImportFrom(r13, r14, r15, r16) r18 = 'TypeVar' r19 = CPyDict_SetItem(r5, r18, r17) r20 = r19 >= 0 :: signed r21 = 'typing' r22 = 'Generic' r23 = 'Generic' r24 = CPyImport_ImportFrom(r13, r21, r22, r23) r25 = 'Generic' r26 = CPyDict_SetItem(r5, r25, r24) r27 = r26 >= 0 :: signed r28 = __main__.globals :: static r29 = 'trait' r30 = PyList_New(1) r31 = get_element_ptr r30 ob_item :: PyListObject r32 = load_mem r31 :: ptr* set_mem r32, r29 :: builtins.object* keep_alive r30 r33 = 'mypy_extensions' r34 = PyImport_ImportModuleLevelObject(r33, r28, 0, r30, 0) mypy_extensions = r34 :: module r35 = 'mypy_extensions' r36 = 'trait' r37 = 'trait' r38 = CPyImport_ImportFrom(r34, r35, r36, r37) r39 = 'trait' r40 = CPyDict_SetItem(r28, r39, r38) r41 = r40 >= 0 :: signed r42 = 'T' r43 = __main__.globals :: static r44 = 'TypeVar' r45 = CPyDict_GetItem(r43, r44) r46 = PyObject_CallFunctionObjArgs(r45, r42, 0) r47 = __main__.globals :: static r48 = 'T' r49 = CPyDict_SetItem(r47, r48, r46) r50 = r49 >= 0 :: signed r51 = :: object r52 = '__main__' r53 = __main__.C_template :: type r54 = CPyType_FromTemplate(r53, r51, r52) r55 = C_trait_vtable_setup() r56 = '__mypyc_attrs__' r57 = PyTuple_Pack(0) r58 = PyObject_SetAttr(r54, r56, r57) r59 = r58 >= 0 :: signed __main__.C = r54 :: type r60 = __main__.globals :: static r61 = 'C' r62 = CPyDict_SetItem(r60, r61, r54) r63 = r62 >= 0 :: signed r64 = :: object r65 = '__main__' r66 = __main__.S_template :: type r67 = CPyType_FromTemplate(r66, r64, r65) r68 = '__mypyc_attrs__' r69 = PyTuple_Pack(0) r70 = PyObject_SetAttr(r67, r68, r69) r71 = r70 >= 0 :: signed __main__.S = r67 :: type r72 = __main__.globals :: static r73 = 'S' r74 = CPyDict_SetItem(r72, r73, r67) r75 = r74 >= 0 :: signed r76 = __main__.C :: type r77 = __main__.S :: type r78 = __main__.globals :: static r79 = 'Generic' r80 = CPyDict_GetItem(r78, r79) r81 = __main__.globals :: static r82 = 'T' r83 = CPyDict_GetItem(r81, r82) r84 = PyObject_GetItem(r80, r83) r85 = PyTuple_Pack(3, r76, r77, r84) r86 = '__main__' r87 = __main__.D_template :: type r88 = CPyType_FromTemplate(r87, r85, r86) r89 = D_trait_vtable_setup() r90 = '__mypyc_attrs__' r91 = '__dict__' r92 = PyTuple_Pack(1, r91) r93 = PyObject_SetAttr(r88, r90, r92) r94 = r93 >= 0 :: signed __main__.D = r88 :: type r95 = __main__.globals :: static r96 = 'D' r97 = CPyDict_SetItem(r95, r96, r88) r98 = r97 >= 0 :: signed return 1 [case testIsInstance] class A: pass class B(A): pass def f(x: A) -> B: if isinstance(x, B): return x return B() [out] def f(x): x :: __main__.A r0 :: object r1 :: ptr r2 :: object r3 :: bit r4, r5 :: __main__.B L0: r0 = __main__.B :: type r1 = get_element_ptr x ob_type :: PyObject r2 = load_mem r1 :: builtins.object* keep_alive x r3 = r2 == r0 if r3 goto L1 else goto L2 :: bool L1: r4 = cast(__main__.B, x) return r4 L2: r5 = B() return r5 [case testIsInstanceTuple] from typing import Union class R: pass class A(R): pass class B(R): pass class C(R): pass def f(x: R) -> Union[A, B]: if isinstance(x, (A, B)): return x return A() [out] def f(x): x :: __main__.R r0 :: object r1 :: ptr r2 :: object r3 :: bit r4 :: bool r5 :: object r6 :: ptr r7 :: object r8 :: bit r9 :: union[__main__.A, __main__.B] r10 :: __main__.A L0: r0 = __main__.A :: type r1 = get_element_ptr x ob_type :: PyObject r2 = load_mem r1 :: builtins.object* keep_alive x r3 = r2 == r0 if r3 goto L1 else goto L2 :: bool L1: r4 = r3 goto L3 L2: r5 = __main__.B :: type r6 = get_element_ptr x ob_type :: PyObject r7 = load_mem r6 :: builtins.object* keep_alive x r8 = r7 == r5 r4 = r8 L3: if r4 goto L4 else goto L5 :: bool L4: r9 = cast(union[__main__.A, __main__.B], x) return r9 L5: r10 = A() return r10 [case testIsInstanceFewSubclasses] class R: pass class A(R): pass def f(x: object) -> R: if isinstance(x, R): return x return A() [out] def f(x): x, r0 :: object r1 :: ptr r2 :: object r3 :: bit r4 :: bool r5 :: object r6 :: ptr r7 :: object r8 :: bit r9 :: __main__.R r10 :: __main__.A L0: r0 = __main__.A :: type r1 = get_element_ptr x ob_type :: PyObject r2 = load_mem r1 :: builtins.object* keep_alive x r3 = r2 == r0 if r3 goto L1 else goto L2 :: bool L1: r4 = r3 goto L3 L2: r5 = __main__.R :: type r6 = get_element_ptr x ob_type :: PyObject r7 = load_mem r6 :: builtins.object* keep_alive x r8 = r7 == r5 r4 = r8 L3: if r4 goto L4 else goto L5 :: bool L4: r9 = cast(__main__.R, x) return r9 L5: r10 = A() return r10 [case testIsInstanceFewSubclassesTrait] from mypy_extensions import trait class B: pass @trait class R: pass class A(B, R): pass class C(B, R): pass def f(x: object) -> R: if isinstance(x, R): return x return A() [out] def f(x): x, r0 :: object r1 :: ptr r2 :: object r3 :: bit r4 :: bool r5 :: object r6 :: ptr r7 :: object r8 :: bit r9 :: __main__.R r10 :: __main__.A L0: r0 = __main__.A :: type r1 = get_element_ptr x ob_type :: PyObject r2 = load_mem r1 :: builtins.object* keep_alive x r3 = r2 == r0 if r3 goto L1 else goto L2 :: bool L1: r4 = r3 goto L3 L2: r5 = __main__.C :: type r6 = get_element_ptr x ob_type :: PyObject r7 = load_mem r6 :: builtins.object* keep_alive x r8 = r7 == r5 r4 = r8 L3: if r4 goto L4 else goto L5 :: bool L4: r9 = cast(__main__.R, x) return r9 L5: r10 = A() return r10 [case testIsInstanceManySubclasses] class R: pass class A(R): pass class B(R): pass class C(R): pass def f(x: object) -> R: if isinstance(x, R): return x return B() [out] def f(x): x, r0 :: object r1 :: bool r2 :: __main__.R r3 :: __main__.B L0: r0 = __main__.R :: type r1 = CPy_TypeCheck(x, r0) if r1 goto L1 else goto L2 :: bool L1: r2 = cast(__main__.R, x) return r2 L2: r3 = B() return r3 [case testFakeSuper] class A: def __init__(self, x: int) -> None: self.x = x class B(A): def __init__(self, x: int, y: int) -> None: A.__init__(self, x) self.y = y [out] def A.__init__(self, x): self :: __main__.A x :: int L0: self.x = x return 1 def B.__init__(self, x, y): self :: __main__.B x, y :: int r0 :: None L0: r0 = A.__init__(self, x) self.y = y return 1 [case testClassMethod] class C: @staticmethod def foo(x: int) -> int: return 10 + x @classmethod def bar(cls, x: int) -> int: return 10 + x def lol() -> int: return C.foo(1) + C.bar(2) [out] def C.foo(x): x, r0 :: int L0: r0 = CPyTagged_Add(20, x) return r0 def C.bar(cls, x): cls :: object x, r0 :: int L0: r0 = CPyTagged_Add(20, x) return r0 def lol(): r0 :: int r1 :: object r2, r3 :: int L0: r0 = C.foo(2) r1 = __main__.C :: type r2 = C.bar(r1, 4) r3 = CPyTagged_Add(r0, r2) return r3 [case testSuper1] class A: def __init__(self, x: int) -> None: self.x = x class B(A): def __init__(self, x: int, y: int) -> None: super().__init__(x) self.y = y [out] def A.__init__(self, x): self :: __main__.A x :: int L0: self.x = x return 1 def B.__init__(self, x, y): self :: __main__.B x, y :: int r0 :: None L0: r0 = A.__init__(self, x) self.y = y return 1 [case testSuper2] from mypy_extensions import trait @trait class T: def foo(self) -> None: pass class X(T): def foo(self) -> None: super().foo() [out] def T.foo(self): self :: __main__.T L0: return 1 def X.foo(self): self :: __main__.X r0 :: None L0: r0 = T.foo(self) return 1 [case testSuperCallToObjectInitIsOmitted] class C: def __init__(self) -> None: super().__init__() class D: pass class E(D): def __init__(self) -> None: super().__init__() class F(C): def __init__(self) -> None: super().__init__() class DictSubclass(dict): def __init__(self) -> None: super().__init__() [out] def C.__init__(self): self :: __main__.C L0: return 1 def E.__init__(self): self :: __main__.E L0: return 1 def F.__init__(self): self :: __main__.F r0 :: None L0: r0 = C.__init__(self) return 1 def DictSubclass.__init__(self): self :: dict r0 :: object r1 :: str r2, r3, r4 :: object r5 :: str r6, r7 :: object L0: r0 = builtins :: module r1 = 'super' r2 = CPyObject_GetAttr(r0, r1) r3 = __main__.DictSubclass :: type r4 = PyObject_CallFunctionObjArgs(r2, r3, self, 0) r5 = '__init__' r6 = CPyObject_GetAttr(r4, r5) r7 = PyObject_CallFunctionObjArgs(r6, 0) return 1 [case testClassVariable] from typing import ClassVar class A: x = 10 # type: ClassVar[int] def f() -> int: return A.x [out] def f(): r0 :: object r1 :: str r2 :: object r3 :: int L0: r0 = __main__.A :: type r1 = 'x' r2 = CPyObject_GetAttr(r0, r1) r3 = unbox(int, r2) return r3 [case testNoEqDefined] class A: pass def f(a: A, b: A) -> bool: return a == b def f2(a: A, b: A) -> bool: return a != b [out] def f(a, b): a, b :: __main__.A r0 :: bit L0: r0 = a == b return r0 def f2(a, b): a, b :: __main__.A r0 :: bit L0: r0 = a != b return r0 [case testEqDefined] class Base: def __eq__(self, other: object) -> bool: return False class Derived(Base): def __eq__(self, other: object) -> bool: return True def f(a: Base, b: Base) -> bool: return a == b def f2(a: Base, b: Base) -> bool: return a != b def fOpt(a: Derived, b: Derived) -> bool: return a == b def fOpt2(a: Derived, b: Derived) -> bool: return a != b [out] def Base.__eq__(self, other): self :: __main__.Base other, r0 :: object L0: r0 = box(bool, 0) return r0 def Base.__ne__(__mypyc_self__, rhs): __mypyc_self__ :: __main__.Base rhs, r0, r1 :: object r2 :: bit r3 :: int32 r4 :: bit r5 :: bool r6 :: object L0: r0 = __mypyc_self__.__eq__(rhs) r1 = load_address _Py_NotImplementedStruct r2 = r0 == r1 if r2 goto L2 else goto L1 :: bool L1: r3 = PyObject_Not(r0) r4 = r3 >= 0 :: signed r5 = truncate r3: int32 to builtins.bool r6 = box(bool, r5) return r6 L2: return r1 def Derived.__eq__(self, other): self :: __main__.Derived other, r0 :: object L0: r0 = box(bool, 1) return r0 def f(a, b): a, b :: __main__.Base r0 :: object r1 :: bool L0: r0 = PyObject_RichCompare(a, b, 2) r1 = unbox(bool, r0) return r1 def f2(a, b): a, b :: __main__.Base r0 :: object r1 :: bool L0: r0 = PyObject_RichCompare(a, b, 3) r1 = unbox(bool, r0) return r1 def fOpt(a, b): a, b :: __main__.Derived r0 :: object r1 :: bool L0: r0 = a.__eq__(b) r1 = unbox(bool, r0) return r1 def fOpt2(a, b): a, b :: __main__.Derived r0 :: object r1 :: bool L0: r0 = a.__ne__(b) r1 = unbox(bool, r0) return r1 [case testEqDefinedLater] def f(a: 'Base', b: 'Base') -> bool: return a == b def f2(a: 'Base', b: 'Base') -> bool: return a != b def fOpt(a: 'Derived', b: 'Derived') -> bool: return a == b def fOpt2(a: 'Derived', b: 'Derived') -> bool: return a != b class Base: pass class Derived(Base): def __eq__(self, other: object) -> bool: return True [out] def f(a, b): a, b :: __main__.Base r0 :: object r1 :: bool L0: r0 = PyObject_RichCompare(a, b, 2) r1 = unbox(bool, r0) return r1 def f2(a, b): a, b :: __main__.Base r0 :: object r1 :: bool L0: r0 = PyObject_RichCompare(a, b, 3) r1 = unbox(bool, r0) return r1 def fOpt(a, b): a, b :: __main__.Derived r0 :: object r1 :: bool L0: r0 = a.__eq__(b) r1 = unbox(bool, r0) return r1 def fOpt2(a, b): a, b :: __main__.Derived r0 :: str r1 :: object r2 :: bool L0: r0 = '__ne__' r1 = CPyObject_CallMethodObjArgs(a, r0, b, 0) r2 = unbox(bool, r1) return r2 def Derived.__eq__(self, other): self :: __main__.Derived other, r0 :: object L0: r0 = box(bool, 1) return r0 def Derived.__ne__(__mypyc_self__, rhs): __mypyc_self__ :: __main__.Derived rhs, r0, r1 :: object r2 :: bit r3 :: int32 r4 :: bit r5 :: bool r6 :: object L0: r0 = __mypyc_self__.__eq__(rhs) r1 = load_address _Py_NotImplementedStruct r2 = r0 == r1 if r2 goto L2 else goto L1 :: bool L1: r3 = PyObject_Not(r0) r4 = r3 >= 0 :: signed r5 = truncate r3: int32 to builtins.bool r6 = box(bool, r5) return r6 L2: return r1 [case testDefaultVars] from typing import ClassVar, Optional class A: x = 10 def lol(self) -> None: self.x = 100 LOL = 'lol' class B(A): y = LOL z: Optional[str] = None b = True bogus = None # type: int [out] def A.lol(self): self :: __main__.A r0 :: bool L0: self.x = 200; r0 = is_error return 1 def A.__mypyc_defaults_setup(__mypyc_self__): __mypyc_self__ :: __main__.A L0: __mypyc_self__.x = 20 return 1 def B.__mypyc_defaults_setup(__mypyc_self__): __mypyc_self__ :: __main__.B r0 :: dict r1 :: str r2 :: object r3 :: str r4 :: object L0: __mypyc_self__.x = 20 r0 = __main__.globals :: static r1 = 'LOL' r2 = CPyDict_GetItem(r0, r1) r3 = cast(str, r2) __mypyc_self__.y = r3 r4 = box(None, 1) __mypyc_self__.z = r4 __mypyc_self__.b = 1 return 1 [case testSubclassDictSpecalized] from typing import Dict class WelpDict(Dict[str, int]): pass def foo(x: WelpDict) -> None: # we care that the specalized op gets used x.update(x) [out] def foo(x): x :: dict r0 :: int32 r1 :: bit L0: r0 = CPyDict_Update(x, x) r1 = r0 >= 0 :: signed return 1 [case testNoSpuriousLinearity] # Make sure that the non-trait MRO linearity check isn't affected by processing order class A(B): pass class B(C): pass class C: pass [out] [case testDeletableSemanticAnalysis] class Err1: __deletable__ = 'x' # E: "__deletable__" must be initialized with a list or tuple expression class Err2: __deletable__ = [ 1 # E: Invalid "__deletable__" item; string literal expected ] class Err3: __deletable__ = ['x', ['y'], 'z'] # E: Invalid "__deletable__" item; string literal expected class Err4: __deletable__ = (1,) # E: Invalid "__deletable__" item; string literal expected a = ['x'] class Err5: __deletable__ = a # E: "__deletable__" must be initialized with a list or tuple expression class Ok1: __deletable__ = ('x',) x: int class Ok2: __deletable__ = ['x'] x: int [case testInvalidDeletableAttribute] class NotDeletable: __deletable__ = ['x'] x: int y: int def g(o: NotDeletable) -> None: del o.x del o.y # E: "y" cannot be deleted \ # N: Using "__deletable__ = ['']" in the class body enables "del obj." class Base: x: int class Deriv(Base): __deletable__ = ['x'] # E: Attribute "x" not defined in "Deriv" (defined in "Base") class UndefinedDeletable: __deletable__ = ['x'] # E: Attribute "x" not defined class DeletableProperty: __deletable__ = ['prop'] # E: Cannot make property "prop" deletable @property def prop(self) -> int: return 5 [case testFinalDeletable] from typing import Final class DeletableFinal1: x: Final[int] # E: Deletable attribute cannot be final __deletable__ = ['x'] def __init__(self, x: int) -> None: self.x = x class DeletableFinal2: X: Final = 0 # E: Deletable attribute cannot be final __deletable__ = ['X'] [case testNeedAnnotateClassVar] from typing import Final, ClassVar, Type class C: a = 'A' b: str = 'B' f: Final = 'F' c: ClassVar = 'C' class D(C): pass def f() -> None: C.a # E: Cannot access instance attribute "a" through class object \ # N: (Hint: Use "x: Final = ..." or "x: ClassVar = ..." to define a class attribute) C.b # E: Cannot access instance attribute "b" through class object \ # N: (Hint: Use "x: Final = ..." or "x: ClassVar = ..." to define a class attribute) C.f C.c D.a # E: Cannot access instance attribute "a" through class object \ # N: (Hint: Use "x: Final = ..." or "x: ClassVar = ..." to define a class attribute) D.b # E: Cannot access instance attribute "b" through class object \ # N: (Hint: Use "x: Final = ..." or "x: ClassVar = ..." to define a class attribute) D.f D.c def g(c: Type[C], d: Type[D]) -> None: c.a # E: Cannot access instance attribute "a" through class object \ # N: (Hint: Use "x: Final = ..." or "x: ClassVar = ..." to define a class attribute) c.f c.c d.a # E: Cannot access instance attribute "a" through class object \ # N: (Hint: Use "x: Final = ..." or "x: ClassVar = ..." to define a class attribute) d.f d.c [case testSetAttributeWithDefaultInInit] class C: s = '' def __init__(self, s: str) -> None: self.s = s [out] def C.__init__(self, s): self :: __main__.C s :: str r0 :: bool L0: self.s = s; r0 = is_error return 1 def C.__mypyc_defaults_setup(__mypyc_self__): __mypyc_self__ :: __main__.C r0 :: str L0: r0 = '' __mypyc_self__.s = r0 return 1 [case testBorrowAttribute] def f(d: D) -> int: return d.c.x class C: x: int class D: c: C [out] def f(d): d :: __main__.D r0 :: __main__.C r1 :: int L0: r0 = borrow d.c r1 = r0.x keep_alive d return r1 [case testNoBorrowOverPropertyAccess] class C: d: D class D: @property def e(self) -> E: return E() class E: x: int def f(c: C) -> int: return c.d.e.x [out] def D.e(self): self :: __main__.D r0 :: __main__.E L0: r0 = E() return r0 def f(c): c :: __main__.C r0 :: __main__.D r1 :: __main__.E r2 :: int L0: r0 = c.d r1 = r0.e r2 = r1.x return r2 [case testBorrowResultOfCustomGetItemInIfStatement] from typing import List class C: def __getitem__(self, x: int) -> List[int]: return [] def f(x: C) -> None: # In this case the keep_alive must come before the branch, as otherwise # reference count transform will get confused. if x[1][0] == 2: y = 1 else: y = 2 [out] def C.__getitem__(self, x): self :: __main__.C x :: int r0 :: list L0: r0 = PyList_New(0) return r0 def f(x): x :: __main__.C r0 :: list r1 :: object r2 :: int r3 :: bit y :: int L0: r0 = x.__getitem__(2) r1 = CPyList_GetItemShortBorrow(r0, 0) r2 = unbox(int, r1) r3 = r2 == 4 keep_alive r0 if r3 goto L1 else goto L2 :: bool L1: y = 2 goto L3 L2: y = 4 L3: return 1