exceptions.test 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  1. -- Test cases for exception handling insertion transform.
  2. --
  3. -- The result includes refcount handling since these two transforms interact.
  4. [case testListGetAndUnboxError]
  5. from typing import List
  6. def f(x: List[int]) -> int:
  7. return x[0]
  8. [out]
  9. def f(x):
  10. x :: list
  11. r0 :: object
  12. r1, r2 :: int
  13. L0:
  14. r0 = CPyList_GetItemShort(x, 0)
  15. if is_error(r0) goto L3 (error at f:3) else goto L1
  16. L1:
  17. r1 = unbox(int, r0)
  18. dec_ref r0
  19. if is_error(r1) goto L3 (error at f:3) else goto L2
  20. L2:
  21. return r1
  22. L3:
  23. r2 = <error> :: int
  24. return r2
  25. [case testListAppendAndSetItemError]
  26. from typing import List
  27. def f(x: List[int], y: int, z: int) -> None:
  28. x.append(y)
  29. x[y] = z
  30. [out]
  31. def f(x, y, z):
  32. x :: list
  33. y, z :: int
  34. r0 :: object
  35. r1 :: i32
  36. r2 :: bit
  37. r3 :: object
  38. r4 :: bit
  39. r5 :: None
  40. L0:
  41. inc_ref y :: int
  42. r0 = box(int, y)
  43. r1 = PyList_Append(x, r0)
  44. dec_ref r0
  45. r2 = r1 >= 0 :: signed
  46. if not r2 goto L3 (error at f:3) else goto L1 :: bool
  47. L1:
  48. inc_ref z :: int
  49. r3 = box(int, z)
  50. r4 = CPyList_SetItem(x, y, r3)
  51. if not r4 goto L3 (error at f:4) else goto L2 :: bool
  52. L2:
  53. return 1
  54. L3:
  55. r5 = <error> :: None
  56. return r5
  57. [case testOptionalHandling]
  58. from typing import Optional
  59. class A: pass
  60. def f(x: Optional[A]) -> int:
  61. if x is None:
  62. return 1
  63. if x is not None:
  64. return 2
  65. return 3
  66. [out]
  67. def f(x):
  68. x :: union[__main__.A, None]
  69. r0 :: object
  70. r1 :: bit
  71. r2 :: __main__.A
  72. r3 :: object
  73. r4 :: bit
  74. r5 :: int
  75. L0:
  76. r0 = load_address _Py_NoneStruct
  77. r1 = x == r0
  78. if r1 goto L1 else goto L2 :: bool
  79. L1:
  80. return 2
  81. L2:
  82. r2 = borrow cast(__main__.A, x)
  83. if is_error(r2) goto L6 (error at f:8) else goto L3
  84. L3:
  85. r3 = load_address _Py_NoneStruct
  86. r4 = r2 != r3
  87. if r4 goto L4 else goto L5 :: bool
  88. L4:
  89. return 4
  90. L5:
  91. return 6
  92. L6:
  93. r5 = <error> :: int
  94. return r5
  95. [case testListSum]
  96. from typing import List
  97. def sum(a: List[int], l: int) -> int:
  98. sum = 0
  99. i = 0
  100. while i < l:
  101. sum = sum + a[i]
  102. i = i + 1
  103. return sum
  104. [out]
  105. def sum(a, l):
  106. a :: list
  107. l, sum, i :: int
  108. r0 :: native_int
  109. r1 :: bit
  110. r2 :: native_int
  111. r3, r4, r5 :: bit
  112. r6 :: object
  113. r7, r8, r9, r10 :: int
  114. L0:
  115. sum = 0
  116. i = 0
  117. L1:
  118. r0 = i & 1
  119. r1 = r0 != 0
  120. if r1 goto L3 else goto L2 :: bool
  121. L2:
  122. r2 = l & 1
  123. r3 = r2 != 0
  124. if r3 goto L3 else goto L4 :: bool
  125. L3:
  126. r4 = CPyTagged_IsLt_(i, l)
  127. if r4 goto L5 else goto L10 :: bool
  128. L4:
  129. r5 = i < l :: signed
  130. if r5 goto L5 else goto L10 :: bool
  131. L5:
  132. r6 = CPyList_GetItemBorrow(a, i)
  133. if is_error(r6) goto L11 (error at sum:6) else goto L6
  134. L6:
  135. r7 = unbox(int, r6)
  136. if is_error(r7) goto L11 (error at sum:6) else goto L7
  137. L7:
  138. r8 = CPyTagged_Add(sum, r7)
  139. dec_ref sum :: int
  140. dec_ref r7 :: int
  141. sum = r8
  142. r9 = CPyTagged_Add(i, 2)
  143. dec_ref i :: int
  144. i = r9
  145. goto L1
  146. L8:
  147. return sum
  148. L9:
  149. r10 = <error> :: int
  150. return r10
  151. L10:
  152. dec_ref i :: int
  153. goto L8
  154. L11:
  155. dec_ref sum :: int
  156. dec_ref i :: int
  157. goto L9
  158. [case testTryExcept]
  159. def g() -> None:
  160. try:
  161. object()
  162. except:
  163. print("weeee")
  164. [out]
  165. def g():
  166. r0 :: object
  167. r1 :: str
  168. r2, r3 :: object
  169. r4 :: tuple[object, object, object]
  170. r5 :: str
  171. r6 :: object
  172. r7 :: str
  173. r8, r9 :: object
  174. r10 :: bit
  175. r11 :: None
  176. L0:
  177. L1:
  178. r0 = builtins :: module
  179. r1 = 'object'
  180. r2 = CPyObject_GetAttr(r0, r1)
  181. if is_error(r2) goto L3 (error at g:3) else goto L2
  182. L2:
  183. r3 = PyObject_CallFunctionObjArgs(r2, 0)
  184. dec_ref r2
  185. if is_error(r3) goto L3 (error at g:3) else goto L10
  186. L3:
  187. r4 = CPy_CatchError()
  188. r5 = 'weeee'
  189. r6 = builtins :: module
  190. r7 = 'print'
  191. r8 = CPyObject_GetAttr(r6, r7)
  192. if is_error(r8) goto L6 (error at g:5) else goto L4
  193. L4:
  194. r9 = PyObject_CallFunctionObjArgs(r8, r5, 0)
  195. dec_ref r8
  196. if is_error(r9) goto L6 (error at g:5) else goto L11
  197. L5:
  198. CPy_RestoreExcInfo(r4)
  199. dec_ref r4
  200. goto L8
  201. L6:
  202. CPy_RestoreExcInfo(r4)
  203. dec_ref r4
  204. r10 = CPy_KeepPropagating()
  205. if not r10 goto L9 else goto L7 :: bool
  206. L7:
  207. unreachable
  208. L8:
  209. return 1
  210. L9:
  211. r11 = <error> :: None
  212. return r11
  213. L10:
  214. dec_ref r3
  215. goto L8
  216. L11:
  217. dec_ref r9
  218. goto L5
  219. [case testGenopsTryFinally]
  220. def a() -> str:
  221. try:
  222. print()
  223. return 'hi'
  224. finally:
  225. print('goodbye!')
  226. [out]
  227. def a():
  228. r0 :: object
  229. r1 :: str
  230. r2, r3 :: object
  231. r4, r5 :: str
  232. r6, r7 :: tuple[object, object, object]
  233. r8 :: str
  234. r9 :: tuple[object, object, object]
  235. r10 :: str
  236. r11 :: object
  237. r12 :: str
  238. r13, r14 :: object
  239. r15 :: bit
  240. r16 :: str
  241. L0:
  242. L1:
  243. r0 = builtins :: module
  244. r1 = 'print'
  245. r2 = CPyObject_GetAttr(r0, r1)
  246. if is_error(r2) goto L5 (error at a:3) else goto L2
  247. L2:
  248. r3 = PyObject_CallFunctionObjArgs(r2, 0)
  249. dec_ref r2
  250. if is_error(r3) goto L5 (error at a:3) else goto L19
  251. L3:
  252. r4 = 'hi'
  253. inc_ref r4
  254. r5 = r4
  255. L4:
  256. r6 = <error> :: tuple[object, object, object]
  257. r7 = r6
  258. goto L6
  259. L5:
  260. r8 = <error> :: str
  261. r5 = r8
  262. r9 = CPy_CatchError()
  263. r7 = r9
  264. L6:
  265. r10 = 'goodbye!'
  266. r11 = builtins :: module
  267. r12 = 'print'
  268. r13 = CPyObject_GetAttr(r11, r12)
  269. if is_error(r13) goto L20 (error at a:6) else goto L7
  270. L7:
  271. r14 = PyObject_CallFunctionObjArgs(r13, r10, 0)
  272. dec_ref r13
  273. if is_error(r14) goto L20 (error at a:6) else goto L21
  274. L8:
  275. if is_error(r7) goto L11 else goto L22
  276. L9:
  277. CPy_Reraise()
  278. if not 0 goto L13 else goto L23 :: bool
  279. L10:
  280. unreachable
  281. L11:
  282. if is_error(r5) goto L17 else goto L12
  283. L12:
  284. return r5
  285. L13:
  286. if is_error(r7) goto L15 else goto L14
  287. L14:
  288. CPy_RestoreExcInfo(r7)
  289. xdec_ref r7
  290. L15:
  291. r15 = CPy_KeepPropagating()
  292. if not r15 goto L18 else goto L16 :: bool
  293. L16:
  294. unreachable
  295. L17:
  296. unreachable
  297. L18:
  298. r16 = <error> :: str
  299. return r16
  300. L19:
  301. dec_ref r3
  302. goto L3
  303. L20:
  304. xdec_ref r5
  305. goto L13
  306. L21:
  307. dec_ref r14
  308. goto L8
  309. L22:
  310. xdec_ref r5
  311. goto L9
  312. L23:
  313. xdec_ref r7
  314. goto L10
  315. [case testDocstring1]
  316. def lol() -> None:
  317. """Hello"""
  318. pass
  319. [out]
  320. def lol():
  321. L0:
  322. return 1
  323. [case testExceptUndefined1]
  324. from typing import Any
  325. def lol(x: Any) -> object:
  326. try:
  327. st = x.foo
  328. except:
  329. return ''
  330. # No uninit check should be generated, since the exception branch always returns
  331. return st
  332. [out]
  333. def lol(x):
  334. x :: object
  335. r0 :: str
  336. r1, st :: object
  337. r2 :: tuple[object, object, object]
  338. r3 :: str
  339. L0:
  340. L1:
  341. r0 = 'foo'
  342. r1 = CPyObject_GetAttr(x, r0)
  343. if is_error(r1) goto L3 (error at lol:4) else goto L2
  344. L2:
  345. st = r1
  346. goto L4
  347. L3:
  348. r2 = CPy_CatchError()
  349. r3 = ''
  350. CPy_RestoreExcInfo(r2)
  351. dec_ref r2
  352. inc_ref r3
  353. return r3
  354. L4:
  355. return st
  356. [case testExceptUndefined2]
  357. from typing import Any
  358. def lol(x: Any) -> object:
  359. try:
  360. a = x.foo
  361. b = x.bar
  362. except:
  363. pass
  364. # uninit checks are needed, since the exception can skip initializing the vars
  365. return a + b
  366. [out]
  367. def lol(x):
  368. x, r0, a, r1, b :: object
  369. r2 :: str
  370. r3 :: object
  371. r4 :: str
  372. r5 :: object
  373. r6 :: tuple[object, object, object]
  374. r7, r8 :: bool
  375. r9, r10 :: object
  376. L0:
  377. r0 = <error> :: object
  378. a = r0
  379. r1 = <error> :: object
  380. b = r1
  381. L1:
  382. r2 = 'foo'
  383. r3 = CPyObject_GetAttr(x, r2)
  384. if is_error(r3) goto L4 (error at lol:4) else goto L15
  385. L2:
  386. a = r3
  387. r4 = 'bar'
  388. r5 = CPyObject_GetAttr(x, r4)
  389. if is_error(r5) goto L4 (error at lol:5) else goto L16
  390. L3:
  391. b = r5
  392. goto L6
  393. L4:
  394. r6 = CPy_CatchError()
  395. L5:
  396. CPy_RestoreExcInfo(r6)
  397. dec_ref r6
  398. L6:
  399. if is_error(a) goto L17 else goto L9
  400. L7:
  401. r7 = raise UnboundLocalError('local variable "a" referenced before assignment')
  402. if not r7 goto L14 (error at lol:9) else goto L8 :: bool
  403. L8:
  404. unreachable
  405. L9:
  406. if is_error(b) goto L18 else goto L12
  407. L10:
  408. r8 = raise UnboundLocalError('local variable "b" referenced before assignment')
  409. if not r8 goto L14 (error at lol:9) else goto L11 :: bool
  410. L11:
  411. unreachable
  412. L12:
  413. r9 = PyNumber_Add(a, b)
  414. xdec_ref a
  415. xdec_ref b
  416. if is_error(r9) goto L14 (error at lol:9) else goto L13
  417. L13:
  418. return r9
  419. L14:
  420. r10 = <error> :: object
  421. return r10
  422. L15:
  423. xdec_ref a
  424. goto L2
  425. L16:
  426. xdec_ref b
  427. goto L3
  428. L17:
  429. xdec_ref b
  430. goto L7
  431. L18:
  432. xdec_ref a
  433. goto L10
  434. [case testMaybeUninitVarExc]
  435. def f(b: bool) -> None:
  436. u = 'a'
  437. while b:
  438. v = 'b'
  439. if v is not u:
  440. break
  441. print(v)
  442. [out]
  443. def f(b):
  444. b :: bool
  445. r0, v, r1, u, r2 :: str
  446. r3, r4 :: bit
  447. r5 :: object
  448. r6 :: str
  449. r7 :: object
  450. r8 :: bool
  451. r9 :: object
  452. r10 :: None
  453. L0:
  454. r0 = <error> :: str
  455. v = r0
  456. r1 = 'a'
  457. inc_ref r1
  458. u = r1
  459. L1:
  460. if b goto L10 else goto L11 :: bool
  461. L2:
  462. r2 = 'b'
  463. inc_ref r2
  464. v = r2
  465. r3 = v == u
  466. r4 = r3 ^ 1
  467. if r4 goto L11 else goto L1 :: bool
  468. L3:
  469. r5 = builtins :: module
  470. r6 = 'print'
  471. r7 = CPyObject_GetAttr(r5, r6)
  472. if is_error(r7) goto L12 (error at f:7) else goto L4
  473. L4:
  474. if is_error(v) goto L13 else goto L7
  475. L5:
  476. r8 = raise UnboundLocalError('local variable "v" referenced before assignment')
  477. if not r8 goto L9 (error at f:7) else goto L6 :: bool
  478. L6:
  479. unreachable
  480. L7:
  481. r9 = PyObject_CallFunctionObjArgs(r7, v, 0)
  482. dec_ref r7
  483. xdec_ref v
  484. if is_error(r9) goto L9 (error at f:7) else goto L14
  485. L8:
  486. return 1
  487. L9:
  488. r10 = <error> :: None
  489. return r10
  490. L10:
  491. xdec_ref v
  492. goto L2
  493. L11:
  494. dec_ref u
  495. goto L3
  496. L12:
  497. xdec_ref v
  498. goto L9
  499. L13:
  500. dec_ref r7
  501. goto L5
  502. L14:
  503. dec_ref r9
  504. goto L8
  505. [case testExceptionWithOverlappingErrorValue]
  506. from mypy_extensions import i64
  507. def f() -> i64:
  508. return 0
  509. def g() -> i64:
  510. return f()
  511. [out]
  512. def f():
  513. L0:
  514. return 0
  515. def g():
  516. r0 :: i64
  517. r1 :: bit
  518. r2 :: object
  519. r3 :: i64
  520. L0:
  521. r0 = f()
  522. r1 = r0 == -113
  523. if r1 goto L2 else goto L1 :: bool
  524. L1:
  525. return r0
  526. L2:
  527. r2 = PyErr_Occurred()
  528. if not is_error(r2) goto L3 (error at g:7) else goto L1
  529. L3:
  530. r3 = <error> :: i64
  531. return r3
  532. [case testExceptionWithNativeAttributeGetAndSet]
  533. class C:
  534. def __init__(self, x: int) -> None:
  535. self.x = x
  536. def foo(c: C, x: int) -> None:
  537. c.x = x - c.x
  538. [out]
  539. def C.__init__(self, x):
  540. self :: __main__.C
  541. x :: int
  542. L0:
  543. inc_ref x :: int
  544. self.x = x
  545. return 1
  546. def foo(c, x):
  547. c :: __main__.C
  548. x, r0, r1 :: int
  549. r2 :: bool
  550. L0:
  551. r0 = borrow c.x
  552. r1 = CPyTagged_Subtract(x, r0)
  553. c.x = r1
  554. return 1
  555. [case testExceptionWithOverlappingFloatErrorValue]
  556. def f() -> float:
  557. return 0.0
  558. def g() -> float:
  559. return f()
  560. [out]
  561. def f():
  562. L0:
  563. return 0.0
  564. def g():
  565. r0 :: float
  566. r1 :: bit
  567. r2 :: object
  568. r3 :: float
  569. L0:
  570. r0 = f()
  571. r1 = r0 == -113.0
  572. if r1 goto L2 else goto L1 :: bool
  573. L1:
  574. return r0
  575. L2:
  576. r2 = PyErr_Occurred()
  577. if not is_error(r2) goto L3 (error at g:5) else goto L1
  578. L3:
  579. r3 = <error> :: float
  580. return r3
  581. [case testExceptionWithLowLevelIntAttribute]
  582. from mypy_extensions import i32, i64
  583. class C:
  584. def __init__(self, x: i32, y: i64) -> None:
  585. self.x = x
  586. self.y = y
  587. def f(c: C) -> None:
  588. c.x
  589. c.y
  590. [out]
  591. def C.__init__(self, x, y):
  592. self :: __main__.C
  593. x :: i32
  594. y :: i64
  595. L0:
  596. self.x = x
  597. self.y = y
  598. return 1
  599. def f(c):
  600. c :: __main__.C
  601. r0 :: i32
  602. r1 :: i64
  603. L0:
  604. r0 = c.x
  605. r1 = c.y
  606. return 1
  607. [case testConditionallyUndefinedI64]
  608. from mypy_extensions import i64
  609. def f(x: i64) -> i64:
  610. if x:
  611. y: i64 = 2
  612. return y
  613. [out]
  614. def f(x):
  615. x, r0, y :: i64
  616. __locals_bitmap0 :: u32
  617. r1 :: bit
  618. r2, r3 :: u32
  619. r4 :: bit
  620. r5 :: bool
  621. r6 :: i64
  622. L0:
  623. r0 = <error> :: i64
  624. y = r0
  625. __locals_bitmap0 = 0
  626. r1 = x != 0
  627. if r1 goto L1 else goto L2 :: bool
  628. L1:
  629. y = 2
  630. r2 = __locals_bitmap0 | 1
  631. __locals_bitmap0 = r2
  632. L2:
  633. r3 = __locals_bitmap0 & 1
  634. r4 = r3 == 0
  635. if r4 goto L3 else goto L5 :: bool
  636. L3:
  637. r5 = raise UnboundLocalError('local variable "y" referenced before assignment')
  638. if not r5 goto L6 (error at f:-1) else goto L4 :: bool
  639. L4:
  640. unreachable
  641. L5:
  642. return y
  643. L6:
  644. r6 = <error> :: i64
  645. return r6
  646. [case testExceptionWithFloatAttribute]
  647. class C:
  648. def __init__(self, x: float, y: float) -> None:
  649. self.x = x
  650. if x:
  651. self.y = y
  652. def f(c: C) -> float:
  653. return c.x + c.y
  654. [out]
  655. def C.__init__(self, x, y):
  656. self :: __main__.C
  657. x, y :: float
  658. r0 :: bit
  659. L0:
  660. self.x = x
  661. r0 = x != 0.0
  662. if r0 goto L1 else goto L2 :: bool
  663. L1:
  664. self.y = y
  665. L2:
  666. return 1
  667. def f(c):
  668. c :: __main__.C
  669. r0, r1 :: float
  670. r2 :: bit
  671. r3 :: float
  672. r4 :: object
  673. r5 :: float
  674. L0:
  675. r0 = c.x
  676. r1 = c.y
  677. r2 = r1 == -113.0
  678. if r2 goto L2 else goto L1 :: bool
  679. L1:
  680. r3 = r0 + r1
  681. return r3
  682. L2:
  683. r4 = PyErr_Occurred()
  684. if not is_error(r4) goto L3 (error at f:8) else goto L1
  685. L3:
  686. r5 = <error> :: float
  687. return r5