PageRenderTime 66ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/rpython/rtyper/test/test_rlist.py

https://bitbucket.org/pypy/pypy/
Python | 1717 lines | 1712 code | 4 blank | 1 comment | 3 complexity | 2da2333fecab0170621fa495ae7a502f MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0

Large files files are truncated, but you can click here to view the full file

  1. import sys
  2. import re
  3. import py
  4. from rpython.rtyper.debug import ll_assert
  5. from rpython.rtyper.error import TyperError
  6. from rpython.rtyper.llinterp import LLException, LLAssertFailure
  7. from rpython.rtyper.lltypesystem import rlist as ll_rlist
  8. from rpython.rtyper.lltypesystem.rlist import ListRepr, FixedSizeListRepr, ll_newlist, ll_fixed_newlist
  9. from rpython.rtyper.rint import signed_repr
  10. from rpython.rtyper.rlist import *
  11. from rpython.rtyper.test.tool import BaseRtypingTest
  12. from rpython.translator.translator import TranslationContext
  13. # undo the specialization parameters
  14. for n1 in 'get set del'.split():
  15. if n1 == "get":
  16. extraarg = "ll_getitem_fast, "
  17. else:
  18. extraarg = ""
  19. for n2 in '', '_nonneg':
  20. name = 'll_%sitem%s' % (n1, n2)
  21. globals()['_' + name] = globals()[name]
  22. exec """if 1:
  23. def %s(*args):
  24. return _%s(dum_checkidx, %s*args)
  25. """ % (name, name, extraarg)
  26. del n1, n2, name
  27. class BaseTestListImpl:
  28. def check_list(self, l1, expected):
  29. assert ll_len(l1) == len(expected)
  30. for i, x in zip(range(len(expected)), expected):
  31. assert ll_getitem_nonneg(l1, i) == x
  32. def test_rlist_basic(self):
  33. l = self.sample_list()
  34. assert ll_getitem(l, -4) == 42
  35. assert ll_getitem_nonneg(l, 1) == 43
  36. assert ll_getitem(l, 2) == 44
  37. assert ll_getitem(l, 3) == 45
  38. assert ll_len(l) == 4
  39. self.check_list(l, [42, 43, 44, 45])
  40. def test_rlist_set(self):
  41. l = self.sample_list()
  42. ll_setitem(l, -1, 99)
  43. self.check_list(l, [42, 43, 44, 99])
  44. ll_setitem_nonneg(l, 1, 77)
  45. self.check_list(l, [42, 77, 44, 99])
  46. def test_rlist_slice(self):
  47. l = self.sample_list()
  48. LIST = typeOf(l).TO
  49. self.check_list(ll_listslice_startonly(LIST, l, 0), [42, 43, 44, 45])
  50. self.check_list(ll_listslice_startonly(LIST, l, 1), [43, 44, 45])
  51. self.check_list(ll_listslice_startonly(LIST, l, 2), [44, 45])
  52. self.check_list(ll_listslice_startonly(LIST, l, 3), [45])
  53. self.check_list(ll_listslice_startonly(LIST, l, 4), [])
  54. for start in range(5):
  55. for stop in range(start, 8):
  56. self.check_list(ll_listslice_startstop(LIST, l, start, stop),
  57. [42, 43, 44, 45][start:stop])
  58. def test_rlist_setslice(self):
  59. n = 100
  60. for start in range(5):
  61. for stop in range(start, 5):
  62. l1 = self.sample_list()
  63. l2 = self.sample_list()
  64. expected = [42, 43, 44, 45]
  65. for i in range(start, stop):
  66. expected[i] = n
  67. ll_setitem(l2, i, n)
  68. n += 1
  69. l2 = ll_listslice_startstop(typeOf(l2).TO, l2, start, stop)
  70. ll_listsetslice(l1, start, stop, l2)
  71. self.check_list(l1, expected)
  72. # helper used by some tests below
  73. def list_is_clear(lis, idx):
  74. items = lis._obj.items._obj.items
  75. for i in range(idx, len(items)):
  76. if items[i]._obj is not None:
  77. return False
  78. return True
  79. class TestListImpl(BaseTestListImpl):
  80. def sample_list(self): # [42, 43, 44, 45]
  81. rlist = ListRepr(None, signed_repr)
  82. rlist.setup()
  83. l = ll_newlist(rlist.lowleveltype.TO, 3)
  84. ll_setitem(l, 0, 42)
  85. ll_setitem(l, -2, 43)
  86. ll_setitem_nonneg(l, 2, 44)
  87. ll_append(l, 45)
  88. return l
  89. def test_rlist_del(self):
  90. l = self.sample_list()
  91. ll_delitem_nonneg(l, 0)
  92. self.check_list(l, [43, 44, 45])
  93. ll_delitem(l, -2)
  94. self.check_list(l, [43, 45])
  95. ll_delitem(l, 1)
  96. self.check_list(l, [43])
  97. ll_delitem(l, 0)
  98. self.check_list(l, [])
  99. def test_rlist_extend_concat(self):
  100. l = self.sample_list()
  101. ll_extend(l, l)
  102. self.check_list(l, [42, 43, 44, 45] * 2)
  103. l1 = ll_concat(typeOf(l).TO, l, l)
  104. assert typeOf(l1) == typeOf(l)
  105. assert l1 != l
  106. self.check_list(l1, [42, 43, 44, 45] * 4)
  107. def test_rlist_delslice(self):
  108. l = self.sample_list()
  109. ll_listdelslice_startonly(l, 3)
  110. self.check_list(l, [42, 43, 44])
  111. ll_listdelslice_startonly(l, 0)
  112. self.check_list(l, [])
  113. for start in range(5):
  114. for stop in range(start, 8):
  115. l = self.sample_list()
  116. ll_listdelslice_startstop(l, start, stop)
  117. expected = [42, 43, 44, 45]
  118. del expected[start:stop]
  119. self.check_list(l, expected)
  120. class TestFixedSizeListImpl(BaseTestListImpl):
  121. def sample_list(self): # [42, 43, 44, 45]
  122. rlist = FixedSizeListRepr(None, signed_repr)
  123. rlist.setup()
  124. l = ll_fixed_newlist(rlist.lowleveltype.TO, 4)
  125. ll_setitem(l, 0, 42)
  126. ll_setitem(l, -3, 43)
  127. ll_setitem_nonneg(l, 2, 44)
  128. ll_setitem(l, 3, 45)
  129. return l
  130. def test_rlist_extend_concat(self):
  131. l = self.sample_list()
  132. lvar = TestListImpl.sample_list(TestListImpl())
  133. ll_extend(lvar, l)
  134. self.check_list(lvar, [42, 43, 44, 45] * 2)
  135. l1 = ll_concat(typeOf(l).TO, lvar, l)
  136. assert typeOf(l1) == typeOf(l)
  137. assert l1 != l
  138. self.check_list(l1, [42, 43, 44, 45] * 3)
  139. l1 = ll_concat(typeOf(l).TO, l, lvar)
  140. assert typeOf(l1) == typeOf(l)
  141. assert l1 != l
  142. self.check_list(l1, [42, 43, 44, 45] * 3)
  143. lvar1 = ll_concat(typeOf(lvar).TO, lvar, l)
  144. assert typeOf(lvar1) == typeOf(lvar)
  145. assert lvar1 != lvar
  146. self.check_list(l1, [42, 43, 44, 45] * 3)
  147. lvar1 = ll_concat(typeOf(lvar).TO, l, lvar)
  148. assert typeOf(lvar1) == typeOf(lvar)
  149. assert lvar1 != lvar
  150. self.check_list(lvar1, [42, 43, 44, 45] * 3)
  151. # ____________________________________________________________
  152. # these classes are used in the tests below
  153. class Foo:
  154. pass
  155. class Bar(Foo):
  156. pass
  157. class Freezing:
  158. def _freeze_(self):
  159. return True
  160. class TestRlist(BaseRtypingTest):
  161. rlist = ll_rlist
  162. def test_simple(self):
  163. def dummyfn():
  164. l = [10, 20, 30]
  165. return l[2]
  166. res = self.interpret(dummyfn, [])
  167. assert res == 30
  168. def test_append(self):
  169. def dummyfn():
  170. l = []
  171. l.append(50)
  172. l.append(60)
  173. l.append(70)
  174. l.append(80)
  175. l.append(90)
  176. return len(l), l[0], l[-1]
  177. res = self.interpret(dummyfn, [])
  178. assert res.item0 == 5
  179. assert res.item1 == 50
  180. assert res.item2 == 90
  181. def test_len(self):
  182. def dummyfn():
  183. l = [5, 10]
  184. return len(l)
  185. res = self.interpret(dummyfn, [])
  186. assert res == 2
  187. def dummyfn():
  188. l = [5]
  189. l.append(6)
  190. return len(l)
  191. res = self.interpret(dummyfn, [])
  192. assert res == 2
  193. def test_iterate(self):
  194. def dummyfn():
  195. total = 0
  196. for x in [1, 3, 5, 7, 9]:
  197. total += x
  198. return total
  199. res = self.interpret(dummyfn, [])
  200. assert res == 25
  201. def dummyfn():
  202. total = 0
  203. l = [1, 3, 5, 7]
  204. l.append(9)
  205. for x in l:
  206. total += x
  207. return total
  208. res = self.interpret(dummyfn, [])
  209. assert res == 25
  210. def test_iterate_next(self):
  211. def dummyfn():
  212. total = 0
  213. it = iter([1, 3, 5, 7, 9])
  214. while 1:
  215. try:
  216. x = it.next()
  217. except StopIteration:
  218. break
  219. total += x
  220. return total
  221. res = self.interpret(dummyfn, [])
  222. assert res == 25
  223. def dummyfn():
  224. total = 0
  225. l = [1, 3, 5, 7]
  226. l.append(9)
  227. it = iter(l)
  228. while 1:
  229. try:
  230. x = it.next()
  231. except StopIteration:
  232. break
  233. total += x
  234. return total
  235. res = self.interpret(dummyfn, [])
  236. assert res == 25
  237. def test_recursive(self):
  238. def dummyfn(N):
  239. l = []
  240. while N > 0:
  241. l = [l]
  242. N -= 1
  243. return len(l)
  244. res = self.interpret(dummyfn, [5])
  245. assert res == 1
  246. def dummyfn(N):
  247. l = []
  248. while N > 0:
  249. l.append(l)
  250. N -= 1
  251. return len(l)
  252. res = self.interpret(dummyfn, [5])
  253. assert res == 5
  254. def test_add(self):
  255. def dummyfn():
  256. l = [5]
  257. l += [6, 7]
  258. return l + [8]
  259. res = self.interpret(dummyfn, [])
  260. assert self.ll_to_list(res) == [5, 6, 7, 8]
  261. def dummyfn():
  262. l = [5]
  263. l += [6, 7]
  264. l2 = l + [8]
  265. l2.append(9)
  266. return l2
  267. res = self.interpret(dummyfn, [])
  268. assert self.ll_to_list(res) == [5, 6, 7, 8, 9]
  269. def test_slice(self):
  270. def dummyfn():
  271. l = [5, 6, 7, 8, 9]
  272. return l[:2], l[1:4], l[3:]
  273. res = self.interpret(dummyfn, [])
  274. assert self.ll_to_list(res.item0) == [5, 6]
  275. assert self.ll_to_list(res.item1) == [6, 7, 8]
  276. assert self.ll_to_list(res.item2) == [8, 9]
  277. def dummyfn():
  278. l = [5, 6, 7, 8]
  279. l.append(9)
  280. return l[:2], l[1:4], l[3:]
  281. res = self.interpret(dummyfn, [])
  282. assert self.ll_to_list(res.item0) == [5, 6]
  283. assert self.ll_to_list(res.item1) == [6, 7, 8]
  284. assert self.ll_to_list(res.item2) == [8, 9]
  285. def test_getslice_not_constant_folded(self):
  286. l = list('abcdef')
  287. def dummyfn():
  288. result = []
  289. for i in range(3):
  290. l2 = l[2:]
  291. result.append(l2.pop())
  292. return result
  293. res = self.interpret(dummyfn, [])
  294. assert self.ll_to_list(res) == ['f', 'f', 'f']
  295. def test_set_del_item(self):
  296. def dummyfn():
  297. l = [5, 6, 7]
  298. l[1] = 55
  299. l[-1] = 66
  300. return l
  301. res = self.interpret(dummyfn, [])
  302. assert self.ll_to_list(res) == [5, 55, 66]
  303. def dummyfn():
  304. l = []
  305. l.append(5)
  306. l.append(6)
  307. l.append(7)
  308. l[1] = 55
  309. l[-1] = 66
  310. return l
  311. res = self.interpret(dummyfn, [])
  312. assert self.ll_to_list(res) == [5, 55, 66]
  313. def dummyfn():
  314. l = [5, 6, 7]
  315. l[1] = 55
  316. l[-1] = 66
  317. del l[0]
  318. del l[-1]
  319. del l[:]
  320. return len(l)
  321. res = self.interpret(dummyfn, [])
  322. assert res == 0
  323. def test_setslice(self):
  324. def dummyfn():
  325. l = [10, 9, 8, 7]
  326. l[:2] = [6, 5]
  327. return l[0], l[1], l[2], l[3]
  328. res = self.interpret(dummyfn, ())
  329. assert res.item0 == 6
  330. assert res.item1 == 5
  331. assert res.item2 == 8
  332. assert res.item3 == 7
  333. def dummyfn():
  334. l = [10, 9, 8]
  335. l.append(7)
  336. l[:2] = [6, 5]
  337. return l[0], l[1], l[2], l[3]
  338. res = self.interpret(dummyfn, ())
  339. assert res.item0 == 6
  340. assert res.item1 == 5
  341. assert res.item2 == 8
  342. assert res.item3 == 7
  343. def dummyfn():
  344. l = [10, 9, 8, 7]
  345. l[1:3] = [42]
  346. return l[0], l[1], l[2]
  347. res = self.interpret(dummyfn, ())
  348. assert res.item0 == 10
  349. assert res.item1 == 42
  350. assert res.item2 == 7
  351. def dummyfn():
  352. l = [10, 9, 8, 7]
  353. l[1:3] = [6, 5, 0]
  354. return l[0], l[1], l[2], l[3], l[4]
  355. res = self.interpret(dummyfn, ())
  356. assert res.item0 == 10
  357. assert res.item1 == 6
  358. assert res.item2 == 5
  359. assert res.item3 == 0
  360. assert res.item4 == 7
  361. def dummyfn():
  362. l = [10, 9, 8, 7]
  363. l[1:1] = [6, 5, 0]
  364. return l[0], l[1], l[2], l[3], l[4], l[5], l[6]
  365. res = self.interpret(dummyfn, ())
  366. assert res.item0 == 10
  367. assert res.item1 == 6
  368. assert res.item2 == 5
  369. assert res.item3 == 0
  370. assert res.item4 == 9
  371. assert res.item5 == 8
  372. assert res.item6 == 7
  373. def dummyfn():
  374. l = [10, 9, 8, 7]
  375. l[1:3] = []
  376. return l[0], l[1]
  377. res = self.interpret(dummyfn, ())
  378. assert res.item0 == 10
  379. assert res.item1 == 7
  380. def test_delslice(self):
  381. def dummyfn():
  382. l = [10, 9, 8, 7]
  383. del l[:2]
  384. return len(l), l[0], l[1]
  385. res = self.interpret(dummyfn, ())
  386. assert res.item0 == 2
  387. assert res.item1 == 8
  388. assert res.item2 == 7
  389. def dummyfn():
  390. l = [10, 9, 8, 7]
  391. del l[2:]
  392. return len(l), l[0], l[1]
  393. res = self.interpret(dummyfn, ())
  394. assert res.item0 == 2
  395. assert res.item1 == 10
  396. assert res.item2 == 9
  397. def test_bltn_list(self):
  398. # test for ll_copy()
  399. for resize1 in [False, True]:
  400. for resize2 in [False, True]:
  401. def dummyfn():
  402. l1 = [42]
  403. if resize1:
  404. l1.append(43)
  405. l2 = list(l1)
  406. if resize2:
  407. l2.append(44)
  408. l2[0] = 0
  409. return l1[0]
  410. res = self.interpret(dummyfn, ())
  411. assert res == 42
  412. def test_bltn_list_from_string(self):
  413. def dummyfn(n):
  414. l1 = list(str(n))
  415. return ord(l1[0])
  416. res = self.interpret(dummyfn, [71234])
  417. assert res == ord('7')
  418. def test_bltn_list_from_unicode(self):
  419. def dummyfn(n):
  420. l1 = list(unicode(str(n)))
  421. return ord(l1[0])
  422. res = self.interpret(dummyfn, [71234])
  423. assert res == ord('7')
  424. def test_bltn_list_from_string_resize(self):
  425. def dummyfn(n):
  426. l1 = list(str(n))
  427. l1.append('X')
  428. return ord(l1[0])
  429. res = self.interpret(dummyfn, [71234])
  430. assert res == ord('7')
  431. def test_bltn_list_from_unicode_resize(self):
  432. def dummyfn(n):
  433. l1 = list(unicode(str(n)))
  434. l1.append(u'X')
  435. return ord(l1[0])
  436. res = self.interpret(dummyfn, [71234])
  437. assert res == ord('7')
  438. def test_is_true(self):
  439. def is_true(lst):
  440. if lst:
  441. return True
  442. else:
  443. return False
  444. def dummyfn1():
  445. return is_true(None)
  446. def dummyfn2():
  447. return is_true([])
  448. def dummyfn3():
  449. return is_true([0])
  450. assert self.interpret(dummyfn1, ()) == False
  451. assert self.interpret(dummyfn2, ()) == False
  452. assert self.interpret(dummyfn3, ()) == True
  453. def test_list_index_simple(self):
  454. def dummyfn(i):
  455. l = [5, 6, 7, 8]
  456. return l.index(i)
  457. res = self.interpret(dummyfn, (6,))
  458. assert res == 1
  459. self.interpret_raises(ValueError, dummyfn, [42])
  460. def test_insert_pop(self):
  461. def dummyfn():
  462. l = [6, 7, 8]
  463. l.insert(0, 5)
  464. l.insert(1, 42)
  465. l.pop(2)
  466. l.pop(0)
  467. l.pop(-1)
  468. l.pop()
  469. return l[-1]
  470. res = self.interpret(dummyfn, ())
  471. assert res == 42
  472. def test_insert_bug(self):
  473. def dummyfn(n):
  474. l = [1]
  475. l = l[:]
  476. l.pop(0)
  477. if n < 0:
  478. l.insert(0, 42)
  479. else:
  480. l.insert(n, 42)
  481. return l
  482. res = self.interpret(dummyfn, [0])
  483. assert res.ll_length() == 1
  484. assert res.ll_getitem_fast(0) == 42
  485. res = self.interpret(dummyfn, [-1])
  486. assert res.ll_length() == 1
  487. assert res.ll_getitem_fast(0) == 42
  488. def test_inst_pop(self):
  489. class A:
  490. pass
  491. l = [A(), A()]
  492. def f(idx):
  493. try:
  494. return l.pop(idx)
  495. except IndexError:
  496. return None
  497. res = self.interpret(f, [1])
  498. assert self.class_name(res) == 'A'
  499. #''.join(res.super.typeptr.name) == 'A\00'
  500. def test_reverse(self):
  501. def dummyfn():
  502. l = [5, 3, 2]
  503. l.reverse()
  504. return l[0]*100 + l[1]*10 + l[2]
  505. res = self.interpret(dummyfn, ())
  506. assert res == 235
  507. def dummyfn():
  508. l = [5]
  509. l.append(3)
  510. l.append(2)
  511. l.reverse()
  512. return l[0]*100 + l[1]*10 + l[2]
  513. res = self.interpret(dummyfn, ())
  514. assert res == 235
  515. def test_reversed(self):
  516. klist = [1, 2, 3]
  517. def fn():
  518. res = []
  519. for elem in reversed(klist):
  520. res.append(elem)
  521. return res[0] * 100 + res[1] * 10 + res[2]
  522. res = self.interpret(fn, [])
  523. assert res == fn()
  524. def test_prebuilt_list(self):
  525. klist = [6, 7, 8, 9]
  526. def dummyfn(n):
  527. return klist[n]
  528. res = self.interpret(dummyfn, [0])
  529. assert res == 6
  530. res = self.interpret(dummyfn, [3])
  531. assert res == 9
  532. res = self.interpret(dummyfn, [-2])
  533. assert res == 8
  534. klist = ['a', 'd', 'z']
  535. def mkdummyfn():
  536. def dummyfn(n):
  537. klist.append('k')
  538. return klist[n]
  539. return dummyfn
  540. res = self.interpret(mkdummyfn(), [0])
  541. assert res == 'a'
  542. res = self.interpret(mkdummyfn(), [3])
  543. assert res == 'k'
  544. res = self.interpret(mkdummyfn(), [-2])
  545. assert res == 'z'
  546. def test_bound_list_method(self):
  547. klist = [1, 2, 3]
  548. # for testing constant methods without actually mutating the constant
  549. def dummyfn(n):
  550. klist.extend([])
  551. self.interpret(dummyfn, [7])
  552. def test_list_is(self):
  553. def dummyfn():
  554. l1 = []
  555. return l1 is l1
  556. res = self.interpret(dummyfn, [])
  557. assert res is True
  558. def dummyfn():
  559. l2 = [1, 2]
  560. return l2 is l2
  561. res = self.interpret(dummyfn, [])
  562. assert res is True
  563. def dummyfn():
  564. l1 = [2]
  565. l2 = [1, 2]
  566. return l1 is l2
  567. res = self.interpret(dummyfn, [])
  568. assert res is False
  569. def dummyfn():
  570. l1 = [1, 2]
  571. l2 = [1]
  572. l2.append(2)
  573. return l1 is l2
  574. res = self.interpret(dummyfn, [])
  575. assert res is False
  576. def dummyfn():
  577. l1 = None
  578. l2 = [1, 2]
  579. return l1 is l2
  580. res = self.interpret(dummyfn, [])
  581. assert res is False
  582. def dummyfn():
  583. l1 = None
  584. l2 = [1]
  585. l2.append(2)
  586. return l1 is l2
  587. res = self.interpret(dummyfn, [])
  588. assert res is False
  589. def test_list_compare(self):
  590. def fn(i, j, neg=False):
  591. s1 = [[1, 2, 3], [4, 5, 1], None]
  592. s2 = [[1, 2, 3], [4, 5, 1], [1], [1, 2], [4, 5, 1, 6],
  593. [7, 1, 1, 8, 9, 10], None]
  594. if neg: return s1[i] != s2[i]
  595. return s1[i] == s2[j]
  596. for i in range(3):
  597. for j in range(7):
  598. for case in False, True:
  599. res = self.interpret(fn, [i,j,case])
  600. assert res is fn(i, j, case)
  601. def fn(i, j, neg=False):
  602. s1 = [[1, 2, 3], [4, 5, 1], None]
  603. l = []
  604. l.extend([1,2,3])
  605. s2 = [l, [4, 5, 1], [1], [1, 2], [4, 5, 1, 6],
  606. [7, 1, 1, 8, 9, 10], None]
  607. if neg: return s1[i] != s2[i]
  608. return s1[i] == s2[j]
  609. for i in range(3):
  610. for j in range(7):
  611. for case in False, True:
  612. res = self.interpret(fn, [i,j,case])
  613. assert res is fn(i, j, case)
  614. def test_list_comparestr(self):
  615. def fn(i, j, neg=False):
  616. s1 = [["hell"], ["hello", "world"]]
  617. s1[0][0] += "o" # ensure no interning
  618. s2 = [["hello"], ["world"]]
  619. if neg: return s1[i] != s2[i]
  620. return s1[i] == s2[j]
  621. for i in range(2):
  622. for j in range(2):
  623. for case in False, True:
  624. res = self.interpret(fn, [i,j,case])
  625. assert res is fn(i, j, case)
  626. def test_list_compare_char_str(self):
  627. def fn(i, j):
  628. l1 = [str(i)]
  629. l2 = [chr(j)]
  630. return l1 == l2
  631. res = self.interpret(fn, [65, 65])
  632. assert res is False
  633. res = self.interpret(fn, [1, 49])
  634. assert res is True
  635. def test_list_compareinst(self):
  636. def fn(i, j, neg=False):
  637. foo1 = Foo()
  638. foo2 = Foo()
  639. bar1 = Bar()
  640. s1 = [[foo1], [foo2], [bar1]]
  641. s2 = s1[:]
  642. if neg: return s1[i] != s2[i]
  643. return s1[i] == s2[j]
  644. for i in range(3):
  645. for j in range(3):
  646. for case in False, True:
  647. res = self.interpret(fn, [i, j, case])
  648. assert res is fn(i, j, case)
  649. def fn(i, j, neg=False):
  650. foo1 = Foo()
  651. foo2 = Foo()
  652. bar1 = Bar()
  653. s1 = [[foo1], [foo2], [bar1]]
  654. s2 = s1[:]
  655. s2[0].extend([])
  656. if neg: return s1[i] != s2[i]
  657. return s1[i] == s2[j]
  658. for i in range(3):
  659. for j in range(3):
  660. for case in False, True:
  661. res = self.interpret(fn, [i, j, case])
  662. assert res is fn(i, j, case)
  663. def test_list_contains(self):
  664. def fn(i, neg=False):
  665. foo1 = Foo()
  666. foo2 = Foo()
  667. bar1 = Bar()
  668. bar2 = Bar()
  669. lis = [foo1, foo2, bar1]
  670. args = lis + [bar2]
  671. if neg : return args[i] not in lis
  672. return args[i] in lis
  673. for i in range(4):
  674. for case in False, True:
  675. res = self.interpret(fn, [i, case])
  676. assert res is fn(i, case)
  677. def fn(i, neg=False):
  678. foo1 = Foo()
  679. foo2 = Foo()
  680. bar1 = Bar()
  681. bar2 = Bar()
  682. lis = [foo1, foo2, bar1]
  683. lis.append(lis.pop())
  684. args = lis + [bar2]
  685. if neg : return args[i] not in lis
  686. return args[i] in lis
  687. for i in range(4):
  688. for case in False, True:
  689. res = self.interpret(fn, [i, case])
  690. assert res is fn(i, case)
  691. def test_constant_list_contains(self):
  692. # a 'contains' operation on list containing only annotation-time
  693. # constants should be optimized into the equivalent code of
  694. # 'in prebuilt-dictionary'. Hard to test directly...
  695. def g():
  696. return 16
  697. def f(i):
  698. return i in [1, 2, 4, 8, g()]
  699. res = self.interpret(f, [2])
  700. assert res is True
  701. res = self.interpret(f, [15])
  702. assert res is False
  703. res = self.interpret(f, [16])
  704. assert res is True
  705. def test_nonconstant_list_contains(self):
  706. def f(i):
  707. return i in [1, -i, 2, 4, 8]
  708. res = self.interpret(f, [2])
  709. assert res is True
  710. res = self.interpret(f, [15])
  711. assert res is False
  712. res = self.interpret(f, [0])
  713. assert res is True
  714. def test_not_a_char_list_after_all_1(self):
  715. def fn(n):
  716. l = ['h', 'e', 'l', 'l', '0']
  717. return str(n) in l # turns into: str(n) in {'h','e','l','0'}
  718. res = self.interpret(fn, [5])
  719. assert res is False
  720. res = self.interpret(fn, [0])
  721. assert res is True
  722. def fn():
  723. l = ['h', 'e', 'l', 'l', '0']
  724. return 'hi' in l # turns into: 'hi' in {'h','e','l','0'}
  725. res = self.interpret(fn, [])
  726. assert res is False
  727. def test_not_a_char_list_after_all_2(self):
  728. def fn(n):
  729. l = ['h', 'e', 'l', 'l', 'o', chr(n)]
  730. return 'world' in l
  731. res = self.interpret(fn, [0])
  732. assert res is False
  733. def test_list_index(self):
  734. def fn(i):
  735. foo1 = Foo()
  736. foo2 = Foo()
  737. bar1 = Bar()
  738. bar2 = Bar()
  739. lis = [foo1, foo2, bar1]
  740. args = lis + [bar2]
  741. return lis.index(args[i])
  742. for i in range(4):
  743. for varsize in False, True:
  744. try:
  745. res2 = fn(i)
  746. res1 = self.interpret(fn, [i])
  747. assert res1 == res2
  748. except Exception as e:
  749. self.interpret_raises(e.__class__, fn, [i])
  750. def fn(i):
  751. foo1 = Foo()
  752. foo2 = Foo()
  753. bar1 = Bar()
  754. bar2 = Bar()
  755. lis = [foo1, foo2, bar1]
  756. args = lis + [bar2]
  757. lis.append(lis.pop())
  758. return lis.index(args[i])
  759. for i in range(4):
  760. for varsize in False, True:
  761. try:
  762. res2 = fn(i)
  763. res1 = self.interpret(fn, [i])
  764. assert res1 == res2
  765. except Exception as e:
  766. self.interpret_raises(e.__class__, fn, [i])
  767. def test_list_str(self):
  768. def fn():
  769. return str([1,2,3])
  770. res = self.interpret(fn, [])
  771. assert self.ll_to_string(res) == fn()
  772. def fn():
  773. return str([[1,2,3]])
  774. res = self.interpret(fn, [])
  775. assert self.ll_to_string(res) == fn()
  776. def fn():
  777. l = [1,2]
  778. l.append(3)
  779. return str(l)
  780. res = self.interpret(fn, [])
  781. assert self.ll_to_string(res) == fn()
  782. def fn():
  783. l = [1,2]
  784. l.append(3)
  785. return str([l])
  786. res = self.interpret(fn, [])
  787. assert self.ll_to_string(res) == fn()
  788. def fn():
  789. return str([])
  790. res = self.interpret(fn, [])
  791. assert self.ll_to_string(res) == fn()
  792. def fn():
  793. return str([1.25])
  794. res = self.interpret(fn, [])
  795. assert eval(self.ll_to_string(res)) == [1.25]
  796. def test_list_or_None(self):
  797. empty_list = []
  798. nonempty_list = [1, 2]
  799. def fn(i):
  800. test = [None, empty_list, nonempty_list][i]
  801. if test:
  802. return 1
  803. else:
  804. return 0
  805. res = self.interpret(fn, [0])
  806. assert res == 0
  807. res = self.interpret(fn, [1])
  808. assert res == 0
  809. res = self.interpret(fn, [2])
  810. assert res == 1
  811. nonempty_list = [1, 2]
  812. def fn(i):
  813. empty_list = [1]
  814. empty_list.pop()
  815. nonempty_list = []
  816. nonempty_list.extend([1,2])
  817. test = [None, empty_list, nonempty_list][i]
  818. if test:
  819. return 1
  820. else:
  821. return 0
  822. res = self.interpret(fn, [0])
  823. assert res == 0
  824. res = self.interpret(fn, [1])
  825. assert res == 0
  826. res = self.interpret(fn, [2])
  827. assert res == 1
  828. def test_inst_list(self):
  829. def fn():
  830. l = [None]
  831. l[0] = Foo()
  832. l.append(Bar())
  833. l2 = [l[1], l[0], l[0]]
  834. l.extend(l2)
  835. for x in l2:
  836. l.append(x)
  837. x = l.pop()
  838. x = l.pop()
  839. x = l.pop()
  840. x = l2.pop()
  841. return str(x)+";"+str(l)
  842. res = self.ll_to_string(self.interpret(fn, []))
  843. res = res.replace('rpython.rtyper.test.test_rlist.', '')
  844. res = re.sub(' at 0x[a-z0-9]+', '', res)
  845. assert res == '<Foo object>;[<Foo object>, <Bar object>, <Bar object>, <Foo object>, <Foo object>]'
  846. def fn():
  847. l = [None] * 2
  848. l[0] = Foo()
  849. l[1] = Bar()
  850. l2 = [l[1], l[0], l[0]]
  851. l = l + [None] * 3
  852. i = 2
  853. for x in l2:
  854. l[i] = x
  855. i += 1
  856. return str(l)
  857. res = self.ll_to_string(self.interpret(fn, []))
  858. res = res.replace('rpython.rtyper.test.test_rlist.', '')
  859. res = re.sub(' at 0x[a-z0-9]+', '', res)
  860. assert res == '[<Foo object>, <Bar object>, <Bar object>, <Foo object>, <Foo object>]'
  861. def test_list_slice_minusone(self):
  862. def fn(i):
  863. lst = [i, i+1, i+2]
  864. lst2 = lst[:-1]
  865. return lst[-1] * lst2[-1]
  866. res = self.interpret(fn, [5])
  867. assert res == 42
  868. def fn(i):
  869. lst = [i, i+1, i+2, 7]
  870. lst.pop()
  871. lst2 = lst[:-1]
  872. return lst[-1] * lst2[-1]
  873. res = self.interpret(fn, [5])
  874. assert res == 42
  875. def test_list_multiply(self):
  876. def fn(i):
  877. lst = [i] * i
  878. ret = len(lst)
  879. if ret:
  880. ret *= lst[-1]
  881. return ret
  882. for arg in (1, 9, 0, -1, -27):
  883. res = self.interpret(fn, [arg])
  884. assert res == fn(arg)
  885. def fn(i):
  886. lst = [i, i + 1] * i
  887. ret = len(lst)
  888. if ret:
  889. ret *= lst[-1]
  890. return ret
  891. for arg in (1, 9, 0, -1, -27):
  892. res = self.interpret(fn, [arg])
  893. assert res == fn(arg)
  894. def fn(i):
  895. lst = i * [i, i + 1]
  896. ret = len(lst)
  897. if ret:
  898. ret *= lst[-1]
  899. return ret
  900. for arg in (1, 9, 0, -1, -27):
  901. res = self.interpret(fn, [arg])
  902. assert res == fn(arg)
  903. def test_list_inplace_multiply(self):
  904. def fn(i):
  905. lst = [i]
  906. lst *= i
  907. ret = len(lst)
  908. if ret:
  909. ret *= lst[-1]
  910. return ret
  911. for arg in (1, 9, 0, -1, -27):
  912. res = self.interpret(fn, [arg])
  913. assert res == fn(arg)
  914. def fn(i):
  915. lst = [i, i + 1]
  916. lst *= i
  917. ret = len(lst)
  918. if ret:
  919. ret *= lst[-1]
  920. return ret
  921. for arg in (1, 9, 0, -1, -27):
  922. res = self.interpret(fn, [arg])
  923. assert res == fn(arg)
  924. def test_indexerror(self):
  925. def fn(i):
  926. l = [5, 8, 3]
  927. try:
  928. l[i] = 99
  929. except IndexError:
  930. pass
  931. try:
  932. del l[i]
  933. except IndexError:
  934. pass
  935. try:
  936. return l[2]
  937. except IndexError:
  938. return -1
  939. res = self.interpret(fn, [6])
  940. assert res == 3
  941. res = self.interpret(fn, [-2])
  942. assert res == -1
  943. def fn(i):
  944. l = [5, 8]
  945. l.append(3)
  946. try:
  947. l[i] = 99
  948. except IndexError:
  949. pass
  950. try:
  951. del l[i]
  952. except IndexError:
  953. pass
  954. try:
  955. return l[2]
  956. except IndexError:
  957. return -1
  958. res = self.interpret(fn, [6])
  959. assert res == 3
  960. res = self.interpret(fn, [-2])
  961. assert res == -1
  962. def test_list_basic_ops(self):
  963. def list_basic_ops(i=int, j=int):
  964. l = [1,2,3]
  965. l.insert(0, 42)
  966. del l[1]
  967. l.append(i)
  968. listlen = len(l)
  969. l.extend(l)
  970. del l[listlen:]
  971. l += [5,6]
  972. l[1] = i
  973. return l[j]
  974. for i in range(6):
  975. for j in range(6):
  976. res = self.interpret(list_basic_ops, [i, j])
  977. assert res == list_basic_ops(i, j)
  978. def test_valueerror(self):
  979. def fn(i):
  980. l = [4, 7, 3]
  981. try:
  982. j = l.index(i)
  983. except ValueError:
  984. j = 100
  985. return j
  986. res = self.interpret(fn, [4])
  987. assert res == 0
  988. res = self.interpret(fn, [7])
  989. assert res == 1
  990. res = self.interpret(fn, [3])
  991. assert res == 2
  992. res = self.interpret(fn, [6])
  993. assert res == 100
  994. def fn(i):
  995. l = [5, 8]
  996. l.append(3)
  997. try:
  998. l[i] = 99
  999. except IndexError:
  1000. pass
  1001. try:
  1002. del l[i]
  1003. except IndexError:
  1004. pass
  1005. try:
  1006. return l[2]
  1007. except IndexError:
  1008. return -1
  1009. res = self.interpret(fn, [6])
  1010. assert res == 3
  1011. res = self.interpret(fn, [-2])
  1012. assert res == -1
  1013. def test_voidlist_prebuilt(self):
  1014. frlist = [Freezing()] * 17
  1015. def mylength(l):
  1016. return len(l)
  1017. def f():
  1018. return mylength(frlist)
  1019. res = self.interpret(f, [])
  1020. assert res == 17
  1021. def test_voidlist_fixed(self):
  1022. fr = Freezing()
  1023. def f():
  1024. return len([fr, fr])
  1025. res = self.interpret(f, [])
  1026. assert res == 2
  1027. def test_voidlist_nonfixed(self):
  1028. class Freezing:
  1029. def _freeze_(self):
  1030. return True
  1031. fr = Freezing()
  1032. def f():
  1033. lst = [fr, fr]
  1034. lst.append(fr)
  1035. del lst[1]
  1036. assert lst[0] is fr
  1037. return len(lst)
  1038. res = self.interpret(f, [])
  1039. assert res == 2
  1040. def test_access_in_try(self):
  1041. def f(sq):
  1042. try:
  1043. return sq[2]
  1044. except ZeroDivisionError:
  1045. return 42
  1046. return -1
  1047. def g(n):
  1048. l = [1] * n
  1049. return f(l)
  1050. res = self.interpret(g, [3])
  1051. assert res == 1
  1052. def test_access_in_try_set(self):
  1053. def f(sq):
  1054. try:
  1055. sq[2] = 77
  1056. except ZeroDivisionError:
  1057. return 42
  1058. return -1
  1059. def g(n):
  1060. l = [1] * n
  1061. f(l)
  1062. return l[2]
  1063. res = self.interpret(g, [3])
  1064. assert res == 77
  1065. def test_list_equality(self):
  1066. def dummyfn(n):
  1067. lst = [12] * n
  1068. assert lst == [12, 12, 12]
  1069. lst2 = [[12, 34], [5], [], [12, 12, 12], [5]]
  1070. assert lst in lst2
  1071. self.interpret(dummyfn, [3])
  1072. def test_list_remove(self):
  1073. def dummyfn(n, p):
  1074. l = range(n)
  1075. l.remove(p)
  1076. return len(l)
  1077. res = self.interpret(dummyfn, [1, 0])
  1078. assert res == 0
  1079. def test_getitem_exc_1(self):
  1080. def f(x):
  1081. l = [1]
  1082. return l[x]
  1083. res = self.interpret(f, [0])
  1084. assert res == 1
  1085. with py.test.raises(LLAssertFailure):
  1086. self.interpret(f, [1])
  1087. def f(x):
  1088. l = [1]
  1089. try:
  1090. return l[x]
  1091. except IndexError:
  1092. return -1
  1093. except Exception:
  1094. return 0
  1095. res = self.interpret(f, [0])
  1096. assert res == 1
  1097. res = self.interpret(f, [1])
  1098. assert res == -1
  1099. def f(x):
  1100. l = [1]
  1101. try:
  1102. return l[x]
  1103. except Exception:
  1104. return 0
  1105. res = self.interpret(f, [0])
  1106. assert res == 1
  1107. res = self.interpret(f, [1])
  1108. assert res == 0
  1109. def f(x):
  1110. l = [1]
  1111. try:
  1112. return l[x]
  1113. except ValueError:
  1114. return 0
  1115. res = self.interpret(f, [0])
  1116. assert res == 1
  1117. def test_getitem_exc_2(self):
  1118. def f(x):
  1119. l = [1]
  1120. return l[x]
  1121. res = self.interpret(f, [0])
  1122. assert res == 1
  1123. with py.test.raises(LLAssertFailure):
  1124. self.interpret(f, [1])
  1125. def f(x):
  1126. l = [1]
  1127. try:
  1128. return l[x]
  1129. except IndexError:
  1130. return -1
  1131. except Exception:
  1132. return 0
  1133. res = self.interpret(f, [0])
  1134. assert res == 1
  1135. res = self.interpret(f, [1])
  1136. assert res == -1
  1137. def f(x):
  1138. l = [1]
  1139. try:
  1140. return l[x]
  1141. except Exception:
  1142. return 0
  1143. res = self.interpret(f, [0])
  1144. assert res == 1
  1145. res = self.interpret(f, [1])
  1146. assert res == 0
  1147. def f(x):
  1148. l = [1]
  1149. try:
  1150. return l[x]
  1151. except ValueError:
  1152. return 0
  1153. res = self.interpret(f, [0])
  1154. assert res == 1
  1155. with py.test.raises(LLAssertFailure):
  1156. self.interpret(f, [1])
  1157. def test_charlist_extension_1(self):
  1158. def f(n):
  1159. s = 'hello%d' % n
  1160. l = ['a', 'b']
  1161. l += s
  1162. return ''.join(l)
  1163. res = self.interpret(f, [58])
  1164. assert self.ll_to_string(res) == 'abhello58'
  1165. def test_unicharlist_extension_1(self):
  1166. def f(n):
  1167. s = 'hello%d' % n
  1168. l = [u'a', u'b']
  1169. l += s
  1170. return ''.join([chr(ord(c)) for c in l])
  1171. res = self.interpret(f, [58])
  1172. assert self.ll_to_string(res) == 'abhello58'
  1173. def test_extend_a_non_char_list_1(self):
  1174. def f(n):
  1175. s = 'hello%d' % n
  1176. l = ['foo', 'bar']
  1177. l += s # NOT SUPPORTED for now if l is not a list of chars
  1178. return ''.join(l)
  1179. py.test.raises(TyperError, self.interpret, f, [58])
  1180. def test_charlist_extension_2(self):
  1181. def f(n, i):
  1182. s = 'hello%d' % n
  1183. assert 0 <= i <= len(s)
  1184. l = ['a', 'b']
  1185. l += s[i:]
  1186. return ''.join(l)
  1187. res = self.interpret(f, [9381701, 3])
  1188. assert self.ll_to_string(res) == 'ablo9381701'
  1189. def test_unicharlist_extension_2(self):
  1190. def f(n, i):
  1191. s = 'hello%d' % n
  1192. assert 0 <= i <= len(s)
  1193. l = [u'a', u'b']
  1194. l += s[i:]
  1195. return ''.join([chr(ord(c)) for c in l])
  1196. res = self.interpret(f, [9381701, 3])
  1197. assert self.ll_to_string(res) == 'ablo9381701'
  1198. def test_extend_a_non_char_list_2(self):
  1199. def f(n, i):
  1200. s = 'hello%d' % n
  1201. assert 0 <= i <= len(s)
  1202. l = ['foo', 'bar']
  1203. l += s[i:] # NOT SUPPORTED for now if l is not a list of chars
  1204. return ''.join(l)
  1205. py.test.raises(TyperError, self.interpret, f, [9381701, 3])
  1206. def test_charlist_extension_3(self):
  1207. def f(n, i, j):
  1208. s = 'hello%d' % n
  1209. assert 0 <= i <= j <= len(s)
  1210. l = ['a', 'b']
  1211. l += s[i:j]
  1212. return ''.join(l)
  1213. res = self.interpret(f, [9381701, 3, 7])
  1214. assert self.ll_to_string(res) == 'ablo93'
  1215. def test_unicharlist_extension_3(self):
  1216. def f(n, i, j):
  1217. s = 'hello%d' % n
  1218. assert 0 <= i <= j <= len(s)
  1219. l = [u'a', u'b']
  1220. l += s[i:j]
  1221. return ''.join([chr(ord(c)) for c in l])
  1222. res = self.interpret(f, [9381701, 3, 7])
  1223. assert self.ll_to_string(res) == 'ablo93'
  1224. def test_charlist_extension_4(self):
  1225. def f(n):
  1226. s = 'hello%d' % n
  1227. l = ['a', 'b']
  1228. l += s[:-1]
  1229. return ''.join(l)
  1230. res = self.interpret(f, [9381701])
  1231. assert self.ll_to_string(res) == 'abhello938170'
  1232. def test_unicharlist_extension_4(self):
  1233. def f(n):
  1234. s = 'hello%d' % n
  1235. l = [u'a', u'b']
  1236. l += s[:-1]
  1237. return ''.join([chr(ord(c)) for c in l])
  1238. res = self.interpret(f, [9381701])
  1239. assert self.ll_to_string(res) == 'abhello938170'
  1240. def test_charlist_extension_5(self):
  1241. def f(count):
  1242. l = ['a', 'b']
  1243. l += '.' * count # char * count
  1244. return ''.join(l)
  1245. res = self.interpret(f, [7])
  1246. assert self.ll_to_string(res) == 'ab.......'
  1247. res = self.interpret(f, [0])
  1248. assert self.ll_to_string(res) == 'ab'
  1249. def test_unicharlist_extension_5(self):
  1250. def f(count):
  1251. l = [u'a', u'b']
  1252. l += '.' * count # NON-UNICODE-char * count
  1253. return ''.join([chr(ord(c)) for c in l])
  1254. res = self.interpret(f, [7])
  1255. assert self.ll_to_string(res) == 'ab.......'
  1256. res = self.interpret(f, [0])
  1257. assert self.ll_to_string(res) == 'ab'
  1258. def test_charlist_extension_6(self):
  1259. def f(count):
  1260. l = ['a', 'b']
  1261. l += count * '.' # count * char
  1262. return ''.join(l)
  1263. res = self.interpret(f, [7])
  1264. assert self.ll_to_string(res) == 'ab.......'
  1265. res = self.interpret(f, [0])
  1266. assert self.ll_to_string(res) == 'ab'
  1267. def test_extend_a_non_char_list_6(self):
  1268. def f(count):
  1269. l = ['foo', 'bar']
  1270. # NOT SUPPORTED for now if l is not a list of chars
  1271. l += count * '.'
  1272. return ''.join(l)
  1273. py.test.raises(TyperError, self.interpret, f, [5])
  1274. def test_r_short_list(self):
  1275. from rpython.rtyper.lltypesystem.rffi import r_short
  1276. from rpython.rlib import rarithmetic
  1277. def f(i):
  1278. l = [r_short(0)] * 10
  1279. l[i+1] = r_short(3)
  1280. return rarithmetic.widen(l[i])
  1281. res = self.interpret(f, [3])
  1282. assert res == 0
  1283. def test_make_new_list(self):
  1284. class A:
  1285. def _freeze_(self):
  1286. return True
  1287. a1 = A()
  1288. a2 = A()
  1289. def f(i):
  1290. lst = [a1, a1]
  1291. lst2 = list(lst)
  1292. lst2.append(a2)
  1293. return lst2[i] is a2
  1294. res = self.interpret(f, [1])
  1295. assert res == False
  1296. res = self.interpret(f, [2])
  1297. assert res == True
  1298. def test_immutable_list_out_of_instance(self):
  1299. for immutable_fields in (["a", "b"], ["a", "b", "y[*]"]):
  1300. class A(object):
  1301. _immutable_fields_ = immutable_fields
  1302. class B(A):
  1303. pass
  1304. def f(i):
  1305. b = B()
  1306. lst = [i]
  1307. lst[0] += 1
  1308. b.y = lst
  1309. ll_assert(b.y is lst, "copying when reading out the attr?")
  1310. return b.y[0]
  1311. res = self.interpret(f, [10])
  1312. assert res == 11
  1313. t, rtyper, graph = self.gengraph(f, [int])
  1314. block = graph.startblock
  1315. op = block.operations[-1]
  1316. assert op.opname == 'direct_call'
  1317. func = op.args[2].value
  1318. assert ('foldable' in func.func_name) == \
  1319. ("y[*]" in immutable_fields)
  1320. def test_hints(self):
  1321. from rpython.rlib.objectmodel import newlist_hint
  1322. strings = ['abc', 'def']
  1323. def f(i):
  1324. z = strings[i]
  1325. x = newlist_hint(sizehint=13)
  1326. x += z
  1327. return ''.join(x)
  1328. res = self.interpret(f, [0])
  1329. assert self.ll_to_string(res) == 'abc'
  1330. def test_memoryerror(self):
  1331. def fn(i):
  1332. lst = [0] * i
  1333. lst[i-1] = 5
  1334. return lst[0]
  1335. res = self.interpret(fn, [1])
  1336. assert res == 5
  1337. res = self.interpret(fn, [2])
  1338. assert res == 0
  1339. self.interpret_raises(MemoryError, fn, [sys.maxint])
  1340. def test_type_erase_fixed_size(self):
  1341. class A(object):
  1342. pass
  1343. class B(object):
  1344. pass
  1345. def f():
  1346. return [A()], [B()]
  1347. t = TranslationContext()
  1348. s = t.buildannotator().build_types(f, [])
  1349. rtyper = t.buildrtyper()
  1350. rtyper.specialize()
  1351. s_A_list = s.items[0]
  1352. s_B_list = s.items[1]
  1353. r_A_list = rtyper.getrepr(s_A_list)
  1354. assert isinstance(r_A_list, self.rlist.FixedSizeListRepr)
  1355. r_B_list = rtyper.getrepr(s_B_list)
  1356. assert isinstance(r_B_list, self.rlist.FixedSizeListRepr)
  1357. assert r_A_list.lowleveltype == r_B_list.lowleveltype
  1358. def test_type_erase_var_size(self):
  1359. class A(object):
  1360. pass
  1361. class B(object):
  1362. pass
  1363. def f():
  1364. la = [A()]
  1365. lb = [B()]
  1366. la.append(None)
  1367. lb.append(None)
  1368. return la, lb
  1369. t = TranslationContext()
  1370. s = t.buildannotator().build_types(f, [])
  1371. rtyper = t.buildrtyper()
  1372. rtyper.specialize()
  1373. s_A_list = s.items[0]
  1374. s_B_list = s.items[1]
  1375. r_A_list = rtyper.getrepr(s_A_list)
  1376. assert isinstance(r_A_list, self.rlist.ListRepr)
  1377. r_B_list = rtyper.getrepr(s_B_list)
  1378. assert isinstance(r_B_list, self.rlist.ListRepr)
  1379. assert r_A_list.lowleveltype == r_B_list.lowleveltype
  1380. def test_no_unneeded_refs(self):
  1381. def fndel(p, q):
  1382. lis = ["5", "3", "99"]
  1383. assert q >= 0
  1384. assert p >= 0
  1385. del lis[p:q]
  1386. return lis
  1387. def fnpop(n):
  1388. lis = ["5", "3", "99"]
  1389. while n:
  1390. lis.pop()
  1391. n -=1
  1392. return lis
  1393. for i in range(2, 3+1):
  1394. lis = self.interpret(fndel, [0, i])
  1395. assert list_is_clear(lis, 3-i)
  1396. for i in range(3):
  1397. lis = self.interpret(fnpop, [i])
  1398. assert list_is_clear(lis, 3-i)
  1399. def test_oopspec(self):
  1400. lst1 = [123, 456] # non-mutated list
  1401. def f(i):
  1402. lst2 = [i]
  1403. lst2.append(42) # mutated list
  1404. return lst1[i] + lst2[i]
  1405. from rpython.annotator import model as annmodel
  1406. _, _, graph = self.gengraph(f, [annmodel.SomeInteger(nonneg=True)])
  1407. block = graph.startblock
  1408. lst1_getitem_op = block.operations[-3] # XXX graph fishing
  1409. lst2_getitem_op = block.operations[-2]
  1410. func1 = lst1_getitem_op.args[2].value
  1411. func2 = lst2_getitem_op.args[2].value
  1412. assert func1.oopspec == 'list.getitem_foldable(l, index)'
  1413. assert not hasattr(func2, 'oopspec')
  1414. def test_iterate_over_immutable_list(self):
  1415. from rpython.rtyper import rlist
  1416. class MyException(Exception):
  1417. pass
  1418. lst = list('abcdef')
  1419. def dummyfn():
  1420. total = 0
  1421. for c in lst:
  1422. total += ord(c)
  1423. return total
  1424. #
  1425. prev = rlist.ll_getitem_foldable_nonneg
  1426. try:
  1427. def seen_ok(l, index):
  1428. if index == 5:
  1429. raise KeyError # expected case
  1430. return prev(l, index)
  1431. rlist.ll_getitem_foldable_nonneg = seen_ok
  1432. e = py.test.raises(LLException, self.interpret, dummyfn, [])
  1433. assert 'KeyError' in str(e.value)
  1434. finally:
  1435. rlist.ll_getitem_foldable_nonneg = prev
  1436. def test_iterate_over_immutable_list_quasiimmut_attr(self):
  1437. from rpython.rtyper import rlist
  1438. class MyException(Exception):
  1439. pass
  1440. class Foo:
  1441. _immutable_fields_ = ['lst?[*]']
  1442. lst = list('abcdef')
  1443. foo = Foo()
  1444. def dummyfn():
  1445. total = 0
  1446. for c in foo.lst:
  1447. total += ord(c)
  1448. return total
  1449. #
  1450. prev = rlist.ll_getitem_foldable_nonneg
  1451. try:
  1452. def seen_ok(l, index):
  1453. if index == 5:
  1454. raise KeyError # expected case
  1455. return prev(l, index)
  1456. rlist.ll_getitem_foldable_nonneg = seen_ok
  1457. e = py.test.raises(LLException, self.interpret, dummyfn, [])
  1458. assert 'KeyError' in str(e.value)
  1459. finally:
  1460. rlist.ll_getitem_foldable_nonneg = prev
  1461. def test_iterate_over_mutable_list(self):
  1462. from rpython.rtyper import rlist
  1463. class MyException(Exception):
  1464. pass
  1465. lst = list('abcdef')
  1466. def dummyfn():
  1467. total = 0
  1468. for c in lst:
  1469. total += ord(c)
  1470. lst[0] = 'x'
  1471. return total
  1472. #
  1473. prev = rlist.ll_getitem_foldable_nonneg
  1474. try:
  1475. def seen_ok(l, index):
  1476. if index == 5:
  1477. raise KeyError # expected case
  1478. return prev(l, index)
  1479. rlist.ll_getitem_foldable_nonneg = seen_ok
  1480. res = self.interpret(dummyfn, [])
  1481. assert res == sum(map(ord, 'abcdef'))
  1482. finally:
  1483. rlist.ll_getitem_foldable_nonneg = prev
  1484. def test_extend_was_not_overallocating(self):
  1485. from rpython.rlib import rgc
  1486. from rpython.rlib.objectmodel import resizelist_hint
  1487. from rpython.rtyper.lltypesystem import lltype
  1488. old_arraycopy = rgc.ll_arraycopy
  1489. try:
  1490. GLOB = lltype.GcStruct('GLOB', ('seen', lltype.Signed))
  1491. glob = lltype.malloc(GLOB, immortal=True)
  1492. glob.seen = 0
  1493. def my_arraycopy(*args):
  1494. glob.seen += 1
  1495. return old_arraycopy(*args)
  1496. rgc.ll_arraycopy = my_arraycopy
  1497. def dummyfn():
  1498. lst = []
  1499. i = 0
  1500. while i < 30:
  1501. i += 1
  1502. resizelist_hint(lst, i)
  1503. lst.append(i)
  1504. return glob.seen
  1505. res = self.interpret(dummyfn, [])
  1506. finally:
  1507. rgc.ll_arraycopy = old_arraycopy
  1508. #
  1509. assert 2 <= res <= 10
  1510. def test_alloc_and_set(self):
  1511. def fn(i):
  1512. lst = [0] * r_uint(i)
  1513. return lst
  1514. t, rtyper, graph = self.gengraph(fn, [int])
  1515. block = graph.startblock
  1516. seen = 0
  1517. for

Large files files are truncated, but you can click here to view the full file