PageRenderTime 55ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/tools/logilab/astng/test/unittest_inference.py

https://gitlab.com/holtscomm/gae-purchase-order-system
Python | 1145 lines | 1117 code | 9 blank | 19 comment | 4 complexity | bbfd7267bb5f80bf0df776abdbebf609 MD5 | raw file
  1. # copyright 2003-2010 Sylvain Thenault, all rights reserved.
  2. # contact mailto:thenault@gmail.com
  3. #
  4. # This file is part of logilab-astng.
  5. #
  6. # logilab-astng is free software: you can redistribute it and/or modify it
  7. # under the terms of the GNU Lesser General Public License as published by the
  8. # Free Software Foundation, either version 2.1 of the License, or (at your
  9. # option) any later version.
  10. #
  11. # logilab-astng is distributed in the hope that it will be useful, but
  12. # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
  14. # for more details.
  15. #
  16. # You should have received a copy of the GNU Lesser General Public License along
  17. # with logilab-astng. If not, see <http://www.gnu.org/licenses/>.
  18. """tests for the astng inference capabilities
  19. """
  20. from os.path import join, dirname, abspath
  21. import sys
  22. from StringIO import StringIO
  23. from logilab.common.testlib import TestCase, unittest_main
  24. from logilab.astng import InferenceError, builder, nodes
  25. from logilab.astng.inference import infer_end as inference_infer_end
  26. from logilab.astng.bases import YES, Instance, BoundMethod, UnboundMethod,\
  27. path_wrapper, BUILTINS_NAME
  28. def get_name_node(start_from, name, index=0):
  29. return [n for n in start_from.nodes_of_class(nodes.Name) if n.name == name][index]
  30. def get_node_of_class(start_from, klass):
  31. return start_from.nodes_of_class(klass).next()
  32. builder = builder.ASTNGBuilder()
  33. class InferenceUtilsTC(TestCase):
  34. def test_path_wrapper(self):
  35. def infer_default(self, *args):
  36. raise InferenceError
  37. infer_default = path_wrapper(infer_default)
  38. infer_end = path_wrapper(inference_infer_end)
  39. self.failUnlessRaises(InferenceError,
  40. infer_default(1).next)
  41. self.failUnlessEqual(infer_end(1).next(), 1)
  42. if sys.version_info < (3, 0):
  43. EXC_MODULE = 'exceptions'
  44. else:
  45. EXC_MODULE = BUILTINS_NAME
  46. class InferenceTC(TestCase):
  47. CODE = '''
  48. class C(object):
  49. "new style"
  50. attr = 4
  51. def meth1(self, arg1, optarg=0):
  52. var = object()
  53. print ("yo", arg1, optarg)
  54. self.iattr = "hop"
  55. return var
  56. def meth2(self):
  57. self.meth1(*self.meth3)
  58. def meth3(self, d=attr):
  59. b = self.attr
  60. c = self.iattr
  61. return b, c
  62. ex = Exception("msg")
  63. v = C().meth1(1)
  64. m_unbound = C.meth1
  65. m_bound = C().meth1
  66. a, b, c = ex, 1, "bonjour"
  67. [d, e, f] = [ex, 1.0, ("bonjour", v)]
  68. g, h = f
  69. i, (j, k) = "glup", f
  70. a, b= b, a # Gasp !
  71. '''
  72. astng = builder.string_build(CODE, __name__, __file__)
  73. def test_module_inference(self):
  74. infered = self.astng.infer()
  75. obj = infered.next()
  76. self.failUnlessEqual(obj.name, __name__)
  77. self.failUnlessEqual(obj.root().name, __name__)
  78. self.failUnlessRaises(StopIteration, infered.next)
  79. def test_class_inference(self):
  80. infered = self.astng['C'].infer()
  81. obj = infered.next()
  82. self.failUnlessEqual(obj.name, 'C')
  83. self.failUnlessEqual(obj.root().name, __name__)
  84. self.failUnlessRaises(StopIteration, infered.next)
  85. def test_function_inference(self):
  86. infered = self.astng['C']['meth1'].infer()
  87. obj = infered.next()
  88. self.failUnlessEqual(obj.name, 'meth1')
  89. self.failUnlessEqual(obj.root().name, __name__)
  90. self.failUnlessRaises(StopIteration, infered.next)
  91. def test_builtin_name_inference(self):
  92. infered = self.astng['C']['meth1']['var'].infer()
  93. var = infered.next()
  94. self.failUnlessEqual(var.name, 'object')
  95. self.failUnlessEqual(var.root().name, BUILTINS_NAME)
  96. self.failUnlessRaises(StopIteration, infered.next)
  97. def test_tupleassign_name_inference(self):
  98. infered = self.astng['a'].infer()
  99. exc = infered.next()
  100. self.assertIsInstance(exc, Instance)
  101. self.failUnlessEqual(exc.name, 'Exception')
  102. self.failUnlessEqual(exc.root().name, EXC_MODULE)
  103. self.failUnlessRaises(StopIteration, infered.next)
  104. infered = self.astng['b'].infer()
  105. const = infered.next()
  106. self.assertIsInstance(const, nodes.Const)
  107. self.failUnlessEqual(const.value, 1)
  108. self.failUnlessRaises(StopIteration, infered.next)
  109. infered = self.astng['c'].infer()
  110. const = infered.next()
  111. self.assertIsInstance(const, nodes.Const)
  112. self.failUnlessEqual(const.value, "bonjour")
  113. self.failUnlessRaises(StopIteration, infered.next)
  114. def test_listassign_name_inference(self):
  115. infered = self.astng['d'].infer()
  116. exc = infered.next()
  117. self.assertIsInstance(exc, Instance)
  118. self.failUnlessEqual(exc.name, 'Exception')
  119. self.failUnlessEqual(exc.root().name, EXC_MODULE)
  120. self.failUnlessRaises(StopIteration, infered.next)
  121. infered = self.astng['e'].infer()
  122. const = infered.next()
  123. self.assertIsInstance(const, nodes.Const)
  124. self.failUnlessEqual(const.value, 1.0)
  125. self.failUnlessRaises(StopIteration, infered.next)
  126. infered = self.astng['f'].infer()
  127. const = infered.next()
  128. self.assertIsInstance(const, nodes.Tuple)
  129. self.failUnlessRaises(StopIteration, infered.next)
  130. def test_advanced_tupleassign_name_inference1(self):
  131. infered = self.astng['g'].infer()
  132. const = infered.next()
  133. self.assertIsInstance(const, nodes.Const)
  134. self.failUnlessEqual(const.value, "bonjour")
  135. self.failUnlessRaises(StopIteration, infered.next)
  136. infered = self.astng['h'].infer()
  137. var = infered.next()
  138. self.failUnlessEqual(var.name, 'object')
  139. self.failUnlessEqual(var.root().name, BUILTINS_NAME)
  140. self.failUnlessRaises(StopIteration, infered.next)
  141. def test_advanced_tupleassign_name_inference2(self):
  142. infered = self.astng['i'].infer()
  143. const = infered.next()
  144. self.assertIsInstance(const, nodes.Const)
  145. self.failUnlessEqual(const.value, u"glup")
  146. self.failUnlessRaises(StopIteration, infered.next)
  147. infered = self.astng['j'].infer()
  148. const = infered.next()
  149. self.assertIsInstance(const, nodes.Const)
  150. self.failUnlessEqual(const.value, "bonjour")
  151. self.failUnlessRaises(StopIteration, infered.next)
  152. infered = self.astng['k'].infer()
  153. var = infered.next()
  154. self.failUnlessEqual(var.name, 'object')
  155. self.failUnlessEqual(var.root().name, BUILTINS_NAME)
  156. self.failUnlessRaises(StopIteration, infered.next)
  157. def test_swap_assign_inference(self):
  158. infered = self.astng.locals['a'][1].infer()
  159. const = infered.next()
  160. self.assertIsInstance(const, nodes.Const)
  161. self.failUnlessEqual(const.value, 1)
  162. self.failUnlessRaises(StopIteration, infered.next)
  163. infered = self.astng.locals['b'][1].infer()
  164. exc = infered.next()
  165. self.assertIsInstance(exc, Instance)
  166. self.failUnlessEqual(exc.name, 'Exception')
  167. self.failUnlessEqual(exc.root().name, EXC_MODULE)
  168. self.failUnlessRaises(StopIteration, infered.next)
  169. def test_getattr_inference1(self):
  170. infered = self.astng['ex'].infer()
  171. exc = infered.next()
  172. self.assertIsInstance(exc, Instance)
  173. self.failUnlessEqual(exc.name, 'Exception')
  174. self.failUnlessEqual(exc.root().name, EXC_MODULE)
  175. self.failUnlessRaises(StopIteration, infered.next)
  176. def test_getattr_inference2(self):
  177. infered = get_node_of_class(self.astng['C']['meth2'], nodes.Getattr).infer()
  178. meth1 = infered.next()
  179. self.failUnlessEqual(meth1.name, 'meth1')
  180. self.failUnlessEqual(meth1.root().name, __name__)
  181. self.failUnlessRaises(StopIteration, infered.next)
  182. def test_getattr_inference3(self):
  183. infered = self.astng['C']['meth3']['b'].infer()
  184. const = infered.next()
  185. self.assertIsInstance(const, nodes.Const)
  186. self.failUnlessEqual(const.value, 4)
  187. self.failUnlessRaises(StopIteration, infered.next)
  188. def test_getattr_inference4(self):
  189. infered = self.astng['C']['meth3']['c'].infer()
  190. const = infered.next()
  191. self.assertIsInstance(const, nodes.Const)
  192. self.failUnlessEqual(const.value, "hop")
  193. self.failUnlessRaises(StopIteration, infered.next)
  194. def test_callfunc_inference(self):
  195. infered = self.astng['v'].infer()
  196. meth1 = infered.next()
  197. self.assertIsInstance(meth1, Instance)
  198. self.failUnlessEqual(meth1.name, 'object')
  199. self.failUnlessEqual(meth1.root().name, BUILTINS_NAME)
  200. self.failUnlessRaises(StopIteration, infered.next)
  201. def test_unbound_method_inference(self):
  202. infered = self.astng['m_unbound'].infer()
  203. meth1 = infered.next()
  204. self.assertIsInstance(meth1, UnboundMethod)
  205. self.failUnlessEqual(meth1.name, 'meth1')
  206. self.failUnlessEqual(meth1.parent.frame().name, 'C')
  207. self.failUnlessRaises(StopIteration, infered.next)
  208. def test_bound_method_inference(self):
  209. infered = self.astng['m_bound'].infer()
  210. meth1 = infered.next()
  211. self.assertIsInstance(meth1, BoundMethod)
  212. self.failUnlessEqual(meth1.name, 'meth1')
  213. self.failUnlessEqual(meth1.parent.frame().name, 'C')
  214. self.failUnlessRaises(StopIteration, infered.next)
  215. def test_args_default_inference1(self):
  216. optarg = get_name_node(self.astng['C']['meth1'], 'optarg')
  217. infered = optarg.infer()
  218. obj1 = infered.next()
  219. self.assertIsInstance(obj1, nodes.Const)
  220. self.failUnlessEqual(obj1.value, 0)
  221. obj1 = infered.next()
  222. self.assertIs(obj1, YES, obj1)
  223. self.failUnlessRaises(StopIteration, infered.next)
  224. def test_args_default_inference2(self):
  225. infered = self.astng['C']['meth3'].ilookup('d')
  226. obj1 = infered.next()
  227. self.assertIsInstance(obj1, nodes.Const)
  228. self.failUnlessEqual(obj1.value, 4)
  229. obj1 = infered.next()
  230. self.assertIs(obj1, YES, obj1)
  231. self.failUnlessRaises(StopIteration, infered.next)
  232. def test_inference_restrictions(self):
  233. infered = get_name_node(self.astng['C']['meth1'], 'arg1').infer()
  234. obj1 = infered.next()
  235. self.assertIs(obj1, YES, obj1)
  236. self.failUnlessRaises(StopIteration, infered.next)
  237. def test_ancestors_inference(self):
  238. code = '''
  239. class A:
  240. pass
  241. class A(A):
  242. pass
  243. '''
  244. astng = builder.string_build(code, __name__, __file__)
  245. a1 = astng.locals['A'][0]
  246. a2 = astng.locals['A'][1]
  247. a2_ancestors = list(a2.ancestors())
  248. self.failUnlessEqual(len(a2_ancestors), 1)
  249. self.failUnless(a2_ancestors[0] is a1)
  250. def test_ancestors_inference2(self):
  251. code = '''
  252. class A:
  253. pass
  254. class B(A): pass
  255. class A(B):
  256. pass
  257. '''
  258. astng = builder.string_build(code, __name__, __file__)
  259. a1 = astng.locals['A'][0]
  260. a2 = astng.locals['A'][1]
  261. a2_ancestors = list(a2.ancestors())
  262. self.failUnlessEqual(len(a2_ancestors), 2)
  263. self.failUnless(a2_ancestors[0] is astng.locals['B'][0])
  264. self.failUnless(a2_ancestors[1] is a1, a2_ancestors[1])
  265. def test_f_arg_f(self):
  266. code = '''
  267. def f(f=1):
  268. return f
  269. a = f()
  270. '''
  271. astng = builder.string_build(code, __name__, __file__)
  272. a = astng['a']
  273. a_infered = a.infered()
  274. self.failUnlessEqual(a_infered[0].value, 1)
  275. self.assertEqual(len(a_infered), 1)
  276. def test_exc_ancestors(self):
  277. code = '''
  278. def f():
  279. raise NotImplementedError
  280. '''
  281. astng = builder.string_build(code, __name__, __file__)
  282. error = astng.nodes_of_class(nodes.Name).next()
  283. nie = error.infered()[0]
  284. self.assertIsInstance(nie, nodes.Class)
  285. nie_ancestors = [c.name for c in nie.ancestors()]
  286. if sys.version_info < (3, 0):
  287. self.failUnlessEqual(nie_ancestors, ['RuntimeError', 'StandardError', 'Exception', 'BaseException', 'object'])
  288. else:
  289. self.failUnlessEqual(nie_ancestors, ['RuntimeError', 'Exception', 'BaseException', 'object'])
  290. def test_except_inference(self):
  291. code = '''
  292. try:
  293. print (hop)
  294. except NameError, ex:
  295. ex1 = ex
  296. except Exception, ex:
  297. ex2 = ex
  298. raise
  299. '''
  300. if sys.version_info >= (3, 0):
  301. code = code.replace(', ex:', ' as ex:')
  302. astng = builder.string_build(code, __name__, __file__)
  303. ex1 = astng['ex1']
  304. ex1_infer = ex1.infer()
  305. ex1 = ex1_infer.next()
  306. self.assertIsInstance(ex1, Instance)
  307. self.failUnlessEqual(ex1.name, 'NameError')
  308. self.failUnlessRaises(StopIteration, ex1_infer.next)
  309. ex2 = astng['ex2']
  310. ex2_infer = ex2.infer()
  311. ex2 = ex2_infer.next()
  312. self.assertIsInstance(ex2, Instance)
  313. self.failUnlessEqual(ex2.name, 'Exception')
  314. self.failUnlessRaises(StopIteration, ex2_infer.next)
  315. def test_del1(self):
  316. code = '''
  317. del undefined_attr
  318. '''
  319. delete = builder.string_build(code, __name__, __file__).body[0]
  320. self.failUnlessRaises(InferenceError, delete.infer)
  321. def test_del2(self):
  322. code = '''
  323. a = 1
  324. b = a
  325. del a
  326. c = a
  327. a = 2
  328. d = a
  329. '''
  330. astng = builder.string_build(code, __name__, __file__)
  331. n = astng['b']
  332. n_infer = n.infer()
  333. infered = n_infer.next()
  334. self.assertIsInstance(infered, nodes.Const)
  335. self.failUnlessEqual(infered.value, 1)
  336. self.failUnlessRaises(StopIteration, n_infer.next)
  337. n = astng['c']
  338. n_infer = n.infer()
  339. self.failUnlessRaises(InferenceError, n_infer.next)
  340. n = astng['d']
  341. n_infer = n.infer()
  342. infered = n_infer.next()
  343. self.assertIsInstance(infered, nodes.Const)
  344. self.failUnlessEqual(infered.value, 2)
  345. self.failUnlessRaises(StopIteration, n_infer.next)
  346. def test_builtin_types(self):
  347. code = '''
  348. l = [1]
  349. t = (2,)
  350. d = {}
  351. s = ''
  352. s2 = '_'
  353. '''
  354. astng = builder.string_build(code, __name__, __file__)
  355. n = astng['l']
  356. infered = n.infer().next()
  357. self.assertIsInstance(infered, nodes.List)
  358. self.assertIsInstance(infered, Instance)
  359. self.failUnlessEqual(infered.getitem(0).value, 1)
  360. self.assertIsInstance(infered._proxied, nodes.Class)
  361. self.failUnlessEqual(infered._proxied.name, 'list')
  362. self.failUnless('append' in infered._proxied.locals)
  363. n = astng['t']
  364. infered = n.infer().next()
  365. self.assertIsInstance(infered, nodes.Tuple)
  366. self.assertIsInstance(infered, Instance)
  367. self.failUnlessEqual(infered.getitem(0).value, 2)
  368. self.assertIsInstance(infered._proxied, nodes.Class)
  369. self.failUnlessEqual(infered._proxied.name, 'tuple')
  370. n = astng['d']
  371. infered = n.infer().next()
  372. self.assertIsInstance(infered, nodes.Dict)
  373. self.assertIsInstance(infered, Instance)
  374. self.assertIsInstance(infered._proxied, nodes.Class)
  375. self.failUnlessEqual(infered._proxied.name, 'dict')
  376. self.failUnless('get' in infered._proxied.locals)
  377. n = astng['s']
  378. infered = n.infer().next()
  379. self.assertIsInstance(infered, nodes.Const)
  380. self.assertIsInstance(infered, Instance)
  381. self.failUnlessEqual(infered.name, 'str')
  382. self.failUnless('lower' in infered._proxied.locals)
  383. n = astng['s2']
  384. infered = n.infer().next()
  385. self.failUnlessEqual(infered.getitem(0).value, '_')
  386. def test_unicode_type(self):
  387. if sys.version_info >= (3, 0):
  388. self.skipTest('unicode removed on py >= 3.0')
  389. code = '''u = u""'''
  390. astng = builder.string_build(code, __name__, __file__)
  391. n = astng['u']
  392. infered = n.infer().next()
  393. self.assertIsInstance(infered, nodes.Const)
  394. self.assertIsInstance(infered, Instance)
  395. self.failUnlessEqual(infered.name, 'unicode')
  396. self.failUnless('lower' in infered._proxied.locals)
  397. def test_descriptor_are_callable(self):
  398. code = '''
  399. class A:
  400. statm = staticmethod(open)
  401. clsm = classmethod('whatever')
  402. '''
  403. astng = builder.string_build(code, __name__, __file__)
  404. statm = astng['A'].igetattr('statm').next()
  405. self.failUnless(statm.callable())
  406. clsm = astng['A'].igetattr('clsm').next()
  407. self.failUnless(clsm.callable())
  408. def test_bt_ancestor_crash(self):
  409. code = '''
  410. class Warning(Warning):
  411. pass
  412. '''
  413. astng = builder.string_build(code, __name__, __file__)
  414. w = astng['Warning']
  415. ancestors = w.ancestors()
  416. ancestor = ancestors.next()
  417. self.failUnlessEqual(ancestor.name, 'Warning')
  418. self.failUnlessEqual(ancestor.root().name, EXC_MODULE)
  419. ancestor = ancestors.next()
  420. self.failUnlessEqual(ancestor.name, 'Exception')
  421. self.failUnlessEqual(ancestor.root().name, EXC_MODULE)
  422. ancestor = ancestors.next()
  423. self.failUnlessEqual(ancestor.name, 'BaseException')
  424. self.failUnlessEqual(ancestor.root().name, EXC_MODULE)
  425. ancestor = ancestors.next()
  426. self.failUnlessEqual(ancestor.name, 'object')
  427. self.failUnlessEqual(ancestor.root().name, BUILTINS_NAME)
  428. self.failUnlessRaises(StopIteration, ancestors.next)
  429. def test_qqch(self):
  430. code = '''
  431. from logilab.common.modutils import load_module_from_name
  432. xxx = load_module_from_name('__pkginfo__')
  433. '''
  434. astng = builder.string_build(code, __name__, __file__)
  435. xxx = astng['xxx']
  436. self.assertSetEqual(set(n.__class__ for n in xxx.infered()),
  437. set([nodes.Const, YES.__class__]))
  438. def test_method_argument(self):
  439. code = '''
  440. class ErudiEntitySchema:
  441. """a entity has a type, a set of subject and or object relations"""
  442. def __init__(self, e_type, **kwargs):
  443. kwargs['e_type'] = e_type.capitalize().encode()
  444. def meth(self, e_type, *args, **kwargs):
  445. kwargs['e_type'] = e_type.capitalize().encode()
  446. print(args)
  447. '''
  448. astng = builder.string_build(code, __name__, __file__)
  449. arg = get_name_node(astng['ErudiEntitySchema']['__init__'], 'e_type')
  450. self.failUnlessEqual([n.__class__ for n in arg.infer()],
  451. [YES.__class__])
  452. arg = get_name_node(astng['ErudiEntitySchema']['__init__'], 'kwargs')
  453. self.failUnlessEqual([n.__class__ for n in arg.infer()],
  454. [nodes.Dict])
  455. arg = get_name_node(astng['ErudiEntitySchema']['meth'], 'e_type')
  456. self.failUnlessEqual([n.__class__ for n in arg.infer()],
  457. [YES.__class__])
  458. arg = get_name_node(astng['ErudiEntitySchema']['meth'], 'args')
  459. self.failUnlessEqual([n.__class__ for n in arg.infer()],
  460. [nodes.Tuple])
  461. arg = get_name_node(astng['ErudiEntitySchema']['meth'], 'kwargs')
  462. self.failUnlessEqual([n.__class__ for n in arg.infer()],
  463. [nodes.Dict])
  464. def test_tuple_then_list(self):
  465. code = '''
  466. def test_view(rql, vid, tags=()):
  467. tags = list(tags)
  468. tags.append(vid)
  469. '''
  470. astng = builder.string_build(code, __name__, __file__)
  471. name = get_name_node(astng['test_view'], 'tags', -1)
  472. it = name.infer()
  473. tags = it.next()
  474. self.failUnlessEqual(tags.__class__, Instance)
  475. self.failUnlessEqual(tags._proxied.name, 'list')
  476. self.failUnlessRaises(StopIteration, it.next)
  477. def test_mulassign_inference(self):
  478. code = '''
  479. def first_word(line):
  480. """Return the first word of a line"""
  481. return line.split()[0]
  482. def last_word(line):
  483. """Return last word of a line"""
  484. return line.split()[-1]
  485. def process_line(word_pos):
  486. """Silly function: returns (ok, callable) based on argument.
  487. For test purpose only.
  488. """
  489. if word_pos > 0:
  490. return (True, first_word)
  491. elif word_pos < 0:
  492. return (True, last_word)
  493. else:
  494. return (False, None)
  495. if __name__ == '__main__':
  496. line_number = 0
  497. for a_line in file('test_callable.py'):
  498. tupletest = process_line(line_number)
  499. (ok, fct) = process_line(line_number)
  500. if ok:
  501. fct(a_line)
  502. '''
  503. astng = builder.string_build(code, __name__, __file__)
  504. self.failUnlessEqual(len(list(astng['process_line'].infer_call_result(
  505. None))), 3)
  506. self.failUnlessEqual(len(list(astng['tupletest'].infer())), 3)
  507. values = ['Function(first_word)', 'Function(last_word)', 'Const(NoneType)']
  508. self.failUnlessEqual([str(infered)
  509. for infered in astng['fct'].infer()], values)
  510. def test_float_complex_ambiguity(self):
  511. code = '''
  512. def no_conjugate_member(magic_flag):
  513. """should not raise E1101 on something.conjugate"""
  514. if magic_flag:
  515. something = 1.0
  516. else:
  517. something = 1.0j
  518. if isinstance(something, float):
  519. return something
  520. return something.conjugate()
  521. '''
  522. astng = builder.string_build(code, __name__, __file__)
  523. self.failUnlessEqual([i.value for i in
  524. astng['no_conjugate_member'].ilookup('something')], [1.0, 1.0j])
  525. self.failUnlessEqual([i.value for i in
  526. get_name_node(astng, 'something', -1).infer()], [1.0, 1.0j])
  527. def test_lookup_cond_branches(self):
  528. code = '''
  529. def no_conjugate_member(magic_flag):
  530. """should not raise E1101 on something.conjugate"""
  531. something = 1.0
  532. if magic_flag:
  533. something = 1.0j
  534. return something.conjugate()
  535. '''
  536. astng = builder.string_build(code, __name__, __file__)
  537. self.failUnlessEqual([i.value for i in
  538. get_name_node(astng, 'something', -1).infer()], [1.0, 1.0j])
  539. def test_simple_subscript(self):
  540. code = '''
  541. a = [1, 2, 3][0]
  542. b = (1, 2, 3)[1]
  543. c = (1, 2, 3)[-1]
  544. d = a + b + c
  545. print (d)
  546. '''
  547. astng = builder.string_build(code, __name__, __file__)
  548. self.failUnlessEqual([i.value for i in
  549. get_name_node(astng, 'a', -1).infer()], [1])
  550. self.failUnlessEqual([i.value for i in
  551. get_name_node(astng, 'b', -1).infer()], [2])
  552. self.failUnlessEqual([i.value for i in
  553. get_name_node(astng, 'c', -1).infer()], [3])
  554. self.failUnlessEqual([i.value for i in
  555. get_name_node(astng, 'd', -1).infer()], [6])
  556. #def test_simple_tuple(self):
  557. #"""test case for a simple tuple value"""
  558. ## XXX tuple inference is not implemented ...
  559. #code = """
  560. #a = (1,)
  561. #b = (22,)
  562. #some = a + b
  563. #"""
  564. #astng = builder.string_build(code, __name__, __file__)
  565. #self.failUnlessEqual(astng['some'].infer.next().as_string(), "(1, 22)")
  566. def test_simple_for(self):
  567. code = '''
  568. for a in [1, 2, 3]:
  569. print (a)
  570. for b,c in [(1,2), (3,4)]:
  571. print (b)
  572. print (c)
  573. print ([(d,e) for e,d in ([1,2], [3,4])])
  574. '''
  575. astng = builder.string_build(code, __name__, __file__)
  576. self.failUnlessEqual([i.value for i in
  577. get_name_node(astng, 'a', -1).infer()], [1, 2, 3])
  578. self.failUnlessEqual([i.value for i in
  579. get_name_node(astng, 'b', -1).infer()], [1, 3])
  580. self.failUnlessEqual([i.value for i in
  581. get_name_node(astng, 'c', -1).infer()], [2, 4])
  582. self.failUnlessEqual([i.value for i in
  583. get_name_node(astng, 'd', -1).infer()], [2, 4])
  584. self.failUnlessEqual([i.value for i in
  585. get_name_node(astng, 'e', -1).infer()], [1, 3])
  586. def test_simple_for_genexpr(self):
  587. code = '''
  588. print ((d,e) for e,d in ([1,2], [3,4]))
  589. '''
  590. astng = builder.string_build(code, __name__, __file__)
  591. self.failUnlessEqual([i.value for i in
  592. get_name_node(astng, 'd', -1).infer()], [2, 4])
  593. self.failUnlessEqual([i.value for i in
  594. get_name_node(astng, 'e', -1).infer()], [1, 3])
  595. def test_builtin_help(self):
  596. code = '''
  597. help()
  598. '''
  599. # XXX failing since __builtin__.help assignment has
  600. # been moved into a function...
  601. astng = builder.string_build(code, __name__, __file__)
  602. node = get_name_node(astng, 'help', -1)
  603. infered = list(node.infer())
  604. self.failUnlessEqual(len(infered), 1, infered)
  605. self.assertIsInstance(infered[0], Instance)
  606. self.failUnlessEqual(str(infered[0]),
  607. 'Instance of site._Helper')
  608. def test_builtin_open(self):
  609. code = '''
  610. open("toto.txt")
  611. '''
  612. astng = builder.string_build(code, __name__, __file__)
  613. node = get_name_node(astng, 'open', -1)
  614. infered = list(node.infer())
  615. self.failUnlessEqual(len(infered), 1)
  616. self.assertIsInstance(infered[0], nodes.Function)
  617. self.failUnlessEqual(infered[0].name, 'open')
  618. def test_callfunc_context_func(self):
  619. code = '''
  620. def mirror(arg=None):
  621. return arg
  622. un = mirror(1)
  623. '''
  624. astng = builder.string_build(code, __name__, __file__)
  625. infered = list(astng.igetattr('un'))
  626. self.failUnlessEqual(len(infered), 1)
  627. self.assertIsInstance(infered[0], nodes.Const)
  628. self.failUnlessEqual(infered[0].value, 1)
  629. def test_callfunc_context_lambda(self):
  630. code = '''
  631. mirror = lambda x=None: x
  632. un = mirror(1)
  633. '''
  634. astng = builder.string_build(code, __name__, __file__)
  635. infered = list(astng.igetattr('mirror'))
  636. self.failUnlessEqual(len(infered), 1)
  637. self.assertIsInstance(infered[0], nodes.Lambda)
  638. infered = list(astng.igetattr('un'))
  639. self.failUnlessEqual(len(infered), 1)
  640. self.assertIsInstance(infered[0], nodes.Const)
  641. self.failUnlessEqual(infered[0].value, 1)
  642. def test_factory_method(self):
  643. code = '''
  644. class Super(object):
  645. @classmethod
  646. def instance(cls):
  647. return cls()
  648. class Sub(Super):
  649. def method(self):
  650. print ('method called')
  651. sub = Sub.instance()
  652. '''
  653. astng = builder.string_build(code, __name__, __file__)
  654. infered = list(astng.igetattr('sub'))
  655. self.failUnlessEqual(len(infered), 1)
  656. self.assertIsInstance(infered[0], Instance)
  657. self.failUnlessEqual(infered[0]._proxied.name, 'Sub')
  658. def test_import_as(self):
  659. code = '''
  660. import os.path as osp
  661. print (osp.dirname(__file__))
  662. from os.path import exists as e
  663. assert e(__file__)
  664. from new import code as make_code
  665. print (make_code)
  666. '''
  667. astng = builder.string_build(code, __name__, __file__)
  668. infered = list(astng.igetattr('osp'))
  669. self.failUnlessEqual(len(infered), 1)
  670. self.assertIsInstance(infered[0], nodes.Module)
  671. self.failUnlessEqual(infered[0].name, 'os.path')
  672. infered = list(astng.igetattr('e'))
  673. self.failUnlessEqual(len(infered), 1)
  674. self.assertIsInstance(infered[0], nodes.Function)
  675. self.failUnlessEqual(infered[0].name, 'exists')
  676. if sys.version_info >= (3, 0):
  677. self.skipTest('<new> module has been removed')
  678. infered = list(astng.igetattr('make_code'))
  679. self.failUnlessEqual(len(infered), 1)
  680. self.assertIsInstance(infered[0], Instance)
  681. self.failUnlessEqual(str(infered[0]),
  682. 'Instance of %s.type' % BUILTINS_NAME)
  683. def _test_const_infered(self, node, value):
  684. infered = list(node.infer())
  685. self.failUnlessEqual(len(infered), 1)
  686. self.assertIsInstance(infered[0], nodes.Const)
  687. self.failUnlessEqual(infered[0].value, value)
  688. def test_unary_not(self):
  689. for code in ('a = not (1,); b = not ()',
  690. 'a = not {1:2}; b = not {}'):
  691. astng = builder.string_build(code, __name__, __file__)
  692. self._test_const_infered(astng['a'], False)
  693. self._test_const_infered(astng['b'], True)
  694. def test_binary_op_int_add(self):
  695. astng = builder.string_build('a = 1 + 2', __name__, __file__)
  696. self._test_const_infered(astng['a'], 3)
  697. def test_binary_op_int_sub(self):
  698. astng = builder.string_build('a = 1 - 2', __name__, __file__)
  699. self._test_const_infered(astng['a'], -1)
  700. def test_binary_op_float_div(self):
  701. astng = builder.string_build('a = 1 / 2.', __name__, __file__)
  702. self._test_const_infered(astng['a'], 1 / 2.)
  703. def test_binary_op_str_mul(self):
  704. astng = builder.string_build('a = "*" * 40', __name__, __file__)
  705. self._test_const_infered(astng['a'], "*" * 40)
  706. def test_binary_op_bitand(self):
  707. astng = builder.string_build('a = 23&20', __name__, __file__)
  708. self._test_const_infered(astng['a'], 23&20)
  709. def test_binary_op_bitor(self):
  710. astng = builder.string_build('a = 23|8', __name__, __file__)
  711. self._test_const_infered(astng['a'], 23|8)
  712. def test_binary_op_bitxor(self):
  713. astng = builder.string_build('a = 23^9', __name__, __file__)
  714. self._test_const_infered(astng['a'], 23^9)
  715. def test_binary_op_shiftright(self):
  716. astng = builder.string_build('a = 23 >>1', __name__, __file__)
  717. self._test_const_infered(astng['a'], 23>>1)
  718. def test_binary_op_shiftleft(self):
  719. astng = builder.string_build('a = 23 <<1', __name__, __file__)
  720. self._test_const_infered(astng['a'], 23<<1)
  721. def test_binary_op_list_mul(self):
  722. for code in ('a = [[]] * 2', 'a = 2 * [[]]'):
  723. astng = builder.string_build(code, __name__, __file__)
  724. infered = list(astng['a'].infer())
  725. self.failUnlessEqual(len(infered), 1)
  726. self.assertIsInstance(infered[0], nodes.List)
  727. self.failUnlessEqual(len(infered[0].elts), 2)
  728. self.assertIsInstance(infered[0].elts[0], nodes.List)
  729. self.assertIsInstance(infered[0].elts[1], nodes.List)
  730. def test_binary_op_list_mul_none(self):
  731. 'test correct handling on list multiplied by None'
  732. astng = builder.string_build( 'a = [1] * None\nb = [1] * "r"')
  733. infered = astng['a'].infered()
  734. self.assertEqual(len(infered), 1)
  735. self.assertEqual(infered[0], YES)
  736. infered = astng['b'].infered()
  737. self.assertEqual(len(infered), 1)
  738. self.assertEqual(infered[0], YES)
  739. def test_binary_op_tuple_add(self):
  740. astng = builder.string_build('a = (1,) + (2,)', __name__, __file__)
  741. infered = list(astng['a'].infer())
  742. self.failUnlessEqual(len(infered), 1)
  743. self.assertIsInstance(infered[0], nodes.Tuple)
  744. self.failUnlessEqual(len(infered[0].elts), 2)
  745. self.failUnlessEqual(infered[0].elts[0].value, 1)
  746. self.failUnlessEqual(infered[0].elts[1].value, 2)
  747. def test_binary_op_custom_class(self):
  748. code = '''
  749. class myarray:
  750. def __init__(self, array):
  751. self.array = array
  752. def __mul__(self, x):
  753. return myarray([2,4,6])
  754. def astype(self):
  755. return "ASTYPE"
  756. def randint(maximum):
  757. if maximum is not None:
  758. return myarray([1,2,3]) * 2
  759. else:
  760. return int(5)
  761. x = randint(1)
  762. '''
  763. astng = builder.string_build(code, __name__, __file__)
  764. infered = list(astng.igetattr('x'))
  765. self.failUnlessEqual(len(infered), 2)
  766. value = [str(v) for v in infered]
  767. # The __name__ trick here makes it work when invoked directly
  768. # (__name__ == '__main__') and through pytest (__name__ ==
  769. # 'unittest_inference')
  770. self.assertEqual(value, ['Instance of %s.myarray' % __name__,
  771. 'Instance of %s.int' % BUILTINS_NAME])
  772. def test_nonregr_lambda_arg(self):
  773. code = '''
  774. def f(g = lambda: None):
  775. g().x
  776. '''
  777. astng = builder.string_build(code, __name__, __file__)
  778. callfuncnode = astng['f'].body[0].value.expr
  779. infered = list(callfuncnode.infer())
  780. self.failUnlessEqual(len(infered), 2, infered)
  781. infered.remove(YES)
  782. self.assertIsInstance(infered[0], nodes.Const)
  783. self.failUnlessEqual(infered[0].value, None)
  784. def test_nonregr_getitem_empty_tuple(self):
  785. code = '''
  786. def f(x):
  787. a = ()[x]
  788. '''
  789. astng = builder.string_build(code, __name__, __file__)
  790. infered = list(astng['f'].ilookup('a'))
  791. self.failUnlessEqual(len(infered), 1)
  792. self.failUnlessEqual(infered[0], YES)
  793. def test_python25_generator_exit(self):
  794. sys.stderr = StringIO()
  795. data = "b = {}[str(0)+''].a"
  796. astng = builder.string_build(data, __name__, __file__)
  797. list(astng['b'].infer())
  798. output = sys.stderr.getvalue()
  799. # I have no idea how to test for this in another way...
  800. self.failIf("RuntimeError" in output, "Exception exceptions.RuntimeError: 'generator ignored GeneratorExit' in <generator object> ignored")
  801. sys.stderr = sys.__stderr__
  802. def test_python25_relative_import(self):
  803. data = "from ...common import date; print (date)"
  804. # !! FIXME also this relative import would not work 'in real' (no __init__.py in test/)
  805. # the test works since we pretend we have a package by passing the full modname
  806. astng = builder.string_build(data, 'logilab.astng.test.unittest_inference', __file__)
  807. infered = get_name_node(astng, 'date').infer().next()
  808. self.assertIsInstance(infered, nodes.Module)
  809. self.assertEqual(infered.name, 'logilab.common.date')
  810. def test_python25_no_relative_import(self):
  811. fname = join(abspath(dirname(__file__)), 'regrtest_data', 'package', 'absimport.py')
  812. astng = builder.file_build(fname, 'absimport')
  813. self.failUnless(astng.absolute_import_activated(), True)
  814. infered = get_name_node(astng, 'import_package_subpackage_module').infer().next()
  815. # failed to import since absolute_import is activated
  816. self.failUnless(infered is YES)
  817. def test_nonregr_absolute_import(self):
  818. fname = join(abspath(dirname(__file__)), 'regrtest_data', 'absimp', 'string.py')
  819. astng = builder.file_build(fname, 'absimp.string')
  820. self.failUnless(astng.absolute_import_activated(), True)
  821. infered = get_name_node(astng, 'string').infer().next()
  822. self.assertIsInstance(infered, nodes.Module)
  823. self.assertEqual(infered.name, 'string')
  824. self.failUnless('lower' in infered.locals)
  825. def test_mechanize_open(self):
  826. try:
  827. import mechanize
  828. except ImportError:
  829. self.skipTest('require mechanize installed')
  830. data = '''from mechanize import Browser
  831. print (Browser)
  832. b = Browser()
  833. '''
  834. astng = builder.string_build(data, __name__, __file__)
  835. browser = get_name_node(astng, 'Browser').infer().next()
  836. self.assertIsInstance(browser, nodes.Class)
  837. bopen = list(browser.igetattr('open'))
  838. self.skipTest('the commit said: "huum, see that later"')
  839. self.assertEqual(len(bopen), 1)
  840. self.assertIsInstance(bopen[0], nodes.Function)
  841. self.failUnless(bopen[0].callable())
  842. b = get_name_node(astng, 'b').infer().next()
  843. self.assertIsInstance(b, Instance)
  844. bopen = list(b.igetattr('open'))
  845. self.assertEqual(len(bopen), 1)
  846. self.assertIsInstance(bopen[0], BoundMethod)
  847. self.failUnless(bopen[0].callable())
  848. def test_property(self):
  849. code = '''
  850. from smtplib import SMTP
  851. class SendMailController(object):
  852. @property
  853. def smtp(self):
  854. return SMTP(mailhost, port)
  855. @property
  856. def me(self):
  857. return self
  858. my_smtp = SendMailController().smtp
  859. my_me = SendMailController().me
  860. '''
  861. decorators = set(['%s.property' % BUILTINS_NAME])
  862. astng = builder.string_build(code, __name__, __file__)
  863. self.assertEqual(astng['SendMailController']['smtp'].decoratornames(),
  864. decorators)
  865. propinfered = list(astng.body[2].value.infer())
  866. self.assertEqual(len(propinfered), 1)
  867. propinfered = propinfered[0]
  868. self.assertIsInstance(propinfered, Instance)
  869. self.assertEqual(propinfered.name, 'SMTP')
  870. self.assertEqual(propinfered.root().name, 'smtplib')
  871. self.assertEqual(astng['SendMailController']['me'].decoratornames(),
  872. decorators)
  873. propinfered = list(astng.body[3].value.infer())
  874. self.assertEqual(len(propinfered), 1)
  875. propinfered = propinfered[0]
  876. self.assertIsInstance(propinfered, Instance)
  877. self.assertEqual(propinfered.name, 'SendMailController')
  878. self.assertEqual(propinfered.root().name, __name__)
  879. def test_im_func_unwrap(self):
  880. code = '''
  881. class EnvBasedTC:
  882. def pactions(self):
  883. pass
  884. pactions = EnvBasedTC.pactions.im_func
  885. print (pactions)
  886. class EnvBasedTC2:
  887. pactions = EnvBasedTC.pactions.im_func
  888. print (pactions)
  889. '''
  890. astng = builder.string_build(code, __name__, __file__)
  891. pactions = get_name_node(astng, 'pactions')
  892. infered = list(pactions.infer())
  893. self.assertEqual(len(infered), 1)
  894. self.assertIsInstance(infered[0], nodes.Function)
  895. pactions = get_name_node(astng['EnvBasedTC2'], 'pactions')
  896. infered = list(pactions.infer())
  897. self.assertEqual(len(infered), 1)
  898. self.assertIsInstance(infered[0], nodes.Function)
  899. def test_augassign(self):
  900. code = '''
  901. a = 1
  902. a += 2
  903. print (a)
  904. '''
  905. astng = builder.string_build(code, __name__, __file__)
  906. infered = list(get_name_node(astng, 'a').infer())
  907. self.assertEqual(len(infered), 1)
  908. self.assertIsInstance(infered[0], nodes.Const)
  909. self.assertEqual(infered[0].value, 3)
  910. def test_nonregr_func_arg(self):
  911. code = '''
  912. def foo(self, bar):
  913. def baz():
  914. pass
  915. def qux():
  916. return baz
  917. spam = bar(None, qux)
  918. print (spam)
  919. '''
  920. astng = builder.string_build(code, __name__, __file__)
  921. infered = list(get_name_node(astng['foo'], 'spam').infer())
  922. self.assertEqual(len(infered), 1)
  923. self.assertIs(infered[0], YES)
  924. def test_nonregr_func_global(self):
  925. code = '''
  926. active_application = None
  927. def get_active_application():
  928. global active_application
  929. return active_application
  930. class Application(object):
  931. def __init__(self):
  932. global active_application
  933. active_application = self
  934. class DataManager(object):
  935. def __init__(self, app=None):
  936. self.app = get_active_application()
  937. def test(self):
  938. p = self.app
  939. print (p)
  940. '''
  941. astng = builder.string_build(code, __name__, __file__)
  942. infered = list(Instance(astng['DataManager']).igetattr('app'))
  943. self.assertEqual(len(infered), 2, infered) # None / Instance(Application)
  944. infered = list(get_name_node(astng['DataManager']['test'], 'p').infer())
  945. self.assertEqual(len(infered), 2, infered)
  946. for node in infered:
  947. if isinstance(node, Instance) and node.name == 'Application':
  948. break
  949. else:
  950. self.fail('expected to find an instance of Application in %s' % infered)
  951. def test_list_inference(self):
  952. """#20464"""
  953. code = '''
  954. import optparse
  955. A = []
  956. B = []
  957. def test():
  958. xyz = [
  959. "foobar=%s" % options.ca,
  960. ] + A + B
  961. if options.bind is not None:
  962. xyz.append("bind=%s" % options.bind)
  963. return xyz
  964. def main():
  965. global options
  966. parser = optparse.OptionParser()
  967. (options, args) = parser.parse_args()
  968. Z = test()
  969. '''
  970. astng = builder.string_build(code, __name__, __file__)
  971. infered = list(astng['Z'].infer())
  972. self.assertEqual(len(infered), 1, infered)
  973. self.assertIsInstance(infered[0], Instance)
  974. self.assertIsInstance(infered[0]._proxied, nodes.Class)
  975. self.assertEqual(infered[0]._proxied.name, 'list')
  976. def test__new__(self):
  977. code = '''
  978. class NewTest(object):
  979. "doc"
  980. def __new__(cls, arg):
  981. self = object.__new__(cls)
  982. self.arg = arg
  983. return self
  984. n = NewTest()
  985. '''
  986. astng = builder.string_build(code, __name__, __file__)
  987. self.assertRaises(InferenceError, list, astng['NewTest'].igetattr('arg'))
  988. n = astng['n'].infer().next()
  989. infered = list(n.igetattr('arg'))
  990. self.assertEqual(len(infered), 1, infered)
  991. def test_two_parents_from_same_module(self):
  992. code = '''
  993. from data import nonregr
  994. class Xxx(nonregr.Aaa, nonregr.Ccc):
  995. "doc"
  996. '''
  997. astng = builder.string_build(code, __name__, __file__)
  998. parents = list(astng['Xxx'].ancestors())
  999. self.assertEqual(len(parents), 3, parents) # Aaa, Ccc, object
  1000. if __name__ == '__main__':
  1001. unittest_main()