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_regrtest.py 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. # Copyright (c) 2006-2008, 2010-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr>
  2. # Copyright (c) 2013-2014 Google, Inc.
  3. # Copyright (c) 2014-2016 Claudiu Popa <pcmanticore@gmail.com>
  4. # Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
  5. # For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
  6. import sys
  7. import unittest
  8. import textwrap
  9. import six
  10. from astroid import MANAGER, Instance, nodes
  11. from astroid.bases import BUILTINS
  12. from astroid.builder import AstroidBuilder, extract_node
  13. from astroid import exceptions
  14. from astroid.raw_building import build_module
  15. from astroid.manager import AstroidManager
  16. from astroid.test_utils import require_version
  17. from astroid.tests import resources
  18. from astroid import transforms
  19. class NonRegressionTests(resources.AstroidCacheSetupMixin,
  20. unittest.TestCase):
  21. def setUp(self):
  22. sys.path.insert(0, resources.find('data'))
  23. MANAGER.always_load_extensions = True
  24. MANAGER.astroid_cache[BUILTINS] = self._builtins
  25. def tearDown(self):
  26. # Since we may have created a brainless manager, leading
  27. # to a new cache builtin module and proxy classes in the constants,
  28. # clear out the global manager cache.
  29. MANAGER.clear_cache(self._builtins)
  30. MANAGER.always_load_extensions = False
  31. sys.path.pop(0)
  32. sys.path_importer_cache.pop(resources.find('data'), None)
  33. def brainless_manager(self):
  34. manager = AstroidManager()
  35. # avoid caching into the AstroidManager borg since we get problems
  36. # with other tests :
  37. manager.__dict__ = {}
  38. manager._failed_import_hooks = []
  39. manager.astroid_cache = {}
  40. manager._mod_file_cache = {}
  41. manager._transform = transforms.TransformVisitor()
  42. manager.clear_cache() # trigger proper bootstraping
  43. return manager
  44. def test_module_path(self):
  45. man = self.brainless_manager()
  46. mod = man.ast_from_module_name('package.import_package_subpackage_module')
  47. package = next(mod.igetattr('package'))
  48. self.assertEqual(package.name, 'package')
  49. subpackage = next(package.igetattr('subpackage'))
  50. self.assertIsInstance(subpackage, nodes.Module)
  51. self.assertTrue(subpackage.package)
  52. self.assertEqual(subpackage.name, 'package.subpackage')
  53. module = next(subpackage.igetattr('module'))
  54. self.assertEqual(module.name, 'package.subpackage.module')
  55. def test_package_sidepackage(self):
  56. manager = self.brainless_manager()
  57. assert 'package.sidepackage' not in MANAGER.astroid_cache
  58. package = manager.ast_from_module_name('absimp')
  59. self.assertIsInstance(package, nodes.Module)
  60. self.assertTrue(package.package)
  61. subpackage = next(package.getattr('sidepackage')[0].infer())
  62. self.assertIsInstance(subpackage, nodes.Module)
  63. self.assertTrue(subpackage.package)
  64. self.assertEqual(subpackage.name, 'absimp.sidepackage')
  65. def test_living_property(self):
  66. builder = AstroidBuilder()
  67. builder._done = {}
  68. builder._module = sys.modules[__name__]
  69. builder.object_build(build_module('module_name', ''), Whatever)
  70. def test_new_style_class_detection(self):
  71. try:
  72. import pygtk # pylint: disable=unused-variable
  73. except ImportError:
  74. self.skipTest('test skipped: pygtk is not available')
  75. # XXX may fail on some pygtk version, because objects in
  76. # gobject._gobject have __module__ set to gobject :(
  77. builder = AstroidBuilder()
  78. data = """
  79. import pygtk
  80. pygtk.require("2.6")
  81. import gobject
  82. class A(gobject.GObject):
  83. pass
  84. """
  85. astroid = builder.string_build(data, __name__, __file__)
  86. a = astroid['A']
  87. self.assertTrue(a.newstyle)
  88. def test_numpy_crash(self):
  89. """test don't crash on numpy"""
  90. #a crash occurred somewhere in the past, and an
  91. # InferenceError instead of a crash was better, but now we even infer!
  92. try:
  93. import numpy # pylint: disable=unused-variable
  94. except ImportError:
  95. self.skipTest('test skipped: numpy is not available')
  96. builder = AstroidBuilder()
  97. data = """
  98. from numpy import multiply
  99. multiply(1, 2, 3)
  100. """
  101. astroid = builder.string_build(data, __name__, __file__)
  102. callfunc = astroid.body[1].value.func
  103. inferred = callfunc.inferred()
  104. self.assertEqual(len(inferred), 1)
  105. @require_version('3.0')
  106. def test_nameconstant(self):
  107. # used to fail for Python 3.4
  108. builder = AstroidBuilder()
  109. astroid = builder.string_build("def test(x=True): pass")
  110. default = astroid.body[0].args.args[0]
  111. self.assertEqual(default.name, 'x')
  112. self.assertEqual(next(default.infer()).value, True)
  113. @require_version('2.7')
  114. def test_with_infer_assignnames(self):
  115. builder = AstroidBuilder()
  116. data = """
  117. with open('a.txt') as stream, open('b.txt'):
  118. stream.read()
  119. """
  120. astroid = builder.string_build(data, __name__, __file__)
  121. # Used to crash due to the fact that the second
  122. # context manager didn't use an assignment name.
  123. list(astroid.nodes_of_class(nodes.Call))[-1].inferred()
  124. def test_recursion_regression_issue25(self):
  125. builder = AstroidBuilder()
  126. data = """
  127. import recursion as base
  128. _real_Base = base.Base
  129. class Derived(_real_Base):
  130. pass
  131. def run():
  132. base.Base = Derived
  133. """
  134. astroid = builder.string_build(data, __name__, __file__)
  135. # Used to crash in _is_metaclass, due to wrong
  136. # ancestors chain
  137. classes = astroid.nodes_of_class(nodes.ClassDef)
  138. for klass in classes:
  139. # triggers the _is_metaclass call
  140. klass.type # pylint: disable=pointless-statement
  141. def test_decorator_callchain_issue42(self):
  142. builder = AstroidBuilder()
  143. data = """
  144. def test():
  145. def factory(func):
  146. def newfunc():
  147. func()
  148. return newfunc
  149. return factory
  150. @test()
  151. def crash():
  152. pass
  153. """
  154. astroid = builder.string_build(data, __name__, __file__)
  155. self.assertEqual(astroid['crash'].type, 'function')
  156. def test_filter_stmts_scoping(self):
  157. builder = AstroidBuilder()
  158. data = """
  159. def test():
  160. compiler = int()
  161. class B(compiler.__class__):
  162. pass
  163. compiler = B()
  164. return compiler
  165. """
  166. astroid = builder.string_build(data, __name__, __file__)
  167. test = astroid['test']
  168. result = next(test.infer_call_result(astroid))
  169. self.assertIsInstance(result, Instance)
  170. base = next(result._proxied.bases[0].infer())
  171. self.assertEqual(base.name, 'int')
  172. def test_ancestors_patching_class_recursion(self):
  173. node = AstroidBuilder().string_build(textwrap.dedent("""
  174. import string
  175. Template = string.Template
  176. class A(Template):
  177. pass
  178. class B(A):
  179. pass
  180. def test(x=False):
  181. if x:
  182. string.Template = A
  183. else:
  184. string.Template = B
  185. """))
  186. klass = node['A']
  187. ancestors = list(klass.ancestors())
  188. self.assertEqual(ancestors[0].qname(), 'string.Template')
  189. def test_ancestors_yes_in_bases(self):
  190. # Test for issue https://bitbucket.org/logilab/astroid/issue/84
  191. # This used to crash astroid with a TypeError, because an Uninferable
  192. # node was present in the bases
  193. node = extract_node("""
  194. def with_metaclass(meta, *bases):
  195. class metaclass(meta):
  196. def __new__(cls, name, this_bases, d):
  197. return meta(name, bases, d)
  198. return type.__new__(metaclass, 'temporary_class', (), {})
  199. import lala
  200. class A(with_metaclass(object, lala.lala)): #@
  201. pass
  202. """)
  203. ancestors = list(node.ancestors())
  204. if six.PY3:
  205. self.assertEqual(len(ancestors), 1)
  206. self.assertEqual(ancestors[0].qname(),
  207. "{}.object".format(BUILTINS))
  208. else:
  209. self.assertEqual(len(ancestors), 0)
  210. def test_ancestors_missing_from_function(self):
  211. # Test for https://www.logilab.org/ticket/122793
  212. node = extract_node('''
  213. def gen(): yield
  214. GEN = gen()
  215. next(GEN)
  216. ''')
  217. self.assertRaises(exceptions.InferenceError, next, node.infer())
  218. def test_unicode_in_docstring(self):
  219. # Crashed for astroid==1.4.1
  220. # Test for https://bitbucket.org/logilab/astroid/issues/273/
  221. # In a regular file, "coding: utf-8" would have been used.
  222. node = extract_node(u'''
  223. from __future__ import unicode_literals
  224. class MyClass(object):
  225. def method(self):
  226. "With unicode : %s "
  227. instance = MyClass()
  228. ''' % u"\u2019")
  229. next(node.value.infer()).as_string()
  230. def test_binop_generates_nodes_with_parents(self):
  231. node = extract_node('''
  232. def no_op(*args):
  233. pass
  234. def foo(*args):
  235. def inner(*more_args):
  236. args + more_args #@
  237. return inner
  238. ''')
  239. inferred = next(node.infer())
  240. self.assertIsInstance(inferred, nodes.Tuple)
  241. self.assertIsNotNone(inferred.parent)
  242. self.assertIsInstance(inferred.parent, nodes.BinOp)
  243. def test_decorator_names_inference_error_leaking(self):
  244. node = extract_node('''
  245. class Parent(object):
  246. @property
  247. def foo(self):
  248. pass
  249. class Child(Parent):
  250. @Parent.foo.getter
  251. def foo(self): #@
  252. return super(Child, self).foo + ['oink']
  253. ''')
  254. inferred = next(node.infer())
  255. self.assertEqual(inferred.decoratornames(), set())
  256. def test_ssl_protocol(self):
  257. node = extract_node('''
  258. import ssl
  259. ssl.PROTOCOL_TLSv1
  260. ''')
  261. inferred = next(node.infer())
  262. self.assertIsInstance(inferred, nodes.Const)
  263. def test_recursive_property_method(self):
  264. node = extract_node('''
  265. class APropert():
  266. @property
  267. def property(self):
  268. return self
  269. APropert().property
  270. ''')
  271. next(node.infer())
  272. def test_uninferable_string_argument_of_namedtuple(self):
  273. node = extract_node('''
  274. import collections
  275. collections.namedtuple('{}'.format("a"), '')()
  276. ''')
  277. next(node.infer())
  278. @require_version(maxver='3.0')
  279. def test_reassignment_in_except_handler(self):
  280. node = extract_node('''
  281. import exceptions
  282. try:
  283. {}["a"]
  284. except KeyError, exceptions.IndexError:
  285. pass
  286. IndexError #@
  287. ''')
  288. self.assertEqual(len(node.inferred()), 1)
  289. class Whatever(object):
  290. a = property(lambda x: x, lambda x: x)
  291. if __name__ == '__main__':
  292. unittest.main()