test_codeop.py 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. """
  2. Test cases for codeop.py
  3. Nick Mathewson
  4. """
  5. import sys
  6. import unittest
  7. import warnings
  8. from test import support
  9. from test.support import warnings_helper
  10. from codeop import compile_command, PyCF_DONT_IMPLY_DEDENT
  11. import io
  12. if support.is_jython:
  13. def unify_callables(d):
  14. for n,v in d.items():
  15. if hasattr(v, '__call__'):
  16. d[n] = True
  17. return d
  18. class CodeopTests(unittest.TestCase):
  19. def assertValid(self, str, symbol='single'):
  20. '''succeed iff str is a valid piece of code'''
  21. if support.is_jython:
  22. code = compile_command(str, "<input>", symbol)
  23. self.assertTrue(code)
  24. if symbol == "single":
  25. d,r = {},{}
  26. saved_stdout = sys.stdout
  27. sys.stdout = io.StringIO()
  28. try:
  29. exec(code, d)
  30. exec(compile(str,"<input>","single"), r)
  31. finally:
  32. sys.stdout = saved_stdout
  33. elif symbol == 'eval':
  34. ctx = {'a': 2}
  35. d = { 'value': eval(code,ctx) }
  36. r = { 'value': eval(str,ctx) }
  37. self.assertEqual(unify_callables(r),unify_callables(d))
  38. else:
  39. expected = compile(str, "<input>", symbol, PyCF_DONT_IMPLY_DEDENT)
  40. self.assertEqual(compile_command(str, "<input>", symbol), expected)
  41. def assertIncomplete(self, str, symbol='single'):
  42. '''succeed iff str is the start of a valid piece of code'''
  43. self.assertEqual(compile_command(str, symbol=symbol), None)
  44. def assertInvalid(self, str, symbol='single', is_syntax=1):
  45. '''succeed iff str is the start of an invalid piece of code'''
  46. try:
  47. compile_command(str,symbol=symbol)
  48. self.fail("No exception raised for invalid code")
  49. except SyntaxError:
  50. self.assertTrue(is_syntax)
  51. except OverflowError:
  52. self.assertTrue(not is_syntax)
  53. def test_valid(self):
  54. av = self.assertValid
  55. # special case
  56. if not support.is_jython:
  57. self.assertEqual(compile_command(""),
  58. compile("pass", "<input>", 'single',
  59. PyCF_DONT_IMPLY_DEDENT))
  60. self.assertEqual(compile_command("\n"),
  61. compile("pass", "<input>", 'single',
  62. PyCF_DONT_IMPLY_DEDENT))
  63. else:
  64. av("")
  65. av("\n")
  66. av("a = 1")
  67. av("\na = 1")
  68. av("a = 1\n")
  69. av("a = 1\n\n")
  70. av("\n\na = 1\n\n")
  71. av("def x():\n pass\n")
  72. av("if 1:\n pass\n")
  73. av("\n\nif 1: pass\n")
  74. av("\n\nif 1: pass\n\n")
  75. av("def x():\n\n pass\n")
  76. av("def x():\n pass\n \n")
  77. av("def x():\n pass\n \n")
  78. av("pass\n")
  79. av("3**3\n")
  80. av("if 9==3:\n pass\nelse:\n pass\n")
  81. av("if 1:\n pass\n if 1:\n pass\n else:\n pass\n")
  82. av("#a\n#b\na = 3\n")
  83. av("#a\n\n \na=3\n")
  84. av("a=3\n\n")
  85. av("a = 9+ \\\n3")
  86. av("3**3","eval")
  87. av("(lambda z: \n z**3)","eval")
  88. av("9+ \\\n3","eval")
  89. av("9+ \\\n3\n","eval")
  90. av("\n\na**3","eval")
  91. av("\n \na**3","eval")
  92. av("#a\n#b\na**3","eval")
  93. av("\n\na = 1\n\n")
  94. av("\n\nif 1: a=1\n\n")
  95. av("if 1:\n pass\n if 1:\n pass\n else:\n pass\n")
  96. av("#a\n\n \na=3\n\n")
  97. av("\n\na**3","eval")
  98. av("\n \na**3","eval")
  99. av("#a\n#b\na**3","eval")
  100. av("def f():\n try: pass\n finally: [x for x in (1,2)]\n")
  101. av("def f():\n pass\n#foo\n")
  102. av("@a.b.c\ndef f():\n pass\n")
  103. def test_incomplete(self):
  104. ai = self.assertIncomplete
  105. ai("(a **")
  106. ai("(a,b,")
  107. ai("(a,b,(")
  108. ai("(a,b,(")
  109. ai("a = (")
  110. ai("a = {")
  111. ai("b + {")
  112. ai("print([1,\n2,")
  113. ai("print({1:1,\n2:3,")
  114. ai("print((1,\n2,")
  115. ai("if 9==3:\n pass\nelse:")
  116. ai("if 9==3:\n pass\nelse:\n")
  117. ai("if 9==3:\n pass\nelse:\n pass")
  118. ai("if 1:")
  119. ai("if 1:\n")
  120. ai("if 1:\n pass\n if 1:\n pass\n else:")
  121. ai("if 1:\n pass\n if 1:\n pass\n else:\n")
  122. ai("if 1:\n pass\n if 1:\n pass\n else:\n pass")
  123. ai("def x():")
  124. ai("def x():\n")
  125. ai("def x():\n\n")
  126. ai("def x():\n pass")
  127. ai("def x():\n pass\n ")
  128. ai("def x():\n pass\n ")
  129. ai("\n\ndef x():\n pass")
  130. ai("a = 9+ \\")
  131. ai("a = 'a\\")
  132. ai("a = '''xy")
  133. ai("","eval")
  134. ai("\n","eval")
  135. ai("(","eval")
  136. ai("(9+","eval")
  137. ai("9+ \\","eval")
  138. ai("lambda z: \\","eval")
  139. ai("if True:\n if True:\n if True: \n")
  140. ai("@a(")
  141. ai("@a(b")
  142. ai("@a(b,")
  143. ai("@a(b,c")
  144. ai("@a(b,c,")
  145. ai("from a import (")
  146. ai("from a import (b")
  147. ai("from a import (b,")
  148. ai("from a import (b,c")
  149. ai("from a import (b,c,")
  150. ai("[")
  151. ai("[a")
  152. ai("[a,")
  153. ai("[a,b")
  154. ai("[a,b,")
  155. ai("{")
  156. ai("{a")
  157. ai("{a:")
  158. ai("{a:b")
  159. ai("{a:b,")
  160. ai("{a:b,c")
  161. ai("{a:b,c:")
  162. ai("{a:b,c:d")
  163. ai("{a:b,c:d,")
  164. ai("a(")
  165. ai("a(b")
  166. ai("a(b,")
  167. ai("a(b,c")
  168. ai("a(b,c,")
  169. ai("a[")
  170. ai("a[b")
  171. ai("a[b,")
  172. ai("a[b:")
  173. ai("a[b:c")
  174. ai("a[b:c:")
  175. ai("a[b:c:d")
  176. ai("def a(")
  177. ai("def a(b")
  178. ai("def a(b,")
  179. ai("def a(b,c")
  180. ai("def a(b,c,")
  181. ai("(")
  182. ai("(a")
  183. ai("(a,")
  184. ai("(a,b")
  185. ai("(a,b,")
  186. ai("if a:\n pass\nelif b:")
  187. ai("if a:\n pass\nelif b:\n pass\nelse:")
  188. ai("while a:")
  189. ai("while a:\n pass\nelse:")
  190. ai("for a in b:")
  191. ai("for a in b:\n pass\nelse:")
  192. ai("try:")
  193. ai("try:\n pass\nexcept:")
  194. ai("try:\n pass\nfinally:")
  195. ai("try:\n pass\nexcept:\n pass\nfinally:")
  196. ai("with a:")
  197. ai("with a as b:")
  198. ai("class a:")
  199. ai("class a(")
  200. ai("class a(b")
  201. ai("class a(b,")
  202. ai("class a():")
  203. ai("[x for")
  204. ai("[x for x in")
  205. ai("[x for x in (")
  206. ai("(x for")
  207. ai("(x for x in")
  208. ai("(x for x in (")
  209. def test_invalid(self):
  210. ai = self.assertInvalid
  211. ai("a b")
  212. ai("a @")
  213. ai("a b @")
  214. ai("a ** @")
  215. ai("a = ")
  216. ai("a = 9 +")
  217. ai("def x():\n\npass\n")
  218. ai("\n\n if 1: pass\n\npass")
  219. ai("a = 9+ \\\n")
  220. ai("a = 'a\\ ")
  221. ai("a = 'a\\\n")
  222. ai("a = 1","eval")
  223. ai("]","eval")
  224. ai("())","eval")
  225. ai("[}","eval")
  226. ai("9+","eval")
  227. ai("lambda z:","eval")
  228. ai("a b","eval")
  229. ai("return 2.3")
  230. ai("if (a == 1 and b = 2): pass")
  231. ai("del 1")
  232. ai("del (1,)")
  233. ai("del [1]")
  234. ai("del '1'")
  235. ai("[i for i in range(10)] = (1, 2, 3)")
  236. def test_invalid_exec(self):
  237. ai = self.assertInvalid
  238. ai("raise = 4", symbol="exec")
  239. ai('def a-b', symbol='exec')
  240. ai('await?', symbol='exec')
  241. ai('=!=', symbol='exec')
  242. ai('a await raise b', symbol='exec')
  243. ai('a await raise b?+1', symbol='exec')
  244. def test_filename(self):
  245. self.assertEqual(compile_command("a = 1\n", "abc").co_filename,
  246. compile("a = 1\n", "abc", 'single').co_filename)
  247. self.assertNotEqual(compile_command("a = 1\n", "abc").co_filename,
  248. compile("a = 1\n", "def", 'single').co_filename)
  249. def test_warning(self):
  250. # Test that the warning is only returned once.
  251. with warnings_helper.check_warnings(
  252. (".*literal", SyntaxWarning),
  253. (".*invalid", DeprecationWarning),
  254. ) as w:
  255. compile_command(r"'\e' is 0")
  256. self.assertEqual(len(w.warnings), 2)
  257. # bpo-41520: check SyntaxWarning treated as an SyntaxError
  258. with warnings.catch_warnings(), self.assertRaises(SyntaxError):
  259. warnings.simplefilter('error', SyntaxWarning)
  260. compile_command('1 is 1', symbol='exec')
  261. # Check DeprecationWarning treated as an SyntaxError
  262. with warnings.catch_warnings(), self.assertRaises(SyntaxError):
  263. warnings.simplefilter('error', DeprecationWarning)
  264. compile_command(r"'\e'", symbol='exec')
  265. def test_incomplete_warning(self):
  266. with warnings.catch_warnings(record=True) as w:
  267. warnings.simplefilter('always')
  268. self.assertIncomplete("'\\e' + (")
  269. self.assertEqual(w, [])
  270. def test_invalid_warning(self):
  271. with warnings.catch_warnings(record=True) as w:
  272. warnings.simplefilter('always')
  273. self.assertInvalid("'\\e' 1")
  274. self.assertEqual(len(w), 1)
  275. self.assertEqual(w[0].category, DeprecationWarning)
  276. self.assertRegex(str(w[0].message), 'invalid escape sequence')
  277. self.assertEqual(w[0].filename, '<input>')
  278. if __name__ == "__main__":
  279. unittest.main()