Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

unittest_lookup.py 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. # Copyright (c) 2007-2013 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr>
  2. # Copyright (c) 2014-2016 Claudiu Popa <pcmanticore@gmail.com>
  3. # Copyright (c) 2014 Google, Inc.
  4. # Copyright (c) 2015-2016 Cara Vinson <ceridwenv@gmail.com>
  5. # Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
  6. # For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
  7. """tests for the astroid variable lookup capabilities
  8. """
  9. import functools
  10. import sys
  11. import unittest
  12. from astroid import builder
  13. from astroid import exceptions
  14. from astroid import nodes
  15. from astroid import scoped_nodes
  16. from astroid import util
  17. from astroid.tests import resources
  18. class LookupTest(resources.SysPathSetup, unittest.TestCase):
  19. def setUp(self):
  20. super(LookupTest, self).setUp()
  21. self.module = resources.build_file('data/module.py', 'data.module')
  22. self.module2 = resources.build_file('data/module2.py', 'data.module2')
  23. self.nonregr = resources.build_file('data/nonregr.py', 'data.nonregr')
  24. def test_limit(self):
  25. code = '''
  26. l = [a
  27. for a,b in list]
  28. a = 1
  29. b = a
  30. a = None
  31. def func():
  32. c = 1
  33. '''
  34. astroid = builder.parse(code, __name__)
  35. # a & b
  36. a = next(astroid.nodes_of_class(nodes.Name))
  37. self.assertEqual(a.lineno, 2)
  38. if sys.version_info < (3, 0):
  39. self.assertEqual(len(astroid.lookup('b')[1]), 1)
  40. self.assertEqual(len(astroid.lookup('a')[1]), 1)
  41. b = astroid.locals['b'][1]
  42. else:
  43. self.assertEqual(len(astroid.lookup('b')[1]), 1)
  44. self.assertEqual(len(astroid.lookup('a')[1]), 1)
  45. b = astroid.locals['b'][0]
  46. stmts = a.lookup('a')[1]
  47. self.assertEqual(len(stmts), 1)
  48. self.assertEqual(b.lineno, 6)
  49. b_infer = b.infer()
  50. b_value = next(b_infer)
  51. self.assertEqual(b_value.value, 1)
  52. # c
  53. self.assertRaises(StopIteration, functools.partial(next, b_infer))
  54. func = astroid.locals['func'][0]
  55. self.assertEqual(len(func.lookup('c')[1]), 1)
  56. def test_module(self):
  57. astroid = builder.parse('pass', __name__)
  58. # built-in objects
  59. none = next(astroid.ilookup('None'))
  60. self.assertIsNone(none.value)
  61. obj = next(astroid.ilookup('object'))
  62. self.assertIsInstance(obj, nodes.ClassDef)
  63. self.assertEqual(obj.name, 'object')
  64. self.assertRaises(exceptions.InferenceError,
  65. functools.partial(next, astroid.ilookup('YOAA')))
  66. # XXX
  67. self.assertEqual(len(list(self.nonregr.ilookup('enumerate'))), 2)
  68. def test_class_ancestor_name(self):
  69. code = '''
  70. class A:
  71. pass
  72. class A(A):
  73. pass
  74. '''
  75. astroid = builder.parse(code, __name__)
  76. cls1 = astroid.locals['A'][0]
  77. cls2 = astroid.locals['A'][1]
  78. name = next(cls2.nodes_of_class(nodes.Name))
  79. self.assertEqual(next(name.infer()), cls1)
  80. ### backport those test to inline code
  81. def test_method(self):
  82. method = self.module['YOUPI']['method']
  83. my_dict = next(method.ilookup('MY_DICT'))
  84. self.assertTrue(isinstance(my_dict, nodes.Dict), my_dict)
  85. none = next(method.ilookup('None'))
  86. self.assertIsNone(none.value)
  87. self.assertRaises(exceptions.InferenceError,
  88. functools.partial(next, method.ilookup('YOAA')))
  89. def test_function_argument_with_default(self):
  90. make_class = self.module2['make_class']
  91. base = next(make_class.ilookup('base'))
  92. self.assertTrue(isinstance(base, nodes.ClassDef), base.__class__)
  93. self.assertEqual(base.name, 'YO')
  94. self.assertEqual(base.root().name, 'data.module')
  95. def test_class(self):
  96. klass = self.module['YOUPI']
  97. my_dict = next(klass.ilookup('MY_DICT'))
  98. self.assertIsInstance(my_dict, nodes.Dict)
  99. none = next(klass.ilookup('None'))
  100. self.assertIsNone(none.value)
  101. obj = next(klass.ilookup('object'))
  102. self.assertIsInstance(obj, nodes.ClassDef)
  103. self.assertEqual(obj.name, 'object')
  104. self.assertRaises(exceptions.InferenceError,
  105. functools.partial(next, klass.ilookup('YOAA')))
  106. def test_inner_classes(self):
  107. ddd = list(self.nonregr['Ccc'].ilookup('Ddd'))
  108. self.assertEqual(ddd[0].name, 'Ddd')
  109. def test_loopvar_hiding(self):
  110. astroid = builder.parse("""
  111. x = 10
  112. for x in range(5):
  113. print (x)
  114. if x > 0:
  115. print ('#' * x)
  116. """, __name__)
  117. xnames = [n for n in astroid.nodes_of_class(nodes.Name) if n.name == 'x']
  118. # inside the loop, only one possible assignment
  119. self.assertEqual(len(xnames[0].lookup('x')[1]), 1)
  120. # outside the loop, two possible assignments
  121. self.assertEqual(len(xnames[1].lookup('x')[1]), 2)
  122. self.assertEqual(len(xnames[2].lookup('x')[1]), 2)
  123. def test_list_comps(self):
  124. astroid = builder.parse("""
  125. print ([ i for i in range(10) ])
  126. print ([ i for i in range(10) ])
  127. print ( list( i for i in range(10) ) )
  128. """, __name__)
  129. xnames = [n for n in astroid.nodes_of_class(nodes.Name) if n.name == 'i']
  130. self.assertEqual(len(xnames[0].lookup('i')[1]), 1)
  131. self.assertEqual(xnames[0].lookup('i')[1][0].lineno, 2)
  132. self.assertEqual(len(xnames[1].lookup('i')[1]), 1)
  133. self.assertEqual(xnames[1].lookup('i')[1][0].lineno, 3)
  134. self.assertEqual(len(xnames[2].lookup('i')[1]), 1)
  135. self.assertEqual(xnames[2].lookup('i')[1][0].lineno, 4)
  136. def test_list_comp_target(self):
  137. """test the list comprehension target"""
  138. astroid = builder.parse("""
  139. ten = [ var for var in range(10) ]
  140. var
  141. """)
  142. var = astroid.body[1].value
  143. if sys.version_info < (3, 0):
  144. self.assertEqual(var.inferred(), [util.Uninferable])
  145. else:
  146. self.assertRaises(exceptions.NameInferenceError, var.inferred)
  147. def test_dict_comps(self):
  148. astroid = builder.parse("""
  149. print ({ i: j for i in range(10) for j in range(10) })
  150. print ({ i: j for i in range(10) for j in range(10) })
  151. """, __name__)
  152. xnames = [n for n in astroid.nodes_of_class(nodes.Name) if n.name == 'i']
  153. self.assertEqual(len(xnames[0].lookup('i')[1]), 1)
  154. self.assertEqual(xnames[0].lookup('i')[1][0].lineno, 2)
  155. self.assertEqual(len(xnames[1].lookup('i')[1]), 1)
  156. self.assertEqual(xnames[1].lookup('i')[1][0].lineno, 3)
  157. xnames = [n for n in astroid.nodes_of_class(nodes.Name) if n.name == 'j']
  158. self.assertEqual(len(xnames[0].lookup('i')[1]), 1)
  159. self.assertEqual(xnames[0].lookup('i')[1][0].lineno, 2)
  160. self.assertEqual(len(xnames[1].lookup('i')[1]), 1)
  161. self.assertEqual(xnames[1].lookup('i')[1][0].lineno, 3)
  162. def test_set_comps(self):
  163. astroid = builder.parse("""
  164. print ({ i for i in range(10) })
  165. print ({ i for i in range(10) })
  166. """, __name__)
  167. xnames = [n for n in astroid.nodes_of_class(nodes.Name) if n.name == 'i']
  168. self.assertEqual(len(xnames[0].lookup('i')[1]), 1)
  169. self.assertEqual(xnames[0].lookup('i')[1][0].lineno, 2)
  170. self.assertEqual(len(xnames[1].lookup('i')[1]), 1)
  171. self.assertEqual(xnames[1].lookup('i')[1][0].lineno, 3)
  172. def test_set_comp_closure(self):
  173. astroid = builder.parse("""
  174. ten = { var for var in range(10) }
  175. var
  176. """)
  177. var = astroid.body[1].value
  178. self.assertRaises(exceptions.NameInferenceError, var.inferred)
  179. def test_generator_attributes(self):
  180. tree = builder.parse("""
  181. def count():
  182. "test"
  183. yield 0
  184. iterer = count()
  185. num = iterer.next()
  186. """)
  187. next_node = tree.body[2].value.func
  188. gener = next_node.expr.inferred()[0]
  189. if sys.version_info < (3, 0):
  190. self.assertIsInstance(gener.getattr('next')[0], nodes.FunctionDef)
  191. else:
  192. self.assertIsInstance(gener.getattr('__next__')[0], nodes.FunctionDef)
  193. self.assertIsInstance(gener.getattr('send')[0], nodes.FunctionDef)
  194. self.assertIsInstance(gener.getattr('throw')[0], nodes.FunctionDef)
  195. self.assertIsInstance(gener.getattr('close')[0], nodes.FunctionDef)
  196. def test_explicit___name__(self):
  197. code = '''
  198. class Pouet:
  199. __name__ = "pouet"
  200. p1 = Pouet()
  201. class PouetPouet(Pouet): pass
  202. p2 = Pouet()
  203. class NoName: pass
  204. p3 = NoName()
  205. '''
  206. astroid = builder.parse(code, __name__)
  207. p1 = next(astroid['p1'].infer())
  208. self.assertTrue(p1.getattr('__name__'))
  209. p2 = next(astroid['p2'].infer())
  210. self.assertTrue(p2.getattr('__name__'))
  211. self.assertTrue(astroid['NoName'].getattr('__name__'))
  212. p3 = next(astroid['p3'].infer())
  213. self.assertRaises(exceptions.AttributeInferenceError, p3.getattr, '__name__')
  214. def test_function_module_special(self):
  215. astroid = builder.parse('''
  216. def initialize(linter):
  217. """initialize linter with checkers in this package """
  218. package_load(linter, __path__[0])
  219. ''', 'data.__init__')
  220. path = [n for n in astroid.nodes_of_class(nodes.Name) if n.name == '__path__'][0]
  221. self.assertEqual(len(path.lookup('__path__')[1]), 1)
  222. def test_builtin_lookup(self):
  223. self.assertEqual(scoped_nodes.builtin_lookup('__dict__')[1], ())
  224. intstmts = scoped_nodes.builtin_lookup('int')[1]
  225. self.assertEqual(len(intstmts), 1)
  226. self.assertIsInstance(intstmts[0], nodes.ClassDef)
  227. self.assertEqual(intstmts[0].name, 'int')
  228. # pylint: disable=no-member; union type in const_factory, this shouldn't happen
  229. self.assertIs(intstmts[0], nodes.const_factory(1)._proxied)
  230. def test_decorator_arguments_lookup(self):
  231. code = '''
  232. def decorator(value):
  233. def wrapper(function):
  234. return function
  235. return wrapper
  236. class foo:
  237. member = 10 #@
  238. @decorator(member) #This will cause pylint to complain
  239. def test(self):
  240. pass
  241. '''
  242. member = builder.extract_node(code, __name__).targets[0]
  243. it = member.infer()
  244. obj = next(it)
  245. self.assertIsInstance(obj, nodes.Const)
  246. self.assertEqual(obj.value, 10)
  247. self.assertRaises(StopIteration, functools.partial(next, it))
  248. def test_inner_decorator_member_lookup(self):
  249. code = '''
  250. class FileA:
  251. def decorator(bla):
  252. return bla
  253. @__(decorator)
  254. def funcA():
  255. return 4
  256. '''
  257. decname = builder.extract_node(code, __name__)
  258. it = decname.infer()
  259. obj = next(it)
  260. self.assertIsInstance(obj, nodes.FunctionDef)
  261. self.assertRaises(StopIteration, functools.partial(next, it))
  262. def test_static_method_lookup(self):
  263. code = '''
  264. class FileA:
  265. @staticmethod
  266. def funcA():
  267. return 4
  268. class Test:
  269. FileA = [1,2,3]
  270. def __init__(self):
  271. print (FileA.funcA())
  272. '''
  273. astroid = builder.parse(code, __name__)
  274. it = astroid['Test']['__init__'].ilookup('FileA')
  275. obj = next(it)
  276. self.assertIsInstance(obj, nodes.ClassDef)
  277. self.assertRaises(StopIteration, functools.partial(next, it))
  278. def test_global_delete(self):
  279. code = '''
  280. def run2():
  281. f = Frobble()
  282. class Frobble:
  283. pass
  284. Frobble.mumble = True
  285. del Frobble
  286. def run1():
  287. f = Frobble()
  288. '''
  289. astroid = builder.parse(code, __name__)
  290. stmts = astroid['run2'].lookup('Frobbel')[1]
  291. self.assertEqual(len(stmts), 0)
  292. stmts = astroid['run1'].lookup('Frobbel')[1]
  293. self.assertEqual(len(stmts), 0)
  294. if __name__ == '__main__':
  295. unittest.main()