irbuild-optional.test 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536
  1. [case testIsNone]
  2. from typing import Optional
  3. class A: pass
  4. def f(x: Optional[A]) -> int:
  5. if x is None:
  6. return 1
  7. return 2
  8. [out]
  9. def f(x):
  10. x :: union[__main__.A, None]
  11. r0 :: object
  12. r1 :: bit
  13. L0:
  14. r0 = load_address _Py_NoneStruct
  15. r1 = x == r0
  16. if r1 goto L1 else goto L2 :: bool
  17. L1:
  18. return 2
  19. L2:
  20. return 4
  21. [case testIsNotNone]
  22. from typing import Optional
  23. class A: pass
  24. def f(x: Optional[A]) -> int:
  25. if x is not None:
  26. return 1
  27. return 2
  28. [out]
  29. def f(x):
  30. x :: union[__main__.A, None]
  31. r0 :: object
  32. r1 :: bit
  33. L0:
  34. r0 = load_address _Py_NoneStruct
  35. r1 = x != r0
  36. if r1 goto L1 else goto L2 :: bool
  37. L1:
  38. return 2
  39. L2:
  40. return 4
  41. [case testIsTruthy]
  42. from typing import Optional
  43. class A: pass
  44. def f(x: Optional[A]) -> int:
  45. if x:
  46. return 1
  47. return 2
  48. [out]
  49. def f(x):
  50. x :: union[__main__.A, None]
  51. r0 :: object
  52. r1 :: bit
  53. L0:
  54. r0 = load_address _Py_NoneStruct
  55. r1 = x != r0
  56. if r1 goto L1 else goto L2 :: bool
  57. L1:
  58. return 2
  59. L2:
  60. return 4
  61. [case testIsTruthyOverride]
  62. from typing import Optional
  63. class A: pass
  64. class B(A):
  65. def __bool__(self) -> bool:
  66. return False
  67. def f(x: Optional[A]) -> int:
  68. if x:
  69. return 1
  70. return 2
  71. [out]
  72. def B.__bool__(self):
  73. self :: __main__.B
  74. L0:
  75. return 0
  76. def f(x):
  77. x :: union[__main__.A, None]
  78. r0 :: object
  79. r1 :: bit
  80. r2 :: __main__.A
  81. r3 :: i32
  82. r4 :: bit
  83. r5 :: bool
  84. L0:
  85. r0 = load_address _Py_NoneStruct
  86. r1 = x != r0
  87. if r1 goto L1 else goto L3 :: bool
  88. L1:
  89. r2 = cast(__main__.A, x)
  90. r3 = PyObject_IsTrue(r2)
  91. r4 = r3 >= 0 :: signed
  92. r5 = truncate r3: i32 to builtins.bool
  93. if r5 goto L2 else goto L3 :: bool
  94. L2:
  95. return 2
  96. L3:
  97. return 4
  98. [case testAssignToOptional]
  99. from typing import Optional
  100. class A:
  101. a: Optional[int]
  102. def f(x: Optional[A], y: Optional[A], z: Optional[int]) -> None:
  103. x = None
  104. x = A()
  105. x = y
  106. z = 1
  107. a = A()
  108. a.a = 1
  109. a.a = None
  110. [out]
  111. def f(x, y, z):
  112. x, y :: union[__main__.A, None]
  113. z :: union[int, None]
  114. r0 :: object
  115. r1 :: __main__.A
  116. r2 :: object
  117. r3, a :: __main__.A
  118. r4 :: object
  119. r5 :: bool
  120. r6 :: object
  121. r7 :: bool
  122. L0:
  123. r0 = box(None, 1)
  124. x = r0
  125. r1 = A()
  126. x = r1
  127. x = y
  128. r2 = object 1
  129. z = r2
  130. r3 = A()
  131. a = r3
  132. r4 = object 1
  133. a.a = r4; r5 = is_error
  134. r6 = box(None, 1)
  135. a.a = r6; r7 = is_error
  136. return 1
  137. [case testBoxOptionalListItem]
  138. from typing import List, Optional
  139. def f(x: List[Optional[int]]) -> None:
  140. x[0] = 0
  141. x[1] = None
  142. [out]
  143. def f(x):
  144. x :: list
  145. r0 :: object
  146. r1 :: bit
  147. r2 :: object
  148. r3 :: bit
  149. L0:
  150. r0 = object 0
  151. r1 = CPyList_SetItem(x, 0, r0)
  152. r2 = box(None, 1)
  153. r3 = CPyList_SetItem(x, 2, r2)
  154. return 1
  155. [case testNarrowDownFromOptional]
  156. from typing import Optional
  157. class A: pass
  158. def f(x: Optional[A]) -> A:
  159. y = A()
  160. if x is not None:
  161. y = x
  162. return x
  163. return y
  164. [out]
  165. def f(x):
  166. x :: union[__main__.A, None]
  167. r0, y :: __main__.A
  168. r1 :: object
  169. r2 :: bit
  170. r3, r4 :: __main__.A
  171. L0:
  172. r0 = A()
  173. y = r0
  174. r1 = load_address _Py_NoneStruct
  175. r2 = x != r1
  176. if r2 goto L1 else goto L2 :: bool
  177. L1:
  178. r3 = cast(__main__.A, x)
  179. y = r3
  180. r4 = cast(__main__.A, x)
  181. return r4
  182. L2:
  183. return y
  184. [case testPartialOptionalType]
  185. def f(y: int) -> None:
  186. x = None
  187. if y == 1:
  188. x = y
  189. if x is not None:
  190. y = x
  191. [out]
  192. def f(y):
  193. y :: int
  194. r0 :: object
  195. x :: union[int, None]
  196. r1 :: bit
  197. r2, r3 :: object
  198. r4 :: bit
  199. r5 :: int
  200. L0:
  201. r0 = box(None, 1)
  202. x = r0
  203. r1 = y == 2
  204. if r1 goto L1 else goto L2 :: bool
  205. L1:
  206. r2 = box(int, y)
  207. x = r2
  208. L2:
  209. r3 = load_address _Py_NoneStruct
  210. r4 = x != r3
  211. if r4 goto L3 else goto L4 :: bool
  212. L3:
  213. r5 = unbox(int, x)
  214. y = r5
  215. L4:
  216. return 1
  217. [case testUnionType]
  218. from typing import Union
  219. class A:
  220. a: int
  221. def f(x: Union[int, A]) -> int:
  222. if isinstance(x, int):
  223. return x + 1
  224. else:
  225. return x.a
  226. [out]
  227. def f(x):
  228. x :: union[int, __main__.A]
  229. r0 :: object
  230. r1 :: i32
  231. r2 :: bit
  232. r3 :: bool
  233. r4, r5 :: int
  234. r6 :: __main__.A
  235. r7 :: int
  236. L0:
  237. r0 = load_address PyLong_Type
  238. r1 = PyObject_IsInstance(x, r0)
  239. r2 = r1 >= 0 :: signed
  240. r3 = truncate r1: i32 to builtins.bool
  241. if r3 goto L1 else goto L2 :: bool
  242. L1:
  243. r4 = unbox(int, x)
  244. r5 = CPyTagged_Add(r4, 2)
  245. return r5
  246. L2:
  247. r6 = borrow cast(__main__.A, x)
  248. r7 = r6.a
  249. keep_alive x
  250. return r7
  251. L3:
  252. unreachable
  253. [case testUnionTypeInList]
  254. from typing import List, Union
  255. def f(x: List[Union[int, str]]) -> object:
  256. return x[0]
  257. [out]
  258. def f(x):
  259. x :: list
  260. r0 :: object
  261. r1 :: union[int, str]
  262. L0:
  263. r0 = CPyList_GetItemShort(x, 0)
  264. r1 = cast(union[int, str], r0)
  265. return r1
  266. [case testUnionAttributeAccess]
  267. from typing import Union
  268. class A:
  269. a: int
  270. class B:
  271. a: object
  272. def get(o: Union[A, B]) -> None:
  273. z = o.a
  274. def set(o: Union[A, B], s: str) -> None:
  275. o.a = s
  276. [out]
  277. def get(o):
  278. o :: union[__main__.A, __main__.B]
  279. r0 :: object
  280. r1 :: ptr
  281. r2 :: object
  282. r3 :: bit
  283. r4 :: __main__.A
  284. r5 :: int
  285. r6, r7 :: object
  286. r8 :: __main__.B
  287. r9, z :: object
  288. L0:
  289. r0 = __main__.A :: type
  290. r1 = get_element_ptr o ob_type :: PyObject
  291. r2 = load_mem r1 :: builtins.object*
  292. keep_alive o
  293. r3 = r2 == r0
  294. if r3 goto L1 else goto L2 :: bool
  295. L1:
  296. r4 = cast(__main__.A, o)
  297. r5 = r4.a
  298. r6 = box(int, r5)
  299. r7 = r6
  300. goto L3
  301. L2:
  302. r8 = cast(__main__.B, o)
  303. r9 = r8.a
  304. r7 = r9
  305. L3:
  306. z = r7
  307. return 1
  308. def set(o, s):
  309. o :: union[__main__.A, __main__.B]
  310. s, r0 :: str
  311. r1 :: i32
  312. r2 :: bit
  313. L0:
  314. r0 = 'a'
  315. r1 = PyObject_SetAttr(o, r0, s)
  316. r2 = r1 >= 0 :: signed
  317. return 1
  318. [case testUnionMethodCall]
  319. from typing import Union
  320. class A:
  321. def f(self, x: int) -> int:
  322. return x
  323. class B:
  324. def f(self, x: object) -> object:
  325. return x
  326. class C:
  327. def f(self, x: object) -> int:
  328. return 0
  329. def g(o: Union[A, B, C]) -> None:
  330. z = o.f(1)
  331. [out]
  332. def A.f(self, x):
  333. self :: __main__.A
  334. x :: int
  335. L0:
  336. return x
  337. def B.f(self, x):
  338. self :: __main__.B
  339. x :: object
  340. L0:
  341. return x
  342. def C.f(self, x):
  343. self :: __main__.C
  344. x :: object
  345. L0:
  346. return 0
  347. def g(o):
  348. o :: union[__main__.A, __main__.B, __main__.C]
  349. r0 :: object
  350. r1 :: ptr
  351. r2 :: object
  352. r3 :: bit
  353. r4 :: __main__.A
  354. r5 :: int
  355. r6, r7, r8 :: object
  356. r9 :: ptr
  357. r10 :: object
  358. r11 :: bit
  359. r12 :: __main__.B
  360. r13, r14 :: object
  361. r15 :: __main__.C
  362. r16 :: object
  363. r17 :: int
  364. r18, z :: object
  365. L0:
  366. r0 = __main__.A :: type
  367. r1 = get_element_ptr o ob_type :: PyObject
  368. r2 = load_mem r1 :: builtins.object*
  369. keep_alive o
  370. r3 = r2 == r0
  371. if r3 goto L1 else goto L2 :: bool
  372. L1:
  373. r4 = cast(__main__.A, o)
  374. r5 = r4.f(2)
  375. r6 = box(int, r5)
  376. r7 = r6
  377. goto L5
  378. L2:
  379. r8 = __main__.B :: type
  380. r9 = get_element_ptr o ob_type :: PyObject
  381. r10 = load_mem r9 :: builtins.object*
  382. keep_alive o
  383. r11 = r10 == r8
  384. if r11 goto L3 else goto L4 :: bool
  385. L3:
  386. r12 = cast(__main__.B, o)
  387. r13 = object 1
  388. r14 = r12.f(r13)
  389. r7 = r14
  390. goto L5
  391. L4:
  392. r15 = cast(__main__.C, o)
  393. r16 = object 1
  394. r17 = r15.f(r16)
  395. r18 = box(int, r17)
  396. r7 = r18
  397. L5:
  398. z = r7
  399. return 1
  400. [case testUnionWithNonNativeItem]
  401. from typing import Union
  402. from m import B
  403. class A:
  404. x: int
  405. def f(o: Union[A, B]) -> None:
  406. o.x
  407. def g(o: Union[B, A]) -> None:
  408. o.x
  409. [file m.py]
  410. class B:
  411. x: int
  412. [out]
  413. def f(o):
  414. o :: union[__main__.A, object]
  415. r0 :: object
  416. r1 :: ptr
  417. r2 :: object
  418. r3 :: bit
  419. r4 :: __main__.A
  420. r5, r6 :: int
  421. r7 :: object
  422. r8 :: str
  423. r9 :: object
  424. r10 :: int
  425. L0:
  426. r0 = __main__.A :: type
  427. r1 = get_element_ptr o ob_type :: PyObject
  428. r2 = load_mem r1 :: builtins.object*
  429. keep_alive o
  430. r3 = r2 == r0
  431. if r3 goto L1 else goto L2 :: bool
  432. L1:
  433. r4 = cast(__main__.A, o)
  434. r5 = r4.x
  435. r6 = r5
  436. goto L3
  437. L2:
  438. r7 = o
  439. r8 = 'x'
  440. r9 = CPyObject_GetAttr(r7, r8)
  441. r10 = unbox(int, r9)
  442. r6 = r10
  443. L3:
  444. return 1
  445. def g(o):
  446. o :: union[object, __main__.A]
  447. r0 :: object
  448. r1 :: ptr
  449. r2 :: object
  450. r3 :: bit
  451. r4 :: __main__.A
  452. r5, r6 :: int
  453. r7 :: object
  454. r8 :: str
  455. r9 :: object
  456. r10 :: int
  457. L0:
  458. r0 = __main__.A :: type
  459. r1 = get_element_ptr o ob_type :: PyObject
  460. r2 = load_mem r1 :: builtins.object*
  461. keep_alive o
  462. r3 = r2 == r0
  463. if r3 goto L1 else goto L2 :: bool
  464. L1:
  465. r4 = cast(__main__.A, o)
  466. r5 = r4.x
  467. r6 = r5
  468. goto L3
  469. L2:
  470. r7 = o
  471. r8 = 'x'
  472. r9 = CPyObject_GetAttr(r7, r8)
  473. r10 = unbox(int, r9)
  474. r6 = r10
  475. L3:
  476. return 1
  477. [case testUnionWithNoNativeItems]
  478. from typing import Union
  479. from m import A, B
  480. def f(o: Union[A, B]) -> None:
  481. o.x
  482. [file m.py]
  483. class A:
  484. x: object
  485. class B:
  486. x: int
  487. [out]
  488. def f(o):
  489. o :: object
  490. r0 :: str
  491. r1 :: object
  492. L0:
  493. r0 = 'x'
  494. r1 = CPyObject_GetAttr(o, r0)
  495. return 1