| [case testEmptyClass] |
| class Empty: pass |
| |
| def f(e: Empty) -> Empty: |
| return e |
| [file driver.py] |
| from native import Empty, f |
| |
| print(isinstance(Empty, type)) |
| print(Empty) |
| print(str(Empty())[:20]) |
| |
| e = Empty() |
| print(f(e) is e) |
| [out] |
| True |
| <class 'native.Empty'> |
| <native.Empty object |
| True |
| |
| [case testClassWithFields] |
| class C: |
| x: int |
| y: int |
| z: 'D' |
| class D: |
| pass |
| [file driver.py] |
| from native import C |
| |
| c = C() |
| assert not hasattr(c, 'x') |
| assert not hasattr(c, 'y') |
| c.x = 1 |
| c.y = 2 |
| print(c.x) |
| print(c.y) |
| c.x = 10**30 |
| print(c.x) |
| c.x = 10**30+1 |
| print(c.x) |
| assert hasattr(c, 'x') |
| assert hasattr(c, 'y') |
| assert not hasattr(c, 'z') |
| del c.x |
| assert not hasattr(c, 'x') |
| assert hasattr(c, 'y') |
| del c.y |
| assert not hasattr(c, 'y') |
| c.x = 10**30+2 |
| print(c.x) |
| assert hasattr(c, 'x') |
| [out] |
| 1 |
| 2 |
| 1000000000000000000000000000000 |
| 1000000000000000000000000000001 |
| 1000000000000000000000000000002 |
| |
| [case testNonExtInheritance] |
| from typing import Any |
| |
| def decorator(cls) -> Any: |
| return cls |
| |
| class C: |
| def __init__(self) -> None: |
| self.c = 3 |
| |
| def get_c(self) -> int: |
| return self.c |
| |
| class B(C): |
| def __init__(self) -> None: |
| super().__init__() |
| self.b = 2 |
| |
| def get_b(self) -> int: |
| return self.b |
| |
| @decorator |
| class A(B): |
| def __init__(self) -> None: |
| super().__init__() |
| self.a = 1 |
| |
| @classmethod |
| def constant(cls) -> int: |
| return 4 |
| |
| def get_a(self) -> int: |
| return self.a |
| |
| [file driver.py] |
| from native import A |
| a = A() |
| assert a.a == 1 |
| assert a.b == 2 |
| assert a.c == 3 |
| assert a.get_a() == 1 |
| assert a.get_b() == 2 |
| assert a.get_c() == 3 |
| assert A.constant() == 4 |
| |
| [case testEnum] |
| from enum import Enum |
| |
| class TestEnum(Enum): |
| a : int = 1 |
| b : int = 2 |
| |
| @classmethod |
| def test(cls) -> int: |
| return 3 |
| |
| assert TestEnum.test() == 3 |
| |
| [file other.py] |
| # Force a multi-module test to make sure we can compile multi-file with |
| # non-extension classes |
| |
| [file driver.py] |
| from native import TestEnum |
| assert TestEnum.a.name == 'a' |
| assert TestEnum.a.value == 1 |
| assert TestEnum.b.name == 'b' |
| assert TestEnum.b.value == 2 |
| |
| [case testRunDataclass] |
| from dataclasses import dataclass, field |
| from typing import Set, List, Callable, Any |
| |
| @dataclass |
| class Person1: |
| age : int |
| name : str |
| |
| def __bool__(self) -> bool: |
| return self.name == 'robot' |
| |
| def testBool(p: Person1) -> bool: |
| if p: |
| return True |
| else: |
| return False |
| |
| @dataclass |
| class Person1b(Person1): |
| id: str = '000' |
| |
| @dataclass |
| class Person2: |
| age : int |
| name : str = field(default='robot') |
| |
| @dataclass(order = True) |
| class Person3: |
| age : int = field(default = 6) |
| friendIDs : List[int] = field(default_factory = list) |
| |
| def get_age(self) -> int: |
| return (self.age) |
| |
| def set_age(self, new_age : int) -> None: |
| self.age = new_age |
| |
| def add_friendID(self, fid : int) -> None: |
| self.friendIDs.append(fid) |
| |
| def get_friendIDs(self) -> List[int]: |
| return self.friendIDs |
| |
| def get_next_age(g: Callable[[Any], int]) -> Callable[[Any], int]: |
| def f(a: Any) -> int: |
| return g(a) + 1 |
| return f |
| |
| @dataclass |
| class Person4: |
| age : int |
| _name : str = 'Bot' |
| |
| @get_next_age |
| def get_age(self) -> int: |
| return self.age |
| |
| @property |
| def name(self) -> str: |
| return self._name |
| |
| [file other.py] |
| from native import Person1, Person1b, Person2, Person3, Person4, testBool |
| i1 = Person1(age = 5, name = 'robot') |
| assert i1.age == 5 |
| assert i1.name == 'robot' |
| assert testBool(i1) == True |
| assert testBool(Person1(age = 5, name = 'robo')) == False |
| i1b = Person1b(age = 5, name = 'robot') |
| assert i1b.age == 5 |
| assert i1b.name == 'robot' |
| assert testBool(i1b) == True |
| assert testBool(Person1b(age = 5, name = 'robo')) == False |
| i1c = Person1b(age = 20, name = 'robot', id = 'test') |
| assert i1c.age == 20 |
| assert i1c.id == 'test' |
| |
| i2 = Person2(age = 5) |
| assert i2.age == 5 |
| assert i2.name == 'robot' |
| i3 = Person2(age = 5, name = 'new_robot') |
| assert i3.age == 5 |
| assert i3.name == 'new_robot' |
| i4 = Person3() |
| assert i4.age == 6 |
| assert i4.friendIDs == [] |
| i5 = Person3(age = 5) |
| assert i5.age == 5 |
| assert i5.friendIDs == [] |
| i6 = Person3(age = 5, friendIDs = [1,2,3]) |
| assert i6.age == 5 |
| assert i6.friendIDs == [1,2,3] |
| assert i6.get_age() == 5 |
| i6.set_age(10) |
| assert i6.get_age() == 10 |
| i6.add_friendID(4) |
| assert i6.get_friendIDs() == [1,2,3,4] |
| i7 = Person4(age = 5) |
| assert i7.get_age() == 6 |
| i7.age += 3 |
| assert i7.age == 8 |
| assert i7.name == 'Bot' |
| i8 = Person3(age = 1, friendIDs = [1,2]) |
| i9 = Person3(age = 1, friendIDs = [1,2]) |
| assert i8 == i9 |
| i8.age = 2 |
| assert i8 > i9 |
| |
| |
| [file driver.py] |
| import sys |
| |
| # Dataclasses introduced in 3.7 |
| version = sys.version_info[:2] |
| if version[0] < 3 or version[1] < 7: |
| exit() |
| |
| # Run the tests in both interpreted and compiled mode |
| import other |
| import other_interpreted |
| |
| # Test for an exceptional cases |
| from testutil import assertRaises |
| from native import Person1, Person1b, Person3 |
| from types import BuiltinMethodType |
| |
| with assertRaises(TypeError, "missing 1 required positional argument"): |
| Person1(0) |
| |
| with assertRaises(TypeError, "missing 2 required positional arguments"): |
| Person1b() |
| |
| with assertRaises(TypeError, "int object expected; got str"): |
| Person1('nope', 'test') |
| |
| p = Person1(0, 'test') |
| with assertRaises(TypeError, "int object expected; got str"): |
| p.age = 'nope' |
| |
| assert isinstance(Person3().get_age, BuiltinMethodType) |
| |
| [case testGetAttribute] |
| class C: |
| x: int |
| y: int |
| |
| def getx(c: C) -> int: |
| return c.x |
| |
| def gety(c: C) -> int: |
| return c.y |
| [file driver.py] |
| from native import C, getx, gety |
| c = C() |
| c.x = 10**30 |
| c.y = 10**30 + 1 |
| print(getx(c)) |
| print(gety(c)) |
| [out] |
| 1000000000000000000000000000000 |
| 1000000000000000000000000000001 |
| |
| [case testSetAttribute] |
| class C: |
| x: int |
| y: int |
| |
| def setx(c: C, v: int) -> None: |
| c.x = v |
| |
| def sety(c: C, v: int) -> None: |
| c.y = v |
| [file driver.py] |
| from native import C, setx, sety |
| c = C() |
| setx(c, 10**30) |
| sety(c, 10**30 + 1) |
| print(c.x) |
| print(c.y) |
| setx(c, 4) |
| sety(c, 5) |
| print(c.x, c.y) |
| setx(c, 10**30 + 2) |
| sety(c, 10**30 + 3) |
| print(c.x) |
| print(c.y) |
| [out] |
| 1000000000000000000000000000000 |
| 1000000000000000000000000000001 |
| 4 5 |
| 1000000000000000000000000000002 |
| 1000000000000000000000000000003 |
| |
| [case testAttributeTypes] |
| from typing import List, Tuple |
| class C: |
| a: List[int] |
| b: bool |
| c: C |
| d: object |
| |
| def setattrs(o: C, a: List[int], b: bool, c: C) -> None: |
| o.a = a |
| o.b = b |
| o.c = c |
| |
| def getattrs(o: C) -> Tuple[List[int], bool, C]: |
| return o.a, o.b, o.c |
| [file driver.py] |
| from native import C, setattrs, getattrs |
| c1 = C() |
| c2 = C() |
| aa = [2] |
| setattrs(c1, aa, True, c2) |
| a, b, c = getattrs(c1) |
| assert a is aa |
| assert b is True |
| assert c is c2 |
| |
| o = object() |
| c1.d = o |
| assert c1.d is o |
| |
| [case testConstructClassWithDefaultConstructor] |
| class C: |
| a: int |
| b: int |
| |
| def f() -> C: |
| c = C() |
| c.a = 13 |
| return c |
| [file driver.py] |
| from native import f, C |
| c = f() |
| assert c.a == 13 |
| assert type(c) == C |
| assert not hasattr(c, 'b') |
| |
| [case testListOfUserDefinedClass] |
| class C: |
| x: int |
| |
| def f() -> int: |
| c = C() |
| c.x = 5 |
| a = [c] |
| d = a[0] |
| return d.x + 1 |
| |
| def g() -> int: |
| a = [C()] |
| a[0].x = 3 |
| return a[0].x + 4 |
| [file driver.py] |
| from native import f, g |
| print(f()) |
| print(g()) |
| [out] |
| 6 |
| 7 |
| |
| [case testCastUserClass] |
| from typing import List |
| |
| class C: |
| x: int |
| |
| def f(a: List[C]) -> C: |
| return a[0] |
| [file driver.py] |
| from native import f, C |
| c = C() |
| assert f([c]) is c |
| |
| [case testClass1] |
| class A: |
| def __init__(self, x: int) -> None: |
| self.x = x |
| def foo(self) -> int: |
| return self.x+1 |
| def foo() -> int: |
| a = A(20) |
| return a.foo() |
| [file driver.py] |
| from native import A, foo |
| a = A(10) |
| assert a.foo() == 11 |
| assert foo() == 21 |
| |
| [case testGenericClass] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| class C(Generic[T]): |
| x: T |
| def __init__(self, x: T) -> None: |
| self.x = x |
| def get(self) -> T: |
| return self.x |
| def set(self, y: T) -> None: |
| self.x = y |
| |
| def f(c: C[int]) -> int: |
| y = c.get() |
| d = C[int](2) |
| c.set(c.get() + 1 + d.get()) |
| c.x = c.x + 2 |
| return c.x |
| |
| [file driver.py] |
| from native import C, f |
| c = C(6) |
| assert f(c) == 11 |
| c.x = 'x' |
| assert c.x == 'x' |
| c.set([1]) |
| assert c.x == [1] |
| assert c.get() == [1] |
| |
| [case testSubclass1] |
| from typing import Tuple |
| |
| class A: |
| def __init__(self) -> None: |
| self.x = 10 |
| def hi(self, suffix: str) -> str: |
| return str(self.x) + suffix |
| class B(A): |
| def __init__(self) -> None: |
| self.x = 20 |
| self.y = 'world' |
| def hi(self, suffix: str) -> str: |
| return 'hello ' + str(self.y) + suffix |
| |
| def use_a(x: A) -> Tuple[int, str]: |
| return (x.x, x.hi('')) |
| def use_b(x: B) -> str: |
| return x.hi('') |
| |
| [file driver.py] |
| from native import A, B, use_a, use_b |
| a = A() |
| b = B() |
| assert use_a(a) == (10, '10') |
| assert use_a(b) == (20, 'hello world') |
| assert a.x == 10 |
| assert b.x == 20 |
| assert b.y == 'world' |
| assert a.hi('!') == '10!' |
| assert b.hi('!') == 'hello world!' |
| assert use_b(b) == 'hello world' |
| |
| [case testSubclassSpecialize1] |
| class A: |
| def foo(self, x: int) -> object: |
| print('A') |
| return str(x) |
| def bar(self, x: int) -> None: |
| print(x + 1) |
| class B(A): |
| def foo(self, x: object) -> int: |
| print('B') |
| return id(x) |
| def bar(self, x: object) -> None: |
| print(x) |
| |
| def use_a(x: A, y: int) -> object: |
| x.bar(10) |
| return x.foo(y) |
| |
| def use_b(x: B, y: object) -> int: |
| return x.foo(y) |
| |
| [file driver.py] |
| from native import A, B, use_a, use_b |
| a = A() |
| b = B() |
| o = object() |
| i = 10 |
| assert a.foo(10) == '10' |
| assert b.foo(o) == id(o) |
| assert use_a(a, 10) == '10' |
| assert use_b(b, o) == id(o) |
| assert use_a(b, i) == id(i) |
| [out] |
| A |
| B |
| 11 |
| A |
| B |
| 10 |
| B |
| |
| [case testSubclassSpecialize2] |
| class A: |
| def foo(self, x: int) -> object: |
| print('A') |
| return str(x) |
| class B(A): |
| def foo(self, x: object) -> object: |
| print('B') |
| return x |
| class C(B): |
| def foo(self, x: object) -> int: |
| print('C') |
| 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) |
| |
| [file driver.py] |
| from native import A, B, C, use_a, use_b, use_c |
| a = A() |
| b = B() |
| c = C() |
| o = object() |
| i = 10 |
| assert a.foo(10) == '10' |
| assert b.foo(o) == o |
| assert c.foo(o) == id(o) |
| assert use_a(a, 10) == '10' |
| assert use_a(b, i) is i |
| assert use_a(c, i) == id(i) |
| assert use_b(b, o) == o |
| assert use_b(c, o) == id(o) |
| assert use_c(c, o) == id(o) |
| [out] |
| A |
| B |
| C |
| A |
| B |
| C |
| B |
| C |
| C |
| |
| [case testIsInstance] |
| from typing import Optional |
| class X: pass |
| class A(X): pass |
| class B(A): pass |
| |
| def isa(x: object) -> bool: |
| return isinstance(x, A) |
| def isint(x: object) -> bool: |
| return isinstance(x, int) |
| def isstr(x: object) -> bool: |
| return isinstance(x, str) |
| def islist(x: object) -> bool: |
| return isinstance(x, list) |
| def ist(x: object, t: object) -> bool: # TODO: Second argument should be 'type' |
| return isinstance(x, t) |
| def pointless(x: Optional[X]) -> str: |
| if isinstance(x, A): |
| return str(x) |
| return '' |
| [file driver.py] |
| from native import X, A, B, isa, isint, isstr, islist, ist |
| assert isa(1) == False |
| assert isa(A()) == True |
| assert isa(B()) == True |
| assert isa(X()) == False |
| |
| assert isint(1) == True |
| assert isint('') == False |
| assert isint(A()) == False |
| |
| assert isstr(1) == False |
| assert isstr('') == True |
| |
| assert islist(1) == False |
| assert islist([]) == True |
| |
| assert ist(1, int) == True |
| assert ist(1, str) == False |
| try: |
| ist(1, 2) |
| except TypeError: |
| pass |
| else: |
| assert False |
| |
| [case testSubclassUninitAttr] |
| class X: |
| x: int |
| class A(X): |
| pass |
| [file driver.py] |
| import traceback |
| from native import A |
| try: |
| A().x |
| except AttributeError: |
| traceback.print_exc() |
| [out] |
| Traceback (most recent call last): |
| File "driver.py", line 4, in <module> |
| A().x |
| AttributeError: attribute 'x' of 'X' undefined |
| |
| [case testClassMethods] |
| MYPY = False |
| if MYPY: |
| from typing import ClassVar |
| class C: |
| lurr: 'ClassVar[int]' = 9 |
| @staticmethod |
| def foo(x: int) -> int: return 10 + x |
| @classmethod |
| def bar(cls, x: int) -> int: return cls.lurr + x |
| @staticmethod |
| def baz(x: int, y: int = 10) -> int: return y - x |
| @classmethod |
| def quux(cls, x: int, y: int = 10) -> int: return y - x |
| |
| class D(C): |
| def f(self) -> int: |
| return super().foo(1) + super().bar(2) + super().baz(10) + super().quux(10) |
| |
| def test1() -> int: |
| return C.foo(1) + C.bar(2) + C.baz(10) + C.quux(10) + C.quux(y=10, x=9) |
| def test2() -> int: |
| c = C() |
| return c.foo(1) + c.bar(2) + c.baz(10) |
| [file driver.py] |
| from native import * |
| assert C.foo(10) == 20 |
| assert C.bar(10) == 19 |
| c = C() |
| assert c.foo(10) == 20 |
| assert c.bar(10) == 19 |
| |
| assert test1() == 23 |
| assert test2() == 22 |
| |
| d = D() |
| assert d.f() == 22 |
| |
| [case testSuper] |
| from mypy_extensions import trait |
| from typing import List |
| |
| 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 |
| class C(B): |
| def __init__(self, x: int, y: int) -> None: |
| init = super(C, self).__init__ |
| init(x, y+1) |
| |
| class X: |
| def __init__(self, x: int) -> None: |
| self.x = x |
| class Y(X): |
| pass |
| class Z(Y): |
| def __init__(self, x: int, y: int) -> None: |
| super().__init__(x) |
| self.y = y |
| |
| @trait |
| class T: |
| def v_int(self, x: int) -> None: pass |
| def v_list(self, x: List[int]) -> None: |
| if x: |
| self.v_int(x[0]) |
| self.v_list(x[1:]) |
| |
| class PrintList(T): |
| def v_int(self, x: int) -> None: |
| print(x) |
| def v_list(self, x: List[int]) -> None: |
| print('yo!') |
| super().v_list(x) |
| |
| [file driver.py] |
| import traceback |
| from native import * |
| b = B(10, 20) |
| assert b.x == 10 and b.y == 20 |
| c = C(10, 20) |
| assert c.x == 10 and c.y == 21 |
| z = Z(10, 20) |
| assert z.x == 10 and z.y == 20 |
| |
| PrintList().v_list([1,2,3]) |
| [out] |
| yo! |
| 1 |
| yo! |
| 2 |
| yo! |
| 3 |
| yo! |
| |
| [case testSubclassException] |
| class Failure(Exception): |
| def __init__(self, x: int) -> None: |
| self.x = x |
| |
| def foo() -> None: |
| raise Failure(10) |
| |
| def heyo() -> int: |
| try: |
| foo() |
| except Failure as e: |
| return e.x |
| return -1 |
| |
| [file driver.py] |
| from native import foo, heyo, Failure |
| try: |
| foo() |
| except Failure as e: |
| assert str(e) == '10' |
| assert e.x == 10 |
| heyo() |
| |
| [case testSubclassDict] |
| from typing import Dict |
| class WelpDict(Dict[str, int]): |
| def __init__(self) -> None: |
| self.emarhavil = 3 |
| def foo(self) -> int: |
| return self.emarhavil |
| |
| def welp() -> int: |
| x = WelpDict() |
| x['a'] = 10 |
| x['b'] = 15 |
| x.emarhavil = 5 |
| return x['a'] + x['b'] + x.emarhavil + x.foo() |
| |
| [file driver.py] |
| from native import welp |
| assert welp() == 35 |
| |
| [case testSubclassPy] |
| from b import B, V |
| class A(B): |
| def __init__(self, x: int, y: int) -> None: |
| super().__init__(y) |
| self.x = x |
| |
| def foo(self, x: int) -> int: |
| print("hi", x) |
| return x+1 |
| |
| class C(V[int]): |
| def f(self) -> int: return 10 |
| |
| assert isinstance(C(), V) |
| |
| def f(x: A) -> None: |
| print(x.x) |
| print(x.y) |
| print(x.foo(20)) |
| |
| [file b.py] |
| from typing import Generic, TypeVar |
| T = TypeVar('T') |
| |
| class B: |
| def __init__(self, y: int) -> None: |
| self.y = y |
| def foo(self, x: int) -> int: |
| print("parent!") |
| return x + self.y |
| def bar(self) -> None: |
| print("hello!", self.y) |
| |
| class V(Generic[T]): |
| def f(self) -> T: |
| raise Exception('unimplemented') |
| [file driver.py] |
| import native |
| a = native.A(10, 20) |
| a.foo(10) |
| a.bar() |
| native.f(a) |
| [out] |
| hi 10 |
| hello! 20 |
| 10 |
| 20 |
| hi 20 |
| 21 |
| |
| [case testDisallowSubclassFromPy] |
| # We'll want to allow this at some point but right now we need to |
| # disallow it because it doesn't work. |
| class A: |
| pass |
| [file b.py] |
| from native import A |
| |
| # It would be better if we disallowed it at class decl time but it is |
| # really easy to do in __new__ |
| |
| class B(A): |
| pass |
| |
| [file driver.py] |
| from b import B |
| try: |
| B() |
| except TypeError: |
| pass |
| else: |
| assert False, "instantiating was supposed to fail" |
| |
| [case testClassVariable] |
| MYPY = False |
| if MYPY: |
| from typing import ClassVar |
| class A: |
| x = 10 # type: ClassVar[int] |
| |
| def g(x: int) -> None: |
| A.x = 10 |
| def f() -> int: |
| return A.x |
| [file driver.py] |
| from native import A, f |
| assert f() == 10 |
| A.x = 200 |
| assert f() == 200 |
| |
| [case testDefaultVars] |
| from typing import Optional |
| class A: |
| x = 10 |
| w: object = 10 |
| def lol(self) -> None: |
| self.x = 100 |
| |
| LOL = 'lol' |
| class B(A): |
| y = LOL |
| z = None # type: Optional[str] |
| b = True |
| bogus = None # type: int |
| |
| def g() -> None: |
| a = A() |
| assert a.x == 10 |
| a.x = 20 |
| assert a.x == 20 |
| b = B() |
| assert b.x == 10 |
| b.x = 20 |
| assert b.x == 20 |
| assert b.y == 'lol' |
| b.y = 'rofl' |
| assert b.y == 'rofl' |
| assert b.z is None |
| [file driver.py] |
| from native import * |
| g() |
| |
| a = A() |
| assert a.x == 10 |
| a.x = 20 |
| assert a.x == 20 |
| b = B() |
| assert b.x == 10 |
| b.x = 20 |
| assert b.x == 20 |
| assert b.y == 'lol' |
| b.y = 'rofl' |
| assert b.y == 'rofl' |
| assert b.z is None |
| # N.B: this doesn't match cpython |
| assert not hasattr(b, 'bogus') |
| |
| [case testMethodOverrideDefault1] |
| class A: |
| def foo(self, x: int) -> None: |
| pass |
| class B(A): |
| def foo(self, x: int, y: int = 10) -> None: |
| print(x, y) |
| |
| def a(x: A) -> None: |
| x.foo(1) |
| def b(x: B) -> None: |
| x.foo(2) |
| x.foo(2, 3) |
| |
| [file driver.py] |
| from native import B, a, b |
| a(B()) |
| b(B()) |
| [out] |
| 1 10 |
| 2 10 |
| 2 3 |
| |
| [case testMethodOverrideDefault2] |
| class A: |
| def foo(self, *, x: int = 0) -> None: |
| pass |
| def bar(self, *, x: int = 0, y: int = 0) -> None: |
| pass |
| def baz(self, x: int = 0) -> None: |
| pass |
| class B(A): |
| def foo(self, *, y: int = 0, x: int = 0) -> None: |
| print(x, y) |
| def bar(self, *, y: int = 0, x: int = 0) -> None: |
| print(x, y) |
| def baz(self, x: int = 0, *, y: int = 0) -> None: |
| print(x, y) |
| |
| def a(x: A) -> None: |
| x.foo(x=1) |
| x.bar(x=1, y=2) |
| x.bar(x=2, y=1) |
| x.baz() |
| x.baz(1) |
| x.baz(x=2) |
| |
| [file driver.py] |
| from native import B, a |
| a(B()) |
| [out] |
| 1 0 |
| 1 2 |
| 2 1 |
| 0 0 |
| 1 0 |
| 2 0 |
| |
| [case testMethodOverrideDefault3] |
| class A: |
| @classmethod |
| def foo(cls, *, x: int = 0) -> None: |
| pass |
| @staticmethod |
| def bar(*, x: int = 0) -> None: |
| pass |
| @staticmethod |
| def baz() -> object: |
| pass |
| class B(A): |
| @classmethod |
| def foo(cls, *, y: int = 0, x: int = 0) -> None: |
| print(x, y) |
| print(cls.__name__) # type: ignore |
| @staticmethod |
| def bar(*, y: int = 0, x: int = 0) -> None: |
| print(x, y) |
| @staticmethod |
| def baz() -> int: |
| return 10 |
| |
| # This is just to make sure that this stuff works even when the |
| # methods might be overriden. |
| class C(B): |
| @classmethod |
| def foo(cls, *, y: int = 0, x: int = 0) -> None: |
| pass |
| @staticmethod |
| def bar(*, y: int = 0, x: int = 0) -> None: |
| pass |
| @staticmethod |
| def baz() -> int: |
| return 10 |
| |
| def a(x: A) -> None: |
| x.foo(x=1) |
| x.bar(x=1) |
| print(x.baz()) |
| |
| [file driver.py] |
| from native import B, a |
| a(B()) |
| [out] |
| 1 0 |
| B |
| 1 0 |
| 10 |
| |
| [case testOverride] |
| class A: |
| def f(self) -> int: |
| return 0 |
| def g(self) -> int: |
| return 1 |
| |
| class B(A): |
| def g(self) -> int: |
| return 2 |
| |
| class C(B): |
| def f(self) -> int: |
| return 3 |
| |
| def test() -> None: |
| ba: A = B() |
| ca: A = C() |
| assert ba.f() == 0 |
| assert ba.g() == 2 |
| assert ca.f() == 3 |
| assert ca.g() == 2 |
| cc = C() |
| assert cc.f() == 3 |
| assert cc.g() == 2 |
| print('ok') |
| [file driver.py] |
| import native |
| native.test() |
| [out] |
| ok |
| |
| [case testNoMetaclass] |
| from foo import Base |
| |
| class Nothing(Base): # type: ignore |
| pass |
| |
| [file foo.py] |
| from typing import Any |
| class Meta(type): |
| pass |
| |
| class _Base(metaclass=Meta): |
| pass |
| Base = _Base # type: Any |
| |
| [file driver.py] |
| try: |
| import native |
| except TypeError as e: |
| assert(str(e) == "mypyc classes can't have a metaclass") |
| |
| [case testPickling] |
| from mypy_extensions import trait |
| from typing import Any, TypeVar, Generic |
| |
| def dec(x: Any) -> Any: |
| return x |
| |
| class A: |
| x: int |
| y: str |
| |
| class B(A): |
| z: bool |
| |
| def __init__(self, x: int, y: str, z: bool) -> None: |
| self.x = x |
| self.y = y |
| self.z = z |
| |
| @trait |
| class T: |
| a: str |
| |
| class C(B, T): |
| w: object |
| |
| # property shouldn't go in |
| @property |
| def foo(self) -> int: |
| return 0 |
| |
| @dec |
| class D: |
| x: int |
| |
| class E(D): |
| y: int |
| |
| |
| U = TypeVar('U') |
| |
| class F(Generic[U]): |
| y: int |
| |
| class G(F[int]): |
| pass |
| |
| [file driver.py] |
| from native import A, B, T, C, D, E, F, G |
| |
| import copy |
| import pickle |
| |
| assert A.__mypyc_attrs__ == ('x', 'y') |
| assert B.__mypyc_attrs__ == ('z', 'x', 'y') |
| assert T.__mypyc_attrs__ == ('a',) |
| assert C.__mypyc_attrs__ == ('w', 'z', 'x', 'y', 'a') |
| assert not hasattr(D, '__mypyc_attrs__') |
| assert E.__mypyc_attrs__ == ('y', '__dict__') |
| assert F.__mypyc_attrs__ == ('y', '__dict__') |
| assert G.__mypyc_attrs__ == ('y', '__dict__') |
| |
| b = B(10, '20', False) |
| assert b.__getstate__() == {'z': False, 'x': 10, 'y': '20'} |
| b2 = copy.copy(b) |
| assert b is not b2 and b.y == b2.y |
| |
| b3 = pickle.loads(pickle.dumps(b)) |
| assert b is not b3 and b.y == b3.y |
| |
| e = E() |
| e.x = 10 |
| e.y = 20 |
| |
| assert e.__getstate__() == {'y': 20, '__dict__': {'x': 10}} |
| e2 = pickle.loads(pickle.dumps(e)) |
| assert e is not e2 and e.x == e2.x and e.y == e2.y |
| |
| |
| [case testInterpretedParentInit] |
| from interp import C |
| from typing import TypeVar |
| |
| T = TypeVar('T') |
| |
| def dec(x: T) -> T: |
| return x |
| |
| @dec |
| class A: |
| def __init__(self, x: int) -> None: |
| self.x = x |
| |
| class B(A): |
| s = 'test' |
| |
| def b(x: int) -> B: return B(x) |
| |
| class D(C): |
| s = 'test' |
| |
| def d(x: int) -> D: return D(x) |
| |
| |
| [file interp.py] |
| class C: |
| def __init__(self, x: int) -> None: |
| self.x = x |
| |
| [file driver.py] |
| from native import b, d, B, D |
| |
| def test(f, v): |
| x = f(v) |
| assert x.x == v |
| assert x.s == 'test' |
| |
| test(b, 20) |
| test(d, 30) |
| test(B, -1) |
| test(D, -2) |