aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/test/test_parser.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_parser.py')
-rw-r--r--Lib/test/test_parser.py243
1 files changed, 161 insertions, 82 deletions
diff --git a/Lib/test/test_parser.py b/Lib/test/test_parser.py
index 12fa89cd464..70eb9c0cc2b 100644
--- a/Lib/test/test_parser.py
+++ b/Lib/test/test_parser.py
@@ -1,8 +1,9 @@
import parser
import unittest
import sys
+import operator
import struct
-from test import test_support as support
+from test import support
#
# First, we test that we can generate trees from valid source fragments,
@@ -17,7 +18,7 @@ class RoundtripLegalSyntaxTestCase(unittest.TestCase):
t = st1.totuple()
try:
st2 = parser.sequence2st(t)
- except parser.ParserError, why:
+ except parser.ParserError as why:
self.fail("could not roundtrip %r: %s" % (s, why))
self.assertEqual(t, st2.totuple(),
@@ -32,8 +33,8 @@ class RoundtripLegalSyntaxTestCase(unittest.TestCase):
suite = parser.suite("from __future__ import unicode_literals; x = ''")
code = suite.compile()
scope = {}
- exec code in scope
- self.assertIsInstance(scope["x"], unicode)
+ exec(code, {}, scope)
+ self.assertIsInstance(scope["x"], str)
def check_suite(self, s):
self.roundtrip(parser.suite, s)
@@ -57,39 +58,25 @@ class RoundtripLegalSyntaxTestCase(unittest.TestCase):
" if (yield):\n"
" yield x\n")
+ def test_nonlocal_statement(self):
+ self.check_suite("def f():\n"
+ " x = 0\n"
+ " def g():\n"
+ " nonlocal x\n")
+ self.check_suite("def f():\n"
+ " x = y = 0\n"
+ " def g():\n"
+ " nonlocal x, y\n")
+
def test_expressions(self):
self.check_expr("foo(1)")
- self.check_expr("{1:1}")
- self.check_expr("{1:1, 2:2, 3:3}")
- self.check_expr("{1:1, 2:2, 3:3,}")
- self.check_expr("{1}")
- self.check_expr("{1, 2, 3}")
- self.check_expr("{1, 2, 3,}")
- self.check_expr("[]")
- self.check_expr("[1]")
self.check_expr("[1, 2, 3]")
- self.check_expr("[1, 2, 3,]")
- self.check_expr("()")
- self.check_expr("(1,)")
- self.check_expr("(1, 2, 3)")
- self.check_expr("(1, 2, 3,)")
self.check_expr("[x**3 for x in range(20)]")
self.check_expr("[x**3 for x in range(20) if x % 3]")
self.check_expr("[x**3 for x in range(20) if x % 2 if x % 3]")
- self.check_expr("[x+y for x in range(30) for y in range(20) if x % 2 if y % 3]")
- #self.check_expr("[x for x in lambda: True, lambda: False if x()]")
self.check_expr("list(x**3 for x in range(20))")
self.check_expr("list(x**3 for x in range(20) if x % 3)")
self.check_expr("list(x**3 for x in range(20) if x % 2 if x % 3)")
- self.check_expr("list(x+y for x in range(30) for y in range(20) if x % 2 if y % 3)")
- self.check_expr("{x**3 for x in range(30)}")
- self.check_expr("{x**3 for x in range(30) if x % 3}")
- self.check_expr("{x**3 for x in range(30) if x % 2 if x % 3}")
- self.check_expr("{x+y for x in range(30) for y in range(20) if x % 2 if y % 3}")
- self.check_expr("{x**3: y**2 for x, y in zip(range(30), range(30))}")
- self.check_expr("{x**3: y**2 for x, y in zip(range(30), range(30)) if x % 3}")
- self.check_expr("{x**3: y**2 for x, y in zip(range(30), range(30)) if x % 3 if y % 3}")
- self.check_expr("{x:y for x in range(30) for y in range(20) if x % 2 if y % 3}")
self.check_expr("foo(*args)")
self.check_expr("foo(*args, **kw)")
self.check_expr("foo(**kw)")
@@ -118,17 +105,10 @@ class RoundtripLegalSyntaxTestCase(unittest.TestCase):
self.check_expr("lambda foo=bar, blaz=blat+2, **z: 0")
self.check_expr("lambda foo=bar, blaz=blat+2, *y, **z: 0")
self.check_expr("lambda x, *y, **z: 0")
- self.check_expr("lambda x: 5 if x else 2")
self.check_expr("(x for x in range(10))")
self.check_expr("foo(x for x in range(10))")
-
- def test_print(self):
- self.check_suite("print")
- self.check_suite("print 1")
- self.check_suite("print 1,")
- self.check_suite("print >>fp")
- self.check_suite("print >>fp, 1")
- self.check_suite("print >>fp, 1,")
+ self.check_expr("...")
+ self.check_expr("a[...]")
def test_simple_expression(self):
# expr_stmt
@@ -179,8 +159,30 @@ class RoundtripLegalSyntaxTestCase(unittest.TestCase):
self.check_suite("@funcattrs()\n"
"def f(): pass")
+ # keyword-only arguments
+ self.check_suite("def f(*, a): pass")
+ self.check_suite("def f(*, a = 5): pass")
+ self.check_suite("def f(*, a = 5, b): pass")
+ self.check_suite("def f(*, a, b = 5): pass")
+ self.check_suite("def f(*, a, b = 5, **kwds): pass")
+ self.check_suite("def f(*args, a): pass")
+ self.check_suite("def f(*args, a = 5): pass")
+ self.check_suite("def f(*args, a = 5, b): pass")
+ self.check_suite("def f(*args, a, b = 5): pass")
+ self.check_suite("def f(*args, a, b = 5, **kwds): pass")
+
+ # function annotations
+ self.check_suite("def f(a: int): pass")
+ self.check_suite("def f(a: int = 5): pass")
+ self.check_suite("def f(*args: list): pass")
+ self.check_suite("def f(**kwds: dict): pass")
+ self.check_suite("def f(*, a: int): pass")
+ self.check_suite("def f(*, a: int = 5): pass")
+ self.check_suite("def f() -> int: pass")
+
def test_class_defs(self):
self.check_suite("class foo():pass")
+ self.check_suite("class foo(object):pass")
self.check_suite("@class_decorator\n"
"class foo():pass")
self.check_suite("@class_decorator(arg)\n"
@@ -189,7 +191,6 @@ class RoundtripLegalSyntaxTestCase(unittest.TestCase):
"@decorator2\n"
"class foo():pass")
-
def test_import_from_statement(self):
self.check_suite("from sys.path import *")
self.check_suite("from sys.path import dirname")
@@ -225,8 +226,14 @@ class RoundtripLegalSyntaxTestCase(unittest.TestCase):
def test_relative_imports(self):
self.check_suite("from . import name")
self.check_suite("from .. import name")
+ # check all the way up to '....', since '...' is tokenized
+ # differently from '.' (it's an ellipsis token).
+ self.check_suite("from ... import name")
+ self.check_suite("from .... import name")
self.check_suite("from .pkg import name")
self.check_suite("from ..pkg import name")
+ self.check_suite("from ...pkg import name")
+ self.check_suite("from ....pkg import name")
def test_pep263(self):
self.check_suite("# -*- coding: iso-8859-1 -*-\n"
@@ -250,12 +257,6 @@ class RoundtripLegalSyntaxTestCase(unittest.TestCase):
self.check_suite("try: pass\nexcept: pass\nelse: pass\n"
"finally: pass\n")
- def test_except_clause(self):
- self.check_suite("try: pass\nexcept: pass\n")
- self.check_suite("try: pass\nexcept A: pass\n")
- self.check_suite("try: pass\nexcept A, e: pass\n")
- self.check_suite("try: pass\nexcept A as e: pass\n")
-
def test_position(self):
# An absolutely minimal test of position information. Better
# tests would be a big project.
@@ -293,6 +294,43 @@ class RoundtripLegalSyntaxTestCase(unittest.TestCase):
(0, '', 2, -1)],
terminals)
+ def test_extended_unpacking(self):
+ self.check_suite("*a = y")
+ self.check_suite("x, *b, = m")
+ self.check_suite("[*a, *b] = y")
+ self.check_suite("for [*x, b] in x: pass")
+
+ def test_raise_statement(self):
+ self.check_suite("raise\n")
+ self.check_suite("raise e\n")
+ self.check_suite("try:\n"
+ " suite\n"
+ "except Exception as e:\n"
+ " raise ValueError from e\n")
+
+ def test_set_displays(self):
+ self.check_expr('{2}')
+ self.check_expr('{2,}')
+ self.check_expr('{2, 3}')
+ self.check_expr('{2, 3,}')
+
+ def test_dict_displays(self):
+ self.check_expr('{}')
+ self.check_expr('{a:b}')
+ self.check_expr('{a:b,}')
+ self.check_expr('{a:b, c:d}')
+ self.check_expr('{a:b, c:d,}')
+
+ def test_set_comprehensions(self):
+ self.check_expr('{x for x in seq}')
+ self.check_expr('{f(x) for x in seq}')
+ self.check_expr('{f(x) for x in seq if condition(x)}')
+
+ def test_dict_comprehensions(self):
+ self.check_expr('{x:x for x in seq}')
+ self.check_expr('{x**2:x[3] for x in seq if condition(x)}')
+ self.check_expr('{x:x for x in seq1 for y in seq2 if condition(x, y)}')
+
#
# Second, we take *invalid* trees and make sure we get ParserError
@@ -432,29 +470,6 @@ class IllegalSyntaxTestCase(unittest.TestCase):
(0, ''))))
self.check_bad_tree(tree, "def f():\n return 1\n yield 1")
- def test_print_chevron_comma(self):
- # Illegal input: print >>fp,
- tree = \
- (257,
- (264,
- (265,
- (266,
- (268,
- (1, 'print'),
- (35, '>>'),
- (290,
- (291,
- (292,
- (293,
- (295,
- (296,
- (297,
- (298, (299, (300, (301, (302, (303, (1, 'fp')))))))))))))),
- (12, ','))),
- (4, ''))),
- (0, ''))
- self.check_bad_tree(tree, "print >>fp,")
-
def test_a_comma_comma_c(self):
# Illegal input: a,,c
tree = \
@@ -527,18 +542,18 @@ class IllegalSyntaxTestCase(unittest.TestCase):
self.check_bad_tree(tree, "malformed global ast")
def test_missing_import_source(self):
- # from import a
+ # from import fred
tree = \
(257,
- (267,
- (268,
- (269,
- (281,
- (283, (1, 'from'), (1, 'import'),
- (286, (284, (1, 'fred')))))),
+ (268,
+ (269,
+ (270,
+ (282,
+ (284, (1, 'from'), (1, 'import'),
+ (287, (285, (1, 'fred')))))),
(4, ''))),
(4, ''), (0, ''))
- self.check_bad_tree(tree, "from import a")
+ self.check_bad_tree(tree, "from import fred")
class CompileTestCase(unittest.TestCase):
@@ -554,7 +569,7 @@ class CompileTestCase(unittest.TestCase):
st = parser.suite('x = 2; y = x + 3')
code = parser.compilest(st)
globs = {}
- exec code in globs
+ exec(code, globs)
self.assertEqual(globs['y'], 5)
def test_compile_error(self):
@@ -562,9 +577,9 @@ class CompileTestCase(unittest.TestCase):
self.assertRaises(SyntaxError, parser.compilest, st)
def test_compile_badunicode(self):
- st = parser.suite('a = u"\U12345678"')
+ st = parser.suite('a = "\\U12345678"')
self.assertRaises(SyntaxError, parser.compilest, st)
- st = parser.suite('a = u"\u1"')
+ st = parser.suite('a = "\\u1"')
self.assertRaises(SyntaxError, parser.compilest, st)
def test_issue_9011(self):
@@ -577,27 +592,90 @@ class CompileTestCase(unittest.TestCase):
code2 = parser.compilest(st)
self.assertEqual(eval(code2), -3)
-
class ParserStackLimitTestCase(unittest.TestCase):
- """try to push the parser to/over it's limits.
+ """try to push the parser to/over its limits.
see http://bugs.python.org/issue1881 for a discussion
"""
def _nested_expression(self, level):
return "["*level+"]"*level
def test_deeply_nested_list(self):
- e = self._nested_expression(99)
+ # XXX used to be 99 levels in 2.x
+ e = self._nested_expression(93)
st = parser.expr(e)
st.compile()
def test_trigger_memory_error(self):
e = self._nested_expression(100)
- print >>sys.stderr, "Expecting 's_push: parser stack overflow' in next line"
+ print("Expecting 's_push: parser stack overflow' in next line",
+ file=sys.stderr)
+ sys.stderr.flush()
self.assertRaises(MemoryError, parser.expr, e)
class STObjectTestCase(unittest.TestCase):
"""Test operations on ST objects themselves"""
+ def test_comparisons(self):
+ # ST objects should support order and equality comparisons
+ st1 = parser.expr('2 + 3')
+ st2 = parser.suite('x = 2; y = x + 3')
+ st3 = parser.expr('list(x**3 for x in range(20))')
+ st1_copy = parser.expr('2 + 3')
+ st2_copy = parser.suite('x = 2; y = x + 3')
+ st3_copy = parser.expr('list(x**3 for x in range(20))')
+
+ # exercise fast path for object identity
+ self.assertEqual(st1 == st1, True)
+ self.assertEqual(st2 == st2, True)
+ self.assertEqual(st3 == st3, True)
+ # slow path equality
+ self.assertEqual(st1, st1_copy)
+ self.assertEqual(st2, st2_copy)
+ self.assertEqual(st3, st3_copy)
+ self.assertEqual(st1 == st2, False)
+ self.assertEqual(st1 == st3, False)
+ self.assertEqual(st2 == st3, False)
+ self.assertEqual(st1 != st1, False)
+ self.assertEqual(st2 != st2, False)
+ self.assertEqual(st3 != st3, False)
+ self.assertEqual(st1 != st1_copy, False)
+ self.assertEqual(st2 != st2_copy, False)
+ self.assertEqual(st3 != st3_copy, False)
+ self.assertEqual(st2 != st1, True)
+ self.assertEqual(st1 != st3, True)
+ self.assertEqual(st3 != st2, True)
+ # we don't particularly care what the ordering is; just that
+ # it's usable and self-consistent
+ self.assertEqual(st1 < st2, not (st2 <= st1))
+ self.assertEqual(st1 < st3, not (st3 <= st1))
+ self.assertEqual(st2 < st3, not (st3 <= st2))
+ self.assertEqual(st1 < st2, st2 > st1)
+ self.assertEqual(st1 < st3, st3 > st1)
+ self.assertEqual(st2 < st3, st3 > st2)
+ self.assertEqual(st1 <= st2, st2 >= st1)
+ self.assertEqual(st3 <= st1, st1 >= st3)
+ self.assertEqual(st2 <= st3, st3 >= st2)
+ # transitivity
+ bottom = min(st1, st2, st3)
+ top = max(st1, st2, st3)
+ mid = sorted([st1, st2, st3])[1]
+ self.assertTrue(bottom < mid)
+ self.assertTrue(bottom < top)
+ self.assertTrue(mid < top)
+ self.assertTrue(bottom <= mid)
+ self.assertTrue(bottom <= top)
+ self.assertTrue(mid <= top)
+ self.assertTrue(bottom <= bottom)
+ self.assertTrue(mid <= mid)
+ self.assertTrue(top <= top)
+ # interaction with other types
+ self.assertEqual(st1 == 1588.602459, False)
+ self.assertEqual('spanish armada' != st2, True)
+ self.assertRaises(TypeError, operator.ge, st3, None)
+ self.assertRaises(TypeError, operator.le, False, st1)
+ self.assertRaises(TypeError, operator.lt, st1, 1815)
+ self.assertRaises(TypeError, operator.gt, b'waterloo', st2)
+
check_sizeof = support.check_sizeof
@support.cpython_only
@@ -639,6 +717,7 @@ class STObjectTestCase(unittest.TestCase):
# XXX tests for pickling and unpickling of ST objects should go here
+
def test_main():
support.run_unittest(
RoundtripLegalSyntaxTestCase,