Martin v. Löwis | 3bd071e | 2001-07-30 12:30:08 +0000 | [diff] [blame] | 1 | """ |
| 2 | Test cases for codeop.py |
| 3 | Nick Mathewson |
| 4 | """ |
Pablo Galindo | c5fc156 | 2020-04-22 23:29:27 +0100 | [diff] [blame] | 5 | import sys |
Martin v. Löwis | 3bd071e | 2001-07-30 12:30:08 +0000 | [diff] [blame] | 6 | import unittest |
Victor Stinner | 369a1cb | 2020-08-12 14:53:28 +0200 | [diff] [blame] | 7 | import warnings |
Victor Stinner | 1def775 | 2020-04-23 03:03:24 +0200 | [diff] [blame] | 8 | from test import support |
Hai Shi | 96a6a6d | 2020-07-09 21:25:10 +0800 | [diff] [blame] | 9 | from test.support import warnings_helper |
Martin v. Löwis | 3bd071e | 2001-07-30 12:30:08 +0000 | [diff] [blame] | 10 | |
Guido van Rossum | 4b499dd3 | 2003-02-13 22:07:59 +0000 | [diff] [blame] | 11 | from codeop import compile_command, PyCF_DONT_IMPLY_DEDENT |
Guido van Rossum | 34d1928 | 2007-08-09 01:03:29 +0000 | [diff] [blame] | 12 | import io |
Martin v. Löwis | 3bd071e | 2001-07-30 12:30:08 +0000 | [diff] [blame] | 13 | |
Victor Stinner | 1def775 | 2020-04-23 03:03:24 +0200 | [diff] [blame] | 14 | if support.is_jython: |
Samuele Pedroni | de9a0d3 | 2003-05-17 02:39:52 +0000 | [diff] [blame] | 15 | |
| 16 | def unify_callables(d): |
| 17 | for n,v in d.items(): |
Guido van Rossum | d59da4b | 2007-05-22 18:11:13 +0000 | [diff] [blame] | 18 | if hasattr(v, '__call__'): |
| 19 | d[n] = True |
Samuele Pedroni | de9a0d3 | 2003-05-17 02:39:52 +0000 | [diff] [blame] | 20 | return d |
| 21 | |
Martin v. Löwis | 3bd071e | 2001-07-30 12:30:08 +0000 | [diff] [blame] | 22 | class CodeopTests(unittest.TestCase): |
| 23 | |
| 24 | def assertValid(self, str, symbol='single'): |
| 25 | '''succeed iff str is a valid piece of code''' |
Victor Stinner | 1def775 | 2020-04-23 03:03:24 +0200 | [diff] [blame] | 26 | if support.is_jython: |
Samuele Pedroni | de9a0d3 | 2003-05-17 02:39:52 +0000 | [diff] [blame] | 27 | code = compile_command(str, "<input>", symbol) |
Benjamin Peterson | c9c0f20 | 2009-06-30 23:06:06 +0000 | [diff] [blame] | 28 | self.assertTrue(code) |
Samuele Pedroni | de9a0d3 | 2003-05-17 02:39:52 +0000 | [diff] [blame] | 29 | if symbol == "single": |
| 30 | d,r = {},{} |
Samuele Pedroni | 72c5c77 | 2003-05-17 12:51:10 +0000 | [diff] [blame] | 31 | saved_stdout = sys.stdout |
Guido van Rossum | 34d1928 | 2007-08-09 01:03:29 +0000 | [diff] [blame] | 32 | sys.stdout = io.StringIO() |
Samuele Pedroni | de9a0d3 | 2003-05-17 02:39:52 +0000 | [diff] [blame] | 33 | try: |
Georg Brandl | 7cae87c | 2006-09-06 06:51:57 +0000 | [diff] [blame] | 34 | exec(code, d) |
| 35 | exec(compile(str,"<input>","single"), r) |
Samuele Pedroni | de9a0d3 | 2003-05-17 02:39:52 +0000 | [diff] [blame] | 36 | finally: |
Samuele Pedroni | 72c5c77 | 2003-05-17 12:51:10 +0000 | [diff] [blame] | 37 | sys.stdout = saved_stdout |
Samuele Pedroni | de9a0d3 | 2003-05-17 02:39:52 +0000 | [diff] [blame] | 38 | elif symbol == 'eval': |
| 39 | ctx = {'a': 2} |
| 40 | d = { 'value': eval(code,ctx) } |
| 41 | r = { 'value': eval(str,ctx) } |
Ezio Melotti | b3aedd4 | 2010-11-20 19:04:17 +0000 | [diff] [blame] | 42 | self.assertEqual(unify_callables(r),unify_callables(d)) |
Samuele Pedroni | de9a0d3 | 2003-05-17 02:39:52 +0000 | [diff] [blame] | 43 | else: |
| 44 | expected = compile(str, "<input>", symbol, PyCF_DONT_IMPLY_DEDENT) |
Ezio Melotti | b3aedd4 | 2010-11-20 19:04:17 +0000 | [diff] [blame] | 45 | self.assertEqual(compile_command(str, "<input>", symbol), expected) |
Martin v. Löwis | 3bd071e | 2001-07-30 12:30:08 +0000 | [diff] [blame] | 46 | |
| 47 | def assertIncomplete(self, str, symbol='single'): |
| 48 | '''succeed iff str is the start of a valid piece of code''' |
Ezio Melotti | b3aedd4 | 2010-11-20 19:04:17 +0000 | [diff] [blame] | 49 | self.assertEqual(compile_command(str, symbol=symbol), None) |
Martin v. Löwis | 3bd071e | 2001-07-30 12:30:08 +0000 | [diff] [blame] | 50 | |
| 51 | def assertInvalid(self, str, symbol='single', is_syntax=1): |
| 52 | '''succeed iff str is the start of an invalid piece of code''' |
| 53 | try: |
| 54 | compile_command(str,symbol=symbol) |
Andrew Svetlov | 737fb89 | 2012-12-18 21:14:22 +0200 | [diff] [blame] | 55 | self.fail("No exception raised for invalid code") |
Martin v. Löwis | 3bd071e | 2001-07-30 12:30:08 +0000 | [diff] [blame] | 56 | except SyntaxError: |
Benjamin Peterson | c9c0f20 | 2009-06-30 23:06:06 +0000 | [diff] [blame] | 57 | self.assertTrue(is_syntax) |
Martin v. Löwis | 3bd071e | 2001-07-30 12:30:08 +0000 | [diff] [blame] | 58 | except OverflowError: |
Benjamin Peterson | c9c0f20 | 2009-06-30 23:06:06 +0000 | [diff] [blame] | 59 | self.assertTrue(not is_syntax) |
Martin v. Löwis | 3bd071e | 2001-07-30 12:30:08 +0000 | [diff] [blame] | 60 | |
| 61 | def test_valid(self): |
| 62 | av = self.assertValid |
Samuele Pedroni | de9a0d3 | 2003-05-17 02:39:52 +0000 | [diff] [blame] | 63 | |
| 64 | # special case |
Victor Stinner | 1def775 | 2020-04-23 03:03:24 +0200 | [diff] [blame] | 65 | if not support.is_jython: |
Ezio Melotti | b3aedd4 | 2010-11-20 19:04:17 +0000 | [diff] [blame] | 66 | self.assertEqual(compile_command(""), |
| 67 | compile("pass", "<input>", 'single', |
| 68 | PyCF_DONT_IMPLY_DEDENT)) |
| 69 | self.assertEqual(compile_command("\n"), |
| 70 | compile("pass", "<input>", 'single', |
| 71 | PyCF_DONT_IMPLY_DEDENT)) |
Samuele Pedroni | de9a0d3 | 2003-05-17 02:39:52 +0000 | [diff] [blame] | 72 | else: |
| 73 | av("") |
| 74 | av("\n") |
Tim Peters | f545baa | 2003-06-15 23:26:30 +0000 | [diff] [blame] | 75 | |
Samuele Pedroni | de9a0d3 | 2003-05-17 02:39:52 +0000 | [diff] [blame] | 76 | av("a = 1") |
| 77 | av("\na = 1") |
Martin v. Löwis | 3bd071e | 2001-07-30 12:30:08 +0000 | [diff] [blame] | 78 | av("a = 1\n") |
Samuele Pedroni | de9a0d3 | 2003-05-17 02:39:52 +0000 | [diff] [blame] | 79 | av("a = 1\n\n") |
| 80 | av("\n\na = 1\n\n") |
| 81 | |
Martin v. Löwis | 3bd071e | 2001-07-30 12:30:08 +0000 | [diff] [blame] | 82 | av("def x():\n pass\n") |
Samuele Pedroni | de9a0d3 | 2003-05-17 02:39:52 +0000 | [diff] [blame] | 83 | av("if 1:\n pass\n") |
| 84 | |
| 85 | av("\n\nif 1: pass\n") |
| 86 | av("\n\nif 1: pass\n\n") |
| 87 | |
| 88 | av("def x():\n\n pass\n") |
| 89 | av("def x():\n pass\n \n") |
| 90 | av("def x():\n pass\n \n") |
| 91 | |
Martin v. Löwis | 3bd071e | 2001-07-30 12:30:08 +0000 | [diff] [blame] | 92 | av("pass\n") |
| 93 | av("3**3\n") |
Samuele Pedroni | de9a0d3 | 2003-05-17 02:39:52 +0000 | [diff] [blame] | 94 | |
Martin v. Löwis | 3bd071e | 2001-07-30 12:30:08 +0000 | [diff] [blame] | 95 | av("if 9==3:\n pass\nelse:\n pass\n") |
Samuele Pedroni | de9a0d3 | 2003-05-17 02:39:52 +0000 | [diff] [blame] | 96 | av("if 1:\n pass\n if 1:\n pass\n else:\n pass\n") |
| 97 | |
Martin v. Löwis | 3bd071e | 2001-07-30 12:30:08 +0000 | [diff] [blame] | 98 | av("#a\n#b\na = 3\n") |
| 99 | av("#a\n\n \na=3\n") |
| 100 | av("a=3\n\n") |
Samuele Pedroni | de9a0d3 | 2003-05-17 02:39:52 +0000 | [diff] [blame] | 101 | av("a = 9+ \\\n3") |
Martin v. Löwis | 3bd071e | 2001-07-30 12:30:08 +0000 | [diff] [blame] | 102 | |
| 103 | av("3**3","eval") |
| 104 | av("(lambda z: \n z**3)","eval") |
Samuele Pedroni | de9a0d3 | 2003-05-17 02:39:52 +0000 | [diff] [blame] | 105 | |
| 106 | av("9+ \\\n3","eval") |
| 107 | av("9+ \\\n3\n","eval") |
| 108 | |
| 109 | av("\n\na**3","eval") |
| 110 | av("\n \na**3","eval") |
Martin v. Löwis | 3bd071e | 2001-07-30 12:30:08 +0000 | [diff] [blame] | 111 | av("#a\n#b\na**3","eval") |
Tim Peters | ab9ba27 | 2001-08-09 21:40:30 +0000 | [diff] [blame] | 112 | |
Frank Wierzbicki | 0d0367f | 2009-08-02 22:19:05 +0000 | [diff] [blame] | 113 | av("\n\na = 1\n\n") |
| 114 | av("\n\nif 1: a=1\n\n") |
| 115 | |
| 116 | av("if 1:\n pass\n if 1:\n pass\n else:\n pass\n") |
| 117 | av("#a\n\n \na=3\n\n") |
| 118 | |
| 119 | av("\n\na**3","eval") |
| 120 | av("\n \na**3","eval") |
| 121 | av("#a\n#b\na**3","eval") |
| 122 | |
| 123 | av("def f():\n try: pass\n finally: [x for x in (1,2)]\n") |
| 124 | av("def f():\n pass\n#foo\n") |
| 125 | av("@a.b.c\ndef f():\n pass\n") |
| 126 | |
Martin v. Löwis | 3bd071e | 2001-07-30 12:30:08 +0000 | [diff] [blame] | 127 | def test_incomplete(self): |
| 128 | ai = self.assertIncomplete |
Samuele Pedroni | de9a0d3 | 2003-05-17 02:39:52 +0000 | [diff] [blame] | 129 | |
Martin v. Löwis | 3bd071e | 2001-07-30 12:30:08 +0000 | [diff] [blame] | 130 | ai("(a **") |
Martin v. Löwis | 3bd071e | 2001-07-30 12:30:08 +0000 | [diff] [blame] | 131 | ai("(a,b,") |
| 132 | ai("(a,b,(") |
| 133 | ai("(a,b,(") |
Samuele Pedroni | de9a0d3 | 2003-05-17 02:39:52 +0000 | [diff] [blame] | 134 | ai("a = (") |
| 135 | ai("a = {") |
| 136 | ai("b + {") |
| 137 | |
Pablo Galindo | dbb2281 | 2021-02-09 20:07:38 +0000 | [diff] [blame] | 138 | ai("print([1,\n2,") |
| 139 | ai("print({1:1,\n2:3,") |
| 140 | ai("print((1,\n2,") |
| 141 | |
Samuele Pedroni | de9a0d3 | 2003-05-17 02:39:52 +0000 | [diff] [blame] | 142 | ai("if 9==3:\n pass\nelse:") |
Martin v. Löwis | 3bd071e | 2001-07-30 12:30:08 +0000 | [diff] [blame] | 143 | ai("if 9==3:\n pass\nelse:\n") |
| 144 | ai("if 9==3:\n pass\nelse:\n pass") |
Samuele Pedroni | de9a0d3 | 2003-05-17 02:39:52 +0000 | [diff] [blame] | 145 | ai("if 1:") |
| 146 | ai("if 1:\n") |
| 147 | ai("if 1:\n pass\n if 1:\n pass\n else:") |
Tim Peters | f545baa | 2003-06-15 23:26:30 +0000 | [diff] [blame] | 148 | ai("if 1:\n pass\n if 1:\n pass\n else:\n") |
| 149 | ai("if 1:\n pass\n if 1:\n pass\n else:\n pass") |
| 150 | |
Samuele Pedroni | de9a0d3 | 2003-05-17 02:39:52 +0000 | [diff] [blame] | 151 | ai("def x():") |
| 152 | ai("def x():\n") |
| 153 | ai("def x():\n\n") |
Tim Peters | ab9ba27 | 2001-08-09 21:40:30 +0000 | [diff] [blame] | 154 | |
Samuele Pedroni | de9a0d3 | 2003-05-17 02:39:52 +0000 | [diff] [blame] | 155 | ai("def x():\n pass") |
| 156 | ai("def x():\n pass\n ") |
| 157 | ai("def x():\n pass\n ") |
| 158 | ai("\n\ndef x():\n pass") |
| 159 | |
| 160 | ai("a = 9+ \\") |
| 161 | ai("a = 'a\\") |
| 162 | ai("a = '''xy") |
| 163 | |
| 164 | ai("","eval") |
| 165 | ai("\n","eval") |
Martin v. Löwis | 3bd071e | 2001-07-30 12:30:08 +0000 | [diff] [blame] | 166 | ai("(","eval") |
Martin v. Löwis | 3bd071e | 2001-07-30 12:30:08 +0000 | [diff] [blame] | 167 | ai("(9+","eval") |
| 168 | ai("9+ \\","eval") |
| 169 | ai("lambda z: \\","eval") |
| 170 | |
Frank Wierzbicki | 0d0367f | 2009-08-02 22:19:05 +0000 | [diff] [blame] | 171 | ai("if True:\n if True:\n if True: \n") |
| 172 | |
| 173 | ai("@a(") |
| 174 | ai("@a(b") |
| 175 | ai("@a(b,") |
| 176 | ai("@a(b,c") |
| 177 | ai("@a(b,c,") |
| 178 | |
| 179 | ai("from a import (") |
| 180 | ai("from a import (b") |
| 181 | ai("from a import (b,") |
| 182 | ai("from a import (b,c") |
| 183 | ai("from a import (b,c,") |
| 184 | |
Miss Islington (bot) | 280425d | 2021-06-23 03:02:40 -0700 | [diff] [blame^] | 185 | ai("[") |
| 186 | ai("[a") |
| 187 | ai("[a,") |
| 188 | ai("[a,b") |
| 189 | ai("[a,b,") |
Frank Wierzbicki | 0d0367f | 2009-08-02 22:19:05 +0000 | [diff] [blame] | 190 | |
Miss Islington (bot) | 280425d | 2021-06-23 03:02:40 -0700 | [diff] [blame^] | 191 | ai("{") |
| 192 | ai("{a") |
| 193 | ai("{a:") |
| 194 | ai("{a:b") |
| 195 | ai("{a:b,") |
| 196 | ai("{a:b,c") |
| 197 | ai("{a:b,c:") |
| 198 | ai("{a:b,c:d") |
| 199 | ai("{a:b,c:d,") |
Frank Wierzbicki | 0d0367f | 2009-08-02 22:19:05 +0000 | [diff] [blame] | 200 | |
| 201 | ai("a(") |
| 202 | ai("a(b") |
| 203 | ai("a(b,") |
| 204 | ai("a(b,c") |
| 205 | ai("a(b,c,") |
| 206 | |
| 207 | ai("a[") |
| 208 | ai("a[b") |
| 209 | ai("a[b,") |
| 210 | ai("a[b:") |
| 211 | ai("a[b:c") |
| 212 | ai("a[b:c:") |
| 213 | ai("a[b:c:d") |
| 214 | |
| 215 | ai("def a(") |
| 216 | ai("def a(b") |
| 217 | ai("def a(b,") |
| 218 | ai("def a(b,c") |
| 219 | ai("def a(b,c,") |
| 220 | |
| 221 | ai("(") |
| 222 | ai("(a") |
| 223 | ai("(a,") |
| 224 | ai("(a,b") |
| 225 | ai("(a,b,") |
| 226 | |
| 227 | ai("if a:\n pass\nelif b:") |
| 228 | ai("if a:\n pass\nelif b:\n pass\nelse:") |
| 229 | |
| 230 | ai("while a:") |
| 231 | ai("while a:\n pass\nelse:") |
| 232 | |
| 233 | ai("for a in b:") |
| 234 | ai("for a in b:\n pass\nelse:") |
| 235 | |
| 236 | ai("try:") |
| 237 | ai("try:\n pass\nexcept:") |
| 238 | ai("try:\n pass\nfinally:") |
| 239 | ai("try:\n pass\nexcept:\n pass\nfinally:") |
| 240 | |
| 241 | ai("with a:") |
| 242 | ai("with a as b:") |
| 243 | |
| 244 | ai("class a:") |
| 245 | ai("class a(") |
| 246 | ai("class a(b") |
| 247 | ai("class a(b,") |
| 248 | ai("class a():") |
| 249 | |
| 250 | ai("[x for") |
| 251 | ai("[x for x in") |
| 252 | ai("[x for x in (") |
| 253 | |
| 254 | ai("(x for") |
| 255 | ai("(x for x in") |
| 256 | ai("(x for x in (") |
| 257 | |
Martin v. Löwis | 3bd071e | 2001-07-30 12:30:08 +0000 | [diff] [blame] | 258 | def test_invalid(self): |
| 259 | ai = self.assertInvalid |
| 260 | ai("a b") |
Samuele Pedroni | de9a0d3 | 2003-05-17 02:39:52 +0000 | [diff] [blame] | 261 | |
| 262 | ai("a @") |
| 263 | ai("a b @") |
| 264 | ai("a ** @") |
Tim Peters | f545baa | 2003-06-15 23:26:30 +0000 | [diff] [blame] | 265 | |
Martin v. Löwis | 3bd071e | 2001-07-30 12:30:08 +0000 | [diff] [blame] | 266 | ai("a = ") |
| 267 | ai("a = 9 +") |
| 268 | |
Samuele Pedroni | de9a0d3 | 2003-05-17 02:39:52 +0000 | [diff] [blame] | 269 | ai("def x():\n\npass\n") |
| 270 | |
| 271 | ai("\n\n if 1: pass\n\npass") |
| 272 | |
| 273 | ai("a = 9+ \\\n") |
| 274 | ai("a = 'a\\ ") |
| 275 | ai("a = 'a\\\n") |
| 276 | |
Martin v. Löwis | 3bd071e | 2001-07-30 12:30:08 +0000 | [diff] [blame] | 277 | ai("a = 1","eval") |
Martin v. Löwis | 3bd071e | 2001-07-30 12:30:08 +0000 | [diff] [blame] | 278 | ai("]","eval") |
| 279 | ai("())","eval") |
| 280 | ai("[}","eval") |
| 281 | ai("9+","eval") |
| 282 | ai("lambda z:","eval") |
| 283 | ai("a b","eval") |
| 284 | |
Frank Wierzbicki | 0d0367f | 2009-08-02 22:19:05 +0000 | [diff] [blame] | 285 | ai("return 2.3") |
| 286 | ai("if (a == 1 and b = 2): pass") |
| 287 | |
| 288 | ai("del 1") |
Frank Wierzbicki | 0d0367f | 2009-08-02 22:19:05 +0000 | [diff] [blame] | 289 | ai("del (1,)") |
| 290 | ai("del [1]") |
| 291 | ai("del '1'") |
| 292 | |
| 293 | ai("[i for i in range(10)] = (1, 2, 3)") |
| 294 | |
Pablo Galindo | 5b956ca | 2020-05-11 01:41:26 +0100 | [diff] [blame] | 295 | def test_invalid_exec(self): |
| 296 | ai = self.assertInvalid |
| 297 | ai("raise = 4", symbol="exec") |
| 298 | ai('def a-b', symbol='exec') |
| 299 | ai('await?', symbol='exec') |
| 300 | ai('=!=', symbol='exec') |
| 301 | ai('a await raise b', symbol='exec') |
| 302 | ai('a await raise b?+1', symbol='exec') |
| 303 | |
Martin v. Löwis | 3bd071e | 2001-07-30 12:30:08 +0000 | [diff] [blame] | 304 | def test_filename(self): |
Ezio Melotti | b3aedd4 | 2010-11-20 19:04:17 +0000 | [diff] [blame] | 305 | self.assertEqual(compile_command("a = 1\n", "abc").co_filename, |
| 306 | compile("a = 1\n", "abc", 'single').co_filename) |
| 307 | self.assertNotEqual(compile_command("a = 1\n", "abc").co_filename, |
| 308 | compile("a = 1\n", "def", 'single').co_filename) |
Martin v. Löwis | 3bd071e | 2001-07-30 12:30:08 +0000 | [diff] [blame] | 309 | |
Cheryl Sabella | 052d3fc | 2020-06-04 19:40:24 -0400 | [diff] [blame] | 310 | def test_warning(self): |
| 311 | # Test that the warning is only returned once. |
Terry Jan Reedy | c818b15 | 2020-08-13 13:18:49 -0400 | [diff] [blame] | 312 | with warnings_helper.check_warnings( |
| 313 | (".*literal", SyntaxWarning), |
| 314 | (".*invalid", DeprecationWarning), |
| 315 | ) as w: |
| 316 | compile_command(r"'\e' is 0") |
| 317 | self.assertEqual(len(w.warnings), 2) |
Fred Drake | 2e2be37 | 2001-09-20 21:33:42 +0000 | [diff] [blame] | 318 | |
Victor Stinner | 369a1cb | 2020-08-12 14:53:28 +0200 | [diff] [blame] | 319 | # bpo-41520: check SyntaxWarning treated as an SyntaxError |
Terry Jan Reedy | c818b15 | 2020-08-13 13:18:49 -0400 | [diff] [blame] | 320 | with warnings.catch_warnings(), self.assertRaises(SyntaxError): |
Victor Stinner | 369a1cb | 2020-08-12 14:53:28 +0200 | [diff] [blame] | 321 | warnings.simplefilter('error', SyntaxWarning) |
Terry Jan Reedy | c818b15 | 2020-08-13 13:18:49 -0400 | [diff] [blame] | 322 | compile_command('1 is 1', symbol='exec') |
Victor Stinner | 369a1cb | 2020-08-12 14:53:28 +0200 | [diff] [blame] | 323 | |
| 324 | |
Fred Drake | 2e2be37 | 2001-09-20 21:33:42 +0000 | [diff] [blame] | 325 | if __name__ == "__main__": |
Zachary Ware | 38c707e | 2015-04-13 15:00:43 -0500 | [diff] [blame] | 326 | unittest.main() |