blob: 04b45be0aeab61f613d2ff1a26d1ef0611fc5e66 [file] [log] [blame]
Fred Drake79ca79d2000-08-21 22:30:53 +00001import parser
Benjamin Petersonc0747cf2008-11-03 20:31:38 +00002import os
Fred Drake58422e52001-06-04 03:56:24 +00003import unittest
Christian Heimesb186d002008-03-18 15:15:01 +00004import sys
Mark Dickinson211c6252009-02-01 10:28:51 +00005import operator
Benjamin Petersonee8712c2008-05-20 21:35:26 +00006from test import support
Fred Drake79ca79d2000-08-21 22:30:53 +00007
8#
9# First, we test that we can generate trees from valid source fragments,
10# and that these valid trees are indeed allowed by the tree-loading side
11# of the parser module.
12#
13
Fred Drake58422e52001-06-04 03:56:24 +000014class RoundtripLegalSyntaxTestCase(unittest.TestCase):
Guido van Rossum32c2ae72002-08-22 19:45:32 +000015
Fred Drake58422e52001-06-04 03:56:24 +000016 def roundtrip(self, f, s):
17 st1 = f(s)
18 t = st1.totuple()
19 try:
Fred Drake6e4f2c02001-07-17 19:33:25 +000020 st2 = parser.sequence2st(t)
Guido van Rossumb940e112007-01-10 16:19:56 +000021 except parser.ParserError as why:
Anthony Baxterc2a5a632004-08-02 06:10:11 +000022 self.fail("could not roundtrip %r: %s" % (s, why))
Fred Drake79ca79d2000-08-21 22:30:53 +000023
Fred Drake58422e52001-06-04 03:56:24 +000024 self.assertEquals(t, st2.totuple(),
25 "could not re-generate syntax tree")
Fred Drake28f739a2000-08-25 22:42:40 +000026
Fred Drake58422e52001-06-04 03:56:24 +000027 def check_expr(self, s):
28 self.roundtrip(parser.expr, s)
Fred Drake28f739a2000-08-25 22:42:40 +000029
Benjamin Petersonf216c942008-10-31 02:28:05 +000030 def test_flags_passed(self):
31 # The unicode literals flags has to be passed from the paser to AST
32 # generation.
33 suite = parser.suite("from __future__ import unicode_literals; x = ''")
34 code = suite.compile()
35 scope = {}
36 exec(code, {}, scope)
37 self.assertTrue(isinstance(scope["x"], str))
38
Fred Drake58422e52001-06-04 03:56:24 +000039 def check_suite(self, s):
40 self.roundtrip(parser.suite, s)
Fred Drake28f739a2000-08-25 22:42:40 +000041
Fred Drakecf580c72001-07-17 03:01:29 +000042 def test_yield_statement(self):
Tim Peters496563a2002-04-01 00:28:59 +000043 self.check_suite("def f(): yield 1")
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000044 self.check_suite("def f(): yield")
45 self.check_suite("def f(): x += yield")
46 self.check_suite("def f(): x = yield 1")
47 self.check_suite("def f(): x = y = yield 1")
48 self.check_suite("def f(): x = yield")
49 self.check_suite("def f(): x = y = yield")
50 self.check_suite("def f(): 1 + (yield)*2")
51 self.check_suite("def f(): (yield 1)*2")
Tim Peters496563a2002-04-01 00:28:59 +000052 self.check_suite("def f(): return; yield 1")
53 self.check_suite("def f(): yield 1; return")
54 self.check_suite("def f():\n"
Fred Drakecf580c72001-07-17 03:01:29 +000055 " for x in range(30):\n"
56 " yield x\n")
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000057 self.check_suite("def f():\n"
58 " if (yield):\n"
59 " yield x\n")
Fred Drakecf580c72001-07-17 03:01:29 +000060
Fred Drake58422e52001-06-04 03:56:24 +000061 def test_expressions(self):
62 self.check_expr("foo(1)")
63 self.check_expr("[1, 2, 3]")
64 self.check_expr("[x**3 for x in range(20)]")
65 self.check_expr("[x**3 for x in range(20) if x % 3]")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000066 self.check_expr("[x**3 for x in range(20) if x % 2 if x % 3]")
67 self.check_expr("list(x**3 for x in range(20))")
68 self.check_expr("list(x**3 for x in range(20) if x % 3)")
69 self.check_expr("list(x**3 for x in range(20) if x % 2 if x % 3)")
Fred Drake58422e52001-06-04 03:56:24 +000070 self.check_expr("foo(*args)")
71 self.check_expr("foo(*args, **kw)")
72 self.check_expr("foo(**kw)")
73 self.check_expr("foo(key=value)")
74 self.check_expr("foo(key=value, *args)")
75 self.check_expr("foo(key=value, *args, **kw)")
76 self.check_expr("foo(key=value, **kw)")
77 self.check_expr("foo(a, b, c, *args)")
78 self.check_expr("foo(a, b, c, *args, **kw)")
79 self.check_expr("foo(a, b, c, **kw)")
Benjamin Peterson3938a902008-08-20 02:33:00 +000080 self.check_expr("foo(a, *args, keyword=23)")
Fred Drake58422e52001-06-04 03:56:24 +000081 self.check_expr("foo + bar")
Michael W. Hudson5e83b7a2003-01-29 14:20:23 +000082 self.check_expr("foo - bar")
83 self.check_expr("foo * bar")
84 self.check_expr("foo / bar")
85 self.check_expr("foo // bar")
Fred Drake58422e52001-06-04 03:56:24 +000086 self.check_expr("lambda: 0")
87 self.check_expr("lambda x: 0")
88 self.check_expr("lambda *y: 0")
89 self.check_expr("lambda *y, **z: 0")
90 self.check_expr("lambda **z: 0")
91 self.check_expr("lambda x, y: 0")
92 self.check_expr("lambda foo=bar: 0")
93 self.check_expr("lambda foo=bar, spaz=nifty+spit: 0")
94 self.check_expr("lambda foo=bar, **z: 0")
95 self.check_expr("lambda foo=bar, blaz=blat+2, **z: 0")
96 self.check_expr("lambda foo=bar, blaz=blat+2, *y, **z: 0")
97 self.check_expr("lambda x, *y, **z: 0")
Raymond Hettinger354433a2004-05-19 08:20:33 +000098 self.check_expr("(x for x in range(10))")
99 self.check_expr("foo(x for x in range(10))")
Fred Drake79ca79d2000-08-21 22:30:53 +0000100
Fred Drake58422e52001-06-04 03:56:24 +0000101 def test_simple_expression(self):
102 # expr_stmt
103 self.check_suite("a")
Fred Drake79ca79d2000-08-21 22:30:53 +0000104
Fred Drake58422e52001-06-04 03:56:24 +0000105 def test_simple_assignments(self):
106 self.check_suite("a = b")
107 self.check_suite("a = b = c = d = e")
Fred Drake28f739a2000-08-25 22:42:40 +0000108
Fred Drake58422e52001-06-04 03:56:24 +0000109 def test_simple_augmented_assignments(self):
110 self.check_suite("a += b")
111 self.check_suite("a -= b")
112 self.check_suite("a *= b")
113 self.check_suite("a /= b")
Michael W. Hudson5e83b7a2003-01-29 14:20:23 +0000114 self.check_suite("a //= b")
Fred Drake58422e52001-06-04 03:56:24 +0000115 self.check_suite("a %= b")
116 self.check_suite("a &= b")
117 self.check_suite("a |= b")
118 self.check_suite("a ^= b")
119 self.check_suite("a <<= b")
120 self.check_suite("a >>= b")
121 self.check_suite("a **= b")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000122
Fred Drake58422e52001-06-04 03:56:24 +0000123 def test_function_defs(self):
124 self.check_suite("def f(): pass")
125 self.check_suite("def f(*args): pass")
126 self.check_suite("def f(*args, **kw): pass")
127 self.check_suite("def f(**kw): pass")
128 self.check_suite("def f(foo=bar): pass")
129 self.check_suite("def f(foo=bar, *args): pass")
130 self.check_suite("def f(foo=bar, *args, **kw): pass")
131 self.check_suite("def f(foo=bar, **kw): pass")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000132
Fred Drake58422e52001-06-04 03:56:24 +0000133 self.check_suite("def f(a, b): pass")
134 self.check_suite("def f(a, b, *args): pass")
135 self.check_suite("def f(a, b, *args, **kw): pass")
136 self.check_suite("def f(a, b, **kw): pass")
137 self.check_suite("def f(a, b, foo=bar): pass")
138 self.check_suite("def f(a, b, foo=bar, *args): pass")
139 self.check_suite("def f(a, b, foo=bar, *args, **kw): pass")
140 self.check_suite("def f(a, b, foo=bar, **kw): pass")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000141
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000142 self.check_suite("@staticmethod\n"
143 "def f(): pass")
144 self.check_suite("@staticmethod\n"
145 "@funcattrs(x, y)\n"
146 "def f(): pass")
147 self.check_suite("@funcattrs()\n"
148 "def f(): pass")
149
Brett Cannonf4189912005-04-09 02:30:16 +0000150 def test_class_defs(self):
151 self.check_suite("class foo():pass")
Guido van Rossumfc158e22007-11-15 19:17:28 +0000152 self.check_suite("class foo(object):pass")
Mark Dickinsona441e642010-07-04 16:39:03 +0000153 self.check_suite("@class_decorator\n"
154 "class foo():pass")
155 self.check_suite("@class_decorator(arg)\n"
156 "class foo():pass")
157 self.check_suite("@decorator1\n"
158 "@decorator2\n"
159 "class foo():pass")
Tim Peterse8906822005-04-20 17:45:13 +0000160
Fred Drake58422e52001-06-04 03:56:24 +0000161 def test_import_from_statement(self):
162 self.check_suite("from sys.path import *")
163 self.check_suite("from sys.path import dirname")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000164 self.check_suite("from sys.path import (dirname)")
165 self.check_suite("from sys.path import (dirname,)")
Fred Drake58422e52001-06-04 03:56:24 +0000166 self.check_suite("from sys.path import dirname as my_dirname")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000167 self.check_suite("from sys.path import (dirname as my_dirname)")
168 self.check_suite("from sys.path import (dirname as my_dirname,)")
Fred Drake58422e52001-06-04 03:56:24 +0000169 self.check_suite("from sys.path import dirname, basename")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000170 self.check_suite("from sys.path import (dirname, basename)")
171 self.check_suite("from sys.path import (dirname, basename,)")
Fred Drake58422e52001-06-04 03:56:24 +0000172 self.check_suite(
173 "from sys.path import dirname as my_dirname, basename")
174 self.check_suite(
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000175 "from sys.path import (dirname as my_dirname, basename)")
176 self.check_suite(
177 "from sys.path import (dirname as my_dirname, basename,)")
178 self.check_suite(
Fred Drake58422e52001-06-04 03:56:24 +0000179 "from sys.path import dirname, basename as my_basename")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000180 self.check_suite(
181 "from sys.path import (dirname, basename as my_basename)")
182 self.check_suite(
183 "from sys.path import (dirname, basename as my_basename,)")
Benjamin Petersonc0747cf2008-11-03 20:31:38 +0000184 self.check_suite("from .bogus import x")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000185
Fred Drake58422e52001-06-04 03:56:24 +0000186 def test_basic_import_statement(self):
187 self.check_suite("import sys")
188 self.check_suite("import sys as system")
189 self.check_suite("import sys, math")
190 self.check_suite("import sys as system, math")
191 self.check_suite("import sys, math as my_math")
Fred Drake79ca79d2000-08-21 22:30:53 +0000192
Mark Dickinson1b9b5722010-07-04 18:16:43 +0000193 def test_relative_imports(self):
194 self.check_suite("from . import name")
195 self.check_suite("from .. import name")
Mark Dickinson0dce8152010-07-04 18:39:48 +0000196 # check all the way up to '....', since '...' is tokenized
197 # differently from '.' (it's an ellipsis token).
198 self.check_suite("from ... import name")
199 self.check_suite("from .... import name")
Mark Dickinson1b9b5722010-07-04 18:16:43 +0000200 self.check_suite("from .pkg import name")
201 self.check_suite("from ..pkg import name")
Mark Dickinson0dce8152010-07-04 18:39:48 +0000202 self.check_suite("from ...pkg import name")
203 self.check_suite("from ....pkg import name")
Mark Dickinson1b9b5722010-07-04 18:16:43 +0000204
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000205 def test_pep263(self):
206 self.check_suite("# -*- coding: iso-8859-1 -*-\n"
207 "pass\n")
208
209 def test_assert(self):
210 self.check_suite("assert alo < ahi and blo < bhi\n")
211
Benjamin Peterson4469d0c2008-11-30 22:46:23 +0000212 def test_with(self):
213 self.check_suite("with open('x'): pass\n")
214 self.check_suite("with open('x') as f: pass\n")
Georg Brandl0c315622009-05-25 21:10:36 +0000215 self.check_suite("with open('x') as f, open('y') as g: pass\n")
Benjamin Peterson4469d0c2008-11-30 22:46:23 +0000216
Georg Brandleee31162008-12-07 15:15:22 +0000217 def test_try_stmt(self):
218 self.check_suite("try: pass\nexcept: pass\n")
219 self.check_suite("try: pass\nfinally: pass\n")
220 self.check_suite("try: pass\nexcept A: pass\nfinally: pass\n")
221 self.check_suite("try: pass\nexcept A: pass\nexcept: pass\n"
222 "finally: pass\n")
223 self.check_suite("try: pass\nexcept: pass\nelse: pass\n")
224 self.check_suite("try: pass\nexcept: pass\nelse: pass\n"
225 "finally: pass\n")
226
Thomas Wouters89f507f2006-12-13 04:49:30 +0000227 def test_position(self):
228 # An absolutely minimal test of position information. Better
229 # tests would be a big project.
230 code = "def f(x):\n return x + 1\n"
231 st1 = parser.suite(code)
232 st2 = st1.totuple(line_info=1, col_info=1)
233
234 def walk(tree):
235 node_type = tree[0]
236 next = tree[1]
237 if isinstance(next, tuple):
238 for elt in tree[1:]:
239 for x in walk(elt):
240 yield x
241 else:
242 yield tree
243
244 terminals = list(walk(st2))
245 self.assertEqual([
246 (1, 'def', 1, 0),
247 (1, 'f', 1, 4),
248 (7, '(', 1, 5),
249 (1, 'x', 1, 6),
250 (8, ')', 1, 7),
251 (11, ':', 1, 8),
252 (4, '', 1, 9),
253 (5, '', 2, -1),
254 (1, 'return', 2, 4),
255 (1, 'x', 2, 11),
256 (14, '+', 2, 13),
257 (2, '1', 2, 15),
258 (4, '', 2, 16),
259 (6, '', 2, -1),
260 (4, '', 2, -1),
261 (0, '', 2, -1)],
262 terminals)
263
264
Fred Drake79ca79d2000-08-21 22:30:53 +0000265#
266# Second, we take *invalid* trees and make sure we get ParserError
267# rejections for them.
268#
269
Fred Drake58422e52001-06-04 03:56:24 +0000270class IllegalSyntaxTestCase(unittest.TestCase):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000271
Fred Drake58422e52001-06-04 03:56:24 +0000272 def check_bad_tree(self, tree, label):
273 try:
Fred Drake6e4f2c02001-07-17 19:33:25 +0000274 parser.sequence2st(tree)
Fred Drake58422e52001-06-04 03:56:24 +0000275 except parser.ParserError:
276 pass
277 else:
278 self.fail("did not detect invalid tree for %r" % label)
Fred Drake79ca79d2000-08-21 22:30:53 +0000279
Fred Drake58422e52001-06-04 03:56:24 +0000280 def test_junk(self):
281 # not even remotely valid:
282 self.check_bad_tree((1, 2, 3), "<junk>")
283
Fred Drakecf580c72001-07-17 03:01:29 +0000284 def test_illegal_yield_1(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000285 # Illegal yield statement: def f(): return 1; yield 1
Fred Drakecf580c72001-07-17 03:01:29 +0000286 tree = \
287 (257,
288 (264,
289 (285,
290 (259,
291 (1, 'def'),
292 (1, 'f'),
293 (260, (7, '('), (8, ')')),
294 (11, ':'),
295 (291,
296 (4, ''),
297 (5, ''),
298 (264,
299 (265,
300 (266,
301 (272,
302 (275,
303 (1, 'return'),
304 (313,
305 (292,
306 (293,
307 (294,
308 (295,
309 (297,
310 (298,
311 (299,
312 (300,
313 (301,
314 (302, (303, (304, (305, (2, '1')))))))))))))))))),
315 (264,
316 (265,
317 (266,
318 (272,
319 (276,
320 (1, 'yield'),
321 (313,
322 (292,
323 (293,
324 (294,
325 (295,
326 (297,
327 (298,
328 (299,
329 (300,
330 (301,
331 (302,
332 (303, (304, (305, (2, '1')))))))))))))))))),
333 (4, ''))),
334 (6, ''))))),
335 (4, ''),
336 (0, ''))))
337 self.check_bad_tree(tree, "def f():\n return 1\n yield 1")
338
339 def test_illegal_yield_2(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000340 # Illegal return in generator: def f(): return 1; yield 1
Fred Drakecf580c72001-07-17 03:01:29 +0000341 tree = \
342 (257,
343 (264,
344 (265,
345 (266,
346 (278,
347 (1, 'from'),
348 (281, (1, '__future__')),
349 (1, 'import'),
350 (279, (1, 'generators')))),
351 (4, ''))),
352 (264,
353 (285,
354 (259,
355 (1, 'def'),
356 (1, 'f'),
357 (260, (7, '('), (8, ')')),
358 (11, ':'),
359 (291,
360 (4, ''),
361 (5, ''),
362 (264,
363 (265,
364 (266,
365 (272,
366 (275,
367 (1, 'return'),
368 (313,
369 (292,
370 (293,
371 (294,
372 (295,
373 (297,
374 (298,
375 (299,
376 (300,
377 (301,
378 (302, (303, (304, (305, (2, '1')))))))))))))))))),
379 (264,
380 (265,
381 (266,
382 (272,
383 (276,
384 (1, 'yield'),
385 (313,
386 (292,
387 (293,
388 (294,
389 (295,
390 (297,
391 (298,
392 (299,
393 (300,
394 (301,
395 (302,
396 (303, (304, (305, (2, '1')))))))))))))))))),
397 (4, ''))),
398 (6, ''))))),
399 (4, ''),
400 (0, ''))))
401 self.check_bad_tree(tree, "def f():\n return 1\n yield 1")
402
Fred Drake58422e52001-06-04 03:56:24 +0000403 def test_a_comma_comma_c(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000404 # Illegal input: a,,c
Fred Drake58422e52001-06-04 03:56:24 +0000405 tree = \
406 (258,
407 (311,
408 (290,
409 (291,
410 (292,
411 (293,
412 (295,
413 (296,
414 (297,
415 (298, (299, (300, (301, (302, (303, (1, 'a')))))))))))))),
416 (12, ','),
417 (12, ','),
418 (290,
419 (291,
420 (292,
421 (293,
422 (295,
423 (296,
424 (297,
425 (298, (299, (300, (301, (302, (303, (1, 'c'))))))))))))))),
426 (4, ''),
427 (0, ''))
428 self.check_bad_tree(tree, "a,,c")
429
430 def test_illegal_operator(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000431 # Illegal input: a $= b
Fred Drake58422e52001-06-04 03:56:24 +0000432 tree = \
433 (257,
434 (264,
435 (265,
436 (266,
437 (267,
438 (312,
439 (291,
440 (292,
441 (293,
442 (294,
443 (296,
444 (297,
445 (298,
446 (299,
447 (300, (301, (302, (303, (304, (1, 'a'))))))))))))))),
448 (268, (37, '$=')),
449 (312,
450 (291,
451 (292,
452 (293,
453 (294,
454 (296,
455 (297,
456 (298,
457 (299,
458 (300, (301, (302, (303, (304, (1, 'b'))))))))))))))))),
459 (4, ''))),
460 (0, ''))
461 self.check_bad_tree(tree, "a $= b")
Fred Drake79ca79d2000-08-21 22:30:53 +0000462
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000463 def test_malformed_global(self):
464 #doesn't have global keyword in ast
465 tree = (257,
466 (264,
467 (265,
468 (266,
469 (282, (1, 'foo'))), (4, ''))),
470 (4, ''),
Tim Petersf2715e02003-02-19 02:35:07 +0000471 (0, ''))
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000472 self.check_bad_tree(tree, "malformed global ast")
Fred Drake79ca79d2000-08-21 22:30:53 +0000473
Mark Dickinson1b9b5722010-07-04 18:16:43 +0000474 def test_missing_import_source(self):
475 # from import fred
476 tree = \
477 (257,
478 (268,
479 (269,
480 (270,
481 (282,
482 (284, (1, 'from'), (1, 'import'),
483 (287, (285, (1, 'fred')))))),
484 (4, ''))),
485 (4, ''), (0, ''))
486 self.check_bad_tree(tree, "from import fred")
487
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000488
489class CompileTestCase(unittest.TestCase):
490
491 # These tests are very minimal. :-(
492
493 def test_compile_expr(self):
494 st = parser.expr('2 + 3')
495 code = parser.compilest(st)
496 self.assertEquals(eval(code), 5)
497
498 def test_compile_suite(self):
499 st = parser.suite('x = 2; y = x + 3')
500 code = parser.compilest(st)
501 globs = {}
Georg Brandl7cae87c2006-09-06 06:51:57 +0000502 exec(code, globs)
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000503 self.assertEquals(globs['y'], 5)
504
505 def test_compile_error(self):
506 st = parser.suite('1 = 3 + 4')
507 self.assertRaises(SyntaxError, parser.compilest, st)
508
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000509 def test_compile_badunicode(self):
Guido van Rossum7eb6ca52007-07-18 21:00:22 +0000510 st = parser.suite('a = "\\U12345678"')
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000511 self.assertRaises(SyntaxError, parser.compilest, st)
Guido van Rossum7eb6ca52007-07-18 21:00:22 +0000512 st = parser.suite('a = "\\u1"')
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000513 self.assertRaises(SyntaxError, parser.compilest, st)
514
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000515class ParserStackLimitTestCase(unittest.TestCase):
Mark Dickinsona58eed92010-06-17 12:37:17 +0000516 """try to push the parser to/over its limits.
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000517 see http://bugs.python.org/issue1881 for a discussion
518 """
519 def _nested_expression(self, level):
520 return "["*level+"]"*level
521
522 def test_deeply_nested_list(self):
523 # XXX used to be 99 levels in 2.x
524 e = self._nested_expression(93)
525 st = parser.expr(e)
526 st.compile()
527
528 def test_trigger_memory_error(self):
529 e = self._nested_expression(100)
Christian Heimesb186d002008-03-18 15:15:01 +0000530 print("Expecting 's_push: parser stack overflow' in next line",
531 file=sys.stderr)
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000532 self.assertRaises(MemoryError, parser.expr, e)
533
Mark Dickinson211c6252009-02-01 10:28:51 +0000534class STObjectTestCase(unittest.TestCase):
535 """Test operations on ST objects themselves"""
536
537 def test_comparisons(self):
538 # ST objects should support order and equality comparisons
539 st1 = parser.expr('2 + 3')
540 st2 = parser.suite('x = 2; y = x + 3')
541 st3 = parser.expr('list(x**3 for x in range(20))')
542 st1_copy = parser.expr('2 + 3')
543 st2_copy = parser.suite('x = 2; y = x + 3')
544 st3_copy = parser.expr('list(x**3 for x in range(20))')
545
546 # exercise fast path for object identity
547 self.assertEquals(st1 == st1, True)
548 self.assertEquals(st2 == st2, True)
549 self.assertEquals(st3 == st3, True)
550 # slow path equality
551 self.assertEqual(st1, st1_copy)
552 self.assertEqual(st2, st2_copy)
553 self.assertEqual(st3, st3_copy)
554 self.assertEquals(st1 == st2, False)
555 self.assertEquals(st1 == st3, False)
556 self.assertEquals(st2 == st3, False)
557 self.assertEquals(st1 != st1, False)
558 self.assertEquals(st2 != st2, False)
559 self.assertEquals(st3 != st3, False)
560 self.assertEquals(st1 != st1_copy, False)
561 self.assertEquals(st2 != st2_copy, False)
562 self.assertEquals(st3 != st3_copy, False)
563 self.assertEquals(st2 != st1, True)
564 self.assertEquals(st1 != st3, True)
565 self.assertEquals(st3 != st2, True)
566 # we don't particularly care what the ordering is; just that
567 # it's usable and self-consistent
568 self.assertEquals(st1 < st2, not (st2 <= st1))
569 self.assertEquals(st1 < st3, not (st3 <= st1))
570 self.assertEquals(st2 < st3, not (st3 <= st2))
571 self.assertEquals(st1 < st2, st2 > st1)
572 self.assertEquals(st1 < st3, st3 > st1)
573 self.assertEquals(st2 < st3, st3 > st2)
574 self.assertEquals(st1 <= st2, st2 >= st1)
575 self.assertEquals(st3 <= st1, st1 >= st3)
576 self.assertEquals(st2 <= st3, st3 >= st2)
577 # transitivity
578 bottom = min(st1, st2, st3)
579 top = max(st1, st2, st3)
580 mid = sorted([st1, st2, st3])[1]
Georg Brandlab91fde2009-08-13 08:51:18 +0000581 self.assertTrue(bottom < mid)
582 self.assertTrue(bottom < top)
583 self.assertTrue(mid < top)
584 self.assertTrue(bottom <= mid)
585 self.assertTrue(bottom <= top)
586 self.assertTrue(mid <= top)
587 self.assertTrue(bottom <= bottom)
588 self.assertTrue(mid <= mid)
589 self.assertTrue(top <= top)
Mark Dickinson211c6252009-02-01 10:28:51 +0000590 # interaction with other types
591 self.assertEquals(st1 == 1588.602459, False)
592 self.assertEquals('spanish armada' != st2, True)
593 self.assertRaises(TypeError, operator.ge, st3, None)
594 self.assertRaises(TypeError, operator.le, False, st1)
595 self.assertRaises(TypeError, operator.lt, st1, 1815)
596 self.assertRaises(TypeError, operator.gt, b'waterloo', st2)
597
598
599 # XXX tests for pickling and unpickling of ST objects should go here
600
601
Fred Drake2e2be372001-09-20 21:33:42 +0000602def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000603 support.run_unittest(
Walter Dörwald21d3a322003-05-01 17:45:56 +0000604 RoundtripLegalSyntaxTestCase,
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000605 IllegalSyntaxTestCase,
606 CompileTestCase,
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000607 ParserStackLimitTestCase,
Mark Dickinson211c6252009-02-01 10:28:51 +0000608 STObjectTestCase,
Walter Dörwald21d3a322003-05-01 17:45:56 +0000609 )
Fred Drake2e2be372001-09-20 21:33:42 +0000610
611
612if __name__ == "__main__":
613 test_main()