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

/rpython/annotator/test/test_annrpython.py

https://bitbucket.org/pypy/pypy/
Python | 4652 lines | 4237 code | 333 blank | 82 comment | 134 complexity | 110d1c09fbd137bc641194cbba8997c5 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. from __future__ import with_statement
  2. import py.test
  3. import sys
  4. from collections import OrderedDict
  5. from rpython.conftest import option
  6. from rpython.annotator import model as annmodel
  7. from rpython.annotator.model import AnnotatorError, UnionError
  8. from rpython.annotator.annrpython import RPythonAnnotator as _RPythonAnnotator
  9. from rpython.annotator.classdesc import NoSuchAttrError
  10. from rpython.translator.translator import graphof as tgraphof
  11. from rpython.annotator.policy import AnnotatorPolicy
  12. from rpython.annotator.signature import Sig, SignatureError
  13. from rpython.annotator.listdef import ListDef, ListChangeUnallowed
  14. from rpython.annotator.dictdef import DictDef
  15. from rpython.flowspace.model import *
  16. from rpython.rlib.rarithmetic import r_uint, base_int, r_longlong, r_ulonglong
  17. from rpython.rlib.rarithmetic import r_singlefloat
  18. from rpython.rlib import objectmodel
  19. from rpython.flowspace.flowcontext import FlowingError
  20. from rpython.flowspace.operation import op
  21. from rpython.translator.test import snippet
  22. def graphof(a, func):
  23. return tgraphof(a.translator, func)
  24. def listitem(s_list):
  25. assert isinstance(s_list, annmodel.SomeList)
  26. return s_list.listdef.listitem.s_value
  27. def somelist(s_type):
  28. return annmodel.SomeList(ListDef(None, s_type))
  29. def dictkey(s_dict):
  30. assert isinstance(s_dict, annmodel.SomeDict)
  31. return s_dict.dictdef.dictkey.s_value
  32. def dictvalue(s_dict):
  33. assert isinstance(s_dict, annmodel.SomeDict)
  34. return s_dict.dictdef.dictvalue.s_value
  35. def somedict(annotator, s_key, s_value):
  36. return annmodel.SomeDict(DictDef(annotator.bookkeeper, s_key, s_value))
  37. class TestAnnotateTestCase:
  38. def teardown_method(self, meth):
  39. assert annmodel.s_Bool == annmodel.SomeBool()
  40. class RPythonAnnotator(_RPythonAnnotator):
  41. def build_types(self, *args):
  42. s = _RPythonAnnotator.build_types(self, *args)
  43. self.validate()
  44. if option.view:
  45. self.translator.view()
  46. return s
  47. def test_simple_func(self):
  48. """
  49. one test source:
  50. def f(x):
  51. return x+1
  52. """
  53. x = Variable("x")
  54. oper = op.add(x, Constant(1))
  55. block = Block([x])
  56. fun = FunctionGraph("f", block)
  57. block.operations.append(oper)
  58. block.closeblock(Link([oper.result], fun.returnblock))
  59. a = self.RPythonAnnotator()
  60. a.addpendingblock(fun, fun.startblock, [annmodel.SomeInteger()])
  61. a.complete()
  62. assert a.gettype(fun.getreturnvar()) == int
  63. def test_while(self):
  64. """
  65. one test source:
  66. def f(i):
  67. while i > 0:
  68. i = i - 1
  69. return i
  70. """
  71. i1 = Variable("i1")
  72. i2 = Variable("i2")
  73. conditionop = op.gt(i1, Constant(0))
  74. decop = op.add(i2, Constant(-1))
  75. headerblock = Block([i1])
  76. whileblock = Block([i2])
  77. fun = FunctionGraph("f", headerblock)
  78. headerblock.operations.append(conditionop)
  79. headerblock.exitswitch = conditionop.result
  80. headerblock.closeblock(Link([i1], fun.returnblock, False),
  81. Link([i1], whileblock, True))
  82. whileblock.operations.append(decop)
  83. whileblock.closeblock(Link([decop.result], headerblock))
  84. a = self.RPythonAnnotator()
  85. a.addpendingblock(fun, fun.startblock, [annmodel.SomeInteger()])
  86. a.complete()
  87. assert a.gettype(fun.getreturnvar()) == int
  88. def test_while_sum(self):
  89. """
  90. one test source:
  91. def f(i):
  92. sum = 0
  93. while i > 0:
  94. sum = sum + i
  95. i = i - 1
  96. return sum
  97. """
  98. i1 = Variable("i1")
  99. i2 = Variable("i2")
  100. i3 = Variable("i3")
  101. sum2 = Variable("sum2")
  102. sum3 = Variable("sum3")
  103. conditionop = op.gt(i2, Constant(0))
  104. decop = op.add(i3, Constant(-1))
  105. addop = op.add(i3, sum3)
  106. startblock = Block([i1])
  107. headerblock = Block([i2, sum2])
  108. whileblock = Block([i3, sum3])
  109. fun = FunctionGraph("f", startblock)
  110. startblock.closeblock(Link([i1, Constant(0)], headerblock))
  111. headerblock.operations.append(conditionop)
  112. headerblock.exitswitch = conditionop.result
  113. headerblock.closeblock(Link([sum2], fun.returnblock, False),
  114. Link([i2, sum2], whileblock, True))
  115. whileblock.operations.append(addop)
  116. whileblock.operations.append(decop)
  117. whileblock.closeblock(Link([decop.result, addop.result], headerblock))
  118. a = self.RPythonAnnotator()
  119. a.addpendingblock(fun, fun.startblock, [annmodel.SomeInteger()])
  120. a.complete()
  121. assert a.gettype(fun.getreturnvar()) == int
  122. def test_f_calls_g(self):
  123. a = self.RPythonAnnotator()
  124. s = a.build_types(f_calls_g, [int])
  125. # result should be an integer
  126. assert s.knowntype == int
  127. def test_lists(self):
  128. a = self.RPythonAnnotator()
  129. end_cell = a.build_types(snippet.poor_man_rev_range, [int])
  130. # result should be a list of integers
  131. assert listitem(end_cell).knowntype == int
  132. def test_factorial(self):
  133. a = self.RPythonAnnotator()
  134. s = a.build_types(snippet.factorial, [int])
  135. # result should be an integer
  136. assert s.knowntype == int
  137. def test_factorial2(self):
  138. a = self.RPythonAnnotator()
  139. s = a.build_types(snippet.factorial2, [int])
  140. # result should be an integer
  141. assert s.knowntype == int
  142. def test_build_instance(self):
  143. a = self.RPythonAnnotator()
  144. s = a.build_types(snippet.build_instance, [])
  145. # result should be a snippet.C instance
  146. assert isinstance(s, annmodel.SomeInstance)
  147. assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.C)
  148. def test_set_attr(self):
  149. a = self.RPythonAnnotator()
  150. s = a.build_types(snippet.set_attr, [])
  151. # result should be an integer
  152. assert s.knowntype == int
  153. def test_merge_setattr(self):
  154. a = self.RPythonAnnotator()
  155. s = a.build_types(snippet.merge_setattr, [int])
  156. # result should be an integer
  157. assert s.knowntype == int
  158. def test_inheritance1(self):
  159. a = self.RPythonAnnotator()
  160. s = a.build_types(snippet.inheritance1, [])
  161. # result should be exactly:
  162. assert s == annmodel.SomeTuple([
  163. a.bookkeeper.immutablevalue(()),
  164. annmodel.SomeInteger()
  165. ])
  166. def test_poor_man_range(self):
  167. a = self.RPythonAnnotator()
  168. s = a.build_types(snippet.poor_man_range, [int])
  169. # result should be a list of integers
  170. assert listitem(s).knowntype == int
  171. def test_staticmethod(self):
  172. class X(object):
  173. @staticmethod
  174. def stat(value):
  175. return value + 4
  176. def f(v):
  177. return X().stat(v)
  178. a = self.RPythonAnnotator()
  179. s = a.build_types(f, [int])
  180. assert isinstance(s, annmodel.SomeInteger)
  181. def test_classmethod(self):
  182. class X(object):
  183. @classmethod
  184. def meth(cls):
  185. return None
  186. def f():
  187. return X().meth()
  188. a = self.RPythonAnnotator()
  189. py.test.raises(AnnotatorError, a.build_types, f, [])
  190. def test_methodcall1(self):
  191. a = self.RPythonAnnotator()
  192. s = a.build_types(snippet._methodcall1, [int])
  193. # result should be a tuple of (C, positive_int)
  194. assert s.knowntype == tuple
  195. assert len(s.items) == 2
  196. s0 = s.items[0]
  197. assert isinstance(s0, annmodel.SomeInstance)
  198. assert s0.classdef == a.bookkeeper.getuniqueclassdef(snippet.C)
  199. assert s.items[1].knowntype == int
  200. assert s.items[1].nonneg == True
  201. def test_classes_methodcall1(self):
  202. a = self.RPythonAnnotator()
  203. a.build_types(snippet._methodcall1, [int])
  204. # the user classes should have the following attributes:
  205. getcdef = a.bookkeeper.getuniqueclassdef
  206. assert getcdef(snippet.F).attrs.keys() == ['m']
  207. assert getcdef(snippet.G).attrs.keys() == ['m2']
  208. assert getcdef(snippet.H).attrs.keys() == ['attr']
  209. assert getcdef(snippet.H).about_attribute('attr') == (
  210. a.bookkeeper.immutablevalue(1))
  211. def test_generaldict(self):
  212. a = self.RPythonAnnotator()
  213. s = a.build_types(snippet.generaldict, [str, int, str, int])
  214. # result should be an integer
  215. assert s.knowntype == int
  216. def test_somebug1(self):
  217. a = self.RPythonAnnotator()
  218. s = a.build_types(snippet._somebug1, [int])
  219. # result should be a built-in method
  220. assert isinstance(s, annmodel.SomeBuiltin)
  221. def test_with_init(self):
  222. a = self.RPythonAnnotator()
  223. s = a.build_types(snippet.with_init, [int])
  224. # result should be an integer
  225. assert s.knowntype == int
  226. def test_with_more_init(self):
  227. a = self.RPythonAnnotator()
  228. s = a.build_types(snippet.with_more_init, [int, bool])
  229. # the user classes should have the following attributes:
  230. getcdef = a.bookkeeper.getuniqueclassdef
  231. # XXX on which class should the attribute 'a' appear? We only
  232. # ever flow WithInit.__init__ with a self which is an instance
  233. # of WithMoreInit, so currently it appears on WithMoreInit.
  234. assert getcdef(snippet.WithMoreInit).about_attribute('a') == (
  235. annmodel.SomeInteger())
  236. assert getcdef(snippet.WithMoreInit).about_attribute('b') == (
  237. annmodel.SomeBool())
  238. def test_global_instance(self):
  239. a = self.RPythonAnnotator()
  240. s = a.build_types(snippet.global_instance, [])
  241. # currently this returns the constant 42.
  242. # XXX not sure this is the best behavior...
  243. assert s == a.bookkeeper.immutablevalue(42)
  244. def test_call_five(self):
  245. a = self.RPythonAnnotator()
  246. s = a.build_types(snippet.call_five, [])
  247. # returns should be a list of constants (= 5)
  248. assert listitem(s) == a.bookkeeper.immutablevalue(5)
  249. def test_call_five_six(self):
  250. a = self.RPythonAnnotator()
  251. s = a.build_types(snippet.call_five_six, [])
  252. # returns should be a list of positive integers
  253. assert listitem(s) == annmodel.SomeInteger(nonneg=True)
  254. def test_constant_result(self):
  255. a = self.RPythonAnnotator()
  256. s = a.build_types(snippet.constant_result, [])
  257. #a.translator.simplify()
  258. # must return "yadda"
  259. assert s == a.bookkeeper.immutablevalue("yadda")
  260. graphs = a.translator.graphs
  261. assert len(graphs) == 2
  262. assert graphs[0].func is snippet.constant_result
  263. assert graphs[1].func is snippet.forty_two
  264. a.simplify()
  265. #a.translator.view()
  266. def test_flow_type_info(self):
  267. a = self.RPythonAnnotator()
  268. s = a.build_types(snippet.flow_type_info, [int])
  269. a.simplify()
  270. assert s.knowntype == int
  271. a = self.RPythonAnnotator()
  272. s = a.build_types(snippet.flow_type_info, [str])
  273. a.simplify()
  274. assert s.knowntype == int
  275. def test_flow_type_info_2(self):
  276. a = self.RPythonAnnotator()
  277. s = a.build_types(snippet.flow_type_info,
  278. [annmodel.SomeInteger(nonneg=True)])
  279. # this checks that isinstance(i, int) didn't lose the
  280. # actually more precise information that i is non-negative
  281. assert s == annmodel.SomeInteger(nonneg=True)
  282. def test_flow_usertype_info(self):
  283. a = self.RPythonAnnotator()
  284. s = a.build_types(snippet.flow_usertype_info, [snippet.WithInit])
  285. #a.translator.view()
  286. assert isinstance(s, annmodel.SomeInstance)
  287. assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.WithInit)
  288. def test_flow_usertype_info2(self):
  289. a = self.RPythonAnnotator()
  290. s = a.build_types(snippet.flow_usertype_info, [snippet.WithMoreInit])
  291. #a.translator.view()
  292. assert isinstance(s, annmodel.SomeInstance)
  293. assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.WithMoreInit)
  294. def test_mergefunctions(self):
  295. a = self.RPythonAnnotator()
  296. s = a.build_types(snippet.mergefunctions, [int])
  297. # the test is mostly that the above line hasn't blown up
  298. # but let's at least check *something*
  299. assert isinstance(s, annmodel.SomePBC)
  300. def test_func_calls_func_which_just_raises(self):
  301. a = self.RPythonAnnotator()
  302. s = a.build_types(snippet.funccallsex, [])
  303. # the test is mostly that the above line hasn't blown up
  304. # but let's at least check *something*
  305. #self.assert_(isinstance(s, SomeCallable))
  306. def test_tuple_unpack_from_const_tuple_with_different_types(self):
  307. a = self.RPythonAnnotator()
  308. s = a.build_types(snippet.func_arg_unpack, [])
  309. assert isinstance(s, annmodel.SomeInteger)
  310. assert s.const == 3
  311. def test_star_unpack_list(self):
  312. def g():
  313. pass
  314. def f(l):
  315. return g(*l)
  316. a = self.RPythonAnnotator()
  317. with py.test.raises(AnnotatorError):
  318. a.build_types(f, [[int]])
  319. def test_star_unpack_and_keywords(self):
  320. def g(a, b, c=0, d=0):
  321. return a + b + c + d
  322. def f(a, b):
  323. return g(a, *(b,), d=5)
  324. a = self.RPythonAnnotator()
  325. s_result = a.build_types(f, [int, int])
  326. assert isinstance(s_result, annmodel.SomeInteger)
  327. def test_pbc_attr_preserved_on_instance(self):
  328. a = self.RPythonAnnotator()
  329. s = a.build_types(snippet.preserve_pbc_attr_on_instance, [bool])
  330. #a.simplify()
  331. #a.translator.view()
  332. assert s == annmodel.SomeInteger(nonneg=True)
  333. #self.assertEquals(s.__class__, annmodel.SomeInteger)
  334. def test_pbc_attr_preserved_on_instance_with_slots(self):
  335. a = self.RPythonAnnotator()
  336. s = a.build_types(snippet.preserve_pbc_attr_on_instance_with_slots,
  337. [bool])
  338. assert s == annmodel.SomeInteger(nonneg=True)
  339. def test_is_and_knowntype_data(self):
  340. a = self.RPythonAnnotator()
  341. s = a.build_types(snippet.is_and_knowntype, [str])
  342. #a.simplify()
  343. #a.translator.view()
  344. assert s == a.bookkeeper.immutablevalue(None)
  345. def test_isinstance_and_knowntype_data(self):
  346. a = self.RPythonAnnotator()
  347. x = a.bookkeeper.immutablevalue(snippet.apbc)
  348. s = a.build_types(snippet.isinstance_and_knowntype, [x])
  349. #a.simplify()
  350. #a.translator.view()
  351. assert s == x
  352. def test_somepbc_simplify(self):
  353. a = self.RPythonAnnotator()
  354. # this example used to trigger an AssertionError
  355. a.build_types(snippet.somepbc_simplify, [])
  356. def test_builtin_methods(self):
  357. a = self.RPythonAnnotator()
  358. iv = a.bookkeeper.immutablevalue
  359. # this checks that some built-in methods are really supported by
  360. # the annotator (it doesn't check that they operate property, though)
  361. for example, methname, s_example in [
  362. ('', 'join', annmodel.SomeString()),
  363. ([], 'append', somelist(annmodel.s_Int)),
  364. ([], 'extend', somelist(annmodel.s_Int)),
  365. ([], 'reverse', somelist(annmodel.s_Int)),
  366. ([], 'insert', somelist(annmodel.s_Int)),
  367. ([], 'pop', somelist(annmodel.s_Int)),
  368. ]:
  369. constmeth = getattr(example, methname)
  370. s_constmeth = iv(constmeth)
  371. assert isinstance(s_constmeth, annmodel.SomeBuiltin)
  372. s_meth = s_example.getattr(iv(methname))
  373. assert isinstance(s_constmeth, annmodel.SomeBuiltin)
  374. def test_str_join(self):
  375. a = self.RPythonAnnotator()
  376. def g(n):
  377. if n:
  378. return ["foo", "bar"]
  379. def f(n):
  380. g(0)
  381. return ''.join(g(n))
  382. s = a.build_types(f, [int])
  383. assert s.knowntype == str
  384. assert s.no_nul
  385. def test_unicode_join(self):
  386. a = self.RPythonAnnotator()
  387. def g(n):
  388. if n:
  389. return [u"foo", u"bar"]
  390. def f(n):
  391. g(0)
  392. return u''.join(g(n))
  393. s = a.build_types(f, [int])
  394. assert s.knowntype == unicode
  395. assert s.no_nul
  396. def test_str_split(self):
  397. a = self.RPythonAnnotator()
  398. def g(n):
  399. if n:
  400. return "test string"
  401. def f(n):
  402. if n:
  403. return g(n).split(' ')
  404. s = a.build_types(f, [int])
  405. assert isinstance(s, annmodel.SomeList)
  406. s_item = s.listdef.listitem.s_value
  407. assert s_item.no_nul
  408. def test_unicode_split(self):
  409. a = self.RPythonAnnotator()
  410. def g(n):
  411. if n:
  412. return u"test string"
  413. def f(n):
  414. if n:
  415. return g(n).split(u' ')
  416. s = a.build_types(f, [int])
  417. assert isinstance(s, annmodel.SomeList)
  418. s_item = s.listdef.listitem.s_value
  419. assert s_item.no_nul
  420. def test_str_split_nul(self):
  421. def f(n):
  422. return n.split('\0')[0]
  423. a = self.RPythonAnnotator()
  424. a.translator.config.translation.check_str_without_nul = True
  425. s = a.build_types(f, [annmodel.SomeString(no_nul=False, can_be_None=False)])
  426. assert isinstance(s, annmodel.SomeString)
  427. assert not s.can_be_None
  428. assert s.no_nul
  429. def g(n):
  430. return n.split('\0', 1)[0]
  431. a = self.RPythonAnnotator()
  432. a.translator.config.translation.check_str_without_nul = True
  433. s = a.build_types(g, [annmodel.SomeString(no_nul=False, can_be_None=False)])
  434. assert isinstance(s, annmodel.SomeString)
  435. assert not s.can_be_None
  436. assert not s.no_nul
  437. def test_unicode_split_nul(self):
  438. def f(n):
  439. return n.split(u'\0')[0]
  440. a = self.RPythonAnnotator()
  441. a.translator.config.translation.check_str_without_nul = True
  442. s = a.build_types(f, [annmodel.SomeUnicodeString(
  443. no_nul=False, can_be_None=False)])
  444. assert isinstance(s, annmodel.SomeUnicodeString)
  445. assert not s.can_be_None
  446. assert s.no_nul
  447. def g(n):
  448. return n.split(u'\0', 1)[0]
  449. a = self.RPythonAnnotator()
  450. a.translator.config.translation.check_str_without_nul = True
  451. s = a.build_types(g, [annmodel.SomeUnicodeString(
  452. no_nul=False, can_be_None=False)])
  453. assert isinstance(s, annmodel.SomeUnicodeString)
  454. assert not s.can_be_None
  455. assert not s.no_nul
  456. def test_str_splitlines(self):
  457. a = self.RPythonAnnotator()
  458. def f(a_str):
  459. return a_str.splitlines()
  460. s = a.build_types(f, [str])
  461. assert isinstance(s, annmodel.SomeList)
  462. assert s.listdef.listitem.resized
  463. def test_str_strip(self):
  464. a = self.RPythonAnnotator()
  465. def f(n, a_str):
  466. if n == 0:
  467. return a_str.strip(' ')
  468. elif n == 1:
  469. return a_str.rstrip(' ')
  470. else:
  471. return a_str.lstrip(' ')
  472. s = a.build_types(f, [int, annmodel.SomeString(no_nul=True)])
  473. assert s.no_nul
  474. def test_unicode_strip(self):
  475. a = self.RPythonAnnotator()
  476. def f(n, a_str):
  477. if n == 0:
  478. return a_str.strip(u' ')
  479. elif n == 1:
  480. return a_str.rstrip(u' ')
  481. else:
  482. return a_str.lstrip(u' ')
  483. s = a.build_types(f, [int, annmodel.SomeUnicodeString(no_nul=True)])
  484. assert s.no_nul
  485. def test_str_mul(self):
  486. a = self.RPythonAnnotator()
  487. def f(a_str):
  488. return a_str * 3
  489. s = a.build_types(f, [str])
  490. assert isinstance(s, annmodel.SomeString)
  491. def test_str_isalpha(self):
  492. def f(s):
  493. return s.isalpha()
  494. a = self.RPythonAnnotator()
  495. s = a.build_types(f, [str])
  496. assert isinstance(s, annmodel.SomeBool)
  497. def test_simple_slicing(self):
  498. a = self.RPythonAnnotator()
  499. s = a.build_types(snippet.simple_slice, [somelist(annmodel.s_Int)])
  500. assert isinstance(s, annmodel.SomeList)
  501. def test_simple_iter_list(self):
  502. a = self.RPythonAnnotator()
  503. s = a.build_types(snippet.simple_iter, [somelist(annmodel.s_Int)])
  504. assert isinstance(s, annmodel.SomeIterator)
  505. def test_simple_iter_next(self):
  506. def f(x):
  507. i = iter(range(x))
  508. return i.next()
  509. a = self.RPythonAnnotator()
  510. s = a.build_types(f, [int])
  511. assert isinstance(s, annmodel.SomeInteger)
  512. def test_simple_iter_dict(self):
  513. a = self.RPythonAnnotator()
  514. t = somedict(a, annmodel.SomeInteger(), annmodel.SomeInteger())
  515. s = a.build_types(snippet.simple_iter, [t])
  516. assert isinstance(s, annmodel.SomeIterator)
  517. def test_simple_zip(self):
  518. a = self.RPythonAnnotator()
  519. x = somelist(annmodel.SomeInteger())
  520. y = somelist(annmodel.SomeString())
  521. s = a.build_types(snippet.simple_zip, [x,y])
  522. assert s.knowntype == list
  523. assert listitem(s).knowntype == tuple
  524. assert listitem(s).items[0].knowntype == int
  525. assert listitem(s).items[1].knowntype == str
  526. def test_dict_copy(self):
  527. a = self.RPythonAnnotator()
  528. t = somedict(a, annmodel.SomeInteger(), annmodel.SomeInteger())
  529. s = a.build_types(snippet.dict_copy, [t])
  530. assert isinstance(dictkey(s), annmodel.SomeInteger)
  531. assert isinstance(dictvalue(s), annmodel.SomeInteger)
  532. def test_dict_update(self):
  533. a = self.RPythonAnnotator()
  534. s = a.build_types(snippet.dict_update, [int])
  535. assert isinstance(dictkey(s), annmodel.SomeInteger)
  536. assert isinstance(dictvalue(s), annmodel.SomeInteger)
  537. def test_dict_update_2(self):
  538. a = self.RPythonAnnotator()
  539. def g(n):
  540. if n:
  541. return {3: 4}
  542. def f(n):
  543. g(0)
  544. d = {}
  545. d.update(g(n))
  546. return d
  547. s = a.build_types(f, [int])
  548. assert dictkey(s).knowntype == int
  549. def test_dict_keys(self):
  550. a = self.RPythonAnnotator()
  551. s = a.build_types(snippet.dict_keys, [])
  552. assert isinstance(listitem(s), annmodel.SomeString)
  553. def test_dict_keys2(self):
  554. a = self.RPythonAnnotator()
  555. s = a.build_types(snippet.dict_keys2, [])
  556. assert type(listitem(s)) is annmodel.SomeString
  557. def test_dict_values(self):
  558. a = self.RPythonAnnotator()
  559. s = a.build_types(snippet.dict_values, [])
  560. assert isinstance(listitem(s), annmodel.SomeString)
  561. def test_dict_values2(self):
  562. a = self.RPythonAnnotator()
  563. s = a.build_types(snippet.dict_values2, [])
  564. assert type(listitem(s)) is annmodel.SomeString
  565. def test_dict_items(self):
  566. a = self.RPythonAnnotator()
  567. s = a.build_types(snippet.dict_items, [])
  568. assert isinstance(listitem(s), annmodel.SomeTuple)
  569. s_key, s_value = listitem(s).items
  570. assert isinstance(s_key, annmodel.SomeString)
  571. assert isinstance(s_value, annmodel.SomeInteger)
  572. def test_dict_setdefault(self):
  573. a = self.RPythonAnnotator()
  574. def f():
  575. d = {}
  576. d.setdefault('a', 2)
  577. d.setdefault('a', -3)
  578. return d
  579. s = a.build_types(f, [])
  580. assert isinstance(s, annmodel.SomeDict)
  581. assert isinstance(dictkey(s), annmodel.SomeString)
  582. assert isinstance(dictvalue(s), annmodel.SomeInteger)
  583. assert not dictvalue(s).nonneg
  584. def test_exception_deduction(self):
  585. a = self.RPythonAnnotator()
  586. s = a.build_types(snippet.exception_deduction, [])
  587. assert isinstance(s, annmodel.SomeInstance)
  588. assert s.classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc)
  589. def test_exception_deduction_we_are_dumb(self):
  590. a = self.RPythonAnnotator()
  591. s = a.build_types(snippet.exception_deduction_we_are_dumb, [])
  592. assert isinstance(s, annmodel.SomeInstance)
  593. assert s.classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc)
  594. def test_nested_exception_deduction(self):
  595. a = self.RPythonAnnotator()
  596. s = a.build_types(snippet.nested_exception_deduction, [])
  597. assert isinstance(s, annmodel.SomeTuple)
  598. assert isinstance(s.items[0], annmodel.SomeInstance)
  599. assert isinstance(s.items[1], annmodel.SomeInstance)
  600. assert s.items[0].classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc)
  601. assert s.items[1].classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc2)
  602. def test_exc_deduction_our_exc_plus_others(self):
  603. a = self.RPythonAnnotator()
  604. s = a.build_types(snippet.exc_deduction_our_exc_plus_others, [])
  605. assert isinstance(s, annmodel.SomeInteger)
  606. def test_exc_deduction_our_excs_plus_others(self):
  607. a = self.RPythonAnnotator()
  608. s = a.build_types(snippet.exc_deduction_our_excs_plus_others, [])
  609. assert isinstance(s, annmodel.SomeInteger)
  610. def test_complex_exception_deduction(self):
  611. class InternalError(Exception):
  612. def __init__(self, msg):
  613. self.msg = msg
  614. class AppError(Exception):
  615. def __init__(self, msg):
  616. self.msg = msg
  617. def apperror(msg):
  618. return AppError(msg)
  619. def f(string):
  620. if not string:
  621. raise InternalError('Empty string')
  622. return string, None
  623. def cleanup():
  624. pass
  625. def g(string):
  626. try:
  627. try:
  628. string, _ = f(string)
  629. except ZeroDivisionError:
  630. raise apperror('ZeroDivisionError')
  631. try:
  632. result, _ = f(string)
  633. finally:
  634. cleanup()
  635. except InternalError as e:
  636. raise apperror(e.msg)
  637. return result
  638. a = self.RPythonAnnotator()
  639. s_result = a.build_types(g, [str])
  640. assert isinstance(s_result, annmodel.SomeString)
  641. def test_method_exception_specialization(self):
  642. def f(l):
  643. try:
  644. return l.pop()
  645. except Exception:
  646. raise
  647. a = self.RPythonAnnotator()
  648. s = a.build_types(f, [[int]])
  649. graph = graphof(a, f)
  650. etype, evalue = graph.exceptblock.inputargs
  651. assert evalue.annotation.classdefs == {
  652. a.bookkeeper.getuniqueclassdef(IndexError)}
  653. assert etype.annotation.const == IndexError
  654. def test_operation_always_raising(self):
  655. def operation_always_raising(n):
  656. lst = []
  657. try:
  658. return lst[n]
  659. except IndexError:
  660. return 24
  661. a = self.RPythonAnnotator()
  662. s = a.build_types(operation_always_raising, [int])
  663. assert s == a.bookkeeper.immutablevalue(24)
  664. def test_propagation_of_fresh_instances_through_attrs(self):
  665. a = self.RPythonAnnotator()
  666. s = a.build_types(snippet.propagation_of_fresh_instances_through_attrs, [int])
  667. assert s is not None
  668. def test_propagation_of_fresh_instances_through_attrs_rec_0(self):
  669. a = self.RPythonAnnotator()
  670. s = a.build_types(snippet.make_r, [int])
  671. Rdef = a.bookkeeper.getuniqueclassdef(snippet.R)
  672. assert s.classdef == Rdef
  673. assert Rdef.attrs['r'].s_value.classdef == Rdef
  674. assert Rdef.attrs['n'].s_value.knowntype == int
  675. assert Rdef.attrs['m'].s_value.knowntype == int
  676. def test_propagation_of_fresh_instances_through_attrs_rec_eo(self):
  677. a = self.RPythonAnnotator()
  678. s = a.build_types(snippet.make_eo, [int])
  679. assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.B)
  680. Even_def = a.bookkeeper.getuniqueclassdef(snippet.Even)
  681. Odd_def = a.bookkeeper.getuniqueclassdef(snippet.Odd)
  682. assert listitem(Even_def.attrs['x'].s_value).classdef == Odd_def
  683. assert listitem(Even_def.attrs['y'].s_value).classdef == Even_def
  684. assert listitem(Odd_def.attrs['x'].s_value).classdef == Even_def
  685. assert listitem(Odd_def.attrs['y'].s_value).classdef == Odd_def
  686. def test_flow_rev_numbers(self):
  687. a = self.RPythonAnnotator()
  688. s = a.build_types(snippet.flow_rev_numbers, [int])
  689. assert s.knowntype == int
  690. assert not s.is_constant() # !
  691. def test_methodcall_is_precise(self):
  692. a = self.RPythonAnnotator()
  693. s = a.build_types(snippet.methodcall_is_precise, [bool])
  694. getcdef = a.bookkeeper.getuniqueclassdef
  695. assert 'x' not in getcdef(snippet.CBase).attrs
  696. assert (getcdef(snippet.CSub1).attrs['x'].s_value ==
  697. a.bookkeeper.immutablevalue(42))
  698. assert (getcdef(snippet.CSub2).attrs['x'].s_value ==
  699. a.bookkeeper.immutablevalue('world'))
  700. assert s == a.bookkeeper.immutablevalue(42)
  701. def test_call_star_args(self):
  702. a = self.RPythonAnnotator(policy=AnnotatorPolicy())
  703. s = a.build_types(snippet.call_star_args, [int])
  704. assert s.knowntype == int
  705. def test_call_star_args_multiple(self):
  706. a = self.RPythonAnnotator(policy=AnnotatorPolicy())
  707. s = a.build_types(snippet.call_star_args_multiple, [int])
  708. assert s.knowntype == int
  709. def test_exception_deduction_with_raise1(self):
  710. a = self.RPythonAnnotator()
  711. s = a.build_types(snippet.exception_deduction_with_raise1, [bool])
  712. assert isinstance(s, annmodel.SomeInstance)
  713. assert s.classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc)
  714. def test_exception_deduction_with_raise2(self):
  715. a = self.RPythonAnnotator()
  716. s = a.build_types(snippet.exception_deduction_with_raise2, [bool])
  717. assert isinstance(s, annmodel.SomeInstance)
  718. assert s.classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc)
  719. def test_exception_deduction_with_raise3(self):
  720. a = self.RPythonAnnotator()
  721. s = a.build_types(snippet.exception_deduction_with_raise3, [bool])
  722. assert isinstance(s, annmodel.SomeInstance)
  723. assert s.classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc)
  724. def test_type_is(self):
  725. class B(object):
  726. pass
  727. class C(B):
  728. pass
  729. def f(x):
  730. assert type(x) is C
  731. return x
  732. a = self.RPythonAnnotator()
  733. s = a.build_types(f, [B])
  734. assert s.classdef is a.bookkeeper.getuniqueclassdef(C)
  735. @py.test.mark.xfail
  736. def test_union_type_some_pbc(self):
  737. class A(object):
  738. name = "A"
  739. def f(self):
  740. return type(self)
  741. class B(A):
  742. name = "B"
  743. def f(tp):
  744. return tp
  745. def main(n):
  746. if n:
  747. if n == 1:
  748. inst = A()
  749. else:
  750. inst = B()
  751. arg = inst.f()
  752. else:
  753. arg = B
  754. return f(arg).name
  755. a = self.RPythonAnnotator()
  756. s = a.build_types(main, [int])
  757. assert isinstance(s, annmodel.SomeString)
  758. def test_ann_assert(self):
  759. def assert_(x):
  760. assert x,"XXX"
  761. a = self.RPythonAnnotator()
  762. s = a.build_types(assert_, [int])
  763. assert s.const is None
  764. def test_string_and_none(self):
  765. def f(n):
  766. if n:
  767. return 'y'
  768. else:
  769. return 'n'
  770. def g(n):
  771. if n:
  772. return 'y'
  773. else:
  774. return None
  775. a = self.RPythonAnnotator()
  776. s = a.build_types(f, [bool])
  777. assert s.knowntype == str
  778. assert not s.can_be_None
  779. s = a.build_types(g, [bool])
  780. assert s.knowntype == str
  781. assert s.can_be_None
  782. def test_implicit_exc(self):
  783. def f(l):
  784. try:
  785. l[0]
  786. except (KeyError, IndexError) as e:
  787. return e
  788. return None
  789. a = self.RPythonAnnotator()
  790. s = a.build_types(f, [somelist(annmodel.s_Int)])
  791. assert s.classdef is a.bookkeeper.getuniqueclassdef(IndexError) # KeyError ignored because l is a list
  792. def test_freeze_protocol(self):
  793. class Stuff:
  794. def __init__(self):
  795. self.called = False
  796. def _freeze_(self):
  797. self.called = True
  798. return True
  799. myobj = Stuff()
  800. a = self.RPythonAnnotator()
  801. s = a.build_types(lambda: myobj, [])
  802. assert myobj.called
  803. assert isinstance(s, annmodel.SomePBC)
  804. assert s.const == myobj
  805. def test_cleanup_protocol(self):
  806. class Stuff:
  807. def __init__(self):
  808. self.called = False
  809. def _cleanup_(self):
  810. self.called = True
  811. myobj = Stuff()
  812. a = self.RPythonAnnotator()
  813. s = a.build_types(lambda: myobj, [])
  814. assert myobj.called
  815. assert isinstance(s, annmodel.SomeInstance)
  816. assert s.classdef is a.bookkeeper.getuniqueclassdef(Stuff)
  817. def test_circular_mutable_getattr(self):
  818. class C:
  819. pass
  820. c = C()
  821. c.x = c
  822. def f():
  823. return c.x
  824. a = self.RPythonAnnotator()
  825. s = a.build_types(f, [])
  826. assert isinstance(s, annmodel.SomeInstance)
  827. assert s.classdef == a.bookkeeper.getuniqueclassdef(C)
  828. def test_circular_list_type(self):
  829. def f(n):
  830. lst = []
  831. for i in range(n):
  832. lst = [lst]
  833. return lst
  834. a = self.RPythonAnnotator()
  835. s = a.build_types(f, [int])
  836. assert listitem(s) == s
  837. def test_harmonic(self):
  838. a = self.RPythonAnnotator()
  839. s = a.build_types(snippet.harmonic, [int])
  840. assert s.knowntype == float
  841. # check that the list produced by range() is not mutated or resized
  842. graph = graphof(a, snippet.harmonic)
  843. all_vars = set().union(*[block.getvariables() for block in graph.iterblocks()])
  844. print all_vars
  845. for var in all_vars:
  846. s_value = var.annotation
  847. if isinstance(s_value, annmodel.SomeList):
  848. assert not s_value.listdef.listitem.resized
  849. assert not s_value.listdef.listitem.mutated
  850. assert s_value.listdef.listitem.range_step
  851. def test_bool(self):
  852. def f(a,b):
  853. return bool(a) or bool(b)
  854. a = self.RPythonAnnotator()
  855. s = a.build_types(f, [int, somelist(annmodel.s_Int)])
  856. assert s.knowntype == bool
  857. def test_float(self):
  858. def f(n):
  859. return float(n)
  860. a = self.RPythonAnnotator()
  861. s = a.build_types(f, [int])
  862. assert s.knowntype == float
  863. def test_r_uint(self):
  864. def f(n):
  865. return n + constant_unsigned_five
  866. a = self.RPythonAnnotator()
  867. s = a.build_types(f, [r_uint])
  868. assert s == annmodel.SomeInteger(nonneg = True, unsigned = True)
  869. def test_large_unsigned(self):
  870. large_constant = sys.maxint * 2 + 1 # 0xFFFFFFFF on 32-bit platforms
  871. def f():
  872. return large_constant
  873. a = self.RPythonAnnotator()
  874. with py.test.raises(ValueError):
  875. a.build_types(f, [])
  876. # if you want to get a r_uint, you have to be explicit about it
  877. def test_add_different_ints(self):
  878. def f(a, b):
  879. return a + b
  880. a = self.RPythonAnnotator()
  881. with py.test.raises(UnionError):
  882. a.build_types(f, [r_uint, int])
  883. def test_merge_different_ints(self):
  884. def f(a, b):
  885. if a:
  886. c = a
  887. else:
  888. c = b
  889. return c
  890. a = self.RPythonAnnotator()
  891. with py.test.raises(UnionError):
  892. a.build_types(f, [r_uint, int])
  893. def test_merge_ruint_zero(self):
  894. def f(a):
  895. if a:
  896. c = a
  897. else:
  898. c = 0
  899. return c
  900. a = self.RPythonAnnotator()
  901. s = a.build_types(f, [r_uint])
  902. assert s == annmodel.SomeInteger(nonneg = True, unsigned = True)
  903. def test_merge_ruint_nonneg_signed(self):
  904. def f(a, b):
  905. if a:
  906. c = a
  907. else:
  908. assert b >= 0
  909. c = b
  910. return c
  911. a = self.RPythonAnnotator()
  912. s = a.build_types(f, [r_uint, int])
  913. assert s == annmodel.SomeInteger(nonneg = True, unsigned = True)
  914. def test_prebuilt_long_that_is_not_too_long(self):
  915. small_constant = 12L
  916. def f():
  917. return small_constant
  918. a = self.RPythonAnnotator()
  919. s = a.build_types(f, [])
  920. assert s.const == 12
  921. assert s.nonneg
  922. assert not s.unsigned
  923. #
  924. small_constant = -23L
  925. def f():
  926. return small_constant
  927. a = self.RPythonAnnotator()
  928. s = a.build_types(f, [])
  929. assert s.const == -23
  930. assert not s.nonneg
  931. assert not s.unsigned
  932. def test_pbc_getattr(self):
  933. class C:
  934. def __init__(self, v1, v2):
  935. self.v2 = v2
  936. self.v1 = v1
  937. def _freeze_(self):
  938. return True
  939. c1 = C(1,'a')
  940. c2 = C(2,'b')
  941. c3 = C(3,'c')
  942. def f1(l, c):
  943. l.append(c.v1)
  944. def f2(l, c):
  945. l.append(c.v2)
  946. def g():
  947. l1 = []
  948. l2 = []
  949. f1(l1, c1)
  950. f1(l1, c2)
  951. f2(l2, c2)
  952. f2(l2, c3)
  953. return l1,l2
  954. a = self.RPythonAnnotator()
  955. s = a.build_types(g,[])
  956. l1, l2 = s.items
  957. assert listitem(l1).knowntype == int
  958. assert listitem(l2).knowntype == str
  959. acc1 = a.bookkeeper.getdesc(c1).getattrfamily()
  960. acc2 = a.bookkeeper.getdesc(c2).getattrfamily()
  961. acc3 = a.bookkeeper.getdesc(c3).getattrfamily()
  962. assert acc1 is acc2 is acc3
  963. assert len(acc1.descs) == 3
  964. assert dict.fromkeys(acc1.attrs) == {'v1': None, 'v2': None}
  965. def test_single_pbc_getattr(self):
  966. class C:
  967. def __init__(self, v1, v2):
  968. self.v1 = v1
  969. self.v2 = v2
  970. def _freeze_(self):
  971. return True
  972. c1 = C(11, "hello")
  973. c2 = C(22, 623)
  974. def f1(l, c):
  975. l.append(c.v1)
  976. def f2(c):
  977. return c.v2
  978. def f3(c):
  979. return c.v2
  980. def g():
  981. l = []
  982. f1(l, c1)
  983. f1(l, c2)
  984. return l, f2(c1), f3(c2)
  985. a = self.RPythonAnnotator()
  986. s = a.build_types(g,[])
  987. s_l, s_c1v2, s_c2v2 = s.items
  988. assert listitem(s_l).knowntype == int
  989. assert s_c1v2.const == "hello"
  990. assert s_c2v2.const == 623
  991. acc1 = a.bookkeeper.getdesc(c1).getattrfamily()
  992. acc2 = a.bookkeeper.getdesc(c2).getattrfamily()
  993. assert acc1 is acc2
  994. assert acc1.attrs.keys() == ['v1']
  995. def test_isinstance_unsigned_1(self):
  996. def f(x):
  997. return isinstance(x, r_uint)
  998. def g():
  999. v = r_uint(1)
  1000. return f(v)
  1001. a = self.RPythonAnnotator()
  1002. s = a.build_types(g, [])
  1003. assert s.const == True
  1004. def test_isinstance_unsigned_2(self):
  1005. class Foo:
  1006. pass
  1007. def f(x):
  1008. return isinstance(x, r_uint)
  1009. def g():
  1010. v = Foo()
  1011. return f(v)
  1012. a = self.RPythonAnnotator()
  1013. s = a.build_types(g, [])
  1014. assert s.const == False
  1015. def test_isinstance_base_int(self):
  1016. def f(x):
  1017. return isinstance(x, base_int)
  1018. def g(n):
  1019. v = r_uint(n)
  1020. return f(v)
  1021. a = self.RPythonAnnotator()
  1022. s = a.build_types(g, [int])
  1023. assert s.const == True
  1024. def test_isinstance_basic(self):
  1025. def f():
  1026. return isinstance(IndexError(), type)
  1027. a = self.RPythonAnnotator()
  1028. s = a.build_types(f, [])
  1029. assert s.const == False
  1030. def test_alloc_like(self):
  1031. class Base(object):
  1032. pass
  1033. class C1(Base):
  1034. pass
  1035. class C2(Base):
  1036. pass
  1037. def inst(cls):
  1038. return cls()
  1039. def alloc(cls):
  1040. i = inst(cls)
  1041. assert isinstance(i, cls)
  1042. return i
  1043. alloc._annspecialcase_ = "specialize:arg(0)"
  1044. def f():
  1045. c1 = alloc(C1)
  1046. c2 = alloc(C2)
  1047. return c1,c2
  1048. a = self.RPythonAnnotator()
  1049. s = a.build_types(f, [])
  1050. C1df = a.bookkeeper.getuniqueclassdef(C1)
  1051. C2df = a.bookkeeper.getuniqueclassdef(C2)
  1052. assert s.items[0].classdef == C1df
  1053. assert s.items[1].classdef == C2df
  1054. allocdesc = a.bookkeeper.getdesc(alloc)
  1055. s_C1 = a.bookkeeper.immutablevalue(C1)
  1056. s_C2 = a.bookkeeper.immutablevalue(C2)
  1057. graph1 = allocdesc.specialize([s_C1], None)
  1058. graph2 = allocdesc.specialize([s_C2], None)
  1059. assert a.binding(graph1.getreturnvar()).classdef == C1df
  1060. assert a.binding(graph2.getreturnvar()).classdef == C2df
  1061. assert graph1 in a.translator.graphs
  1062. assert graph2 in a.translator.graphs
  1063. def test_specialcase_args(self):
  1064. class C1(object):
  1065. pass
  1066. class C2(object):
  1067. pass
  1068. def alloc(cls, cls2):
  1069. i = cls()
  1070. assert isinstance(i, cls)
  1071. j = cls2()
  1072. assert isinstance(j, cls2)
  1073. return i
  1074. def f():
  1075. alloc(C1, C1)
  1076. alloc(C1, C2)
  1077. alloc(C2, C1)
  1078. alloc(C2, C2)
  1079. alloc._annspecialcase_ = "specialize:arg(0,1)"
  1080. a = self.RPythonAnnotator()
  1081. C1df = a.bookkeeper.getuniqueclassdef(C1)
  1082. C2df = a.bookkeeper.getuniqueclassdef(C2)
  1083. s = a.build_types(f, [])
  1084. allocdesc = a.bookkeeper.getdesc(alloc)
  1085. s_C1 = a.bookkeeper.immutablevalue(C1)
  1086. s_C2 = a.bookkeeper.immutablevalue(C2)
  1087. graph1 = allocdesc.specialize([s_C1, s_C2], None)
  1088. graph2 = allocdesc.specialize([s_C2, s_C2], None)
  1089. assert a.binding(graph1.getreturnvar()).classdef == C1df
  1090. assert a.binding(graph2.getreturnvar()).classdef == C2df
  1091. assert graph1 in a.translator.graphs
  1092. assert graph2 in a.translator.graphs
  1093. def test_specialize_arg_bound_method(self):
  1094. class GC(object):
  1095. def trace(self, callback, *args):
  1096. return callback(*args)
  1097. trace._annspecialcase_ = "specialize:arg(1)"
  1098. def callback1(self, arg1):
  1099. self.x = arg1
  1100. return "hello"
  1101. def callback2(self, arg2, arg3):
  1102. self.y = arg2
  1103. self.z = arg3
  1104. return 6
  1105. def f():
  1106. gc = GC()
  1107. s1 = gc.trace(gc.callback1, "foo")
  1108. n2 = gc.trace(gc.callback2, 7, 2)
  1109. return (s1, n2, gc.x, gc.y, gc.z)
  1110. a = self.RPythonAnnotator()
  1111. s = a.build_types(f, [])
  1112. assert s.items[0].const == "hello"
  1113. assert s.items[1].const == 6
  1114. assert s.items[2].const == "foo"
  1115. assert s.items[3].const == 7
  1116. assert s.items[4].const == 2
  1117. def test_specialize_and_star_args(self):
  1118. class I(object):
  1119. def execute(self, op, *args):
  1120. if op == 0:
  1121. return args[0]+args[1]
  1122. if op == 1:
  1123. return args[0] * args[1] + args[2]
  1124. execute._annspecialcase_ = "specialize:arg(1)"
  1125. def f(x, y):
  1126. i = I()
  1127. a = i.execute(0, x, y)
  1128. b = i.execute(1, y, y, 5)
  1129. return a+b
  1130. a = self.RPythonAnnotator()
  1131. s = a.build_types(f, [int, int])
  1132. executedesc = a.bookkeeper.getdesc(I.execute.im_func)
  1133. assert len(executedesc._cache) == 2
  1134. assert len(executedesc._cache[(0, 'star', 2)].startblock.inputargs) == 4
  1135. assert len(executedesc._cache[(1, 'star', 3)].startblock.inputargs) == 5
  1136. def test_specialize_arg_or_var(self):
  1137. def f(a):
  1138. return 1
  1139. f._annspecialcase_ = 'specialize:arg_or_var(0)'
  1140. def fn(a):
  1141. return f(3) + f(a)
  1142. a = self.RPythonAnnotator()
  1143. a.build_types(fn, [int])
  1144. executedesc = a.bookkeeper.getdesc(f)
  1145. assert sorted(executedesc._cache.keys()) == [None, (3,)]
  1146. # we got two different special
  1147. def test_specialize_call_location(self):
  1148. def g(a):
  1149. return a
  1150. g._annspecialcase_ = "specialize:call_location"
  1151. def f(x):
  1152. return g(x)
  1153. f._annspecialcase_ = "specialize:argtype(0)"
  1154. def h(y):
  1155. w = f(y)
  1156. return int(f(str(y))) + w
  1157. a = self.RPythonAnnotator()
  1158. assert a.build_types(h, [int]) == annmodel.SomeInteger()
  1159. def test_assert_list_doesnt_lose_info(self):
  1160. class T(object):
  1161. pass
  1162. def g(l):
  1163. assert isinstance(l, list)
  1164. return l
  1165. def f():
  1166. l = [T()]
  1167. return g(l)
  1168. a = self.RPythonAnnotator()
  1169. s = a.build_types(f, [])
  1170. s_item = listitem(s)
  1171. assert isinstance(s_item, annmodel.SomeInstance)
  1172. assert s_item.classdef is a.bookkeeper.getuniqueclassdef(T)
  1173. def test_int_str_mul(self):
  1174. def f(x,a,b):
  1175. return a*x+x*b
  1176. a = self.RPythonAnnotator()
  1177. s = a.build_types(f, [str,int,int])
  1178. assert s.knowntype == str
  1179. def test_list_tuple(self):
  1180. def g0(x):
  1181. return list(x)
  1182. def g1(x):
  1183. return list(x)
  1184. def f(n):
  1185. l1 = g0(())
  1186. l2 = g1((1,))
  1187. if n:
  1188. t = (1,)
  1189. else:
  1190. t = (2,)
  1191. l3 = g1(t)
  1192. return l1, l2, l3
  1193. a = self.RPythonAnnotator()
  1194. s = a.build_types(f, [bool])
  1195. assert listitem(s.items[0]) == annmodel.SomeImpossibleValue()
  1196. assert listitem(s.items[1]).knowntype == int
  1197. assert listitem(s.items[2]).knowntype == int
  1198. def test_empty_list(self):
  1199. def f():
  1200. l = []
  1201. return bool(l)
  1202. def g():
  1203. l = []
  1204. x = bool(l)
  1205. l.append(1)
  1206. return x, bool(l)
  1207. a = self.RPythonAnnotator()
  1208. s = a.build_types(f, [])
  1209. assert s.const == False
  1210. a = self.RPythonAnnotator()
  1211. s = a.build_types(g, [])
  1212. assert s.items[0].knowntype == bool and not s.items[0].is_constant()
  1213. assert s.items[1].knowntype == bool and not s.items[1].is_constant()
  1214. def test_empty_dict(self):
  1215. def f():
  1216. d = {}
  1217. return bool(d)
  1218. def g():
  1219. d = {}
  1220. x = bool(d)
  1221. d['a'] = 1
  1222. return x, bool(d)
  1223. a = self.RPythonAnnotator()
  1224. s = a.build_types(f, [])
  1225. assert s.const == False
  1226. a = self.RPythonAnnotator()
  1227. s = a.build_types(g, [])
  1228. assert s.items[0].knowntype == bool and not s.items[0].is_constant()
  1229. assert s.items[1].knowntype == bool and not s.items[1].is_constant()
  1230. def test_call_two_funcs_but_one_can_only_raise(self):
  1231. a = self.RPythonAnnotator()
  1232. s = a.build_types(snippet.call_two_funcs_but_one_can_only_raise,
  1233. [int])
  1234. assert s == a.bookkeeper.immutablevalue(None)
  1235. def test_reraiseKeyError(self):
  1236. def f(dic):
  1237. try:
  1238. dic[5]
  1239. except KeyError:
  1240. raise
  1241. a = self.RPythonAnnotator()
  1242. a.build_types(f, [somedict(a, annmodel.s_Int, annmodel.s_Int)])
  1243. fg = graphof(a, f)
  1244. et, ev = fg.exceptblock.inputargs
  1245. t = annmodel.SomeTypeOf([ev])
  1246. t.const = KeyError
  1247. assert et.annotation == t
  1248. s_ev = ev.annotation
  1249. assert s_ev == a.bookkeeper.new_exception([KeyError])
  1250. def test_reraiseAnything(self):
  1251. def f(dic):
  1252. try:
  1253. dic[5]
  1254. except:
  1255. raise
  1256. a = self.RPythonAnnotator()
  1257. a.build_types(f, [somedict(a, annmodel.s_Int, annmodel.s_Int)])
  1258. fg = graphof(a, f)
  1259. et, ev = fg.exceptblock.inputargs
  1260. t = annmodel.SomeTypeOf([ev])
  1261. t.const = KeyError # IndexError ignored because 'dic' is a dict
  1262. assert et.annotation == t
  1263. s_ev = ev.annotation
  1264. assert s_ev == a.bookkeeper.new_exception([KeyError])
  1265. def test_exception_mixing(self):
  1266. def h():
  1267. pass
  1268. def g():
  1269. pass
  1270. class X(Exception):
  1271. def __init__(self, x=0):
  1272. self.x = x
  1273. def f(a, l):
  1274. if a==1:
  1275. raise X
  1276. elif a==2:
  1277. raise X(1)
  1278. elif a==3:
  1279. raise X(4)
  1280. else:
  1281. try:
  1282. l[0]
  1283. x,y = l
  1284. g()
  1285. finally:
  1286. h()
  1287. a = self.RPythonAnnotator()
  1288. a.build_types(f, [int, somelist(annmodel.s_Int)])
  1289. fg = graphof(a, f)
  1290. et, ev = fg.exceptblock.inputargs
  1291. t = annmodel.SomeTypeOf([ev])
  1292. assert et.annotation == t
  1293. s_ev = ev.annotation
  1294. assert (isinstance(s_ev, annmodel.SomeInstance) and
  1295. s_ev.classdef == a.bookkeeper.getuniqueclassdef(Exception))
  1296. def test_try_except_raise_finally1(self):
  1297. def h(): pass
  1298. def g(): pass
  1299. class X(Exception): pass
  1300. def f():
  1301. try:
  1302. try:
  1303. g()
  1304. except X:
  1305. h()
  1306. raise
  1307. finally:
  1308. h()
  1309. a = self.RPythonAnnotator()
  1310. a.build_types(f, [])
  1311. fg = graphof(a, f)
  1312. et, ev = fg.exceptblock.inputargs
  1313. t = annmodel.SomeTypeOf([ev])
  1314. assert et.annotation == t
  1315. s_ev = ev.annotation
  1316. assert (isinstance(s_ev, annmodel.SomeInstance) and
  1317. s_ev.classdef == a.bookkeeper.getuniqueclassdef(Exception))
  1318. def test_inplace_div(self):
  1319. def f(n):
  1320. n /= 2
  1321. return n / 2
  1322. a = self.RPythonAnnotator()
  1323. s = a.build_types(f, [int])
  1324. assert s.knowntype == int
  1325. def test_prime(self):
  1326. a = self.RPythonAnnotator()
  1327. s = a.build_types(snippet.prime, [int])
  1328. assert s.knowntype == bool
  1329. def test_and_bool_coalesce(self):
  1330. def f(a,b,c,d,e):
  1331. x = a and b
  1332. if x:
  1333. return d,c
  1334. return e,c
  1335. a = self.RPythonAnnotator()
  1336. s = a.build_types(f, [int, str, a.bookkeeper.immutablevalue(1.0), a.bookkeeper.immutablevalue('d'), a.bookkeeper.immutablevalue('e')])
  1337. assert s == annmodel.SomeTuple([annmodel.SomeChar(), a.bookkeeper.immutablevalue(1.0)])
  1338. def test_bool_coalesce2(self):
  1339. def f(a,b,a1,b1,c,d,e):
  1340. x = (a or b) and (a1 or b1)
  1341. if x:
  1342. return d,c
  1343. return e,c
  1344. a = self.RPythonAnnotator()
  1345. s = a.build_types(f, [int, str, float, somelist(annmodel.s_Int),
  1346. a.bookkeeper.immutablevalue(1.0),
  1347. a.bookkeeper.immutablevalue('d'),
  1348. a.bookkeeper.immutablevalue('e')])
  1349. assert s == annmodel.SomeTuple([annmodel.SomeChar(),
  1350. a.bookkeeper.immutablevalue(1.0)])
  1351. def test_bool_coalesce_sanity(self):
  1352. def f(a):
  1353. while a:
  1354. pass
  1355. a = self.RPythonAnnotator()
  1356. s = a.build_types(f, [int])
  1357. assert s == a.bookkeeper.immutablevalue(None)
  1358. def test_non_None_path(self):
  1359. class C:
  1360. pass
  1361. def g(c):
  1362. if c is None:
  1363. return C()
  1364. return c
  1365. def f(x):
  1366. if x:
  1367. c = None
  1368. else:
  1369. c = C()
  1370. return g(c)
  1371. a = self.RPythonAnnotator()
  1372. s = a.build_types(f, [bool])
  1373. assert s.can_be_none() == False
  1374. def test_can_be_None_path(self):
  1375. class C:
  1376. pass
  1377. def f(x):
  1378. if x:
  1379. c = None
  1380. else:
  1381. c = C()
  1382. return isinstance(c, C)
  1383. a = self.RPythonAnnotator()
  1384. s = a.build_types(f, [bool])
  1385. assert not s.is_constant()
  1386. def test_nonneg_cleverness(self):
  1387. def f(a, b, c, d, e, f, g, h):
  1388. if a < 0: a = 0
  1389. if b <= 0: b = 0
  1390. if c >= 0:
  1391. pass
  1392. else:
  1393. c = 0
  1394. if d < a: d = a
  1395. if e <= b: e = 1
  1396. if c > f: f = 2
  1397. if d >= g: g = 3
  1398. if h != a: h = 0
  1399. return a, b, c, d, e, f, g, h
  1400. a = self.RPythonAnnotator()
  1401. s = a.build_types(f, [int]*8)
  1402. assert s == annmodel.SomeTuple([annmodel.SomeInteger(nonneg=True)] * 8)
  1403. def test_general_nonneg_cleverness(self):
  1404. def f(a, b, c, d, e, f, g, h):
  1405. if a < 0: a = 0
  1406. if b <= 0: b = 0
  1407. if c >= 0:
  1408. pass
  1409. else:
  1410. c = 0
  1411. if d < a: d = a
  1412. if e <= b: e = 1
  1413. if c > f: f = 2
  1414. if d >= g: g = 3
  1415. if h != a: h = 0
  1416. return a, b, c, d, e, f, g, h
  1417. a = self.RPythonAnnotator()
  1418. s = a.build_types(f, [r_longlong]*8)
  1419. assert s == annmodel.SomeTuple([annmodel.SomeInteger(nonneg=True, knowntype=r_longlong)] * 8)
  1420. def test_more_nonneg_cleverness(self):
  1421. def f(start, stop):
  1422. assert 0 <= start <= stop
  1423. return start, stop
  1424. a = self.RPythonAnnotator()
  1425. s = a.build_types(f, [int, int])
  1426. assert s == annmodel.SomeTuple([annmodel.SomeInteger(nonneg=True)] * 2)
  1427. def test_more_general_nonneg_cleverness(self):
  1428. def f(start, stop):
  1429. assert 0 <= start <= stop
  1430. return start, stop
  1431. a = self.RPythonAnnotator()
  1432. s = a.build_types(f, [r_longlong, r_longlong])
  1433. assert s == annmodel.SomeTuple([annmodel.SomeInteger(nonneg=True, knowntype=r_longlong)] * 2)
  1434. def test_nonneg_cleverness_is_gentle_with_unsigned(self):
  1435. def witness1(x):
  1436. pass
  1437. def witness2(x):
  1438. pass
  1439. def f(x):
  1440. if 0 < x:
  1441. witness1(x)
  1442. if x > 0:
  1443. witness2(x)
  1444. a = self.RPythonAnnotator()
  1445. s = a.build_types(f, [annmodel.SomeInteger(unsigned=True)])
  1446. wg1 = graphof(a, witness1)
  1447. wg2 = graphof(a, witness2)
  1448. assert a.binding(wg1.getargs()[0]).unsigned is True
  1449. assert a.binding(wg2.getargs()[0]).unsigned is True
  1450. def test_general_nonneg_cleverness_is_gentle_with_unsigned(self):
  1451. def witness1(x):
  1452. pass
  1453. def witness2(x):
  1454. pass
  1455. def f(x):
  1456. if 0 < x:
  1457. witness1(x)
  1458. if x > 0:
  1459. witness2(x)
  1460. a = self.RPythonAnnotator()
  1461. s = a.build_types(f, [annmodel.SomeInteger(knowntype=r_ulonglong)])
  1462. wg1 = graphof(a, witness1)
  1463. wg2 = graphof(a, witness2)
  1464. assert a.binding(wg1.getargs()[0]).knowntype is r_ulonglong
  1465. assert a.binding(wg2.getargs()[0]).knowntype is r_ulonglong
  1466. def test_nonneg_cleverness_in_max(self):
  1467. def f(x):
  1468. return max(x, 0) + max(0, x)
  1469. a = self.RPythonAnnotator()
  1470. s = a.build_types(f, [int])
  1471. assert s.nonneg
  1472. def test_attr_moving_into_parent(self):
  1473. class A: pass
  1474. class B(A): pass
  1475. a1 = A()
  1476. b1 = B()
  1477. b1.stuff = a1
  1478. a1.stuff = None
  1479. def f():
  1480. return b1.stuff
  1481. a = self.RPythonAnnotator()
  1482. s = a.build_types(f, [])
  1483. assert isinstance(s, annmodel.SomeInstance)
  1484. assert not s.can_be_None
  1485. assert s.classdef is a.bookkeeper.getuniqueclassdef(A)
  1486. def test_class_attribute(self):
  1487. class A:
  1488. stuff = 42
  1489. class B(A):
  1490. pass
  1491. def f():
  1492. b = B()
  1493. return b.stuff
  1494. a = self.RPythonAnnotator()
  1495. s = a.build_types(f, [])
  1496. assert s == a.bookkeeper.immutablevalue(42)
  1497. def test_attr_recursive_getvalue(self):
  1498. class A: pass
  1499. a2 = A()
  1500. a2.stuff = None
  1501. a1 = A()
  1502. a1.stuff = a2
  1503. def f():
  1504. return a1.stuff
  1505. a = self.RPythonAnnotator()
  1506. s = a.build_types(f, [])
  1507. assert isinstance(s, annmodel.SomeInstance)
  1508. assert s.can_be_None
  1509. assert s.classdef is a.bookkeeper.getuniqueclassdef(A)
  1510. def test_long_list_recursive_getvalue(self):
  1511. class A: pass
  1512. lst = []
  1513. for i in range(500):
  1514. a1 = A()
  1515. a1.stuff = lst
  1516. lst.append(a1)
  1517. def f():
  1518. A().stuff = None
  1519. return (A().stuff, lst)[1]
  1520. a = self.RPythonAnnotator()
  1521. s = a.build_types(f, [])
  1522. assert isinstance(s, annmodel.SomeList)
  1523. s_item = s.listdef.listitem.s_value
  1524. assert isinstance(s_item, annmodel.SomeInstance)
  1525. def test_immutable_dict(self):
  1526. d = {4: "hello",
  1527. 5: "world"}
  1528. def f(n):
  1529. return d[n]
  1530. a = self.RPythonAnnotator()
  1531. s = a.build_types(f, [int])
  1532. assert isinstance(s, annmodel.SomeString)
  1533. def test_immutable_recursive_list(self):
  1534. l = []
  1535. l.append(l)
  1536. def f():
  1537. return l
  1538. a = self.RPythonAnnotator()
  1539. s = a.build_types(f, [])
  1540. assert isinstance(s, annmodel.SomeList)
  1541. s_item = s.listdef.listitem.s_value
  1542. assert isinstance(s_item, annmodel.SomeList)
  1543. assert s_item.listdef.same_as(s.listdef)
  1544. def test_defaults_with_list_or_dict(self):
  1545. def fn1(a=[]):
  1546. return a
  1547. def fn2(a={}):
  1548. return a
  1549. def f():
  1550. fn1()
  1551. fn2()
  1552. return fn1([6, 7]), fn2({2: 3, 4: 5})
  1553. a = self.RPythonAnnotator()
  1554. s = a.build_types(f, [])
  1555. assert isinstance(s, annmodel.SomeTuple)
  1556. s1, s2 = s.items
  1557. assert not s1.is_constant()
  1558. assert not s2.is_constant()
  1559. assert isinstance(s1.listdef.listitem. s_value, annmodel.SomeInteger)
  1560. assert isinstance(s2.dictdef.dictkey. s_value, annmodel.SomeInteger)
  1561. assert isinstance(s2.dictdef.dictvalue.s_value, annmodel.SomeInteger)
  1562. def test_pbc_union(self):
  1563. class A:
  1564. def meth(self):
  1565. return 12
  1566. class B(A):
  1567. pass
  1568. class C(B):
  1569. pass
  1570. def f(i):
  1571. if i:
  1572. f(0)
  1573. x = B()
  1574. else:
  1575. x = C()
  1576. return x.meth()
  1577. a = self.RPythonAnnotator()
  1578. s = a.build_types(f, [int])
  1579. assert s == a.bookkeeper.immutablevalue(12)
  1580. def test_int(self):
  1581. def f(x, s):
  1582. return int(x) + int(s) + int(s, 16)
  1583. a = self.RPythonAnnotator()
  1584. s = a.build_types(f, [int, str])
  1585. assert s.knowntype == int
  1586. def test_int_nonneg(self):
  1587. def f(x, y):
  1588. assert x >= 0
  1589. return int(x) + int(y == 3)
  1590. a = self.RPythonAnnotator()
  1591. s = a.build_types(f, [int, int])
  1592. assert isinstance(s, annmodel.SomeInteger)
  1593. assert s.nonneg
  1594. def test_listitem_merge_asymmetry_bug(self):
  1595. class K:
  1596. pass
  1597. def mutr(k, x, i):
  1598. k.l2 = [x] + k.l2 # this involves a side-effectful union and unification, with this order
  1599. # of arguments some reflowing was missed
  1600. k.l2[i] = x
  1601. def witness(i):
  1602. pass
  1603. def trouble(k):
  1604. l = k.l1 + k.l2
  1605. for i in range(len(l)):
  1606. witness(l[i])
  1607. def f(flag, k, x, i):
  1608. if flag:
  1609. k = K()
  1610. k.l1 = []
  1611. k.l2 = []
  1612. trouble(k)
  1613. mutr(k, x, i)
  1614. a = self.RPythonAnnotator()
  1615. a.build_types(f, [bool, K, int, int])
  1616. g = graphof(a, witness)
  1617. assert a.binding(g.getargs()[0]).knowntype == int
  1618. # check RPython static semantics of isinstance(x,bool|int) as needed for wrap
  1619. def test_isinstance_int_bool(self):
  1620. def f(x):
  1621. if isinstance(x, int):
  1622. if isinstance(x, bool):
  1623. return "bool"
  1624. return "int"
  1625. return "dontknow"
  1626. a = self.RPythonAnnotator()
  1627. s = a.build_types(f, [bool])
  1628. assert s.const == "bool"
  1629. a = self.RPythonAnnotator()
  1630. s = a.build_types(f, [int])
  1631. assert s.const == "int"
  1632. a = self.RPythonAnnotator()
  1633. s = a.build_types(f, [float])
  1634. assert s.const == "dontknow"
  1635. def test_hidden_method(self):
  1636. class Base:
  1637. def method(self):
  1638. return ["should be hidden"]
  1639. def indirect(self):
  1640. return self.method()
  1641. class A(Base):
  1642. def method(self):
  1643. return "visible"
  1644. class B(A): # note: it's a chain of subclasses
  1645. def method(self):
  1646. return None
  1647. def f(flag):
  1648. if flag:
  1649. obj = A()
  1650. else:
  1651. obj = B()
  1652. return obj.indirect()
  1653. a = self.RPythonAnnotator()
  1654. s = a.build_types(f, [bool])
  1655. assert annmodel.SomeString(can_be_None=True).contains(s)
  1656. def test_dont_see_AttributeError_clause(self):
  1657. class Stuff:
  1658. def _freeze_(self):
  1659. return True
  1660. def createcompiler(self):
  1661. try:
  1662. return self.default_compiler
  1663. except AttributeError:
  1664. compiler = "yadda"
  1665. self.default_compiler = compiler
  1666. return compiler
  1667. stuff = Stuff()
  1668. stuff.default_compiler = 123
  1669. def f():
  1670. return stuff.createcompiler()
  1671. a = self.RPythonAnnotator()
  1672. s = a.build_types(f, [])
  1673. assert s == a.bookkeeper.immutablevalue(123)
  1674. def test_class_attribute_is_an_instance_of_itself(self):
  1675. class Base:
  1676. hello = None
  1677. class A(Base):
  1678. pass
  1679. A.hello = globalA = A()
  1680. def f():
  1681. return (Base().hello, globalA)
  1682. a = self.RPythonAnnotator()
  1683. s = a.build_types(f, [])
  1684. assert isinstance(s, annmodel.SomeTuple)
  1685. assert isinstance(s.items[0], annmodel.SomeInstance)
  1686. assert s.items[0].classdef is a.bookkeeper.getuniqueclassdef(A)
  1687. assert s.items[0].can_be_None
  1688. assert s.items[1] == a.bookkeeper.immutablevalue(A.hello)
  1689. def test_dict_and_none(self):
  1690. def f(i):
  1691. if i:
  1692. return {}
  1693. else:
  1694. return None
  1695. a = self.RPythonAnnotator()
  1696. s = a.build_types(f, [int])
  1697. assert s.knowntype == annmodel.SomeOrderedDict.knowntype
  1698. def test_const_list_and_none(self):
  1699. def g(l=None):
  1700. return l is None
  1701. L = [1,2]
  1702. def f():
  1703. g()
  1704. return g(L)
  1705. a = self.RPythonAnnotator()
  1706. s = a.build_types(f, [])
  1707. assert s.knowntype == bool
  1708. assert not s.is_constant()
  1709. def test_const_dict_and_none(self):
  1710. def g(d=None):
  1711. return d is None
  1712. D = {1:2}
  1713. def f():
  1714. g(D)
  1715. return g()
  1716. a = self.RPythonAnnotator()
  1717. s = a.build_types(f, [])
  1718. assert s.knowntype == bool
  1719. assert not s.is_constant()
  1720. def test_issubtype_and_const(self):
  1721. class A(object):
  1722. pass
  1723. class B(object):
  1724. pass
  1725. class C(A):
  1726. pass
  1727. b = B()
  1728. c = C()
  1729. def g(f):
  1730. if f == 1:
  1731. x = b
  1732. elif f == 2:
  1733. x = c
  1734. else:
  1735. x = C()
  1736. t = type(x)
  1737. return issubclass(t, A)
  1738. a = self.RPythonAnnotator()
  1739. x = annmodel.SomeInteger()
  1740. x.const = 1
  1741. s = a.build_types(g, [x])
  1742. assert s.const == False
  1743. a = self.RPythonAnnotator()
  1744. x = annmodel.SomeInteger()
  1745. x.const = 2
  1746. s = a.build_types(g, [x])
  1747. assert s.const == True
  1748. def test_reading_also_generalizes(self):
  1749. def f1(i):
  1750. d = {'c': i}
  1751. return d['not-a-char'], d
  1752. a = self.RPythonAnnotator()
  1753. s = a.build_types(f1, [int])
  1754. assert dictkey(s.items[1]).__class__ == annmodel.SomeString
  1755. def f2(i):
  1756. d = {'c': i}
  1757. return d.get('not-a-char', i+1), d
  1758. a = self.RPythonAnnotator()
  1759. s = a.build_types(f2, [int])
  1760. assert dictkey(s.items[1]).__class__ == annmodel.SomeString
  1761. def f3(i):
  1762. d = {'c': i}
  1763. return 'not-a-char' in d, d
  1764. a = self.RPythonAnnotator()
  1765. s = a.build_types(f3, [int])
  1766. assert dictkey(s.items[1]).__class__ == annmodel.SomeString
  1767. def f4():
  1768. lst = ['a', 'b', 'c']
  1769. return 'not-a-char' in lst, lst
  1770. a = self.RPythonAnnotator()
  1771. s = a.build_types(f4, [])
  1772. assert listitem(s.items[1]).__class__ == annmodel.SomeString
  1773. def f5():
  1774. lst = ['a', 'b', 'c']
  1775. return lst.index('not-a-char'), lst
  1776. a = self.RPythonAnnotator()
  1777. s = a.build_types(f5, [])
  1778. assert listitem(s.items[1]).__class__ == annmodel.SomeString
  1779. def test_true_str_is_not_none(self):
  1780. def f(s):
  1781. if s:
  1782. return s
  1783. else:
  1784. return ''
  1785. def g(i):
  1786. if i:
  1787. return f(None)
  1788. else:
  1789. return f('')
  1790. a = self.RPythonAnnotator()
  1791. s = a.build_types(g, [int])
  1792. assert s.knowntype == str
  1793. assert not s.can_be_None
  1794. def test_true_func_is_not_none(self):
  1795. def a1():
  1796. pass
  1797. def a2():
  1798. pass
  1799. def f(a):
  1800. if a:
  1801. return a
  1802. else:
  1803. return a2
  1804. def g(i):
  1805. if i:
  1806. return f(None)
  1807. else:
  1808. return f(a1)
  1809. a = self.RPythonAnnotator()
  1810. s = a.build_types(g, [int])
  1811. assert not s.can_be_None
  1812. def test_string_noNUL_canbeNone(self):
  1813. def f(a):
  1814. if a:
  1815. return "abc"
  1816. else:
  1817. return None
  1818. a = self.RPythonAnnotator()
  1819. s = a.build_types(f, [int])
  1820. assert s.can_be_None
  1821. assert s.no_nul
  1822. def test_unicode_noNUL_canbeNone(self):
  1823. def f(a):
  1824. if a:
  1825. return u"abc"
  1826. else:
  1827. return None
  1828. a = self.RPythonAnnotator()
  1829. s = a.build_types(f, [int])
  1830. assert s.can_be_None
  1831. assert s.no_nul
  1832. def test_str_or_None(self):
  1833. def f(a):
  1834. if a:
  1835. return "abc"
  1836. else:
  1837. return None
  1838. def g(a):
  1839. x = f(a)
  1840. if x is None:
  1841. return "abcd"
  1842. return x
  1843. a = self.RPythonAnnotator()
  1844. s = a.build_types(f, [int])
  1845. assert s.can_be_None
  1846. assert s.no_nul
  1847. def test_unicode_or_None(self):
  1848. def f(a):
  1849. if a:
  1850. return u"abc"
  1851. else:
  1852. return None
  1853. def g(a):
  1854. x = f(a)
  1855. if x is None:
  1856. return u"abcd"
  1857. return x
  1858. a = self.RPythonAnnotator()
  1859. s = a.build_types(f, [int])
  1860. assert s.can_be_None
  1861. assert s.no_nul
  1862. def test_emulated_pbc_call_simple(self):
  1863. def f(a,b):
  1864. return a + b
  1865. from rpython.annotator import annrpython
  1866. a = annrpython.RPythonAnnotator()
  1867. from rpython.annotator import model as annmodel
  1868. s_f = a.bookkeeper.immutablevalue(f)
  1869. a.bookkeeper.emulate_pbc_call('f', s_f, [annmodel.SomeInteger(), annmodel.SomeInteger()])
  1870. a.complete()
  1871. a.simplify()
  1872. assert a.binding(graphof(a, f).getreturnvar()).knowntype == int
  1873. fdesc = a.bookkeeper.getdesc(f)
  1874. someint = annmodel.SomeInteger()
  1875. assert (fdesc.get_s_signatures((2, (), False))
  1876. == [([someint,someint],someint)])
  1877. def test_emulated_pbc_call_callback(self):
  1878. def f(a,b):
  1879. return a + b
  1880. from rpython.annotator import annrpython
  1881. a = annrpython.RPythonAnnotator()
  1882. from rpython.annotator import model as annmodel
  1883. memo = []
  1884. def callb(ann, graph):
  1885. memo.append(annmodel.SomeInteger() == ann.binding(graph.getreturnvar()))
  1886. s_f = a.bookkeeper.immutablevalue(f)
  1887. s = a.bookkeeper.emulate_pbc_call('f', s_f, [annmodel.SomeInteger(), annmodel.SomeInteger()],
  1888. callback=callb)
  1889. assert s == annmodel.SomeImpossibleValue()
  1890. a.complete()
  1891. assert a.binding(graphof(a, f).getreturnvar()).knowntype == int
  1892. assert len(memo) >= 1
  1893. for t in memo:
  1894. assert t
  1895. def test_iterator_union(self):
  1896. def it(d):
  1897. return d.iteritems()
  1898. d0 = {1:2}
  1899. def f():
  1900. it(d0)
  1901. return it({1:2})
  1902. a = self.RPythonAnnotator()
  1903. s = a.build_types(f, [])
  1904. assert isinstance(s, annmodel.SomeIterator)
  1905. assert s.variant == ('items',)
  1906. def test_iteritems_str0(self):
  1907. def it(d):
  1908. return d.iteritems()
  1909. def f():
  1910. d0 = {'1a': '2a', '3': '4'}
  1911. for item in it(d0):
  1912. return "%s=%s" % item
  1913. raise ValueError
  1914. a = self.RPythonAnnotator()
  1915. s = a.build_types(f, [])
  1916. assert isinstance(s, annmodel.SomeString)
  1917. assert s.no_nul
  1918. def test_iteritems_unicode0(self):
  1919. def it(d):
  1920. return d.iteritems()
  1921. def f():
  1922. d0 = {u'1a': u'2a', u'3': u'4'}
  1923. for item in it(d0):
  1924. return u"%s=%s" % item
  1925. raise ValueError
  1926. a = self.RPythonAnnotator()
  1927. s = a.build_types(f, [])
  1928. assert isinstance(s, annmodel.SomeUnicodeString)
  1929. assert s.no_nul
  1930. def test_no_nul_mod(self):
  1931. def f(x):
  1932. s = "%d" % x
  1933. return s
  1934. a = self.RPythonAnnotator()
  1935. s = a.build_types(f, [int])
  1936. assert isinstance(s, annmodel.SomeString)
  1937. assert s.no_nul
  1938. def test_no_nul_mod_unicode(self):
  1939. def f(x):
  1940. s = u"%d" % x
  1941. return s
  1942. a = self.RPythonAnnotator()
  1943. s = a.build_types(f, [int])
  1944. assert isinstance(s, annmodel.SomeUnicodeString)
  1945. assert s.no_nul
  1946. def test_mul_str0(self):
  1947. def f(s):
  1948. return s*10
  1949. a = self.RPythonAnnotator()
  1950. s = a.build_types(f, [annmodel.SomeString(no_nul=True)])
  1951. assert isinstance(s, annmodel.SomeString)
  1952. assert s.no_nul
  1953. a = self.RPythonAnnotator()
  1954. s = a.build_types(f, [annmodel.SomeUnicodeString(no_nul=True)])
  1955. assert isinstance(s, annmodel.SomeUnicodeString)
  1956. assert s.no_nul
  1957. def test_reverse_mul_str0(self):
  1958. def f(s):
  1959. return 10*s
  1960. a = self.RPythonAnnotator()
  1961. s = a.build_types(f, [annmodel.SomeString(no_nul=True)])
  1962. assert isinstance(s, annmodel.SomeString)
  1963. assert s.no_nul
  1964. a = self.RPythonAnnotator()
  1965. s = a.build_types(f, [annmodel.SomeUnicodeString(no_nul=True)])
  1966. assert isinstance(s, annmodel.SomeUnicodeString)
  1967. assert s.no_nul
  1968. def test_getitem_str0(self):
  1969. def f(s, n):
  1970. if n == 1:
  1971. return s[0]
  1972. elif n == 2:
  1973. return s[1]
  1974. elif n == 3:
  1975. return s[1:]
  1976. return s
  1977. a = self.RPythonAnnotator()
  1978. a.translator.config.translation.check_str_without_nul = True
  1979. s = a.build_types(f, [annmodel.SomeString(no_nul=True),
  1980. annmodel.SomeInteger()])
  1981. assert isinstance(s, annmodel.SomeString)
  1982. assert s.no_nul
  1983. a = self.RPythonAnnotator()
  1984. a.translator.config.translation.check_str_without_nul = True
  1985. s = a.build_types(f, [annmodel.SomeUnicodeString(no_nul=True),
  1986. annmodel.SomeInteger()])
  1987. assert isinstance(s, annmodel.SomeUnicodeString)
  1988. assert s.no_nul
  1989. def test_non_none_and_none_with_isinstance(self):
  1990. class A(object):
  1991. pass
  1992. class B(A):
  1993. pass
  1994. def g(x):
  1995. if isinstance(x, A):
  1996. return x
  1997. return None
  1998. def f():
  1999. g(B())
  2000. return g(None)
  2001. a = self.RPythonAnnotator()
  2002. s = a.build_types(f, [])
  2003. assert isinstance(s, annmodel.SomeInstance)
  2004. assert s.classdef == a.bookkeeper.getuniqueclassdef(B)
  2005. def test_type_is_no_improvement(self):
  2006. class B(object):
  2007. pass
  2008. class C(B):
  2009. pass
  2010. class D(B):
  2011. pass
  2012. def f(x):
  2013. if type(x) is C:
  2014. return x
  2015. raise Exception
  2016. a = self.RPythonAnnotator()
  2017. s = a.build_types(f, [D])
  2018. assert s == annmodel.SomeImpossibleValue()
  2019. def test_is_constant_instance(self):
  2020. class A(object):
  2021. pass
  2022. prebuilt_instance = A()
  2023. def f(x):
  2024. if x is prebuilt_instance:
  2025. return x
  2026. raise Exception
  2027. a = self.RPythonAnnotator()
  2028. s = a.build_types(f, [A])
  2029. assert s.is_constant()
  2030. assert s.const is prebuilt_instance
  2031. def test_call_memoized_function(self):
  2032. fr1 = Freezing()
  2033. fr2 = Freezing()
  2034. def getorbuild(key):
  2035. a = 1
  2036. if key is fr1:
  2037. result = eval("a+2")
  2038. else:
  2039. result = eval("a+6")
  2040. return result
  2041. getorbuild._annspecialcase_ = "specialize:memo"
  2042. def f1(i):
  2043. if i > 0:
  2044. fr = fr1
  2045. else:
  2046. fr = fr2
  2047. return getorbuild(fr)
  2048. a = self.RPythonAnnotator()
  2049. s = a.build_types(f1, [int])
  2050. assert s.knowntype == int
  2051. def test_call_memoized_function_with_bools(self):
  2052. fr1 = Freezing()
  2053. fr2 = Freezing()
  2054. def getorbuild(key, flag1, flag2):
  2055. a = 1
  2056. if key is fr1:
  2057. result = eval("a+2")
  2058. else:
  2059. result = eval("a+6")
  2060. if flag1:
  2061. result += 100
  2062. if flag2:
  2063. result += 1000
  2064. return result
  2065. getorbuild._annspecialcase_ = "specialize:memo"
  2066. def f1(i):
  2067. if i > 0:
  2068. fr = fr1
  2069. else:
  2070. fr = fr2
  2071. return getorbuild(fr, i % 2 == 0, i % 3 == 0)
  2072. a = self.RPythonAnnotator()
  2073. s = a.build_types(f1, [int])
  2074. assert s.knowntype == int
  2075. def test_stored_bound_method(self):
  2076. # issue 129
  2077. class H:
  2078. def h(self):
  2079. return 42
  2080. class C:
  2081. def __init__(self, func):
  2082. self.f = func
  2083. def do(self):
  2084. return self.f()
  2085. def g():
  2086. h = H()
  2087. c = C(h.h)
  2088. return c.do()
  2089. a = self.RPythonAnnotator()
  2090. s = a.build_types(g, [])
  2091. assert s.is_constant()
  2092. assert s.const == 42
  2093. def test_stored_bound_method_2(self):
  2094. # issue 129
  2095. class H:
  2096. pass
  2097. class H1(H):
  2098. def h(self):
  2099. return 42
  2100. class H2(H):
  2101. def h(self):
  2102. return 17
  2103. class C:
  2104. def __init__(self, func):
  2105. self.f = func
  2106. def do(self):
  2107. return self.f()
  2108. def g(flag):
  2109. if flag:
  2110. h = H1()
  2111. else:
  2112. h = H2()
  2113. c = C(h.h)
  2114. return c.do()
  2115. a = self.RPythonAnnotator()
  2116. s = a.build_types(g, [int])
  2117. assert s.knowntype == int
  2118. assert not s.is_constant()
  2119. def test_getorbuild_as_attr(self):
  2120. from rpython.rlib.cache import Cache
  2121. class SpaceCache(Cache):
  2122. def _build(self, callable):
  2123. return callable()
  2124. class CacheX(Cache):
  2125. def _build(self, key):
  2126. return key.x
  2127. class CacheY(Cache):
  2128. def _build(self, key):
  2129. return key.y
  2130. class X:
  2131. def __init__(self, x):
  2132. self.x = x
  2133. def _freeze_(self):
  2134. return True
  2135. class Y:
  2136. def __init__(self, y):
  2137. self.y = y
  2138. def _freeze_(self):
  2139. return True
  2140. X1 = X(1)
  2141. Y2 = Y("hello")
  2142. fromcache = SpaceCache().getorbuild
  2143. def f():
  2144. return (fromcache(CacheX).getorbuild(X1),
  2145. fromcache(CacheY).getorbuild(Y2))
  2146. a = self.RPythonAnnotator()
  2147. s = a.build_types(f, [])
  2148. assert s.items[0].knowntype == int
  2149. assert s.items[1].knowntype == str
  2150. def test_constant_bound_method(self):
  2151. class C:
  2152. def __init__(self, value):
  2153. self.value = value
  2154. def meth(self):
  2155. return self.value
  2156. meth = C(1).meth
  2157. def f():
  2158. return meth()
  2159. a = self.RPythonAnnotator()
  2160. s = a.build_types(f, [])
  2161. assert s.knowntype == int
  2162. def test_annotate__del__(self):
  2163. class A(object):
  2164. def __init__(self):
  2165. self.a = 2
  2166. def __del__(self):
  2167. self.a = 1
  2168. def f():
  2169. return A().a
  2170. a = self.RPythonAnnotator()
  2171. t = a.translator
  2172. s = a.build_types(f, [])
  2173. assert s.knowntype == int
  2174. graph = tgraphof(t, A.__del__.im_func)
  2175. assert graph.startblock in a.annotated
  2176. def test_annotate__del__baseclass(self):
  2177. class A(object):
  2178. def __init__(self):
  2179. self.a = 2
  2180. def __del__(self):
  2181. self.a = 1
  2182. class B(A):
  2183. def __init__(self):
  2184. self.a = 3
  2185. def f():
  2186. return B().a
  2187. a = self.RPythonAnnotator()
  2188. t = a.translator
  2189. s = a.build_types(f, [])
  2190. assert s.knowntype == int
  2191. graph = tgraphof(t, A.__del__.im_func)
  2192. assert graph.startblock in a.annotated
  2193. def test_annotate_type(self):
  2194. class A:
  2195. pass
  2196. x = [A(), A()]
  2197. def witness(t):
  2198. return type(t)
  2199. def get(i):
  2200. return x[i]
  2201. def f(i):
  2202. witness(None)
  2203. return witness(get(i))
  2204. a = self.RPythonAnnotator()
  2205. s = a.build_types(f, [int])
  2206. assert isinstance(s, annmodel.SomeType)
  2207. def test_annotate_iter_empty_container(self):
  2208. def f():
  2209. n = 0
  2210. d = {}
  2211. for x in []: n += x
  2212. for y in d: n += y
  2213. for z in d.iterkeys(): n += z
  2214. for s in d.itervalues(): n += s
  2215. for t, u in d.items(): n += t * u
  2216. for t, u in d.iteritems(): n += t * u
  2217. return n
  2218. a = self.RPythonAnnotator()
  2219. s = a.build_types(f, [])
  2220. assert s.is_constant()
  2221. assert s.const == 0
  2222. def test_mixin(self):
  2223. class Mixin(object):
  2224. _mixin_ = True
  2225. def m(self, v):
  2226. return v
  2227. class Base(object):
  2228. pass
  2229. class A(Base, Mixin):
  2230. pass
  2231. class B(Base, Mixin):
  2232. pass
  2233. class C(B):
  2234. pass
  2235. def f():
  2236. a = A()
  2237. v0 = a.m(2)
  2238. b = B()
  2239. v1 = b.m('x')
  2240. c = C()
  2241. v2 = c.m('y')
  2242. return v0, v1, v2
  2243. a = self.RPythonAnnotator()
  2244. s = a.build_types(f, [])
  2245. assert isinstance(s.items[0], annmodel.SomeInteger)
  2246. assert isinstance(s.items[1], annmodel.SomeChar)
  2247. assert isinstance(s.items[2], annmodel.SomeChar)
  2248. def test_mixin_staticmethod(self):
  2249. class Mixin(object):
  2250. _mixin_ = True
  2251. @staticmethod
  2252. def m(v):
  2253. return v
  2254. class Base(object):
  2255. pass
  2256. class A(Base, Mixin):
  2257. pass
  2258. class B(Base, Mixin):
  2259. pass
  2260. class C(B):
  2261. pass
  2262. def f():
  2263. a = A()
  2264. v0 = a.m(2)
  2265. b = B()
  2266. v1 = b.m('x')
  2267. c = C()
  2268. v2 = c.m('y')
  2269. return v0, v1, v2
  2270. a = self.RPythonAnnotator()
  2271. s = a.build_types(f, [])
  2272. assert isinstance(s.items[0], annmodel.SomeInteger)
  2273. assert isinstance(s.items[1], annmodel.SomeChar)
  2274. assert isinstance(s.items[2], annmodel.SomeChar)
  2275. def test_mixin_first(self):
  2276. class Mixin(object):
  2277. _mixin_ = True
  2278. def foo(self): return 4
  2279. class Base(object):
  2280. def foo(self): return 5
  2281. class Concrete(Mixin, Base):
  2282. pass
  2283. def f():
  2284. return Concrete().foo()
  2285. assert f() == 4
  2286. a = self.RPythonAnnotator()
  2287. s = a.build_types(f, [])
  2288. assert s.const == 4
  2289. def test_mixin_last(self):
  2290. class Mixin(object):
  2291. _mixin_ = True
  2292. def foo(self): return 4
  2293. class Base(object):
  2294. def foo(self): return 5
  2295. class Concrete(Base, Mixin):
  2296. pass
  2297. def f():
  2298. return Concrete().foo()
  2299. assert f() == 5
  2300. a = self.RPythonAnnotator()
  2301. s = a.build_types(f, [])
  2302. assert s.const == 5
  2303. def test_mixin_concrete(self):
  2304. class Mixin(object):
  2305. _mixin_ = True
  2306. def foo(self): return 4
  2307. class Concrete(Mixin):
  2308. def foo(self): return 5
  2309. def f():
  2310. return Concrete().foo()
  2311. assert f() == 5
  2312. a = self.RPythonAnnotator()
  2313. s = a.build_types(f, [])
  2314. assert s.const == 5
  2315. def test_multiple_mixins_mro(self):
  2316. # an obscure situation, but it occurred in module/micronumpy/types.py
  2317. class A(object):
  2318. _mixin_ = True
  2319. def foo(self): return 1
  2320. class B(A):
  2321. _mixin_ = True
  2322. def foo(self): return 2
  2323. class C(A):
  2324. _mixin_ = True
  2325. class D(B, C):
  2326. _mixin_ = True
  2327. class Concrete(D):
  2328. pass
  2329. def f():
  2330. return Concrete().foo()
  2331. assert f() == 2
  2332. a = self.RPythonAnnotator()
  2333. s = a.build_types(f, [])
  2334. assert s.const == 2
  2335. def test_multiple_mixins_mro_2(self):
  2336. class A(object):
  2337. _mixin_ = True
  2338. def foo(self): return 1
  2339. class B(A):
  2340. _mixin_ = True
  2341. def foo(self): return 2
  2342. class C(A):
  2343. _mixin_ = True
  2344. class Concrete(C, B):
  2345. pass
  2346. def f():
  2347. return Concrete().foo()
  2348. assert f() == 2
  2349. a = self.RPythonAnnotator()
  2350. s = a.build_types(f, [])
  2351. assert s.const == 2
  2352. def test_cannot_use_directly_mixin(self):
  2353. class A(object):
  2354. _mixin_ = True
  2355. #
  2356. def f():
  2357. return A()
  2358. a = self.RPythonAnnotator()
  2359. py.test.raises(AnnotatorError, a.build_types, f, [])
  2360. #
  2361. class B(object):
  2362. pass
  2363. x = B()
  2364. def g():
  2365. return isinstance(x, A)
  2366. py.test.raises(AnnotatorError, a.build_types, g, [])
  2367. def test_import_from_mixin(self):
  2368. class M(object):
  2369. def f(self):
  2370. return self.a
  2371. class I(object):
  2372. objectmodel.import_from_mixin(M)
  2373. def __init__(self, i):
  2374. self.a = i
  2375. class S(object):
  2376. objectmodel.import_from_mixin(M)
  2377. def __init__(self, s):
  2378. self.a = s
  2379. def f(n):
  2380. return (I(n).f(), S("a" * n).f())
  2381. assert f(3) == (3, "aaa")
  2382. a = self.RPythonAnnotator()
  2383. s = a.build_types(f, [int])
  2384. assert isinstance(s.items[0], annmodel.SomeInteger)
  2385. assert isinstance(s.items[1], annmodel.SomeString)
  2386. def test___class___attribute(self):
  2387. class Base(object): pass
  2388. class A(Base): pass
  2389. class B(Base): pass
  2390. class C(A): pass
  2391. def seelater():
  2392. C()
  2393. def f(n):
  2394. if n == 1:
  2395. x = A()
  2396. else:
  2397. x = B()
  2398. y = B()
  2399. result = x.__class__, y.__class__
  2400. seelater()
  2401. return result
  2402. a = self.RPythonAnnotator()
  2403. s = a.build_types(f, [int])
  2404. assert isinstance(s.items[0], annmodel.SomePBC)
  2405. assert len(s.items[0].descriptions) == 4
  2406. assert isinstance(s.items[1], annmodel.SomePBC)
  2407. assert len(s.items[1].descriptions) == 1
  2408. def test_slots(self):
  2409. # check that the annotator ignores slots instead of being
  2410. # confused by them showing up as 'member' objects in the class
  2411. class A(object):
  2412. __slots__ = ('a', 'b')
  2413. def f(x):
  2414. a = A()
  2415. a.b = x
  2416. return a.b
  2417. a = self.RPythonAnnotator()
  2418. s = a.build_types(f, [int])
  2419. assert s.knowntype == int
  2420. def test_slots_reads(self):
  2421. class A(object):
  2422. __slots__ = ()
  2423. class B(A):
  2424. def __init__(self, x):
  2425. self.x = x
  2426. def f(x):
  2427. if x:
  2428. a = A()
  2429. else:
  2430. a = B(x)
  2431. return a.x # should explode here
  2432. a = self.RPythonAnnotator()
  2433. with py.test.raises(NoSuchAttrError) as excinfo:
  2434. a.build_types(f, [int])
  2435. # this should explode on reading the attribute 'a.x', but it can
  2436. # sometimes explode on 'self.x = x', which does not make much sense.
  2437. # But it looks hard to fix in general: we don't know yet during 'a.x'
  2438. # if the attribute x will be read-only or read-write.
  2439. def test_unboxed_value(self):
  2440. class A(object):
  2441. __slots__ = ()
  2442. class C(A, objectmodel.UnboxedValue):
  2443. __slots__ = unboxedattrname = 'smallint'
  2444. def f(n):
  2445. return C(n).smallint
  2446. a = self.RPythonAnnotator()
  2447. s = a.build_types(f, [int])
  2448. assert s.knowntype == int
  2449. def test_annotate_bool(self):
  2450. def f(x):
  2451. return ~x
  2452. a = self.RPythonAnnotator()
  2453. s = a.build_types(f, [bool])
  2454. assert s.knowntype == int
  2455. def f(x):
  2456. return -x
  2457. a = self.RPythonAnnotator()
  2458. s = a.build_types(f, [bool])
  2459. assert s.knowntype == int
  2460. def f(x):
  2461. return +x
  2462. a = self.RPythonAnnotator()
  2463. s = a.build_types(f, [bool])
  2464. assert s.knowntype == int
  2465. def f(x):
  2466. return abs(x)
  2467. a = self.RPythonAnnotator()
  2468. s = a.build_types(f, [bool])
  2469. assert s.knowntype == int
  2470. def f(x):
  2471. return int(x)
  2472. a = self.RPythonAnnotator()
  2473. s = a.build_types(f, [bool])
  2474. assert s.knowntype == int
  2475. def f(x, y):
  2476. return x + y
  2477. a = self.RPythonAnnotator()
  2478. s = a.build_types(f, [bool, int])
  2479. assert s.knowntype == int
  2480. a = self.RPythonAnnotator()
  2481. s = a.build_types(f, [int, bool])
  2482. assert s.knowntype == int
  2483. def test_annotate_rarith(self):
  2484. inttypes = [int, r_uint, r_longlong, r_ulonglong]
  2485. for inttype in inttypes:
  2486. c = inttype()
  2487. def f():
  2488. return c
  2489. a = self.RPythonAnnotator()
  2490. s = a.build_types(f, [])
  2491. assert isinstance(s, annmodel.SomeInteger)
  2492. assert s.knowntype == inttype
  2493. assert s.unsigned == (inttype(-1) > 0)
  2494. for inttype in inttypes:
  2495. def f():
  2496. return inttype(0)
  2497. a = self.RPythonAnnotator()
  2498. s = a.build_types(f, [])
  2499. assert isinstance(s, annmodel.SomeInteger)
  2500. assert s.knowntype == inttype
  2501. assert s.unsigned == (inttype(-1) > 0)
  2502. for inttype in inttypes:
  2503. def f(x):
  2504. return x
  2505. a = self.RPythonAnnotator()
  2506. s = a.build_types(f, [inttype])
  2507. assert isinstance(s, annmodel.SomeInteger)
  2508. assert s.knowntype == inttype
  2509. assert s.unsigned == (inttype(-1) > 0)
  2510. def test_annotate_rshift(self):
  2511. def f(x):
  2512. return x >> 2
  2513. a = self.RPythonAnnotator()
  2514. s = a.build_types(f, [annmodel.SomeInteger(nonneg=True)])
  2515. assert isinstance(s, annmodel.SomeInteger)
  2516. assert s.nonneg
  2517. def test_prebuilt_mutables(self):
  2518. class A:
  2519. pass
  2520. class B:
  2521. pass
  2522. a1 = A()
  2523. a2 = A()
  2524. a1.d = {} # this tests confusion between the two '{}', which
  2525. a2.d = {} # compare equal
  2526. a1.l = []
  2527. a2.l = []
  2528. b = B()
  2529. b.d1 = a1.d
  2530. b.d2 = a2.d
  2531. b.l1 = a1.l
  2532. b.l2 = a2.l
  2533. def dmutate(d):
  2534. d[123] = 321
  2535. def lmutate(l):
  2536. l.append(42)
  2537. def readout(d, l):
  2538. return len(d) + len(l)
  2539. def f():
  2540. dmutate(b.d1)
  2541. dmutate(b.d2)
  2542. dmutate(a1.d)
  2543. dmutate(a2.d)
  2544. lmutate(b.l1)
  2545. lmutate(b.l2)
  2546. lmutate(a1.l)
  2547. lmutate(a2.l)
  2548. return readout(a1.d, a1.l) + readout(a2.d, a2.l)
  2549. a = self.RPythonAnnotator()
  2550. a.build_types(f, [])
  2551. v1, v2 = graphof(a, readout).getargs()
  2552. assert not a.binding(v1).is_constant()
  2553. assert not a.binding(v2).is_constant()
  2554. def test_prebuilt_mutables_dont_use_eq(self):
  2555. # test that __eq__ is not called during annotation, at least
  2556. # when we know that the classes differ anyway
  2557. class Base(object):
  2558. def __eq__(self, other):
  2559. if self is other:
  2560. return True
  2561. raise ValueError
  2562. def __hash__(self):
  2563. return 42
  2564. class A(Base):
  2565. pass
  2566. class B(Base):
  2567. pass
  2568. a1 = A()
  2569. a2 = B()
  2570. a1.x = 5
  2571. a2.x = 6
  2572. def f():
  2573. return a1.x + a2.x
  2574. a = self.RPythonAnnotator()
  2575. s = a.build_types(f, [])
  2576. assert s.knowntype == int
  2577. def test_chr_out_of_bounds(self):
  2578. def g(n, max):
  2579. if n < max:
  2580. return chr(n)
  2581. else:
  2582. return '?'
  2583. def fun(max):
  2584. v = g(1000, max)
  2585. return g(ord(v), max)
  2586. a = self.RPythonAnnotator()
  2587. s = a.build_types(fun, [int])
  2588. assert isinstance(s, annmodel.SomeChar)
  2589. def test_range_nonneg(self):
  2590. def fun(n, k):
  2591. for i in range(n):
  2592. if k == 17:
  2593. return i
  2594. return 0
  2595. a = self.RPythonAnnotator()
  2596. s = a.build_types(fun, [int, int])
  2597. assert isinstance(s, annmodel.SomeInteger)
  2598. assert s.nonneg
  2599. def test_range_nonneg_variablestep(self):
  2600. def get_step(n):
  2601. if n == 1:
  2602. return 2
  2603. else:
  2604. return 3
  2605. def fun(n, k):
  2606. step = get_step(n)
  2607. for i in range(0, n, step):
  2608. if k == 17:
  2609. return i
  2610. return 0
  2611. a = self.RPythonAnnotator()
  2612. s = a.build_types(fun, [int, int])
  2613. assert isinstance(s, annmodel.SomeInteger)
  2614. assert s.nonneg
  2615. def test_reverse_range_nonneg(self):
  2616. def fun(n, k):
  2617. for i in range(n-1, -1, -1):
  2618. if k == 17:
  2619. return i
  2620. return 0
  2621. a = self.RPythonAnnotator()
  2622. s = a.build_types(fun, [int, int])
  2623. assert isinstance(s, annmodel.SomeInteger)
  2624. assert s.nonneg
  2625. def test_sig(self):
  2626. def fun(x, y):
  2627. return x+y
  2628. s_nonneg = annmodel.SomeInteger(nonneg=True)
  2629. fun._annenforceargs_ = Sig(int, s_nonneg)
  2630. a = self.RPythonAnnotator()
  2631. s = a.build_types(fun, [s_nonneg, s_nonneg])
  2632. assert isinstance(s, annmodel.SomeInteger)
  2633. assert not s.nonneg
  2634. with py.test.raises(SignatureError):
  2635. a.build_types(fun, [int, int])
  2636. def test_sig_simpler(self):
  2637. def fun(x, y):
  2638. return x+y
  2639. s_nonneg = annmodel.SomeInteger(nonneg=True)
  2640. fun._annenforceargs_ = (int, s_nonneg)
  2641. a = self.RPythonAnnotator()
  2642. s = a.build_types(fun, [s_nonneg, s_nonneg])
  2643. assert isinstance(s, annmodel.SomeInteger)
  2644. assert not s.nonneg
  2645. with py.test.raises(SignatureError):
  2646. a.build_types(fun, [int, int])
  2647. def test_sig_lambda(self):
  2648. def fun(x, y):
  2649. return y
  2650. s_nonneg = annmodel.SomeInteger(nonneg=True)
  2651. fun._annenforceargs_ = Sig(lambda s1,s2: s1, lambda s1,s2: s1)
  2652. # means: the 2nd argument's annotation becomes the 1st argument's
  2653. # input annotation
  2654. a = self.RPythonAnnotator()
  2655. s = a.build_types(fun, [int, s_nonneg])
  2656. assert isinstance(s, annmodel.SomeInteger)
  2657. assert not s.nonneg
  2658. with py.test.raises(SignatureError):
  2659. a.build_types(fun, [s_nonneg, int])
  2660. def test_sig_bug(self):
  2661. def g(x, y=5):
  2662. return y == 5
  2663. g._annenforceargs_ = (int, int)
  2664. def fun(x):
  2665. return g(x)
  2666. a = self.RPythonAnnotator()
  2667. s = a.build_types(fun, [int])
  2668. assert s.knowntype is bool
  2669. assert s.is_constant()
  2670. def test_sig_list(self):
  2671. def g(buf):
  2672. buf.append(5)
  2673. g._annenforceargs_ = ([int],)
  2674. def fun():
  2675. lst = []
  2676. g(lst)
  2677. return lst[0]
  2678. a = self.RPythonAnnotator()
  2679. s = a.build_types(fun, [])
  2680. assert s.knowntype is int
  2681. assert not s.is_constant()
  2682. def test_slots_check(self):
  2683. class Base(object):
  2684. __slots__ = 'x'
  2685. class A(Base):
  2686. __slots__ = 'y'
  2687. def m(self):
  2688. return 65
  2689. class C(Base):
  2690. __slots__ = 'z'
  2691. def m(self):
  2692. return 67
  2693. for attrname, works in [('x', True),
  2694. ('y', False),
  2695. ('z', False),
  2696. ('t', False)]:
  2697. def fun(n):
  2698. if n: o = A()
  2699. else: o = C()
  2700. setattr(o, attrname, 12)
  2701. return o.m()
  2702. a = self.RPythonAnnotator()
  2703. if works:
  2704. a.build_types(fun, [int])
  2705. else:
  2706. with py.test.raises(NoSuchAttrError):
  2707. a.build_types(fun, [int])
  2708. def test_slots_enforce_attrs(self):
  2709. class Superbase(object):
  2710. __slots__ = 'x'
  2711. class Base(Superbase):
  2712. pass
  2713. class A(Base):
  2714. pass
  2715. class B(Base):
  2716. pass
  2717. def fun(s):
  2718. if s is None: # known not to be None in this test
  2719. o = B()
  2720. o.x = 12
  2721. elif len(s) > 5:
  2722. o = A()
  2723. else:
  2724. o = Base()
  2725. return o.x
  2726. a = self.RPythonAnnotator()
  2727. s = a.build_types(fun, [str])
  2728. assert s == annmodel.s_ImpossibleValue # but not blocked blocks
  2729. def test_enforced_attrs_check(self):
  2730. class Base(object):
  2731. _attrs_ = 'x'
  2732. class A(Base):
  2733. _attrs_ = 'y'
  2734. def m(self):
  2735. return 65
  2736. class C(Base):
  2737. _attrs_ = 'z'
  2738. def m(self):
  2739. return 67
  2740. for attrname, works in [('x', True),
  2741. ('y', False),
  2742. ('z', False),
  2743. ('t', False)]:
  2744. def fun(n):
  2745. if n: o = A()
  2746. else: o = C()
  2747. setattr(o, attrname, 12)
  2748. return o.m()
  2749. a = self.RPythonAnnotator()
  2750. if works:
  2751. a.build_types(fun, [int])
  2752. else:
  2753. py.test.raises(NoSuchAttrError, a.build_types, fun, [int])
  2754. def test_attrs_enforce_attrs(self):
  2755. class Superbase(object):
  2756. _attrs_ = 'x'
  2757. class Base(Superbase):
  2758. pass
  2759. class A(Base):
  2760. pass
  2761. class B(Base):
  2762. pass
  2763. def fun(s):
  2764. if s is None: # known not to be None in this test
  2765. o = B()
  2766. o.x = 12
  2767. elif len(s) > 5:
  2768. o = A()
  2769. else:
  2770. o = Base()
  2771. return o.x
  2772. a = self.RPythonAnnotator()
  2773. s = a.build_types(fun, [str])
  2774. assert s == annmodel.s_ImpossibleValue # but not blocked blocks
  2775. def test_pbc_enforce_attrs(self):
  2776. class F(object):
  2777. _attrs_ = ['foo',]
  2778. def _freeze_(self):
  2779. return True
  2780. p1 = F()
  2781. p2 = F()
  2782. def g(): pass
  2783. def f(x):
  2784. if x:
  2785. p = p1
  2786. else:
  2787. p = p2
  2788. g()
  2789. return p.foo
  2790. a = self.RPythonAnnotator()
  2791. a.build_types(f, [bool])
  2792. def test_float_cmp(self):
  2793. def fun(x, y):
  2794. return (x < y,
  2795. x <= y,
  2796. x == y,
  2797. x != y,
  2798. x > y,
  2799. x >= y)
  2800. a = self.RPythonAnnotator(policy=AnnotatorPolicy())
  2801. s = a.build_types(fun, [float, float])
  2802. assert [s_item.knowntype for s_item in s.items] == [bool] * 6
  2803. def test_empty_range(self):
  2804. def g(lst):
  2805. total = 0
  2806. for i in range(len(lst)):
  2807. total += lst[i]
  2808. return total
  2809. def fun():
  2810. return g([])
  2811. a = self.RPythonAnnotator(policy=AnnotatorPolicy())
  2812. s = a.build_types(fun, [])
  2813. assert s.const == 0
  2814. def test_compare_int_bool(self):
  2815. def fun(x):
  2816. return 50 < x
  2817. a = self.RPythonAnnotator(policy=AnnotatorPolicy())
  2818. s = a.build_types(fun, [bool])
  2819. assert isinstance(s, annmodel.SomeBool)
  2820. def test_long_as_intermediate_value(self):
  2821. from sys import maxint
  2822. from rpython.rlib.rarithmetic import intmask
  2823. def fun(x):
  2824. if x > 0:
  2825. v = maxint
  2826. else:
  2827. v = -maxint
  2828. return intmask(v * 10)
  2829. P = AnnotatorPolicy()
  2830. a = self.RPythonAnnotator(policy=P)
  2831. s = a.build_types(fun, [bool])
  2832. assert isinstance(s, annmodel.SomeInteger)
  2833. def test_instance_with_flags(self):
  2834. from rpython.rlib.jit import hint
  2835. class A:
  2836. _virtualizable_ = []
  2837. class B(A):
  2838. def meth(self):
  2839. return self
  2840. class C(A):
  2841. def meth(self):
  2842. return self
  2843. def f(n):
  2844. x = B()
  2845. x = hint(x, access_directly=True)
  2846. m = x.meth
  2847. for i in range(n):
  2848. x = C()
  2849. m = x.meth
  2850. return x, m, m()
  2851. a = self.RPythonAnnotator()
  2852. s = a.build_types(f, [a.bookkeeper.immutablevalue(0)])
  2853. assert isinstance(s.items[0], annmodel.SomeInstance)
  2854. assert s.items[0].flags == {'access_directly': True}
  2855. assert isinstance(s.items[1], annmodel.SomePBC)
  2856. assert len(s.items[1].descriptions) == 1
  2857. assert s.items[1].any_description().flags == {'access_directly':
  2858. True}
  2859. assert isinstance(s.items[2], annmodel.SomeInstance)
  2860. assert s.items[2].flags == {'access_directly': True}
  2861. a = self.RPythonAnnotator()
  2862. s = a.build_types(f, [int])
  2863. assert isinstance(s.items[0], annmodel.SomeInstance)
  2864. assert s.items[0].flags == {}
  2865. assert isinstance(s.items[1], annmodel.SomePBC)
  2866. assert isinstance(s.items[2], annmodel.SomeInstance)
  2867. assert s.items[2].flags == {}
  2868. @py.test.mark.xfail
  2869. def test_no_access_directly_on_heap(self):
  2870. from rpython.rlib.jit import hint
  2871. class A:
  2872. _virtualizable_ = []
  2873. class I:
  2874. pass
  2875. def f():
  2876. x = A()
  2877. x = hint(x, access_directly=True)
  2878. i = I()
  2879. i.x = x
  2880. a = self.RPythonAnnotator()
  2881. with py.test.raises(AnnotatorError):
  2882. a.build_types(f, [])
  2883. class M:
  2884. def __init__(self):
  2885. self.l = []
  2886. self.d = {}
  2887. class C:
  2888. def _freeze_(self):
  2889. return True
  2890. def __init__(self):
  2891. self.m = M()
  2892. self.l2 = []
  2893. c = C()
  2894. def f():
  2895. x = A()
  2896. x = hint(x, access_directly=True)
  2897. c.m.l.append(x)
  2898. a = self.RPythonAnnotator()
  2899. py.test.raises(AnnotatorError, a.build_types, f, [])
  2900. def f():
  2901. x = A()
  2902. x = hint(x, access_directly=True)
  2903. c.m.d[None] = x
  2904. a = self.RPythonAnnotator()
  2905. py.test.raises(AnnotatorError, a.build_types, f, [])
  2906. def f():
  2907. x = A()
  2908. x = hint(x, access_directly=True)
  2909. c.m.d[x] = None
  2910. a = self.RPythonAnnotator()
  2911. py.test.raises(AnnotatorError, a.build_types, f, [])
  2912. def test_weakref(self):
  2913. import weakref
  2914. class A:
  2915. pass
  2916. class B(A):
  2917. pass
  2918. class C(A):
  2919. pass
  2920. def f(n):
  2921. if n:
  2922. b = B()
  2923. b.hello = 42
  2924. r = weakref.ref(b)
  2925. else:
  2926. c = C()
  2927. c.hello = 64
  2928. r = weakref.ref(c)
  2929. return r().hello
  2930. a = self.RPythonAnnotator()
  2931. s = a.build_types(f, [int])
  2932. assert isinstance(s, annmodel.SomeInteger)
  2933. assert not s.is_constant()
  2934. def test_float_pow_unsupported(self):
  2935. def f(x, y):
  2936. x **= y
  2937. return x ** y
  2938. a = self.RPythonAnnotator()
  2939. py.test.raises(FlowingError, a.build_types, f, [int, int])
  2940. a = self.RPythonAnnotator()
  2941. py.test.raises(FlowingError, a.build_types, f, [float, float])
  2942. def test_intcmp_bug(self):
  2943. def g(x, y):
  2944. return x <= y
  2945. def f(x, y):
  2946. if g(x, y):
  2947. g(x, r_uint(y))
  2948. a = self.RPythonAnnotator()
  2949. with py.test.raises(UnionError):
  2950. a.build_types(f, [int, int])
  2951. def test_compare_with_zero(self):
  2952. def g():
  2953. should_not_see_this
  2954. def f(n):
  2955. assert n >= 0
  2956. if n < 0:
  2957. g()
  2958. if not (n >= 0):
  2959. g()
  2960. a = self.RPythonAnnotator()
  2961. a.build_types(f, [int])
  2962. def test_r_singlefloat(self):
  2963. z = r_singlefloat(0.4)
  2964. def g(n):
  2965. if n > 0:
  2966. return r_singlefloat(n * 0.1)
  2967. else:
  2968. return z
  2969. a = self.RPythonAnnotator()
  2970. s = a.build_types(g, [int])
  2971. assert isinstance(s, annmodel.SomeSingleFloat)
  2972. def test_unicode_simple(self):
  2973. def f():
  2974. return u'xxx'
  2975. a = self.RPythonAnnotator()
  2976. s = a.build_types(f, [])
  2977. assert isinstance(s, annmodel.SomeUnicodeString)
  2978. def test_unicode(self):
  2979. def g(n):
  2980. if n > 0:
  2981. return unichr(1234)
  2982. else:
  2983. return u"x\xe4x"
  2984. def f(n):
  2985. x = g(0)
  2986. return x[n]
  2987. a = self.RPythonAnnotator()
  2988. s = a.build_types(g, [int])
  2989. assert isinstance(s, annmodel.SomeUnicodeString)
  2990. a = self.RPythonAnnotator()
  2991. s = a.build_types(f, [int])
  2992. assert isinstance(s, annmodel.SomeUnicodeCodePoint)
  2993. def test_unicode_from_string(self):
  2994. def f(x):
  2995. return unicode(x)
  2996. a = self.RPythonAnnotator()
  2997. s = a.build_types(f, [str])
  2998. assert isinstance(s, annmodel.SomeUnicodeString)
  2999. def test_unicode_add(self):
  3000. def f(x):
  3001. return unicode(x) + unichr(1234)
  3002. def g(x):
  3003. return unichr(x) + unichr(2)
  3004. a = self.RPythonAnnotator()
  3005. s = a.build_types(f, [str])
  3006. assert isinstance(s, annmodel.SomeUnicodeString)
  3007. a = self.RPythonAnnotator()
  3008. s = a.build_types(f, [int])
  3009. assert isinstance(s, annmodel.SomeUnicodeString)
  3010. def test_unicode_startswith(self):
  3011. def f(x):
  3012. return u'xxxx'.replace(x, u'z')
  3013. a = self.RPythonAnnotator()
  3014. s = a.build_types(f, [unicode])
  3015. assert isinstance(s, annmodel.SomeUnicodeString)
  3016. def test_unicode_buildtypes(self):
  3017. def f(x):
  3018. return x
  3019. a = self.RPythonAnnotator()
  3020. s = a.build_types(f, [unicode])
  3021. assert isinstance(s, annmodel.SomeUnicodeString)
  3022. def test_replace_annotations(self):
  3023. def f(x):
  3024. return 'a'.replace(x, 'b')
  3025. a = self.RPythonAnnotator()
  3026. s = a.build_types(f, [str])
  3027. assert isinstance(s, annmodel.SomeString)
  3028. assert s.no_nul
  3029. def f(x):
  3030. return u'a'.replace(x, u'b')
  3031. a = self.RPythonAnnotator()
  3032. s = a.build_types(f, [unicode])
  3033. assert isinstance(s, annmodel.SomeUnicodeString)
  3034. assert s.no_nul
  3035. def test_unicode_char(self):
  3036. def f(x, i):
  3037. for c in x:
  3038. if c == i:
  3039. return c
  3040. return 'x'
  3041. a = self.RPythonAnnotator()
  3042. s = a.build_types(f, [unicode, str])
  3043. assert isinstance(s, annmodel.SomeUnicodeCodePoint)
  3044. def test_strformatting_unicode(self):
  3045. def f(x):
  3046. return '%s' % unichr(x)
  3047. a = self.RPythonAnnotator()
  3048. py.test.raises(AnnotatorError, a.build_types, f, [int])
  3049. def f(x):
  3050. return '%s' % (unichr(x) * 3)
  3051. a = self.RPythonAnnotator()
  3052. py.test.raises(AnnotatorError, a.build_types, f, [int])
  3053. def f(x):
  3054. return '%s%s' % (1, unichr(x))
  3055. a = self.RPythonAnnotator()
  3056. py.test.raises(AnnotatorError, a.build_types, f, [int])
  3057. def f(x):
  3058. return '%s%s' % (1, unichr(x) * 15)
  3059. a = self.RPythonAnnotator()
  3060. py.test.raises(AnnotatorError, a.build_types, f, [int])
  3061. def test_strformatting_tuple(self):
  3062. """
  3063. A function which returns the result of interpolating a tuple of a
  3064. single str into a str format string should be annotated as returning
  3065. SomeString.
  3066. """
  3067. def f(x):
  3068. return '%s' % (x,)
  3069. a = self.RPythonAnnotator()
  3070. s = a.build_types(f, [str])
  3071. assert isinstance(s, annmodel.SomeString)
  3072. def test_unicodeformatting(self):
  3073. def f(x):
  3074. return u'%s' % x
  3075. a = self.RPythonAnnotator()
  3076. s = a.build_types(f, [unicode])
  3077. assert isinstance(s, annmodel.SomeUnicodeString)
  3078. def test_unicodeformatting_tuple(self):
  3079. def f(x):
  3080. return u'%s' % (x,)
  3081. a = self.RPythonAnnotator()
  3082. s = a.build_types(f, [unicode])
  3083. assert isinstance(s, annmodel.SomeUnicodeString)
  3084. def test_extended_slice(self):
  3085. a = self.RPythonAnnotator()
  3086. def f(start, end, step):
  3087. return [1, 2, 3][start:end:step]
  3088. with py.test.raises(AnnotatorError):
  3089. a.build_types(f, [int, int, int])
  3090. a = self.RPythonAnnotator()
  3091. with py.test.raises(AnnotatorError):
  3092. a.build_types(f, [annmodel.SomeInteger(nonneg=True),
  3093. annmodel.SomeInteger(nonneg=True),
  3094. annmodel.SomeInteger(nonneg=True)])
  3095. def f(x):
  3096. return x[::-1]
  3097. a = self.RPythonAnnotator()
  3098. with py.test.raises(AnnotatorError):
  3099. a.build_types(f, [str])
  3100. def f(x):
  3101. return x[::2]
  3102. a = self.RPythonAnnotator()
  3103. with py.test.raises(AnnotatorError):
  3104. a.build_types(f, [str])
  3105. def f(x):
  3106. return x[1:2:1]
  3107. a = self.RPythonAnnotator()
  3108. with py.test.raises(AnnotatorError):
  3109. a.build_types(f, [str])
  3110. def test_negative_slice(self):
  3111. def f(s, e):
  3112. return [1, 2, 3][s:e]
  3113. a = self.RPythonAnnotator()
  3114. py.test.raises(AnnotatorError, "a.build_types(f, [int, int])")
  3115. a.build_types(f, [annmodel.SomeInteger(nonneg=True),
  3116. annmodel.SomeInteger(nonneg=True)])
  3117. def f(x):
  3118. return x[:-1]
  3119. a.build_types(f, [str])
  3120. def test_negative_number_find(self):
  3121. def f(s, e):
  3122. return "xyz".find("x", s, e)
  3123. a = self.RPythonAnnotator()
  3124. py.test.raises(AnnotatorError, "a.build_types(f, [int, int])")
  3125. a.build_types(f, [annmodel.SomeInteger(nonneg=True),
  3126. annmodel.SomeInteger(nonneg=True)])
  3127. def f(s, e):
  3128. return "xyz".rfind("x", s, e)
  3129. py.test.raises(AnnotatorError, "a.build_types(f, [int, int])")
  3130. a.build_types(f, [annmodel.SomeInteger(nonneg=True),
  3131. annmodel.SomeInteger(nonneg=True)])
  3132. def f(s, e):
  3133. return "xyz".count("x", s, e)
  3134. py.test.raises(AnnotatorError, "a.build_types(f, [int, int])")
  3135. a.build_types(f, [annmodel.SomeInteger(nonneg=True),
  3136. annmodel.SomeInteger(nonneg=True)])
  3137. def test_setslice(self):
  3138. def f():
  3139. lst = [2, 5, 7]
  3140. lst[1:2] = [4]
  3141. return lst
  3142. a = self.RPythonAnnotator()
  3143. s = a.build_types(f, [])
  3144. assert isinstance(s, annmodel.SomeList)
  3145. assert s.listdef.listitem.resized
  3146. assert not s.listdef.listitem.immutable
  3147. assert s.listdef.listitem.mutated
  3148. def test_delslice(self):
  3149. def f():
  3150. lst = [2, 5, 7]
  3151. del lst[1:2]
  3152. return lst
  3153. a = self.RPythonAnnotator()
  3154. s = a.build_types(f, [])
  3155. assert isinstance(s, annmodel.SomeList)
  3156. assert s.listdef.listitem.resized
  3157. def test_varargs(self):
  3158. def f(*args):
  3159. return args[0] + 42
  3160. a = self.RPythonAnnotator()
  3161. s = a.build_types(f, [int, int])
  3162. assert isinstance(s, annmodel.SomeInteger)
  3163. def test_listitem_no_mutating(self):
  3164. from rpython.rlib.debug import check_annotation
  3165. called = []
  3166. def checker(ann, bk):
  3167. called.append(True)
  3168. assert not ann.listdef.listitem.mutated
  3169. ann.listdef.never_resize()
  3170. def f():
  3171. l = [1,2,3]
  3172. check_annotation(l, checker)
  3173. return l
  3174. def g():
  3175. l = f()
  3176. l.append(4)
  3177. a = self.RPythonAnnotator()
  3178. py.test.raises(ListChangeUnallowed, a.build_types, g, [])
  3179. assert called
  3180. def test_listitem_no_mutating2(self):
  3181. from rpython.rlib.debug import make_sure_not_resized
  3182. def f():
  3183. return make_sure_not_resized([1,2,3])
  3184. def g():
  3185. l = [1,2,3]
  3186. l.append(4)
  3187. return l
  3188. def fn(i):
  3189. if i:
  3190. func = f
  3191. else:
  3192. func = g
  3193. return func()
  3194. a = self.RPythonAnnotator()
  3195. a.translator.config.translation.list_comprehension_operations = True
  3196. py.test.raises(ListChangeUnallowed, a.build_types, fn, [int])
  3197. def test_listitem_never_resize(self):
  3198. from rpython.rlib.debug import check_annotation
  3199. def checker(ann, bk):
  3200. ann.listdef.never_resize()
  3201. def f():
  3202. l = [1,2,3]
  3203. l.append(4)
  3204. check_annotation(l, checker)
  3205. a = self.RPythonAnnotator()
  3206. py.test.raises(ListChangeUnallowed, a.build_types, f, [])
  3207. def test_len_of_empty_list(self):
  3208. class X:
  3209. pass
  3210. def f(n):
  3211. x = X()
  3212. x.lst = None
  3213. if n < 0: # to showcase a failure of the famous "assert contains"
  3214. return len(x.lst)
  3215. x.lst = []
  3216. return len(x.lst)
  3217. a = self.RPythonAnnotator()
  3218. s = a.build_types(f, [int])
  3219. assert s.const == 0
  3220. def test_hash_sideeffect(self):
  3221. class X:
  3222. pass
  3223. x1 = X()
  3224. x2 = X()
  3225. x3 = X()
  3226. d = {(2, x1): 5, (3, x2): 7}
  3227. def f(n, m):
  3228. if m == 1: x = x1
  3229. elif m == 2: x = x2
  3230. else: x = x3
  3231. return d[n, x]
  3232. a = self.RPythonAnnotator()
  3233. s = a.build_types(f, [int, int])
  3234. assert s.knowntype == int
  3235. assert hasattr(x1, '__precomputed_identity_hash')
  3236. assert hasattr(x2, '__precomputed_identity_hash')
  3237. assert not hasattr(x3, '__precomputed_identity_hash')
  3238. def test_contains_of_empty_dict(self):
  3239. class A(object):
  3240. def meth(self):
  3241. return 1
  3242. def g(x, y):
  3243. d1 = {}
  3244. for i in range(y):
  3245. if x in d1:
  3246. return d1[x].meth()
  3247. d1[i+1] = A()
  3248. return 0
  3249. a = self.RPythonAnnotator()
  3250. s = a.build_types(g, [int, int])
  3251. assert s.knowntype is int
  3252. def f(x):
  3253. d0 = {}
  3254. if x in d0:
  3255. d0[x].meth()
  3256. return x+1
  3257. a = self.RPythonAnnotator()
  3258. s = a.build_types(f, [int])
  3259. assert s.knowntype is int
  3260. def test_relax(self):
  3261. def f(*args):
  3262. return args[0] + args[1]
  3263. f.relax_sig_check = True
  3264. def g(x):
  3265. return f(x, x - x)
  3266. a = self.RPythonAnnotator()
  3267. s = a.build_types(g, [int])
  3268. assert a.bookkeeper.getdesc(f).getuniquegraph()
  3269. def test_cannot_raise_ll_exception(self):
  3270. from rpython.rtyper.annlowlevel import cast_instance_to_base_ptr
  3271. #
  3272. def f():
  3273. e = OverflowError()
  3274. lle = cast_instance_to_base_ptr(e)
  3275. raise Exception(lle)
  3276. # ^^^ instead, must cast back from a base ptr to an instance
  3277. a = self.RPythonAnnotator()
  3278. with py.test.raises(AssertionError):
  3279. a.build_types(f, [])
  3280. def test_enumerate(self):
  3281. def f():
  3282. for i, x in enumerate(['a', 'b', 'c', 'd']):
  3283. if i == 2:
  3284. return x
  3285. return '?'
  3286. a = self.RPythonAnnotator()
  3287. s = a.build_types(f, [])
  3288. assert isinstance(s, annmodel.SomeChar)
  3289. def test_context_manager(self):
  3290. class C:
  3291. def __init__(self):
  3292. pass
  3293. def __enter__(self):
  3294. self.x = 1
  3295. def __exit__(self, *args):
  3296. self.x = 3
  3297. def f():
  3298. c = C()
  3299. with c:
  3300. pass
  3301. return c.x
  3302. a = self.RPythonAnnotator()
  3303. s = a.build_types(f, [])
  3304. assert isinstance(s, annmodel.SomeInteger)
  3305. # not a constant: both __enter__ and __exit__ have been annotated
  3306. assert not s.is_constant()
  3307. def test_make_sure_not_resized(self):
  3308. from rpython.rlib.debug import make_sure_not_resized
  3309. def pycode(consts):
  3310. make_sure_not_resized(consts)
  3311. def build1():
  3312. return pycode(consts=[1])
  3313. def build2():
  3314. return pycode(consts=[0])
  3315. def fn():
  3316. build1()
  3317. build2()
  3318. a = self.RPythonAnnotator()
  3319. a.translator.config.translation.list_comprehension_operations = True
  3320. a.build_types(fn, [])
  3321. # assert did not raise ListChangeUnallowed
  3322. def test_return_immutable_list(self):
  3323. class A:
  3324. _immutable_fields_ = ['lst[*]']
  3325. def f(n):
  3326. a = A()
  3327. l1 = [n, 0]
  3328. l1[1] = n+1
  3329. a.lst = l1
  3330. return a.lst
  3331. a = self.RPythonAnnotator()
  3332. s = a.build_types(f, [int])
  3333. assert s.listdef.listitem.immutable
  3334. def test_return_immutable_list_quasiimmut_field(self):
  3335. class A:
  3336. _immutable_fields_ = ['lst?[*]']
  3337. def f(n):
  3338. a = A()
  3339. l1 = [n, 0]
  3340. l1[1] = n+1
  3341. a.lst = l1
  3342. return a.lst
  3343. a = self.RPythonAnnotator()
  3344. s = a.build_types(f, [int])
  3345. assert s.listdef.listitem.immutable
  3346. def test_immutable_list_is_actually_resized(self):
  3347. class A:
  3348. _immutable_fields_ = ['lst[*]']
  3349. def f(n):
  3350. a = A()
  3351. l1 = [n]
  3352. l1.append(n+1)
  3353. a.lst = l1
  3354. return a.lst
  3355. a = self.RPythonAnnotator()
  3356. py.test.raises(ListChangeUnallowed, a.build_types, f, [int])
  3357. def test_immutable_list_is_assigned_a_resizable_list(self):
  3358. class A:
  3359. _immutable_fields_ = ['lst[*]']
  3360. def f(n):
  3361. a = A()
  3362. foo = []
  3363. foo.append(n)
  3364. a.lst = foo
  3365. a = self.RPythonAnnotator()
  3366. py.test.raises(ListChangeUnallowed, a.build_types, f, [int])
  3367. def test_can_merge_immutable_list_with_regular_list(self):
  3368. class A:
  3369. _immutable_fields_ = ['lst[*]']
  3370. def foo(lst):
  3371. pass
  3372. def f(n):
  3373. a = A()
  3374. l1 = [n, 0]
  3375. l1[1] = n+1
  3376. a.lst = l1
  3377. if n > 0:
  3378. foo(a.lst)
  3379. else:
  3380. lst = [0]
  3381. lst[0] = n
  3382. foo(lst)
  3383. a = self.RPythonAnnotator()
  3384. a.build_types(f, [int])
  3385. def f(n):
  3386. a = A()
  3387. l1 = [n, 0]
  3388. l1[1] = n+1
  3389. a.lst = l1
  3390. if n > 0:
  3391. lst = [0]
  3392. lst[0] = n
  3393. foo(lst)
  3394. else:
  3395. foo(a.lst)
  3396. a = self.RPythonAnnotator()
  3397. a.build_types(f, [int])
  3398. def test_immutable_field_subclass(self):
  3399. class Root:
  3400. pass
  3401. class A(Root):
  3402. _immutable_fields_ = ['_my_lst[*]']
  3403. def __init__(self, lst):
  3404. self._my_lst = lst
  3405. def foo(x):
  3406. return len(x._my_lst)
  3407. def f(n):
  3408. foo(A([2, n]))
  3409. foo(Root())
  3410. a = self.RPythonAnnotator()
  3411. e = py.test.raises(Exception, a.build_types, f, [int])
  3412. assert "field '_my_lst' was migrated" in str(e.value)
  3413. def test_range_variable_step(self):
  3414. def g(n):
  3415. return range(0, 10, n)
  3416. def f(n):
  3417. r = g(1) # constant step, at first
  3418. s = g(n) # but it becomes a variable step
  3419. return r
  3420. a = self.RPythonAnnotator()
  3421. s = a.build_types(f, [int])
  3422. assert s.listdef.listitem.range_step == 0
  3423. def test_specialize_arg_memo(self):
  3424. @objectmodel.specialize.memo()
  3425. def g(n):
  3426. return n
  3427. @objectmodel.specialize.arg(0)
  3428. def f(i):
  3429. return g(i)
  3430. def main(i):
  3431. if i == 2:
  3432. return f(2)
  3433. elif i == 3:
  3434. return f(3)
  3435. else:
  3436. raise NotImplementedError
  3437. a = self.RPythonAnnotator()
  3438. s = a.build_types(main, [int])
  3439. assert isinstance(s, annmodel.SomeInteger)
  3440. def test_join_none_and_nonnull(self):
  3441. from rpython.rlib.rstring import assert_str0
  3442. def f(i):
  3443. a = str(i)
  3444. a = assert_str0(a)
  3445. return a.join([None])
  3446. a = self.RPythonAnnotator()
  3447. s = a.build_types(f, [int])
  3448. assert isinstance(s, annmodel.SomeString)
  3449. assert not s.can_be_None
  3450. def test_contains_no_nul(self):
  3451. def f(i):
  3452. if "\0" in i:
  3453. return None
  3454. else:
  3455. return i
  3456. a = self.RPythonAnnotator()
  3457. a.translator.config.translation.check_str_without_nul = True
  3458. s = a.build_types(f, [annmodel.SomeString(no_nul=False)])
  3459. assert isinstance(s, annmodel.SomeString)
  3460. assert s.can_be_None
  3461. assert s.no_nul
  3462. def test_contains_no_nul_unicode(self):
  3463. def f(i):
  3464. if u"\0" in i:
  3465. return None
  3466. else:
  3467. return i
  3468. a = self.RPythonAnnotator()
  3469. a.translator.config.translation.check_str_without_nul = True
  3470. s = a.build_types(f, [annmodel.SomeUnicodeString(no_nul=False)])
  3471. assert isinstance(s, annmodel.SomeUnicodeString)
  3472. assert s.can_be_None
  3473. assert s.no_nul
  3474. def test_no___call__(self):
  3475. class X(object):
  3476. def __call__(self):
  3477. xxx
  3478. x = X()
  3479. def f():
  3480. return x
  3481. a = self.RPythonAnnotator()
  3482. e = py.test.raises(Exception, a.build_types, f, [])
  3483. assert 'object with a __call__ is not RPython' in str(e.value)
  3484. def test_os_getcwd(self):
  3485. import os
  3486. def fn():
  3487. return os.getcwd()
  3488. a = self.RPythonAnnotator()
  3489. s = a.build_types(fn, [])
  3490. assert isinstance(s, annmodel.SomeString)
  3491. assert s.no_nul
  3492. def test_os_getenv(self):
  3493. import os
  3494. def fn():
  3495. return os.environ.get('PATH')
  3496. a = self.RPythonAnnotator()
  3497. s = a.build_types(fn, [])
  3498. assert isinstance(s, annmodel.SomeString)
  3499. assert s.no_nul
  3500. def test_base_iter(self):
  3501. class A(object):
  3502. def __iter__(self):
  3503. return self
  3504. def fn():
  3505. return iter(A())
  3506. a = self.RPythonAnnotator()
  3507. s = a.build_types(fn, [])
  3508. assert isinstance(s, annmodel.SomeInstance)
  3509. assert s.classdef.name.endswith('.A')
  3510. def test_iter_next(self):
  3511. class A(object):
  3512. def __iter__(self):
  3513. return self
  3514. def next(self):
  3515. return 1
  3516. def fn():
  3517. s = 0
  3518. for x in A():
  3519. s += x
  3520. return s
  3521. a = self.RPythonAnnotator()
  3522. s = a.build_types(fn, [])
  3523. assert len(a.translator.graphs) == 3 # fn, __iter__, next
  3524. assert isinstance(s, annmodel.SomeInteger)
  3525. def test_next_function(self):
  3526. def fn(n):
  3527. x = [0, 1, n]
  3528. i = iter(x)
  3529. return next(i) + next(i)
  3530. a = self.RPythonAnnotator()
  3531. s = a.build_types(fn, [int])
  3532. assert isinstance(s, annmodel.SomeInteger)
  3533. def test_instance_getitem(self):
  3534. class A(object):
  3535. def __getitem__(self, i):
  3536. return i * i
  3537. def fn(i):
  3538. a = A()
  3539. return a[i]
  3540. a = self.RPythonAnnotator()
  3541. s = a.build_types(fn, [int])
  3542. assert len(a.translator.graphs) == 2 # fn, __getitem__
  3543. assert isinstance(s, annmodel.SomeInteger)
  3544. def test_instance_setitem(self):
  3545. class A(object):
  3546. def __setitem__(self, i, v):
  3547. self.value = i * v
  3548. def fn(i, v):
  3549. a = A()
  3550. a[i] = v
  3551. return a.value
  3552. a = self.RPythonAnnotator()
  3553. s = a.build_types(fn, [int, int])
  3554. assert len(a.translator.graphs) == 2 # fn, __setitem__
  3555. assert isinstance(s, annmodel.SomeInteger)
  3556. def test_instance_getslice(self):
  3557. class A(object):
  3558. def __getslice__(self, stop, start):
  3559. return "Test"[stop:start]
  3560. def fn():
  3561. a = A()
  3562. return a[0:2]
  3563. a = self.RPythonAnnotator()
  3564. s = a.build_types(fn, [])
  3565. assert len(a.translator.graphs) == 2 # fn, __getslice__
  3566. assert isinstance(s, annmodel.SomeString)
  3567. def test_instance_setslice(self):
  3568. class A(object):
  3569. def __setslice__(self, stop, start, value):
  3570. self.value = value
  3571. def fn():
  3572. a = A()
  3573. a[0:2] = '00'
  3574. return a.value
  3575. a = self.RPythonAnnotator()
  3576. s = a.build_types(fn, [])
  3577. assert len(a.translator.graphs) == 2 # fn, __setslice__
  3578. assert isinstance(s, annmodel.SomeString)
  3579. def test_instance_len(self):
  3580. class A(object):
  3581. def __len__(self):
  3582. return 0
  3583. def fn():
  3584. a = A()
  3585. return len(a)
  3586. a = self.RPythonAnnotator()
  3587. s = a.build_types(fn, [])
  3588. assert len(a.translator.graphs) == 2 # fn, __len__
  3589. assert isinstance(s, annmodel.SomeInteger)
  3590. def test_reversed(self):
  3591. def fn(n):
  3592. for elem in reversed([1, 2, 3, 4, 5]):
  3593. return elem
  3594. return n
  3595. a = self.RPythonAnnotator()
  3596. s = a.build_types(fn, [int])
  3597. assert isinstance(s, annmodel.SomeInteger)
  3598. def test_no_attr_on_common_exception_classes(self):
  3599. for cls in [ValueError, Exception]:
  3600. def fn():
  3601. e = cls()
  3602. e.foo = "bar"
  3603. a = self.RPythonAnnotator()
  3604. with py.test.raises(NoSuchAttrError):
  3605. a.build_types(fn, [])
  3606. def test_lower_char(self):
  3607. def fn(c):
  3608. return c.lower()
  3609. a = self.RPythonAnnotator()
  3610. s = a.build_types(fn, [annmodel.SomeChar()])
  3611. assert s == annmodel.SomeChar()
  3612. def test_isinstance_double_const(self):
  3613. class X(object):
  3614. def _freeze_(self):
  3615. return True
  3616. x = X()
  3617. def f(i):
  3618. if i:
  3619. x1 = x
  3620. else:
  3621. x1 = None
  3622. print "hello" # this is to force the merge of blocks
  3623. return isinstance(x1, X)
  3624. a = self.RPythonAnnotator()
  3625. s = a.build_types(f, [annmodel.SomeInteger()])
  3626. assert isinstance(s, annmodel.SomeBool)
  3627. def test_object_init(self):
  3628. class A(object):
  3629. pass
  3630. class B(A):
  3631. def __init__(self):
  3632. A.__init__(self)
  3633. def f():
  3634. B()
  3635. a = self.RPythonAnnotator()
  3636. a.build_types(f, []) # assert did not explode
  3637. def test_bytearray(self):
  3638. def f():
  3639. return bytearray("xyz")
  3640. a = self.RPythonAnnotator()
  3641. s = a.build_types(f, [])
  3642. assert isinstance(s, annmodel.SomeByteArray)
  3643. assert not s.is_constant() # never a constant!
  3644. def test_bytearray_add(self):
  3645. def f(a):
  3646. return a + bytearray("xyz")
  3647. a = self.RPythonAnnotator()
  3648. assert isinstance(a.build_types(f, [annmodel.SomeByteArray()]),
  3649. annmodel.SomeByteArray)
  3650. a = self.RPythonAnnotator()
  3651. assert isinstance(a.build_types(f, [str]),
  3652. annmodel.SomeByteArray)
  3653. a = self.RPythonAnnotator()
  3654. assert isinstance(a.build_types(f, [annmodel.SomeChar()]),
  3655. annmodel.SomeByteArray)
  3656. def test_bytearray_setitem_getitem(self):
  3657. def f(b, i, c):
  3658. b[i] = c
  3659. return b[i + 1]
  3660. a = self.RPythonAnnotator()
  3661. assert isinstance(a.build_types(f, [annmodel.SomeByteArray(),
  3662. int, int]),
  3663. annmodel.SomeInteger)
  3664. def test_constant_startswith_endswith(self):
  3665. def f():
  3666. return "abc".startswith("ab") and "abc".endswith("bc")
  3667. a = self.RPythonAnnotator()
  3668. assert a.build_types(f, []).const is True
  3669. def test_specific_attributes(self):
  3670. class A(object):
  3671. pass
  3672. class B(A):
  3673. def __init__(self, x):
  3674. assert x >= 0
  3675. self.x = x
  3676. def fn(i):
  3677. if i % 2:
  3678. a = A()
  3679. else:
  3680. a = B(3)
  3681. if i % 3:
  3682. a.x = -3
  3683. if isinstance(a, B):
  3684. return a.x
  3685. return 0
  3686. a = self.RPythonAnnotator()
  3687. assert not a.build_types(fn, [int]).nonneg
  3688. def test_unionerror_attrs(self):
  3689. def f(x):
  3690. if x < 10:
  3691. return 1
  3692. else:
  3693. return "bbb"
  3694. a = self.RPythonAnnotator()
  3695. with py.test.raises(UnionError) as exc:
  3696. a.build_types(f, [int])
  3697. the_exc = exc.value
  3698. s_objs = set([type(the_exc.s_obj1), type(the_exc.s_obj2)])
  3699. assert s_objs == set([annmodel.SomeInteger, annmodel.SomeString])
  3700. def test_unionerror_tuple_size(self):
  3701. def f(x):
  3702. if x < 10:
  3703. return (1, )
  3704. else:
  3705. return (1, 2)
  3706. a = self.RPythonAnnotator()
  3707. with py.test.raises(UnionError) as exc:
  3708. a.build_types(f, [int])
  3709. assert "RPython cannot unify tuples of different length: 2 versus 1" in exc.value.msg
  3710. def test_unionerror_signedness(self):
  3711. def f(x):
  3712. if x < 10:
  3713. return r_uint(99)
  3714. else:
  3715. return -1
  3716. a = self.RPythonAnnotator()
  3717. with py.test.raises(UnionError) as exc:
  3718. a.build_types(f, [int])
  3719. assert ("RPython cannot prove that these integers are of the "
  3720. "same signedness" in exc.value.msg)
  3721. def test_unionerror_instance(self):
  3722. class A(object): pass
  3723. class B(object): pass
  3724. def f(x):
  3725. if x < 10:
  3726. return A()
  3727. else:
  3728. return B()
  3729. a = self.RPythonAnnotator()
  3730. with py.test.raises(UnionError) as exc:
  3731. a.build_types(f, [int])
  3732. assert ("RPython cannot unify instances with no common base class"
  3733. in exc.value.msg)
  3734. def test_unionerror_iters(self):
  3735. def f(x):
  3736. d = { 1 : "a", 2 : "b" }
  3737. if x < 10:
  3738. return d.iterkeys()
  3739. else:
  3740. return d.itervalues()
  3741. a = self.RPythonAnnotator()
  3742. with py.test.raises(UnionError) as exc:
  3743. a.build_types(f, [int])
  3744. assert ("RPython cannot unify incompatible iterator variants" in
  3745. exc.value.msg)
  3746. def test_variable_getattr(self):
  3747. class A(object): pass
  3748. def f(y):
  3749. a = A()
  3750. return getattr(a, y)
  3751. a = self.RPythonAnnotator()
  3752. with py.test.raises(AnnotatorError) as exc:
  3753. a.build_types(f, [str])
  3754. assert ("variable argument to getattr" in exc.value.msg)
  3755. def test_bad_call(self):
  3756. def f(x):
  3757. return x()
  3758. a = self.RPythonAnnotator()
  3759. with py.test.raises(AnnotatorError) as exc:
  3760. a.build_types(f, [str])
  3761. assert ("Cannot prove that the object is callable" in exc.value.msg)
  3762. def test_UnionError_on_PBC(self):
  3763. l = ['a', 1]
  3764. def f(x):
  3765. l.append(x)
  3766. a = self.RPythonAnnotator()
  3767. with py.test.raises(UnionError) as excinfo:
  3768. a.build_types(f, [int])
  3769. assert 'Happened at file' in excinfo.value.source
  3770. assert 'Known variable annotations:' in excinfo.value.source
  3771. def test_str_format_error(self):
  3772. def f(s, x):
  3773. return s.format(x)
  3774. a = self.RPythonAnnotator()
  3775. with py.test.raises(AnnotatorError) as exc:
  3776. a.build_types(f, [str, str])
  3777. assert ("format() is not RPython" in exc.value.msg)
  3778. def test_prebuilt_ordered_dict(self):
  3779. d = OrderedDict([("aa", 1)])
  3780. def f():
  3781. return d
  3782. a = self.RPythonAnnotator()
  3783. assert isinstance(a.build_types(f, []), annmodel.SomeOrderedDict)
  3784. def test_enumerate_none(self):
  3785. # enumerate(None) can occur as an intermediate step during a full
  3786. # annotation, because the None will be generalized later to
  3787. # None-or-list for example
  3788. def f(flag):
  3789. if flag:
  3790. x = None
  3791. else:
  3792. x = [42]
  3793. return enumerate(x).next()
  3794. a = self.RPythonAnnotator()
  3795. s = a.build_types(f, [int])
  3796. assert isinstance(s, annmodel.SomeTuple)
  3797. assert s.items[1].const == 42
  3798. def test_unpack_none_gets_a_blocked_block(self):
  3799. def f(x):
  3800. a, b = x
  3801. a = self.RPythonAnnotator()
  3802. py.test.raises(AnnotatorError,
  3803. a.build_types, f, [annmodel.s_None])
  3804. def test_class___name__(self):
  3805. class Abc(object):
  3806. pass
  3807. def f():
  3808. return Abc().__class__.__name__
  3809. a = self.RPythonAnnotator()
  3810. s = a.build_types(f, [])
  3811. assert isinstance(s, annmodel.SomeString)
  3812. def test_isinstance_str_1(self):
  3813. def g():
  3814. pass
  3815. def f(n):
  3816. if n > 5:
  3817. s = "foo"
  3818. else:
  3819. s = None
  3820. g()
  3821. return isinstance(s, str)
  3822. a = self.RPythonAnnotator()
  3823. s = a.build_types(f, [int])
  3824. assert isinstance(s, annmodel.SomeBool)
  3825. assert not s.is_constant()
  3826. def test_isinstance_str_2(self):
  3827. def g():
  3828. pass
  3829. def f(n):
  3830. if n > 5:
  3831. s = "foo"
  3832. else:
  3833. s = None
  3834. g()
  3835. if isinstance(s, str):
  3836. return s
  3837. return ""
  3838. a = self.RPythonAnnotator()
  3839. s = a.build_types(f, [int])
  3840. assert isinstance(s, annmodel.SomeString)
  3841. assert not s.can_be_none()
  3842. def test_property_getter(self):
  3843. class O1(object):
  3844. def __init__(self, x):
  3845. self._x = x
  3846. @property
  3847. def x(self):
  3848. return self._x
  3849. def f(n):
  3850. o = O1(n)
  3851. return o.x + getattr(o, 'x')
  3852. a = self.RPythonAnnotator()
  3853. s = a.build_types(f, [int])
  3854. assert isinstance(s, annmodel.SomeInteger)
  3855. op = list(graphof(a, f).iterblocks())[0].operations
  3856. i = 0
  3857. c = 0
  3858. while i < len(op):
  3859. if op[i].opname == 'getattr':
  3860. c += 1
  3861. assert op[i].args[1].value == 'x__getter__'
  3862. i += 1
  3863. assert i < len(op) and op[i].opname == 'simple_call' and \
  3864. op[i].args[0] == op[i - 1].result
  3865. i += 1
  3866. assert c == 2
  3867. def test_property_setter(self):
  3868. class O2(object):
  3869. def __init__(self):
  3870. self._x = 0
  3871. def set_x(self, v):
  3872. self._x = v
  3873. x = property(fset=set_x)
  3874. def f(n):
  3875. o = O2()
  3876. o.x = n
  3877. setattr(o, 'x', n)
  3878. a = self.RPythonAnnotator()
  3879. s = a.build_types(f, [int])
  3880. op = list(graphof(a, f).iterblocks())[0].operations
  3881. i = 0
  3882. c = 0
  3883. while i < len(op):
  3884. if op[i].opname == 'getattr':
  3885. c += 1
  3886. assert op[i].args[1].value == 'x__setter__'
  3887. i += 1
  3888. assert i < len(op) and op[i].opname == 'simple_call' and \
  3889. op[i].args[0] == op[i - 1].result and len(op[i].args) == 2
  3890. i += 1
  3891. assert c == 2
  3892. def test_property_unionerr(self):
  3893. class O1(object):
  3894. def __init__(self, x):
  3895. self._x = x
  3896. @property
  3897. def x(self):
  3898. return self._x
  3899. class O2(O1):
  3900. def set_x(self, v):
  3901. self._x = v
  3902. x = property(fset=set_x)
  3903. def f1(n):
  3904. o = O2(n)
  3905. return o.x
  3906. def f2(n):
  3907. o = O2(n)
  3908. o.x = 20
  3909. a = self.RPythonAnnotator()
  3910. with py.test.raises(UnionError) as exc:
  3911. a.build_types(f1, [int])
  3912. a = self.RPythonAnnotator()
  3913. with py.test.raises(UnionError) as exc:
  3914. a.build_types(f2, [int])
  3915. @py.test.mark.xfail(reason="May produce garbage annotations instead of "
  3916. "raising AnnotatorError, depending on annotation order")
  3917. def test_property_union_2(self):
  3918. class Base(object):
  3919. pass
  3920. class A(Base):
  3921. def __init__(self):
  3922. pass
  3923. @property
  3924. def x(self):
  3925. return 42
  3926. class B(Base):
  3927. def __init__(self, x):
  3928. self.x = x
  3929. def f(n):
  3930. if n < 0:
  3931. obj = A()
  3932. else:
  3933. obj = B(n)
  3934. return obj.x
  3935. a = self.RPythonAnnotator()
  3936. # Ideally, this should translate to something sensible,
  3937. # but for now, AnnotatorError is better than silently mistranslating.
  3938. with py.test.raises(AnnotatorError):
  3939. a.build_types(f, [int])
  3940. @py.test.mark.xfail(reason="May produce garbage annotations instead of "
  3941. "raising AnnotatorError, depending on annotation order")
  3942. def test_property_union_3(self):
  3943. class Base(object):
  3944. pass
  3945. class A(Base):
  3946. @property
  3947. def x(self):
  3948. return 42
  3949. class B(Base):
  3950. x = 43
  3951. def f(n):
  3952. if n < 0:
  3953. obj = A()
  3954. else:
  3955. obj = B()
  3956. return obj.x
  3957. a = self.RPythonAnnotator()
  3958. with py.test.raises(AnnotatorError):
  3959. a.build_types(f, [int])
  3960. def test_dict_can_be_none_ordering_issue(self):
  3961. def g(d):
  3962. return 42 in d
  3963. def f(n):
  3964. g(None)
  3965. g({})
  3966. a = self.RPythonAnnotator()
  3967. a.build_types(f, [int])
  3968. def test_numbers_dont_have_len(self):
  3969. def f(x):
  3970. return len(x)
  3971. a = self.RPythonAnnotator()
  3972. with py.test.raises(AnnotatorError):
  3973. a.build_types(f, [int])
  3974. with py.test.raises(AnnotatorError):
  3975. a.build_types(f, [float])
  3976. def test_numbers_dont_contain(self):
  3977. def f(x):
  3978. return 1 in x
  3979. a = self.RPythonAnnotator()
  3980. with py.test.raises(AnnotatorError):
  3981. a.build_types(f, [int])
  3982. with py.test.raises(AnnotatorError):
  3983. a.build_types(f, [float])
  3984. def test_Ellipsis_not_rpython(self):
  3985. def f():
  3986. return Ellipsis
  3987. a = self.RPythonAnnotator()
  3988. e = py.test.raises(Exception, a.build_types, f, [])
  3989. assert str(e.value) == "Don't know how to represent Ellipsis"
  3990. def test_must_be_light_finalizer(self):
  3991. from rpython.rlib import rgc
  3992. @rgc.must_be_light_finalizer
  3993. class A(object):
  3994. pass
  3995. class B(A):
  3996. def __del__(self):
  3997. pass
  3998. class C(A):
  3999. @rgc.must_be_light_finalizer
  4000. def __del__(self):
  4001. pass
  4002. class D(object):
  4003. def __del__(self):
  4004. pass
  4005. def fb():
  4006. B()
  4007. def fc():
  4008. C()
  4009. def fd():
  4010. D()
  4011. a = self.RPythonAnnotator()
  4012. a.build_types(fc, [])
  4013. a.build_types(fd, [])
  4014. py.test.raises(AnnotatorError, a.build_types, fb, [])
  4015. def test_annotate_generator_with_unreachable_yields(self):
  4016. def f(n):
  4017. if n < 0:
  4018. yield 42
  4019. yield n
  4020. yield n
  4021. def main(n):
  4022. for x in f(abs(n)):
  4023. pass
  4024. #
  4025. a = self.RPythonAnnotator()
  4026. a.build_types(main, [int])
  4027. def test_string_mod_nonconstant(self):
  4028. def f(x):
  4029. return x % 5
  4030. a = self.RPythonAnnotator()
  4031. e = py.test.raises(AnnotatorError, a.build_types, f, [str])
  4032. assert ('string formatting requires a constant string/unicode'
  4033. in str(e.value))
  4034. def g(n):
  4035. return [0, 1, 2, n]
  4036. def f_calls_g(n):
  4037. total = 0
  4038. lst = g(n)
  4039. i = 0
  4040. while i < len(lst):
  4041. total += i
  4042. i += 1
  4043. return total
  4044. constant_unsigned_five = r_uint(5)
  4045. class Freezing:
  4046. def _freeze_(self):
  4047. return True