test_parser.py revision f4189916e366045a44755d453c89d30e5006f84f
1import parser 2import unittest 3from test import test_support 4 5# 6# First, we test that we can generate trees from valid source fragments, 7# and that these valid trees are indeed allowed by the tree-loading side 8# of the parser module. 9# 10 11class RoundtripLegalSyntaxTestCase(unittest.TestCase): 12 13 def roundtrip(self, f, s): 14 st1 = f(s) 15 t = st1.totuple() 16 try: 17 st2 = parser.sequence2st(t) 18 except parser.ParserError, why: 19 self.fail("could not roundtrip %r: %s" % (s, why)) 20 21 self.assertEquals(t, st2.totuple(), 22 "could not re-generate syntax tree") 23 24 def check_expr(self, s): 25 self.roundtrip(parser.expr, s) 26 27 def check_suite(self, s): 28 self.roundtrip(parser.suite, s) 29 30 def test_yield_statement(self): 31 self.check_suite("def f(): yield 1") 32 self.check_suite("def f(): return; yield 1") 33 self.check_suite("def f(): yield 1; return") 34 self.check_suite("def f():\n" 35 " for x in range(30):\n" 36 " yield x\n") 37 38 def test_expressions(self): 39 self.check_expr("foo(1)") 40 self.check_expr("[1, 2, 3]") 41 self.check_expr("[x**3 for x in range(20)]") 42 self.check_expr("[x**3 for x in range(20) if x % 3]") 43 self.check_expr("foo(*args)") 44 self.check_expr("foo(*args, **kw)") 45 self.check_expr("foo(**kw)") 46 self.check_expr("foo(key=value)") 47 self.check_expr("foo(key=value, *args)") 48 self.check_expr("foo(key=value, *args, **kw)") 49 self.check_expr("foo(key=value, **kw)") 50 self.check_expr("foo(a, b, c, *args)") 51 self.check_expr("foo(a, b, c, *args, **kw)") 52 self.check_expr("foo(a, b, c, **kw)") 53 self.check_expr("foo + bar") 54 self.check_expr("foo - bar") 55 self.check_expr("foo * bar") 56 self.check_expr("foo / bar") 57 self.check_expr("foo // bar") 58 self.check_expr("lambda: 0") 59 self.check_expr("lambda x: 0") 60 self.check_expr("lambda *y: 0") 61 self.check_expr("lambda *y, **z: 0") 62 self.check_expr("lambda **z: 0") 63 self.check_expr("lambda x, y: 0") 64 self.check_expr("lambda foo=bar: 0") 65 self.check_expr("lambda foo=bar, spaz=nifty+spit: 0") 66 self.check_expr("lambda foo=bar, **z: 0") 67 self.check_expr("lambda foo=bar, blaz=blat+2, **z: 0") 68 self.check_expr("lambda foo=bar, blaz=blat+2, *y, **z: 0") 69 self.check_expr("lambda x, *y, **z: 0") 70 self.check_expr("(x for x in range(10))") 71 self.check_expr("foo(x for x in range(10))") 72 73 def test_print(self): 74 self.check_suite("print") 75 self.check_suite("print 1") 76 self.check_suite("print 1,") 77 self.check_suite("print >>fp") 78 self.check_suite("print >>fp, 1") 79 self.check_suite("print >>fp, 1,") 80 81 def test_simple_expression(self): 82 # expr_stmt 83 self.check_suite("a") 84 85 def test_simple_assignments(self): 86 self.check_suite("a = b") 87 self.check_suite("a = b = c = d = e") 88 89 def test_simple_augmented_assignments(self): 90 self.check_suite("a += b") 91 self.check_suite("a -= b") 92 self.check_suite("a *= b") 93 self.check_suite("a /= b") 94 self.check_suite("a //= b") 95 self.check_suite("a %= b") 96 self.check_suite("a &= b") 97 self.check_suite("a |= b") 98 self.check_suite("a ^= b") 99 self.check_suite("a <<= b") 100 self.check_suite("a >>= b") 101 self.check_suite("a **= b") 102 103 def test_function_defs(self): 104 self.check_suite("def f(): pass") 105 self.check_suite("def f(*args): pass") 106 self.check_suite("def f(*args, **kw): pass") 107 self.check_suite("def f(**kw): pass") 108 self.check_suite("def f(foo=bar): pass") 109 self.check_suite("def f(foo=bar, *args): pass") 110 self.check_suite("def f(foo=bar, *args, **kw): pass") 111 self.check_suite("def f(foo=bar, **kw): pass") 112 113 self.check_suite("def f(a, b): pass") 114 self.check_suite("def f(a, b, *args): pass") 115 self.check_suite("def f(a, b, *args, **kw): pass") 116 self.check_suite("def f(a, b, **kw): pass") 117 self.check_suite("def f(a, b, foo=bar): pass") 118 self.check_suite("def f(a, b, foo=bar, *args): pass") 119 self.check_suite("def f(a, b, foo=bar, *args, **kw): pass") 120 self.check_suite("def f(a, b, foo=bar, **kw): pass") 121 122 self.check_suite("@staticmethod\n" 123 "def f(): pass") 124 self.check_suite("@staticmethod\n" 125 "@funcattrs(x, y)\n" 126 "def f(): pass") 127 self.check_suite("@funcattrs()\n" 128 "def f(): pass") 129 130 def test_class_defs(self): 131 self.check_suite("class foo():pass") 132 133 def test_import_from_statement(self): 134 self.check_suite("from sys.path import *") 135 self.check_suite("from sys.path import dirname") 136 self.check_suite("from sys.path import (dirname)") 137 self.check_suite("from sys.path import (dirname,)") 138 self.check_suite("from sys.path import dirname as my_dirname") 139 self.check_suite("from sys.path import (dirname as my_dirname)") 140 self.check_suite("from sys.path import (dirname as my_dirname,)") 141 self.check_suite("from sys.path import dirname, basename") 142 self.check_suite("from sys.path import (dirname, basename)") 143 self.check_suite("from sys.path import (dirname, basename,)") 144 self.check_suite( 145 "from sys.path import dirname as my_dirname, basename") 146 self.check_suite( 147 "from sys.path import (dirname as my_dirname, basename)") 148 self.check_suite( 149 "from sys.path import (dirname as my_dirname, basename,)") 150 self.check_suite( 151 "from sys.path import dirname, basename as my_basename") 152 self.check_suite( 153 "from sys.path import (dirname, basename as my_basename)") 154 self.check_suite( 155 "from sys.path import (dirname, basename as my_basename,)") 156 157 def test_basic_import_statement(self): 158 self.check_suite("import sys") 159 self.check_suite("import sys as system") 160 self.check_suite("import sys, math") 161 self.check_suite("import sys as system, math") 162 self.check_suite("import sys, math as my_math") 163 164 def test_pep263(self): 165 self.check_suite("# -*- coding: iso-8859-1 -*-\n" 166 "pass\n") 167 168 def test_assert(self): 169 self.check_suite("assert alo < ahi and blo < bhi\n") 170 171# 172# Second, we take *invalid* trees and make sure we get ParserError 173# rejections for them. 174# 175 176class IllegalSyntaxTestCase(unittest.TestCase): 177 178 def check_bad_tree(self, tree, label): 179 try: 180 parser.sequence2st(tree) 181 except parser.ParserError: 182 pass 183 else: 184 self.fail("did not detect invalid tree for %r" % label) 185 186 def test_junk(self): 187 # not even remotely valid: 188 self.check_bad_tree((1, 2, 3), "<junk>") 189 190 def test_illegal_yield_1(self): 191 # Illegal yield statement: def f(): return 1; yield 1 192 tree = \ 193 (257, 194 (264, 195 (285, 196 (259, 197 (1, 'def'), 198 (1, 'f'), 199 (260, (7, '('), (8, ')')), 200 (11, ':'), 201 (291, 202 (4, ''), 203 (5, ''), 204 (264, 205 (265, 206 (266, 207 (272, 208 (275, 209 (1, 'return'), 210 (313, 211 (292, 212 (293, 213 (294, 214 (295, 215 (297, 216 (298, 217 (299, 218 (300, 219 (301, 220 (302, (303, (304, (305, (2, '1')))))))))))))))))), 221 (264, 222 (265, 223 (266, 224 (272, 225 (276, 226 (1, 'yield'), 227 (313, 228 (292, 229 (293, 230 (294, 231 (295, 232 (297, 233 (298, 234 (299, 235 (300, 236 (301, 237 (302, 238 (303, (304, (305, (2, '1')))))))))))))))))), 239 (4, ''))), 240 (6, ''))))), 241 (4, ''), 242 (0, '')))) 243 self.check_bad_tree(tree, "def f():\n return 1\n yield 1") 244 245 def test_illegal_yield_2(self): 246 # Illegal return in generator: def f(): return 1; yield 1 247 tree = \ 248 (257, 249 (264, 250 (265, 251 (266, 252 (278, 253 (1, 'from'), 254 (281, (1, '__future__')), 255 (1, 'import'), 256 (279, (1, 'generators')))), 257 (4, ''))), 258 (264, 259 (285, 260 (259, 261 (1, 'def'), 262 (1, 'f'), 263 (260, (7, '('), (8, ')')), 264 (11, ':'), 265 (291, 266 (4, ''), 267 (5, ''), 268 (264, 269 (265, 270 (266, 271 (272, 272 (275, 273 (1, 'return'), 274 (313, 275 (292, 276 (293, 277 (294, 278 (295, 279 (297, 280 (298, 281 (299, 282 (300, 283 (301, 284 (302, (303, (304, (305, (2, '1')))))))))))))))))), 285 (264, 286 (265, 287 (266, 288 (272, 289 (276, 290 (1, 'yield'), 291 (313, 292 (292, 293 (293, 294 (294, 295 (295, 296 (297, 297 (298, 298 (299, 299 (300, 300 (301, 301 (302, 302 (303, (304, (305, (2, '1')))))))))))))))))), 303 (4, ''))), 304 (6, ''))))), 305 (4, ''), 306 (0, '')))) 307 self.check_bad_tree(tree, "def f():\n return 1\n yield 1") 308 309 def test_print_chevron_comma(self): 310 # Illegal input: print >>fp, 311 tree = \ 312 (257, 313 (264, 314 (265, 315 (266, 316 (268, 317 (1, 'print'), 318 (35, '>>'), 319 (290, 320 (291, 321 (292, 322 (293, 323 (295, 324 (296, 325 (297, 326 (298, (299, (300, (301, (302, (303, (1, 'fp')))))))))))))), 327 (12, ','))), 328 (4, ''))), 329 (0, '')) 330 self.check_bad_tree(tree, "print >>fp,") 331 332 def test_a_comma_comma_c(self): 333 # Illegal input: a,,c 334 tree = \ 335 (258, 336 (311, 337 (290, 338 (291, 339 (292, 340 (293, 341 (295, 342 (296, 343 (297, 344 (298, (299, (300, (301, (302, (303, (1, 'a')))))))))))))), 345 (12, ','), 346 (12, ','), 347 (290, 348 (291, 349 (292, 350 (293, 351 (295, 352 (296, 353 (297, 354 (298, (299, (300, (301, (302, (303, (1, 'c'))))))))))))))), 355 (4, ''), 356 (0, '')) 357 self.check_bad_tree(tree, "a,,c") 358 359 def test_illegal_operator(self): 360 # Illegal input: a $= b 361 tree = \ 362 (257, 363 (264, 364 (265, 365 (266, 366 (267, 367 (312, 368 (291, 369 (292, 370 (293, 371 (294, 372 (296, 373 (297, 374 (298, 375 (299, 376 (300, (301, (302, (303, (304, (1, 'a'))))))))))))))), 377 (268, (37, '$=')), 378 (312, 379 (291, 380 (292, 381 (293, 382 (294, 383 (296, 384 (297, 385 (298, 386 (299, 387 (300, (301, (302, (303, (304, (1, 'b'))))))))))))))))), 388 (4, ''))), 389 (0, '')) 390 self.check_bad_tree(tree, "a $= b") 391 392 def test_malformed_global(self): 393 #doesn't have global keyword in ast 394 tree = (257, 395 (264, 396 (265, 397 (266, 398 (282, (1, 'foo'))), (4, ''))), 399 (4, ''), 400 (0, '')) 401 self.check_bad_tree(tree, "malformed global ast") 402 403def test_main(): 404 test_support.run_unittest( 405 RoundtripLegalSyntaxTestCase, 406 IllegalSyntaxTestCase 407 ) 408 409 410if __name__ == "__main__": 411 test_main() 412