test_parser.py revision f2715e076435b74638acb81512c2ee014f75aea2
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: 19 self.fail("could not roundtrip %r" % s) 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 71 def test_print(self): 72 self.check_suite("print") 73 self.check_suite("print 1") 74 self.check_suite("print 1,") 75 self.check_suite("print >>fp") 76 self.check_suite("print >>fp, 1") 77 self.check_suite("print >>fp, 1,") 78 79 def test_simple_expression(self): 80 # expr_stmt 81 self.check_suite("a") 82 83 def test_simple_assignments(self): 84 self.check_suite("a = b") 85 self.check_suite("a = b = c = d = e") 86 87 def test_simple_augmented_assignments(self): 88 self.check_suite("a += b") 89 self.check_suite("a -= b") 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 101 def test_function_defs(self): 102 self.check_suite("def f(): pass") 103 self.check_suite("def f(*args): pass") 104 self.check_suite("def f(*args, **kw): pass") 105 self.check_suite("def f(**kw): pass") 106 self.check_suite("def f(foo=bar): pass") 107 self.check_suite("def f(foo=bar, *args): pass") 108 self.check_suite("def f(foo=bar, *args, **kw): pass") 109 self.check_suite("def f(foo=bar, **kw): pass") 110 111 self.check_suite("def f(a, b): pass") 112 self.check_suite("def f(a, b, *args): pass") 113 self.check_suite("def f(a, b, *args, **kw): pass") 114 self.check_suite("def f(a, b, **kw): pass") 115 self.check_suite("def f(a, b, foo=bar): pass") 116 self.check_suite("def f(a, b, foo=bar, *args): pass") 117 self.check_suite("def f(a, b, foo=bar, *args, **kw): pass") 118 self.check_suite("def f(a, b, foo=bar, **kw): pass") 119 120 def test_import_from_statement(self): 121 self.check_suite("from sys.path import *") 122 self.check_suite("from sys.path import dirname") 123 self.check_suite("from sys.path import dirname as my_dirname") 124 self.check_suite("from sys.path import dirname, basename") 125 self.check_suite( 126 "from sys.path import dirname as my_dirname, basename") 127 self.check_suite( 128 "from sys.path import dirname, basename as my_basename") 129 130 def test_basic_import_statement(self): 131 self.check_suite("import sys") 132 self.check_suite("import sys as system") 133 self.check_suite("import sys, math") 134 self.check_suite("import sys as system, math") 135 self.check_suite("import sys, math as my_math") 136 137 def test_pep263(self): 138 self.check_suite("# -*- coding: iso-8859-1 -*-\n" 139 "pass\n") 140 141 def test_assert(self): 142 self.check_suite("assert alo < ahi and blo < bhi\n") 143 144# 145# Second, we take *invalid* trees and make sure we get ParserError 146# rejections for them. 147# 148 149class IllegalSyntaxTestCase(unittest.TestCase): 150 151 def check_bad_tree(self, tree, label): 152 try: 153 parser.sequence2st(tree) 154 except parser.ParserError: 155 pass 156 else: 157 self.fail("did not detect invalid tree for %r" % label) 158 159 def test_junk(self): 160 # not even remotely valid: 161 self.check_bad_tree((1, 2, 3), "<junk>") 162 163 def test_illegal_yield_1(self): 164 # Illegal yield statement: def f(): return 1; yield 1 165 tree = \ 166 (257, 167 (264, 168 (285, 169 (259, 170 (1, 'def'), 171 (1, 'f'), 172 (260, (7, '('), (8, ')')), 173 (11, ':'), 174 (291, 175 (4, ''), 176 (5, ''), 177 (264, 178 (265, 179 (266, 180 (272, 181 (275, 182 (1, 'return'), 183 (313, 184 (292, 185 (293, 186 (294, 187 (295, 188 (297, 189 (298, 190 (299, 191 (300, 192 (301, 193 (302, (303, (304, (305, (2, '1')))))))))))))))))), 194 (264, 195 (265, 196 (266, 197 (272, 198 (276, 199 (1, 'yield'), 200 (313, 201 (292, 202 (293, 203 (294, 204 (295, 205 (297, 206 (298, 207 (299, 208 (300, 209 (301, 210 (302, 211 (303, (304, (305, (2, '1')))))))))))))))))), 212 (4, ''))), 213 (6, ''))))), 214 (4, ''), 215 (0, '')))) 216 self.check_bad_tree(tree, "def f():\n return 1\n yield 1") 217 218 def test_illegal_yield_2(self): 219 # Illegal return in generator: def f(): return 1; yield 1 220 tree = \ 221 (257, 222 (264, 223 (265, 224 (266, 225 (278, 226 (1, 'from'), 227 (281, (1, '__future__')), 228 (1, 'import'), 229 (279, (1, 'generators')))), 230 (4, ''))), 231 (264, 232 (285, 233 (259, 234 (1, 'def'), 235 (1, 'f'), 236 (260, (7, '('), (8, ')')), 237 (11, ':'), 238 (291, 239 (4, ''), 240 (5, ''), 241 (264, 242 (265, 243 (266, 244 (272, 245 (275, 246 (1, 'return'), 247 (313, 248 (292, 249 (293, 250 (294, 251 (295, 252 (297, 253 (298, 254 (299, 255 (300, 256 (301, 257 (302, (303, (304, (305, (2, '1')))))))))))))))))), 258 (264, 259 (265, 260 (266, 261 (272, 262 (276, 263 (1, 'yield'), 264 (313, 265 (292, 266 (293, 267 (294, 268 (295, 269 (297, 270 (298, 271 (299, 272 (300, 273 (301, 274 (302, 275 (303, (304, (305, (2, '1')))))))))))))))))), 276 (4, ''))), 277 (6, ''))))), 278 (4, ''), 279 (0, '')))) 280 self.check_bad_tree(tree, "def f():\n return 1\n yield 1") 281 282 def test_print_chevron_comma(self): 283 # Illegal input: print >>fp, 284 tree = \ 285 (257, 286 (264, 287 (265, 288 (266, 289 (268, 290 (1, 'print'), 291 (35, '>>'), 292 (290, 293 (291, 294 (292, 295 (293, 296 (295, 297 (296, 298 (297, 299 (298, (299, (300, (301, (302, (303, (1, 'fp')))))))))))))), 300 (12, ','))), 301 (4, ''))), 302 (0, '')) 303 self.check_bad_tree(tree, "print >>fp,") 304 305 def test_a_comma_comma_c(self): 306 # Illegal input: a,,c 307 tree = \ 308 (258, 309 (311, 310 (290, 311 (291, 312 (292, 313 (293, 314 (295, 315 (296, 316 (297, 317 (298, (299, (300, (301, (302, (303, (1, 'a')))))))))))))), 318 (12, ','), 319 (12, ','), 320 (290, 321 (291, 322 (292, 323 (293, 324 (295, 325 (296, 326 (297, 327 (298, (299, (300, (301, (302, (303, (1, 'c'))))))))))))))), 328 (4, ''), 329 (0, '')) 330 self.check_bad_tree(tree, "a,,c") 331 332 def test_illegal_operator(self): 333 # Illegal input: a $= b 334 tree = \ 335 (257, 336 (264, 337 (265, 338 (266, 339 (267, 340 (312, 341 (291, 342 (292, 343 (293, 344 (294, 345 (296, 346 (297, 347 (298, 348 (299, 349 (300, (301, (302, (303, (304, (1, 'a'))))))))))))))), 350 (268, (37, '$=')), 351 (312, 352 (291, 353 (292, 354 (293, 355 (294, 356 (296, 357 (297, 358 (298, 359 (299, 360 (300, (301, (302, (303, (304, (1, 'b'))))))))))))))))), 361 (4, ''))), 362 (0, '')) 363 self.check_bad_tree(tree, "a $= b") 364 365 def test_malformed_global(self): 366 #doesn't have global keyword in ast 367 tree = (257, 368 (264, 369 (265, 370 (266, 371 (282, (1, 'foo'))), (4, ''))), 372 (4, ''), 373 (0, '')) 374 self.check_bad_tree(tree, "malformed global ast") 375 376def test_main(): 377 loader = unittest.TestLoader() 378 suite = unittest.TestSuite() 379 suite.addTest(loader.loadTestsFromTestCase(RoundtripLegalSyntaxTestCase)) 380 suite.addTest(loader.loadTestsFromTestCase(IllegalSyntaxTestCase)) 381 test_support.run_suite(suite) 382 383 384if __name__ == "__main__": 385 test_main() 386