[case testTraitBasic1] from mypy_extensions import trait class A: line: int def foo(self) -> None: print("foo") @trait class T: def bar(self) -> None: print("bar") def baz(self) -> object: return None class C(A, T): def baz(self) -> int: return 10 def use_t(t: T) -> object: t.bar() return t.baz() def use_c(c: C) -> int: use_t(c) c.foo() c.bar() return c.baz() use_t(C()) # This trait is dead code but there's no reason it shouldn't compile @trait class ChildlessTrait: def __init__(self) -> None: pass [file driver.py] from native import A, T, C, use_c, use_t c = C() c.foo() c.bar() assert c.baz() == 10 assert use_c(c) == 10 assert use_t(c) == 10 [out] bar foo bar bar foo bar bar [case testTraitBasic2] from mypy_extensions import trait class A: line: int def foo(self) -> None: print("foo") @trait class T: def bar(self) -> None: print("bar", self.baz()) def baz(self) -> int: return -1 @trait class T2: line: int def baz(self) -> int: return -2 class C(A, T): def __init__(self) -> None: self.line = 1337 self.x = 12 def baz(self) -> int: return self.x class D(C, T2): def __init__(self) -> None: self.line = 1337 self.x = 13 @trait class T3: def baz(self) -> int: return -2 class E(T3): def __init__(self) -> None: pass def use_t(t: T) -> None: t.bar() def use_t2(t: T2) -> int: t.line = t.line return t.line def use_c(c: C) -> int: use_t(c) c.foo() c.bar() return c.line def use_d(d: D) -> int: return d.baz() [file driver.py] from native import A, T, C, D, use_c, use_t, use_d, use_t2 c = C() d = D() c.foo() c.bar() print("baz", c.baz()) print("baz", d.baz()) use_c(c) use_t(c) use_c(d) use_t(d) assert use_d(d) == 13 print(d.line) assert d.line == 1337 assert use_t2(d) == 1337 [out] foo bar 12 baz 12 baz 13 bar 12 foo bar 12 bar 12 bar 13 foo bar 13 bar 13 1337 [case testTrait3] from mypy_extensions import trait from typing import Generic, TypeVar @trait class T1: pass @trait class T2: pass T = TypeVar('T') class C(Generic[T], T1, T2): pass @trait class S1(Generic[T]): def foo(self) -> None: pass def bar(self, x: T) -> T: raise Exception @trait class S2(S1[T]): def bar(self, x: T) -> T: return x @trait class S3(S2[T]): def bar(self, x: T) -> T: return x class D(S3[bool]): def bar(self, x: bool) -> bool: return x [file driver.py] import native [case testTrait4] from mypy_extensions import trait from typing import Generic, TypeVar T = TypeVar('T') @trait class S1(Generic[T]): def bar(self) -> T: raise Exception class S2(S1[bool]): def bar(self) -> bool: return False class D(S2): pass def lol(x: S1) -> None: x.bar() [file driver.py] import native native.lol(native.D()) [case testTraitOrdering] import other_b # Regression test for a bug where inheriting from a class that # inherited from a trait that got processed later on the command line # filed to compile. [file other_b.py] from other_c import Plugin class Whatever(Plugin): pass [file other_c.py] from mypy_extensions import trait @trait class Base: x = None # type: int class Plugin(Base): def __init__(self) -> None: self.x = 10 [file driver.py] from native import * [case testDiamond] from mypy_extensions import trait @trait class Base: def get_value(self) -> str: return "Base" @trait class Trait(Base): def get_value(self) -> str: return "Trait" class Message(Base): def show_message(self) -> None: print("I am a " + self.get_value()) class DerivedMessage(Message, Trait): pass [file driver.py] from native import * a = Message() a.show_message() b = DerivedMessage() b.show_message() [out] I am a Base I am a Trait [case testTraitAttrsSubTrait] from mypy_extensions import trait class A: a: int @trait class T1: x: int @trait class T2(T1): y: int class C(A, T2): c: int def f(t1: T1, t2: T2) -> None: t1.x, t2.x = t2.x, t1.x def g(t1: T1, t2: T2) -> None: t2.y = t1.x def get_x(c: C) -> int: return c.x def get_y(c: C) -> int: return c.y [file driver.py] from native import C, f, g, get_x, get_y c1 = C() c2 = C() c1.x = 1 c1.y = 0 c2.x = 2 c2.y = 0 f(c1, c2) assert c1.x == 2 assert c2.x == 1 assert get_x(c1) == 2 assert get_x(c2) == 1 assert get_y(c2) == 0 g(c1, c2) assert get_y(c2) == 2 [out] [case testTraitAttrsTriangle] from mypy_extensions import trait class A: a: int @trait class T(A): x: int def meth(self) -> int: return self.a class B(A): b: int class C(B, T): pass def take_t(t: T) -> int: return t.x + t.meth() def take_c(c: C) -> int: return c.x + c.meth() [file driver.py] from native import C, take_t, take_c c = C() c.a = 1 c.x = 10 assert take_t(c) == take_c(c) == 11 [out] [case testTraitAttrsTree] from mypy_extensions import trait class A: a: int @trait class T1: x: int class B(A, T1): b: int @trait class T2: x: int class C(B, T2): pass def f(t1: T1, t2: T2) -> None: t1.x, t2.x = t2.x, t1.x def g(c1: C, c2: C) -> None: c1.x, c2.x = c2.x, c1.x [file driver.py] from native import C, f, g c1 = C() c2 = C() c1.x = 1 c2.x = 2 f(c1, c2) assert c1.x == 2 assert c2.x == 1 g(c1, c2) assert c1.x == 1 assert c2.x == 2 [out] [case testTraitErrorMessages] from mypy_extensions import trait @trait class Trait: pass def create() -> Trait: return Trait() [file driver.py] from native import Trait, create from testutil import assertRaises with assertRaises(TypeError, "traits may not be directly created"): Trait() with assertRaises(TypeError, "traits may not be directly created"): create() class Sub(Trait): pass with assertRaises(TypeError, "interpreted classes cannot inherit from compiled traits"): Sub()