run-traits.test 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. [case testTraitBasic1]
  2. from mypy_extensions import trait
  3. class A:
  4. line: int
  5. def foo(self) -> None:
  6. print("foo")
  7. @trait
  8. class T:
  9. def bar(self) -> None:
  10. print("bar")
  11. def baz(self) -> object:
  12. return None
  13. class C(A, T):
  14. def baz(self) -> int:
  15. return 10
  16. def use_t(t: T) -> object:
  17. t.bar()
  18. return t.baz()
  19. def use_c(c: C) -> int:
  20. use_t(c)
  21. c.foo()
  22. c.bar()
  23. return c.baz()
  24. use_t(C())
  25. # This trait is dead code but there's no reason it shouldn't compile
  26. @trait
  27. class ChildlessTrait:
  28. def __init__(self) -> None:
  29. pass
  30. [file driver.py]
  31. from native import A, T, C, use_c, use_t
  32. c = C()
  33. c.foo()
  34. c.bar()
  35. assert c.baz() == 10
  36. assert use_c(c) == 10
  37. assert use_t(c) == 10
  38. [out]
  39. bar
  40. foo
  41. bar
  42. bar
  43. foo
  44. bar
  45. bar
  46. [case testTraitBasic2]
  47. from mypy_extensions import trait
  48. class A:
  49. line: int
  50. def foo(self) -> None:
  51. print("foo")
  52. @trait
  53. class T:
  54. def bar(self) -> None:
  55. print("bar", self.baz())
  56. def baz(self) -> int:
  57. return -1
  58. @trait
  59. class T2:
  60. line: int
  61. def baz(self) -> int:
  62. return -2
  63. class C(A, T):
  64. def __init__(self) -> None:
  65. self.line = 1337
  66. self.x = 12
  67. def baz(self) -> int:
  68. return self.x
  69. class D(C, T2):
  70. def __init__(self) -> None:
  71. self.line = 1337
  72. self.x = 13
  73. @trait
  74. class T3:
  75. def baz(self) -> int:
  76. return -2
  77. class E(T3):
  78. def __init__(self) -> None:
  79. pass
  80. def use_t(t: T) -> None:
  81. t.bar()
  82. def use_t2(t: T2) -> int:
  83. t.line = t.line
  84. return t.line
  85. def use_c(c: C) -> int:
  86. use_t(c)
  87. c.foo()
  88. c.bar()
  89. return c.line
  90. def use_d(d: D) -> int:
  91. return d.baz()
  92. [file driver.py]
  93. from native import A, T, C, D, use_c, use_t, use_d, use_t2
  94. c = C()
  95. d = D()
  96. c.foo()
  97. c.bar()
  98. print("baz", c.baz())
  99. print("baz", d.baz())
  100. use_c(c)
  101. use_t(c)
  102. use_c(d)
  103. use_t(d)
  104. assert use_d(d) == 13
  105. print(d.line)
  106. assert d.line == 1337
  107. assert use_t2(d) == 1337
  108. [out]
  109. foo
  110. bar 12
  111. baz 12
  112. baz 13
  113. bar 12
  114. foo
  115. bar 12
  116. bar 12
  117. bar 13
  118. foo
  119. bar 13
  120. bar 13
  121. 1337
  122. [case testTrait3]
  123. from mypy_extensions import trait
  124. from typing import Generic, TypeVar
  125. @trait
  126. class T1: pass
  127. @trait
  128. class T2: pass
  129. T = TypeVar('T')
  130. class C(Generic[T], T1, T2):
  131. pass
  132. @trait
  133. class S1(Generic[T]):
  134. def foo(self) -> None: pass
  135. def bar(self, x: T) -> T: raise Exception
  136. @trait
  137. class S2(S1[T]):
  138. def bar(self, x: T) -> T: return x
  139. @trait
  140. class S3(S2[T]):
  141. def bar(self, x: T) -> T: return x
  142. class D(S3[bool]):
  143. def bar(self, x: bool) -> bool: return x
  144. [file driver.py]
  145. import native
  146. [case testTrait4]
  147. from mypy_extensions import trait
  148. from typing import Generic, TypeVar
  149. T = TypeVar('T')
  150. @trait
  151. class S1(Generic[T]):
  152. def bar(self) -> T: raise Exception
  153. class S2(S1[bool]):
  154. def bar(self) -> bool: return False
  155. class D(S2):
  156. pass
  157. def lol(x: S1) -> None:
  158. x.bar()
  159. [file driver.py]
  160. import native
  161. native.lol(native.D())
  162. [case testTraitOrdering]
  163. import other_b
  164. # Regression test for a bug where inheriting from a class that
  165. # inherited from a trait that got processed later on the command line
  166. # filed to compile.
  167. [file other_b.py]
  168. from other_c import Plugin
  169. class Whatever(Plugin):
  170. pass
  171. [file other_c.py]
  172. from mypy_extensions import trait
  173. @trait
  174. class Base:
  175. x = None # type: int
  176. class Plugin(Base):
  177. def __init__(self) -> None:
  178. self.x = 10
  179. [file driver.py]
  180. from native import *
  181. [case testDiamond]
  182. from mypy_extensions import trait
  183. @trait
  184. class Base:
  185. def get_value(self) -> str:
  186. return "Base"
  187. @trait
  188. class Trait(Base):
  189. def get_value(self) -> str:
  190. return "Trait"
  191. class Message(Base):
  192. def show_message(self) -> None:
  193. print("I am a " + self.get_value())
  194. class DerivedMessage(Message, Trait):
  195. pass
  196. [file driver.py]
  197. from native import *
  198. a = Message()
  199. a.show_message()
  200. b = DerivedMessage()
  201. b.show_message()
  202. [out]
  203. I am a Base
  204. I am a Trait
  205. [case testTraitAttrsSubTrait]
  206. from mypy_extensions import trait
  207. class A:
  208. a: int
  209. @trait
  210. class T1:
  211. x: int
  212. @trait
  213. class T2(T1):
  214. y: int
  215. class C(A, T2):
  216. c: int
  217. def f(t1: T1, t2: T2) -> None:
  218. t1.x, t2.x = t2.x, t1.x
  219. def g(t1: T1, t2: T2) -> None:
  220. t2.y = t1.x
  221. def get_x(c: C) -> int:
  222. return c.x
  223. def get_y(c: C) -> int:
  224. return c.y
  225. [file driver.py]
  226. from native import C, f, g, get_x, get_y
  227. c1 = C()
  228. c2 = C()
  229. c1.x = 1
  230. c1.y = 0
  231. c2.x = 2
  232. c2.y = 0
  233. f(c1, c2)
  234. assert c1.x == 2
  235. assert c2.x == 1
  236. assert get_x(c1) == 2
  237. assert get_x(c2) == 1
  238. assert get_y(c2) == 0
  239. g(c1, c2)
  240. assert get_y(c2) == 2
  241. [out]
  242. [case testTraitAttrsTriangle]
  243. from mypy_extensions import trait
  244. class A:
  245. a: int
  246. @trait
  247. class T(A):
  248. x: int
  249. def meth(self) -> int:
  250. return self.a
  251. class B(A):
  252. b: int
  253. class C(B, T):
  254. pass
  255. def take_t(t: T) -> int:
  256. return t.x + t.meth()
  257. def take_c(c: C) -> int:
  258. return c.x + c.meth()
  259. [file driver.py]
  260. from native import C, take_t, take_c
  261. c = C()
  262. c.a = 1
  263. c.x = 10
  264. assert take_t(c) == take_c(c) == 11
  265. [out]
  266. [case testTraitAttrsTree]
  267. from mypy_extensions import trait
  268. class A:
  269. a: int
  270. @trait
  271. class T1:
  272. x: int
  273. class B(A, T1):
  274. b: int
  275. @trait
  276. class T2:
  277. x: int
  278. class C(B, T2):
  279. pass
  280. def f(t1: T1, t2: T2) -> None:
  281. t1.x, t2.x = t2.x, t1.x
  282. def g(c1: C, c2: C) -> None:
  283. c1.x, c2.x = c2.x, c1.x
  284. [file driver.py]
  285. from native import C, f, g
  286. c1 = C()
  287. c2 = C()
  288. c1.x = 1
  289. c2.x = 2
  290. f(c1, c2)
  291. assert c1.x == 2
  292. assert c2.x == 1
  293. g(c1, c2)
  294. assert c1.x == 1
  295. assert c2.x == 2
  296. [out]
  297. [case testTraitErrorMessages]
  298. from mypy_extensions import trait
  299. @trait
  300. class Trait:
  301. pass
  302. def create() -> Trait:
  303. return Trait()
  304. [file driver.py]
  305. from native import Trait, create
  306. from testutil import assertRaises
  307. with assertRaises(TypeError, "traits may not be directly created"):
  308. Trait()
  309. with assertRaises(TypeError, "traits may not be directly created"):
  310. create()
  311. class Sub(Trait):
  312. pass
  313. with assertRaises(TypeError, "interpreted classes cannot inherit from compiled traits"):
  314. Sub()