1 import parser 2 import unittest 3 import sys 4 from test import test_support 5 6 # 7 # First, we test that we can generate trees from valid source fragments, 8 # and that these valid trees are indeed allowed by the tree-loading side 9 # of the parser module. 10 # 11 12 class RoundtripLegalSyntaxTestCase(unittest.TestCase): 13 14 def roundtrip(self, f, s): 15 st1 = f(s) 16 t = st1.totuple() 17 try: 18 st2 = parser.sequence2st(t) 19 except parser.ParserError, why: 20 self.fail("could not roundtrip %r: %s" % (s, why)) 21 22 self.assertEqual(t, st2.totuple(), 23 "could not re-generate syntax tree") 24 25 def check_expr(self, s): 26 self.roundtrip(parser.expr, s) 27 28 def test_flags_passed(self): 29 # The unicode literals flags has to be passed from the paser to AST 30 # generation. 31 suite = parser.suite("from __future__ import unicode_literals; x = ''") 32 code = suite.compile() 33 scope = {} 34 exec code in scope 35 self.assertIsInstance(scope["x"], unicode) 36 37 def check_suite(self, s): 38 self.roundtrip(parser.suite, s) 39 40 def test_yield_statement(self): 41 self.check_suite("def f(): yield 1") 42 self.check_suite("def f(): yield") 43 self.check_suite("def f(): x += yield") 44 self.check_suite("def f(): x = yield 1") 45 self.check_suite("def f(): x = y = yield 1") 46 self.check_suite("def f(): x = yield") 47 self.check_suite("def f(): x = y = yield") 48 self.check_suite("def f(): 1 + (yield)*2") 49 self.check_suite("def f(): (yield 1)*2") 50 self.check_suite("def f(): return; yield 1") 51 self.check_suite("def f(): yield 1; return") 52 self.check_suite("def f():\n" 53 " for x in range(30):\n" 54 " yield x\n") 55 self.check_suite("def f():\n" 56 " if (yield):\n" 57 " yield x\n") 58 59 def test_expressions(self): 60 self.check_expr("foo(1)") 61 self.check_expr("{1:1}") 62 self.check_expr("{1:1, 2:2, 3:3}") 63 self.check_expr("{1:1, 2:2, 3:3,}") 64 self.check_expr("{1}") 65 self.check_expr("{1, 2, 3}") 66 self.check_expr("{1, 2, 3,}") 67 self.check_expr("[]") 68 self.check_expr("[1]") 69 self.check_expr("[1, 2, 3]") 70 self.check_expr("[1, 2, 3,]") 71 self.check_expr("()") 72 self.check_expr("(1,)") 73 self.check_expr("(1, 2, 3)") 74 self.check_expr("(1, 2, 3,)") 75 self.check_expr("[x**3 for x in range(20)]") 76 self.check_expr("[x**3 for x in range(20) if x % 3]") 77 self.check_expr("[x**3 for x in range(20) if x % 2 if x % 3]") 78 self.check_expr("[x+y for x in range(30) for y in range(20) if x % 2 if y % 3]") 79 #self.check_expr("[x for x in lambda: True, lambda: False if x()]") 80 self.check_expr("list(x**3 for x in range(20))") 81 self.check_expr("list(x**3 for x in range(20) if x % 3)") 82 self.check_expr("list(x**3 for x in range(20) if x % 2 if x % 3)") 83 self.check_expr("list(x+y for x in range(30) for y in range(20) if x % 2 if y % 3)") 84 self.check_expr("{x**3 for x in range(30)}") 85 self.check_expr("{x**3 for x in range(30) if x % 3}") 86 self.check_expr("{x**3 for x in range(30) if x % 2 if x % 3}") 87 self.check_expr("{x+y for x in range(30) for y in range(20) if x % 2 if y % 3}") 88 self.check_expr("{x**3: y**2 for x, y in zip(range(30), range(30))}") 89 self.check_expr("{x**3: y**2 for x, y in zip(range(30), range(30)) if x % 3}") 90 self.check_expr("{x**3: y**2 for x, y in zip(range(30), range(30)) if x % 3 if y % 3}") 91 self.check_expr("{x:y for x in range(30) for y in range(20) if x % 2 if y % 3}") 92 self.check_expr("foo(*args)") 93 self.check_expr("foo(*args, **kw)") 94 self.check_expr("foo(**kw)") 95 self.check_expr("foo(key=value)") 96 self.check_expr("foo(key=value, *args)") 97 self.check_expr("foo(key=value, *args, **kw)") 98 self.check_expr("foo(key=value, **kw)") 99 self.check_expr("foo(a, b, c, *args)") 100 self.check_expr("foo(a, b, c, *args, **kw)") 101 self.check_expr("foo(a, b, c, **kw)") 102 self.check_expr("foo(a, *args, keyword=23)") 103 self.check_expr("foo + bar") 104 self.check_expr("foo - bar") 105 self.check_expr("foo * bar") 106 self.check_expr("foo / bar") 107 self.check_expr("foo // bar") 108 self.check_expr("lambda: 0") 109 self.check_expr("lambda x: 0") 110 self.check_expr("lambda *y: 0") 111 self.check_expr("lambda *y, **z: 0") 112 self.check_expr("lambda **z: 0") 113 self.check_expr("lambda x, y: 0") 114 self.check_expr("lambda foo=bar: 0") 115 self.check_expr("lambda foo=bar, spaz=nifty+spit: 0") 116 self.check_expr("lambda foo=bar, **z: 0") 117 self.check_expr("lambda foo=bar, blaz=blat+2, **z: 0") 118 self.check_expr("lambda foo=bar, blaz=blat+2, *y, **z: 0") 119 self.check_expr("lambda x, *y, **z: 0") 120 self.check_expr("lambda x: 5 if x else 2") 121 self.check_expr("(x for x in range(10))") 122 self.check_expr("foo(x for x in range(10))") 123 124 def test_print(self): 125 self.check_suite("print") 126 self.check_suite("print 1") 127 self.check_suite("print 1,") 128 self.check_suite("print >>fp") 129 self.check_suite("print >>fp, 1") 130 self.check_suite("print >>fp, 1,") 131 132 def test_simple_expression(self): 133 # expr_stmt 134 self.check_suite("a") 135 136 def test_simple_assignments(self): 137 self.check_suite("a = b") 138 self.check_suite("a = b = c = d = e") 139 140 def test_simple_augmented_assignments(self): 141 self.check_suite("a += b") 142 self.check_suite("a -= b") 143 self.check_suite("a *= b") 144 self.check_suite("a /= b") 145 self.check_suite("a //= b") 146 self.check_suite("a %= b") 147 self.check_suite("a &= b") 148 self.check_suite("a |= b") 149 self.check_suite("a ^= b") 150 self.check_suite("a <<= b") 151 self.check_suite("a >>= b") 152 self.check_suite("a **= b") 153 154 def test_function_defs(self): 155 self.check_suite("def f(): pass") 156 self.check_suite("def f(*args): pass") 157 self.check_suite("def f(*args, **kw): pass") 158 self.check_suite("def f(**kw): pass") 159 self.check_suite("def f(foo=bar): pass") 160 self.check_suite("def f(foo=bar, *args): pass") 161 self.check_suite("def f(foo=bar, *args, **kw): pass") 162 self.check_suite("def f(foo=bar, **kw): pass") 163 164 self.check_suite("def f(a, b): pass") 165 self.check_suite("def f(a, b, *args): pass") 166 self.check_suite("def f(a, b, *args, **kw): pass") 167 self.check_suite("def f(a, b, **kw): pass") 168 self.check_suite("def f(a, b, foo=bar): pass") 169 self.check_suite("def f(a, b, foo=bar, *args): pass") 170 self.check_suite("def f(a, b, foo=bar, *args, **kw): pass") 171 self.check_suite("def f(a, b, foo=bar, **kw): pass") 172 173 self.check_suite("@staticmethod\n" 174 "def f(): pass") 175 self.check_suite("@staticmethod\n" 176 "@funcattrs(x, y)\n" 177 "def f(): pass") 178 self.check_suite("@funcattrs()\n" 179 "def f(): pass") 180 181 def test_class_defs(self): 182 self.check_suite("class foo():pass") 183 self.check_suite("@class_decorator\n" 184 "class foo():pass") 185 self.check_suite("@class_decorator(arg)\n" 186 "class foo():pass") 187 self.check_suite("@decorator1\n" 188 "@decorator2\n" 189 "class foo():pass") 190 191 192 def test_import_from_statement(self): 193 self.check_suite("from sys.path import *") 194 self.check_suite("from sys.path import dirname") 195 self.check_suite("from sys.path import (dirname)") 196 self.check_suite("from sys.path import (dirname,)") 197 self.check_suite("from sys.path import dirname as my_dirname") 198 self.check_suite("from sys.path import (dirname as my_dirname)") 199 self.check_suite("from sys.path import (dirname as my_dirname,)") 200 self.check_suite("from sys.path import dirname, basename") 201 self.check_suite("from sys.path import (dirname, basename)") 202 self.check_suite("from sys.path import (dirname, basename,)") 203 self.check_suite( 204 "from sys.path import dirname as my_dirname, basename") 205 self.check_suite( 206 "from sys.path import (dirname as my_dirname, basename)") 207 self.check_suite( 208 "from sys.path import (dirname as my_dirname, basename,)") 209 self.check_suite( 210 "from sys.path import dirname, basename as my_basename") 211 self.check_suite( 212 "from sys.path import (dirname, basename as my_basename)") 213 self.check_suite( 214 "from sys.path import (dirname, basename as my_basename,)") 215 self.check_suite("from .bogus import x") 216 217 def test_basic_import_statement(self): 218 self.check_suite("import sys") 219 self.check_suite("import sys as system") 220 self.check_suite("import sys, math") 221 self.check_suite("import sys as system, math") 222 self.check_suite("import sys, math as my_math") 223 224 def test_relative_imports(self): 225 self.check_suite("from . import name") 226 self.check_suite("from .. import name") 227 self.check_suite("from .pkg import name") 228 self.check_suite("from ..pkg import name") 229 230 def test_pep263(self): 231 self.check_suite("# -*- coding: iso-8859-1 -*-\n" 232 "pass\n") 233 234 def test_assert(self): 235 self.check_suite("assert alo < ahi and blo < bhi\n") 236 237 def test_with(self): 238 self.check_suite("with open('x'): pass\n") 239 self.check_suite("with open('x') as f: pass\n") 240 self.check_suite("with open('x') as f, open('y') as g: pass\n") 241 242 def test_try_stmt(self): 243 self.check_suite("try: pass\nexcept: pass\n") 244 self.check_suite("try: pass\nfinally: pass\n") 245 self.check_suite("try: pass\nexcept A: pass\nfinally: pass\n") 246 self.check_suite("try: pass\nexcept A: pass\nexcept: pass\n" 247 "finally: pass\n") 248 self.check_suite("try: pass\nexcept: pass\nelse: pass\n") 249 self.check_suite("try: pass\nexcept: pass\nelse: pass\n" 250 "finally: pass\n") 251 252 def test_except_clause(self): 253 self.check_suite("try: pass\nexcept: pass\n") 254 self.check_suite("try: pass\nexcept A: pass\n") 255 self.check_suite("try: pass\nexcept A, e: pass\n") 256 self.check_suite("try: pass\nexcept A as e: pass\n") 257 258 def test_position(self): 259 # An absolutely minimal test of position information. Better 260 # tests would be a big project. 261 code = "def f(x):\n return x + 1" 262 st1 = parser.suite(code) 263 st2 = st1.totuple(line_info=1, col_info=1) 264 265 def walk(tree): 266 node_type = tree[0] 267 next = tree[1] 268 if isinstance(next, tuple): 269 for elt in tree[1:]: 270 for x in walk(elt): 271 yield x 272 else: 273 yield tree 274 275 terminals = list(walk(st2)) 276 self.assertEqual([ 277 (1, 'def', 1, 0), 278 (1, 'f', 1, 4), 279 (7, '(', 1, 5), 280 (1, 'x', 1, 6), 281 (8, ')', 1, 7), 282 (11, ':', 1, 8), 283 (4, '', 1, 9), 284 (5, '', 2, -1), 285 (1, 'return', 2, 4), 286 (1, 'x', 2, 11), 287 (14, '+', 2, 13), 288 (2, '1', 2, 15), 289 (4, '', 2, 16), 290 (6, '', 2, -1), 291 (4, '', 2, -1), 292 (0, '', 2, -1)], 293 terminals) 294 295 296 # 297 # Second, we take *invalid* trees and make sure we get ParserError 298 # rejections for them. 299 # 300 301 class IllegalSyntaxTestCase(unittest.TestCase): 302 303 def check_bad_tree(self, tree, label): 304 try: 305 parser.sequence2st(tree) 306 except parser.ParserError: 307 pass 308 else: 309 self.fail("did not detect invalid tree for %r" % label) 310 311 def test_junk(self): 312 # not even remotely valid: 313 self.check_bad_tree((1, 2, 3), "<junk>") 314 315 def test_illegal_yield_1(self): 316 # Illegal yield statement: def f(): return 1; yield 1 317 tree = \ 318 (257, 319 (264, 320 (285, 321 (259, 322 (1, 'def'), 323 (1, 'f'), 324 (260, (7, '('), (8, ')')), 325 (11, ':'), 326 (291, 327 (4, ''), 328 (5, ''), 329 (264, 330 (265, 331 (266, 332 (272, 333 (275, 334 (1, 'return'), 335 (313, 336 (292, 337 (293, 338 (294, 339 (295, 340 (297, 341 (298, 342 (299, 343 (300, 344 (301, 345 (302, (303, (304, (305, (2, '1')))))))))))))))))), 346 (264, 347 (265, 348 (266, 349 (272, 350 (276, 351 (1, 'yield'), 352 (313, 353 (292, 354 (293, 355 (294, 356 (295, 357 (297, 358 (298, 359 (299, 360 (300, 361 (301, 362 (302, 363 (303, (304, (305, (2, '1')))))))))))))))))), 364 (4, ''))), 365 (6, ''))))), 366 (4, ''), 367 (0, '')))) 368 self.check_bad_tree(tree, "def f():\n return 1\n yield 1") 369 370 def test_illegal_yield_2(self): 371 # Illegal return in generator: def f(): return 1; yield 1 372 tree = \ 373 (257, 374 (264, 375 (265, 376 (266, 377 (278, 378 (1, 'from'), 379 (281, (1, '__future__')), 380 (1, 'import'), 381 (279, (1, 'generators')))), 382 (4, ''))), 383 (264, 384 (285, 385 (259, 386 (1, 'def'), 387 (1, 'f'), 388 (260, (7, '('), (8, ')')), 389 (11, ':'), 390 (291, 391 (4, ''), 392 (5, ''), 393 (264, 394 (265, 395 (266, 396 (272, 397 (275, 398 (1, 'return'), 399 (313, 400 (292, 401 (293, 402 (294, 403 (295, 404 (297, 405 (298, 406 (299, 407 (300, 408 (301, 409 (302, (303, (304, (305, (2, '1')))))))))))))))))), 410 (264, 411 (265, 412 (266, 413 (272, 414 (276, 415 (1, 'yield'), 416 (313, 417 (292, 418 (293, 419 (294, 420 (295, 421 (297, 422 (298, 423 (299, 424 (300, 425 (301, 426 (302, 427 (303, (304, (305, (2, '1')))))))))))))))))), 428 (4, ''))), 429 (6, ''))))), 430 (4, ''), 431 (0, '')))) 432 self.check_bad_tree(tree, "def f():\n return 1\n yield 1") 433 434 def test_print_chevron_comma(self): 435 # Illegal input: print >>fp, 436 tree = \ 437 (257, 438 (264, 439 (265, 440 (266, 441 (268, 442 (1, 'print'), 443 (35, '>>'), 444 (290, 445 (291, 446 (292, 447 (293, 448 (295, 449 (296, 450 (297, 451 (298, (299, (300, (301, (302, (303, (1, 'fp')))))))))))))), 452 (12, ','))), 453 (4, ''))), 454 (0, '')) 455 self.check_bad_tree(tree, "print >>fp,") 456 457 def test_a_comma_comma_c(self): 458 # Illegal input: a,,c 459 tree = \ 460 (258, 461 (311, 462 (290, 463 (291, 464 (292, 465 (293, 466 (295, 467 (296, 468 (297, 469 (298, (299, (300, (301, (302, (303, (1, 'a')))))))))))))), 470 (12, ','), 471 (12, ','), 472 (290, 473 (291, 474 (292, 475 (293, 476 (295, 477 (296, 478 (297, 479 (298, (299, (300, (301, (302, (303, (1, 'c'))))))))))))))), 480 (4, ''), 481 (0, '')) 482 self.check_bad_tree(tree, "a,,c") 483 484 def test_illegal_operator(self): 485 # Illegal input: a $= b 486 tree = \ 487 (257, 488 (264, 489 (265, 490 (266, 491 (267, 492 (312, 493 (291, 494 (292, 495 (293, 496 (294, 497 (296, 498 (297, 499 (298, 500 (299, 501 (300, (301, (302, (303, (304, (1, 'a'))))))))))))))), 502 (268, (37, '$=')), 503 (312, 504 (291, 505 (292, 506 (293, 507 (294, 508 (296, 509 (297, 510 (298, 511 (299, 512 (300, (301, (302, (303, (304, (1, 'b'))))))))))))))))), 513 (4, ''))), 514 (0, '')) 515 self.check_bad_tree(tree, "a $= b") 516 517 def test_malformed_global(self): 518 #doesn't have global keyword in ast 519 tree = (257, 520 (264, 521 (265, 522 (266, 523 (282, (1, 'foo'))), (4, ''))), 524 (4, ''), 525 (0, '')) 526 self.check_bad_tree(tree, "malformed global ast") 527 528 def test_missing_import_source(self): 529 # from import a 530 tree = \ 531 (257, 532 (267, 533 (268, 534 (269, 535 (281, 536 (283, (1, 'from'), (1, 'import'), 537 (286, (284, (1, 'fred')))))), 538 (4, ''))), 539 (4, ''), (0, '')) 540 self.check_bad_tree(tree, "from import a") 541 542 543 class CompileTestCase(unittest.TestCase): 544 545 # These tests are very minimal. :-( 546 547 def test_compile_expr(self): 548 st = parser.expr('2 + 3') 549 code = parser.compilest(st) 550 self.assertEqual(eval(code), 5) 551 552 def test_compile_suite(self): 553 st = parser.suite('x = 2; y = x + 3') 554 code = parser.compilest(st) 555 globs = {} 556 exec code in globs 557 self.assertEqual(globs['y'], 5) 558 559 def test_compile_error(self): 560 st = parser.suite('1 = 3 + 4') 561 self.assertRaises(SyntaxError, parser.compilest, st) 562 563 def test_compile_badunicode(self): 564 st = parser.suite('a = u"\U12345678"') 565 self.assertRaises(SyntaxError, parser.compilest, st) 566 st = parser.suite('a = u"\u1"') 567 self.assertRaises(SyntaxError, parser.compilest, st) 568 569 class ParserStackLimitTestCase(unittest.TestCase): 570 """try to push the parser to/over it's limits. 571 see http://bugs.python.org/issue1881 for a discussion 572 """ 573 def _nested_expression(self, level): 574 return "["*level+"]"*level 575 576 def test_deeply_nested_list(self): 577 e = self._nested_expression(99) 578 st = parser.expr(e) 579 st.compile() 580 581 def test_trigger_memory_error(self): 582 e = self._nested_expression(100) 583 print >>sys.stderr, "Expecting 's_push: parser stack overflow' in next line" 584 self.assertRaises(MemoryError, parser.expr, e) 585 586 def test_main(): 587 test_support.run_unittest( 588 RoundtripLegalSyntaxTestCase, 589 IllegalSyntaxTestCase, 590 CompileTestCase, 591 ParserStackLimitTestCase, 592 ) 593 594 595 if __name__ == "__main__": 596 test_main() 597