| # Test cases for glue methods. |
| # |
| # These are used when subclass method signature has a different representation |
| # compared to the base class. |
| |
| [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 testPropertyDerivedGen] |
| from typing import Callable |
| class BaseProperty: |
| @property |
| def value(self) -> object: |
| return self._incrementer |
| |
| @property |
| def bad_value(self) -> object: |
| return self._incrementer |
| |
| @property |
| def next(self) -> BaseProperty: |
| return BaseProperty(self._incrementer + 1) |
| |
| def __init__(self, value: int) -> None: |
| self._incrementer = value |
| |
| class DerivedProperty(BaseProperty): |
| @property |
| def value(self) -> int: |
| return self._incrementer |
| |
| @property |
| def bad_value(self) -> object: |
| return self._incrementer |
| |
| @property |
| def next(self) -> DerivedProperty: |
| return DerivedProperty(self._incr_func, self._incr_func(self.value)) |
| |
| def __init__(self, incr_func: Callable[[int], int], value: int) -> None: |
| BaseProperty.__init__(self, value) |
| self._incr_func = incr_func |
| |
| |
| class AgainProperty(DerivedProperty): |
| @property |
| def next(self) -> AgainProperty: |
| return AgainProperty(self._incr_func, self._incr_func(self._incr_func(self.value))) |
| |
| @property |
| def bad_value(self) -> int: |
| return self._incrementer |
| [out] |
| def BaseProperty.value(self): |
| self :: __main__.BaseProperty |
| r0 :: int |
| r1 :: object |
| L0: |
| r0 = self._incrementer |
| r1 = box(int, r0) |
| return r1 |
| def BaseProperty.bad_value(self): |
| self :: __main__.BaseProperty |
| r0 :: int |
| r1 :: object |
| L0: |
| r0 = self._incrementer |
| r1 = box(int, r0) |
| return r1 |
| def BaseProperty.next(self): |
| self :: __main__.BaseProperty |
| r0, r1 :: int |
| r2 :: __main__.BaseProperty |
| L0: |
| r0 = borrow self._incrementer |
| r1 = CPyTagged_Add(r0, 2) |
| keep_alive self |
| r2 = BaseProperty(r1) |
| return r2 |
| def BaseProperty.__init__(self, value): |
| self :: __main__.BaseProperty |
| value :: int |
| L0: |
| self._incrementer = value |
| return 1 |
| def DerivedProperty.value(self): |
| self :: __main__.DerivedProperty |
| r0 :: int |
| L0: |
| r0 = self._incrementer |
| return r0 |
| def DerivedProperty.value__BaseProperty_glue(__mypyc_self__): |
| __mypyc_self__ :: __main__.DerivedProperty |
| r0 :: int |
| r1 :: object |
| L0: |
| r0 = __mypyc_self__.value |
| r1 = box(int, r0) |
| return r1 |
| def DerivedProperty.bad_value(self): |
| self :: __main__.DerivedProperty |
| r0 :: int |
| r1 :: object |
| L0: |
| r0 = self._incrementer |
| r1 = box(int, r0) |
| return r1 |
| def DerivedProperty.next(self): |
| self :: __main__.DerivedProperty |
| r0 :: object |
| r1 :: int |
| r2, r3, r4 :: object |
| r5 :: int |
| r6 :: __main__.DerivedProperty |
| L0: |
| r0 = self._incr_func |
| r1 = self.value |
| r2 = self._incr_func |
| r3 = box(int, r1) |
| r4 = PyObject_CallFunctionObjArgs(r2, r3, 0) |
| r5 = unbox(int, r4) |
| r6 = DerivedProperty(r0, r5) |
| return r6 |
| def DerivedProperty.next__BaseProperty_glue(__mypyc_self__): |
| __mypyc_self__, r0 :: __main__.DerivedProperty |
| L0: |
| r0 = __mypyc_self__.next |
| return r0 |
| def DerivedProperty.__init__(self, incr_func, value): |
| self :: __main__.DerivedProperty |
| incr_func :: object |
| value :: int |
| r0 :: None |
| L0: |
| r0 = BaseProperty.__init__(self, value) |
| self._incr_func = incr_func |
| return 1 |
| def AgainProperty.next(self): |
| self :: __main__.AgainProperty |
| r0 :: object |
| r1 :: int |
| r2, r3, r4 :: object |
| r5 :: int |
| r6, r7, r8 :: object |
| r9 :: int |
| r10 :: __main__.AgainProperty |
| L0: |
| r0 = self._incr_func |
| r1 = self.value |
| r2 = self._incr_func |
| r3 = box(int, r1) |
| r4 = PyObject_CallFunctionObjArgs(r2, r3, 0) |
| r5 = unbox(int, r4) |
| r6 = self._incr_func |
| r7 = box(int, r5) |
| r8 = PyObject_CallFunctionObjArgs(r6, r7, 0) |
| r9 = unbox(int, r8) |
| r10 = AgainProperty(r0, r9) |
| return r10 |
| def AgainProperty.next__DerivedProperty_glue(__mypyc_self__): |
| __mypyc_self__, r0 :: __main__.AgainProperty |
| L0: |
| r0 = __mypyc_self__.next |
| return r0 |
| def AgainProperty.next__BaseProperty_glue(__mypyc_self__): |
| __mypyc_self__, r0 :: __main__.AgainProperty |
| L0: |
| r0 = __mypyc_self__.next |
| return r0 |
| def AgainProperty.bad_value(self): |
| self :: __main__.AgainProperty |
| r0 :: int |
| L0: |
| r0 = self._incrementer |
| return r0 |
| def AgainProperty.bad_value__DerivedProperty_glue(__mypyc_self__): |
| __mypyc_self__ :: __main__.AgainProperty |
| r0 :: int |
| r1 :: object |
| L0: |
| r0 = __mypyc_self__.bad_value |
| r1 = box(int, r0) |
| return r1 |
| def AgainProperty.bad_value__BaseProperty_glue(__mypyc_self__): |
| __mypyc_self__ :: __main__.AgainProperty |
| r0 :: int |
| r1 :: object |
| L0: |
| r0 = __mypyc_self__.bad_value |
| r1 = box(int, r0) |
| return r1 |
| |
| [case testPropertyTraitSubclassing] |
| from mypy_extensions import trait |
| @trait |
| class SubclassedTrait: |
| @property |
| def this(self) -> SubclassedTrait: |
| return self |
| |
| @property |
| def boxed(self) -> object: |
| return 3 |
| |
| class DerivingObject(SubclassedTrait): |
| @property |
| def this(self) -> DerivingObject: |
| return self |
| |
| @property |
| def boxed(self) -> int: |
| return 5 |
| [out] |
| def SubclassedTrait.this(self): |
| self :: __main__.SubclassedTrait |
| L0: |
| return self |
| def SubclassedTrait.boxed(self): |
| self :: __main__.SubclassedTrait |
| r0 :: object |
| L0: |
| r0 = object 3 |
| return r0 |
| def DerivingObject.this(self): |
| self :: __main__.DerivingObject |
| L0: |
| return self |
| def DerivingObject.this__SubclassedTrait_glue(__mypyc_self__): |
| __mypyc_self__, r0 :: __main__.DerivingObject |
| L0: |
| r0 = __mypyc_self__.this |
| return r0 |
| def DerivingObject.boxed(self): |
| self :: __main__.DerivingObject |
| L0: |
| return 10 |
| def DerivingObject.boxed__SubclassedTrait_glue(__mypyc_self__): |
| __mypyc_self__ :: __main__.DerivingObject |
| r0 :: int |
| r1 :: object |
| L0: |
| r0 = __mypyc_self__.boxed |
| r1 = box(int, r0) |
| return r1 |
| |
| [case testI64GlueWithExtraDefaultArg] |
| from mypy_extensions import i64 |
| |
| class C: |
| def f(self) -> None: pass |
| |
| class D(C): |
| def f(self, x: i64 = 44) -> None: pass |
| [out] |
| def C.f(self): |
| self :: __main__.C |
| L0: |
| return 1 |
| def D.f(self, x, __bitmap): |
| self :: __main__.D |
| x :: i64 |
| __bitmap, r0 :: u32 |
| r1 :: bit |
| L0: |
| r0 = __bitmap & 1 |
| r1 = r0 == 0 |
| if r1 goto L1 else goto L2 :: bool |
| L1: |
| x = 44 |
| L2: |
| return 1 |
| def D.f__C_glue(self): |
| self :: __main__.D |
| r0 :: None |
| L0: |
| r0 = D.f(self, 0, 0) |
| return r0 |
| |
| [case testI64GlueWithSecondDefaultArg] |
| from mypy_extensions import i64 |
| |
| class C: |
| def f(self, x: i64 = 11) -> None: pass |
| class D(C): |
| def f(self, x: i64 = 12, y: i64 = 13) -> None: pass |
| [out] |
| def C.f(self, x, __bitmap): |
| self :: __main__.C |
| x :: i64 |
| __bitmap, r0 :: u32 |
| r1 :: bit |
| L0: |
| r0 = __bitmap & 1 |
| r1 = r0 == 0 |
| if r1 goto L1 else goto L2 :: bool |
| L1: |
| x = 11 |
| L2: |
| return 1 |
| def D.f(self, x, y, __bitmap): |
| self :: __main__.D |
| x, y :: i64 |
| __bitmap, r0 :: u32 |
| r1 :: bit |
| r2 :: u32 |
| r3 :: bit |
| L0: |
| r0 = __bitmap & 1 |
| r1 = r0 == 0 |
| if r1 goto L1 else goto L2 :: bool |
| L1: |
| x = 12 |
| L2: |
| r2 = __bitmap & 2 |
| r3 = r2 == 0 |
| if r3 goto L3 else goto L4 :: bool |
| L3: |
| y = 13 |
| L4: |
| return 1 |
| def D.f__C_glue(self, x, __bitmap): |
| self :: __main__.D |
| x :: i64 |
| __bitmap :: u32 |
| r0 :: None |
| L0: |
| r0 = D.f(self, x, 0, __bitmap) |
| return r0 |
| |
| [case testI64GlueWithInvalidOverride] |
| from mypy_extensions import i64 |
| |
| class C: |
| def f(self, x: i64, y: i64 = 5) -> None: pass |
| def ff(self, x: int) -> None: pass |
| class CC(C): |
| def f(self, x: i64 = 12, y: i64 = 5) -> None: pass # Line 7 |
| def ff(self, x: int = 12) -> None: pass |
| |
| class D: |
| def f(self, x: int) -> None: pass |
| class DD(D): |
| def f(self, x: i64) -> None: pass # Line 13 |
| |
| class E: |
| def f(self, x: i64) -> None: pass |
| class EE(E): |
| def f(self, x: int) -> None: pass # Line 18 |
| [out] |
| main:7: error: An argument with type "i64" cannot be given a default value in a method override |
| main:13: error: Incompatible argument type "i64" (base class has type "int") |
| main:18: error: Incompatible argument type "int" (base class has type "i64") |