/
eb
/
python_learn
Обзор
Документация
Войти
/
eb
/
python_learn
Код
Запросы
0
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
main
venv/Lib/site-packages/mypyc/test-data/run-classes.test
1 770 строк
34 KB
EvgeniyBudaev
Улучшения в системе type hints
01 мар 2021, 16:52
01 мар 2021, 16:52
e4c1f6e
Код
Авторство
О чём код?
[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 testNonExtMisc] from typing import Any, overload def decorator(cls) -> Any: return cls @decorator class C: def __init__(self) -> None: self.c = 3 def get_c(self) -> int: return self.c @decorator 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 @decorator class Overload: @overload def get(self, index: int) -> int: ... @overload def get(self, index: str) -> str: ... def get(self, index: Any) -> Any: return index def get(c: Overload, s: str) -> str: return c.get(s) [file driver.py] from native import A, Overload, get 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 o = Overload() assert get(o, "test") == "test" assert o.get(20) == 20 [case testEnum] from enum import Enum class TestEnum(Enum): _order_ = "a b" 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] import sys # "_order_" isn't supported in 3.5 if sys.version_info[:2] > (3, 5): 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 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, Sequence 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 # Test subclassing generic classes both with and without a generic param class A(Sequence[int]): pass class B(Sequence[T]): pass 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 def foo(self, x: int) -> int: return x class B(A): def __init__(self, x: int, y: int) -> None: super().__init__(x) self.y = y def foo(self, x: int) -> int: return super().foo(x+1) class C(B): def __init__(self, x: int, y: int) -> None: init = super(C, self).__init__ init(x, y+1) def foo(self, x: int) -> int: # should go to A, not B return super(B, self).foo(x+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 assert c.foo(10) == 11 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 testProtocol] from typing_extensions import Protocol class Proto(Protocol): def foo(self, x: int) -> None: pass def bar(self, x: int) -> None: pass class A: def foo(self, x: int) -> None: print("A:", x) def bar(self, *args: int, **kwargs: int) -> None: print("A:", args, kwargs) class B(A, Proto): def foo(self, x: int) -> None: print("B:", x) def bar(self, *args: int, **kwargs: int) -> None: print("B:", args, kwargs) def f(x: Proto) -> None: x.foo(20) x.bar(x=20) [file driver.py] from native import A, B, f f(A()) f(B()) # ... this exploits a bug in glue methods to distinguish whether we # are making a direct call or a pycall... [out] A: 20 A: () {'x': 20} B: 20 B: (20,) {} [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 overridden. 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 testMetaclass] from meta import Meta import six class Nothing1(metaclass=Meta): pass def ident(x): return x @ident class Test: pass class Nothing2(six.with_metaclass(Meta, Test)): pass @six.add_metaclass(Meta) class Nothing3: pass [file meta.py] from typing import Any class Meta(type): def __new__(mcs, name, bases, dct): dct['X'] = 10 return super().__new__(mcs, name, bases, dct) [file driver.py] from native import Nothing1, Nothing2, Nothing3 assert Nothing1.X == 10 assert Nothing2.X == 10 assert Nothing3.X == 10 [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) [case testInterpretedInherit] from typing import TypeVar, Any, overload from mypy_extensions import mypyc_attr, trait T = TypeVar('T') def dec(x: T) -> T: return x @mypyc_attr(allow_interpreted_subclasses=True) class Top: def spam(self) -> str: return "grandparent" @mypyc_attr(allow_interpreted_subclasses=True) @trait class Trait: def trait_method(self) -> str: return "trait" @mypyc_attr(allow_interpreted_subclasses=True) class Foo(Top, Trait): def __init__(self, x: int) -> None: self.x = x def foo(self) -> str: return "parent foo: " + self.bar(self.x) def bar(self, x: int) -> str: return "parent bar: {}".format(x + self.x) @dec def decorated(self) -> str: return "decorated parent" @property def read_property(self) -> str: return "parent prop" @overload def overloaded(self, index: int) -> int: ... @overload def overloaded(self, index: str) -> str: ... def overloaded(self, index: Any) -> Any: return index def foo(x: Foo) -> str: return x.foo() def bar(x: Foo, y: int) -> str: return x.bar(y) def spam(x: Top) -> str: return x.spam() def decorated(x: Foo) -> str: return x.decorated() def prop(x: Foo) -> str: return x.read_property def trait_method(x: Trait) -> str: return x.trait_method() def overloaded(x: Foo, s: str) -> str: return x.overloaded(s) [file interp.py] from typing import Any from native import Foo class Bar(Foo): def bar(self, x: int) -> str: return "child bar: {}".format(x + self.x) def spam(self) -> str: assert super().spam() == "grandparent" return "child" @property def read_property(self) -> str: return "child prop" def decorated(self) -> str: return "decorated child" def trait_method(self) -> str: return "child" def overloaded(self, index: Any) -> Any: return index + index class InterpBase: def eggs(self) -> str: return "eggs" class Baz(InterpBase, Bar): def __init__(self) -> None: super().__init__(1000) self.z = self.read_property [file driver.py] from native import Foo, foo, bar, spam, decorated, overloaded, prop, trait_method from interp import Bar, Baz from unittest.mock import patch from testutil import assertRaises x = Foo(10) y = Bar(20) z = Baz() assert isinstance(y, Bar) assert y.x == 20 assert y.bar(10) == "child bar: 30" assert y.foo() == "parent foo: child bar: 40" assert foo(y) == "parent foo: child bar: 40" assert bar(y, 30) == "child bar: 50" y.x = 30 assert bar(y, 30) == "child bar: 60" assert spam(y) == "child" assert y.read_property == "child prop" assert prop(x) == "parent prop" assert prop(y) == "child prop" assert y.decorated() == "decorated child" assert decorated(y) == "decorated child" assert y.overloaded("test") == "testtest" assert overloaded(y, "test") == "testtest" assert y.trait_method() == "child" assert trait_method(y) == "child" assert z.bar(10) == "child bar: 1010" assert bar(z, 10) == "child bar: 1010" assert z.z == "child prop" assert z.eggs() == "eggs" with patch("interp.Bar.spam", lambda self: "monkey patched"): assert y.spam() == "monkey patched" spam(y) == "monkey patched" with patch("interp.Bar.spam", lambda self: 20): assert y.spam() == 20 with assertRaises(TypeError, "str object expected; got int"): spam(y) with assertRaises(TypeError, "int object expected; got str"): y.x = "test" [case testProperty] from typing import Callable from mypy_extensions import trait class Temperature: @property def celsius(self) -> float: return 5.0 * (self.farenheit - 32.0) / 9.0 def __init__(self, farenheit: float) -> None: self.farenheit = farenheit def print_temp(self) -> None: print("F:", self.farenheit, "C:", self.celsius) @property def rankine(self) -> float: raise NotImplementedError class Access: @property def number_of_accesses(self) -> int: self._count += 1 return self._count def __init__(self) -> None: self._count = 0 from typing import Callable class BaseProperty: @property def doc(self) -> str: return "Represents a sequence of values. Updates itself by next, which is a new value." @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 def __init__(self, incr_func: Callable[[int], int], value: int) -> None: BaseProperty.__init__(self, value) self._incr_func = incr_func @property def next(self) -> DerivedProperty: return DerivedProperty(self._incr_func, self._incr_func(self.value)) 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 def print_first_n(n: int, thing: BaseProperty) -> None: vals = [] cur_thing = thing for _ in range(n): vals.append(cur_thing.value) cur_thing = cur_thing.next print ('', vals) @trait class Trait: @property def value(self) -> int: return 3 class Printer(Trait): def print_value(self) -> None: print(self.value) [file driver.py] from native import Temperature, Access import traceback x = Temperature(32.0) try: print (x.rankine) except NotImplementedError as e: traceback.print_exc() print (x.celsius) x.print_temp() y = Temperature(212.0) print (y.celsius) y.print_temp() z = Access() print (z.number_of_accesses) print (z.number_of_accesses) print (z.number_of_accesses) print (z.number_of_accesses) from native import BaseProperty, DerivedProperty, AgainProperty, print_first_n a = BaseProperty(7) b = DerivedProperty((lambda x: x // 2 if (x % 2 == 0) else 3 * x + 1), 7) c = AgainProperty((lambda x: x // 2 if (x % 2 == 0) else 3 * x + 1), 7) def py_print_first_n(n: int, thing: BaseProperty) -> None: vals = [] cur_thing = thing for _ in range(n): vals.append(cur_thing.value) cur_thing = cur_thing.next print ('', vals) py_print_first_n(20, a) py_print_first_n(20, b) py_print_first_n(20, c) print(a.next.next.next.bad_value) print(b.next.next.next.bad_value) print(c.next.next.next.bad_value) print_first_n(20, a) print_first_n(20, b) print_first_n(20, c) print (a.doc) print (b.doc) print (c.doc) from native import Printer Printer().print_value() print (Printer().value) [out] Traceback (most recent call last): File "driver.py", line 5, in <module> print (x.rankine) File "native.py", line 16, in rankine raise NotImplementedError NotImplementedError 0.0 F: 32.0 C: 0.0 100.0 F: 212.0 C: 100.0 1 2 3 4 [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26] [7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1, 4, 2, 1] [7, 11, 17, 26, 40, 10, 16, 4, 1, 2, 4, 1, 2, 4, 1, 2, 4, 1, 2, 4] 10 34 26 [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26] [7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1, 4, 2, 1] [7, 11, 17, 26, 40, 10, 16, 4, 1, 2, 4, 1, 2, 4, 1, 2, 4, 1, 2, 4] Represents a sequence of values. Updates itself by next, which is a new value. Represents a sequence of values. Updates itself by next, which is a new value. Represents a sequence of values. Updates itself by next, which is a new value. 3 3 [case testPropertySetters] from mypy_extensions import trait class Foo(): def __init__(self) -> None: self.attr = "unmodified" class A: def __init__(self) -> None: self._x = 0 self._foo = Foo() @property def x(self) -> int: return self._x @x.setter def x(self, val : int) -> None: self._x = val @property def foo(self) -> Foo: return self._foo @foo.setter def foo(self, val : Foo) -> None: self._foo = val # Overrides base property setters and getters class B(A): def __init__(self) -> None: self._x = 10 @property def x(self) -> int: return self._x + 1 @x.setter def x(self, val : int) -> None: self._x = val + 1 #Inerits base property setters and getters class C(A): def __init__(self) -> None: A.__init__(self) @trait class D(): def __init__(self) -> None: self._x = 0 @property def x(self) -> int: return self._x @x.setter def x(self, val : int) -> None: self._x = val #Inherits trait property setters and getters class E(D): def __init__(self) -> None: D.__init__(self) #Overrides trait property setters and getters class F(D): def __init__(self) -> None: self._x = 10 @property def x(self) -> int: return self._x + 10 @x.setter def x(self, val : int) -> None: self._x = val + 10 # # Property setter and getter are subtypes of base property setters and getters # # class G(A): # # def __init__(self) -> None: # # A.__init__(self) # # @property # # def y(self) -> int: # # return self._y # # @y.setter # # def y(self, val : object) -> None: # # self._y = val [file other.py] # Run in both interpreted and compiled mode from native import A, B, C, D, E, F a = A() assert a.x == 0 assert a._x == 0 a.x = 1 assert a.x == 1 assert a._x == 1 a._x = 0 assert a.x == 0 assert a._x == 0 b = B() assert b.x == 11 assert b._x == 10 b.x = 11 assert b.x == 13 b._x = 11 assert b.x == 12 c = C() assert c.x == 0 c.x = 1000 assert c.x == 1000 e = E() assert e.x == 0 e.x = 1000 assert e.x == 1000 f = F() assert f.x == 20 f.x = 30 assert f.x == 50 [file driver.py] # Run the tests in both interpreted and compiled mode import other import other_interpreted [out] [case testSubclassAttributeAccess] from mypy_extensions import trait class A: v = 0 class B(A): v = 1 class C(B): v = 2 [file driver.py] from native import A, B, C a = A() b = B() c = C()