PageRenderTime 287ms CodeModel.GetById 12ms RepoModel.GetById 14ms app.codeStats 0ms

/tools/logilab/astng/test/unittest_nodes.py

https://gitlab.com/holtscomm/gae-purchase-order-system
Python | 392 lines | 347 code | 11 blank | 34 comment | 1 complexity | 46c228a7dfc9601230eff8fb72d349af MD5 | raw file
  1. # This program is free software; you can redistribute it and/or modify it under
  2. # the terms of the GNU Lesser General Public License as published by the Free Software
  3. # Foundation; either version 2 of the License, or (at your option) any later
  4. # version.
  5. # copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
  6. # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
  7. # copyright 2003-2010 Sylvain Thenault, all rights reserved.
  8. # contact mailto:thenault@gmail.com
  9. #
  10. # This file is part of logilab-astng.
  11. #
  12. # logilab-astng is free software: you can redistribute it and/or modify it
  13. # under the terms of the GNU Lesser General Public License as published by the
  14. # Free Software Foundation, either version 2.1 of the License, or (at your
  15. # option) any later version.
  16. #
  17. # logilab-astng is distributed in the hope that it will be useful, but
  18. # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  19. # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
  20. # for more details.
  21. #
  22. # You should have received a copy of the GNU Lesser General Public License along
  23. # with logilab-astng. If not, see <http://www.gnu.org/licenses/>.
  24. # This program is distributed in the hope that it will be useful, but WITHOUT
  25. # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  26. # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
  27. # You should have received a copy of the GNU Lesser General Public License along with
  28. # this program; if not, write to the Free Software Foundation, Inc.,
  29. # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  30. """tests for specific behaviour of astng nodes
  31. """
  32. import sys
  33. from logilab.common import testlib
  34. from logilab.astng.exceptions import ASTNGBuildingException, NotFoundError
  35. from logilab.astng import BUILTINS_MODULE, builder, nodes
  36. from logilab.astng.as_string import as_string
  37. from data import module as test_module
  38. from os.path import join, abspath, dirname
  39. DATA = join(dirname(abspath(__file__)), 'data')
  40. abuilder = builder.ASTNGBuilder()
  41. class AsString(testlib.TestCase):
  42. def test_varargs_kwargs_as_string(self):
  43. ast = abuilder.string_build( 'raise_string(*args, **kwargs)').body[0]
  44. self.assertEqual(as_string(ast), 'raise_string(*args, **kwargs)')
  45. def test_module_as_string(self):
  46. """check as_string on a whole module prepared to be returned identically
  47. """
  48. data = open(join(DATA, 'module.py')).read()
  49. self.assertMultiLineEqual(as_string(MODULE), data)
  50. data = open(join(DATA, 'module2.py')).read()
  51. self.assertMultiLineEqual(as_string(MODULE2), data)
  52. def test_2_7_as_string(self):
  53. """check as_string for python syntax >= 2.7"""
  54. if sys.version_info < (2, 7):
  55. self.skipTest("test python >= 2.7 specific")
  56. code = '''one_two = {1, 2}
  57. b = {v: k for (k, v) in enumerate('string')}
  58. cdd = {k for k in b}\n\n'''
  59. ast = abuilder.string_build(code)
  60. self.assertMultiLineEqual(as_string(ast), code)
  61. def test_3k_as_string(self):
  62. """check as_string for python 3k syntax"""
  63. if sys.version_info < (3, 0):
  64. self.skipTest("test python 3k specific")
  65. code = '''print()
  66. def function(var):
  67. nonlocal counter
  68. try:
  69. hello
  70. except NameError as nexc:
  71. (*hell, o) = b'hello'
  72. raise AttributeError from nexc
  73. \n'''
  74. # TODO : annotations and keywords for class definition are not yet implemented
  75. _todo = '''
  76. def function(var:int):
  77. nonlocal counter
  78. class Language(metaclass=Natural):
  79. """natural language"""
  80. '''
  81. ast = abuilder.string_build(code)
  82. self.assertEqual(as_string(ast), code)
  83. class _NodeTC(testlib.TestCase):
  84. """test transformation of If Node"""
  85. CODE = None
  86. @property
  87. def astng(self):
  88. try:
  89. return self.__class__.__dict__['CODE_ASTNG']
  90. except KeyError:
  91. astng = abuilder.string_build(self.CODE)
  92. self.__class__.CODE_ASTNG = astng
  93. return astng
  94. class IfNodeTC(_NodeTC):
  95. """test transformation of If Node"""
  96. CODE = """
  97. if 0:
  98. print()
  99. if True:
  100. print()
  101. else:
  102. pass
  103. if "":
  104. print()
  105. elif []:
  106. raise
  107. if 1:
  108. print()
  109. elif True:
  110. print()
  111. elif func():
  112. pass
  113. else:
  114. raise
  115. """
  116. def test_if_elif_else_node(self):
  117. """test transformation for If node"""
  118. self.assertEqual(len(self.astng.body), 4)
  119. for stmt in self.astng.body:
  120. self.assertIsInstance( stmt, nodes.If)
  121. self.failIf(self.astng.body[0].orelse) # simple If
  122. self.assertIsInstance(self.astng.body[1].orelse[0], nodes.Pass) # If / else
  123. self.assertIsInstance(self.astng.body[2].orelse[0], nodes.If) # If / elif
  124. self.assertIsInstance(self.astng.body[3].orelse[0].orelse[0], nodes.If)
  125. def test_block_range(self):
  126. # XXX ensure expected values
  127. self.assertEqual(self.astng.block_range(1), (0, 22))
  128. self.assertEqual(self.astng.block_range(10), (0, 22)) # XXX (10, 22) ?
  129. self.assertEqual(self.astng.body[1].block_range(5), (5, 6))
  130. self.assertEqual(self.astng.body[1].block_range(6), (6, 6))
  131. self.assertEqual(self.astng.body[1].orelse[0].block_range(7), (7, 8))
  132. self.assertEqual(self.astng.body[1].orelse[0].block_range(8), (8, 8))
  133. class TryExceptNodeTC(_NodeTC):
  134. CODE = """
  135. try:
  136. print ('pouet')
  137. except IOError:
  138. pass
  139. except UnicodeError:
  140. print()
  141. else:
  142. print()
  143. """
  144. def test_block_range(self):
  145. # XXX ensure expected values
  146. self.assertEqual(self.astng.body[0].block_range(1), (1, 8))
  147. self.assertEqual(self.astng.body[0].block_range(2), (2, 2))
  148. self.assertEqual(self.astng.body[0].block_range(3), (3, 8))
  149. self.assertEqual(self.astng.body[0].block_range(4), (4, 4))
  150. self.assertEqual(self.astng.body[0].block_range(5), (5, 5))
  151. self.assertEqual(self.astng.body[0].block_range(6), (6, 6))
  152. self.assertEqual(self.astng.body[0].block_range(7), (7, 7))
  153. self.assertEqual(self.astng.body[0].block_range(8), (8, 8))
  154. class TryFinallyNodeTC(_NodeTC):
  155. CODE = """
  156. try:
  157. print ('pouet')
  158. finally:
  159. print ('pouet')
  160. """
  161. def test_block_range(self):
  162. # XXX ensure expected values
  163. self.assertEqual(self.astng.body[0].block_range(1), (1, 4))
  164. self.assertEqual(self.astng.body[0].block_range(2), (2, 2))
  165. self.assertEqual(self.astng.body[0].block_range(3), (3, 4))
  166. self.assertEqual(self.astng.body[0].block_range(4), (4, 4))
  167. class TryFinally25NodeTC(_NodeTC):
  168. CODE = """
  169. try:
  170. print('pouet')
  171. except Exception:
  172. print ('oops')
  173. finally:
  174. print ('pouet')
  175. """
  176. def test_block_range(self):
  177. # XXX ensure expected values
  178. self.assertEqual(self.astng.body[0].block_range(1), (1, 6))
  179. self.assertEqual(self.astng.body[0].block_range(2), (2, 2))
  180. self.assertEqual(self.astng.body[0].block_range(3), (3, 4))
  181. self.assertEqual(self.astng.body[0].block_range(4), (4, 4))
  182. self.assertEqual(self.astng.body[0].block_range(5), (5, 5))
  183. self.assertEqual(self.astng.body[0].block_range(6), (6, 6))
  184. class TryExcept2xNodeTC(_NodeTC):
  185. CODE = """
  186. try:
  187. hello
  188. except AttributeError, (retval, desc):
  189. pass
  190. """
  191. def test_tuple_attribute(self):
  192. if sys.version_info >= (3, 0):
  193. self.skipTest('syntax removed from py3.x')
  194. handler = self.astng.body[0].handlers[0]
  195. self.assertIsInstance(handler.name, nodes.Tuple)
  196. MODULE = abuilder.module_build(test_module)
  197. MODULE2 = abuilder.file_build(join(DATA, 'module2.py'), 'data.module2')
  198. class ImportNodeTC(testlib.TestCase):
  199. def test_import_self_resolve(self):
  200. myos = MODULE2.igetattr('myos').next()
  201. self.failUnless(isinstance(myos, nodes.Module), myos)
  202. self.failUnlessEqual(myos.name, 'os')
  203. self.failUnlessEqual(myos.qname(), 'os')
  204. self.failUnlessEqual(myos.pytype(), '%s.module' % BUILTINS_MODULE)
  205. def test_from_self_resolve(self):
  206. spawn = MODULE.igetattr('spawn').next()
  207. self.failUnless(isinstance(spawn, nodes.Class), spawn)
  208. self.failUnlessEqual(spawn.root().name, 'logilab.common.shellutils')
  209. self.failUnlessEqual(spawn.qname(), 'logilab.common.shellutils.Execute')
  210. self.failUnlessEqual(spawn.pytype(), '%s.classobj' % BUILTINS_MODULE)
  211. abspath = MODULE2.igetattr('abspath').next()
  212. self.failUnless(isinstance(abspath, nodes.Function), abspath)
  213. self.failUnlessEqual(abspath.root().name, 'os.path')
  214. self.failUnlessEqual(abspath.qname(), 'os.path.abspath')
  215. self.failUnlessEqual(abspath.pytype(), '%s.function' % BUILTINS_MODULE)
  216. def test_real_name(self):
  217. from_ = MODULE['spawn']
  218. self.assertEqual(from_.real_name('spawn'), 'Execute')
  219. imp_ = MODULE['os']
  220. self.assertEqual(imp_.real_name('os'), 'os')
  221. self.assertRaises(NotFoundError, imp_.real_name, 'os.path')
  222. imp_ = MODULE['spawn']
  223. self.assertEqual(imp_.real_name('spawn'), 'Execute')
  224. self.assertRaises(NotFoundError, imp_.real_name, 'Execute')
  225. imp_ = MODULE2['YO']
  226. self.assertEqual(imp_.real_name('YO'), 'YO')
  227. self.assertRaises(NotFoundError, imp_.real_name, 'data')
  228. def test_as_string(self):
  229. ast = MODULE['modutils']
  230. self.assertEqual(as_string(ast), "from logilab.common import modutils")
  231. ast = MODULE['spawn']
  232. self.assertEqual(as_string(ast), "from logilab.common.shellutils import Execute as spawn")
  233. ast = MODULE['os']
  234. self.assertEqual(as_string(ast), "import os.path")
  235. code = """from . import here
  236. from .. import door
  237. from .store import bread
  238. from ..cave import wine\n\n"""
  239. ast = abuilder.string_build(code)
  240. self.assertMultiLineEqual(ast.as_string(), code)
  241. class CmpNodeTC(testlib.TestCase):
  242. def test_as_string(self):
  243. ast = abuilder.string_build("a == 2").body[0]
  244. self.assertEqual(as_string(ast), "a == 2")
  245. class ConstNodeTC(testlib.TestCase):
  246. def _test(self, value):
  247. node = nodes.const_factory(value)
  248. self.assertIsInstance(node._proxied, nodes.Class)
  249. self.assertEqual(node._proxied.name, value.__class__.__name__)
  250. self.assertIs(node.value, value)
  251. self.failUnless(node._proxied.parent)
  252. self.assertEqual(node._proxied.root().name, value.__class__.__module__)
  253. def test_none(self):
  254. self._test(None)
  255. def test_bool(self):
  256. self._test(True)
  257. def test_int(self):
  258. self._test(1)
  259. def test_float(self):
  260. self._test(1.0)
  261. def test_complex(self):
  262. self._test(1.0j)
  263. def test_str(self):
  264. self._test('a')
  265. def test_unicode(self):
  266. self._test(u'a')
  267. class NameNodeTC(testlib.TestCase):
  268. def test_assign_to_True(self):
  269. """test that True and False assignements don't crash"""
  270. code = """True = False
  271. def hello(False):
  272. pass
  273. del True
  274. """
  275. if sys.version_info >= (3, 0):
  276. self.assertRaises(SyntaxError,#might become ASTNGBuildingException
  277. abuilder.string_build, code)
  278. else:
  279. ast = abuilder.string_build(code)
  280. ass_true = ast['True']
  281. self.assertIsInstance(ass_true, nodes.AssName)
  282. self.assertEqual(ass_true.name, "True")
  283. del_true = ast.body[2].targets[0]
  284. self.assertIsInstance(del_true, nodes.DelName)
  285. self.assertEqual(del_true.name, "True")
  286. class ArgumentsNodeTC(testlib.TestCase):
  287. def test_linenumbering(self):
  288. ast = abuilder.string_build('''
  289. def func(a,
  290. b): pass
  291. x = lambda x: None
  292. ''')
  293. self.assertEqual(ast['func'].args.fromlineno, 2)
  294. self.failIf(ast['func'].args.is_statement)
  295. xlambda = ast['x'].infer().next()
  296. self.assertEqual(xlambda.args.fromlineno, 4)
  297. self.assertEqual(xlambda.args.tolineno, 4)
  298. self.failIf(xlambda.args.is_statement)
  299. if sys.version_info < (3, 0):
  300. self.assertEqual(ast['func'].args.tolineno, 3)
  301. else:
  302. self.skipTest('FIXME http://bugs.python.org/issue10445 '
  303. '(no line number on function args)')
  304. class SliceNodeTC(testlib.TestCase):
  305. def test(self):
  306. for code in ('a[0]', 'a[1:3]', 'a[:-1:step]', 'a[:,newaxis]',
  307. 'a[newaxis,:]', 'del L[::2]', 'del A[1]', 'del Br[:]'):
  308. ast = abuilder.string_build(code).body[0]
  309. self.assertEqual(ast.as_string(), code)
  310. def test_slice_and_subscripts(self):
  311. code = """a[:1] = bord[2:]
  312. a[:1] = bord[2:]
  313. del bree[3:d]
  314. bord[2:]
  315. del av[d::f], a[df:]
  316. a[:1] = bord[2:]
  317. del SRC[::1,newaxis,1:]
  318. tous[vals] = 1010
  319. del thousand[key]
  320. del a[::2], a[:-1:step]
  321. del Fee.form[left:]
  322. aout.vals = miles.of_stuff
  323. del (ccok, (name.thing, foo.attrib.value)), Fee.form[left:]
  324. if all[1] == bord[0:]:
  325. pass\n\n"""
  326. ast = abuilder.string_build(code)
  327. self.assertEqual(ast.as_string(), code)
  328. class EllipsisNodeTC(testlib.TestCase):
  329. def test(self):
  330. ast = abuilder.string_build('a[...]').body[0]
  331. self.assertEqual(ast.as_string(), 'a[...]')
  332. if __name__ == '__main__':
  333. testlib.unittest_main()