PageRenderTime 51ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/pypy/rpython/test/test_rbuiltin.py

https://bitbucket.org/pypy/pypy/
Python | 595 lines | 588 code | 5 blank | 2 comment | 3 complexity | 70935418660067d4e82cf7d6d8ecadda MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. from pypy.translator.translator import graphof
  2. from pypy.rpython.test import test_llinterp
  3. from pypy.rlib.objectmodel import instantiate, we_are_translated
  4. from pypy.rlib.objectmodel import running_on_llinterp
  5. from pypy.rlib.debug import llinterpcall
  6. from pypy.rpython.lltypesystem import lltype
  7. from pypy.tool import udir
  8. from pypy.rlib.rarithmetic import intmask
  9. from pypy.rlib.rarithmetic import r_int, r_uint, r_longlong, r_ulonglong
  10. from pypy.annotation.builtin import *
  11. from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin
  12. from pypy.rpython.lltypesystem import rffi
  13. from pypy.rpython import extfunc
  14. import py
  15. def enum_direct_calls(translator, func):
  16. blocks = []
  17. graph = graphof(translator, func)
  18. for block in graph.iterblocks():
  19. for op in block.operations:
  20. if op.opname == 'direct_call':
  21. yield op
  22. class BaseTestRbuiltin(BaseRtypingTest):
  23. def test_method_join(self):
  24. # this is tuned to catch a specific bug:
  25. # a wrong rtyper_makekey() for BuiltinMethodRepr
  26. def f():
  27. lst1 = ['abc', 'def']
  28. s1 = ', '.join(lst1)
  29. lst2 = ['1', '2', '3']
  30. s2 = ''.join(lst2)
  31. return s1 + s2
  32. res = self.interpret(f, [])
  33. assert self.ll_to_string(res) == 'abc, def123'
  34. def test_method_repr(self):
  35. def g(n):
  36. if n >= 0:
  37. return "egg"
  38. else:
  39. return "spam"
  40. def f(n):
  41. # this is designed for a specific bug: conversions between
  42. # BuiltinMethodRepr. The append method of the list is passed
  43. # around, and g(-1) below causes a reflowing at the beginning
  44. # of the loop (but not inside the loop). This situation creates
  45. # a newlist returning a SomeList() which '==' but 'is not' the
  46. # SomeList() inside the loop.
  47. x = len([ord(c) for c in g(1)])
  48. g(-1)
  49. return x
  50. res = self.interpret(f, [0])
  51. assert res == 3
  52. def test_chr(self):
  53. def f(x=int):
  54. try:
  55. return chr(x)
  56. except ValueError:
  57. return '?'
  58. res = self.interpret(f, [65])
  59. assert res == 'A'
  60. res = self.interpret(f, [256])
  61. assert res == '?'
  62. res = self.interpret(f, [-1])
  63. assert res == '?'
  64. def test_intmask(self):
  65. def f(x=r_uint):
  66. try:
  67. return intmask(x)
  68. except ValueError:
  69. return 0
  70. res = self.interpret(f, [r_uint(5)])
  71. assert type(res) is int and res == 5
  72. def test_rbuiltin_list(self):
  73. def f():
  74. l=list((1,2,3))
  75. return l == [1,2,3]
  76. def g():
  77. l=list(('he','llo'))
  78. return l == ['he','llo']
  79. def r():
  80. l = ['he','llo']
  81. l1=list(l)
  82. return l == l1 and l is not l1
  83. result = self.interpret(f,[])
  84. assert result
  85. result = self.interpret(g,[])
  86. assert result
  87. result = self.interpret(r,[])
  88. assert result
  89. def test_int_min(self):
  90. def fn(i, j):
  91. return min(i,j)
  92. ev_fun = self.interpret(fn, [0, 0])
  93. assert self.interpret(fn, (1, 2)) == 1
  94. assert self.interpret(fn, (1, -1)) == -1
  95. assert self.interpret(fn, (2, 2)) == 2
  96. assert self.interpret(fn, (-1, -12)) == -12
  97. def test_int_max(self):
  98. def fn(i, j):
  99. return max(i,j)
  100. assert self.interpret(fn, (1, 2)) == 2
  101. assert self.interpret(fn, (1, -1)) == 1
  102. assert self.interpret(fn, (2, 2)) == 2
  103. assert self.interpret(fn, (-1, -12)) == -1
  104. def test_float_min(self):
  105. def fn(i, j):
  106. return min(i, j)
  107. assert self.interpret(fn, (1.9, 2.)) == 1.9
  108. assert self.interpret(fn, (1.5, -1.4)) == -1.4
  109. def test_float_int_min(self):
  110. def fn(i, j):
  111. return min(i, j)
  112. assert self.interpret(fn, (1.9, 2)) == 1.9
  113. assert self.interpret(fn, (1.5, -1)) == -1
  114. def test_float_max(self):
  115. def fn(i, j):
  116. return max(i,j)
  117. assert self.interpret(fn, (1.0, 2.)) == 2
  118. assert self.interpret(fn, (1.1, -1)) == 1.1
  119. def test_builtin_math_floor(self):
  120. import math
  121. def fn(f):
  122. return math.floor(f)
  123. import random
  124. for i in range(5):
  125. rv = 1000 * float(i-10) #random.random()
  126. res = self.interpret(fn, [rv])
  127. assert fn(rv) == res
  128. def test_builtin_math_fmod(self):
  129. import math
  130. def fn(f,y):
  131. return math.fmod(f,y)
  132. for i in range(10):
  133. for j in range(10):
  134. rv = 1000 * float(i-10)
  135. ry = 100 * float(i-10) +0.1
  136. assert self.float_eq(fn(rv,ry), self.interpret(fn, (rv, ry)))
  137. def test_builtin_math_frexp(self):
  138. import math
  139. def fn(f):
  140. return math.frexp(f)
  141. for x in (.5, 1, 1.5, 10/3.0):
  142. for y in (1, -1):
  143. res = self.interpret(fn, [x*y])
  144. mantissa, exponent = math.frexp(x*y)
  145. assert (self.float_eq(res.item0, mantissa) and
  146. self.float_eq(res.item1, exponent))
  147. def test_builtin_math_ldexp(self):
  148. import math
  149. def fn(a, b):
  150. return math.ldexp(a, b)
  151. assert self.interpret(fn, [1, 2]) == 4
  152. self.interpret_raises(OverflowError, fn, [1, 100000])
  153. def test_builtin_math_modf(self):
  154. import math
  155. def fn(f):
  156. return math.modf(f)
  157. res = self.interpret(fn, [10/3.0])
  158. intpart, fracpart = math.modf(10/3.0)
  159. assert self.float_eq(res.item0, intpart) and self.float_eq(res.item1, fracpart)
  160. def test_os_getcwd(self):
  161. import os
  162. def fn():
  163. return os.getcwd()
  164. res = self.interpret(fn, [])
  165. assert self.ll_to_string(res) == fn()
  166. def test_os_write(self):
  167. tmpdir = str(udir.udir.join("os_write_test"))
  168. import os
  169. def wr_open(fname):
  170. fd = os.open(fname, os.O_WRONLY|os.O_CREAT, 0777)
  171. os.write(fd, "hello world")
  172. return fd
  173. def f():
  174. return wr_open(tmpdir)
  175. res = self.interpret(f, [])
  176. os.close(res)
  177. hello = open(tmpdir).read()
  178. assert hello == "hello world"
  179. def test_os_write_single_char(self):
  180. tmpdir = str(udir.udir.join("os_write_test_char"))
  181. import os
  182. def wr_open(fname):
  183. fd = os.open(fname, os.O_WRONLY|os.O_CREAT, 0777)
  184. os.write(fd, "x")
  185. return fd
  186. def f():
  187. return wr_open(tmpdir)
  188. res = self.interpret(f, [])
  189. os.close(res)
  190. hello = open(tmpdir).read()
  191. assert hello == "x"
  192. def test_os_read(self):
  193. import os
  194. tmpfile = str(udir.udir.join("os_read_test"))
  195. f = file(tmpfile, 'w')
  196. f.write('hello world')
  197. f.close()
  198. def fn():
  199. fd = os.open(tmpfile, os.O_RDONLY, 0777)
  200. return os.read(fd, 4096)
  201. res = self.interpret(fn, [])
  202. assert self.ll_to_string(res) == 'hello world'
  203. def test_os_lseek(self):
  204. self._skip_llinterpreter("os.lseek", skipOO=False)
  205. import os
  206. tmpfile = str(udir.udir.join("os_lseek_test"))
  207. f = file(tmpfile, 'w')
  208. f.write('0123456789')
  209. f.close()
  210. SEEK_SET = 0
  211. SEEK_CUR = 1
  212. SEEK_END = 2
  213. def fn():
  214. fd = os.open(tmpfile, os.O_RDONLY, 0777)
  215. res = ''
  216. os.lseek(fd, 5, SEEK_SET)
  217. res += os.read(fd, 1)
  218. os.lseek(fd, 2, SEEK_CUR)
  219. res += os.read(fd, 1)
  220. os.lseek(fd, -2, SEEK_CUR)
  221. res += os.read(fd, 1)
  222. os.lseek(fd, -1, SEEK_END)
  223. res += os.read(fd, 1)
  224. os.close(fd)
  225. return res
  226. res1 = fn()
  227. res2 = self.ll_to_string(self.interpret(fn, []))
  228. assert res1 == res2
  229. def test_os_dup(self):
  230. import os
  231. def fn(fd):
  232. return os.dup(fd)
  233. res = self.interpret(fn, [0])
  234. try:
  235. os.close(res)
  236. except OSError:
  237. pass
  238. count = 0
  239. for dir_call in enum_direct_calls(test_llinterp.typer.annotator.translator, fn):
  240. cfptr = dir_call.args[0]
  241. assert self.get_callable(cfptr.value).__name__.startswith('dup')
  242. count += 1
  243. assert count == 1
  244. def test_os_open(self):
  245. tmpdir = str(udir.udir.join("os_open_test"))
  246. import os
  247. def wr_open(fname):
  248. return os.open(fname, os.O_WRONLY|os.O_CREAT, 0777)
  249. def f():
  250. return wr_open(tmpdir)
  251. res = self.interpret(f, [])
  252. os.close(res)
  253. count = 0
  254. for dir_call in enum_direct_calls(test_llinterp.typer.annotator.translator, wr_open):
  255. cfptr = dir_call.args[0]
  256. assert self.get_callable(cfptr.value).__name__.startswith('os_open')
  257. count += 1
  258. assert count == 1
  259. def test_os_path_exists(self):
  260. self._skip_llinterpreter("os.stat()")
  261. from pypy.rpython.annlowlevel import hlstr
  262. import os
  263. def f(fn):
  264. fn = hlstr(fn)
  265. return os.path.exists(fn)
  266. filename = self.string_to_ll(str(py.path.local(__file__)))
  267. assert self.interpret(f, [filename]) == True
  268. #assert self.interpret(f, [
  269. # self.string_to_ll("strange_filename_that_looks_improbable.sde")]) == False
  270. def test_os_isdir(self):
  271. self._skip_llinterpreter("os.stat()")
  272. from pypy.rpython.annlowlevel import hlstr
  273. import os
  274. def f(fn):
  275. fn = hlstr(fn)
  276. return os.path.isdir(fn)
  277. assert self.interpret(f, [self.string_to_ll("/")]) == True
  278. assert self.interpret(f, [self.string_to_ll(str(py.path.local(__file__)))]) == False
  279. assert self.interpret(f, [self.string_to_ll("another/unlikely/directory/name")]) == False
  280. def test_pbc_isTrue(self):
  281. class C:
  282. def f(self):
  283. pass
  284. def g(obj):
  285. return bool(obj)
  286. def fn(neg):
  287. c = C.f
  288. return g(c)
  289. assert self.interpret(fn, [True])
  290. def fn(neg):
  291. c = None
  292. return g(c)
  293. assert not self.interpret(fn, [True])
  294. def test_const_isinstance(self):
  295. class B(object):
  296. pass
  297. def f():
  298. b = B()
  299. return isinstance(b, B)
  300. res = self.interpret(f, [])
  301. assert res is True
  302. def test_isinstance(self):
  303. class A(object):
  304. pass
  305. class B(A):
  306. pass
  307. class C(A):
  308. pass
  309. def f(x, y):
  310. if x == 1:
  311. a = A()
  312. elif x == 2:
  313. a = B()
  314. else:
  315. a = C()
  316. if y == 1:
  317. res = isinstance(a, A)
  318. cls = A
  319. elif y == 2:
  320. res = isinstance(a, B)
  321. cls = B
  322. else:
  323. res = isinstance(a, C)
  324. cls = C
  325. return int(res) + 2 * isinstance(a, cls)
  326. for x in [1, 2, 3]:
  327. for y in [1, 2, 3]:
  328. res = self.interpret(f, [x, y])
  329. assert res == isinstance([A(), B(), C()][x-1], [A, B, C][y-1]) * 3
  330. def test_isinstance_list(self):
  331. def f(i):
  332. if i == 0:
  333. l = []
  334. else:
  335. l = None
  336. return isinstance(l, list)
  337. res = self.interpret(f, [0])
  338. assert res is True
  339. res = self.interpret(f, [1])
  340. assert res is False
  341. def test_instantiate(self):
  342. class A:
  343. pass
  344. def f():
  345. return instantiate(A)
  346. res = self.interpret(f, [])
  347. assert self.class_name(res) == 'A'
  348. def test_instantiate_multiple(self):
  349. class A:
  350. pass
  351. class B(A):
  352. pass
  353. def f(i):
  354. if i == 1:
  355. cls = A
  356. else:
  357. cls = B
  358. return instantiate(cls)
  359. res = self.interpret(f, [1])
  360. assert self.class_name(res) == 'A'
  361. res = self.interpret(f, [2])
  362. assert self.class_name(res) == 'B'
  363. def test_os_path_join(self):
  364. self._skip_llinterpreter("os path oofakeimpl", skipLL=False)
  365. import os.path
  366. def fn(a, b):
  367. return os.path.join(a, b)
  368. res = self.ll_to_string(self.interpret(fn, ['a', 'b']))
  369. assert res == os.path.join('a', 'b')
  370. def test_exceptions(self):
  371. def fn(a):
  372. try:
  373. a += int(str(int(a)))
  374. a += int(int(a > 5))
  375. finally:
  376. return a
  377. res = self.interpret(fn, [3.25])
  378. assert res == 7.25
  379. def test_debug_llinterpcall(self):
  380. S = lltype.Struct('S', ('m', lltype.Signed))
  381. SPTR = lltype.Ptr(S)
  382. def foo(n):
  383. "NOT_RPYTHON"
  384. s = lltype.malloc(S, immortal=True)
  385. s.m = eval("n*6", locals())
  386. return s
  387. def fn(n):
  388. if running_on_llinterp:
  389. return llinterpcall(SPTR, foo, n).m
  390. else:
  391. return 321
  392. res = self.interpret(fn, [7])
  393. assert res == 42
  394. from pypy.translator.c.test.test_genc import compile
  395. f = compile(fn, [int])
  396. res = f(7)
  397. assert res == 321
  398. def test_id(self):
  399. from pypy.rlib.objectmodel import compute_unique_id
  400. from pypy.rlib.objectmodel import current_object_addr_as_int
  401. class A:
  402. pass
  403. def fn():
  404. a1 = A()
  405. a2 = A()
  406. return (compute_unique_id(a1), current_object_addr_as_int(a1),
  407. compute_unique_id(a2), current_object_addr_as_int(a2))
  408. res = self.interpret(fn, [])
  409. x0, x1, x2, x3 = self.ll_unpack_tuple(res, 4)
  410. assert isinstance(x0, (int, r_longlong))
  411. assert isinstance(x1, int)
  412. assert isinstance(x2, (int, r_longlong))
  413. assert isinstance(x3, int)
  414. assert x0 != x2
  415. # the following checks are probably too precise, but work at
  416. # least on top of llinterp
  417. if type(self) is TestLLtype:
  418. assert x1 == intmask(x0)
  419. assert x3 == intmask(x2)
  420. def test_id_on_builtins(self):
  421. from pypy.rlib.objectmodel import compute_unique_id
  422. from pypy.rlib.rstring import StringBuilder, UnicodeBuilder
  423. def fn():
  424. return (compute_unique_id("foo"),
  425. compute_unique_id(u"bar"),
  426. compute_unique_id([1]),
  427. compute_unique_id({"foo": 3}),
  428. compute_unique_id(StringBuilder()),
  429. compute_unique_id(UnicodeBuilder()))
  430. res = self.interpret(fn, [])
  431. for id in self.ll_unpack_tuple(res, 6):
  432. assert isinstance(id, (int, r_longlong))
  433. def test_uniqueness_of_id_on_strings(self):
  434. from pypy.rlib.objectmodel import compute_unique_id
  435. def fn(s1, s2):
  436. return (compute_unique_id(s1), compute_unique_id(s2))
  437. s1 = "foo"
  438. s2 = ''.join(['f','oo'])
  439. res = self.interpret(fn, [self.string_to_ll(s1), self.string_to_ll(s2)])
  440. i1, i2 = self.ll_unpack_tuple(res, 2)
  441. assert i1 != i2
  442. def test_cast_primitive(self):
  443. from pypy.rpython.annlowlevel import LowLevelAnnotatorPolicy
  444. def llf(u):
  445. return lltype.cast_primitive(lltype.Signed, u)
  446. res = self.interpret(llf, [r_uint(-1)], policy=LowLevelAnnotatorPolicy())
  447. assert res == -1
  448. res = self.interpret(llf, ['x'], policy=LowLevelAnnotatorPolicy())
  449. assert res == ord('x')
  450. def llf(v):
  451. return lltype.cast_primitive(lltype.Unsigned, v)
  452. res = self.interpret(llf, [-1], policy=LowLevelAnnotatorPolicy())
  453. assert res == r_uint(-1)
  454. res = self.interpret(llf, [u'x'], policy=LowLevelAnnotatorPolicy())
  455. assert res == ord(u'x')
  456. res = self.interpret(llf, [1.0], policy=LowLevelAnnotatorPolicy())
  457. assert res == r_uint(1)
  458. def llf(v):
  459. return lltype.cast_primitive(lltype.Char, v)
  460. res = self.interpret(llf, [ord('x')], policy=LowLevelAnnotatorPolicy())
  461. assert res == 'x'
  462. def llf(v):
  463. return lltype.cast_primitive(lltype.UniChar, v)
  464. res = self.interpret(llf, [ord('x')], policy=LowLevelAnnotatorPolicy())
  465. assert res == u'x'
  466. def llf(v):
  467. return lltype.cast_primitive(rffi.SHORT, v)
  468. res = self.interpret(llf, [123], policy=LowLevelAnnotatorPolicy())
  469. assert res == 123
  470. def llf(v):
  471. return lltype.cast_primitive(lltype.Signed, v)
  472. res = self.interpret(llf, [rffi.r_short(123)], policy=LowLevelAnnotatorPolicy())
  473. assert res == 123
  474. def test_force_cast(self):
  475. def llfn(v):
  476. return rffi.cast(rffi.SHORT, v)
  477. res = self.interpret(llfn, [0x12345678])
  478. assert res == 0x5678
  479. class TestLLtype(BaseTestRbuiltin, LLRtypeMixin):
  480. def test_isinstance_obj(self):
  481. _1 = lltype.pyobjectptr(1)
  482. def f(x):
  483. return isinstance(x, int)
  484. res = self.interpret(f, [_1], someobjects=True)
  485. assert res is True
  486. _1_0 = lltype.pyobjectptr(1.0)
  487. res = self.interpret(f, [_1_0], someobjects=True)
  488. assert res is False
  489. def test_hasattr(self):
  490. class A(object):
  491. def __init__(self):
  492. self.x = 42
  493. def f(i):
  494. a = A()
  495. if i==0: return int(hasattr(A, '__init__'))
  496. if i==1: return int(hasattr(A, 'y'))
  497. if i==2: return int(hasattr(42, 'x'))
  498. for x, y in zip(range(3), (1, 0, 0)):
  499. res = self.interpret(f, [x], someobjects=True)
  500. assert res._obj.value == y
  501. # hmm, would like to test against PyObj, is this the wrong place/way?
  502. def test_cast(self):
  503. def llfn(v):
  504. return rffi.cast(rffi.VOIDP, v)
  505. res = self.interpret(llfn, [r_ulonglong(0)])
  506. assert res == lltype.nullptr(rffi.VOIDP.TO)
  507. #
  508. def llfn(v):
  509. return rffi.cast(rffi.LONGLONG, v)
  510. res = self.interpret(llfn, [lltype.nullptr(rffi.VOIDP.TO)])
  511. assert res == 0
  512. if r_longlong is not r_int:
  513. assert isinstance(res, r_longlong)
  514. else:
  515. assert isinstance(res, int)
  516. #
  517. def llfn(v):
  518. return rffi.cast(rffi.ULONGLONG, v)
  519. res = self.interpret(llfn, [lltype.nullptr(rffi.VOIDP.TO)])
  520. assert res == 0
  521. assert isinstance(res, r_ulonglong)
  522. class TestOOtype(BaseTestRbuiltin, OORtypeMixin):
  523. def test_instantiate_multiple_meta(self):
  524. class A:
  525. x = 2
  526. class B(A):
  527. x = 3
  528. def do_stuff(cls):
  529. return cls.x
  530. def f(i):
  531. if i == 1:
  532. cls = A
  533. else:
  534. cls = B
  535. do_stuff(cls)
  536. return instantiate(cls)
  537. res = self.interpret(f, [1])
  538. assert res.getmeta() # check that it exists