1  """Test suite for 2to3's parser and grammar files.
       2  
       3  This is the place to add tests for changes to 2to3's grammar, such as those
       4  merging the grammars for Python 2 and 3. In addition to specific tests for
       5  parts of the grammar we've changed, we also make sure we can parse the
       6  test_grammar.py files from both Python 2 and Python 3.
       7  """
       8  
       9  # Testing imports
      10  from . import support
      11  from .support import driver, driver_no_print_statement
      12  
      13  # Python imports
      14  import difflib
      15  import importlib
      16  import operator
      17  import os
      18  import pickle
      19  import shutil
      20  import subprocess
      21  import sys
      22  import tempfile
      23  import test.support
      24  import unittest
      25  
      26  # Local imports
      27  from lib2to3.pgen2 import driver as pgen2_driver
      28  from lib2to3.pgen2 import tokenize
      29  from ..pgen2.parse import ParseError
      30  from lib2to3.pygram import python_symbols as syms
      31  
      32  
      33  class ESC[4;38;5;81mTestDriver(ESC[4;38;5;149msupportESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      34  
      35      def test_formfeed(self):
      36          s = """print 1\n\x0Cprint 2\n"""
      37          t = driver.parse_string(s)
      38          self.assertEqual(t.children[0].children[0].type, syms.print_stmt)
      39          self.assertEqual(t.children[1].children[0].type, syms.print_stmt)
      40  
      41  
      42  class ESC[4;38;5;81mTestPgen2Caching(ESC[4;38;5;149msupportESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      43      def test_load_grammar_from_txt_file(self):
      44          pgen2_driver.load_grammar(support.grammar_path, save=False, force=True)
      45  
      46      def test_load_grammar_from_pickle(self):
      47          # Make a copy of the grammar file in a temp directory we are
      48          # guaranteed to be able to write to.
      49          tmpdir = tempfile.mkdtemp()
      50          try:
      51              grammar_copy = os.path.join(
      52                      tmpdir, os.path.basename(support.grammar_path))
      53              shutil.copy(support.grammar_path, grammar_copy)
      54              pickle_name = pgen2_driver._generate_pickle_name(grammar_copy)
      55  
      56              pgen2_driver.load_grammar(grammar_copy, save=True, force=True)
      57              self.assertTrue(os.path.exists(pickle_name))
      58  
      59              os.unlink(grammar_copy)  # Only the pickle remains...
      60              pgen2_driver.load_grammar(grammar_copy, save=False, force=False)
      61          finally:
      62              shutil.rmtree(tmpdir)
      63  
      64      @unittest.skipIf(sys.executable is None, 'sys.executable required')
      65      @unittest.skipIf(
      66          sys.platform in {'emscripten', 'wasi'}, 'requires working subprocess'
      67      )
      68      def test_load_grammar_from_subprocess(self):
      69          tmpdir = tempfile.mkdtemp()
      70          tmpsubdir = os.path.join(tmpdir, 'subdir')
      71          try:
      72              os.mkdir(tmpsubdir)
      73              grammar_base = os.path.basename(support.grammar_path)
      74              grammar_copy = os.path.join(tmpdir, grammar_base)
      75              grammar_sub_copy = os.path.join(tmpsubdir, grammar_base)
      76              shutil.copy(support.grammar_path, grammar_copy)
      77              shutil.copy(support.grammar_path, grammar_sub_copy)
      78              pickle_name = pgen2_driver._generate_pickle_name(grammar_copy)
      79              pickle_sub_name = pgen2_driver._generate_pickle_name(
      80                       grammar_sub_copy)
      81              self.assertNotEqual(pickle_name, pickle_sub_name)
      82  
      83              # Generate a pickle file from this process.
      84              pgen2_driver.load_grammar(grammar_copy, save=True, force=True)
      85              self.assertTrue(os.path.exists(pickle_name))
      86  
      87              # Generate a new pickle file in a subprocess with a most likely
      88              # different hash randomization seed.
      89              sub_env = dict(os.environ)
      90              sub_env['PYTHONHASHSEED'] = 'random'
      91              code = """
      92  from lib2to3.pgen2 import driver as pgen2_driver
      93  pgen2_driver.load_grammar(%r, save=True, force=True)
      94              """ % (grammar_sub_copy,)
      95              cmd = [sys.executable,
      96                     '-Wignore:lib2to3:DeprecationWarning',
      97                     '-c', code]
      98              subprocess.check_call( cmd, env=sub_env)
      99              self.assertTrue(os.path.exists(pickle_sub_name))
     100  
     101              with open(pickle_name, 'rb') as pickle_f_1, \
     102                      open(pickle_sub_name, 'rb') as pickle_f_2:
     103                  self.assertEqual(
     104                      pickle_f_1.read(), pickle_f_2.read(),
     105                      msg='Grammar caches generated using different hash seeds'
     106                      ' were not identical.')
     107          finally:
     108              shutil.rmtree(tmpdir)
     109  
     110      def test_load_packaged_grammar(self):
     111          modname = __name__ + '.load_test'
     112          class ESC[4;38;5;81mMyLoader:
     113              def get_data(self, where):
     114                  return pickle.dumps({'elephant': 19})
     115          class ESC[4;38;5;81mMyModule:
     116              __file__ = 'parsertestmodule'
     117              __spec__ = importlib.util.spec_from_loader(modname, MyLoader())
     118          sys.modules[modname] = MyModule()
     119          self.addCleanup(operator.delitem, sys.modules, modname)
     120          g = pgen2_driver.load_packaged_grammar(modname, 'Grammar.txt')
     121          self.assertEqual(g.elephant, 19)
     122  
     123  
     124  class ESC[4;38;5;81mGrammarTest(ESC[4;38;5;149msupportESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     125      def validate(self, code):
     126          support.parse_string(code)
     127  
     128      def invalid_syntax(self, code):
     129          try:
     130              self.validate(code)
     131          except ParseError:
     132              pass
     133          else:
     134              raise AssertionError("Syntax shouldn't have been valid")
     135  
     136  
     137  class ESC[4;38;5;81mTestMatrixMultiplication(ESC[4;38;5;149mGrammarTest):
     138      def test_matrix_multiplication_operator(self):
     139          self.validate("a @ b")
     140          self.validate("a @= b")
     141  
     142  
     143  class ESC[4;38;5;81mTestYieldFrom(ESC[4;38;5;149mGrammarTest):
     144      def test_yield_from(self):
     145          self.validate("yield from x")
     146          self.validate("(yield from x) + y")
     147          self.invalid_syntax("yield from")
     148  
     149  
     150  class ESC[4;38;5;81mTestAsyncAwait(ESC[4;38;5;149mGrammarTest):
     151      def test_await_expr(self):
     152          self.validate("""async def foo():
     153                               await x
     154                        """)
     155  
     156          self.validate("""async def foo():
     157                               [i async for i in b]
     158                        """)
     159  
     160          self.validate("""async def foo():
     161                               {i for i in b
     162                                  async for i in a if await i
     163                                    for b in i}
     164                        """)
     165  
     166          self.validate("""async def foo():
     167                               [await i for i in b if await c]
     168                        """)
     169  
     170          self.validate("""async def foo():
     171                               [ i for i in b if c]
     172                        """)
     173  
     174          self.validate("""async def foo():
     175  
     176              def foo(): pass
     177  
     178              def foo(): pass
     179  
     180              await x
     181          """)
     182  
     183          self.validate("""async def foo(): return await a""")
     184  
     185          self.validate("""def foo():
     186              def foo(): pass
     187              async def foo(): await x
     188          """)
     189  
     190          self.invalid_syntax("await x")
     191          self.invalid_syntax("""def foo():
     192                                     await x""")
     193  
     194          self.invalid_syntax("""def foo():
     195              def foo(): pass
     196              async def foo(): pass
     197              await x
     198          """)
     199  
     200      def test_async_var(self):
     201          self.validate("""async = 1""")
     202          self.validate("""await = 1""")
     203          self.validate("""def async(): pass""")
     204  
     205      def test_async_for(self):
     206          self.validate("""async def foo():
     207                               async for a in b: pass""")
     208  
     209      def test_async_with(self):
     210          self.validate("""async def foo():
     211                               async with a: pass""")
     212  
     213          self.invalid_syntax("""def foo():
     214                                     async with a: pass""")
     215  
     216      def test_async_generator(self):
     217          self.validate(
     218              """async def foo():
     219                     return (i * 2 async for i in arange(42))"""
     220          )
     221          self.validate(
     222              """def foo():
     223                     return (i * 2 async for i in arange(42))"""
     224          )
     225  
     226  
     227  class ESC[4;38;5;81mTestRaiseChanges(ESC[4;38;5;149mGrammarTest):
     228      def test_2x_style_1(self):
     229          self.validate("raise")
     230  
     231      def test_2x_style_2(self):
     232          self.validate("raise E, V")
     233  
     234      def test_2x_style_3(self):
     235          self.validate("raise E, V, T")
     236  
     237      def test_2x_style_invalid_1(self):
     238          self.invalid_syntax("raise E, V, T, Z")
     239  
     240      def test_3x_style(self):
     241          self.validate("raise E1 from E2")
     242  
     243      def test_3x_style_invalid_1(self):
     244          self.invalid_syntax("raise E, V from E1")
     245  
     246      def test_3x_style_invalid_2(self):
     247          self.invalid_syntax("raise E from E1, E2")
     248  
     249      def test_3x_style_invalid_3(self):
     250          self.invalid_syntax("raise from E1, E2")
     251  
     252      def test_3x_style_invalid_4(self):
     253          self.invalid_syntax("raise E from")
     254  
     255  
     256  # Modelled after Lib/test/test_grammar.py:TokenTests.test_funcdef issue2292
     257  # and Lib/test/text_parser.py test_list_displays, test_set_displays,
     258  # test_dict_displays, test_argument_unpacking, ... changes.
     259  class ESC[4;38;5;81mTestUnpackingGeneralizations(ESC[4;38;5;149mGrammarTest):
     260      def test_mid_positional_star(self):
     261          self.validate("""func(1, *(2, 3), 4)""")
     262  
     263      def test_double_star_dict_literal(self):
     264          self.validate("""func(**{'eggs':'scrambled', 'spam':'fried'})""")
     265  
     266      def test_double_star_dict_literal_after_keywords(self):
     267          self.validate("""func(spam='fried', **{'eggs':'scrambled'})""")
     268  
     269      def test_double_star_expression(self):
     270          self.validate("""func(**{'a':2} or {})""")
     271          self.validate("""func(**() or {})""")
     272  
     273      def test_star_expression(self):
     274          self.validate("""func(*[] or [2])""")
     275  
     276      def test_list_display(self):
     277          self.validate("""[*{2}, 3, *[4]]""")
     278  
     279      def test_set_display(self):
     280          self.validate("""{*{2}, 3, *[4]}""")
     281  
     282      def test_dict_display_1(self):
     283          self.validate("""{**{}}""")
     284  
     285      def test_dict_display_2(self):
     286          self.validate("""{**{}, 3:4, **{5:6, 7:8}}""")
     287  
     288      def test_complex_star_expression(self):
     289          self.validate("func(* [] or [1])")
     290  
     291      def test_complex_double_star_expression(self):
     292          self.validate("func(**{1: 3} if False else {x: x for x in range(3)})")
     293  
     294      def test_argument_unpacking_1(self):
     295          self.validate("""f(a, *b, *c, d)""")
     296  
     297      def test_argument_unpacking_2(self):
     298          self.validate("""f(**a, **b)""")
     299  
     300      def test_argument_unpacking_3(self):
     301          self.validate("""f(2, *a, *b, **b, **c, **d)""")
     302  
     303      def test_trailing_commas_1(self):
     304          self.validate("def f(a, b): call(a, b)")
     305          self.validate("def f(a, b,): call(a, b,)")
     306  
     307      def test_trailing_commas_2(self):
     308          self.validate("def f(a, *b): call(a, *b)")
     309          self.validate("def f(a, *b,): call(a, *b,)")
     310  
     311      def test_trailing_commas_3(self):
     312          self.validate("def f(a, b=1): call(a, b=1)")
     313          self.validate("def f(a, b=1,): call(a, b=1,)")
     314  
     315      def test_trailing_commas_4(self):
     316          self.validate("def f(a, **b): call(a, **b)")
     317          self.validate("def f(a, **b,): call(a, **b,)")
     318  
     319      def test_trailing_commas_5(self):
     320          self.validate("def f(*a, b=1): call(*a, b=1)")
     321          self.validate("def f(*a, b=1,): call(*a, b=1,)")
     322  
     323      def test_trailing_commas_6(self):
     324          self.validate("def f(*a, **b): call(*a, **b)")
     325          self.validate("def f(*a, **b,): call(*a, **b,)")
     326  
     327      def test_trailing_commas_7(self):
     328          self.validate("def f(*, b=1): call(*b)")
     329          self.validate("def f(*, b=1,): call(*b,)")
     330  
     331      def test_trailing_commas_8(self):
     332          self.validate("def f(a=1, b=2): call(a=1, b=2)")
     333          self.validate("def f(a=1, b=2,): call(a=1, b=2,)")
     334  
     335      def test_trailing_commas_9(self):
     336          self.validate("def f(a=1, **b): call(a=1, **b)")
     337          self.validate("def f(a=1, **b,): call(a=1, **b,)")
     338  
     339      def test_trailing_commas_lambda_1(self):
     340          self.validate("f = lambda a, b: call(a, b)")
     341          self.validate("f = lambda a, b,: call(a, b,)")
     342  
     343      def test_trailing_commas_lambda_2(self):
     344          self.validate("f = lambda a, *b: call(a, *b)")
     345          self.validate("f = lambda a, *b,: call(a, *b,)")
     346  
     347      def test_trailing_commas_lambda_3(self):
     348          self.validate("f = lambda a, b=1: call(a, b=1)")
     349          self.validate("f = lambda a, b=1,: call(a, b=1,)")
     350  
     351      def test_trailing_commas_lambda_4(self):
     352          self.validate("f = lambda a, **b: call(a, **b)")
     353          self.validate("f = lambda a, **b,: call(a, **b,)")
     354  
     355      def test_trailing_commas_lambda_5(self):
     356          self.validate("f = lambda *a, b=1: call(*a, b=1)")
     357          self.validate("f = lambda *a, b=1,: call(*a, b=1,)")
     358  
     359      def test_trailing_commas_lambda_6(self):
     360          self.validate("f = lambda *a, **b: call(*a, **b)")
     361          self.validate("f = lambda *a, **b,: call(*a, **b,)")
     362  
     363      def test_trailing_commas_lambda_7(self):
     364          self.validate("f = lambda *, b=1: call(*b)")
     365          self.validate("f = lambda *, b=1,: call(*b,)")
     366  
     367      def test_trailing_commas_lambda_8(self):
     368          self.validate("f = lambda a=1, b=2: call(a=1, b=2)")
     369          self.validate("f = lambda a=1, b=2,: call(a=1, b=2,)")
     370  
     371      def test_trailing_commas_lambda_9(self):
     372          self.validate("f = lambda a=1, **b: call(a=1, **b)")
     373          self.validate("f = lambda a=1, **b,: call(a=1, **b,)")
     374  
     375  
     376  # Adapted from Python 3's Lib/test/test_grammar.py:GrammarTests.testFuncdef
     377  class ESC[4;38;5;81mTestFunctionAnnotations(ESC[4;38;5;149mGrammarTest):
     378      def test_1(self):
     379          self.validate("""def f(x) -> list: pass""")
     380  
     381      def test_2(self):
     382          self.validate("""def f(x:int): pass""")
     383  
     384      def test_3(self):
     385          self.validate("""def f(*x:str): pass""")
     386  
     387      def test_4(self):
     388          self.validate("""def f(**x:float): pass""")
     389  
     390      def test_5(self):
     391          self.validate("""def f(x, y:1+2): pass""")
     392  
     393      def test_6(self):
     394          self.validate("""def f(a, (b:1, c:2, d)): pass""")
     395  
     396      def test_7(self):
     397          self.validate("""def f(a, (b:1, c:2, d), e:3=4, f=5, *g:6): pass""")
     398  
     399      def test_8(self):
     400          s = """def f(a, (b:1, c:2, d), e:3=4, f=5,
     401                          *g:6, h:7, i=8, j:9=10, **k:11) -> 12: pass"""
     402          self.validate(s)
     403  
     404      def test_9(self):
     405          s = """def f(
     406            a: str,
     407            b: int,
     408            *,
     409            c: bool = False,
     410            **kwargs,
     411          ) -> None:
     412              call(c=c, **kwargs,)"""
     413          self.validate(s)
     414  
     415      def test_10(self):
     416          s = """def f(
     417            a: str,
     418          ) -> None:
     419              call(a,)"""
     420          self.validate(s)
     421  
     422      def test_11(self):
     423          s = """def f(
     424            a: str = '',
     425          ) -> None:
     426              call(a=a,)"""
     427          self.validate(s)
     428  
     429      def test_12(self):
     430          s = """def f(
     431            *args: str,
     432          ) -> None:
     433              call(*args,)"""
     434          self.validate(s)
     435  
     436      def test_13(self):
     437          self.validate("def f(a: str, b: int) -> None: call(a, b)")
     438          self.validate("def f(a: str, b: int,) -> None: call(a, b,)")
     439  
     440      def test_14(self):
     441          self.validate("def f(a: str, *b: int) -> None: call(a, *b)")
     442          self.validate("def f(a: str, *b: int,) -> None: call(a, *b,)")
     443  
     444      def test_15(self):
     445          self.validate("def f(a: str, b: int=1) -> None: call(a, b=1)")
     446          self.validate("def f(a: str, b: int=1,) -> None: call(a, b=1,)")
     447  
     448      def test_16(self):
     449          self.validate("def f(a: str, **b: int) -> None: call(a, **b)")
     450          self.validate("def f(a: str, **b: int,) -> None: call(a, **b,)")
     451  
     452      def test_17(self):
     453          self.validate("def f(*a: str, b: int=1) -> None: call(*a, b=1)")
     454          self.validate("def f(*a: str, b: int=1,) -> None: call(*a, b=1,)")
     455  
     456      def test_18(self):
     457          self.validate("def f(*a: str, **b: int) -> None: call(*a, **b)")
     458          self.validate("def f(*a: str, **b: int,) -> None: call(*a, **b,)")
     459  
     460      def test_19(self):
     461          self.validate("def f(*, b: int=1) -> None: call(*b)")
     462          self.validate("def f(*, b: int=1,) -> None: call(*b,)")
     463  
     464      def test_20(self):
     465          self.validate("def f(a: str='', b: int=2) -> None: call(a=a, b=2)")
     466          self.validate("def f(a: str='', b: int=2,) -> None: call(a=a, b=2,)")
     467  
     468      def test_21(self):
     469          self.validate("def f(a: str='', **b: int) -> None: call(a=a, **b)")
     470          self.validate("def f(a: str='', **b: int,) -> None: call(a=a, **b,)")
     471  
     472  
     473  # Adapted from Python 3's Lib/test/test_grammar.py:GrammarTests.test_var_annot
     474  class ESC[4;38;5;81mTestVarAnnotations(ESC[4;38;5;149mGrammarTest):
     475      def test_1(self):
     476          self.validate("var1: int = 5")
     477  
     478      def test_2(self):
     479          self.validate("var2: [int, str]")
     480  
     481      def test_3(self):
     482          self.validate("def f():\n"
     483                        "    st: str = 'Hello'\n"
     484                        "    a.b: int = (1, 2)\n"
     485                        "    return st\n")
     486  
     487      def test_4(self):
     488          self.validate("def fbad():\n"
     489                        "    x: int\n"
     490                        "    print(x)\n")
     491  
     492      def test_5(self):
     493          self.validate("class C:\n"
     494                        "    x: int\n"
     495                        "    s: str = 'attr'\n"
     496                        "    z = 2\n"
     497                        "    def __init__(self, x):\n"
     498                        "        self.x: int = x\n")
     499  
     500      def test_6(self):
     501          self.validate("lst: List[int] = []")
     502  
     503  
     504  class ESC[4;38;5;81mTestExcept(ESC[4;38;5;149mGrammarTest):
     505      def test_new(self):
     506          s = """
     507              try:
     508                  x
     509              except E as N:
     510                  y"""
     511          self.validate(s)
     512  
     513      def test_old(self):
     514          s = """
     515              try:
     516                  x
     517              except E, N:
     518                  y"""
     519          self.validate(s)
     520  
     521  
     522  class ESC[4;38;5;81mTestStringLiterals(ESC[4;38;5;149mGrammarTest):
     523      prefixes = ("'", '"',
     524          "r'", 'r"', "R'", 'R"',
     525          "u'", 'u"', "U'", 'U"',
     526          "b'", 'b"', "B'", 'B"',
     527          "f'", 'f"', "F'", 'F"',
     528          "ur'", 'ur"', "Ur'", 'Ur"',
     529          "uR'", 'uR"', "UR'", 'UR"',
     530          "br'", 'br"', "Br'", 'Br"',
     531          "bR'", 'bR"', "BR'", 'BR"',
     532          "rb'", 'rb"', "Rb'", 'Rb"',
     533          "rB'", 'rB"', "RB'", 'RB"',)
     534  
     535      def test_lit(self):
     536          for pre in self.prefixes:
     537              single = "{p}spamspamspam{s}".format(p=pre, s=pre[-1])
     538              self.validate(single)
     539              triple = "{p}{s}{s}eggs{s}{s}{s}".format(p=pre, s=pre[-1])
     540              self.validate(triple)
     541  
     542  
     543  # Adapted from Python 3's Lib/test/test_grammar.py:GrammarTests.testAtoms
     544  class ESC[4;38;5;81mTestSetLiteral(ESC[4;38;5;149mGrammarTest):
     545      def test_1(self):
     546          self.validate("""x = {'one'}""")
     547  
     548      def test_2(self):
     549          self.validate("""x = {'one', 1,}""")
     550  
     551      def test_3(self):
     552          self.validate("""x = {'one', 'two', 'three'}""")
     553  
     554      def test_4(self):
     555          self.validate("""x = {2, 3, 4,}""")
     556  
     557  
     558  # Adapted from Python 3's Lib/test/test_unicode_identifiers.py and
     559  # Lib/test/test_tokenize.py:TokenizeTest.test_non_ascii_identifiers
     560  class ESC[4;38;5;81mTestIdentifier(ESC[4;38;5;149mGrammarTest):
     561      def test_non_ascii_identifiers(self):
     562          self.validate("Örter = 'places'\ngrün = 'green'")
     563          self.validate("蟒 = a蟒 = 锦蛇 = 1")
     564          self.validate("µ = aµ = µµ = 1")
     565          self.validate("𝔘𝔫𝔦𝔠𝔬𝔡𝔢 = a_𝔘𝔫𝔦𝔠𝔬𝔡𝔢 = 1")
     566  
     567  
     568  class ESC[4;38;5;81mTestNumericLiterals(ESC[4;38;5;149mGrammarTest):
     569      def test_new_octal_notation(self):
     570          self.validate("""0o7777777777777""")
     571          self.invalid_syntax("""0o7324528887""")
     572  
     573      def test_new_binary_notation(self):
     574          self.validate("""0b101010""")
     575          self.invalid_syntax("""0b0101021""")
     576  
     577  
     578  class ESC[4;38;5;81mTestClassDef(ESC[4;38;5;149mGrammarTest):
     579      def test_new_syntax(self):
     580          self.validate("class B(t=7): pass")
     581          self.validate("class B(t, *args): pass")
     582          self.validate("class B(t, **kwargs): pass")
     583          self.validate("class B(t, *args, **kwargs): pass")
     584          self.validate("class B(t, y=9, *args, **kwargs,): pass")
     585  
     586  
     587  class ESC[4;38;5;81mTestParserIdempotency(ESC[4;38;5;149msupportESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     588  
     589      """A cut-down version of pytree_idempotency.py."""
     590  
     591      def parse_file(self, filepath):
     592          if test.support.verbose:
     593              print(f"Parse file: {filepath}")
     594          with open(filepath, "rb") as fp:
     595              encoding = tokenize.detect_encoding(fp.readline)[0]
     596          self.assertIsNotNone(encoding,
     597                               "can't detect encoding for %s" % filepath)
     598          with open(filepath, "r", encoding=encoding) as fp:
     599              source = fp.read()
     600          try:
     601              tree = driver.parse_string(source)
     602          except ParseError:
     603              try:
     604                  tree = driver_no_print_statement.parse_string(source)
     605              except ParseError as err:
     606                  self.fail('ParseError on file %s (%s)' % (filepath, err))
     607          new = str(tree)
     608          if new != source:
     609              print(diff_texts(source, new, filepath))
     610              self.fail("Idempotency failed: %s" % filepath)
     611  
     612      def test_all_project_files(self):
     613          for filepath in support.all_project_files():
     614              with self.subTest(filepath=filepath):
     615                  self.parse_file(filepath)
     616  
     617      def test_extended_unpacking(self):
     618          driver.parse_string("a, *b, c = x\n")
     619          driver.parse_string("[*a, b] = x\n")
     620          driver.parse_string("(z, *y, w) = m\n")
     621          driver.parse_string("for *z, m in d: pass\n")
     622  
     623  
     624  class ESC[4;38;5;81mTestLiterals(ESC[4;38;5;149mGrammarTest):
     625  
     626      def validate(self, s):
     627          driver.parse_string(support.dedent(s) + "\n\n")
     628  
     629      def test_multiline_bytes_literals(self):
     630          s = """
     631              md5test(b"\xaa" * 80,
     632                      (b"Test Using Larger Than Block-Size Key "
     633                       b"and Larger Than One Block-Size Data"),
     634                      "6f630fad67cda0ee1fb1f562db3aa53e")
     635              """
     636          self.validate(s)
     637  
     638      def test_multiline_bytes_tripquote_literals(self):
     639          s = '''
     640              b"""
     641              <?xml version="1.0" encoding="UTF-8"?>
     642              <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN">
     643              """
     644              '''
     645          self.validate(s)
     646  
     647      def test_multiline_str_literals(self):
     648          s = """
     649              md5test("\xaa" * 80,
     650                      ("Test Using Larger Than Block-Size Key "
     651                       "and Larger Than One Block-Size Data"),
     652                      "6f630fad67cda0ee1fb1f562db3aa53e")
     653              """
     654          self.validate(s)
     655  
     656  
     657  class ESC[4;38;5;81mTestNamedAssignments(ESC[4;38;5;149mGrammarTest):
     658      """Also known as the walrus operator."""
     659  
     660      def test_named_assignment_if(self):
     661          driver.parse_string("if f := x(): pass\n")
     662  
     663      def test_named_assignment_while(self):
     664          driver.parse_string("while f := x(): pass\n")
     665  
     666      def test_named_assignment_generator(self):
     667          driver.parse_string("any((lastNum := num) == 1 for num in [1, 2, 3])\n")
     668  
     669      def test_named_assignment_listcomp(self):
     670          driver.parse_string("[(lastNum := num) == 1 for num in [1, 2, 3]]\n")
     671  
     672  
     673  class ESC[4;38;5;81mTestPositionalOnlyArgs(ESC[4;38;5;149mGrammarTest):
     674  
     675      def test_one_pos_only_arg(self):
     676          driver.parse_string("def one_pos_only_arg(a, /): pass\n")
     677  
     678      def test_all_markers(self):
     679          driver.parse_string(
     680                  "def all_markers(a, b=2, /, c, d=4, *, e=5, f): pass\n")
     681  
     682      def test_all_with_args_and_kwargs(self):
     683          driver.parse_string(
     684                  """def all_markers_with_args_and_kwargs(
     685                             aa, b, /, _cc, d, *args, e, f_f, **kwargs,
     686                     ):
     687                         pass\n""")
     688  
     689      def test_lambda_soup(self):
     690          driver.parse_string(
     691                  "lambda a, b, /, c, d, *args, e, f, **kw: kw\n")
     692  
     693      def test_only_positional_or_keyword(self):
     694          driver.parse_string("def func(a,b,/,*,g,e=3): pass\n")
     695  
     696  
     697  class ESC[4;38;5;81mTestPickleableException(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     698      def test_ParseError(self):
     699          err = ParseError('msg', 2, None, (1, 'context'))
     700          for proto in range(pickle.HIGHEST_PROTOCOL + 1):
     701              err2 = pickle.loads(pickle.dumps(err, protocol=proto))
     702              self.assertEqual(err.args, err2.args)
     703              self.assertEqual(err.msg, err2.msg)
     704              self.assertEqual(err.type, err2.type)
     705              self.assertEqual(err.value, err2.value)
     706              self.assertEqual(err.context, err2.context)
     707  
     708  
     709  def diff_texts(a, b, filename):
     710      a = a.splitlines()
     711      b = b.splitlines()
     712      return difflib.unified_diff(a, b, filename, filename,
     713                                  "(original)", "(reserialized)",
     714                                  lineterm="")
     715  
     716  
     717  if __name__ == '__main__':
     718      unittest.main()