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_python3.py 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. # Copyright (c) 2013-2016 Claudiu Popa <pcmanticore@gmail.com>
  2. # Copyright (c) 2014 Google, Inc.
  3. # Copyright (c) 2015-2016 Cara Vinson <ceridwenv@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. from textwrap import dedent
  7. import unittest
  8. from astroid import nodes
  9. from astroid.node_classes import Assign, Expr, YieldFrom, Name, Const
  10. from astroid.builder import AstroidBuilder, extract_node
  11. from astroid.scoped_nodes import ClassDef, FunctionDef
  12. from astroid.test_utils import require_version
  13. class Python3TC(unittest.TestCase):
  14. @classmethod
  15. def setUpClass(cls):
  16. cls.builder = AstroidBuilder()
  17. @require_version('3.4')
  18. def test_starred_notation(self):
  19. astroid = self.builder.string_build("*a, b = [1, 2, 3]", 'test', 'test')
  20. # Get the star node
  21. node = next(next(next(astroid.get_children()).get_children()).get_children())
  22. self.assertTrue(isinstance(node.assign_type(), Assign))
  23. @require_version('3.4')
  24. def test_yield_from(self):
  25. body = dedent("""
  26. def func():
  27. yield from iter([1, 2])
  28. """)
  29. astroid = self.builder.string_build(body)
  30. func = astroid.body[0]
  31. self.assertIsInstance(func, FunctionDef)
  32. yieldfrom_stmt = func.body[0]
  33. self.assertIsInstance(yieldfrom_stmt, Expr)
  34. self.assertIsInstance(yieldfrom_stmt.value, YieldFrom)
  35. self.assertEqual(yieldfrom_stmt.as_string(),
  36. 'yield from iter([1, 2])')
  37. @require_version('3.4')
  38. def test_yield_from_is_generator(self):
  39. body = dedent("""
  40. def func():
  41. yield from iter([1, 2])
  42. """)
  43. astroid = self.builder.string_build(body)
  44. func = astroid.body[0]
  45. self.assertIsInstance(func, FunctionDef)
  46. self.assertTrue(func.is_generator())
  47. @require_version('3.4')
  48. def test_yield_from_as_string(self):
  49. body = dedent("""
  50. def func():
  51. yield from iter([1, 2])
  52. value = yield from other()
  53. """)
  54. astroid = self.builder.string_build(body)
  55. func = astroid.body[0]
  56. self.assertEqual(func.as_string().strip(), body.strip())
  57. # metaclass tests
  58. @require_version('3.4')
  59. def test_simple_metaclass(self):
  60. astroid = self.builder.string_build("class Test(metaclass=type): pass")
  61. klass = astroid.body[0]
  62. metaclass = klass.metaclass()
  63. self.assertIsInstance(metaclass, ClassDef)
  64. self.assertEqual(metaclass.name, 'type')
  65. @require_version('3.4')
  66. def test_metaclass_error(self):
  67. astroid = self.builder.string_build("class Test(metaclass=typ): pass")
  68. klass = astroid.body[0]
  69. self.assertFalse(klass.metaclass())
  70. @require_version('3.4')
  71. def test_metaclass_imported(self):
  72. astroid = self.builder.string_build(dedent("""
  73. from abc import ABCMeta
  74. class Test(metaclass=ABCMeta): pass"""))
  75. klass = astroid.body[1]
  76. metaclass = klass.metaclass()
  77. self.assertIsInstance(metaclass, ClassDef)
  78. self.assertEqual(metaclass.name, 'ABCMeta')
  79. @require_version('3.4')
  80. def test_metaclass_multiple_keywords(self):
  81. astroid = self.builder.string_build("class Test(magic=None, metaclass=type): pass")
  82. klass = astroid.body[0]
  83. metaclass = klass.metaclass()
  84. self.assertIsInstance(metaclass, ClassDef)
  85. self.assertEqual(metaclass.name, 'type')
  86. @require_version('3.4')
  87. def test_as_string(self):
  88. body = dedent("""
  89. from abc import ABCMeta
  90. class Test(metaclass=ABCMeta): pass""")
  91. astroid = self.builder.string_build(body)
  92. klass = astroid.body[1]
  93. self.assertEqual(klass.as_string(),
  94. '\n\nclass Test(metaclass=ABCMeta):\n pass\n')
  95. @require_version('3.4')
  96. def test_old_syntax_works(self):
  97. astroid = self.builder.string_build(dedent("""
  98. class Test:
  99. __metaclass__ = type
  100. class SubTest(Test): pass
  101. """))
  102. klass = astroid['SubTest']
  103. metaclass = klass.metaclass()
  104. self.assertIsNone(metaclass)
  105. @require_version('3.4')
  106. def test_metaclass_yes_leak(self):
  107. astroid = self.builder.string_build(dedent("""
  108. # notice `ab` instead of `abc`
  109. from ab import ABCMeta
  110. class Meta(metaclass=ABCMeta): pass
  111. """))
  112. klass = astroid['Meta']
  113. self.assertIsNone(klass.metaclass())
  114. @require_version('3.4')
  115. def test_parent_metaclass(self):
  116. astroid = self.builder.string_build(dedent("""
  117. from abc import ABCMeta
  118. class Test(metaclass=ABCMeta): pass
  119. class SubTest(Test): pass
  120. """))
  121. klass = astroid['SubTest']
  122. self.assertTrue(klass.newstyle)
  123. metaclass = klass.metaclass()
  124. self.assertIsInstance(metaclass, ClassDef)
  125. self.assertEqual(metaclass.name, 'ABCMeta')
  126. @require_version('3.4')
  127. def test_metaclass_ancestors(self):
  128. astroid = self.builder.string_build(dedent("""
  129. from abc import ABCMeta
  130. class FirstMeta(metaclass=ABCMeta): pass
  131. class SecondMeta(metaclass=type):
  132. pass
  133. class Simple:
  134. pass
  135. class FirstImpl(FirstMeta): pass
  136. class SecondImpl(FirstImpl): pass
  137. class ThirdImpl(Simple, SecondMeta):
  138. pass
  139. """))
  140. classes = {
  141. 'ABCMeta': ('FirstImpl', 'SecondImpl'),
  142. 'type': ('ThirdImpl', )
  143. }
  144. for metaclass, names in classes.items():
  145. for name in names:
  146. impl = astroid[name]
  147. meta = impl.metaclass()
  148. self.assertIsInstance(meta, ClassDef)
  149. self.assertEqual(meta.name, metaclass)
  150. @require_version('3.4')
  151. def test_annotation_support(self):
  152. astroid = self.builder.string_build(dedent("""
  153. def test(a: int, b: str, c: None, d, e,
  154. *args: float, **kwargs: int)->int:
  155. pass
  156. """))
  157. func = astroid['test']
  158. self.assertIsInstance(func.args.varargannotation, Name)
  159. self.assertEqual(func.args.varargannotation.name, 'float')
  160. self.assertIsInstance(func.args.kwargannotation, Name)
  161. self.assertEqual(func.args.kwargannotation.name, 'int')
  162. self.assertIsInstance(func.returns, Name)
  163. self.assertEqual(func.returns.name, 'int')
  164. arguments = func.args
  165. self.assertIsInstance(arguments.annotations[0], Name)
  166. self.assertEqual(arguments.annotations[0].name, 'int')
  167. self.assertIsInstance(arguments.annotations[1], Name)
  168. self.assertEqual(arguments.annotations[1].name, 'str')
  169. self.assertIsInstance(arguments.annotations[2], Const)
  170. self.assertIsNone(arguments.annotations[2].value)
  171. self.assertIsNone(arguments.annotations[3])
  172. self.assertIsNone(arguments.annotations[4])
  173. astroid = self.builder.string_build(dedent("""
  174. def test(a: int=1, b: str=2):
  175. pass
  176. """))
  177. func = astroid['test']
  178. self.assertIsInstance(func.args.annotations[0], Name)
  179. self.assertEqual(func.args.annotations[0].name, 'int')
  180. self.assertIsInstance(func.args.annotations[1], Name)
  181. self.assertEqual(func.args.annotations[1].name, 'str')
  182. self.assertIsNone(func.returns)
  183. @require_version('3.4')
  184. def test_kwonlyargs_annotations_supper(self):
  185. node = self.builder.string_build(dedent("""
  186. def test(*, a: int, b: str, c: None, d, e):
  187. pass
  188. """))
  189. func = node['test']
  190. arguments = func.args
  191. self.assertIsInstance(arguments.kwonlyargs_annotations[0], Name)
  192. self.assertEqual(arguments.kwonlyargs_annotations[0].name, 'int')
  193. self.assertIsInstance(arguments.kwonlyargs_annotations[1], Name)
  194. self.assertEqual(arguments.kwonlyargs_annotations[1].name, 'str')
  195. self.assertIsInstance(arguments.kwonlyargs_annotations[2], Const)
  196. self.assertIsNone(arguments.kwonlyargs_annotations[2].value)
  197. self.assertIsNone(arguments.kwonlyargs_annotations[3])
  198. self.assertIsNone(arguments.kwonlyargs_annotations[4])
  199. @require_version('3.4')
  200. def test_annotation_as_string(self):
  201. code1 = dedent('''
  202. def test(a, b:int=4, c=2, f:'lala'=4)->2:
  203. pass''')
  204. code2 = dedent('''
  205. def test(a:typing.Generic[T], c:typing.Any=24)->typing.Iterable:
  206. pass''')
  207. for code in (code1, code2):
  208. func = extract_node(code)
  209. self.assertEqual(func.as_string(), code)
  210. @require_version('3.5')
  211. def test_unpacking_in_dicts(self):
  212. code = "{'x': 1, **{'y': 2}}"
  213. node = extract_node(code)
  214. self.assertEqual(node.as_string(), code)
  215. keys = [key for (key, _) in node.items]
  216. self.assertIsInstance(keys[0], nodes.Const)
  217. self.assertIsInstance(keys[1], nodes.DictUnpack)
  218. @require_version('3.5')
  219. def test_nested_unpacking_in_dicts(self):
  220. code = "{'x': 1, **{'y': 2, **{'z': 3}}}"
  221. node = extract_node(code)
  222. self.assertEqual(node.as_string(), code)
  223. @require_version('3.5')
  224. def test_unpacking_in_dict_getitem(self):
  225. node = extract_node('{1:2, **{2:3, 3:4}, **{5: 6}}')
  226. for key, expected in ((1, 2), (2, 3), (3, 4), (5, 6)):
  227. value = node.getitem(nodes.Const(key))
  228. self.assertIsInstance(value, nodes.Const)
  229. self.assertEqual(value.value, expected)
  230. @require_version('3.6')
  231. def test_format_string(self):
  232. code = "f'{greetings} {person}'"
  233. node = extract_node(code)
  234. self.assertEqual(node.as_string(), code)
  235. @require_version('3.6')
  236. def test_underscores_in_numeral_literal(self):
  237. pairs = [
  238. ('10_1000', 101000),
  239. ('10_000_000', 10000000),
  240. ('0x_FF_FF', 65535),
  241. ]
  242. for value, expected in pairs:
  243. node = extract_node(value)
  244. inferred = next(node.infer())
  245. self.assertIsInstance(inferred, nodes.Const)
  246. self.assertEqual(inferred.value, expected)
  247. @require_version('3.6')
  248. def test_async_comprehensions(self):
  249. async_comprehensions = [
  250. extract_node("async def f(): return __([i async for i in aiter() if i % 2])"),
  251. extract_node("async def f(): return __({i async for i in aiter() if i % 2})"),
  252. extract_node("async def f(): return __((i async for i in aiter() if i % 2))"),
  253. extract_node("async def f(): return __({i: i async for i in aiter() if i % 2})")
  254. ]
  255. non_async_comprehensions = [
  256. extract_node("async def f(): return __({i: i for i in iter() if i % 2})")
  257. ]
  258. for comp in async_comprehensions:
  259. self.assertTrue(comp.generators[0].is_async)
  260. for comp in non_async_comprehensions:
  261. self.assertFalse(comp.generators[0].is_async)
  262. @require_version('3.7')
  263. def test_async_comprehensions_outside_coroutine(self):
  264. # When async and await will become keywords, async comprehensions
  265. # will be allowed outside of coroutines body
  266. comprehensions = [
  267. "[i async for i in aiter() if condition(i)]",
  268. "[await fun() for fun in funcs]",
  269. "{await fun() for fun in funcs}",
  270. "{fun: await fun() for fun in funcs}",
  271. "[await fun() for fun in funcs if await smth]",
  272. "{await fun() for fun in funcs if await smth}",
  273. "{fun: await fun() for fun in funcs if await smth}",
  274. "[await fun() async for fun in funcs]",
  275. "{await fun() async for fun in funcs}",
  276. "{fun: await fun() async for fun in funcs}",
  277. "[await fun() async for fun in funcs if await smth]",
  278. "{await fun() async for fun in funcs if await smth}",
  279. "{fun: await fun() async for fun in funcs if await smth}",
  280. ]
  281. for comp in comprehensions:
  282. node = extract_node(comp)
  283. self.assertTrue(node.generators[0].is_async)
  284. @require_version('3.6')
  285. def test_async_comprehensions_as_string(self):
  286. func_bodies = [
  287. "return [i async for i in aiter() if condition(i)]",
  288. "return [await fun() for fun in funcs]",
  289. "return {await fun() for fun in funcs}",
  290. "return {fun: await fun() for fun in funcs}",
  291. "return [await fun() for fun in funcs if await smth]",
  292. "return {await fun() for fun in funcs if await smth}",
  293. "return {fun: await fun() for fun in funcs if await smth}",
  294. "return [await fun() async for fun in funcs]",
  295. "return {await fun() async for fun in funcs}",
  296. "return {fun: await fun() async for fun in funcs}",
  297. "return [await fun() async for fun in funcs if await smth]",
  298. "return {await fun() async for fun in funcs if await smth}",
  299. "return {fun: await fun() async for fun in funcs if await smth}",
  300. ]
  301. for func_body in func_bodies:
  302. code = dedent('''
  303. async def f():
  304. {}'''.format(func_body))
  305. func = extract_node(code)
  306. self.assertEqual(func.as_string().strip(), code.strip())
  307. if __name__ == '__main__':
  308. unittest.main()