Home | History | Annotate | Download | only in test
      1 import copy
      2 import parser
      3 import pickle
      4 import unittest
      5 import operator
      6 import struct
      7 from test import support
      8 from test.support.script_helper import assert_python_failure
      9 
     10 #
     11 #  First, we test that we can generate trees from valid source fragments,
     12 #  and that these valid trees are indeed allowed by the tree-loading side
     13 #  of the parser module.
     14 #
     15 
     16 class RoundtripLegalSyntaxTestCase(unittest.TestCase):
     17 
     18     def roundtrip(self, f, s):
     19         st1 = f(s)
     20         t = st1.totuple()
     21         try:
     22             st2 = parser.sequence2st(t)
     23         except parser.ParserError as why:
     24             self.fail("could not roundtrip %r: %s" % (s, why))
     25 
     26         self.assertEqual(t, st2.totuple(),
     27                          "could not re-generate syntax tree")
     28 
     29     def check_expr(self, s):
     30         self.roundtrip(parser.expr, s)
     31 
     32     def test_flags_passed(self):
     33         # The unicode literals flags has to be passed from the parser to AST
     34         # generation.
     35         suite = parser.suite("from __future__ import unicode_literals; x = ''")
     36         code = suite.compile()
     37         scope = {}
     38         exec(code, {}, scope)
     39         self.assertIsInstance(scope["x"], str)
     40 
     41     def check_suite(self, s):
     42         self.roundtrip(parser.suite, s)
     43 
     44     def test_yield_statement(self):
     45         self.check_suite("def f(): yield 1")
     46         self.check_suite("def f(): yield")
     47         self.check_suite("def f(): x += yield")
     48         self.check_suite("def f(): x = yield 1")
     49         self.check_suite("def f(): x = y = yield 1")
     50         self.check_suite("def f(): x = yield")
     51         self.check_suite("def f(): x = y = yield")
     52         self.check_suite("def f(): 1 + (yield)*2")
     53         self.check_suite("def f(): (yield 1)*2")
     54         self.check_suite("def f(): return; yield 1")
     55         self.check_suite("def f(): yield 1; return")
     56         self.check_suite("def f(): yield from 1")
     57         self.check_suite("def f(): x = yield from 1")
     58         self.check_suite("def f(): f((yield from 1))")
     59         self.check_suite("def f(): yield 1; return 1")
     60         self.check_suite("def f():\n"
     61                          "    for x in range(30):\n"
     62                          "        yield x\n")
     63         self.check_suite("def f():\n"
     64                          "    if (yield):\n"
     65                          "        yield x\n")
     66 
     67     def test_await_statement(self):
     68         self.check_suite("async def f():\n await smth()")
     69         self.check_suite("async def f():\n foo = await smth()")
     70         self.check_suite("async def f():\n foo, bar = await smth()")
     71         self.check_suite("async def f():\n (await smth())")
     72         self.check_suite("async def f():\n foo((await smth()))")
     73         self.check_suite("async def f():\n await foo(); return 42")
     74 
     75     def test_async_with_statement(self):
     76         self.check_suite("async def f():\n async with 1: pass")
     77         self.check_suite("async def f():\n async with a as b, c as d: pass")
     78 
     79     def test_async_for_statement(self):
     80         self.check_suite("async def f():\n async for i in (): pass")
     81         self.check_suite("async def f():\n async for i, b in (): pass")
     82 
     83     def test_nonlocal_statement(self):
     84         self.check_suite("def f():\n"
     85                          "    x = 0\n"
     86                          "    def g():\n"
     87                          "        nonlocal x\n")
     88         self.check_suite("def f():\n"
     89                          "    x = y = 0\n"
     90                          "    def g():\n"
     91                          "        nonlocal x, y\n")
     92 
     93     def test_expressions(self):
     94         self.check_expr("foo(1)")
     95         self.check_expr("[1, 2, 3]")
     96         self.check_expr("[x**3 for x in range(20)]")
     97         self.check_expr("[x**3 for x in range(20) if x % 3]")
     98         self.check_expr("[x**3 for x in range(20) if x % 2 if x % 3]")
     99         self.check_expr("list(x**3 for x in range(20))")
    100         self.check_expr("list(x**3 for x in range(20) if x % 3)")
    101         self.check_expr("list(x**3 for x in range(20) if x % 2 if x % 3)")
    102         self.check_expr("foo(*args)")
    103         self.check_expr("foo(*args, **kw)")
    104         self.check_expr("foo(**kw)")
    105         self.check_expr("foo(key=value)")
    106         self.check_expr("foo(key=value, *args)")
    107         self.check_expr("foo(key=value, *args, **kw)")
    108         self.check_expr("foo(key=value, **kw)")
    109         self.check_expr("foo(a, b, c, *args)")
    110         self.check_expr("foo(a, b, c, *args, **kw)")
    111         self.check_expr("foo(a, b, c, **kw)")
    112         self.check_expr("foo(a, *args, keyword=23)")
    113         self.check_expr("foo + bar")
    114         self.check_expr("foo - bar")
    115         self.check_expr("foo * bar")
    116         self.check_expr("foo / bar")
    117         self.check_expr("foo // bar")
    118         self.check_expr("lambda: 0")
    119         self.check_expr("lambda x: 0")
    120         self.check_expr("lambda *y: 0")
    121         self.check_expr("lambda *y, **z: 0")
    122         self.check_expr("lambda **z: 0")
    123         self.check_expr("lambda x, y: 0")
    124         self.check_expr("lambda foo=bar: 0")
    125         self.check_expr("lambda foo=bar, spaz=nifty+spit: 0")
    126         self.check_expr("lambda foo=bar, **z: 0")
    127         self.check_expr("lambda foo=bar, blaz=blat+2, **z: 0")
    128         self.check_expr("lambda foo=bar, blaz=blat+2, *y, **z: 0")
    129         self.check_expr("lambda x, *y, **z: 0")
    130         self.check_expr("(x for x in range(10))")
    131         self.check_expr("foo(x for x in range(10))")
    132         self.check_expr("...")
    133         self.check_expr("a[...]")
    134 
    135     def test_simple_expression(self):
    136         # expr_stmt
    137         self.check_suite("a")
    138 
    139     def test_simple_assignments(self):
    140         self.check_suite("a = b")
    141         self.check_suite("a = b = c = d = e")
    142 
    143     def test_var_annot(self):
    144         self.check_suite("x: int = 5")
    145         self.check_suite("y: List[T] = []; z: [list] = fun()")
    146         self.check_suite("x: tuple = (1, 2)")
    147         self.check_suite("d[f()]: int = 42")
    148         self.check_suite("f(d[x]): str = 'abc'")
    149         self.check_suite("x.y.z.w: complex = 42j")
    150         self.check_suite("x: int")
    151         self.check_suite("def f():\n"
    152                          "    x: str\n"
    153                          "    y: int = 5\n")
    154         self.check_suite("class C:\n"
    155                          "    x: str\n"
    156                          "    y: int = 5\n")
    157         self.check_suite("class C:\n"
    158                          "    def __init__(self, x: int) -> None:\n"
    159                          "        self.x: int = x\n")
    160         # double check for nonsense
    161         with self.assertRaises(SyntaxError):
    162             exec("2+2: int", {}, {})
    163         with self.assertRaises(SyntaxError):
    164             exec("[]: int = 5", {}, {})
    165         with self.assertRaises(SyntaxError):
    166             exec("x, *y, z: int = range(5)", {}, {})
    167         with self.assertRaises(SyntaxError):
    168             exec("t: tuple = 1, 2", {}, {})
    169         with self.assertRaises(SyntaxError):
    170             exec("u = v: int", {}, {})
    171         with self.assertRaises(SyntaxError):
    172             exec("False: int", {}, {})
    173         with self.assertRaises(SyntaxError):
    174             exec("x.False: int", {}, {})
    175         with self.assertRaises(SyntaxError):
    176             exec("x.y,: int", {}, {})
    177         with self.assertRaises(SyntaxError):
    178             exec("[0]: int", {}, {})
    179         with self.assertRaises(SyntaxError):
    180             exec("f(): int", {}, {})
    181 
    182     def test_simple_augmented_assignments(self):
    183         self.check_suite("a += b")
    184         self.check_suite("a -= b")
    185         self.check_suite("a *= b")
    186         self.check_suite("a /= b")
    187         self.check_suite("a //= b")
    188         self.check_suite("a %= b")
    189         self.check_suite("a &= b")
    190         self.check_suite("a |= b")
    191         self.check_suite("a ^= b")
    192         self.check_suite("a <<= b")
    193         self.check_suite("a >>= b")
    194         self.check_suite("a **= b")
    195 
    196     def test_function_defs(self):
    197         self.check_suite("def f(): pass")
    198         self.check_suite("def f(*args): pass")
    199         self.check_suite("def f(*args, **kw): pass")
    200         self.check_suite("def f(**kw): pass")
    201         self.check_suite("def f(foo=bar): pass")
    202         self.check_suite("def f(foo=bar, *args): pass")
    203         self.check_suite("def f(foo=bar, *args, **kw): pass")
    204         self.check_suite("def f(foo=bar, **kw): pass")
    205 
    206         self.check_suite("def f(a, b): pass")
    207         self.check_suite("def f(a, b, *args): pass")
    208         self.check_suite("def f(a, b, *args, **kw): pass")
    209         self.check_suite("def f(a, b, **kw): pass")
    210         self.check_suite("def f(a, b, foo=bar): pass")
    211         self.check_suite("def f(a, b, foo=bar, *args): pass")
    212         self.check_suite("def f(a, b, foo=bar, *args, **kw): pass")
    213         self.check_suite("def f(a, b, foo=bar, **kw): pass")
    214 
    215         self.check_suite("@staticmethod\n"
    216                          "def f(): pass")
    217         self.check_suite("@staticmethod\n"
    218                          "@funcattrs(x, y)\n"
    219                          "def f(): pass")
    220         self.check_suite("@funcattrs()\n"
    221                          "def f(): pass")
    222 
    223         # keyword-only arguments
    224         self.check_suite("def f(*, a): pass")
    225         self.check_suite("def f(*, a = 5): pass")
    226         self.check_suite("def f(*, a = 5, b): pass")
    227         self.check_suite("def f(*, a, b = 5): pass")
    228         self.check_suite("def f(*, a, b = 5, **kwds): pass")
    229         self.check_suite("def f(*args, a): pass")
    230         self.check_suite("def f(*args, a = 5): pass")
    231         self.check_suite("def f(*args, a = 5, b): pass")
    232         self.check_suite("def f(*args, a, b = 5): pass")
    233         self.check_suite("def f(*args, a, b = 5, **kwds): pass")
    234 
    235         # function annotations
    236         self.check_suite("def f(a: int): pass")
    237         self.check_suite("def f(a: int = 5): pass")
    238         self.check_suite("def f(*args: list): pass")
    239         self.check_suite("def f(**kwds: dict): pass")
    240         self.check_suite("def f(*, a: int): pass")
    241         self.check_suite("def f(*, a: int = 5): pass")
    242         self.check_suite("def f() -> int: pass")
    243 
    244     def test_class_defs(self):
    245         self.check_suite("class foo():pass")
    246         self.check_suite("class foo(object):pass")
    247         self.check_suite("@class_decorator\n"
    248                          "class foo():pass")
    249         self.check_suite("@class_decorator(arg)\n"
    250                          "class foo():pass")
    251         self.check_suite("@decorator1\n"
    252                          "@decorator2\n"
    253                          "class foo():pass")
    254 
    255     def test_import_from_statement(self):
    256         self.check_suite("from sys.path import *")
    257         self.check_suite("from sys.path import dirname")
    258         self.check_suite("from sys.path import (dirname)")
    259         self.check_suite("from sys.path import (dirname,)")
    260         self.check_suite("from sys.path import dirname as my_dirname")
    261         self.check_suite("from sys.path import (dirname as my_dirname)")
    262         self.check_suite("from sys.path import (dirname as my_dirname,)")
    263         self.check_suite("from sys.path import dirname, basename")
    264         self.check_suite("from sys.path import (dirname, basename)")
    265         self.check_suite("from sys.path import (dirname, basename,)")
    266         self.check_suite(
    267             "from sys.path import dirname as my_dirname, basename")
    268         self.check_suite(
    269             "from sys.path import (dirname as my_dirname, basename)")
    270         self.check_suite(
    271             "from sys.path import (dirname as my_dirname, basename,)")
    272         self.check_suite(
    273             "from sys.path import dirname, basename as my_basename")
    274         self.check_suite(
    275             "from sys.path import (dirname, basename as my_basename)")
    276         self.check_suite(
    277             "from sys.path import (dirname, basename as my_basename,)")
    278         self.check_suite("from .bogus import x")
    279 
    280     def test_basic_import_statement(self):
    281         self.check_suite("import sys")
    282         self.check_suite("import sys as system")
    283         self.check_suite("import sys, math")
    284         self.check_suite("import sys as system, math")
    285         self.check_suite("import sys, math as my_math")
    286 
    287     def test_relative_imports(self):
    288         self.check_suite("from . import name")
    289         self.check_suite("from .. import name")
    290         # check all the way up to '....', since '...' is tokenized
    291         # differently from '.' (it's an ellipsis token).
    292         self.check_suite("from ... import name")
    293         self.check_suite("from .... import name")
    294         self.check_suite("from .pkg import name")
    295         self.check_suite("from ..pkg import name")
    296         self.check_suite("from ...pkg import name")
    297         self.check_suite("from ....pkg import name")
    298 
    299     def test_pep263(self):
    300         self.check_suite("# -*- coding: iso-8859-1 -*-\n"
    301                          "pass\n")
    302 
    303     def test_assert(self):
    304         self.check_suite("assert alo < ahi and blo < bhi\n")
    305 
    306     def test_with(self):
    307         self.check_suite("with open('x'): pass\n")
    308         self.check_suite("with open('x') as f: pass\n")
    309         self.check_suite("with open('x') as f, open('y') as g: pass\n")
    310 
    311     def test_try_stmt(self):
    312         self.check_suite("try: pass\nexcept: pass\n")
    313         self.check_suite("try: pass\nfinally: pass\n")
    314         self.check_suite("try: pass\nexcept A: pass\nfinally: pass\n")
    315         self.check_suite("try: pass\nexcept A: pass\nexcept: pass\n"
    316                          "finally: pass\n")
    317         self.check_suite("try: pass\nexcept: pass\nelse: pass\n")
    318         self.check_suite("try: pass\nexcept: pass\nelse: pass\n"
    319                          "finally: pass\n")
    320 
    321     def test_position(self):
    322         # An absolutely minimal test of position information.  Better
    323         # tests would be a big project.
    324         code = "def f(x):\n    return x + 1"
    325         st = parser.suite(code)
    326 
    327         def walk(tree):
    328             node_type = tree[0]
    329             next = tree[1]
    330             if isinstance(next, (tuple, list)):
    331                 for elt in tree[1:]:
    332                     for x in walk(elt):
    333                         yield x
    334             else:
    335                 yield tree
    336 
    337         expected = [
    338             (1, 'def', 1, 0),
    339             (1, 'f', 1, 4),
    340             (7, '(', 1, 5),
    341             (1, 'x', 1, 6),
    342             (8, ')', 1, 7),
    343             (11, ':', 1, 8),
    344             (4, '', 1, 9),
    345             (5, '', 2, -1),
    346             (1, 'return', 2, 4),
    347             (1, 'x', 2, 11),
    348             (14, '+', 2, 13),
    349             (2, '1', 2, 15),
    350             (4, '', 2, 16),
    351             (6, '', 2, -1),
    352             (4, '', 2, -1),
    353             (0, '', 2, -1),
    354         ]
    355 
    356         self.assertEqual(list(walk(st.totuple(line_info=True, col_info=True))),
    357                          expected)
    358         self.assertEqual(list(walk(st.totuple())),
    359                          [(t, n) for t, n, l, c in expected])
    360         self.assertEqual(list(walk(st.totuple(line_info=True))),
    361                          [(t, n, l) for t, n, l, c in expected])
    362         self.assertEqual(list(walk(st.totuple(col_info=True))),
    363                          [(t, n, c) for t, n, l, c in expected])
    364         self.assertEqual(list(walk(st.tolist(line_info=True, col_info=True))),
    365                          [list(x) for x in expected])
    366         self.assertEqual(list(walk(parser.st2tuple(st, line_info=True,
    367                                                    col_info=True))),
    368                          expected)
    369         self.assertEqual(list(walk(parser.st2list(st, line_info=True,
    370                                                   col_info=True))),
    371                          [list(x) for x in expected])
    372 
    373     def test_extended_unpacking(self):
    374         self.check_suite("*a = y")
    375         self.check_suite("x, *b, = m")
    376         self.check_suite("[*a, *b] = y")
    377         self.check_suite("for [*x, b] in x: pass")
    378 
    379     def test_raise_statement(self):
    380         self.check_suite("raise\n")
    381         self.check_suite("raise e\n")
    382         self.check_suite("try:\n"
    383                          "    suite\n"
    384                          "except Exception as e:\n"
    385                          "    raise ValueError from e\n")
    386 
    387     def test_list_displays(self):
    388         self.check_expr('[]')
    389         self.check_expr('[*{2}, 3, *[4]]')
    390 
    391     def test_set_displays(self):
    392         self.check_expr('{*{2}, 3, *[4]}')
    393         self.check_expr('{2}')
    394         self.check_expr('{2,}')
    395         self.check_expr('{2, 3}')
    396         self.check_expr('{2, 3,}')
    397 
    398     def test_dict_displays(self):
    399         self.check_expr('{}')
    400         self.check_expr('{a:b}')
    401         self.check_expr('{a:b,}')
    402         self.check_expr('{a:b, c:d}')
    403         self.check_expr('{a:b, c:d,}')
    404         self.check_expr('{**{}}')
    405         self.check_expr('{**{}, 3:4, **{5:6, 7:8}}')
    406 
    407     def test_argument_unpacking(self):
    408         self.check_expr("f(*a, **b)")
    409         self.check_expr('f(a, *b, *c, *d)')
    410         self.check_expr('f(**a, **b)')
    411         self.check_expr('f(2, *a, *b, **b, **c, **d)')
    412         self.check_expr("f(*b, *() or () and (), **{} and {}, **() or {})")
    413 
    414     def test_set_comprehensions(self):
    415         self.check_expr('{x for x in seq}')
    416         self.check_expr('{f(x) for x in seq}')
    417         self.check_expr('{f(x) for x in seq if condition(x)}')
    418 
    419     def test_dict_comprehensions(self):
    420         self.check_expr('{x:x for x in seq}')
    421         self.check_expr('{x**2:x[3] for x in seq if condition(x)}')
    422         self.check_expr('{x:x for x in seq1 for y in seq2 if condition(x, y)}')
    423 
    424 
    425 #
    426 #  Second, we take *invalid* trees and make sure we get ParserError
    427 #  rejections for them.
    428 #
    429 
    430 class IllegalSyntaxTestCase(unittest.TestCase):
    431 
    432     def check_bad_tree(self, tree, label):
    433         try:
    434             parser.sequence2st(tree)
    435         except parser.ParserError:
    436             pass
    437         else:
    438             self.fail("did not detect invalid tree for %r" % label)
    439 
    440     def test_junk(self):
    441         # not even remotely valid:
    442         self.check_bad_tree((1, 2, 3), "<junk>")
    443 
    444     def test_illegal_terminal(self):
    445         tree = \
    446             (257,
    447              (269,
    448               (270,
    449                (271,
    450                 (277,
    451                  (1,))),
    452                (4, ''))),
    453              (4, ''),
    454              (0, ''))
    455         self.check_bad_tree(tree, "too small items in terminal node")
    456         tree = \
    457             (257,
    458              (269,
    459               (270,
    460                (271,
    461                 (277,
    462                  (1, b'pass'))),
    463                (4, ''))),
    464              (4, ''),
    465              (0, ''))
    466         self.check_bad_tree(tree, "non-string second item in terminal node")
    467         tree = \
    468             (257,
    469              (269,
    470               (270,
    471                (271,
    472                 (277,
    473                  (1, 'pass', '0', 0))),
    474                (4, ''))),
    475              (4, ''),
    476              (0, ''))
    477         self.check_bad_tree(tree, "non-integer third item in terminal node")
    478         tree = \
    479             (257,
    480              (269,
    481               (270,
    482                (271,
    483                 (277,
    484                  (1, 'pass', 0, 0))),
    485                (4, ''))),
    486              (4, ''),
    487              (0, ''))
    488         self.check_bad_tree(tree, "too many items in terminal node")
    489 
    490     def test_illegal_yield_1(self):
    491         # Illegal yield statement: def f(): return 1; yield 1
    492         tree = \
    493         (257,
    494          (264,
    495           (285,
    496            (259,
    497             (1, 'def'),
    498             (1, 'f'),
    499             (260, (7, '('), (8, ')')),
    500             (11, ':'),
    501             (291,
    502              (4, ''),
    503              (5, ''),
    504              (264,
    505               (265,
    506                (266,
    507                 (272,
    508                  (275,
    509                   (1, 'return'),
    510                   (313,
    511                    (292,
    512                     (293,
    513                      (294,
    514                       (295,
    515                        (297,
    516                         (298,
    517                          (299,
    518                           (300,
    519                            (301,
    520                             (302, (303, (304, (305, (2, '1')))))))))))))))))),
    521                (264,
    522                 (265,
    523                  (266,
    524                   (272,
    525                    (276,
    526                     (1, 'yield'),
    527                     (313,
    528                      (292,
    529                       (293,
    530                        (294,
    531                         (295,
    532                          (297,
    533                           (298,
    534                            (299,
    535                             (300,
    536                              (301,
    537                               (302,
    538                                (303, (304, (305, (2, '1')))))))))))))))))),
    539                  (4, ''))),
    540                (6, ''))))),
    541            (4, ''),
    542            (0, ''))))
    543         self.check_bad_tree(tree, "def f():\n  return 1\n  yield 1")
    544 
    545     def test_illegal_yield_2(self):
    546         # Illegal return in generator: def f(): return 1; yield 1
    547         tree = \
    548         (257,
    549          (264,
    550           (265,
    551            (266,
    552             (278,
    553              (1, 'from'),
    554              (281, (1, '__future__')),
    555              (1, 'import'),
    556              (279, (1, 'generators')))),
    557            (4, ''))),
    558          (264,
    559           (285,
    560            (259,
    561             (1, 'def'),
    562             (1, 'f'),
    563             (260, (7, '('), (8, ')')),
    564             (11, ':'),
    565             (291,
    566              (4, ''),
    567              (5, ''),
    568              (264,
    569               (265,
    570                (266,
    571                 (272,
    572                  (275,
    573                   (1, 'return'),
    574                   (313,
    575                    (292,
    576                     (293,
    577                      (294,
    578                       (295,
    579                        (297,
    580                         (298,
    581                          (299,
    582                           (300,
    583                            (301,
    584                             (302, (303, (304, (305, (2, '1')))))))))))))))))),
    585                (264,
    586                 (265,
    587                  (266,
    588                   (272,
    589                    (276,
    590                     (1, 'yield'),
    591                     (313,
    592                      (292,
    593                       (293,
    594                        (294,
    595                         (295,
    596                          (297,
    597                           (298,
    598                            (299,
    599                             (300,
    600                              (301,
    601                               (302,
    602                                (303, (304, (305, (2, '1')))))))))))))))))),
    603                  (4, ''))),
    604                (6, ''))))),
    605            (4, ''),
    606            (0, ''))))
    607         self.check_bad_tree(tree, "def f():\n  return 1\n  yield 1")
    608 
    609     def test_a_comma_comma_c(self):
    610         # Illegal input: a,,c
    611         tree = \
    612         (258,
    613          (311,
    614           (290,
    615            (291,
    616             (292,
    617              (293,
    618               (295,
    619                (296,
    620                 (297,
    621                  (298, (299, (300, (301, (302, (303, (1, 'a')))))))))))))),
    622           (12, ','),
    623           (12, ','),
    624           (290,
    625            (291,
    626             (292,
    627              (293,
    628               (295,
    629                (296,
    630                 (297,
    631                  (298, (299, (300, (301, (302, (303, (1, 'c'))))))))))))))),
    632          (4, ''),
    633          (0, ''))
    634         self.check_bad_tree(tree, "a,,c")
    635 
    636     def test_illegal_operator(self):
    637         # Illegal input: a $= b
    638         tree = \
    639         (257,
    640          (264,
    641           (265,
    642            (266,
    643             (267,
    644              (312,
    645               (291,
    646                (292,
    647                 (293,
    648                  (294,
    649                   (296,
    650                    (297,
    651                     (298,
    652                      (299,
    653                       (300, (301, (302, (303, (304, (1, 'a'))))))))))))))),
    654              (268, (37, '$=')),
    655              (312,
    656               (291,
    657                (292,
    658                 (293,
    659                  (294,
    660                   (296,
    661                    (297,
    662                     (298,
    663                      (299,
    664                       (300, (301, (302, (303, (304, (1, 'b'))))))))))))))))),
    665            (4, ''))),
    666          (0, ''))
    667         self.check_bad_tree(tree, "a $= b")
    668 
    669     def test_malformed_global(self):
    670         #doesn't have global keyword in ast
    671         tree = (257,
    672                 (264,
    673                  (265,
    674                   (266,
    675                    (282, (1, 'foo'))), (4, ''))),
    676                 (4, ''),
    677                 (0, ''))
    678         self.check_bad_tree(tree, "malformed global ast")
    679 
    680     def test_missing_import_source(self):
    681         # from import fred
    682         tree = \
    683             (257,
    684              (268,
    685               (269,
    686                (270,
    687                 (282,
    688                  (284, (1, 'from'), (1, 'import'),
    689                   (287, (285, (1, 'fred')))))),
    690                (4, ''))),
    691              (4, ''), (0, ''))
    692         self.check_bad_tree(tree, "from import fred")
    693 
    694     def test_illegal_encoding(self):
    695         # Illegal encoding declaration
    696         tree = \
    697             (340,
    698              (257, (0, '')))
    699         self.check_bad_tree(tree, "missed encoding")
    700         tree = \
    701             (340,
    702              (257, (0, '')),
    703               b'iso-8859-1')
    704         self.check_bad_tree(tree, "non-string encoding")
    705         tree = \
    706             (340,
    707              (257, (0, '')),
    708               '\udcff')
    709         with self.assertRaises(UnicodeEncodeError):
    710             parser.sequence2st(tree)
    711 
    712 
    713 class CompileTestCase(unittest.TestCase):
    714 
    715     # These tests are very minimal. :-(
    716 
    717     def test_compile_expr(self):
    718         st = parser.expr('2 + 3')
    719         code = parser.compilest(st)
    720         self.assertEqual(eval(code), 5)
    721 
    722     def test_compile_suite(self):
    723         st = parser.suite('x = 2; y = x + 3')
    724         code = parser.compilest(st)
    725         globs = {}
    726         exec(code, globs)
    727         self.assertEqual(globs['y'], 5)
    728 
    729     def test_compile_error(self):
    730         st = parser.suite('1 = 3 + 4')
    731         self.assertRaises(SyntaxError, parser.compilest, st)
    732 
    733     def test_compile_badunicode(self):
    734         st = parser.suite('a = "\\U12345678"')
    735         self.assertRaises(SyntaxError, parser.compilest, st)
    736         st = parser.suite('a = "\\u1"')
    737         self.assertRaises(SyntaxError, parser.compilest, st)
    738 
    739     def test_issue_9011(self):
    740         # Issue 9011: compilation of an unary minus expression changed
    741         # the meaning of the ST, so that a second compilation produced
    742         # incorrect results.
    743         st = parser.expr('-3')
    744         code1 = parser.compilest(st)
    745         self.assertEqual(eval(code1), -3)
    746         code2 = parser.compilest(st)
    747         self.assertEqual(eval(code2), -3)
    748 
    749     def test_compile_filename(self):
    750         st = parser.expr('a + 5')
    751         code = parser.compilest(st)
    752         self.assertEqual(code.co_filename, '<syntax-tree>')
    753         code = st.compile()
    754         self.assertEqual(code.co_filename, '<syntax-tree>')
    755         for filename in 'file.py', b'file.py':
    756             code = parser.compilest(st, filename)
    757             self.assertEqual(code.co_filename, 'file.py')
    758             code = st.compile(filename)
    759             self.assertEqual(code.co_filename, 'file.py')
    760         for filename in bytearray(b'file.py'), memoryview(b'file.py'):
    761             with self.assertWarns(DeprecationWarning):
    762                 code = parser.compilest(st, filename)
    763             self.assertEqual(code.co_filename, 'file.py')
    764             with self.assertWarns(DeprecationWarning):
    765                 code = st.compile(filename)
    766             self.assertEqual(code.co_filename, 'file.py')
    767         self.assertRaises(TypeError, parser.compilest, st, list(b'file.py'))
    768         self.assertRaises(TypeError, st.compile, list(b'file.py'))
    769 
    770 
    771 class ParserStackLimitTestCase(unittest.TestCase):
    772     """try to push the parser to/over its limits.
    773     see http://bugs.python.org/issue1881 for a discussion
    774     """
    775     def _nested_expression(self, level):
    776         return "["*level+"]"*level
    777 
    778     def test_deeply_nested_list(self):
    779         # XXX used to be 99 levels in 2.x
    780         e = self._nested_expression(93)
    781         st = parser.expr(e)
    782         st.compile()
    783 
    784     def test_trigger_memory_error(self):
    785         e = self._nested_expression(100)
    786         rc, out, err = assert_python_failure('-c', e)
    787         # parsing the expression will result in an error message
    788         # followed by a MemoryError (see #11963)
    789         self.assertIn(b's_push: parser stack overflow', err)
    790         self.assertIn(b'MemoryError', err)
    791 
    792 class STObjectTestCase(unittest.TestCase):
    793     """Test operations on ST objects themselves"""
    794 
    795     def test_comparisons(self):
    796         # ST objects should support order and equality comparisons
    797         st1 = parser.expr('2 + 3')
    798         st2 = parser.suite('x = 2; y = x + 3')
    799         st3 = parser.expr('list(x**3 for x in range(20))')
    800         st1_copy = parser.expr('2 + 3')
    801         st2_copy = parser.suite('x = 2; y = x + 3')
    802         st3_copy = parser.expr('list(x**3 for x in range(20))')
    803 
    804         # exercise fast path for object identity
    805         self.assertEqual(st1 == st1, True)
    806         self.assertEqual(st2 == st2, True)
    807         self.assertEqual(st3 == st3, True)
    808         # slow path equality
    809         self.assertEqual(st1, st1_copy)
    810         self.assertEqual(st2, st2_copy)
    811         self.assertEqual(st3, st3_copy)
    812         self.assertEqual(st1 == st2, False)
    813         self.assertEqual(st1 == st3, False)
    814         self.assertEqual(st2 == st3, False)
    815         self.assertEqual(st1 != st1, False)
    816         self.assertEqual(st2 != st2, False)
    817         self.assertEqual(st3 != st3, False)
    818         self.assertEqual(st1 != st1_copy, False)
    819         self.assertEqual(st2 != st2_copy, False)
    820         self.assertEqual(st3 != st3_copy, False)
    821         self.assertEqual(st2 != st1, True)
    822         self.assertEqual(st1 != st3, True)
    823         self.assertEqual(st3 != st2, True)
    824         # we don't particularly care what the ordering is;  just that
    825         # it's usable and self-consistent
    826         self.assertEqual(st1 < st2, not (st2 <= st1))
    827         self.assertEqual(st1 < st3, not (st3 <= st1))
    828         self.assertEqual(st2 < st3, not (st3 <= st2))
    829         self.assertEqual(st1 < st2, st2 > st1)
    830         self.assertEqual(st1 < st3, st3 > st1)
    831         self.assertEqual(st2 < st3, st3 > st2)
    832         self.assertEqual(st1 <= st2, st2 >= st1)
    833         self.assertEqual(st3 <= st1, st1 >= st3)
    834         self.assertEqual(st2 <= st3, st3 >= st2)
    835         # transitivity
    836         bottom = min(st1, st2, st3)
    837         top = max(st1, st2, st3)
    838         mid = sorted([st1, st2, st3])[1]
    839         self.assertTrue(bottom < mid)
    840         self.assertTrue(bottom < top)
    841         self.assertTrue(mid < top)
    842         self.assertTrue(bottom <= mid)
    843         self.assertTrue(bottom <= top)
    844         self.assertTrue(mid <= top)
    845         self.assertTrue(bottom <= bottom)
    846         self.assertTrue(mid <= mid)
    847         self.assertTrue(top <= top)
    848         # interaction with other types
    849         self.assertEqual(st1 == 1588.602459, False)
    850         self.assertEqual('spanish armada' != st2, True)
    851         self.assertRaises(TypeError, operator.ge, st3, None)
    852         self.assertRaises(TypeError, operator.le, False, st1)
    853         self.assertRaises(TypeError, operator.lt, st1, 1815)
    854         self.assertRaises(TypeError, operator.gt, b'waterloo', st2)
    855 
    856     def test_copy_pickle(self):
    857         sts = [
    858             parser.expr('2 + 3'),
    859             parser.suite('x = 2; y = x + 3'),
    860             parser.expr('list(x**3 for x in range(20))')
    861         ]
    862         for st in sts:
    863             st_copy = copy.copy(st)
    864             self.assertEqual(st_copy.totuple(), st.totuple())
    865             st_copy = copy.deepcopy(st)
    866             self.assertEqual(st_copy.totuple(), st.totuple())
    867             for proto in range(pickle.HIGHEST_PROTOCOL+1):
    868                 st_copy = pickle.loads(pickle.dumps(st, proto))
    869                 self.assertEqual(st_copy.totuple(), st.totuple())
    870 
    871     check_sizeof = support.check_sizeof
    872 
    873     @support.cpython_only
    874     def test_sizeof(self):
    875         def XXXROUNDUP(n):
    876             if n <= 1:
    877                 return n
    878             if n <= 128:
    879                 return (n + 3) & ~3
    880             return 1 << (n - 1).bit_length()
    881 
    882         basesize = support.calcobjsize('Pii')
    883         nodesize = struct.calcsize('hP3iP0h')
    884         def sizeofchildren(node):
    885             if node is None:
    886                 return 0
    887             res = 0
    888             hasstr = len(node) > 1 and isinstance(node[-1], str)
    889             if hasstr:
    890                 res += len(node[-1]) + 1
    891             children = node[1:-1] if hasstr else node[1:]
    892             if children:
    893                 res += XXXROUNDUP(len(children)) * nodesize
    894                 for child in children:
    895                     res += sizeofchildren(child)
    896             return res
    897 
    898         def check_st_sizeof(st):
    899             self.check_sizeof(st, basesize + nodesize +
    900                                   sizeofchildren(st.totuple()))
    901 
    902         check_st_sizeof(parser.expr('2 + 3'))
    903         check_st_sizeof(parser.expr('2 + 3 + 4'))
    904         check_st_sizeof(parser.suite('x = 2 + 3'))
    905         check_st_sizeof(parser.suite(''))
    906         check_st_sizeof(parser.suite('# -*- coding: utf-8 -*-'))
    907         check_st_sizeof(parser.expr('[' + '2,' * 1000 + ']'))
    908 
    909 
    910     # XXX tests for pickling and unpickling of ST objects should go here
    911 
    912 class OtherParserCase(unittest.TestCase):
    913 
    914     def test_two_args_to_expr(self):
    915         # See bug #12264
    916         with self.assertRaises(TypeError):
    917             parser.expr("a", "b")
    918 
    919 if __name__ == "__main__":
    920     unittest.main()
    921