From 179869af922252a0c1cef65fd2923856895e7d1b Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 1 Apr 2024 17:01:22 +0200 Subject: [PATCH 01/11] gh-94808: Fix refcounting in PyObject_Print tests (GH-117421) --- Modules/_testcapi/object.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Modules/_testcapi/object.c b/Modules/_testcapi/object.c index ce5b574ec5ce8f..8dd34cf4fc47d4 100644 --- a/Modules/_testcapi/object.c +++ b/Modules/_testcapi/object.c @@ -76,6 +76,8 @@ pyobject_print_noref_object(PyObject *self, PyObject *args) if (PyObject_Print(test_string, fp, 0) < 0){ fclose(fp); + Py_SET_REFCNT(test_string, 1); + Py_DECREF(test_string); return NULL; } @@ -105,10 +107,12 @@ pyobject_print_os_error(PyObject *self, PyObject *args) if (PyObject_Print(test_string, fp, 0) < 0) { fclose(fp); + Py_DECREF(test_string); return NULL; } fclose(fp); + Py_DECREF(test_string); Py_RETURN_NONE; } From ddf814db744006e0f42328aa15ace97c9d8ad681 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Mon, 1 Apr 2024 09:13:38 -0700 Subject: [PATCH 02/11] Silence compiler warnings in gc.c (#117422) --- Python/gc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Python/gc.c b/Python/gc.c index 36e20d05c205a5..a37c1b144e57e9 100644 --- a/Python/gc.c +++ b/Python/gc.c @@ -1317,6 +1317,7 @@ gc_collect_young(PyThreadState *tstate, survivor_count++; } } + (void)survivor_count; // Silence compiler warning gc_list_merge(&survivors, visited); validate_old(gcstate); gcstate->young.count = 0; @@ -1329,12 +1330,14 @@ gc_collect_young(PyThreadState *tstate, add_stats(gcstate, 0, stats); } +#ifndef NDEBUG static inline int IS_IN_VISITED(PyGC_Head *gc, int visited_space) { assert(visited_space == 0 || flip_old_space(visited_space) == 0); return gc_old_space(gc) == visited_space; } +#endif struct container_and_flag { PyGC_Head *container; From c741ad3537193c63fe697a8f0316aecd45eeb9ba Mon Sep 17 00:00:00 2001 From: Justin Turner Arthur Date: Mon, 1 Apr 2024 12:07:29 -0500 Subject: [PATCH 03/11] gh-77714: Provide an async iterator version of as_completed (GH-22491) * as_completed returns object that is both iterator and async iterator * Existing tests adjusted to test both the old and new style * New test to ensure iterator can be resumed * New test to ensure async iterator yields any passed-in Futures as-is Co-authored-by: Serhiy Storchaka Co-authored-by: Guido van Rossum --- Doc/library/asyncio-task.rst | 61 +++- Doc/whatsnew/3.13.rst | 7 + Lib/asyncio/tasks.py | 152 +++++++--- Lib/test/test_asyncio/test_tasks.py | 282 ++++++++++++++---- .../2020-10-02-17-35-19.bpo-33533.GLIhM5.rst | 5 + 5 files changed, 387 insertions(+), 120 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-10-02-17-35-19.bpo-33533.GLIhM5.rst diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index 2aab62c64d2920..3b10a0d628a86e 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -867,19 +867,50 @@ Waiting Primitives .. function:: as_completed(aws, *, timeout=None) - Run :ref:`awaitable objects ` in the *aws* - iterable concurrently. Return an iterator of coroutines. - Each coroutine returned can be awaited to get the earliest next - result from the iterable of the remaining awaitables. - - Raises :exc:`TimeoutError` if the timeout occurs before - all Futures are done. - - Example:: - - for coro in as_completed(aws): - earliest_result = await coro - # ... + Run :ref:`awaitable objects ` in the *aws* iterable + concurrently. The returned object can be iterated to obtain the results + of the awaitables as they finish. + + The object returned by ``as_completed()`` can be iterated as an + :term:`asynchronous iterator` or a plain :term:`iterator`. When asynchronous + iteration is used, the originally-supplied awaitables are yielded if they + are tasks or futures. This makes it easy to correlate previously-scheduled + tasks with their results. Example:: + + ipv4_connect = create_task(open_connection("127.0.0.1", 80)) + ipv6_connect = create_task(open_connection("::1", 80)) + tasks = [ipv4_connect, ipv6_connect] + + async for earliest_connect in as_completed(tasks): + # earliest_connect is done. The result can be obtained by + # awaiting it or calling earliest_connect.result() + reader, writer = await earliest_connect + + if earliest_connect is ipv6_connect: + print("IPv6 connection established.") + else: + print("IPv4 connection established.") + + During asynchronous iteration, implicitly-created tasks will be yielded for + supplied awaitables that aren't tasks or futures. + + When used as a plain iterator, each iteration yields a new coroutine that + returns the result or raises the exception of the next completed awaitable. + This pattern is compatible with Python versions older than 3.13:: + + ipv4_connect = create_task(open_connection("127.0.0.1", 80)) + ipv6_connect = create_task(open_connection("::1", 80)) + tasks = [ipv4_connect, ipv6_connect] + + for next_connect in as_completed(tasks): + # next_connect is not one of the original task objects. It must be + # awaited to obtain the result value or raise the exception of the + # awaitable that finishes next. + reader, writer = await next_connect + + A :exc:`TimeoutError` is raised if the timeout occurs before all awaitables + are done. This is raised by the ``async for`` loop during asynchronous + iteration or by the coroutines yielded during plain iteration. .. versionchanged:: 3.10 Removed the *loop* parameter. @@ -891,6 +922,10 @@ Waiting Primitives .. versionchanged:: 3.12 Added support for generators yielding tasks. + .. versionchanged:: 3.13 + The result can now be used as either an :term:`asynchronous iterator` + or as a plain :term:`iterator` (previously it was only a plain iterator). + Running in Threads ================== diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index 45f7f50bf9f46b..97bee4d38e300a 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -289,6 +289,13 @@ asyncio forcefully close an asyncio server. (Contributed by Pierre Ossman in :gh:`113538`.) +* :func:`asyncio.as_completed` now returns an object that is both an + :term:`asynchronous iterator` and a plain :term:`iterator` of awaitables. + The awaitables yielded by asynchronous iteration include original task or + future objects that were passed in, making it easier to associate results + with the tasks being completed. + (Contributed by Justin Arthur in :gh:`77714`.) + base64 ------ diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index 48e31af9a43167..7fb697b9441c33 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -25,6 +25,7 @@ from . import events from . import exceptions from . import futures +from . import queues from . import timeouts # Helper to generate new task names @@ -564,62 +565,125 @@ async def _cancel_and_wait(fut): fut.remove_done_callback(cb) -# This is *not* a @coroutine! It is just an iterator (yielding Futures). +class _AsCompletedIterator: + """Iterator of awaitables representing tasks of asyncio.as_completed. + + As an asynchronous iterator, iteration yields futures as they finish. As a + plain iterator, new coroutines are yielded that will return or raise the + result of the next underlying future to complete. + """ + def __init__(self, aws, timeout): + self._done = queues.Queue() + self._timeout_handle = None + + loop = events.get_event_loop() + todo = {ensure_future(aw, loop=loop) for aw in set(aws)} + for f in todo: + f.add_done_callback(self._handle_completion) + if todo and timeout is not None: + self._timeout_handle = ( + loop.call_later(timeout, self._handle_timeout) + ) + self._todo = todo + self._todo_left = len(todo) + + def __aiter__(self): + return self + + def __iter__(self): + return self + + async def __anext__(self): + if not self._todo_left: + raise StopAsyncIteration + assert self._todo_left > 0 + self._todo_left -= 1 + return await self._wait_for_one() + + def __next__(self): + if not self._todo_left: + raise StopIteration + assert self._todo_left > 0 + self._todo_left -= 1 + return self._wait_for_one(resolve=True) + + def _handle_timeout(self): + for f in self._todo: + f.remove_done_callback(self._handle_completion) + self._done.put_nowait(None) # Sentinel for _wait_for_one(). + self._todo.clear() # Can't do todo.remove(f) in the loop. + + def _handle_completion(self, f): + if not self._todo: + return # _handle_timeout() was here first. + self._todo.remove(f) + self._done.put_nowait(f) + if not self._todo and self._timeout_handle is not None: + self._timeout_handle.cancel() + + async def _wait_for_one(self, resolve=False): + # Wait for the next future to be done and return it unless resolve is + # set, in which case return either the result of the future or raise + # an exception. + f = await self._done.get() + if f is None: + # Dummy value from _handle_timeout(). + raise exceptions.TimeoutError + return f.result() if resolve else f + + def as_completed(fs, *, timeout=None): - """Return an iterator whose values are coroutines. + """Create an iterator of awaitables or their results in completion order. - When waiting for the yielded coroutines you'll get the results (or - exceptions!) of the original Futures (or coroutines), in the order - in which and as soon as they complete. + Run the supplied awaitables concurrently. The returned object can be + iterated to obtain the results of the awaitables as they finish. - This differs from PEP 3148; the proper way to use this is: + The object returned can be iterated as an asynchronous iterator or a plain + iterator. When asynchronous iteration is used, the originally-supplied + awaitables are yielded if they are tasks or futures. This makes it easy to + correlate previously-scheduled tasks with their results: - for f in as_completed(fs): - result = await f # The 'await' may raise. - # Use result. + ipv4_connect = create_task(open_connection("127.0.0.1", 80)) + ipv6_connect = create_task(open_connection("::1", 80)) + tasks = [ipv4_connect, ipv6_connect] - If a timeout is specified, the 'await' will raise - TimeoutError when the timeout occurs before all Futures are done. + async for earliest_connect in as_completed(tasks): + # earliest_connect is done. The result can be obtained by + # awaiting it or calling earliest_connect.result() + reader, writer = await earliest_connect - Note: The futures 'f' are not necessarily members of fs. - """ - if futures.isfuture(fs) or coroutines.iscoroutine(fs): - raise TypeError(f"expect an iterable of futures, not {type(fs).__name__}") + if earliest_connect is ipv6_connect: + print("IPv6 connection established.") + else: + print("IPv4 connection established.") - from .queues import Queue # Import here to avoid circular import problem. - done = Queue() + During asynchronous iteration, implicitly-created tasks will be yielded for + supplied awaitables that aren't tasks or futures. - loop = events.get_event_loop() - todo = {ensure_future(f, loop=loop) for f in set(fs)} - timeout_handle = None + When used as a plain iterator, each iteration yields a new coroutine that + returns the result or raises the exception of the next completed awaitable. + This pattern is compatible with Python versions older than 3.13: - def _on_timeout(): - for f in todo: - f.remove_done_callback(_on_completion) - done.put_nowait(None) # Queue a dummy value for _wait_for_one(). - todo.clear() # Can't do todo.remove(f) in the loop. + ipv4_connect = create_task(open_connection("127.0.0.1", 80)) + ipv6_connect = create_task(open_connection("::1", 80)) + tasks = [ipv4_connect, ipv6_connect] - def _on_completion(f): - if not todo: - return # _on_timeout() was here first. - todo.remove(f) - done.put_nowait(f) - if not todo and timeout_handle is not None: - timeout_handle.cancel() + for next_connect in as_completed(tasks): + # next_connect is not one of the original task objects. It must be + # awaited to obtain the result value or raise the exception of the + # awaitable that finishes next. + reader, writer = await next_connect - async def _wait_for_one(): - f = await done.get() - if f is None: - # Dummy value from _on_timeout(). - raise exceptions.TimeoutError - return f.result() # May raise f.exception(). + A TimeoutError is raised if the timeout occurs before all awaitables are + done. This is raised by the async for loop during asynchronous iteration or + by the coroutines yielded during plain iteration. + """ + if inspect.isawaitable(fs): + raise TypeError( + f"expects an iterable of awaitables, not {type(fs).__name__}" + ) - for f in todo: - f.add_done_callback(_on_completion) - if todo and timeout is not None: - timeout_handle = loop.call_later(timeout, _on_timeout) - for _ in range(len(todo)): - yield _wait_for_one() + return _AsCompletedIterator(fs, timeout) @types.coroutine diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index 4dfaff847edb90..bc6d88e65a4966 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -1,6 +1,7 @@ """Tests for tasks.py.""" import collections +import contextlib import contextvars import gc import io @@ -1409,12 +1410,6 @@ def gen(): yield 0.01 yield 0 - loop = self.new_test_loop(gen) - # disable "slow callback" warning - loop.slow_callback_duration = 1.0 - completed = set() - time_shifted = False - async def sleeper(dt, x): nonlocal time_shifted await asyncio.sleep(dt) @@ -1424,21 +1419,78 @@ async def sleeper(dt, x): loop.advance_time(0.14) return x - a = sleeper(0.01, 'a') - b = sleeper(0.01, 'b') - c = sleeper(0.15, 'c') + async def try_iterator(awaitables): + values = [] + for f in asyncio.as_completed(awaitables): + values.append(await f) + return values - async def foo(): + async def try_async_iterator(awaitables): values = [] - for f in asyncio.as_completed([b, c, a]): + async for f in asyncio.as_completed(awaitables): values.append(await f) return values - res = loop.run_until_complete(self.new_task(loop, foo())) - self.assertAlmostEqual(0.15, loop.time()) - self.assertTrue('a' in res[:2]) - self.assertTrue('b' in res[:2]) - self.assertEqual(res[2], 'c') + for foo in try_iterator, try_async_iterator: + with self.subTest(method=foo.__name__): + loop = self.new_test_loop(gen) + # disable "slow callback" warning + loop.slow_callback_duration = 1.0 + + completed = set() + time_shifted = False + + a = sleeper(0.01, 'a') + b = sleeper(0.01, 'b') + c = sleeper(0.15, 'c') + + res = loop.run_until_complete(self.new_task(loop, foo([b, c, a]))) + self.assertAlmostEqual(0.15, loop.time()) + self.assertTrue('a' in res[:2]) + self.assertTrue('b' in res[:2]) + self.assertEqual(res[2], 'c') + + def test_as_completed_same_tasks_in_as_out(self): + # Ensures that asynchronously iterating as_completed's iterator + # yields awaitables are the same awaitables that were passed in when + # those awaitables are futures. + async def try_async_iterator(awaitables): + awaitables_out = set() + async for out_aw in asyncio.as_completed(awaitables): + awaitables_out.add(out_aw) + return awaitables_out + + async def coro(i): + return i + + with contextlib.closing(asyncio.new_event_loop()) as loop: + # Coroutines shouldn't be yielded back as finished coroutines + # can't be re-used. + awaitables_in = frozenset( + (coro(0), coro(1), coro(2), coro(3)) + ) + awaitables_out = loop.run_until_complete( + try_async_iterator(awaitables_in) + ) + if awaitables_in - awaitables_out != awaitables_in: + raise self.failureException('Got original coroutines ' + 'out of as_completed iterator.') + + # Tasks should be yielded back. + coro_obj_a = coro('a') + task_b = loop.create_task(coro('b')) + coro_obj_c = coro('c') + task_d = loop.create_task(coro('d')) + awaitables_in = frozenset( + (coro_obj_a, task_b, coro_obj_c, task_d) + ) + awaitables_out = loop.run_until_complete( + try_async_iterator(awaitables_in) + ) + if awaitables_in & awaitables_out != {task_b, task_d}: + raise self.failureException('Only tasks should be yielded ' + 'from as_completed iterator ' + 'as-is.') def test_as_completed_with_timeout(self): @@ -1448,12 +1500,7 @@ def gen(): yield 0 yield 0.1 - loop = self.new_test_loop(gen) - - a = loop.create_task(asyncio.sleep(0.1, 'a')) - b = loop.create_task(asyncio.sleep(0.15, 'b')) - - async def foo(): + async def try_iterator(): values = [] for f in asyncio.as_completed([a, b], timeout=0.12): if values: @@ -1465,16 +1512,33 @@ async def foo(): values.append((2, exc)) return values - res = loop.run_until_complete(self.new_task(loop, foo())) - self.assertEqual(len(res), 2, res) - self.assertEqual(res[0], (1, 'a')) - self.assertEqual(res[1][0], 2) - self.assertIsInstance(res[1][1], asyncio.TimeoutError) - self.assertAlmostEqual(0.12, loop.time()) + async def try_async_iterator(): + values = [] + try: + async for f in asyncio.as_completed([a, b], timeout=0.12): + v = await f + values.append((1, v)) + loop.advance_time(0.02) + except asyncio.TimeoutError as exc: + values.append((2, exc)) + return values - # move forward to close generator - loop.advance_time(10) - loop.run_until_complete(asyncio.wait([a, b])) + for foo in try_iterator, try_async_iterator: + with self.subTest(method=foo.__name__): + loop = self.new_test_loop(gen) + a = loop.create_task(asyncio.sleep(0.1, 'a')) + b = loop.create_task(asyncio.sleep(0.15, 'b')) + + res = loop.run_until_complete(self.new_task(loop, foo())) + self.assertEqual(len(res), 2, res) + self.assertEqual(res[0], (1, 'a')) + self.assertEqual(res[1][0], 2) + self.assertIsInstance(res[1][1], asyncio.TimeoutError) + self.assertAlmostEqual(0.12, loop.time()) + + # move forward to close generator + loop.advance_time(10) + loop.run_until_complete(asyncio.wait([a, b])) def test_as_completed_with_unused_timeout(self): @@ -1483,19 +1547,75 @@ def gen(): yield 0 yield 0.01 - loop = self.new_test_loop(gen) - - a = asyncio.sleep(0.01, 'a') - - async def foo(): + async def try_iterator(): for f in asyncio.as_completed([a], timeout=1): v = await f self.assertEqual(v, 'a') - loop.run_until_complete(self.new_task(loop, foo())) + async def try_async_iterator(): + async for f in asyncio.as_completed([a], timeout=1): + v = await f + self.assertEqual(v, 'a') - def test_as_completed_reverse_wait(self): + for foo in try_iterator, try_async_iterator: + with self.subTest(method=foo.__name__): + a = asyncio.sleep(0.01, 'a') + loop = self.new_test_loop(gen) + loop.run_until_complete(self.new_task(loop, foo())) + loop.close() + + def test_as_completed_resume_iterator(self): + # Test that as_completed returns an iterator that can be resumed + # the next time iteration is performed (i.e. if __iter__ is called + # again) + async def try_iterator(awaitables): + iterations = 0 + iterator = asyncio.as_completed(awaitables) + collected = [] + for f in iterator: + collected.append(await f) + iterations += 1 + if iterations == 2: + break + self.assertEqual(len(collected), 2) + + # Resume same iterator: + for f in iterator: + collected.append(await f) + return collected + + async def try_async_iterator(awaitables): + iterations = 0 + iterator = asyncio.as_completed(awaitables) + collected = [] + async for f in iterator: + collected.append(await f) + iterations += 1 + if iterations == 2: + break + self.assertEqual(len(collected), 2) + + # Resume same iterator: + async for f in iterator: + collected.append(await f) + return collected + + async def coro(i): + return i + + with contextlib.closing(asyncio.new_event_loop()) as loop: + for foo in try_iterator, try_async_iterator: + with self.subTest(method=foo.__name__): + results = loop.run_until_complete( + foo((coro(0), coro(1), coro(2), coro(3))) + ) + self.assertCountEqual(results, (0, 1, 2, 3)) + def test_as_completed_reverse_wait(self): + # Tests the plain iterator style of as_completed iteration to + # ensure that the first future awaited resolves to the first + # completed awaitable from the set we passed in, even if it wasn't + # the first future generated by as_completed. def gen(): yield 0 yield 0.05 @@ -1522,7 +1642,8 @@ async def test(): loop.run_until_complete(test()) def test_as_completed_concurrent(self): - + # Ensure that more than one future or coroutine yielded from + # as_completed can be awaited concurrently. def gen(): when = yield self.assertAlmostEqual(0.05, when) @@ -1530,38 +1651,55 @@ def gen(): self.assertAlmostEqual(0.05, when) yield 0.05 - a = asyncio.sleep(0.05, 'a') - b = asyncio.sleep(0.05, 'b') - fs = {a, b} + async def try_iterator(fs): + return list(asyncio.as_completed(fs)) - async def test(): - futs = list(asyncio.as_completed(fs)) - self.assertEqual(len(futs), 2) - done, pending = await asyncio.wait( - [asyncio.ensure_future(fut) for fut in futs] - ) - self.assertEqual(set(f.result() for f in done), {'a', 'b'}) + async def try_async_iterator(fs): + return [f async for f in asyncio.as_completed(fs)] - loop = self.new_test_loop(gen) - loop.run_until_complete(test()) + for runner in try_iterator, try_async_iterator: + with self.subTest(method=runner.__name__): + a = asyncio.sleep(0.05, 'a') + b = asyncio.sleep(0.05, 'b') + fs = {a, b} + + async def test(): + futs = await runner(fs) + self.assertEqual(len(futs), 2) + done, pending = await asyncio.wait( + [asyncio.ensure_future(fut) for fut in futs] + ) + self.assertEqual(set(f.result() for f in done), {'a', 'b'}) + + loop = self.new_test_loop(gen) + loop.run_until_complete(test()) def test_as_completed_duplicate_coroutines(self): async def coro(s): return s - async def runner(): + async def try_iterator(): result = [] c = coro('ham') for f in asyncio.as_completed([c, c, coro('spam')]): result.append(await f) return result - fut = self.new_task(self.loop, runner()) - self.loop.run_until_complete(fut) - result = fut.result() - self.assertEqual(set(result), {'ham', 'spam'}) - self.assertEqual(len(result), 2) + async def try_async_iterator(): + result = [] + c = coro('ham') + async for f in asyncio.as_completed([c, c, coro('spam')]): + result.append(await f) + return result + + for runner in try_iterator, try_async_iterator: + with self.subTest(method=runner.__name__): + fut = self.new_task(self.loop, runner()) + self.loop.run_until_complete(fut) + result = fut.result() + self.assertEqual(set(result), {'ham', 'spam'}) + self.assertEqual(len(result), 2) def test_as_completed_coroutine_without_loop(self): async def coro(): @@ -1570,8 +1708,8 @@ async def coro(): a = coro() self.addCleanup(a.close) - futs = asyncio.as_completed([a]) with self.assertRaisesRegex(RuntimeError, 'no current event loop'): + futs = asyncio.as_completed([a]) list(futs) def test_as_completed_coroutine_use_running_loop(self): @@ -2044,14 +2182,32 @@ async def coro(): self.assertEqual(res, 42) def test_as_completed_invalid_args(self): + # as_completed() expects a list of futures, not a future instance + # TypeError should be raised either on iterator construction or first + # iteration + + # Plain iterator fut = self.new_future(self.loop) + with self.assertRaises(TypeError): + iterator = asyncio.as_completed(fut) + next(iterator) + coro = coroutine_function() + with self.assertRaises(TypeError): + iterator = asyncio.as_completed(coro) + next(iterator) + coro.close() - # as_completed() expects a list of futures, not a future instance - self.assertRaises(TypeError, self.loop.run_until_complete, - asyncio.as_completed(fut)) + # Async iterator + async def try_async_iterator(aw): + async for f in asyncio.as_completed(aw): + break + + fut = self.new_future(self.loop) + with self.assertRaises(TypeError): + self.loop.run_until_complete(try_async_iterator(fut)) coro = coroutine_function() - self.assertRaises(TypeError, self.loop.run_until_complete, - asyncio.as_completed(coro)) + with self.assertRaises(TypeError): + self.loop.run_until_complete(try_async_iterator(coro)) coro.close() def test_wait_invalid_args(self): diff --git a/Misc/NEWS.d/next/Library/2020-10-02-17-35-19.bpo-33533.GLIhM5.rst b/Misc/NEWS.d/next/Library/2020-10-02-17-35-19.bpo-33533.GLIhM5.rst new file mode 100644 index 00000000000000..3ffd723cf1082a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-10-02-17-35-19.bpo-33533.GLIhM5.rst @@ -0,0 +1,5 @@ +:func:`asyncio.as_completed` now returns an object that is both an asynchronous +iterator and plain iterator. The new asynchronous iteration pattern allows for +easier correlation between prior tasks and their completed results. This is +a closer match to :func:`concurrent.futures.as_completed`'s iteration pattern. +Patch by Justin Arthur. From fc8007ee3635db6ab73e132ebff987c910b6d538 Mon Sep 17 00:00:00 2001 From: Barney Gale Date: Mon, 1 Apr 2024 20:37:41 +0100 Subject: [PATCH 04/11] GH-117337: Deprecate `glob.glob0()` and `glob.glob1()`. (#117371) These undocumented functions are no longer used by `msilib`, so there's no reason to keep them around. --- Doc/whatsnew/3.13.rst | 5 +++ Lib/glob.py | 9 +++++- Lib/test/test_glob.py | 31 +++++++++++++++++++ ...-03-29-15-58-01.gh-issue-117337.7w3Qwp.rst | 3 ++ 4 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2024-03-29-15-58-01.gh-issue-117337.7w3Qwp.rst diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index 97bee4d38e300a..7f6a86efc61bf7 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -813,6 +813,11 @@ Deprecated translation was not found. (Contributed by Serhiy Storchaka in :gh:`88434`.) +* :mod:`glob`: The undocumented :func:`!glob.glob0` and :func:`!glob.glob1` + functions are deprecated. Use :func:`glob.glob` and pass a directory to its + *root_dir* argument instead. + (Contributed by Barney Gale in :gh:`117337`.) + * :mod:`http.server`: :class:`http.server.CGIHTTPRequestHandler` now emits a :exc:`DeprecationWarning` as it will be removed in 3.15. Process-based CGI HTTP servers have been out of favor for a very long time. This code was diff --git a/Lib/glob.py b/Lib/glob.py index d59641195a1c41..a915cf0bdf4502 100644 --- a/Lib/glob.py +++ b/Lib/glob.py @@ -119,12 +119,19 @@ def _glob0(dirname, basename, dir_fd, dironly, include_hidden=False): return [basename] return [] -# Following functions are not public but can be used by third-party code. +_deprecated_function_message = ( + "{name} is deprecated and will be removed in Python {remove}. Use " + "glob.glob and pass a directory to its root_dir argument instead." +) def glob0(dirname, pattern): + import warnings + warnings._deprecated("glob.glob0", _deprecated_function_message, remove=(3, 15)) return _glob0(dirname, pattern, None, False) def glob1(dirname, pattern): + import warnings + warnings._deprecated("glob.glob1", _deprecated_function_message, remove=(3, 15)) return _glob1(dirname, pattern, None, False) # This helper function recursively yields relative pathnames inside a literal diff --git a/Lib/test/test_glob.py b/Lib/test/test_glob.py index 6719bdbb0cc9b1..70ee35ed2850bc 100644 --- a/Lib/test/test_glob.py +++ b/Lib/test/test_glob.py @@ -4,6 +4,7 @@ import shutil import sys import unittest +import warnings from test.support.os_helper import (TESTFN, skip_unless_symlink, can_symlink, create_empty_file, change_cwd) @@ -382,6 +383,36 @@ def test_glob_many_open_files(self): for it in iters: self.assertEqual(next(it), p) + def test_glob0(self): + with self.assertWarns(DeprecationWarning): + glob.glob0(self.tempdir, 'a') + + with warnings.catch_warnings(): + warnings.simplefilter('ignore') + eq = self.assertSequencesEqual_noorder + eq(glob.glob0(self.tempdir, 'a'), ['a']) + eq(glob.glob0(self.tempdir, '.bb'), ['.bb']) + eq(glob.glob0(self.tempdir, '.b*'), []) + eq(glob.glob0(self.tempdir, 'b'), []) + eq(glob.glob0(self.tempdir, '?'), []) + eq(glob.glob0(self.tempdir, '*a'), []) + eq(glob.glob0(self.tempdir, 'a*'), []) + + def test_glob1(self): + with self.assertWarns(DeprecationWarning): + glob.glob1(self.tempdir, 'a') + + with warnings.catch_warnings(): + warnings.simplefilter('ignore') + eq = self.assertSequencesEqual_noorder + eq(glob.glob1(self.tempdir, 'a'), ['a']) + eq(glob.glob1(self.tempdir, '.bb'), ['.bb']) + eq(glob.glob1(self.tempdir, '.b*'), ['.bb']) + eq(glob.glob1(self.tempdir, 'b'), []) + eq(glob.glob1(self.tempdir, '?'), ['a']) + eq(glob.glob1(self.tempdir, '*a'), ['a', 'aaa']) + eq(glob.glob1(self.tempdir, 'a*'), ['a', 'aaa', 'aab']) + def test_translate_matching(self): match = re.compile(glob.translate('*')).match self.assertIsNotNone(match('foo')) diff --git a/Misc/NEWS.d/next/Library/2024-03-29-15-58-01.gh-issue-117337.7w3Qwp.rst b/Misc/NEWS.d/next/Library/2024-03-29-15-58-01.gh-issue-117337.7w3Qwp.rst new file mode 100644 index 00000000000000..73bd2569c7c9cb --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-03-29-15-58-01.gh-issue-117337.7w3Qwp.rst @@ -0,0 +1,3 @@ +Deprecate undocumented :func:`!glob.glob0` and :func:`!glob.glob1` +functions. Use :func:`glob.glob` and pass a directory to its +*root_dir* argument instead. From fc2071687b708598264a3403b7f9104667c1092f Mon Sep 17 00:00:00 2001 From: Matthew Davis <7035647+mdavis-xyz@users.noreply.github.com> Date: Mon, 1 Apr 2024 21:49:14 +0200 Subject: [PATCH 05/11] Docs: add more links to PIPE in subprocess docs (#25416) --- Doc/library/subprocess.rst | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst index 8f6751cb11af2a..49194b82b4cea2 100644 --- a/Doc/library/subprocess.rst +++ b/Doc/library/subprocess.rst @@ -52,10 +52,12 @@ underlying :class:`Popen` interface can be used directly. If *capture_output* is true, stdout and stderr will be captured. When used, the internal :class:`Popen` object is automatically created with - ``stdout=PIPE`` and ``stderr=PIPE``. The *stdout* and *stderr* arguments may - not be supplied at the same time as *capture_output*. If you wish to capture - and combine both streams into one, use ``stdout=PIPE`` and ``stderr=STDOUT`` - instead of *capture_output*. + *stdout* and *stdin* both set to :data:`~subprocess.PIPE`. + The *stdout* and *stderr* arguments may not be supplied at the same time as *capture_output*. + If you wish to capture and combine both streams into one, + set *stdout* to :data:`~subprocess.PIPE` + and *stderr* to :data:`~subprocess.STDOUT`, + instead of using *capture_output*. A *timeout* may be specified in seconds, it is internally passed on to :meth:`Popen.communicate`. If the timeout expires, the child process will be @@ -69,7 +71,8 @@ underlying :class:`Popen` interface can be used directly. subprocess's stdin. If used it must be a byte sequence, or a string if *encoding* or *errors* is specified or *text* is true. When used, the internal :class:`Popen` object is automatically created with - ``stdin=PIPE``, and the *stdin* argument may not be used as well. + *stdin* set to :data:`~subprocess.PIPE`, + and the *stdin* argument may not be used as well. If *check* is true, and the process exits with a non-zero exit code, a :exc:`CalledProcessError` exception will be raised. Attributes of that From 9dae05ee59eeba0e67af2a46f2a2907c9f8d7e4a Mon Sep 17 00:00:00 2001 From: Moshe Kaplan Date: Mon, 1 Apr 2024 15:53:00 -0400 Subject: [PATCH 06/11] Docs: specify XML document name in xml.etree.elementtree example (#24223) --- Doc/library/xml.etree.elementtree.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index 5955647588fa3e..7d721f7633899e 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -49,7 +49,7 @@ and its sub-elements are done on the :class:`Element` level. Parsing XML ^^^^^^^^^^^ -We'll be using the following XML document as the sample data for this section: +We'll be using the fictive :file:`country_data.xml` XML document as the sample data for this section: .. code-block:: xml From 5fd1897ec51cb64ef7990ada538fcd8d9ca1f74b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 2 Apr 2024 12:09:53 +0200 Subject: [PATCH 07/11] gh-113317: Argument Clinic: Add libclinic.converters module (#117315) Move the following converter classes to libclinic.converters: * PyByteArrayObject_converter * PyBytesObject_converter * Py_UNICODE_converter * Py_buffer_converter * Py_complex_converter * Py_ssize_t_converter * bool_converter * byte_converter * char_converter * defining_class_converter * double_converter * fildes_converter * float_converter * int_converter * long_converter * long_long_converter * object_converter * self_converter * short_converter * size_t_converter * slice_index_converter * str_converter * unicode_converter * unsigned_char_converter * unsigned_int_converter * unsigned_long_converter * unsigned_long_long_converter * unsigned_short_converter Move also the following classes to libclinic.converters: * buffer * robuffer * rwbuffer Move the following functions to libclinic.converters: * correct_name_for_self() * r() * str_converter_key() Move Null and NULL to libclinic.utils. --- Lib/test/test_clinic.py | 7 +- Tools/clinic/clinic.py | 1208 +------------------------ Tools/clinic/libclinic/__init__.py | 20 +- Tools/clinic/libclinic/converter.py | 16 + Tools/clinic/libclinic/converters.py | 1211 ++++++++++++++++++++++++++ Tools/clinic/libclinic/function.py | 3 +- Tools/clinic/libclinic/utils.py | 9 + 7 files changed, 1259 insertions(+), 1215 deletions(-) create mode 100644 Tools/clinic/libclinic/converters.py diff --git a/Lib/test/test_clinic.py b/Lib/test/test_clinic.py index f95bf858100be6..a07641d1dfda54 100644 --- a/Lib/test/test_clinic.py +++ b/Lib/test/test_clinic.py @@ -17,6 +17,7 @@ test_tools.skip_if_missing('clinic') with test_tools.imports_under_tool('clinic'): import libclinic + from libclinic.converters import int_converter, str_converter import clinic from clinic import DSLParser @@ -924,7 +925,7 @@ def test_param(self): self.assertEqual(2, len(function.parameters)) p = function.parameters['path'] self.assertEqual('path', p.name) - self.assertIsInstance(p.converter, clinic.int_converter) + self.assertIsInstance(p.converter, int_converter) def test_param_default(self): function = self.parse_function(""" @@ -1023,7 +1024,7 @@ def test_param_no_docstring(self): """) self.assertEqual(3, len(function.parameters)) conv = function.parameters['something_else'].converter - self.assertIsInstance(conv, clinic.str_converter) + self.assertIsInstance(conv, str_converter) def test_param_default_parameters_out_of_order(self): err = ( @@ -2040,7 +2041,7 @@ def test_legacy_converters(self): block = self.parse('module os\nos.access\n path: "s"') module, function = block.signatures conv = (function.parameters['path']).converter - self.assertIsInstance(conv, clinic.str_converter) + self.assertIsInstance(conv, str_converter) def test_legacy_converters_non_string_constant_annotation(self): err = "Annotations must be either a name, a function call, or a string" diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index ea480e61ba9a2b..a4e004d5b124d1 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -8,7 +8,6 @@ import argparse import ast -import builtins as bltns import contextlib import dataclasses as dc import enum @@ -46,7 +45,7 @@ import libclinic.cpp from libclinic import ( ClinicError, Sentinels, VersionTuple, - fail, warn, unspecified, unknown) + fail, warn, unspecified, unknown, NULL) from libclinic.function import ( Module, Class, Function, Parameter, ClassDict, ModuleDict, FunctionKind, @@ -56,8 +55,11 @@ from libclinic.block_parser import Block, BlockParser from libclinic.crenderdata import CRenderData, Include, TemplateDict from libclinic.converter import ( - CConverter, CConverterClassT, ConverterType, + CConverter, ConverterType, converters, legacy_converters) +from libclinic.converters import ( + self_converter, defining_class_converter, object_converter, buffer, + robuffer, rwbuffer, correct_name_for_self) # TODO: @@ -77,15 +79,6 @@ LIMITED_CAPI_REGEX = re.compile(r'# *define +Py_LIMITED_API') -# This one needs to be a distinct class, unlike the other two -class Null: - def __repr__(self) -> str: - return '' - - -NULL = Null() - - ParamTuple = tuple["Parameter", ...] @@ -2098,24 +2091,6 @@ def parse(self, block: Block) -> None: ReturnConverterType = Callable[..., "CReturnConverter"] -def add_legacy_c_converter( - format_unit: str, - **kwargs: Any -) -> Callable[[CConverterClassT], CConverterClassT]: - """ - Adds a legacy converter. - """ - def closure(f: CConverterClassT) -> CConverterClassT: - added_f: Callable[..., CConverter] - if not kwargs: - added_f = f - else: - added_f = functools.partial(f, **kwargs) - if format_unit: - legacy_converters[format_unit] = added_f - return f - return closure - # maps strings to callables. # these callables must be of the form: # def foo(*, ...) @@ -2125,1179 +2100,6 @@ def closure(f: CConverterClassT) -> CConverterClassT: ReturnConverterDict = dict[str, ReturnConverterType] return_converters: ReturnConverterDict = {} -TypeSet = set[bltns.type[object]] - - -class bool_converter(CConverter): - type = 'int' - default_type = bool - format_unit = 'p' - c_ignored_default = '0' - - def converter_init(self, *, accept: TypeSet = {object}) -> None: - if accept == {int}: - self.format_unit = 'i' - elif accept != {object}: - fail(f"bool_converter: illegal 'accept' argument {accept!r}") - if self.default is not unspecified and self.default is not unknown: - self.default = bool(self.default) - self.c_default = str(int(self.default)) - - def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: - if self.format_unit == 'i': - return self.format_code(""" - {paramname} = PyLong_AsInt({argname}); - if ({paramname} == -1 && PyErr_Occurred()) {{{{ - goto exit; - }}}} - """, - argname=argname) - elif self.format_unit == 'p': - return self.format_code(""" - {paramname} = PyObject_IsTrue({argname}); - if ({paramname} < 0) {{{{ - goto exit; - }}}} - """, - argname=argname) - return super().parse_arg(argname, displayname, limited_capi=limited_capi) - -class defining_class_converter(CConverter): - """ - A special-case converter: - this is the default converter used for the defining class. - """ - type = 'PyTypeObject *' - format_unit = '' - show_in_signature = False - - def converter_init(self, *, type: str | None = None) -> None: - self.specified_type = type - - def render(self, parameter: Parameter, data: CRenderData) -> None: - self._render_self(parameter, data) - - def set_template_dict(self, template_dict: TemplateDict) -> None: - template_dict['defining_class_name'] = self.name - - -class char_converter(CConverter): - type = 'char' - default_type = (bytes, bytearray) - format_unit = 'c' - c_ignored_default = "'\0'" - - def converter_init(self) -> None: - if isinstance(self.default, self.default_type): - if len(self.default) != 1: - fail(f"char_converter: illegal default value {self.default!r}") - - self.c_default = repr(bytes(self.default))[1:] - if self.c_default == '"\'"': - self.c_default = r"'\''" - - def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: - if self.format_unit == 'c': - return self.format_code(""" - if (PyBytes_Check({argname}) && PyBytes_GET_SIZE({argname}) == 1) {{{{ - {paramname} = PyBytes_AS_STRING({argname})[0]; - }}}} - else if (PyByteArray_Check({argname}) && PyByteArray_GET_SIZE({argname}) == 1) {{{{ - {paramname} = PyByteArray_AS_STRING({argname})[0]; - }}}} - else {{{{ - {bad_argument} - goto exit; - }}}} - """, - argname=argname, - bad_argument=self.bad_argument(displayname, 'a byte string of length 1', limited_capi=limited_capi), - ) - return super().parse_arg(argname, displayname, limited_capi=limited_capi) - - -@add_legacy_c_converter('B', bitwise=True) -class unsigned_char_converter(CConverter): - type = 'unsigned char' - default_type = int - format_unit = 'b' - c_ignored_default = "'\0'" - - def converter_init(self, *, bitwise: bool = False) -> None: - if bitwise: - self.format_unit = 'B' - - def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: - if self.format_unit == 'b': - return self.format_code(""" - {{{{ - long ival = PyLong_AsLong({argname}); - if (ival == -1 && PyErr_Occurred()) {{{{ - goto exit; - }}}} - else if (ival < 0) {{{{ - PyErr_SetString(PyExc_OverflowError, - "unsigned byte integer is less than minimum"); - goto exit; - }}}} - else if (ival > UCHAR_MAX) {{{{ - PyErr_SetString(PyExc_OverflowError, - "unsigned byte integer is greater than maximum"); - goto exit; - }}}} - else {{{{ - {paramname} = (unsigned char) ival; - }}}} - }}}} - """, - argname=argname) - elif self.format_unit == 'B': - return self.format_code(""" - {{{{ - unsigned long ival = PyLong_AsUnsignedLongMask({argname}); - if (ival == (unsigned long)-1 && PyErr_Occurred()) {{{{ - goto exit; - }}}} - else {{{{ - {paramname} = (unsigned char) ival; - }}}} - }}}} - """, - argname=argname) - return super().parse_arg(argname, displayname, limited_capi=limited_capi) - -class byte_converter(unsigned_char_converter): pass - -class short_converter(CConverter): - type = 'short' - default_type = int - format_unit = 'h' - c_ignored_default = "0" - - def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: - if self.format_unit == 'h': - return self.format_code(""" - {{{{ - long ival = PyLong_AsLong({argname}); - if (ival == -1 && PyErr_Occurred()) {{{{ - goto exit; - }}}} - else if (ival < SHRT_MIN) {{{{ - PyErr_SetString(PyExc_OverflowError, - "signed short integer is less than minimum"); - goto exit; - }}}} - else if (ival > SHRT_MAX) {{{{ - PyErr_SetString(PyExc_OverflowError, - "signed short integer is greater than maximum"); - goto exit; - }}}} - else {{{{ - {paramname} = (short) ival; - }}}} - }}}} - """, - argname=argname) - return super().parse_arg(argname, displayname, limited_capi=limited_capi) - -class unsigned_short_converter(CConverter): - type = 'unsigned short' - default_type = int - c_ignored_default = "0" - - def converter_init(self, *, bitwise: bool = False) -> None: - if bitwise: - self.format_unit = 'H' - else: - self.converter = '_PyLong_UnsignedShort_Converter' - - def use_converter(self) -> None: - if self.converter == '_PyLong_UnsignedShort_Converter': - self.add_include('pycore_long.h', - '_PyLong_UnsignedShort_Converter()') - - def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: - if self.format_unit == 'H': - return self.format_code(""" - {paramname} = (unsigned short)PyLong_AsUnsignedLongMask({argname}); - if ({paramname} == (unsigned short)-1 && PyErr_Occurred()) {{{{ - goto exit; - }}}} - """, - argname=argname) - if not limited_capi: - return super().parse_arg(argname, displayname, limited_capi=limited_capi) - # NOTE: Raises OverflowError for negative integer. - return self.format_code(""" - {{{{ - unsigned long uval = PyLong_AsUnsignedLong({argname}); - if (uval == (unsigned long)-1 && PyErr_Occurred()) {{{{ - goto exit; - }}}} - if (uval > USHRT_MAX) {{{{ - PyErr_SetString(PyExc_OverflowError, - "Python int too large for C unsigned short"); - goto exit; - }}}} - {paramname} = (unsigned short) uval; - }}}} - """, - argname=argname) - -@add_legacy_c_converter('C', accept={str}) -class int_converter(CConverter): - type = 'int' - default_type = int - format_unit = 'i' - c_ignored_default = "0" - - def converter_init( - self, *, accept: TypeSet = {int}, type: str | None = None - ) -> None: - if accept == {str}: - self.format_unit = 'C' - elif accept != {int}: - fail(f"int_converter: illegal 'accept' argument {accept!r}") - if type is not None: - self.type = type - - def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: - if self.format_unit == 'i': - return self.format_code(""" - {paramname} = PyLong_AsInt({argname}); - if ({paramname} == -1 && PyErr_Occurred()) {{{{ - goto exit; - }}}} - """, - argname=argname) - elif self.format_unit == 'C': - return self.format_code(""" - if (!PyUnicode_Check({argname})) {{{{ - {bad_argument} - goto exit; - }}}} - if (PyUnicode_GET_LENGTH({argname}) != 1) {{{{ - {bad_argument} - goto exit; - }}}} - {paramname} = PyUnicode_READ_CHAR({argname}, 0); - """, - argname=argname, - bad_argument=self.bad_argument(displayname, 'a unicode character', limited_capi=limited_capi), - ) - return super().parse_arg(argname, displayname, limited_capi=limited_capi) - -class unsigned_int_converter(CConverter): - type = 'unsigned int' - default_type = int - c_ignored_default = "0" - - def converter_init(self, *, bitwise: bool = False) -> None: - if bitwise: - self.format_unit = 'I' - else: - self.converter = '_PyLong_UnsignedInt_Converter' - - def use_converter(self) -> None: - if self.converter == '_PyLong_UnsignedInt_Converter': - self.add_include('pycore_long.h', - '_PyLong_UnsignedInt_Converter()') - - def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: - if self.format_unit == 'I': - return self.format_code(""" - {paramname} = (unsigned int)PyLong_AsUnsignedLongMask({argname}); - if ({paramname} == (unsigned int)-1 && PyErr_Occurred()) {{{{ - goto exit; - }}}} - """, - argname=argname) - if not limited_capi: - return super().parse_arg(argname, displayname, limited_capi=limited_capi) - # NOTE: Raises OverflowError for negative integer. - return self.format_code(""" - {{{{ - unsigned long uval = PyLong_AsUnsignedLong({argname}); - if (uval == (unsigned long)-1 && PyErr_Occurred()) {{{{ - goto exit; - }}}} - if (uval > UINT_MAX) {{{{ - PyErr_SetString(PyExc_OverflowError, - "Python int too large for C unsigned int"); - goto exit; - }}}} - {paramname} = (unsigned int) uval; - }}}} - """, - argname=argname) - -class long_converter(CConverter): - type = 'long' - default_type = int - format_unit = 'l' - c_ignored_default = "0" - - def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: - if self.format_unit == 'l': - return self.format_code(""" - {paramname} = PyLong_AsLong({argname}); - if ({paramname} == -1 && PyErr_Occurred()) {{{{ - goto exit; - }}}} - """, - argname=argname) - return super().parse_arg(argname, displayname, limited_capi=limited_capi) - -class unsigned_long_converter(CConverter): - type = 'unsigned long' - default_type = int - c_ignored_default = "0" - - def converter_init(self, *, bitwise: bool = False) -> None: - if bitwise: - self.format_unit = 'k' - else: - self.converter = '_PyLong_UnsignedLong_Converter' - - def use_converter(self) -> None: - if self.converter == '_PyLong_UnsignedLong_Converter': - self.add_include('pycore_long.h', - '_PyLong_UnsignedLong_Converter()') - - def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: - if self.format_unit == 'k': - return self.format_code(""" - if (!PyLong_Check({argname})) {{{{ - {bad_argument} - goto exit; - }}}} - {paramname} = PyLong_AsUnsignedLongMask({argname}); - """, - argname=argname, - bad_argument=self.bad_argument(displayname, 'int', limited_capi=limited_capi), - ) - if not limited_capi: - return super().parse_arg(argname, displayname, limited_capi=limited_capi) - # NOTE: Raises OverflowError for negative integer. - return self.format_code(""" - {paramname} = PyLong_AsUnsignedLong({argname}); - if ({paramname} == (unsigned long)-1 && PyErr_Occurred()) {{{{ - goto exit; - }}}} - """, - argname=argname) - -class long_long_converter(CConverter): - type = 'long long' - default_type = int - format_unit = 'L' - c_ignored_default = "0" - - def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: - if self.format_unit == 'L': - return self.format_code(""" - {paramname} = PyLong_AsLongLong({argname}); - if ({paramname} == -1 && PyErr_Occurred()) {{{{ - goto exit; - }}}} - """, - argname=argname) - return super().parse_arg(argname, displayname, limited_capi=limited_capi) - -class unsigned_long_long_converter(CConverter): - type = 'unsigned long long' - default_type = int - c_ignored_default = "0" - - def converter_init(self, *, bitwise: bool = False) -> None: - if bitwise: - self.format_unit = 'K' - else: - self.converter = '_PyLong_UnsignedLongLong_Converter' - - def use_converter(self) -> None: - if self.converter == '_PyLong_UnsignedLongLong_Converter': - self.add_include('pycore_long.h', - '_PyLong_UnsignedLongLong_Converter()') - - def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: - if self.format_unit == 'K': - return self.format_code(""" - if (!PyLong_Check({argname})) {{{{ - {bad_argument} - goto exit; - }}}} - {paramname} = PyLong_AsUnsignedLongLongMask({argname}); - """, - argname=argname, - bad_argument=self.bad_argument(displayname, 'int', limited_capi=limited_capi), - ) - if not limited_capi: - return super().parse_arg(argname, displayname, limited_capi=limited_capi) - # NOTE: Raises OverflowError for negative integer. - return self.format_code(""" - {paramname} = PyLong_AsUnsignedLongLong({argname}); - if ({paramname} == (unsigned long long)-1 && PyErr_Occurred()) {{{{ - goto exit; - }}}} - """, - argname=argname) - -class Py_ssize_t_converter(CConverter): - type = 'Py_ssize_t' - c_ignored_default = "0" - - def converter_init(self, *, accept: TypeSet = {int}) -> None: - if accept == {int}: - self.format_unit = 'n' - self.default_type = int - elif accept == {int, NoneType}: - self.converter = '_Py_convert_optional_to_ssize_t' - else: - fail(f"Py_ssize_t_converter: illegal 'accept' argument {accept!r}") - - def use_converter(self) -> None: - if self.converter == '_Py_convert_optional_to_ssize_t': - self.add_include('pycore_abstract.h', - '_Py_convert_optional_to_ssize_t()') - - def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: - if self.format_unit == 'n': - if limited_capi: - PyNumber_Index = 'PyNumber_Index' - else: - PyNumber_Index = '_PyNumber_Index' - self.add_include('pycore_abstract.h', '_PyNumber_Index()') - return self.format_code(""" - {{{{ - Py_ssize_t ival = -1; - PyObject *iobj = {PyNumber_Index}({argname}); - if (iobj != NULL) {{{{ - ival = PyLong_AsSsize_t(iobj); - Py_DECREF(iobj); - }}}} - if (ival == -1 && PyErr_Occurred()) {{{{ - goto exit; - }}}} - {paramname} = ival; - }}}} - """, - argname=argname, - PyNumber_Index=PyNumber_Index) - if not limited_capi: - return super().parse_arg(argname, displayname, limited_capi=limited_capi) - return self.format_code(""" - if ({argname} != Py_None) {{{{ - if (PyIndex_Check({argname})) {{{{ - {paramname} = PyNumber_AsSsize_t({argname}, PyExc_OverflowError); - if ({paramname} == -1 && PyErr_Occurred()) {{{{ - goto exit; - }}}} - }}}} - else {{{{ - {bad_argument} - goto exit; - }}}} - }}}} - """, - argname=argname, - bad_argument=self.bad_argument(displayname, 'integer or None', limited_capi=limited_capi), - ) - - -class slice_index_converter(CConverter): - type = 'Py_ssize_t' - - def converter_init(self, *, accept: TypeSet = {int, NoneType}) -> None: - if accept == {int}: - self.converter = '_PyEval_SliceIndexNotNone' - self.nullable = False - elif accept == {int, NoneType}: - self.converter = '_PyEval_SliceIndex' - self.nullable = True - else: - fail(f"slice_index_converter: illegal 'accept' argument {accept!r}") - - def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: - if not limited_capi: - return super().parse_arg(argname, displayname, limited_capi=limited_capi) - if self.nullable: - return self.format_code(""" - if (!Py_IsNone({argname})) {{{{ - if (PyIndex_Check({argname})) {{{{ - {paramname} = PyNumber_AsSsize_t({argname}, NULL); - if ({paramname} == -1 && PyErr_Occurred()) {{{{ - return 0; - }}}} - }}}} - else {{{{ - PyErr_SetString(PyExc_TypeError, - "slice indices must be integers or " - "None or have an __index__ method"); - goto exit; - }}}} - }}}} - """, - argname=argname) - else: - return self.format_code(""" - if (PyIndex_Check({argname})) {{{{ - {paramname} = PyNumber_AsSsize_t({argname}, NULL); - if ({paramname} == -1 && PyErr_Occurred()) {{{{ - goto exit; - }}}} - }}}} - else {{{{ - PyErr_SetString(PyExc_TypeError, - "slice indices must be integers or " - "have an __index__ method"); - goto exit; - }}}} - """, - argname=argname) - -class size_t_converter(CConverter): - type = 'size_t' - converter = '_PyLong_Size_t_Converter' - c_ignored_default = "0" - - def use_converter(self) -> None: - self.add_include('pycore_long.h', - '_PyLong_Size_t_Converter()') - - def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: - if self.format_unit == 'n': - return self.format_code(""" - {paramname} = PyNumber_AsSsize_t({argname}, PyExc_OverflowError); - if ({paramname} == -1 && PyErr_Occurred()) {{{{ - goto exit; - }}}} - """, - argname=argname) - if not limited_capi: - return super().parse_arg(argname, displayname, limited_capi=limited_capi) - # NOTE: Raises OverflowError for negative integer. - return self.format_code(""" - {paramname} = PyLong_AsSize_t({argname}); - if ({paramname} == (size_t)-1 && PyErr_Occurred()) {{{{ - goto exit; - }}}} - """, - argname=argname) - - -class fildes_converter(CConverter): - type = 'int' - converter = '_PyLong_FileDescriptor_Converter' - - def use_converter(self) -> None: - self.add_include('pycore_fileutils.h', - '_PyLong_FileDescriptor_Converter()') - - def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: - return self.format_code(""" - {paramname} = PyObject_AsFileDescriptor({argname}); - if ({paramname} < 0) {{{{ - goto exit; - }}}} - """, - argname=argname) - - -class float_converter(CConverter): - type = 'float' - default_type = float - format_unit = 'f' - c_ignored_default = "0.0" - - def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: - if self.format_unit == 'f': - if not limited_capi: - return self.format_code(""" - if (PyFloat_CheckExact({argname})) {{{{ - {paramname} = (float) (PyFloat_AS_DOUBLE({argname})); - }}}} - else - {{{{ - {paramname} = (float) PyFloat_AsDouble({argname}); - if ({paramname} == -1.0 && PyErr_Occurred()) {{{{ - goto exit; - }}}} - }}}} - """, - argname=argname) - else: - return self.format_code(""" - {paramname} = (float) PyFloat_AsDouble({argname}); - if ({paramname} == -1.0 && PyErr_Occurred()) {{{{ - goto exit; - }}}} - """, - argname=argname) - return super().parse_arg(argname, displayname, limited_capi=limited_capi) - -class double_converter(CConverter): - type = 'double' - default_type = float - format_unit = 'd' - c_ignored_default = "0.0" - - def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: - if self.format_unit == 'd': - if not limited_capi: - return self.format_code(""" - if (PyFloat_CheckExact({argname})) {{{{ - {paramname} = PyFloat_AS_DOUBLE({argname}); - }}}} - else - {{{{ - {paramname} = PyFloat_AsDouble({argname}); - if ({paramname} == -1.0 && PyErr_Occurred()) {{{{ - goto exit; - }}}} - }}}} - """, - argname=argname) - else: - return self.format_code(""" - {paramname} = PyFloat_AsDouble({argname}); - if ({paramname} == -1.0 && PyErr_Occurred()) {{{{ - goto exit; - }}}} - """, - argname=argname) - return super().parse_arg(argname, displayname, limited_capi=limited_capi) - - -class Py_complex_converter(CConverter): - type = 'Py_complex' - default_type = complex - format_unit = 'D' - c_ignored_default = "{0.0, 0.0}" - - def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: - if self.format_unit == 'D': - return self.format_code(""" - {paramname} = PyComplex_AsCComplex({argname}); - if (PyErr_Occurred()) {{{{ - goto exit; - }}}} - """, - argname=argname) - return super().parse_arg(argname, displayname, limited_capi=limited_capi) - - -class object_converter(CConverter): - type = 'PyObject *' - format_unit = 'O' - - def converter_init( - self, *, - converter: str | None = None, - type: str | None = None, - subclass_of: str | None = None - ) -> None: - if converter: - if subclass_of: - fail("object: Cannot pass in both 'converter' and 'subclass_of'") - self.format_unit = 'O&' - self.converter = converter - elif subclass_of: - self.format_unit = 'O!' - self.subclass_of = subclass_of - - if type is not None: - self.type = type - - -# -# We define three conventions for buffer types in the 'accept' argument: -# -# buffer : any object supporting the buffer interface -# rwbuffer: any object supporting the buffer interface, but must be writeable -# robuffer: any object supporting the buffer interface, but must not be writeable -# - -class buffer: pass -class rwbuffer: pass -class robuffer: pass - -StrConverterKeyType = tuple[frozenset[type[object]], bool, bool] - -def str_converter_key( - types: TypeSet, encoding: bool | str | None, zeroes: bool -) -> StrConverterKeyType: - return (frozenset(types), bool(encoding), bool(zeroes)) - -str_converter_argument_map: dict[StrConverterKeyType, str] = {} - -class str_converter(CConverter): - type = 'const char *' - default_type = (str, Null, NoneType) - format_unit = 's' - - def converter_init( - self, - *, - accept: TypeSet = {str}, - encoding: str | None = None, - zeroes: bool = False - ) -> None: - - key = str_converter_key(accept, encoding, zeroes) - format_unit = str_converter_argument_map.get(key) - if not format_unit: - fail("str_converter: illegal combination of arguments", key) - - self.format_unit = format_unit - self.length = bool(zeroes) - if encoding: - if self.default not in (Null, None, unspecified): - fail("str_converter: Argument Clinic doesn't support default values for encoded strings") - self.encoding = encoding - self.type = 'char *' - # sorry, clinic can't support preallocated buffers - # for es# and et# - self.c_default = "NULL" - if NoneType in accept and self.c_default == "Py_None": - self.c_default = "NULL" - - def post_parsing(self) -> str: - if self.encoding: - name = self.name - return f"PyMem_FREE({name});\n" - else: - return "" - - def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: - if self.format_unit == 's': - return self.format_code(""" - if (!PyUnicode_Check({argname})) {{{{ - {bad_argument} - goto exit; - }}}} - Py_ssize_t {length_name}; - {paramname} = PyUnicode_AsUTF8AndSize({argname}, &{length_name}); - if ({paramname} == NULL) {{{{ - goto exit; - }}}} - if (strlen({paramname}) != (size_t){length_name}) {{{{ - PyErr_SetString(PyExc_ValueError, "embedded null character"); - goto exit; - }}}} - """, - argname=argname, - bad_argument=self.bad_argument(displayname, 'str', limited_capi=limited_capi), - length_name=self.length_name) - if self.format_unit == 'z': - return self.format_code(""" - if ({argname} == Py_None) {{{{ - {paramname} = NULL; - }}}} - else if (PyUnicode_Check({argname})) {{{{ - Py_ssize_t {length_name}; - {paramname} = PyUnicode_AsUTF8AndSize({argname}, &{length_name}); - if ({paramname} == NULL) {{{{ - goto exit; - }}}} - if (strlen({paramname}) != (size_t){length_name}) {{{{ - PyErr_SetString(PyExc_ValueError, "embedded null character"); - goto exit; - }}}} - }}}} - else {{{{ - {bad_argument} - goto exit; - }}}} - """, - argname=argname, - bad_argument=self.bad_argument(displayname, 'str or None', limited_capi=limited_capi), - length_name=self.length_name) - return super().parse_arg(argname, displayname, limited_capi=limited_capi) - -# -# This is the fourth or fifth rewrite of registering all the -# string converter format units. Previous approaches hid -# bugs--generally mismatches between the semantics of the format -# unit and the arguments necessary to represent those semantics -# properly. Hopefully with this approach we'll get it 100% right. -# -# The r() function (short for "register") both registers the -# mapping from arguments to format unit *and* registers the -# legacy C converter for that format unit. -# -def r(format_unit: str, - *, - accept: TypeSet, - encoding: bool = False, - zeroes: bool = False -) -> None: - if not encoding and format_unit != 's': - # add the legacy c converters here too. - # - # note: add_legacy_c_converter can't work for - # es, es#, et, or et# - # because of their extra encoding argument - # - # also don't add the converter for 's' because - # the metaclass for CConverter adds it for us. - kwargs: dict[str, Any] = {} - if accept != {str}: - kwargs['accept'] = accept - if zeroes: - kwargs['zeroes'] = True - added_f = functools.partial(str_converter, **kwargs) - legacy_converters[format_unit] = added_f - - d = str_converter_argument_map - key = str_converter_key(accept, encoding, zeroes) - if key in d: - sys.exit("Duplicate keys specified for str_converter_argument_map!") - d[key] = format_unit - -r('es', encoding=True, accept={str}) -r('es#', encoding=True, zeroes=True, accept={str}) -r('et', encoding=True, accept={bytes, bytearray, str}) -r('et#', encoding=True, zeroes=True, accept={bytes, bytearray, str}) -r('s', accept={str}) -r('s#', zeroes=True, accept={robuffer, str}) -r('y', accept={robuffer}) -r('y#', zeroes=True, accept={robuffer}) -r('z', accept={str, NoneType}) -r('z#', zeroes=True, accept={robuffer, str, NoneType}) -del r - - -class PyBytesObject_converter(CConverter): - type = 'PyBytesObject *' - format_unit = 'S' - # accept = {bytes} - - def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: - if self.format_unit == 'S': - return self.format_code(""" - if (!PyBytes_Check({argname})) {{{{ - {bad_argument} - goto exit; - }}}} - {paramname} = ({type}){argname}; - """, - argname=argname, - bad_argument=self.bad_argument(displayname, 'bytes', limited_capi=limited_capi), - type=self.type) - return super().parse_arg(argname, displayname, limited_capi=limited_capi) - -class PyByteArrayObject_converter(CConverter): - type = 'PyByteArrayObject *' - format_unit = 'Y' - # accept = {bytearray} - - def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: - if self.format_unit == 'Y': - return self.format_code(""" - if (!PyByteArray_Check({argname})) {{{{ - {bad_argument} - goto exit; - }}}} - {paramname} = ({type}){argname}; - """, - argname=argname, - bad_argument=self.bad_argument(displayname, 'bytearray', limited_capi=limited_capi), - type=self.type) - return super().parse_arg(argname, displayname, limited_capi=limited_capi) - -class unicode_converter(CConverter): - type = 'PyObject *' - default_type = (str, Null, NoneType) - format_unit = 'U' - - def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: - if self.format_unit == 'U': - return self.format_code(""" - if (!PyUnicode_Check({argname})) {{{{ - {bad_argument} - goto exit; - }}}} - {paramname} = {argname}; - """, - argname=argname, - bad_argument=self.bad_argument(displayname, 'str', limited_capi=limited_capi), - ) - return super().parse_arg(argname, displayname, limited_capi=limited_capi) - -@add_legacy_c_converter('u') -@add_legacy_c_converter('u#', zeroes=True) -@add_legacy_c_converter('Z', accept={str, NoneType}) -@add_legacy_c_converter('Z#', accept={str, NoneType}, zeroes=True) -class Py_UNICODE_converter(CConverter): - type = 'const wchar_t *' - default_type = (str, Null, NoneType) - - def converter_init( - self, *, - accept: TypeSet = {str}, - zeroes: bool = False - ) -> None: - format_unit = 'Z' if accept=={str, NoneType} else 'u' - if zeroes: - format_unit += '#' - self.length = True - self.format_unit = format_unit - else: - self.accept = accept - if accept == {str}: - self.converter = '_PyUnicode_WideCharString_Converter' - elif accept == {str, NoneType}: - self.converter = '_PyUnicode_WideCharString_Opt_Converter' - else: - fail(f"Py_UNICODE_converter: illegal 'accept' argument {accept!r}") - self.c_default = "NULL" - - def cleanup(self) -> str: - if self.length: - return "" - else: - return f"""PyMem_Free((void *){self.parser_name});\n""" - - def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: - if not self.length: - if self.accept == {str}: - return self.format_code(""" - if (!PyUnicode_Check({argname})) {{{{ - {bad_argument} - goto exit; - }}}} - {paramname} = PyUnicode_AsWideCharString({argname}, NULL); - if ({paramname} == NULL) {{{{ - goto exit; - }}}} - """, - argname=argname, - bad_argument=self.bad_argument(displayname, 'str', limited_capi=limited_capi), - ) - elif self.accept == {str, NoneType}: - return self.format_code(""" - if ({argname} == Py_None) {{{{ - {paramname} = NULL; - }}}} - else if (PyUnicode_Check({argname})) {{{{ - {paramname} = PyUnicode_AsWideCharString({argname}, NULL); - if ({paramname} == NULL) {{{{ - goto exit; - }}}} - }}}} - else {{{{ - {bad_argument} - goto exit; - }}}} - """, - argname=argname, - bad_argument=self.bad_argument(displayname, 'str or None', limited_capi=limited_capi), - ) - return super().parse_arg(argname, displayname, limited_capi=limited_capi) - -@add_legacy_c_converter('s*', accept={str, buffer}) -@add_legacy_c_converter('z*', accept={str, buffer, NoneType}) -@add_legacy_c_converter('w*', accept={rwbuffer}) -class Py_buffer_converter(CConverter): - type = 'Py_buffer' - format_unit = 'y*' - impl_by_reference = True - c_ignored_default = "{NULL, NULL}" - - def converter_init(self, *, accept: TypeSet = {buffer}) -> None: - if self.default not in (unspecified, None): - fail("The only legal default value for Py_buffer is None.") - - self.c_default = self.c_ignored_default - - if accept == {str, buffer, NoneType}: - format_unit = 'z*' - elif accept == {str, buffer}: - format_unit = 's*' - elif accept == {buffer}: - format_unit = 'y*' - elif accept == {rwbuffer}: - format_unit = 'w*' - else: - fail("Py_buffer_converter: illegal combination of arguments") - - self.format_unit = format_unit - - def cleanup(self) -> str: - name = self.name - return "".join(["if (", name, ".obj) {\n PyBuffer_Release(&", name, ");\n}\n"]) - - def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: - # PyBUF_SIMPLE guarantees that the format units of the buffers are C-contiguous. - if self.format_unit == 'y*': - return self.format_code(""" - if (PyObject_GetBuffer({argname}, &{paramname}, PyBUF_SIMPLE) != 0) {{{{ - goto exit; - }}}} - """, - argname=argname, - bad_argument=self.bad_argument(displayname, 'contiguous buffer', limited_capi=limited_capi), - ) - elif self.format_unit == 's*': - return self.format_code(""" - if (PyUnicode_Check({argname})) {{{{ - Py_ssize_t len; - const char *ptr = PyUnicode_AsUTF8AndSize({argname}, &len); - if (ptr == NULL) {{{{ - goto exit; - }}}} - if (PyBuffer_FillInfo(&{paramname}, {argname}, (void *)ptr, len, 1, PyBUF_SIMPLE) < 0) {{{{ - goto exit; - }}}} - }}}} - else {{{{ /* any bytes-like object */ - if (PyObject_GetBuffer({argname}, &{paramname}, PyBUF_SIMPLE) != 0) {{{{ - goto exit; - }}}} - }}}} - """, - argname=argname, - bad_argument=self.bad_argument(displayname, 'contiguous buffer', limited_capi=limited_capi), - ) - elif self.format_unit == 'w*': - return self.format_code(""" - if (PyObject_GetBuffer({argname}, &{paramname}, PyBUF_WRITABLE) < 0) {{{{ - {bad_argument} - goto exit; - }}}} - """, - argname=argname, - bad_argument=self.bad_argument(displayname, 'read-write bytes-like object', limited_capi=limited_capi), - bad_argument2=self.bad_argument(displayname, 'contiguous buffer', limited_capi=limited_capi), - ) - return super().parse_arg(argname, displayname, limited_capi=limited_capi) - - -def correct_name_for_self( - f: Function -) -> tuple[str, str]: - if f.kind in {CALLABLE, METHOD_INIT, GETTER, SETTER}: - if f.cls: - return "PyObject *", "self" - return "PyObject *", "module" - if f.kind is STATIC_METHOD: - return "void *", "null" - if f.kind in (CLASS_METHOD, METHOD_NEW): - return "PyTypeObject *", "type" - raise AssertionError(f"Unhandled type of function f: {f.kind!r}") - - -class self_converter(CConverter): - """ - A special-case converter: - this is the default converter used for "self". - """ - type: str | None = None - format_unit = '' - - def converter_init(self, *, type: str | None = None) -> None: - self.specified_type = type - - def pre_render(self) -> None: - f = self.function - default_type, default_name = correct_name_for_self(f) - self.signature_name = default_name - self.type = self.specified_type or self.type or default_type - - kind = self.function.kind - - if kind is STATIC_METHOD or kind.new_or_init: - self.show_in_signature = False - - # tp_new (METHOD_NEW) functions are of type newfunc: - # typedef PyObject *(*newfunc)(PyTypeObject *, PyObject *, PyObject *); - # - # tp_init (METHOD_INIT) functions are of type initproc: - # typedef int (*initproc)(PyObject *, PyObject *, PyObject *); - # - # All other functions generated by Argument Clinic are stored in - # PyMethodDef structures, in the ml_meth slot, which is of type PyCFunction: - # typedef PyObject *(*PyCFunction)(PyObject *, PyObject *); - # However! We habitually cast these functions to PyCFunction, - # since functions that accept keyword arguments don't fit this signature - # but are stored there anyway. So strict type equality isn't important - # for these functions. - # - # So: - # - # * The name of the first parameter to the impl and the parsing function will always - # be self.name. - # - # * The type of the first parameter to the impl will always be of self.type. - # - # * If the function is neither tp_new (METHOD_NEW) nor tp_init (METHOD_INIT): - # * The type of the first parameter to the parsing function is also self.type. - # This means that if you step into the parsing function, your "self" parameter - # is of the correct type, which may make debugging more pleasant. - # - # * Else if the function is tp_new (METHOD_NEW): - # * The type of the first parameter to the parsing function is "PyTypeObject *", - # so the type signature of the function call is an exact match. - # * If self.type != "PyTypeObject *", we cast the first parameter to self.type - # in the impl call. - # - # * Else if the function is tp_init (METHOD_INIT): - # * The type of the first parameter to the parsing function is "PyObject *", - # so the type signature of the function call is an exact match. - # * If self.type != "PyObject *", we cast the first parameter to self.type - # in the impl call. - - @property - def parser_type(self) -> str: - assert self.type is not None - if self.function.kind in {METHOD_INIT, METHOD_NEW, STATIC_METHOD, CLASS_METHOD}: - tp, _ = correct_name_for_self(self.function) - return tp - return self.type - - def render(self, parameter: Parameter, data: CRenderData) -> None: - """ - parameter is a clinic.Parameter instance. - data is a CRenderData instance. - """ - if self.function.kind is STATIC_METHOD: - return - - self._render_self(parameter, data) - - if self.type != self.parser_type: - # insert cast to impl_argument[0], aka self. - # we know we're in the first slot in all the CRenderData lists, - # because we render parameters in order, and self is always first. - assert len(data.impl_arguments) == 1 - assert data.impl_arguments[0] == self.name - assert self.type is not None - data.impl_arguments[0] = '(' + self.type + ")" + data.impl_arguments[0] - - def set_template_dict(self, template_dict: TemplateDict) -> None: - template_dict['self_name'] = self.name - template_dict['self_type'] = self.parser_type - kind = self.function.kind - cls = self.function.cls - - if kind.new_or_init and cls and cls.typedef: - if kind is METHOD_NEW: - type_check = ( - '({0} == base_tp || {0}->tp_init == base_tp->tp_init)' - ).format(self.name) - else: - type_check = ('(Py_IS_TYPE({0}, base_tp) ||\n ' - ' Py_TYPE({0})->tp_new == base_tp->tp_new)' - ).format(self.name) - - line = f'{type_check} &&\n ' - template_dict['self_type_check'] = line - - type_object = cls.type_object - type_ptr = f'PyTypeObject *base_tp = {type_object};' - template_dict['base_type_ptr'] = type_ptr - def add_c_return_converter( f: ReturnConverterType, diff --git a/Tools/clinic/libclinic/__init__.py b/Tools/clinic/libclinic/__init__.py index 32231b82bfdc07..7c5cede2396677 100644 --- a/Tools/clinic/libclinic/__init__.py +++ b/Tools/clinic/libclinic/__init__.py @@ -25,13 +25,15 @@ ) from .utils import ( FormatCounterFormatter, + NULL, + Null, + Sentinels, + VersionTuple, compute_checksum, create_regex, - write_file, - VersionTuple, - Sentinels, - unspecified, unknown, + unspecified, + write_file, ) @@ -61,13 +63,15 @@ # Utility functions "FormatCounterFormatter", + "NULL", + "Null", + "Sentinels", + "VersionTuple", "compute_checksum", "create_regex", - "write_file", - "VersionTuple", - "Sentinels", - "unspecified", "unknown", + "unspecified", + "write_file", ] diff --git a/Tools/clinic/libclinic/converter.py b/Tools/clinic/libclinic/converter.py index 744d03c2c1fea4..ac78be3f7958da 100644 --- a/Tools/clinic/libclinic/converter.py +++ b/Tools/clinic/libclinic/converter.py @@ -531,3 +531,19 @@ def add_include(self, name: str, reason: str, # these callables follow the same rules as those for "converters" above. # note however that they will never be called with keyword-only parameters. legacy_converters: ConverterDict = {} + + +def add_legacy_c_converter( + format_unit: str, + **kwargs: Any +) -> Callable[[CConverterClassT], CConverterClassT]: + def closure(f: CConverterClassT) -> CConverterClassT: + added_f: Callable[..., CConverter] + if not kwargs: + added_f = f + else: + added_f = functools.partial(f, **kwargs) + if format_unit: + legacy_converters[format_unit] = added_f + return f + return closure diff --git a/Tools/clinic/libclinic/converters.py b/Tools/clinic/libclinic/converters.py new file mode 100644 index 00000000000000..7fc16f17450aaa --- /dev/null +++ b/Tools/clinic/libclinic/converters.py @@ -0,0 +1,1211 @@ +import builtins as bltns +import functools +import sys +from types import NoneType +from typing import Any + +from libclinic import fail, Null, unspecified, unknown +from libclinic.function import ( + Function, Parameter, + CALLABLE, STATIC_METHOD, CLASS_METHOD, METHOD_INIT, METHOD_NEW, + GETTER, SETTER) +from libclinic.crenderdata import CRenderData, TemplateDict +from libclinic.converter import ( + CConverter, legacy_converters, add_legacy_c_converter) + + +TypeSet = set[bltns.type[object]] + + +class bool_converter(CConverter): + type = 'int' + default_type = bool + format_unit = 'p' + c_ignored_default = '0' + + def converter_init(self, *, accept: TypeSet = {object}) -> None: + if accept == {int}: + self.format_unit = 'i' + elif accept != {object}: + fail(f"bool_converter: illegal 'accept' argument {accept!r}") + if self.default is not unspecified and self.default is not unknown: + self.default = bool(self.default) + self.c_default = str(int(self.default)) + + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: + if self.format_unit == 'i': + return self.format_code(""" + {paramname} = PyLong_AsInt({argname}); + if ({paramname} == -1 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """, + argname=argname) + elif self.format_unit == 'p': + return self.format_code(""" + {paramname} = PyObject_IsTrue({argname}); + if ({paramname} < 0) {{{{ + goto exit; + }}}} + """, + argname=argname) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) + + +class defining_class_converter(CConverter): + """ + A special-case converter: + this is the default converter used for the defining class. + """ + type = 'PyTypeObject *' + format_unit = '' + show_in_signature = False + + def converter_init(self, *, type: str | None = None) -> None: + self.specified_type = type + + def render(self, parameter: Parameter, data: CRenderData) -> None: + self._render_self(parameter, data) + + def set_template_dict(self, template_dict: TemplateDict) -> None: + template_dict['defining_class_name'] = self.name + + +class char_converter(CConverter): + type = 'char' + default_type = (bytes, bytearray) + format_unit = 'c' + c_ignored_default = "'\0'" + + def converter_init(self) -> None: + if isinstance(self.default, self.default_type): + if len(self.default) != 1: + fail(f"char_converter: illegal default value {self.default!r}") + + self.c_default = repr(bytes(self.default))[1:] + if self.c_default == '"\'"': + self.c_default = r"'\''" + + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: + if self.format_unit == 'c': + return self.format_code(""" + if (PyBytes_Check({argname}) && PyBytes_GET_SIZE({argname}) == 1) {{{{ + {paramname} = PyBytes_AS_STRING({argname})[0]; + }}}} + else if (PyByteArray_Check({argname}) && PyByteArray_GET_SIZE({argname}) == 1) {{{{ + {paramname} = PyByteArray_AS_STRING({argname})[0]; + }}}} + else {{{{ + {bad_argument} + goto exit; + }}}} + """, + argname=argname, + bad_argument=self.bad_argument(displayname, 'a byte string of length 1', limited_capi=limited_capi), + ) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) + + +@add_legacy_c_converter('B', bitwise=True) +class unsigned_char_converter(CConverter): + type = 'unsigned char' + default_type = int + format_unit = 'b' + c_ignored_default = "'\0'" + + def converter_init(self, *, bitwise: bool = False) -> None: + if bitwise: + self.format_unit = 'B' + + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: + if self.format_unit == 'b': + return self.format_code(""" + {{{{ + long ival = PyLong_AsLong({argname}); + if (ival == -1 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + else if (ival < 0) {{{{ + PyErr_SetString(PyExc_OverflowError, + "unsigned byte integer is less than minimum"); + goto exit; + }}}} + else if (ival > UCHAR_MAX) {{{{ + PyErr_SetString(PyExc_OverflowError, + "unsigned byte integer is greater than maximum"); + goto exit; + }}}} + else {{{{ + {paramname} = (unsigned char) ival; + }}}} + }}}} + """, + argname=argname) + elif self.format_unit == 'B': + return self.format_code(""" + {{{{ + unsigned long ival = PyLong_AsUnsignedLongMask({argname}); + if (ival == (unsigned long)-1 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + else {{{{ + {paramname} = (unsigned char) ival; + }}}} + }}}} + """, + argname=argname) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) + + +class byte_converter(unsigned_char_converter): + pass + + +class short_converter(CConverter): + type = 'short' + default_type = int + format_unit = 'h' + c_ignored_default = "0" + + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: + if self.format_unit == 'h': + return self.format_code(""" + {{{{ + long ival = PyLong_AsLong({argname}); + if (ival == -1 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + else if (ival < SHRT_MIN) {{{{ + PyErr_SetString(PyExc_OverflowError, + "signed short integer is less than minimum"); + goto exit; + }}}} + else if (ival > SHRT_MAX) {{{{ + PyErr_SetString(PyExc_OverflowError, + "signed short integer is greater than maximum"); + goto exit; + }}}} + else {{{{ + {paramname} = (short) ival; + }}}} + }}}} + """, + argname=argname) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) + + +class unsigned_short_converter(CConverter): + type = 'unsigned short' + default_type = int + c_ignored_default = "0" + + def converter_init(self, *, bitwise: bool = False) -> None: + if bitwise: + self.format_unit = 'H' + else: + self.converter = '_PyLong_UnsignedShort_Converter' + + def use_converter(self) -> None: + if self.converter == '_PyLong_UnsignedShort_Converter': + self.add_include('pycore_long.h', + '_PyLong_UnsignedShort_Converter()') + + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: + if self.format_unit == 'H': + return self.format_code(""" + {paramname} = (unsigned short)PyLong_AsUnsignedLongMask({argname}); + if ({paramname} == (unsigned short)-1 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """, + argname=argname) + if not limited_capi: + return super().parse_arg(argname, displayname, limited_capi=limited_capi) + # NOTE: Raises OverflowError for negative integer. + return self.format_code(""" + {{{{ + unsigned long uval = PyLong_AsUnsignedLong({argname}); + if (uval == (unsigned long)-1 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + if (uval > USHRT_MAX) {{{{ + PyErr_SetString(PyExc_OverflowError, + "Python int too large for C unsigned short"); + goto exit; + }}}} + {paramname} = (unsigned short) uval; + }}}} + """, + argname=argname) + + +@add_legacy_c_converter('C', accept={str}) +class int_converter(CConverter): + type = 'int' + default_type = int + format_unit = 'i' + c_ignored_default = "0" + + def converter_init( + self, *, accept: TypeSet = {int}, type: str | None = None + ) -> None: + if accept == {str}: + self.format_unit = 'C' + elif accept != {int}: + fail(f"int_converter: illegal 'accept' argument {accept!r}") + if type is not None: + self.type = type + + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: + if self.format_unit == 'i': + return self.format_code(""" + {paramname} = PyLong_AsInt({argname}); + if ({paramname} == -1 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """, + argname=argname) + elif self.format_unit == 'C': + return self.format_code(""" + if (!PyUnicode_Check({argname})) {{{{ + {bad_argument} + goto exit; + }}}} + if (PyUnicode_GET_LENGTH({argname}) != 1) {{{{ + {bad_argument} + goto exit; + }}}} + {paramname} = PyUnicode_READ_CHAR({argname}, 0); + """, + argname=argname, + bad_argument=self.bad_argument(displayname, 'a unicode character', limited_capi=limited_capi), + ) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) + + +class unsigned_int_converter(CConverter): + type = 'unsigned int' + default_type = int + c_ignored_default = "0" + + def converter_init(self, *, bitwise: bool = False) -> None: + if bitwise: + self.format_unit = 'I' + else: + self.converter = '_PyLong_UnsignedInt_Converter' + + def use_converter(self) -> None: + if self.converter == '_PyLong_UnsignedInt_Converter': + self.add_include('pycore_long.h', + '_PyLong_UnsignedInt_Converter()') + + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: + if self.format_unit == 'I': + return self.format_code(""" + {paramname} = (unsigned int)PyLong_AsUnsignedLongMask({argname}); + if ({paramname} == (unsigned int)-1 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """, + argname=argname) + if not limited_capi: + return super().parse_arg(argname, displayname, limited_capi=limited_capi) + # NOTE: Raises OverflowError for negative integer. + return self.format_code(""" + {{{{ + unsigned long uval = PyLong_AsUnsignedLong({argname}); + if (uval == (unsigned long)-1 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + if (uval > UINT_MAX) {{{{ + PyErr_SetString(PyExc_OverflowError, + "Python int too large for C unsigned int"); + goto exit; + }}}} + {paramname} = (unsigned int) uval; + }}}} + """, + argname=argname) + + +class long_converter(CConverter): + type = 'long' + default_type = int + format_unit = 'l' + c_ignored_default = "0" + + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: + if self.format_unit == 'l': + return self.format_code(""" + {paramname} = PyLong_AsLong({argname}); + if ({paramname} == -1 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """, + argname=argname) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) + + +class unsigned_long_converter(CConverter): + type = 'unsigned long' + default_type = int + c_ignored_default = "0" + + def converter_init(self, *, bitwise: bool = False) -> None: + if bitwise: + self.format_unit = 'k' + else: + self.converter = '_PyLong_UnsignedLong_Converter' + + def use_converter(self) -> None: + if self.converter == '_PyLong_UnsignedLong_Converter': + self.add_include('pycore_long.h', + '_PyLong_UnsignedLong_Converter()') + + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: + if self.format_unit == 'k': + return self.format_code(""" + if (!PyLong_Check({argname})) {{{{ + {bad_argument} + goto exit; + }}}} + {paramname} = PyLong_AsUnsignedLongMask({argname}); + """, + argname=argname, + bad_argument=self.bad_argument(displayname, 'int', limited_capi=limited_capi), + ) + if not limited_capi: + return super().parse_arg(argname, displayname, limited_capi=limited_capi) + # NOTE: Raises OverflowError for negative integer. + return self.format_code(""" + {paramname} = PyLong_AsUnsignedLong({argname}); + if ({paramname} == (unsigned long)-1 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """, + argname=argname) + + +class long_long_converter(CConverter): + type = 'long long' + default_type = int + format_unit = 'L' + c_ignored_default = "0" + + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: + if self.format_unit == 'L': + return self.format_code(""" + {paramname} = PyLong_AsLongLong({argname}); + if ({paramname} == -1 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """, + argname=argname) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) + + +class unsigned_long_long_converter(CConverter): + type = 'unsigned long long' + default_type = int + c_ignored_default = "0" + + def converter_init(self, *, bitwise: bool = False) -> None: + if bitwise: + self.format_unit = 'K' + else: + self.converter = '_PyLong_UnsignedLongLong_Converter' + + def use_converter(self) -> None: + if self.converter == '_PyLong_UnsignedLongLong_Converter': + self.add_include('pycore_long.h', + '_PyLong_UnsignedLongLong_Converter()') + + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: + if self.format_unit == 'K': + return self.format_code(""" + if (!PyLong_Check({argname})) {{{{ + {bad_argument} + goto exit; + }}}} + {paramname} = PyLong_AsUnsignedLongLongMask({argname}); + """, + argname=argname, + bad_argument=self.bad_argument(displayname, 'int', limited_capi=limited_capi), + ) + if not limited_capi: + return super().parse_arg(argname, displayname, limited_capi=limited_capi) + # NOTE: Raises OverflowError for negative integer. + return self.format_code(""" + {paramname} = PyLong_AsUnsignedLongLong({argname}); + if ({paramname} == (unsigned long long)-1 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """, + argname=argname) + + +class Py_ssize_t_converter(CConverter): + type = 'Py_ssize_t' + c_ignored_default = "0" + + def converter_init(self, *, accept: TypeSet = {int}) -> None: + if accept == {int}: + self.format_unit = 'n' + self.default_type = int + elif accept == {int, NoneType}: + self.converter = '_Py_convert_optional_to_ssize_t' + else: + fail(f"Py_ssize_t_converter: illegal 'accept' argument {accept!r}") + + def use_converter(self) -> None: + if self.converter == '_Py_convert_optional_to_ssize_t': + self.add_include('pycore_abstract.h', + '_Py_convert_optional_to_ssize_t()') + + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: + if self.format_unit == 'n': + if limited_capi: + PyNumber_Index = 'PyNumber_Index' + else: + PyNumber_Index = '_PyNumber_Index' + self.add_include('pycore_abstract.h', '_PyNumber_Index()') + return self.format_code(""" + {{{{ + Py_ssize_t ival = -1; + PyObject *iobj = {PyNumber_Index}({argname}); + if (iobj != NULL) {{{{ + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + }}}} + if (ival == -1 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + {paramname} = ival; + }}}} + """, + argname=argname, + PyNumber_Index=PyNumber_Index) + if not limited_capi: + return super().parse_arg(argname, displayname, limited_capi=limited_capi) + return self.format_code(""" + if ({argname} != Py_None) {{{{ + if (PyIndex_Check({argname})) {{{{ + {paramname} = PyNumber_AsSsize_t({argname}, PyExc_OverflowError); + if ({paramname} == -1 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + }}}} + else {{{{ + {bad_argument} + goto exit; + }}}} + }}}} + """, + argname=argname, + bad_argument=self.bad_argument(displayname, 'integer or None', limited_capi=limited_capi), + ) + + +class slice_index_converter(CConverter): + type = 'Py_ssize_t' + + def converter_init(self, *, accept: TypeSet = {int, NoneType}) -> None: + if accept == {int}: + self.converter = '_PyEval_SliceIndexNotNone' + self.nullable = False + elif accept == {int, NoneType}: + self.converter = '_PyEval_SliceIndex' + self.nullable = True + else: + fail(f"slice_index_converter: illegal 'accept' argument {accept!r}") + + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: + if not limited_capi: + return super().parse_arg(argname, displayname, limited_capi=limited_capi) + if self.nullable: + return self.format_code(""" + if (!Py_IsNone({argname})) {{{{ + if (PyIndex_Check({argname})) {{{{ + {paramname} = PyNumber_AsSsize_t({argname}, NULL); + if ({paramname} == -1 && PyErr_Occurred()) {{{{ + return 0; + }}}} + }}}} + else {{{{ + PyErr_SetString(PyExc_TypeError, + "slice indices must be integers or " + "None or have an __index__ method"); + goto exit; + }}}} + }}}} + """, + argname=argname) + else: + return self.format_code(""" + if (PyIndex_Check({argname})) {{{{ + {paramname} = PyNumber_AsSsize_t({argname}, NULL); + if ({paramname} == -1 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + }}}} + else {{{{ + PyErr_SetString(PyExc_TypeError, + "slice indices must be integers or " + "have an __index__ method"); + goto exit; + }}}} + """, + argname=argname) + + +class size_t_converter(CConverter): + type = 'size_t' + converter = '_PyLong_Size_t_Converter' + c_ignored_default = "0" + + def use_converter(self) -> None: + self.add_include('pycore_long.h', + '_PyLong_Size_t_Converter()') + + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: + if self.format_unit == 'n': + return self.format_code(""" + {paramname} = PyNumber_AsSsize_t({argname}, PyExc_OverflowError); + if ({paramname} == -1 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """, + argname=argname) + if not limited_capi: + return super().parse_arg(argname, displayname, limited_capi=limited_capi) + # NOTE: Raises OverflowError for negative integer. + return self.format_code(""" + {paramname} = PyLong_AsSize_t({argname}); + if ({paramname} == (size_t)-1 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """, + argname=argname) + + +class fildes_converter(CConverter): + type = 'int' + converter = '_PyLong_FileDescriptor_Converter' + + def use_converter(self) -> None: + self.add_include('pycore_fileutils.h', + '_PyLong_FileDescriptor_Converter()') + + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: + return self.format_code(""" + {paramname} = PyObject_AsFileDescriptor({argname}); + if ({paramname} < 0) {{{{ + goto exit; + }}}} + """, + argname=argname) + + +class float_converter(CConverter): + type = 'float' + default_type = float + format_unit = 'f' + c_ignored_default = "0.0" + + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: + if self.format_unit == 'f': + if not limited_capi: + return self.format_code(""" + if (PyFloat_CheckExact({argname})) {{{{ + {paramname} = (float) (PyFloat_AS_DOUBLE({argname})); + }}}} + else + {{{{ + {paramname} = (float) PyFloat_AsDouble({argname}); + if ({paramname} == -1.0 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + }}}} + """, + argname=argname) + else: + return self.format_code(""" + {paramname} = (float) PyFloat_AsDouble({argname}); + if ({paramname} == -1.0 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """, + argname=argname) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) + + +class double_converter(CConverter): + type = 'double' + default_type = float + format_unit = 'd' + c_ignored_default = "0.0" + + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: + if self.format_unit == 'd': + if not limited_capi: + return self.format_code(""" + if (PyFloat_CheckExact({argname})) {{{{ + {paramname} = PyFloat_AS_DOUBLE({argname}); + }}}} + else + {{{{ + {paramname} = PyFloat_AsDouble({argname}); + if ({paramname} == -1.0 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + }}}} + """, + argname=argname) + else: + return self.format_code(""" + {paramname} = PyFloat_AsDouble({argname}); + if ({paramname} == -1.0 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """, + argname=argname) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) + + +class Py_complex_converter(CConverter): + type = 'Py_complex' + default_type = complex + format_unit = 'D' + c_ignored_default = "{0.0, 0.0}" + + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: + if self.format_unit == 'D': + return self.format_code(""" + {paramname} = PyComplex_AsCComplex({argname}); + if (PyErr_Occurred()) {{{{ + goto exit; + }}}} + """, + argname=argname) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) + + +class object_converter(CConverter): + type = 'PyObject *' + format_unit = 'O' + + def converter_init( + self, *, + converter: str | None = None, + type: str | None = None, + subclass_of: str | None = None + ) -> None: + if converter: + if subclass_of: + fail("object: Cannot pass in both 'converter' and 'subclass_of'") + self.format_unit = 'O&' + self.converter = converter + elif subclass_of: + self.format_unit = 'O!' + self.subclass_of = subclass_of + + if type is not None: + self.type = type + + +# +# We define three conventions for buffer types in the 'accept' argument: +# +# buffer : any object supporting the buffer interface +# rwbuffer: any object supporting the buffer interface, but must be writeable +# robuffer: any object supporting the buffer interface, but must not be writeable +# + +class buffer: + pass +class rwbuffer: + pass +class robuffer: + pass + + +StrConverterKeyType = tuple[frozenset[type[object]], bool, bool] + +def str_converter_key( + types: TypeSet, encoding: bool | str | None, zeroes: bool +) -> StrConverterKeyType: + return (frozenset(types), bool(encoding), bool(zeroes)) + +str_converter_argument_map: dict[StrConverterKeyType, str] = {} + + +class str_converter(CConverter): + type = 'const char *' + default_type = (str, Null, NoneType) + format_unit = 's' + + def converter_init( + self, + *, + accept: TypeSet = {str}, + encoding: str | None = None, + zeroes: bool = False + ) -> None: + + key = str_converter_key(accept, encoding, zeroes) + format_unit = str_converter_argument_map.get(key) + if not format_unit: + fail("str_converter: illegal combination of arguments", key) + + self.format_unit = format_unit + self.length = bool(zeroes) + if encoding: + if self.default not in (Null, None, unspecified): + fail("str_converter: Argument Clinic doesn't support default values for encoded strings") + self.encoding = encoding + self.type = 'char *' + # sorry, clinic can't support preallocated buffers + # for es# and et# + self.c_default = "NULL" + if NoneType in accept and self.c_default == "Py_None": + self.c_default = "NULL" + + def post_parsing(self) -> str: + if self.encoding: + name = self.name + return f"PyMem_FREE({name});\n" + else: + return "" + + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: + if self.format_unit == 's': + return self.format_code(""" + if (!PyUnicode_Check({argname})) {{{{ + {bad_argument} + goto exit; + }}}} + Py_ssize_t {length_name}; + {paramname} = PyUnicode_AsUTF8AndSize({argname}, &{length_name}); + if ({paramname} == NULL) {{{{ + goto exit; + }}}} + if (strlen({paramname}) != (size_t){length_name}) {{{{ + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + }}}} + """, + argname=argname, + bad_argument=self.bad_argument(displayname, 'str', limited_capi=limited_capi), + length_name=self.length_name) + if self.format_unit == 'z': + return self.format_code(""" + if ({argname} == Py_None) {{{{ + {paramname} = NULL; + }}}} + else if (PyUnicode_Check({argname})) {{{{ + Py_ssize_t {length_name}; + {paramname} = PyUnicode_AsUTF8AndSize({argname}, &{length_name}); + if ({paramname} == NULL) {{{{ + goto exit; + }}}} + if (strlen({paramname}) != (size_t){length_name}) {{{{ + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + }}}} + }}}} + else {{{{ + {bad_argument} + goto exit; + }}}} + """, + argname=argname, + bad_argument=self.bad_argument(displayname, 'str or None', limited_capi=limited_capi), + length_name=self.length_name) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) + +# +# This is the fourth or fifth rewrite of registering all the +# string converter format units. Previous approaches hid +# bugs--generally mismatches between the semantics of the format +# unit and the arguments necessary to represent those semantics +# properly. Hopefully with this approach we'll get it 100% right. +# +# The r() function (short for "register") both registers the +# mapping from arguments to format unit *and* registers the +# legacy C converter for that format unit. +# +def r(format_unit: str, + *, + accept: TypeSet, + encoding: bool = False, + zeroes: bool = False +) -> None: + if not encoding and format_unit != 's': + # add the legacy c converters here too. + # + # note: add_legacy_c_converter can't work for + # es, es#, et, or et# + # because of their extra encoding argument + # + # also don't add the converter for 's' because + # the metaclass for CConverter adds it for us. + kwargs: dict[str, Any] = {} + if accept != {str}: + kwargs['accept'] = accept + if zeroes: + kwargs['zeroes'] = True + added_f = functools.partial(str_converter, **kwargs) + legacy_converters[format_unit] = added_f + + d = str_converter_argument_map + key = str_converter_key(accept, encoding, zeroes) + if key in d: + sys.exit("Duplicate keys specified for str_converter_argument_map!") + d[key] = format_unit + +r('es', encoding=True, accept={str}) +r('es#', encoding=True, zeroes=True, accept={str}) +r('et', encoding=True, accept={bytes, bytearray, str}) +r('et#', encoding=True, zeroes=True, accept={bytes, bytearray, str}) +r('s', accept={str}) +r('s#', zeroes=True, accept={robuffer, str}) +r('y', accept={robuffer}) +r('y#', zeroes=True, accept={robuffer}) +r('z', accept={str, NoneType}) +r('z#', zeroes=True, accept={robuffer, str, NoneType}) +del r + + +class PyBytesObject_converter(CConverter): + type = 'PyBytesObject *' + format_unit = 'S' + # accept = {bytes} + + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: + if self.format_unit == 'S': + return self.format_code(""" + if (!PyBytes_Check({argname})) {{{{ + {bad_argument} + goto exit; + }}}} + {paramname} = ({type}){argname}; + """, + argname=argname, + bad_argument=self.bad_argument(displayname, 'bytes', limited_capi=limited_capi), + type=self.type) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) + + +class PyByteArrayObject_converter(CConverter): + type = 'PyByteArrayObject *' + format_unit = 'Y' + # accept = {bytearray} + + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: + if self.format_unit == 'Y': + return self.format_code(""" + if (!PyByteArray_Check({argname})) {{{{ + {bad_argument} + goto exit; + }}}} + {paramname} = ({type}){argname}; + """, + argname=argname, + bad_argument=self.bad_argument(displayname, 'bytearray', limited_capi=limited_capi), + type=self.type) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) + + +class unicode_converter(CConverter): + type = 'PyObject *' + default_type = (str, Null, NoneType) + format_unit = 'U' + + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: + if self.format_unit == 'U': + return self.format_code(""" + if (!PyUnicode_Check({argname})) {{{{ + {bad_argument} + goto exit; + }}}} + {paramname} = {argname}; + """, + argname=argname, + bad_argument=self.bad_argument(displayname, 'str', limited_capi=limited_capi), + ) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) + + +@add_legacy_c_converter('u') +@add_legacy_c_converter('u#', zeroes=True) +@add_legacy_c_converter('Z', accept={str, NoneType}) +@add_legacy_c_converter('Z#', accept={str, NoneType}, zeroes=True) +class Py_UNICODE_converter(CConverter): + type = 'const wchar_t *' + default_type = (str, Null, NoneType) + + def converter_init( + self, *, + accept: TypeSet = {str}, + zeroes: bool = False + ) -> None: + format_unit = 'Z' if accept=={str, NoneType} else 'u' + if zeroes: + format_unit += '#' + self.length = True + self.format_unit = format_unit + else: + self.accept = accept + if accept == {str}: + self.converter = '_PyUnicode_WideCharString_Converter' + elif accept == {str, NoneType}: + self.converter = '_PyUnicode_WideCharString_Opt_Converter' + else: + fail(f"Py_UNICODE_converter: illegal 'accept' argument {accept!r}") + self.c_default = "NULL" + + def cleanup(self) -> str: + if self.length: + return "" + else: + return f"""PyMem_Free((void *){self.parser_name});\n""" + + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: + if not self.length: + if self.accept == {str}: + return self.format_code(""" + if (!PyUnicode_Check({argname})) {{{{ + {bad_argument} + goto exit; + }}}} + {paramname} = PyUnicode_AsWideCharString({argname}, NULL); + if ({paramname} == NULL) {{{{ + goto exit; + }}}} + """, + argname=argname, + bad_argument=self.bad_argument(displayname, 'str', limited_capi=limited_capi), + ) + elif self.accept == {str, NoneType}: + return self.format_code(""" + if ({argname} == Py_None) {{{{ + {paramname} = NULL; + }}}} + else if (PyUnicode_Check({argname})) {{{{ + {paramname} = PyUnicode_AsWideCharString({argname}, NULL); + if ({paramname} == NULL) {{{{ + goto exit; + }}}} + }}}} + else {{{{ + {bad_argument} + goto exit; + }}}} + """, + argname=argname, + bad_argument=self.bad_argument(displayname, 'str or None', limited_capi=limited_capi), + ) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) + + +@add_legacy_c_converter('s*', accept={str, buffer}) +@add_legacy_c_converter('z*', accept={str, buffer, NoneType}) +@add_legacy_c_converter('w*', accept={rwbuffer}) +class Py_buffer_converter(CConverter): + type = 'Py_buffer' + format_unit = 'y*' + impl_by_reference = True + c_ignored_default = "{NULL, NULL}" + + def converter_init(self, *, accept: TypeSet = {buffer}) -> None: + if self.default not in (unspecified, None): + fail("The only legal default value for Py_buffer is None.") + + self.c_default = self.c_ignored_default + + if accept == {str, buffer, NoneType}: + format_unit = 'z*' + elif accept == {str, buffer}: + format_unit = 's*' + elif accept == {buffer}: + format_unit = 'y*' + elif accept == {rwbuffer}: + format_unit = 'w*' + else: + fail("Py_buffer_converter: illegal combination of arguments") + + self.format_unit = format_unit + + def cleanup(self) -> str: + name = self.name + return "".join(["if (", name, ".obj) {\n PyBuffer_Release(&", name, ");\n}\n"]) + + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: + # PyBUF_SIMPLE guarantees that the format units of the buffers are C-contiguous. + if self.format_unit == 'y*': + return self.format_code(""" + if (PyObject_GetBuffer({argname}, &{paramname}, PyBUF_SIMPLE) != 0) {{{{ + goto exit; + }}}} + """, + argname=argname, + bad_argument=self.bad_argument(displayname, 'contiguous buffer', limited_capi=limited_capi), + ) + elif self.format_unit == 's*': + return self.format_code(""" + if (PyUnicode_Check({argname})) {{{{ + Py_ssize_t len; + const char *ptr = PyUnicode_AsUTF8AndSize({argname}, &len); + if (ptr == NULL) {{{{ + goto exit; + }}}} + if (PyBuffer_FillInfo(&{paramname}, {argname}, (void *)ptr, len, 1, PyBUF_SIMPLE) < 0) {{{{ + goto exit; + }}}} + }}}} + else {{{{ /* any bytes-like object */ + if (PyObject_GetBuffer({argname}, &{paramname}, PyBUF_SIMPLE) != 0) {{{{ + goto exit; + }}}} + }}}} + """, + argname=argname, + bad_argument=self.bad_argument(displayname, 'contiguous buffer', limited_capi=limited_capi), + ) + elif self.format_unit == 'w*': + return self.format_code(""" + if (PyObject_GetBuffer({argname}, &{paramname}, PyBUF_WRITABLE) < 0) {{{{ + {bad_argument} + goto exit; + }}}} + """, + argname=argname, + bad_argument=self.bad_argument(displayname, 'read-write bytes-like object', limited_capi=limited_capi), + bad_argument2=self.bad_argument(displayname, 'contiguous buffer', limited_capi=limited_capi), + ) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) + + +def correct_name_for_self( + f: Function +) -> tuple[str, str]: + if f.kind in {CALLABLE, METHOD_INIT, GETTER, SETTER}: + if f.cls: + return "PyObject *", "self" + return "PyObject *", "module" + if f.kind is STATIC_METHOD: + return "void *", "null" + if f.kind in (CLASS_METHOD, METHOD_NEW): + return "PyTypeObject *", "type" + raise AssertionError(f"Unhandled type of function f: {f.kind!r}") + + +class self_converter(CConverter): + """ + A special-case converter: + this is the default converter used for "self". + """ + type: str | None = None + format_unit = '' + + def converter_init(self, *, type: str | None = None) -> None: + self.specified_type = type + + def pre_render(self) -> None: + f = self.function + default_type, default_name = correct_name_for_self(f) + self.signature_name = default_name + self.type = self.specified_type or self.type or default_type + + kind = self.function.kind + + if kind is STATIC_METHOD or kind.new_or_init: + self.show_in_signature = False + + # tp_new (METHOD_NEW) functions are of type newfunc: + # typedef PyObject *(*newfunc)(PyTypeObject *, PyObject *, PyObject *); + # + # tp_init (METHOD_INIT) functions are of type initproc: + # typedef int (*initproc)(PyObject *, PyObject *, PyObject *); + # + # All other functions generated by Argument Clinic are stored in + # PyMethodDef structures, in the ml_meth slot, which is of type PyCFunction: + # typedef PyObject *(*PyCFunction)(PyObject *, PyObject *); + # However! We habitually cast these functions to PyCFunction, + # since functions that accept keyword arguments don't fit this signature + # but are stored there anyway. So strict type equality isn't important + # for these functions. + # + # So: + # + # * The name of the first parameter to the impl and the parsing function will always + # be self.name. + # + # * The type of the first parameter to the impl will always be of self.type. + # + # * If the function is neither tp_new (METHOD_NEW) nor tp_init (METHOD_INIT): + # * The type of the first parameter to the parsing function is also self.type. + # This means that if you step into the parsing function, your "self" parameter + # is of the correct type, which may make debugging more pleasant. + # + # * Else if the function is tp_new (METHOD_NEW): + # * The type of the first parameter to the parsing function is "PyTypeObject *", + # so the type signature of the function call is an exact match. + # * If self.type != "PyTypeObject *", we cast the first parameter to self.type + # in the impl call. + # + # * Else if the function is tp_init (METHOD_INIT): + # * The type of the first parameter to the parsing function is "PyObject *", + # so the type signature of the function call is an exact match. + # * If self.type != "PyObject *", we cast the first parameter to self.type + # in the impl call. + + @property + def parser_type(self) -> str: + assert self.type is not None + if self.function.kind in {METHOD_INIT, METHOD_NEW, STATIC_METHOD, CLASS_METHOD}: + tp, _ = correct_name_for_self(self.function) + return tp + return self.type + + def render(self, parameter: Parameter, data: CRenderData) -> None: + """ + parameter is a clinic.Parameter instance. + data is a CRenderData instance. + """ + if self.function.kind is STATIC_METHOD: + return + + self._render_self(parameter, data) + + if self.type != self.parser_type: + # insert cast to impl_argument[0], aka self. + # we know we're in the first slot in all the CRenderData lists, + # because we render parameters in order, and self is always first. + assert len(data.impl_arguments) == 1 + assert data.impl_arguments[0] == self.name + assert self.type is not None + data.impl_arguments[0] = '(' + self.type + ")" + data.impl_arguments[0] + + def set_template_dict(self, template_dict: TemplateDict) -> None: + template_dict['self_name'] = self.name + template_dict['self_type'] = self.parser_type + kind = self.function.kind + cls = self.function.cls + + if kind.new_or_init and cls and cls.typedef: + if kind is METHOD_NEW: + type_check = ( + '({0} == base_tp || {0}->tp_init == base_tp->tp_init)' + ).format(self.name) + else: + type_check = ('(Py_IS_TYPE({0}, base_tp) ||\n ' + ' Py_TYPE({0})->tp_new == base_tp->tp_new)' + ).format(self.name) + + line = f'{type_check} &&\n ' + template_dict['self_type_check'] = line + + type_object = cls.type_object + type_ptr = f'PyTypeObject *base_tp = {type_object};' + template_dict['base_type_ptr'] = type_ptr diff --git a/Tools/clinic/libclinic/function.py b/Tools/clinic/libclinic/function.py index 4fafedb617115c..b0dd08446e802d 100644 --- a/Tools/clinic/libclinic/function.py +++ b/Tools/clinic/libclinic/function.py @@ -6,8 +6,9 @@ import inspect from typing import Final, Any, TYPE_CHECKING if TYPE_CHECKING: - from clinic import Clinic, CReturnConverter, self_converter + from clinic import Clinic, CReturnConverter from libclinic.converter import CConverter + from libclinic.converters import self_converter from libclinic import VersionTuple, unspecified diff --git a/Tools/clinic/libclinic/utils.py b/Tools/clinic/libclinic/utils.py index 95a69f70c5499d..17e8f35be73bf4 100644 --- a/Tools/clinic/libclinic/utils.py +++ b/Tools/clinic/libclinic/utils.py @@ -82,3 +82,12 @@ def __repr__(self) -> str: unspecified: Final = Sentinels.unspecified unknown: Final = Sentinels.unknown + + +# This one needs to be a distinct class, unlike the other two +class Null: + def __repr__(self) -> str: + return '' + + +NULL = Null() From 1d5479b236e9a66dd32a24eff6fb83e3242b999d Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Tue, 2 Apr 2024 11:34:49 +0100 Subject: [PATCH 08/11] gh-117411: move PyFutureFeatures to pycore_symtable.h and make it private (#117412) --- Include/cpython/compile.h | 20 ------------- Include/internal/pycore_compile.h | 8 +++-- Include/internal/pycore_flowgraph.h | 2 +- Include/internal/pycore_symtable.h | 29 +++++++++++++++++-- ...-04-02-10-04-57.gh-issue-117411.YdyVmG.rst | 1 + Python/assemble.c | 3 +- Python/compile.c | 8 ++--- Python/flowgraph.c | 6 ++-- Python/future.c | 9 +++--- Python/symtable.c | 4 +-- Python/traceback.c | 1 - 11 files changed, 49 insertions(+), 42 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-04-02-10-04-57.gh-issue-117411.YdyVmG.rst diff --git a/Include/cpython/compile.h b/Include/cpython/compile.h index 0d587505ef7f85..cfdb7080d45f2b 100644 --- a/Include/cpython/compile.h +++ b/Include/cpython/compile.h @@ -32,28 +32,8 @@ typedef struct { #define _PyCompilerFlags_INIT \ (PyCompilerFlags){.cf_flags = 0, .cf_feature_version = PY_MINOR_VERSION} -/* source location information */ -typedef struct { - int lineno; - int end_lineno; - int col_offset; - int end_col_offset; -} _PyCompilerSrcLocation; - -#define SRC_LOCATION_FROM_AST(n) \ - (_PyCompilerSrcLocation){ \ - .lineno = (n)->lineno, \ - .end_lineno = (n)->end_lineno, \ - .col_offset = (n)->col_offset, \ - .end_col_offset = (n)->end_col_offset } - /* Future feature support */ -typedef struct { - int ff_features; /* flags set by future statements */ - _PyCompilerSrcLocation ff_location; /* location of last future statement */ -} PyFutureFeatures; - #define FUTURE_NESTED_SCOPES "nested_scopes" #define FUTURE_GENERATORS "generators" #define FUTURE_DIVISION "division" diff --git a/Include/internal/pycore_compile.h b/Include/internal/pycore_compile.h index f54f4f7f37acee..eb6e5ca58f7390 100644 --- a/Include/internal/pycore_compile.h +++ b/Include/internal/pycore_compile.h @@ -8,6 +8,8 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +#include "pycore_symtable.h" // _Py_SourceLocation + struct _arena; // Type defined in pycore_pyarena.h struct _mod; // Type defined in pycore_ast.h @@ -27,7 +29,7 @@ extern int _PyCompile_AstOptimize( int optimize, struct _arena *arena); -static const _PyCompilerSrcLocation NO_LOCATION = {-1, -1, -1, -1}; +struct _Py_SourceLocation; extern int _PyAST_Optimize( struct _mod *, @@ -44,7 +46,7 @@ typedef struct { typedef struct { int i_opcode; int i_oparg; - _PyCompilerSrcLocation i_loc; + _Py_SourceLocation i_loc; _PyCompile_ExceptHandlerInfo i_except_handler_info; /* Used by the assembler */ @@ -65,7 +67,7 @@ typedef struct { int _PyCompile_InstructionSequence_UseLabel(_PyCompile_InstructionSequence *seq, int lbl); int _PyCompile_InstructionSequence_Addop(_PyCompile_InstructionSequence *seq, int opcode, int oparg, - _PyCompilerSrcLocation loc); + _Py_SourceLocation loc); int _PyCompile_InstructionSequence_ApplyLabelMap(_PyCompile_InstructionSequence *seq); typedef struct { diff --git a/Include/internal/pycore_flowgraph.h b/Include/internal/pycore_flowgraph.h index 58fed46886ea45..121302aacb3a8b 100644 --- a/Include/internal/pycore_flowgraph.h +++ b/Include/internal/pycore_flowgraph.h @@ -18,7 +18,7 @@ typedef struct { struct _PyCfgBuilder; int _PyCfgBuilder_UseLabel(struct _PyCfgBuilder *g, _PyCfgJumpTargetLabel lbl); -int _PyCfgBuilder_Addop(struct _PyCfgBuilder *g, int opcode, int oparg, _PyCompilerSrcLocation loc); +int _PyCfgBuilder_Addop(struct _PyCfgBuilder *g, int opcode, int oparg, _Py_SourceLocation loc); struct _PyCfgBuilder* _PyCfgBuilder_New(void); void _PyCfgBuilder_Free(struct _PyCfgBuilder *g); diff --git a/Include/internal/pycore_symtable.h b/Include/internal/pycore_symtable.h index b44393b5644673..16e89f80d9d0c8 100644 --- a/Include/internal/pycore_symtable.h +++ b/Include/internal/pycore_symtable.h @@ -29,6 +29,29 @@ typedef enum _comprehension_type { SetComprehension = 3, GeneratorExpression = 4 } _Py_comprehension_ty; +/* source location information */ +typedef struct { + int lineno; + int end_lineno; + int col_offset; + int end_col_offset; +} _Py_SourceLocation; + +#define SRC_LOCATION_FROM_AST(n) \ + (_Py_SourceLocation){ \ + .lineno = (n)->lineno, \ + .end_lineno = (n)->end_lineno, \ + .col_offset = (n)->col_offset, \ + .end_col_offset = (n)->end_col_offset } + +static const _Py_SourceLocation NO_LOCATION = {-1, -1, -1, -1}; + +/* __future__ information */ +typedef struct { + int ff_features; /* flags set by future statements */ + _Py_SourceLocation ff_location; /* location of last future statement */ +} _PyFutureFeatures; + struct _symtable_entry; struct symtable { @@ -44,7 +67,7 @@ struct symtable { consistency with the corresponding compiler structure */ PyObject *st_private; /* name of current class or NULL */ - PyFutureFeatures *st_future; /* module's future features that affect + _PyFutureFeatures *st_future; /* module's future features that affect the symbol table */ int recursion_depth; /* current recursion depth */ int recursion_limit; /* recursion limit */ @@ -100,7 +123,7 @@ extern int _PyST_IsFunctionLike(PySTEntryObject *); extern struct symtable* _PySymtable_Build( struct _mod *mod, PyObject *filename, - PyFutureFeatures *future); + _PyFutureFeatures *future); extern PySTEntryObject* _PySymtable_Lookup(struct symtable *, void *); extern void _PySymtable_Free(struct symtable *); @@ -150,7 +173,7 @@ extern struct symtable* _Py_SymtableStringObjectFlags( int _PyFuture_FromAST( struct _mod * mod, PyObject *filename, - PyFutureFeatures* futures); + _PyFutureFeatures* futures); #ifdef __cplusplus } diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-04-02-10-04-57.gh-issue-117411.YdyVmG.rst b/Misc/NEWS.d/next/Core and Builtins/2024-04-02-10-04-57.gh-issue-117411.YdyVmG.rst new file mode 100644 index 00000000000000..73c60ee33a5413 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2024-04-02-10-04-57.gh-issue-117411.YdyVmG.rst @@ -0,0 +1 @@ +Move ``PyFutureFeatures`` to an internal header and make it private. diff --git a/Python/assemble.c b/Python/assemble.c index 09db2fab48d95c..be3d9c1a74657c 100644 --- a/Python/assemble.c +++ b/Python/assemble.c @@ -5,6 +5,7 @@ #include "pycore_compile.h" #include "pycore_opcode_utils.h" // IS_BACKWARDS_JUMP_OPCODE #include "pycore_opcode_metadata.h" // is_pseudo_target, _PyOpcode_Caches +#include "pycore_symtable.h" // _Py_SourceLocation #define DEFAULT_CODE_SIZE 128 @@ -21,7 +22,7 @@ return ERROR; \ } -typedef _PyCompilerSrcLocation location; +typedef _Py_SourceLocation location; typedef _PyCompile_Instruction instruction; typedef _PyCompile_InstructionSequence instr_sequence; diff --git a/Python/compile.c b/Python/compile.c index 43b3cbd4e1894c..d9312f93d0680f 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -70,11 +70,11 @@ ((C)->c_flags.cf_flags & PyCF_ALLOW_TOP_LEVEL_AWAIT) \ && ((C)->u->u_ste->ste_type == ModuleBlock)) -typedef _PyCompilerSrcLocation location; +typedef _Py_SourceLocation location; typedef struct _PyCfgBuilder cfg_builder; #define LOCATION(LNO, END_LNO, COL, END_COL) \ - ((const _PyCompilerSrcLocation){(LNO), (END_LNO), (COL), (END_COL)}) + ((const _Py_SourceLocation){(LNO), (END_LNO), (COL), (END_COL)}) /* Return true if loc1 starts after loc2 ends. */ static inline bool @@ -408,7 +408,7 @@ handled by the symbol analysis pass. struct compiler { PyObject *c_filename; struct symtable *c_st; - PyFutureFeatures c_future; /* module's __future__ */ + _PyFutureFeatures c_future; /* module's __future__ */ PyCompilerFlags c_flags; int c_optimize; /* optimization level */ @@ -585,7 +585,7 @@ int _PyCompile_AstOptimize(mod_ty mod, PyObject *filename, PyCompilerFlags *cf, int optimize, PyArena *arena) { - PyFutureFeatures future; + _PyFutureFeatures future; if (!_PyFuture_FromAST(mod, filename, &future)) { return -1; } diff --git a/Python/flowgraph.c b/Python/flowgraph.c index 5437c3875ff7b0..9d98f6910cdf54 100644 --- a/Python/flowgraph.c +++ b/Python/flowgraph.c @@ -22,13 +22,13 @@ #define DEFAULT_BLOCK_SIZE 16 -typedef _PyCompilerSrcLocation location; +typedef _Py_SourceLocation location; typedef _PyCfgJumpTargetLabel jump_target_label; typedef struct _PyCfgInstruction { int i_opcode; int i_oparg; - _PyCompilerSrcLocation i_loc; + _Py_SourceLocation i_loc; struct _PyCfgBasicblock *i_target; /* target block (if jump instruction) */ struct _PyCfgBasicblock *i_except; /* target block when exception is raised */ } cfg_instr; @@ -92,7 +92,7 @@ static const jump_target_label NO_LABEL = {-1}; #define IS_LABEL(L) (!SAME_LABEL((L), (NO_LABEL))) #define LOCATION(LNO, END_LNO, COL, END_COL) \ - ((const _PyCompilerSrcLocation){(LNO), (END_LNO), (COL), (END_COL)}) + ((const _Py_SourceLocation){(LNO), (END_LNO), (COL), (END_COL)}) static inline int is_block_push(cfg_instr *i) diff --git a/Python/future.c b/Python/future.c index 0dbc7ede20f324..399345bd8fcbd9 100644 --- a/Python/future.c +++ b/Python/future.c @@ -1,11 +1,12 @@ #include "Python.h" #include "pycore_ast.h" // _PyAST_GetDocString() +#include "pycore_symtable.h" // _PyFutureFeatures #include "pycore_unicodeobject.h" // _PyUnicode_EqualToASCIIString() #define UNDEFINED_FUTURE_FEATURE "future feature %.100s is not defined" static int -future_check_features(PyFutureFeatures *ff, stmt_ty s, PyObject *filename) +future_check_features(_PyFutureFeatures *ff, stmt_ty s, PyObject *filename) { int i; @@ -53,7 +54,7 @@ future_check_features(PyFutureFeatures *ff, stmt_ty s, PyObject *filename) } static int -future_parse(PyFutureFeatures *ff, mod_ty mod, PyObject *filename) +future_parse(_PyFutureFeatures *ff, mod_ty mod, PyObject *filename) { if (!(mod->kind == Module_kind || mod->kind == Interactive_kind)) { return 1; @@ -98,10 +99,10 @@ future_parse(PyFutureFeatures *ff, mod_ty mod, PyObject *filename) int -_PyFuture_FromAST(mod_ty mod, PyObject *filename, PyFutureFeatures *ff) +_PyFuture_FromAST(mod_ty mod, PyObject *filename, _PyFutureFeatures *ff) { ff->ff_features = 0; - ff->ff_location = (_PyCompilerSrcLocation){-1, -1, -1, -1}; + ff->ff_location = (_Py_SourceLocation){-1, -1, -1, -1}; if (!future_parse(ff, mod, filename)) { return 0; diff --git a/Python/symtable.c b/Python/symtable.c index b69452bf77c517..36ccc0e73723d5 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -387,7 +387,7 @@ symtable_new(void) } struct symtable * -_PySymtable_Build(mod_ty mod, PyObject *filename, PyFutureFeatures *future) +_PySymtable_Build(mod_ty mod, PyObject *filename, _PyFutureFeatures *future) { struct symtable *st = symtable_new(); asdl_stmt_seq *seq; @@ -2757,7 +2757,7 @@ _Py_SymtableStringObjectFlags(const char *str, PyObject *filename, _PyArena_Free(arena); return NULL; } - PyFutureFeatures future; + _PyFutureFeatures future; if (!_PyFuture_FromAST(mod, filename, &future)) { _PyArena_Free(arena); return NULL; diff --git a/Python/traceback.c b/Python/traceback.c index 7a188e56c939c0..2564a7db5dcfec 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -5,7 +5,6 @@ #include "pycore_ast.h" // asdl_seq_GET() #include "pycore_call.h" // _PyObject_CallMethodFormat() -#include "pycore_compile.h" // _PyAST_Optimize() #include "pycore_fileutils.h" // _Py_BEGIN_SUPPRESS_IPH #include "pycore_frame.h" // _PyFrame_GetCode() #include "pycore_interp.h" // PyInterpreterState.gc From c97d3af2391e62ef456ef2365d48ab9b8cdbe27b Mon Sep 17 00:00:00 2001 From: Grigoriev Semyon <33061489+grigoriev-semyon@users.noreply.github.com> Date: Tue, 2 Apr 2024 13:42:58 +0300 Subject: [PATCH 09/11] gh-109120: Fix syntax error in handlinh of incorrect star expressions (#117444) --- Grammar/python.gram | 6 +- Lib/test/test_syntax.py | 26 +- ...-04-02-06-16-49.gh-issue-109120.X485oN.rst | 2 + Parser/parser.c | 2647 +++++++++-------- 4 files changed, 1442 insertions(+), 1239 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-04-02-06-16-49.gh-issue-109120.X485oN.rst diff --git a/Grammar/python.gram b/Grammar/python.gram index 696649392ae45d..9564abf5ec314b 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -1013,6 +1013,7 @@ kwargs[asdl_seq*]: starred_expression[expr_ty]: | invalid_starred_expression | '*' a=expression { _PyAST_Starred(a, Load, EXTRA) } + | '*' { RAISE_SYNTAX_ERROR("Invalid star expression") } kwarg_or_starred[KeywordOrStarred*]: | invalid_kwarg @@ -1133,8 +1134,8 @@ func_type_comment[Token*]: # From here on, there are rules for invalid syntax with specialised error messages invalid_arguments: - | ((','.(starred_expression | ( assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' b='*' { - RAISE_SYNTAX_ERROR_KNOWN_LOCATION(b, "iterable argument unpacking follows keyword argument unpacking") } + | ((','.(starred_expression | ( assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) a=',' ','.(starred_expression !'=')+ { + RAISE_SYNTAX_ERROR_STARTING_FROM(a, "iterable argument unpacking follows keyword argument unpacking") } | a=expression b=for_if_clauses ',' [args | expression for_if_clauses] { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, _PyPegen_get_last_comprehension_item(PyPegen_last_item(b, comprehension_ty)), "Generator expression must be parenthesized") } | a=NAME b='=' expression for_if_clauses { @@ -1396,6 +1397,7 @@ invalid_kvpair: | expression a=':' &('}'|',') {RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "expression expected after dictionary key and ':'") } invalid_starred_expression: | a='*' expression '=' b=expression { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "cannot assign to iterable argument unpacking") } + invalid_replacement_field: | '{' a='=' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "f-string: valid expression required before '='") } | '{' a='!' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "f-string: valid expression required before '!'") } diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index d686dbf0c29149..dfa2a3b2f5413b 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -1911,22 +1911,22 @@ >>> A[*(1:2)] Traceback (most recent call last): ... - SyntaxError: invalid syntax + SyntaxError: Invalid star expression >>> A[*(1:2)] = 1 Traceback (most recent call last): ... - SyntaxError: invalid syntax + SyntaxError: Invalid star expression >>> del A[*(1:2)] Traceback (most recent call last): ... - SyntaxError: invalid syntax + SyntaxError: Invalid star expression A[*:] and A[:*] >>> A[*:] Traceback (most recent call last): ... - SyntaxError: invalid syntax + SyntaxError: Invalid star expression >>> A[:*] Traceback (most recent call last): ... @@ -1937,7 +1937,7 @@ >>> A[*] Traceback (most recent call last): ... - SyntaxError: invalid syntax + SyntaxError: Invalid star expression A[**] @@ -2081,11 +2081,23 @@ def f(x: *b) >>> f(**x, *) Traceback (most recent call last): - SyntaxError: iterable argument unpacking follows keyword argument unpacking + SyntaxError: Invalid star expression >>> f(x, *:) Traceback (most recent call last): - SyntaxError: invalid syntax + SyntaxError: Invalid star expression + + >>> f(x, *) + Traceback (most recent call last): + SyntaxError: Invalid star expression + + >>> f(x = 5, *) + Traceback (most recent call last): + SyntaxError: Invalid star expression + + >>> f(x = 5, *:) + Traceback (most recent call last): + SyntaxError: Invalid star expression """ import re diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-04-02-06-16-49.gh-issue-109120.X485oN.rst b/Misc/NEWS.d/next/Core and Builtins/2024-04-02-06-16-49.gh-issue-109120.X485oN.rst new file mode 100644 index 00000000000000..32e70b22f778e1 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2024-04-02-06-16-49.gh-issue-109120.X485oN.rst @@ -0,0 +1,2 @@ +Added handle of incorrect star expressions, e.g ``f(3, *)``. Patch by +Grigoryev Semyon diff --git a/Parser/parser.c b/Parser/parser.c index 6817bd10d3cd7f..35d672b0d397f9 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -482,8 +482,8 @@ static char *soft_keywords[] = { #define _gather_148_type 1395 #define _tmp_150_type 1396 #define _tmp_151_type 1397 -#define _tmp_152_type 1398 -#define _tmp_153_type 1399 +#define _loop0_153_type 1398 +#define _gather_152_type 1399 #define _tmp_154_type 1400 #define _tmp_155_type 1401 #define _tmp_156_type 1402 @@ -492,50 +492,50 @@ static char *soft_keywords[] = { #define _tmp_159_type 1405 #define _tmp_160_type 1406 #define _tmp_161_type 1407 -#define _loop0_162_type 1408 -#define _loop0_163_type 1409 +#define _tmp_162_type 1408 +#define _tmp_163_type 1409 #define _loop0_164_type 1410 -#define _tmp_165_type 1411 -#define _tmp_166_type 1412 +#define _loop0_165_type 1411 +#define _loop0_166_type 1412 #define _tmp_167_type 1413 #define _tmp_168_type 1414 #define _tmp_169_type 1415 -#define _loop0_170_type 1416 -#define _loop0_171_type 1417 +#define _tmp_170_type 1416 +#define _tmp_171_type 1417 #define _loop0_172_type 1418 -#define _loop1_173_type 1419 -#define _tmp_174_type 1420 -#define _loop0_175_type 1421 +#define _loop0_173_type 1419 +#define _loop0_174_type 1420 +#define _loop1_175_type 1421 #define _tmp_176_type 1422 #define _loop0_177_type 1423 -#define _loop1_178_type 1424 -#define _tmp_179_type 1425 -#define _tmp_180_type 1426 +#define _tmp_178_type 1424 +#define _loop0_179_type 1425 +#define _loop1_180_type 1426 #define _tmp_181_type 1427 -#define _loop0_182_type 1428 +#define _tmp_182_type 1428 #define _tmp_183_type 1429 -#define _tmp_184_type 1430 -#define _loop1_185_type 1431 +#define _loop0_184_type 1430 +#define _tmp_185_type 1431 #define _tmp_186_type 1432 -#define _loop0_187_type 1433 -#define _loop0_188_type 1434 +#define _loop1_187_type 1433 +#define _tmp_188_type 1434 #define _loop0_189_type 1435 -#define _loop0_191_type 1436 -#define _gather_190_type 1437 -#define _tmp_192_type 1438 -#define _loop0_193_type 1439 +#define _loop0_190_type 1436 +#define _loop0_191_type 1437 +#define _loop0_193_type 1438 +#define _gather_192_type 1439 #define _tmp_194_type 1440 #define _loop0_195_type 1441 -#define _loop1_196_type 1442 -#define _loop1_197_type 1443 -#define _tmp_198_type 1444 -#define _tmp_199_type 1445 -#define _loop0_200_type 1446 +#define _tmp_196_type 1442 +#define _loop0_197_type 1443 +#define _loop1_198_type 1444 +#define _loop1_199_type 1445 +#define _tmp_200_type 1446 #define _tmp_201_type 1447 -#define _tmp_202_type 1448 +#define _loop0_202_type 1448 #define _tmp_203_type 1449 -#define _loop0_205_type 1450 -#define _gather_204_type 1451 +#define _tmp_204_type 1450 +#define _tmp_205_type 1451 #define _loop0_207_type 1452 #define _gather_206_type 1453 #define _loop0_209_type 1454 @@ -544,14 +544,14 @@ static char *soft_keywords[] = { #define _gather_210_type 1457 #define _loop0_213_type 1458 #define _gather_212_type 1459 -#define _tmp_214_type 1460 -#define _loop0_215_type 1461 -#define _loop1_216_type 1462 -#define _tmp_217_type 1463 -#define _loop0_218_type 1464 -#define _loop1_219_type 1465 -#define _tmp_220_type 1466 -#define _tmp_221_type 1467 +#define _loop0_215_type 1460 +#define _gather_214_type 1461 +#define _tmp_216_type 1462 +#define _loop0_217_type 1463 +#define _loop1_218_type 1464 +#define _tmp_219_type 1465 +#define _loop0_220_type 1466 +#define _loop1_221_type 1467 #define _tmp_222_type 1468 #define _tmp_223_type 1469 #define _tmp_224_type 1470 @@ -560,10 +560,10 @@ static char *soft_keywords[] = { #define _tmp_227_type 1473 #define _tmp_228_type 1474 #define _tmp_229_type 1475 -#define _loop0_231_type 1476 -#define _gather_230_type 1477 -#define _tmp_232_type 1478 -#define _tmp_233_type 1479 +#define _tmp_230_type 1476 +#define _tmp_231_type 1477 +#define _loop0_233_type 1478 +#define _gather_232_type 1479 #define _tmp_234_type 1480 #define _tmp_235_type 1481 #define _tmp_236_type 1482 @@ -575,9 +575,9 @@ static char *soft_keywords[] = { #define _tmp_242_type 1488 #define _tmp_243_type 1489 #define _tmp_244_type 1490 -#define _loop0_245_type 1491 +#define _tmp_245_type 1491 #define _tmp_246_type 1492 -#define _tmp_247_type 1493 +#define _loop0_247_type 1493 #define _tmp_248_type 1494 #define _tmp_249_type 1495 #define _tmp_250_type 1496 @@ -593,9 +593,9 @@ static char *soft_keywords[] = { #define _tmp_260_type 1506 #define _tmp_261_type 1507 #define _tmp_262_type 1508 -#define _loop0_263_type 1509 +#define _tmp_263_type 1509 #define _tmp_264_type 1510 -#define _tmp_265_type 1511 +#define _loop0_265_type 1511 #define _tmp_266_type 1512 #define _tmp_267_type 1513 #define _tmp_268_type 1514 @@ -609,14 +609,17 @@ static char *soft_keywords[] = { #define _tmp_276_type 1522 #define _tmp_277_type 1523 #define _tmp_278_type 1524 -#define _loop0_280_type 1525 -#define _gather_279_type 1526 +#define _tmp_279_type 1525 +#define _tmp_280_type 1526 #define _tmp_281_type 1527 -#define _tmp_282_type 1528 -#define _tmp_283_type 1529 +#define _loop0_283_type 1528 +#define _gather_282_type 1529 #define _tmp_284_type 1530 #define _tmp_285_type 1531 #define _tmp_286_type 1532 +#define _tmp_287_type 1533 +#define _tmp_288_type 1534 +#define _tmp_289_type 1535 static mod_ty file_rule(Parser *p); static mod_ty interactive_rule(Parser *p); @@ -1016,8 +1019,8 @@ static asdl_seq *_loop0_149_rule(Parser *p); static asdl_seq *_gather_148_rule(Parser *p); static void *_tmp_150_rule(Parser *p); static void *_tmp_151_rule(Parser *p); -static void *_tmp_152_rule(Parser *p); -static void *_tmp_153_rule(Parser *p); +static asdl_seq *_loop0_153_rule(Parser *p); +static asdl_seq *_gather_152_rule(Parser *p); static void *_tmp_154_rule(Parser *p); static void *_tmp_155_rule(Parser *p); static void *_tmp_156_rule(Parser *p); @@ -1026,50 +1029,50 @@ static void *_tmp_158_rule(Parser *p); static void *_tmp_159_rule(Parser *p); static void *_tmp_160_rule(Parser *p); static void *_tmp_161_rule(Parser *p); -static asdl_seq *_loop0_162_rule(Parser *p); -static asdl_seq *_loop0_163_rule(Parser *p); +static void *_tmp_162_rule(Parser *p); +static void *_tmp_163_rule(Parser *p); static asdl_seq *_loop0_164_rule(Parser *p); -static void *_tmp_165_rule(Parser *p); -static void *_tmp_166_rule(Parser *p); +static asdl_seq *_loop0_165_rule(Parser *p); +static asdl_seq *_loop0_166_rule(Parser *p); static void *_tmp_167_rule(Parser *p); static void *_tmp_168_rule(Parser *p); static void *_tmp_169_rule(Parser *p); -static asdl_seq *_loop0_170_rule(Parser *p); -static asdl_seq *_loop0_171_rule(Parser *p); +static void *_tmp_170_rule(Parser *p); +static void *_tmp_171_rule(Parser *p); static asdl_seq *_loop0_172_rule(Parser *p); -static asdl_seq *_loop1_173_rule(Parser *p); -static void *_tmp_174_rule(Parser *p); -static asdl_seq *_loop0_175_rule(Parser *p); +static asdl_seq *_loop0_173_rule(Parser *p); +static asdl_seq *_loop0_174_rule(Parser *p); +static asdl_seq *_loop1_175_rule(Parser *p); static void *_tmp_176_rule(Parser *p); static asdl_seq *_loop0_177_rule(Parser *p); -static asdl_seq *_loop1_178_rule(Parser *p); -static void *_tmp_179_rule(Parser *p); -static void *_tmp_180_rule(Parser *p); +static void *_tmp_178_rule(Parser *p); +static asdl_seq *_loop0_179_rule(Parser *p); +static asdl_seq *_loop1_180_rule(Parser *p); static void *_tmp_181_rule(Parser *p); -static asdl_seq *_loop0_182_rule(Parser *p); +static void *_tmp_182_rule(Parser *p); static void *_tmp_183_rule(Parser *p); -static void *_tmp_184_rule(Parser *p); -static asdl_seq *_loop1_185_rule(Parser *p); +static asdl_seq *_loop0_184_rule(Parser *p); +static void *_tmp_185_rule(Parser *p); static void *_tmp_186_rule(Parser *p); -static asdl_seq *_loop0_187_rule(Parser *p); -static asdl_seq *_loop0_188_rule(Parser *p); +static asdl_seq *_loop1_187_rule(Parser *p); +static void *_tmp_188_rule(Parser *p); static asdl_seq *_loop0_189_rule(Parser *p); +static asdl_seq *_loop0_190_rule(Parser *p); static asdl_seq *_loop0_191_rule(Parser *p); -static asdl_seq *_gather_190_rule(Parser *p); -static void *_tmp_192_rule(Parser *p); static asdl_seq *_loop0_193_rule(Parser *p); +static asdl_seq *_gather_192_rule(Parser *p); static void *_tmp_194_rule(Parser *p); static asdl_seq *_loop0_195_rule(Parser *p); -static asdl_seq *_loop1_196_rule(Parser *p); -static asdl_seq *_loop1_197_rule(Parser *p); -static void *_tmp_198_rule(Parser *p); -static void *_tmp_199_rule(Parser *p); -static asdl_seq *_loop0_200_rule(Parser *p); +static void *_tmp_196_rule(Parser *p); +static asdl_seq *_loop0_197_rule(Parser *p); +static asdl_seq *_loop1_198_rule(Parser *p); +static asdl_seq *_loop1_199_rule(Parser *p); +static void *_tmp_200_rule(Parser *p); static void *_tmp_201_rule(Parser *p); -static void *_tmp_202_rule(Parser *p); +static asdl_seq *_loop0_202_rule(Parser *p); static void *_tmp_203_rule(Parser *p); -static asdl_seq *_loop0_205_rule(Parser *p); -static asdl_seq *_gather_204_rule(Parser *p); +static void *_tmp_204_rule(Parser *p); +static void *_tmp_205_rule(Parser *p); static asdl_seq *_loop0_207_rule(Parser *p); static asdl_seq *_gather_206_rule(Parser *p); static asdl_seq *_loop0_209_rule(Parser *p); @@ -1078,14 +1081,14 @@ static asdl_seq *_loop0_211_rule(Parser *p); static asdl_seq *_gather_210_rule(Parser *p); static asdl_seq *_loop0_213_rule(Parser *p); static asdl_seq *_gather_212_rule(Parser *p); -static void *_tmp_214_rule(Parser *p); static asdl_seq *_loop0_215_rule(Parser *p); -static asdl_seq *_loop1_216_rule(Parser *p); -static void *_tmp_217_rule(Parser *p); -static asdl_seq *_loop0_218_rule(Parser *p); -static asdl_seq *_loop1_219_rule(Parser *p); -static void *_tmp_220_rule(Parser *p); -static void *_tmp_221_rule(Parser *p); +static asdl_seq *_gather_214_rule(Parser *p); +static void *_tmp_216_rule(Parser *p); +static asdl_seq *_loop0_217_rule(Parser *p); +static asdl_seq *_loop1_218_rule(Parser *p); +static void *_tmp_219_rule(Parser *p); +static asdl_seq *_loop0_220_rule(Parser *p); +static asdl_seq *_loop1_221_rule(Parser *p); static void *_tmp_222_rule(Parser *p); static void *_tmp_223_rule(Parser *p); static void *_tmp_224_rule(Parser *p); @@ -1094,10 +1097,10 @@ static void *_tmp_226_rule(Parser *p); static void *_tmp_227_rule(Parser *p); static void *_tmp_228_rule(Parser *p); static void *_tmp_229_rule(Parser *p); -static asdl_seq *_loop0_231_rule(Parser *p); -static asdl_seq *_gather_230_rule(Parser *p); -static void *_tmp_232_rule(Parser *p); -static void *_tmp_233_rule(Parser *p); +static void *_tmp_230_rule(Parser *p); +static void *_tmp_231_rule(Parser *p); +static asdl_seq *_loop0_233_rule(Parser *p); +static asdl_seq *_gather_232_rule(Parser *p); static void *_tmp_234_rule(Parser *p); static void *_tmp_235_rule(Parser *p); static void *_tmp_236_rule(Parser *p); @@ -1109,9 +1112,9 @@ static void *_tmp_241_rule(Parser *p); static void *_tmp_242_rule(Parser *p); static void *_tmp_243_rule(Parser *p); static void *_tmp_244_rule(Parser *p); -static asdl_seq *_loop0_245_rule(Parser *p); +static void *_tmp_245_rule(Parser *p); static void *_tmp_246_rule(Parser *p); -static void *_tmp_247_rule(Parser *p); +static asdl_seq *_loop0_247_rule(Parser *p); static void *_tmp_248_rule(Parser *p); static void *_tmp_249_rule(Parser *p); static void *_tmp_250_rule(Parser *p); @@ -1127,9 +1130,9 @@ static void *_tmp_259_rule(Parser *p); static void *_tmp_260_rule(Parser *p); static void *_tmp_261_rule(Parser *p); static void *_tmp_262_rule(Parser *p); -static asdl_seq *_loop0_263_rule(Parser *p); +static void *_tmp_263_rule(Parser *p); static void *_tmp_264_rule(Parser *p); -static void *_tmp_265_rule(Parser *p); +static asdl_seq *_loop0_265_rule(Parser *p); static void *_tmp_266_rule(Parser *p); static void *_tmp_267_rule(Parser *p); static void *_tmp_268_rule(Parser *p); @@ -1143,14 +1146,17 @@ static void *_tmp_275_rule(Parser *p); static void *_tmp_276_rule(Parser *p); static void *_tmp_277_rule(Parser *p); static void *_tmp_278_rule(Parser *p); -static asdl_seq *_loop0_280_rule(Parser *p); -static asdl_seq *_gather_279_rule(Parser *p); +static void *_tmp_279_rule(Parser *p); +static void *_tmp_280_rule(Parser *p); static void *_tmp_281_rule(Parser *p); -static void *_tmp_282_rule(Parser *p); -static void *_tmp_283_rule(Parser *p); +static asdl_seq *_loop0_283_rule(Parser *p); +static asdl_seq *_gather_282_rule(Parser *p); static void *_tmp_284_rule(Parser *p); static void *_tmp_285_rule(Parser *p); static void *_tmp_286_rule(Parser *p); +static void *_tmp_287_rule(Parser *p); +static void *_tmp_288_rule(Parser *p); +static void *_tmp_289_rule(Parser *p); // file: statements? $ @@ -17682,7 +17688,7 @@ kwargs_rule(Parser *p) return _res; } -// starred_expression: invalid_starred_expression | '*' expression +// starred_expression: invalid_starred_expression | '*' expression | '*' static expr_ty starred_expression_rule(Parser *p) { @@ -17759,6 +17765,30 @@ starred_expression_rule(Parser *p) D(fprintf(stderr, "%*c%s starred_expression[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' expression")); } + { // '*' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> starred_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + ) + { + D(fprintf(stderr, "%*c+ starred_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); + _res = RAISE_SYNTAX_ERROR ( "Invalid star expression" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s starred_expression[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*'")); + } _res = NULL; done: p->level--; @@ -19837,7 +19867,7 @@ func_type_comment_rule(Parser *p) } // invalid_arguments: -// | ((','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' '*' +// | ((','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' ','.(starred_expression !'=')+ // | expression for_if_clauses ',' [args | expression for_if_clauses] // | NAME '=' expression for_if_clauses // | [(args ',')] NAME '=' &(',' | ')') @@ -19856,25 +19886,25 @@ invalid_arguments_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // ((','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' '*' + { // ((','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' ','.(starred_expression !'=')+ if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' '*'")); - Token * _literal; + D(fprintf(stderr, "%*c> invalid_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' ','.(starred_expression !'=')+")); + asdl_seq * _gather_152_var; void *_tmp_151_var; - Token * b; + Token * a; if ( (_tmp_151_var = _tmp_151_rule(p)) // (','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs && - (_literal = _PyPegen_expect_token(p, 12)) // token=',' + (a = _PyPegen_expect_token(p, 12)) // token=',' && - (b = _PyPegen_expect_token(p, 16)) // token='*' + (_gather_152_var = _gather_152_rule(p)) // ','.(starred_expression !'=')+ ) { - D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "((','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' '*'")); - _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( b , "iterable argument unpacking follows keyword argument unpacking" ); + D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "((','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' ','.(starred_expression !'=')+")); + _res = RAISE_SYNTAX_ERROR_STARTING_FROM ( a , "iterable argument unpacking follows keyword argument unpacking" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -19884,7 +19914,7 @@ invalid_arguments_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_arguments[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "((','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' '*'")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "((','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' ','.(starred_expression !'=')+")); } { // expression for_if_clauses ',' [args | expression for_if_clauses] if (p->error_indicator) { @@ -19904,7 +19934,7 @@ invalid_arguments_rule(Parser *p) && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_opt_var = _tmp_152_rule(p), !p->error_indicator) // [args | expression for_if_clauses] + (_opt_var = _tmp_154_rule(p), !p->error_indicator) // [args | expression for_if_clauses] ) { D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses ',' [args | expression for_if_clauses]")); @@ -19964,13 +19994,13 @@ invalid_arguments_rule(Parser *p) expr_ty a; Token * b; if ( - (_opt_var = _tmp_153_rule(p), !p->error_indicator) // [(args ',')] + (_opt_var = _tmp_155_rule(p), !p->error_indicator) // [(args ',')] && (a = _PyPegen_name_token(p)) // NAME && (b = _PyPegen_expect_token(p, 22)) // token='=' && - _PyPegen_lookahead(1, _tmp_154_rule, p) + _PyPegen_lookahead(1, _tmp_156_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "[(args ',')] NAME '=' &(',' | ')')")); @@ -20108,7 +20138,7 @@ invalid_kwarg_rule(Parser *p) Token* a; Token * b; if ( - (a = (Token*)_tmp_155_rule(p)) // 'True' | 'False' | 'None' + (a = (Token*)_tmp_157_rule(p)) // 'True' | 'False' | 'None' && (b = _PyPegen_expect_token(p, 22)) // token='=' ) @@ -20168,7 +20198,7 @@ invalid_kwarg_rule(Parser *p) expr_ty a; Token * b; if ( - _PyPegen_lookahead(0, _tmp_156_rule, p) + _PyPegen_lookahead(0, _tmp_158_rule, p) && (a = expression_rule(p)) // expression && @@ -20424,7 +20454,7 @@ invalid_expression_rule(Parser *p) expr_ty a; expr_ty b; if ( - _PyPegen_lookahead(0, _tmp_157_rule, p) + _PyPegen_lookahead(0, _tmp_159_rule, p) && (a = disjunction_rule(p)) // disjunction && @@ -20460,7 +20490,7 @@ invalid_expression_rule(Parser *p) && (b = disjunction_rule(p)) // disjunction && - _PyPegen_lookahead(0, _tmp_158_rule, p) + _PyPegen_lookahead(0, _tmp_160_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "disjunction 'if' disjunction !('else' | ':')")); @@ -20581,7 +20611,7 @@ invalid_named_expression_rule(Parser *p) && (b = bitwise_or_rule(p)) // bitwise_or && - _PyPegen_lookahead(0, _tmp_159_rule, p) + _PyPegen_lookahead(0, _tmp_161_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_named_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '=' bitwise_or !('=' | ':=')")); @@ -20607,7 +20637,7 @@ invalid_named_expression_rule(Parser *p) Token * b; expr_ty bitwise_or_var; if ( - _PyPegen_lookahead(0, _tmp_160_rule, p) + _PyPegen_lookahead(0, _tmp_162_rule, p) && (a = bitwise_or_rule(p)) // bitwise_or && @@ -20615,7 +20645,7 @@ invalid_named_expression_rule(Parser *p) && (bitwise_or_var = bitwise_or_rule(p)) // bitwise_or && - _PyPegen_lookahead(0, _tmp_161_rule, p) + _PyPegen_lookahead(0, _tmp_163_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_named_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!(list | tuple | genexp | 'True' | 'None' | 'False') bitwise_or '=' bitwise_or !('=' | ':=')")); @@ -20695,7 +20725,7 @@ invalid_assignment_rule(Parser *p) D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions* ':' expression")); Token * _literal; Token * _literal_1; - asdl_seq * _loop0_162_var; + asdl_seq * _loop0_164_var; expr_ty a; expr_ty expression_var; if ( @@ -20703,7 +20733,7 @@ invalid_assignment_rule(Parser *p) && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_loop0_162_var = _loop0_162_rule(p)) // star_named_expressions* + (_loop0_164_var = _loop0_164_rule(p)) // star_named_expressions* && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' && @@ -20760,10 +20790,10 @@ invalid_assignment_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* star_expressions '='")); Token * _literal; - asdl_seq * _loop0_163_var; + asdl_seq * _loop0_165_var; expr_ty a; if ( - (_loop0_163_var = _loop0_163_rule(p)) // ((star_targets '='))* + (_loop0_165_var = _loop0_165_rule(p)) // ((star_targets '='))* && (a = star_expressions_rule(p)) // star_expressions && @@ -20790,10 +20820,10 @@ invalid_assignment_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* yield_expr '='")); Token * _literal; - asdl_seq * _loop0_164_var; + asdl_seq * _loop0_166_var; expr_ty a; if ( - (_loop0_164_var = _loop0_164_rule(p)) // ((star_targets '='))* + (_loop0_166_var = _loop0_166_rule(p)) // ((star_targets '='))* && (a = yield_expr_rule(p)) // yield_expr && @@ -20819,7 +20849,7 @@ invalid_assignment_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions augassign (yield_expr | star_expressions)")); - void *_tmp_165_var; + void *_tmp_167_var; expr_ty a; AugOperator* augassign_var; if ( @@ -20827,7 +20857,7 @@ invalid_assignment_rule(Parser *p) && (augassign_var = augassign_rule(p)) // augassign && - (_tmp_165_var = _tmp_165_rule(p)) // yield_expr | star_expressions + (_tmp_167_var = _tmp_167_rule(p)) // yield_expr | star_expressions ) { D(fprintf(stderr, "%*c+ invalid_assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions augassign (yield_expr | star_expressions)")); @@ -21049,11 +21079,11 @@ invalid_comprehension_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('[' | '(' | '{') starred_expression for_if_clauses")); - void *_tmp_166_var; + void *_tmp_168_var; expr_ty a; asdl_comprehension_seq* for_if_clauses_var; if ( - (_tmp_166_var = _tmp_166_rule(p)) // '[' | '(' | '{' + (_tmp_168_var = _tmp_168_rule(p)) // '[' | '(' | '{' && (a = starred_expression_rule(p)) // starred_expression && @@ -21080,12 +21110,12 @@ invalid_comprehension_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('[' | '{') star_named_expression ',' star_named_expressions for_if_clauses")); Token * _literal; - void *_tmp_167_var; + void *_tmp_169_var; expr_ty a; asdl_expr_seq* b; asdl_comprehension_seq* for_if_clauses_var; if ( - (_tmp_167_var = _tmp_167_rule(p)) // '[' | '{' + (_tmp_169_var = _tmp_169_rule(p)) // '[' | '{' && (a = star_named_expression_rule(p)) // star_named_expression && @@ -21115,12 +21145,12 @@ invalid_comprehension_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('[' | '{') star_named_expression ',' for_if_clauses")); - void *_tmp_168_var; + void *_tmp_170_var; expr_ty a; Token * b; asdl_comprehension_seq* for_if_clauses_var; if ( - (_tmp_168_var = _tmp_168_rule(p)) // '[' | '{' + (_tmp_170_var = _tmp_170_rule(p)) // '[' | '{' && (a = star_named_expression_rule(p)) // star_named_expression && @@ -21255,13 +21285,13 @@ invalid_parameters_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(slash_no_default | slash_with_default) param_maybe_default* '/'")); - asdl_seq * _loop0_170_var; - void *_tmp_169_var; + asdl_seq * _loop0_172_var; + void *_tmp_171_var; Token * a; if ( - (_tmp_169_var = _tmp_169_rule(p)) // slash_no_default | slash_with_default + (_tmp_171_var = _tmp_171_rule(p)) // slash_no_default | slash_with_default && - (_loop0_170_var = _loop0_170_rule(p)) // param_maybe_default* + (_loop0_172_var = _loop0_172_rule(p)) // param_maybe_default* && (a = _PyPegen_expect_token(p, 17)) // token='/' ) @@ -21285,7 +21315,7 @@ invalid_parameters_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default? param_no_default* invalid_parameters_helper param_no_default")); - asdl_seq * _loop0_171_var; + asdl_seq * _loop0_173_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings arg_ty a; @@ -21293,7 +21323,7 @@ invalid_parameters_rule(Parser *p) if ( (_opt_var = slash_no_default_rule(p), !p->error_indicator) // slash_no_default? && - (_loop0_171_var = _loop0_171_rule(p)) // param_no_default* + (_loop0_173_var = _loop0_173_rule(p)) // param_no_default* && (invalid_parameters_helper_var = invalid_parameters_helper_rule(p)) // invalid_parameters_helper && @@ -21319,18 +21349,18 @@ invalid_parameters_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default* '(' param_no_default+ ','? ')'")); - asdl_seq * _loop0_172_var; - asdl_seq * _loop1_173_var; + asdl_seq * _loop0_174_var; + asdl_seq * _loop1_175_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings Token * a; Token * b; if ( - (_loop0_172_var = _loop0_172_rule(p)) // param_no_default* + (_loop0_174_var = _loop0_174_rule(p)) // param_no_default* && (a = _PyPegen_expect_token(p, 7)) // token='(' && - (_loop1_173_var = _loop1_173_rule(p)) // param_no_default+ + (_loop1_175_var = _loop1_175_rule(p)) // param_no_default+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -21357,22 +21387,22 @@ invalid_parameters_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "[(slash_no_default | slash_with_default)] param_maybe_default* '*' (',' | param_no_default) param_maybe_default* '/'")); Token * _literal; - asdl_seq * _loop0_175_var; asdl_seq * _loop0_177_var; + asdl_seq * _loop0_179_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings - void *_tmp_176_var; + void *_tmp_178_var; Token * a; if ( - (_opt_var = _tmp_174_rule(p), !p->error_indicator) // [(slash_no_default | slash_with_default)] + (_opt_var = _tmp_176_rule(p), !p->error_indicator) // [(slash_no_default | slash_with_default)] && - (_loop0_175_var = _loop0_175_rule(p)) // param_maybe_default* + (_loop0_177_var = _loop0_177_rule(p)) // param_maybe_default* && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_176_var = _tmp_176_rule(p)) // ',' | param_no_default + (_tmp_178_var = _tmp_178_rule(p)) // ',' | param_no_default && - (_loop0_177_var = _loop0_177_rule(p)) // param_maybe_default* + (_loop0_179_var = _loop0_179_rule(p)) // param_maybe_default* && (a = _PyPegen_expect_token(p, 17)) // token='/' ) @@ -21397,10 +21427,10 @@ invalid_parameters_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default+ '/' '*'")); Token * _literal; - asdl_seq * _loop1_178_var; + asdl_seq * _loop1_180_var; Token * a; if ( - (_loop1_178_var = _loop1_178_rule(p)) // param_maybe_default+ + (_loop1_180_var = _loop1_180_rule(p)) // param_maybe_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -21449,7 +21479,7 @@ invalid_default_rule(Parser *p) if ( (a = _PyPegen_expect_token(p, 22)) // token='=' && - _PyPegen_lookahead(1, _tmp_179_rule, p) + _PyPegen_lookahead(1, _tmp_181_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'=' &(')' | ',')")); @@ -21494,12 +21524,12 @@ invalid_star_etc_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); - void *_tmp_180_var; + void *_tmp_182_var; Token * a; if ( (a = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_180_var = _tmp_180_rule(p)) // ')' | ',' (')' | '**') + (_tmp_182_var = _tmp_182_rule(p)) // ')' | ',' (')' | '**') ) { D(fprintf(stderr, "%*c+ invalid_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); @@ -21582,20 +21612,20 @@ invalid_star_etc_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (param_no_default | ',') param_maybe_default* '*' (param_no_default | ',')")); Token * _literal; - asdl_seq * _loop0_182_var; - void *_tmp_181_var; + asdl_seq * _loop0_184_var; void *_tmp_183_var; + void *_tmp_185_var; Token * a; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_181_var = _tmp_181_rule(p)) // param_no_default | ',' + (_tmp_183_var = _tmp_183_rule(p)) // param_no_default | ',' && - (_loop0_182_var = _loop0_182_rule(p)) // param_maybe_default* + (_loop0_184_var = _loop0_184_rule(p)) // param_maybe_default* && (a = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_183_var = _tmp_183_rule(p)) // param_no_default | ',' + (_tmp_185_var = _tmp_185_rule(p)) // param_no_default | ',' ) { D(fprintf(stderr, "%*c+ invalid_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (param_no_default | ',') param_maybe_default* '*' (param_no_default | ',')")); @@ -21710,7 +21740,7 @@ invalid_kwds_rule(Parser *p) && (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' && - (a = (Token*)_tmp_184_rule(p)) // '*' | '**' | '/' + (a = (Token*)_tmp_186_rule(p)) // '*' | '**' | '/' ) { D(fprintf(stderr, "%*c+ invalid_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' param ',' ('*' | '**' | '/')")); @@ -21775,13 +21805,13 @@ invalid_parameters_helper_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_parameters_helper[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default+")); - asdl_seq * _loop1_185_var; + asdl_seq * _loop1_187_var; if ( - (_loop1_185_var = _loop1_185_rule(p)) // param_with_default+ + (_loop1_187_var = _loop1_187_rule(p)) // param_with_default+ ) { D(fprintf(stderr, "%*c+ invalid_parameters_helper[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_with_default+")); - _res = _loop1_185_var; + _res = _loop1_187_var; goto done; } p->mark = _mark; @@ -21846,13 +21876,13 @@ invalid_lambda_parameters_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(lambda_slash_no_default | lambda_slash_with_default) lambda_param_maybe_default* '/'")); - asdl_seq * _loop0_187_var; - void *_tmp_186_var; + asdl_seq * _loop0_189_var; + void *_tmp_188_var; Token * a; if ( - (_tmp_186_var = _tmp_186_rule(p)) // lambda_slash_no_default | lambda_slash_with_default + (_tmp_188_var = _tmp_188_rule(p)) // lambda_slash_no_default | lambda_slash_with_default && - (_loop0_187_var = _loop0_187_rule(p)) // lambda_param_maybe_default* + (_loop0_189_var = _loop0_189_rule(p)) // lambda_param_maybe_default* && (a = _PyPegen_expect_token(p, 17)) // token='/' ) @@ -21876,7 +21906,7 @@ invalid_lambda_parameters_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default? lambda_param_no_default* invalid_lambda_parameters_helper lambda_param_no_default")); - asdl_seq * _loop0_188_var; + asdl_seq * _loop0_190_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings arg_ty a; @@ -21884,7 +21914,7 @@ invalid_lambda_parameters_rule(Parser *p) if ( (_opt_var = lambda_slash_no_default_rule(p), !p->error_indicator) // lambda_slash_no_default? && - (_loop0_188_var = _loop0_188_rule(p)) // lambda_param_no_default* + (_loop0_190_var = _loop0_190_rule(p)) // lambda_param_no_default* && (invalid_lambda_parameters_helper_var = invalid_lambda_parameters_helper_rule(p)) // invalid_lambda_parameters_helper && @@ -21910,18 +21940,18 @@ invalid_lambda_parameters_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* '(' ','.lambda_param+ ','? ')'")); - asdl_seq * _gather_190_var; - asdl_seq * _loop0_189_var; + asdl_seq * _gather_192_var; + asdl_seq * _loop0_191_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings Token * a; Token * b; if ( - (_loop0_189_var = _loop0_189_rule(p)) // lambda_param_no_default* + (_loop0_191_var = _loop0_191_rule(p)) // lambda_param_no_default* && (a = _PyPegen_expect_token(p, 7)) // token='(' && - (_gather_190_var = _gather_190_rule(p)) // ','.lambda_param+ + (_gather_192_var = _gather_192_rule(p)) // ','.lambda_param+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -21948,22 +21978,22 @@ invalid_lambda_parameters_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "[(lambda_slash_no_default | lambda_slash_with_default)] lambda_param_maybe_default* '*' (',' | lambda_param_no_default) lambda_param_maybe_default* '/'")); Token * _literal; - asdl_seq * _loop0_193_var; asdl_seq * _loop0_195_var; + asdl_seq * _loop0_197_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings - void *_tmp_194_var; + void *_tmp_196_var; Token * a; if ( - (_opt_var = _tmp_192_rule(p), !p->error_indicator) // [(lambda_slash_no_default | lambda_slash_with_default)] + (_opt_var = _tmp_194_rule(p), !p->error_indicator) // [(lambda_slash_no_default | lambda_slash_with_default)] && - (_loop0_193_var = _loop0_193_rule(p)) // lambda_param_maybe_default* + (_loop0_195_var = _loop0_195_rule(p)) // lambda_param_maybe_default* && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_194_var = _tmp_194_rule(p)) // ',' | lambda_param_no_default + (_tmp_196_var = _tmp_196_rule(p)) // ',' | lambda_param_no_default && - (_loop0_195_var = _loop0_195_rule(p)) // lambda_param_maybe_default* + (_loop0_197_var = _loop0_197_rule(p)) // lambda_param_maybe_default* && (a = _PyPegen_expect_token(p, 17)) // token='/' ) @@ -21988,10 +22018,10 @@ invalid_lambda_parameters_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default+ '/' '*'")); Token * _literal; - asdl_seq * _loop1_196_var; + asdl_seq * _loop1_198_var; Token * a; if ( - (_loop1_196_var = _loop1_196_rule(p)) // lambda_param_maybe_default+ + (_loop1_198_var = _loop1_198_rule(p)) // lambda_param_maybe_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -22062,13 +22092,13 @@ invalid_lambda_parameters_helper_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_lambda_parameters_helper[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+")); - asdl_seq * _loop1_197_var; + asdl_seq * _loop1_199_var; if ( - (_loop1_197_var = _loop1_197_rule(p)) // lambda_param_with_default+ + (_loop1_199_var = _loop1_199_rule(p)) // lambda_param_with_default+ ) { D(fprintf(stderr, "%*c+ invalid_lambda_parameters_helper[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+")); - _res = _loop1_197_var; + _res = _loop1_199_var; goto done; } p->mark = _mark; @@ -22104,11 +22134,11 @@ invalid_lambda_star_etc_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); Token * _literal; - void *_tmp_198_var; + void *_tmp_200_var; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_198_var = _tmp_198_rule(p)) // ':' | ',' (':' | '**') + (_tmp_200_var = _tmp_200_rule(p)) // ':' | ',' (':' | '**') ) { D(fprintf(stderr, "%*c+ invalid_lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); @@ -22161,20 +22191,20 @@ invalid_lambda_star_etc_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (lambda_param_no_default | ',') lambda_param_maybe_default* '*' (lambda_param_no_default | ',')")); Token * _literal; - asdl_seq * _loop0_200_var; - void *_tmp_199_var; + asdl_seq * _loop0_202_var; void *_tmp_201_var; + void *_tmp_203_var; Token * a; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_199_var = _tmp_199_rule(p)) // lambda_param_no_default | ',' + (_tmp_201_var = _tmp_201_rule(p)) // lambda_param_no_default | ',' && - (_loop0_200_var = _loop0_200_rule(p)) // lambda_param_maybe_default* + (_loop0_202_var = _loop0_202_rule(p)) // lambda_param_maybe_default* && (a = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_201_var = _tmp_201_rule(p)) // lambda_param_no_default | ',' + (_tmp_203_var = _tmp_203_rule(p)) // lambda_param_no_default | ',' ) { D(fprintf(stderr, "%*c+ invalid_lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (lambda_param_no_default | ',') lambda_param_maybe_default* '*' (lambda_param_no_default | ',')")); @@ -22292,7 +22322,7 @@ invalid_lambda_kwds_rule(Parser *p) && (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' && - (a = (Token*)_tmp_202_rule(p)) // '*' | '**' | '/' + (a = (Token*)_tmp_204_rule(p)) // '*' | '**' | '/' ) { D(fprintf(stderr, "%*c+ invalid_lambda_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' lambda_param ',' ('*' | '**' | '/')")); @@ -22398,7 +22428,7 @@ invalid_with_item_rule(Parser *p) && (a = expression_rule(p)) // expression && - _PyPegen_lookahead(1, _tmp_203_rule, p) + _PyPegen_lookahead(1, _tmp_205_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_with_item[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression 'as' expression &(',' | ')' | ':')")); @@ -22571,14 +22601,14 @@ invalid_import_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_import[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'import' ','.dotted_name+ 'from' dotted_name")); - asdl_seq * _gather_204_var; + asdl_seq * _gather_206_var; Token * _keyword; Token * a; expr_ty dotted_name_var; if ( (a = _PyPegen_expect_token(p, 620)) // token='import' && - (_gather_204_var = _gather_204_rule(p)) // ','.dotted_name+ + (_gather_206_var = _gather_206_rule(p)) // ','.dotted_name+ && (_keyword = _PyPegen_expect_token(p, 621)) // token='from' && @@ -22750,7 +22780,7 @@ invalid_with_stmt_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async'? 'with' ','.(expression ['as' star_target])+ NEWLINE")); - asdl_seq * _gather_206_var; + asdl_seq * _gather_208_var; Token * _keyword; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings @@ -22760,7 +22790,7 @@ invalid_with_stmt_rule(Parser *p) && (_keyword = _PyPegen_expect_token(p, 634)) // token='with' && - (_gather_206_var = _gather_206_rule(p)) // ','.(expression ['as' star_target])+ + (_gather_208_var = _gather_208_rule(p)) // ','.(expression ['as' star_target])+ && (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) @@ -22784,7 +22814,7 @@ invalid_with_stmt_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async'? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' NEWLINE")); - asdl_seq * _gather_208_var; + asdl_seq * _gather_210_var; Token * _keyword; Token * _literal; Token * _literal_1; @@ -22800,7 +22830,7 @@ invalid_with_stmt_rule(Parser *p) && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (_gather_208_var = _gather_208_rule(p)) // ','.(expressions ['as' star_target])+ + (_gather_210_var = _gather_210_rule(p)) // ','.(expressions ['as' star_target])+ && (_opt_var_1 = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -22849,7 +22879,7 @@ invalid_with_stmt_indent_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_with_stmt_indent[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async'? 'with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT")); - asdl_seq * _gather_210_var; + asdl_seq * _gather_212_var; Token * _literal; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings @@ -22860,7 +22890,7 @@ invalid_with_stmt_indent_rule(Parser *p) && (a = _PyPegen_expect_token(p, 634)) // token='with' && - (_gather_210_var = _gather_210_rule(p)) // ','.(expression ['as' star_target])+ + (_gather_212_var = _gather_212_rule(p)) // ','.(expression ['as' star_target])+ && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -22888,7 +22918,7 @@ invalid_with_stmt_indent_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_with_stmt_indent[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async'? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' ':' NEWLINE !INDENT")); - asdl_seq * _gather_212_var; + asdl_seq * _gather_214_var; Token * _literal; Token * _literal_1; Token * _literal_2; @@ -22905,7 +22935,7 @@ invalid_with_stmt_indent_rule(Parser *p) && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (_gather_212_var = _gather_212_rule(p)) // ','.(expressions ['as' star_target])+ + (_gather_214_var = _gather_214_rule(p)) // ','.(expressions ['as' star_target])+ && (_opt_var_1 = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -23002,7 +23032,7 @@ invalid_try_stmt_rule(Parser *p) && (block_var = block_rule(p)) // block && - _PyPegen_lookahead(0, _tmp_214_rule, p) + _PyPegen_lookahead(0, _tmp_216_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_try_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'try' ':' block !('except' | 'finally')")); @@ -23027,8 +23057,8 @@ invalid_try_stmt_rule(Parser *p) Token * _keyword; Token * _literal; Token * _literal_1; - asdl_seq * _loop0_215_var; - asdl_seq * _loop1_216_var; + asdl_seq * _loop0_217_var; + asdl_seq * _loop1_218_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings Token * a; @@ -23039,9 +23069,9 @@ invalid_try_stmt_rule(Parser *p) && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && - (_loop0_215_var = _loop0_215_rule(p)) // block* + (_loop0_217_var = _loop0_217_rule(p)) // block* && - (_loop1_216_var = _loop1_216_rule(p)) // except_block+ + (_loop1_218_var = _loop1_218_rule(p)) // except_block+ && (a = _PyPegen_expect_token(p, 656)) // token='except' && @@ -23049,7 +23079,7 @@ invalid_try_stmt_rule(Parser *p) && (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_217_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var = _tmp_219_rule(p), !p->error_indicator) // ['as' NAME] && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' ) @@ -23076,8 +23106,8 @@ invalid_try_stmt_rule(Parser *p) Token * _keyword; Token * _literal; Token * _literal_1; - asdl_seq * _loop0_218_var; - asdl_seq * _loop1_219_var; + asdl_seq * _loop0_220_var; + asdl_seq * _loop1_221_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings Token * a; @@ -23086,13 +23116,13 @@ invalid_try_stmt_rule(Parser *p) && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && - (_loop0_218_var = _loop0_218_rule(p)) // block* + (_loop0_220_var = _loop0_220_rule(p)) // block* && - (_loop1_219_var = _loop1_219_rule(p)) // except_star_block+ + (_loop1_221_var = _loop1_221_rule(p)) // except_star_block+ && (a = _PyPegen_expect_token(p, 656)) // token='except' && - (_opt_var = _tmp_220_rule(p), !p->error_indicator) // [expression ['as' NAME]] + (_opt_var = _tmp_222_rule(p), !p->error_indicator) // [expression ['as' NAME]] && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' ) @@ -23159,7 +23189,7 @@ invalid_except_stmt_rule(Parser *p) && (expressions_var = expressions_rule(p)) // expressions && - (_opt_var_1 = _tmp_221_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var_1 = _tmp_223_rule(p), !p->error_indicator) // ['as' NAME] && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' ) @@ -23197,7 +23227,7 @@ invalid_except_stmt_rule(Parser *p) && (expression_var = expression_rule(p)) // expression && - (_opt_var_1 = _tmp_222_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var_1 = _tmp_224_rule(p), !p->error_indicator) // ['as' NAME] && (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) @@ -23249,14 +23279,14 @@ invalid_except_stmt_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_except_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' '*' (NEWLINE | ':')")); Token * _literal; - void *_tmp_223_var; + void *_tmp_225_var; Token * a; if ( (a = _PyPegen_expect_token(p, 656)) // token='except' && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_223_var = _tmp_223_rule(p)) // NEWLINE | ':' + (_tmp_225_var = _tmp_225_rule(p)) // NEWLINE | ':' ) { D(fprintf(stderr, "%*c+ invalid_except_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' '*' (NEWLINE | ':')")); @@ -23361,7 +23391,7 @@ invalid_except_stmt_indent_rule(Parser *p) && (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_224_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var = _tmp_226_rule(p), !p->error_indicator) // ['as' NAME] && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -23455,7 +23485,7 @@ invalid_except_star_stmt_indent_rule(Parser *p) && (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_225_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var = _tmp_227_rule(p), !p->error_indicator) // ['as' NAME] && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' && @@ -23819,7 +23849,7 @@ invalid_class_argument_pattern_rule(Parser *p) asdl_pattern_seq* a; asdl_seq* keyword_patterns_var; if ( - (_opt_var = _tmp_226_rule(p), !p->error_indicator) // [positional_patterns ','] + (_opt_var = _tmp_228_rule(p), !p->error_indicator) // [positional_patterns ','] && (keyword_patterns_var = keyword_patterns_rule(p)) // keyword_patterns && @@ -24311,7 +24341,7 @@ invalid_def_raw_rule(Parser *p) && (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' && - (_opt_var_3 = _tmp_227_rule(p), !p->error_indicator) // ['->' expression] + (_opt_var_3 = _tmp_229_rule(p), !p->error_indicator) // ['->' expression] && (_literal_2 = _PyPegen_expect_token(p, 11)) // token=':' && @@ -24374,7 +24404,7 @@ invalid_class_def_raw_rule(Parser *p) && (_opt_var = type_params_rule(p), !p->error_indicator) // type_params? && - (_opt_var_1 = _tmp_228_rule(p), !p->error_indicator) // ['(' arguments? ')'] + (_opt_var_1 = _tmp_230_rule(p), !p->error_indicator) // ['(' arguments? ')'] && (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) @@ -24413,7 +24443,7 @@ invalid_class_def_raw_rule(Parser *p) && (_opt_var = type_params_rule(p), !p->error_indicator) // type_params? && - (_opt_var_1 = _tmp_229_rule(p), !p->error_indicator) // ['(' arguments? ')'] + (_opt_var_1 = _tmp_231_rule(p), !p->error_indicator) // ['(' arguments? ')'] && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -24463,11 +24493,11 @@ invalid_double_starred_kvpairs_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_double_starred_kvpairs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.double_starred_kvpair+ ',' invalid_kvpair")); - asdl_seq * _gather_230_var; + asdl_seq * _gather_232_var; Token * _literal; void *invalid_kvpair_var; if ( - (_gather_230_var = _gather_230_rule(p)) // ','.double_starred_kvpair+ + (_gather_232_var = _gather_232_rule(p)) // ','.double_starred_kvpair+ && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && @@ -24475,7 +24505,7 @@ invalid_double_starred_kvpairs_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ invalid_double_starred_kvpairs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.double_starred_kvpair+ ',' invalid_kvpair")); - _res = _PyPegen_dummy_name(p, _gather_230_var, _literal, invalid_kvpair_var); + _res = _PyPegen_dummy_name(p, _gather_232_var, _literal, invalid_kvpair_var); goto done; } p->mark = _mark; @@ -24528,7 +24558,7 @@ invalid_double_starred_kvpairs_rule(Parser *p) && (a = _PyPegen_expect_token(p, 11)) // token=':' && - _PyPegen_lookahead(1, _tmp_232_rule, p) + _PyPegen_lookahead(1, _tmp_234_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_double_starred_kvpairs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' &('}' | ',')")); @@ -24638,7 +24668,7 @@ invalid_kvpair_rule(Parser *p) && (a = _PyPegen_expect_token(p, 11)) // token=':' && - _PyPegen_lookahead(1, _tmp_233_rule, p) + _PyPegen_lookahead(1, _tmp_235_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_kvpair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' &('}' | ',')")); @@ -24854,7 +24884,7 @@ invalid_replacement_field_rule(Parser *p) if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' && - _PyPegen_lookahead(0, _tmp_234_rule, p) + _PyPegen_lookahead(0, _tmp_236_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' !(yield_expr | star_expressions)")); @@ -24877,13 +24907,13 @@ invalid_replacement_field_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_replacement_field[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) !('=' | '!' | ':' | '}')")); Token * _literal; - void *_tmp_235_var; + void *_tmp_237_var; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' && - (_tmp_235_var = _tmp_235_rule(p)) // yield_expr | star_expressions + (_tmp_237_var = _tmp_237_rule(p)) // yield_expr | star_expressions && - _PyPegen_lookahead(0, _tmp_236_rule, p) + _PyPegen_lookahead(0, _tmp_238_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) !('=' | '!' | ':' | '}')")); @@ -24907,15 +24937,15 @@ invalid_replacement_field_rule(Parser *p) D(fprintf(stderr, "%*c> invalid_replacement_field[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '=' !('!' | ':' | '}')")); Token * _literal; Token * _literal_1; - void *_tmp_237_var; + void *_tmp_239_var; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' && - (_tmp_237_var = _tmp_237_rule(p)) // yield_expr | star_expressions + (_tmp_239_var = _tmp_239_rule(p)) // yield_expr | star_expressions && (_literal_1 = _PyPegen_expect_token(p, 22)) // token='=' && - _PyPegen_lookahead(0, _tmp_238_rule, p) + _PyPegen_lookahead(0, _tmp_240_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '=' !('!' | ':' | '}')")); @@ -24940,12 +24970,12 @@ invalid_replacement_field_rule(Parser *p) Token * _literal; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings - void *_tmp_239_var; + void *_tmp_241_var; void *invalid_conversion_character_var; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' && - (_tmp_239_var = _tmp_239_rule(p)) // yield_expr | star_expressions + (_tmp_241_var = _tmp_241_rule(p)) // yield_expr | star_expressions && (_opt_var = _PyPegen_expect_token(p, 22), !p->error_indicator) // '='? && @@ -24953,7 +24983,7 @@ invalid_replacement_field_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '='? invalid_conversion_character")); - _res = _PyPegen_dummy_name(p, _literal, _tmp_239_var, _opt_var, invalid_conversion_character_var); + _res = _PyPegen_dummy_name(p, _literal, _tmp_241_var, _opt_var, invalid_conversion_character_var); goto done; } p->mark = _mark; @@ -24971,17 +25001,17 @@ invalid_replacement_field_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings void *_opt_var_1; UNUSED(_opt_var_1); // Silence compiler warnings - void *_tmp_240_var; + void *_tmp_242_var; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' && - (_tmp_240_var = _tmp_240_rule(p)) // yield_expr | star_expressions + (_tmp_242_var = _tmp_242_rule(p)) // yield_expr | star_expressions && (_opt_var = _PyPegen_expect_token(p, 22), !p->error_indicator) // '='? && - (_opt_var_1 = _tmp_241_rule(p), !p->error_indicator) // ['!' NAME] + (_opt_var_1 = _tmp_243_rule(p), !p->error_indicator) // ['!' NAME] && - _PyPegen_lookahead(0, _tmp_242_rule, p) + _PyPegen_lookahead(0, _tmp_244_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '='? ['!' NAME] !(':' | '}')")); @@ -25005,24 +25035,24 @@ invalid_replacement_field_rule(Parser *p) D(fprintf(stderr, "%*c> invalid_replacement_field[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '='? ['!' NAME] ':' fstring_format_spec* !'}'")); Token * _literal; Token * _literal_1; - asdl_seq * _loop0_245_var; + asdl_seq * _loop0_247_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings void *_opt_var_1; UNUSED(_opt_var_1); // Silence compiler warnings - void *_tmp_243_var; + void *_tmp_245_var; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' && - (_tmp_243_var = _tmp_243_rule(p)) // yield_expr | star_expressions + (_tmp_245_var = _tmp_245_rule(p)) // yield_expr | star_expressions && (_opt_var = _PyPegen_expect_token(p, 22), !p->error_indicator) // '='? && - (_opt_var_1 = _tmp_244_rule(p), !p->error_indicator) // ['!' NAME] + (_opt_var_1 = _tmp_246_rule(p), !p->error_indicator) // ['!' NAME] && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' && - (_loop0_245_var = _loop0_245_rule(p)) // fstring_format_spec* + (_loop0_247_var = _loop0_247_rule(p)) // fstring_format_spec* && _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 26) // token='}' ) @@ -25051,15 +25081,15 @@ invalid_replacement_field_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings void *_opt_var_1; UNUSED(_opt_var_1); // Silence compiler warnings - void *_tmp_246_var; + void *_tmp_248_var; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' && - (_tmp_246_var = _tmp_246_rule(p)) // yield_expr | star_expressions + (_tmp_248_var = _tmp_248_rule(p)) // yield_expr | star_expressions && (_opt_var = _PyPegen_expect_token(p, 22), !p->error_indicator) // '='? && - (_opt_var_1 = _tmp_247_rule(p), !p->error_indicator) // ['!' NAME] + (_opt_var_1 = _tmp_249_rule(p), !p->error_indicator) // ['!' NAME] && _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 26) // token='}' ) @@ -25106,7 +25136,7 @@ invalid_conversion_character_rule(Parser *p) if ( (_literal = _PyPegen_expect_token(p, 54)) // token='!' && - _PyPegen_lookahead(1, _tmp_248_rule, p) + _PyPegen_lookahead(1, _tmp_250_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_conversion_character[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' &(':' | '}')")); @@ -25173,14 +25203,14 @@ invalid_arithmetic_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_arithmetic[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "sum ('+' | '-' | '*' | '/' | '%' | '//' | '@') 'not' inversion")); - void *_tmp_249_var; + void *_tmp_251_var; Token * a; expr_ty b; expr_ty sum_var; if ( (sum_var = sum_rule(p)) // sum && - (_tmp_249_var = _tmp_249_rule(p)) // '+' | '-' | '*' | '/' | '%' | '//' | '@' + (_tmp_251_var = _tmp_251_rule(p)) // '+' | '-' | '*' | '/' | '%' | '//' | '@' && (a = _PyPegen_expect_token(p, 678)) // token='not' && @@ -25225,11 +25255,11 @@ invalid_factor_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_factor[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('+' | '-' | '~') 'not' factor")); - void *_tmp_250_var; + void *_tmp_252_var; Token * a; expr_ty b; if ( - (_tmp_250_var = _tmp_250_rule(p)) // '+' | '-' | '~' + (_tmp_252_var = _tmp_252_rule(p)) // '+' | '-' | '~' && (a = _PyPegen_expect_token(p, 678)) // token='not' && @@ -26070,12 +26100,12 @@ _loop1_14_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_14[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_251_var; + void *_tmp_253_var; while ( - (_tmp_251_var = _tmp_251_rule(p)) // star_targets '=' + (_tmp_253_var = _tmp_253_rule(p)) // star_targets '=' ) { - _res = _tmp_251_var; + _res = _tmp_253_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -26639,12 +26669,12 @@ _loop0_24_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_24[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); - void *_tmp_252_var; + void *_tmp_254_var; while ( - (_tmp_252_var = _tmp_252_rule(p)) // '.' | '...' + (_tmp_254_var = _tmp_254_rule(p)) // '.' | '...' ) { - _res = _tmp_252_var; + _res = _tmp_254_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -26706,12 +26736,12 @@ _loop1_25_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_25[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); - void *_tmp_253_var; + void *_tmp_255_var; while ( - (_tmp_253_var = _tmp_253_rule(p)) // '.' | '...' + (_tmp_255_var = _tmp_255_rule(p)) // '.' | '...' ) { - _res = _tmp_253_var; + _res = _tmp_255_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -27104,12 +27134,12 @@ _loop1_32_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_32[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('@' named_expression NEWLINE)")); - void *_tmp_254_var; + void *_tmp_256_var; while ( - (_tmp_254_var = _tmp_254_rule(p)) // '@' named_expression NEWLINE + (_tmp_256_var = _tmp_256_rule(p)) // '@' named_expression NEWLINE ) { - _res = _tmp_254_var; + _res = _tmp_256_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -30234,12 +30264,12 @@ _loop1_82_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_82[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' expression)")); - void *_tmp_255_var; + void *_tmp_257_var; while ( - (_tmp_255_var = _tmp_255_rule(p)) // ',' expression + (_tmp_257_var = _tmp_257_rule(p)) // ',' expression ) { - _res = _tmp_255_var; + _res = _tmp_257_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -30306,12 +30336,12 @@ _loop1_83_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_83[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_expression)")); - void *_tmp_256_var; + void *_tmp_258_var; while ( - (_tmp_256_var = _tmp_256_rule(p)) // ',' star_expression + (_tmp_258_var = _tmp_258_rule(p)) // ',' star_expression ) { - _res = _tmp_256_var; + _res = _tmp_258_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -30495,12 +30525,12 @@ _loop1_86_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_86[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('or' conjunction)")); - void *_tmp_257_var; + void *_tmp_259_var; while ( - (_tmp_257_var = _tmp_257_rule(p)) // 'or' conjunction + (_tmp_259_var = _tmp_259_rule(p)) // 'or' conjunction ) { - _res = _tmp_257_var; + _res = _tmp_259_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -30567,12 +30597,12 @@ _loop1_87_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_87[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('and' inversion)")); - void *_tmp_258_var; + void *_tmp_260_var; while ( - (_tmp_258_var = _tmp_258_rule(p)) // 'and' inversion + (_tmp_260_var = _tmp_260_rule(p)) // 'and' inversion ) { - _res = _tmp_258_var; + _res = _tmp_260_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -30759,7 +30789,7 @@ _loop0_91_rule(Parser *p) while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_259_rule(p)) // slice | starred_expression + (elem = _tmp_261_rule(p)) // slice | starred_expression ) { _res = elem; @@ -30824,7 +30854,7 @@ _gather_90_rule(Parser *p) void *elem; asdl_seq * seq; if ( - (elem = _tmp_259_rule(p)) // slice | starred_expression + (elem = _tmp_261_rule(p)) // slice | starred_expression && (seq = _loop0_91_rule(p)) // _loop0_91 ) @@ -32423,12 +32453,12 @@ _loop1_115_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_115[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(fstring | string)")); - void *_tmp_260_var; + void *_tmp_262_var; while ( - (_tmp_260_var = _tmp_260_rule(p)) // fstring | string + (_tmp_262_var = _tmp_262_rule(p)) // fstring | string ) { - _res = _tmp_260_var; + _res = _tmp_262_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -32733,12 +32763,12 @@ _loop0_120_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_120[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); - void *_tmp_261_var; + void *_tmp_263_var; while ( - (_tmp_261_var = _tmp_261_rule(p)) // 'if' disjunction + (_tmp_263_var = _tmp_263_rule(p)) // 'if' disjunction ) { - _res = _tmp_261_var; + _res = _tmp_263_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -32800,12 +32830,12 @@ _loop0_121_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_121[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); - void *_tmp_262_var; + void *_tmp_264_var; while ( - (_tmp_262_var = _tmp_262_rule(p)) // 'if' disjunction + (_tmp_264_var = _tmp_264_rule(p)) // 'if' disjunction ) { - _res = _tmp_262_var; + _res = _tmp_264_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -32858,20 +32888,20 @@ _tmp_122_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _tmp_122[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "bitwise_or ((',' bitwise_or))* ','?")); - asdl_seq * _loop0_263_var; + asdl_seq * _loop0_265_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings expr_ty bitwise_or_var; if ( (bitwise_or_var = bitwise_or_rule(p)) // bitwise_or && - (_loop0_263_var = _loop0_263_rule(p)) // ((',' bitwise_or))* + (_loop0_265_var = _loop0_265_rule(p)) // ((',' bitwise_or))* && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) { D(fprintf(stderr, "%*c+ _tmp_122[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "bitwise_or ((',' bitwise_or))* ','?")); - _res = _PyPegen_dummy_name(p, bitwise_or_var, _loop0_263_var, _opt_var); + _res = _PyPegen_dummy_name(p, bitwise_or_var, _loop0_265_var, _opt_var); goto done; } p->mark = _mark; @@ -32976,7 +33006,7 @@ _loop0_125_rule(Parser *p) while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_264_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' + (elem = _tmp_266_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' ) { _res = elem; @@ -33042,7 +33072,7 @@ _gather_124_rule(Parser *p) void *elem; asdl_seq * seq; if ( - (elem = _tmp_264_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' + (elem = _tmp_266_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' && (seq = _loop0_125_rule(p)) // _loop0_125 ) @@ -33603,12 +33633,12 @@ _loop0_135_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_135[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)")); - void *_tmp_265_var; + void *_tmp_267_var; while ( - (_tmp_265_var = _tmp_265_rule(p)) // ',' star_target + (_tmp_267_var = _tmp_267_rule(p)) // ',' star_target ) { - _res = _tmp_265_var; + _res = _tmp_267_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -33787,12 +33817,12 @@ _loop1_138_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_138[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)")); - void *_tmp_266_var; + void *_tmp_268_var; while ( - (_tmp_266_var = _tmp_266_rule(p)) // ',' star_target + (_tmp_268_var = _tmp_268_rule(p)) // ',' star_target ) { - _res = _tmp_266_var; + _res = _tmp_268_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -34518,13 +34548,13 @@ _tmp_151_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs)")); - void *_tmp_267_var; + void *_tmp_269_var; if ( - (_tmp_267_var = _tmp_267_rule(p)) // ','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs + (_tmp_269_var = _tmp_269_rule(p)) // ','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs ) { D(fprintf(stderr, "%*c+ _tmp_151[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs)")); - _res = _tmp_267_var; + _res = _tmp_269_var; goto done; } p->mark = _mark; @@ -34556,9 +34586,126 @@ _tmp_151_rule(Parser *p) return _res; } -// _tmp_152: args | expression for_if_clauses +// _loop0_153: ',' (starred_expression !'=') +static asdl_seq * +_loop0_153_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' (starred_expression !'=') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (starred_expression !'=')")); + Token * _literal; + void *elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = _tmp_270_rule(p)) // starred_expression !'=' + ) + { + _res = elem; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + PyMem_Free(_children); + p->level--; + return NULL; + } + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_153[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (starred_expression !'=')")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + p->level--; + return _seq; +} + +// _gather_152: (starred_expression !'=') _loop0_153 +static asdl_seq * +_gather_152_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // (starred_expression !'=') _loop0_153 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(starred_expression !'=') _loop0_153")); + void *elem; + asdl_seq * seq; + if ( + (elem = _tmp_270_rule(p)) // starred_expression !'=' + && + (seq = _loop0_153_rule(p)) // _loop0_153 + ) + { + D(fprintf(stderr, "%*c+ _gather_152[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(starred_expression !'=') _loop0_153")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_152[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(starred_expression !'=') _loop0_153")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_154: args | expression for_if_clauses static void * -_tmp_152_rule(Parser *p) +_tmp_154_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -34574,18 +34721,18 @@ _tmp_152_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args")); + D(fprintf(stderr, "%*c> _tmp_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args")); expr_ty args_var; if ( (args_var = args_rule(p)) // args ) { - D(fprintf(stderr, "%*c+ _tmp_152[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args")); + D(fprintf(stderr, "%*c+ _tmp_154[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args")); _res = args_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_152[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_154[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "args")); } { // expression for_if_clauses @@ -34593,7 +34740,7 @@ _tmp_152_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses")); + D(fprintf(stderr, "%*c> _tmp_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses")); expr_ty expression_var; asdl_comprehension_seq* for_if_clauses_var; if ( @@ -34602,12 +34749,12 @@ _tmp_152_rule(Parser *p) (for_if_clauses_var = for_if_clauses_rule(p)) // for_if_clauses ) { - D(fprintf(stderr, "%*c+ _tmp_152[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses")); + D(fprintf(stderr, "%*c+ _tmp_154[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses")); _res = _PyPegen_dummy_name(p, expression_var, for_if_clauses_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_152[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_154[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression for_if_clauses")); } _res = NULL; @@ -34616,9 +34763,9 @@ _tmp_152_rule(Parser *p) return _res; } -// _tmp_153: args ',' +// _tmp_155: args ',' static void * -_tmp_153_rule(Parser *p) +_tmp_155_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -34634,7 +34781,7 @@ _tmp_153_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args ','")); + D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args ','")); Token * _literal; expr_ty args_var; if ( @@ -34643,12 +34790,12 @@ _tmp_153_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args ','")); + D(fprintf(stderr, "%*c+ _tmp_155[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args ','")); _res = _PyPegen_dummy_name(p, args_var, _literal); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_155[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "args ','")); } _res = NULL; @@ -34657,9 +34804,9 @@ _tmp_153_rule(Parser *p) return _res; } -// _tmp_154: ',' | ')' +// _tmp_156: ',' | ')' static void * -_tmp_154_rule(Parser *p) +_tmp_156_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -34675,18 +34822,18 @@ _tmp_154_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_156[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_154[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_156[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_154[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_156[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } { // ')' @@ -34694,18 +34841,18 @@ _tmp_154_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_156[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_154[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_156[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_154[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_156[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } _res = NULL; @@ -34714,9 +34861,9 @@ _tmp_154_rule(Parser *p) return _res; } -// _tmp_155: 'True' | 'False' | 'None' +// _tmp_157: 'True' | 'False' | 'None' static void * -_tmp_155_rule(Parser *p) +_tmp_157_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -34732,18 +34879,18 @@ _tmp_155_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); + D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); Token * _keyword; if ( (_keyword = _PyPegen_expect_token(p, 613)) // token='True' ) { - D(fprintf(stderr, "%*c+ _tmp_155[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); + D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_155[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'True'")); } { // 'False' @@ -34751,18 +34898,18 @@ _tmp_155_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); + D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); Token * _keyword; if ( (_keyword = _PyPegen_expect_token(p, 615)) // token='False' ) { - D(fprintf(stderr, "%*c+ _tmp_155[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); + D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_155[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'False'")); } { // 'None' @@ -34770,18 +34917,18 @@ _tmp_155_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); + D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); Token * _keyword; if ( (_keyword = _PyPegen_expect_token(p, 614)) // token='None' ) { - D(fprintf(stderr, "%*c+ _tmp_155[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); + D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_155[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'None'")); } _res = NULL; @@ -34790,9 +34937,9 @@ _tmp_155_rule(Parser *p) return _res; } -// _tmp_156: NAME '=' +// _tmp_158: NAME '=' static void * -_tmp_156_rule(Parser *p) +_tmp_158_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -34808,7 +34955,7 @@ _tmp_156_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_156[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '='")); + D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '='")); Token * _literal; expr_ty name_var; if ( @@ -34817,12 +34964,12 @@ _tmp_156_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_156[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '='")); + D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '='")); _res = _PyPegen_dummy_name(p, name_var, _literal); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_156[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_158[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME '='")); } _res = NULL; @@ -34831,9 +34978,9 @@ _tmp_156_rule(Parser *p) return _res; } -// _tmp_157: NAME STRING | SOFT_KEYWORD +// _tmp_159: NAME STRING | SOFT_KEYWORD static void * -_tmp_157_rule(Parser *p) +_tmp_159_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -34849,7 +34996,7 @@ _tmp_157_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME STRING")); + D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME STRING")); expr_ty name_var; expr_ty string_var; if ( @@ -34858,12 +35005,12 @@ _tmp_157_rule(Parser *p) (string_var = _PyPegen_string_token(p)) // STRING ) { - D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME STRING")); + D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME STRING")); _res = _PyPegen_dummy_name(p, name_var, string_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_159[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME STRING")); } { // SOFT_KEYWORD @@ -34871,18 +35018,18 @@ _tmp_157_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "SOFT_KEYWORD")); + D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "SOFT_KEYWORD")); expr_ty soft_keyword_var; if ( (soft_keyword_var = _PyPegen_soft_keyword_token(p)) // SOFT_KEYWORD ) { - D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "SOFT_KEYWORD")); + D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "SOFT_KEYWORD")); _res = soft_keyword_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_159[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "SOFT_KEYWORD")); } _res = NULL; @@ -34891,9 +35038,9 @@ _tmp_157_rule(Parser *p) return _res; } -// _tmp_158: 'else' | ':' +// _tmp_160: 'else' | ':' static void * -_tmp_158_rule(Parser *p) +_tmp_160_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -34909,18 +35056,18 @@ _tmp_158_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'else'")); + D(fprintf(stderr, "%*c> _tmp_160[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'else'")); Token * _keyword; if ( (_keyword = _PyPegen_expect_token(p, 664)) // token='else' ) { - D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'else'")); + D(fprintf(stderr, "%*c+ _tmp_160[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'else'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_158[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_160[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'else'")); } { // ':' @@ -34928,18 +35075,18 @@ _tmp_158_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_160[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_160[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_158[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_160[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } _res = NULL; @@ -34948,9 +35095,9 @@ _tmp_158_rule(Parser *p) return _res; } -// _tmp_159: '=' | ':=' +// _tmp_161: '=' | ':=' static void * -_tmp_159_rule(Parser *p) +_tmp_161_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -34966,18 +35113,18 @@ _tmp_159_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c> _tmp_161[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c+ _tmp_161[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_159[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_161[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='")); } { // ':=' @@ -34985,18 +35132,18 @@ _tmp_159_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='")); + D(fprintf(stderr, "%*c> _tmp_161[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 53)) // token=':=' ) { - D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':='")); + D(fprintf(stderr, "%*c+ _tmp_161[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':='")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_159[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_161[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':='")); } _res = NULL; @@ -35005,9 +35152,9 @@ _tmp_159_rule(Parser *p) return _res; } -// _tmp_160: list | tuple | genexp | 'True' | 'None' | 'False' +// _tmp_162: list | tuple | genexp | 'True' | 'None' | 'False' static void * -_tmp_160_rule(Parser *p) +_tmp_162_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35023,18 +35170,18 @@ _tmp_160_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_160[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "list")); + D(fprintf(stderr, "%*c> _tmp_162[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "list")); expr_ty list_var; if ( (list_var = list_rule(p)) // list ) { - D(fprintf(stderr, "%*c+ _tmp_160[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "list")); + D(fprintf(stderr, "%*c+ _tmp_162[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "list")); _res = list_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_160[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_162[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "list")); } { // tuple @@ -35042,18 +35189,18 @@ _tmp_160_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_160[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "tuple")); + D(fprintf(stderr, "%*c> _tmp_162[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "tuple")); expr_ty tuple_var; if ( (tuple_var = tuple_rule(p)) // tuple ) { - D(fprintf(stderr, "%*c+ _tmp_160[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "tuple")); + D(fprintf(stderr, "%*c+ _tmp_162[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "tuple")); _res = tuple_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_160[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_162[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "tuple")); } { // genexp @@ -35061,18 +35208,18 @@ _tmp_160_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_160[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "genexp")); + D(fprintf(stderr, "%*c> _tmp_162[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "genexp")); expr_ty genexp_var; if ( (genexp_var = genexp_rule(p)) // genexp ) { - D(fprintf(stderr, "%*c+ _tmp_160[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "genexp")); + D(fprintf(stderr, "%*c+ _tmp_162[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "genexp")); _res = genexp_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_160[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_162[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "genexp")); } { // 'True' @@ -35080,18 +35227,18 @@ _tmp_160_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_160[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); + D(fprintf(stderr, "%*c> _tmp_162[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); Token * _keyword; if ( (_keyword = _PyPegen_expect_token(p, 613)) // token='True' ) { - D(fprintf(stderr, "%*c+ _tmp_160[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); + D(fprintf(stderr, "%*c+ _tmp_162[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_160[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_162[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'True'")); } { // 'None' @@ -35099,18 +35246,18 @@ _tmp_160_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_160[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); + D(fprintf(stderr, "%*c> _tmp_162[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); Token * _keyword; if ( (_keyword = _PyPegen_expect_token(p, 614)) // token='None' ) { - D(fprintf(stderr, "%*c+ _tmp_160[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); + D(fprintf(stderr, "%*c+ _tmp_162[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_160[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_162[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'None'")); } { // 'False' @@ -35118,18 +35265,18 @@ _tmp_160_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_160[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); + D(fprintf(stderr, "%*c> _tmp_162[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); Token * _keyword; if ( (_keyword = _PyPegen_expect_token(p, 615)) // token='False' ) { - D(fprintf(stderr, "%*c+ _tmp_160[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); + D(fprintf(stderr, "%*c+ _tmp_162[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_160[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_162[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'False'")); } _res = NULL; @@ -35138,9 +35285,9 @@ _tmp_160_rule(Parser *p) return _res; } -// _tmp_161: '=' | ':=' +// _tmp_163: '=' | ':=' static void * -_tmp_161_rule(Parser *p) +_tmp_163_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35156,18 +35303,18 @@ _tmp_161_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_161[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c> _tmp_163[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_161[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c+ _tmp_163[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_161[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_163[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='")); } { // ':=' @@ -35175,18 +35322,18 @@ _tmp_161_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_161[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='")); + D(fprintf(stderr, "%*c> _tmp_163[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 53)) // token=':=' ) { - D(fprintf(stderr, "%*c+ _tmp_161[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':='")); + D(fprintf(stderr, "%*c+ _tmp_163[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':='")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_161[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_163[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':='")); } _res = NULL; @@ -35195,9 +35342,9 @@ _tmp_161_rule(Parser *p) return _res; } -// _loop0_162: star_named_expressions +// _loop0_164: star_named_expressions static asdl_seq * -_loop0_162_rule(Parser *p) +_loop0_164_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35222,7 +35369,7 @@ _loop0_162_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_162[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expressions")); + D(fprintf(stderr, "%*c> _loop0_164[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expressions")); asdl_expr_seq* star_named_expressions_var; while ( (star_named_expressions_var = star_named_expressions_rule(p)) // star_named_expressions @@ -35245,7 +35392,7 @@ _loop0_162_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_162[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_164[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expressions")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -35262,9 +35409,9 @@ _loop0_162_rule(Parser *p) return _seq; } -// _loop0_163: (star_targets '=') +// _loop0_165: (star_targets '=') static asdl_seq * -_loop0_163_rule(Parser *p) +_loop0_165_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35289,13 +35436,13 @@ _loop0_163_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_163[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_268_var; + D(fprintf(stderr, "%*c> _loop0_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); + void *_tmp_271_var; while ( - (_tmp_268_var = _tmp_268_rule(p)) // star_targets '=' + (_tmp_271_var = _tmp_271_rule(p)) // star_targets '=' ) { - _res = _tmp_268_var; + _res = _tmp_271_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -35312,7 +35459,7 @@ _loop0_163_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_163[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_165[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(star_targets '=')")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -35329,9 +35476,9 @@ _loop0_163_rule(Parser *p) return _seq; } -// _loop0_164: (star_targets '=') +// _loop0_166: (star_targets '=') static asdl_seq * -_loop0_164_rule(Parser *p) +_loop0_166_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35356,13 +35503,13 @@ _loop0_164_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_164[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_269_var; + D(fprintf(stderr, "%*c> _loop0_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); + void *_tmp_272_var; while ( - (_tmp_269_var = _tmp_269_rule(p)) // star_targets '=' + (_tmp_272_var = _tmp_272_rule(p)) // star_targets '=' ) { - _res = _tmp_269_var; + _res = _tmp_272_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -35379,7 +35526,7 @@ _loop0_164_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_164[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_166[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(star_targets '=')")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -35396,9 +35543,9 @@ _loop0_164_rule(Parser *p) return _seq; } -// _tmp_165: yield_expr | star_expressions +// _tmp_167: yield_expr | star_expressions static void * -_tmp_165_rule(Parser *p) +_tmp_167_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35414,18 +35561,18 @@ _tmp_165_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_167[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); expr_ty yield_expr_var; if ( (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _tmp_165[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_167[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); _res = yield_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_165[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_167[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } { // star_expressions @@ -35433,18 +35580,18 @@ _tmp_165_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c> _tmp_167[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); expr_ty star_expressions_var; if ( (star_expressions_var = star_expressions_rule(p)) // star_expressions ) { - D(fprintf(stderr, "%*c+ _tmp_165[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c+ _tmp_167[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); _res = star_expressions_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_165[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_167[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; @@ -35453,9 +35600,9 @@ _tmp_165_rule(Parser *p) return _res; } -// _tmp_166: '[' | '(' | '{' +// _tmp_168: '[' | '(' | '{' static void * -_tmp_166_rule(Parser *p) +_tmp_168_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35471,18 +35618,18 @@ _tmp_166_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c> _tmp_168[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 9)) // token='[' ) { - D(fprintf(stderr, "%*c+ _tmp_166[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c+ _tmp_168[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_166[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_168[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['")); } { // '(' @@ -35490,18 +35637,18 @@ _tmp_166_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); + D(fprintf(stderr, "%*c> _tmp_168[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 7)) // token='(' ) { - D(fprintf(stderr, "%*c+ _tmp_166[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); + D(fprintf(stderr, "%*c+ _tmp_168[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_166[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_168[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'('")); } { // '{' @@ -35509,18 +35656,18 @@ _tmp_166_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c> _tmp_168[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' ) { - D(fprintf(stderr, "%*c+ _tmp_166[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c+ _tmp_168[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_166[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_168[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'")); } _res = NULL; @@ -35529,9 +35676,9 @@ _tmp_166_rule(Parser *p) return _res; } -// _tmp_167: '[' | '{' +// _tmp_169: '[' | '{' static void * -_tmp_167_rule(Parser *p) +_tmp_169_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35547,18 +35694,18 @@ _tmp_167_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_167[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c> _tmp_169[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 9)) // token='[' ) { - D(fprintf(stderr, "%*c+ _tmp_167[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c+ _tmp_169[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_167[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_169[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['")); } { // '{' @@ -35566,18 +35713,18 @@ _tmp_167_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_167[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c> _tmp_169[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' ) { - D(fprintf(stderr, "%*c+ _tmp_167[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c+ _tmp_169[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_167[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_169[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'")); } _res = NULL; @@ -35586,9 +35733,9 @@ _tmp_167_rule(Parser *p) return _res; } -// _tmp_168: '[' | '{' +// _tmp_170: '[' | '{' static void * -_tmp_168_rule(Parser *p) +_tmp_170_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35604,18 +35751,18 @@ _tmp_168_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_168[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c> _tmp_170[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 9)) // token='[' ) { - D(fprintf(stderr, "%*c+ _tmp_168[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c+ _tmp_170[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_168[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_170[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['")); } { // '{' @@ -35623,18 +35770,18 @@ _tmp_168_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_168[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c> _tmp_170[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' ) { - D(fprintf(stderr, "%*c+ _tmp_168[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c+ _tmp_170[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_168[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_170[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'")); } _res = NULL; @@ -35643,9 +35790,9 @@ _tmp_168_rule(Parser *p) return _res; } -// _tmp_169: slash_no_default | slash_with_default +// _tmp_171: slash_no_default | slash_with_default static void * -_tmp_169_rule(Parser *p) +_tmp_171_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35661,18 +35808,18 @@ _tmp_169_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_169[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default")); + D(fprintf(stderr, "%*c> _tmp_171[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default")); asdl_arg_seq* slash_no_default_var; if ( (slash_no_default_var = slash_no_default_rule(p)) // slash_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_169[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default")); + D(fprintf(stderr, "%*c+ _tmp_171[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default")); _res = slash_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_169[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_171[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_no_default")); } { // slash_with_default @@ -35680,18 +35827,18 @@ _tmp_169_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_169[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + D(fprintf(stderr, "%*c> _tmp_171[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); SlashWithDefault* slash_with_default_var; if ( (slash_with_default_var = slash_with_default_rule(p)) // slash_with_default ) { - D(fprintf(stderr, "%*c+ _tmp_169[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + D(fprintf(stderr, "%*c+ _tmp_171[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); _res = slash_with_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_169[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_171[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_with_default")); } _res = NULL; @@ -35700,9 +35847,9 @@ _tmp_169_rule(Parser *p) return _res; } -// _loop0_170: param_maybe_default +// _loop0_172: param_maybe_default static asdl_seq * -_loop0_170_rule(Parser *p) +_loop0_172_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35727,7 +35874,7 @@ _loop0_170_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_170[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_172[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); NameDefaultPair* param_maybe_default_var; while ( (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default @@ -35750,7 +35897,7 @@ _loop0_170_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_170[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_172[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -35767,9 +35914,9 @@ _loop0_170_rule(Parser *p) return _seq; } -// _loop0_171: param_no_default +// _loop0_173: param_no_default static asdl_seq * -_loop0_171_rule(Parser *p) +_loop0_173_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35794,7 +35941,7 @@ _loop0_171_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_171[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _loop0_173[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); arg_ty param_no_default_var; while ( (param_no_default_var = param_no_default_rule(p)) // param_no_default @@ -35817,7 +35964,7 @@ _loop0_171_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_171[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_173[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -35834,9 +35981,9 @@ _loop0_171_rule(Parser *p) return _seq; } -// _loop0_172: param_no_default +// _loop0_174: param_no_default static asdl_seq * -_loop0_172_rule(Parser *p) +_loop0_174_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35861,7 +36008,7 @@ _loop0_172_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_172[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _loop0_174[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); arg_ty param_no_default_var; while ( (param_no_default_var = param_no_default_rule(p)) // param_no_default @@ -35884,7 +36031,7 @@ _loop0_172_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_172[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_174[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -35901,9 +36048,9 @@ _loop0_172_rule(Parser *p) return _seq; } -// _loop1_173: param_no_default +// _loop1_175: param_no_default static asdl_seq * -_loop1_173_rule(Parser *p) +_loop1_175_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35928,7 +36075,7 @@ _loop1_173_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_173[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _loop1_175[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); arg_ty param_no_default_var; while ( (param_no_default_var = param_no_default_rule(p)) // param_no_default @@ -35951,7 +36098,7 @@ _loop1_173_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_173[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_175[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } if (_n == 0 || p->error_indicator) { @@ -35973,9 +36120,9 @@ _loop1_173_rule(Parser *p) return _seq; } -// _tmp_174: slash_no_default | slash_with_default +// _tmp_176: slash_no_default | slash_with_default static void * -_tmp_174_rule(Parser *p) +_tmp_176_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35991,18 +36138,18 @@ _tmp_174_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_174[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default")); + D(fprintf(stderr, "%*c> _tmp_176[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default")); asdl_arg_seq* slash_no_default_var; if ( (slash_no_default_var = slash_no_default_rule(p)) // slash_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_174[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default")); + D(fprintf(stderr, "%*c+ _tmp_176[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default")); _res = slash_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_174[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_176[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_no_default")); } { // slash_with_default @@ -36010,18 +36157,18 @@ _tmp_174_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_174[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + D(fprintf(stderr, "%*c> _tmp_176[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); SlashWithDefault* slash_with_default_var; if ( (slash_with_default_var = slash_with_default_rule(p)) // slash_with_default ) { - D(fprintf(stderr, "%*c+ _tmp_174[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + D(fprintf(stderr, "%*c+ _tmp_176[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); _res = slash_with_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_174[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_176[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_with_default")); } _res = NULL; @@ -36030,9 +36177,9 @@ _tmp_174_rule(Parser *p) return _res; } -// _loop0_175: param_maybe_default +// _loop0_177: param_maybe_default static asdl_seq * -_loop0_175_rule(Parser *p) +_loop0_177_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36057,7 +36204,7 @@ _loop0_175_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_175[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_177[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); NameDefaultPair* param_maybe_default_var; while ( (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default @@ -36080,7 +36227,7 @@ _loop0_175_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_175[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_177[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -36097,9 +36244,9 @@ _loop0_175_rule(Parser *p) return _seq; } -// _tmp_176: ',' | param_no_default +// _tmp_178: ',' | param_no_default static void * -_tmp_176_rule(Parser *p) +_tmp_178_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36115,18 +36262,18 @@ _tmp_176_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_176[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_178[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_176[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_178[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_176[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_178[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } { // param_no_default @@ -36134,18 +36281,18 @@ _tmp_176_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_176[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _tmp_178[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); arg_ty param_no_default_var; if ( (param_no_default_var = param_no_default_rule(p)) // param_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_176[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c+ _tmp_178[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); _res = param_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_176[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_178[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } _res = NULL; @@ -36154,9 +36301,9 @@ _tmp_176_rule(Parser *p) return _res; } -// _loop0_177: param_maybe_default +// _loop0_179: param_maybe_default static asdl_seq * -_loop0_177_rule(Parser *p) +_loop0_179_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36181,7 +36328,7 @@ _loop0_177_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_177[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_179[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); NameDefaultPair* param_maybe_default_var; while ( (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default @@ -36204,7 +36351,7 @@ _loop0_177_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_177[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_179[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -36221,9 +36368,9 @@ _loop0_177_rule(Parser *p) return _seq; } -// _loop1_178: param_maybe_default +// _loop1_180: param_maybe_default static asdl_seq * -_loop1_178_rule(Parser *p) +_loop1_180_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36248,7 +36395,7 @@ _loop1_178_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_178[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c> _loop1_180[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); NameDefaultPair* param_maybe_default_var; while ( (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default @@ -36271,7 +36418,7 @@ _loop1_178_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_178[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_180[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); } if (_n == 0 || p->error_indicator) { @@ -36293,9 +36440,9 @@ _loop1_178_rule(Parser *p) return _seq; } -// _tmp_179: ')' | ',' +// _tmp_181: ')' | ',' static void * -_tmp_179_rule(Parser *p) +_tmp_181_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36311,18 +36458,18 @@ _tmp_179_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_179[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_181[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_179[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_181[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_179[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_181[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } { // ',' @@ -36330,18 +36477,18 @@ _tmp_179_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_179[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_181[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_179[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_181[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_179[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_181[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; @@ -36350,9 +36497,9 @@ _tmp_179_rule(Parser *p) return _res; } -// _tmp_180: ')' | ',' (')' | '**') +// _tmp_182: ')' | ',' (')' | '**') static void * -_tmp_180_rule(Parser *p) +_tmp_182_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36368,18 +36515,18 @@ _tmp_180_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_180[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_182[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_180[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_182[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_180[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_182[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } { // ',' (')' | '**') @@ -36387,21 +36534,21 @@ _tmp_180_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_180[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); + D(fprintf(stderr, "%*c> _tmp_182[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); Token * _literal; - void *_tmp_270_var; + void *_tmp_273_var; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_tmp_270_var = _tmp_270_rule(p)) // ')' | '**' + (_tmp_273_var = _tmp_273_rule(p)) // ')' | '**' ) { - D(fprintf(stderr, "%*c+ _tmp_180[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); - _res = _PyPegen_dummy_name(p, _literal, _tmp_270_var); + D(fprintf(stderr, "%*c+ _tmp_182[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); + _res = _PyPegen_dummy_name(p, _literal, _tmp_273_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_180[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_182[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (')' | '**')")); } _res = NULL; @@ -36410,9 +36557,9 @@ _tmp_180_rule(Parser *p) return _res; } -// _tmp_181: param_no_default | ',' +// _tmp_183: param_no_default | ',' static void * -_tmp_181_rule(Parser *p) +_tmp_183_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36428,18 +36575,18 @@ _tmp_181_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_181[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _tmp_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); arg_ty param_no_default_var; if ( (param_no_default_var = param_no_default_rule(p)) // param_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_181[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c+ _tmp_183[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); _res = param_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_181[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_183[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } { // ',' @@ -36447,18 +36594,18 @@ _tmp_181_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_181[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_181[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_183[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_181[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_183[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; @@ -36467,9 +36614,9 @@ _tmp_181_rule(Parser *p) return _res; } -// _loop0_182: param_maybe_default +// _loop0_184: param_maybe_default static asdl_seq * -_loop0_182_rule(Parser *p) +_loop0_184_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36494,7 +36641,7 @@ _loop0_182_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_182[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_184[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); NameDefaultPair* param_maybe_default_var; while ( (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default @@ -36517,7 +36664,7 @@ _loop0_182_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_182[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_184[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -36534,9 +36681,9 @@ _loop0_182_rule(Parser *p) return _seq; } -// _tmp_183: param_no_default | ',' +// _tmp_185: param_no_default | ',' static void * -_tmp_183_rule(Parser *p) +_tmp_185_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36552,18 +36699,18 @@ _tmp_183_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _tmp_185[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); arg_ty param_no_default_var; if ( (param_no_default_var = param_no_default_rule(p)) // param_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_183[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c+ _tmp_185[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); _res = param_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_183[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_185[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } { // ',' @@ -36571,18 +36718,18 @@ _tmp_183_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_185[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_183[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_185[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_183[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_185[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; @@ -36591,9 +36738,9 @@ _tmp_183_rule(Parser *p) return _res; } -// _tmp_184: '*' | '**' | '/' +// _tmp_186: '*' | '**' | '/' static void * -_tmp_184_rule(Parser *p) +_tmp_186_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36609,18 +36756,18 @@ _tmp_184_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_184[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); + D(fprintf(stderr, "%*c> _tmp_186[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' ) { - D(fprintf(stderr, "%*c+ _tmp_184[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); + D(fprintf(stderr, "%*c+ _tmp_186[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_184[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_186[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*'")); } { // '**' @@ -36628,18 +36775,18 @@ _tmp_184_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_184[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c> _tmp_186[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_184[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c+ _tmp_186[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_184[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_186[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } { // '/' @@ -36647,18 +36794,18 @@ _tmp_184_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_184[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'")); + D(fprintf(stderr, "%*c> _tmp_186[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 17)) // token='/' ) { - D(fprintf(stderr, "%*c+ _tmp_184[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'")); + D(fprintf(stderr, "%*c+ _tmp_186[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_184[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_186[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'/'")); } _res = NULL; @@ -36667,9 +36814,9 @@ _tmp_184_rule(Parser *p) return _res; } -// _loop1_185: param_with_default +// _loop1_187: param_with_default static asdl_seq * -_loop1_185_rule(Parser *p) +_loop1_187_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36694,7 +36841,7 @@ _loop1_185_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_185[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); + D(fprintf(stderr, "%*c> _loop1_187[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); NameDefaultPair* param_with_default_var; while ( (param_with_default_var = param_with_default_rule(p)) // param_with_default @@ -36717,7 +36864,7 @@ _loop1_185_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_185[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_187[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); } if (_n == 0 || p->error_indicator) { @@ -36739,9 +36886,9 @@ _loop1_185_rule(Parser *p) return _seq; } -// _tmp_186: lambda_slash_no_default | lambda_slash_with_default +// _tmp_188: lambda_slash_no_default | lambda_slash_with_default static void * -_tmp_186_rule(Parser *p) +_tmp_188_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36757,18 +36904,18 @@ _tmp_186_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_186[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + D(fprintf(stderr, "%*c> _tmp_188[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); asdl_arg_seq* lambda_slash_no_default_var; if ( (lambda_slash_no_default_var = lambda_slash_no_default_rule(p)) // lambda_slash_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_186[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + D(fprintf(stderr, "%*c+ _tmp_188[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); _res = lambda_slash_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_186[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_188[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_no_default")); } { // lambda_slash_with_default @@ -36776,18 +36923,18 @@ _tmp_186_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_186[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + D(fprintf(stderr, "%*c> _tmp_188[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); SlashWithDefault* lambda_slash_with_default_var; if ( (lambda_slash_with_default_var = lambda_slash_with_default_rule(p)) // lambda_slash_with_default ) { - D(fprintf(stderr, "%*c+ _tmp_186[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + D(fprintf(stderr, "%*c+ _tmp_188[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); _res = lambda_slash_with_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_186[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_188[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_with_default")); } _res = NULL; @@ -36796,9 +36943,9 @@ _tmp_186_rule(Parser *p) return _res; } -// _loop0_187: lambda_param_maybe_default +// _loop0_189: lambda_param_maybe_default static asdl_seq * -_loop0_187_rule(Parser *p) +_loop0_189_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36823,7 +36970,7 @@ _loop0_187_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_187[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_189[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); NameDefaultPair* lambda_param_maybe_default_var; while ( (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default @@ -36846,7 +36993,7 @@ _loop0_187_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_187[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_189[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -36863,9 +37010,9 @@ _loop0_187_rule(Parser *p) return _seq; } -// _loop0_188: lambda_param_no_default +// _loop0_190: lambda_param_no_default static asdl_seq * -_loop0_188_rule(Parser *p) +_loop0_190_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36890,7 +37037,7 @@ _loop0_188_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_188[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _loop0_190[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; while ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default @@ -36913,7 +37060,7 @@ _loop0_188_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_188[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_190[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -36930,9 +37077,9 @@ _loop0_188_rule(Parser *p) return _seq; } -// _loop0_189: lambda_param_no_default +// _loop0_191: lambda_param_no_default static asdl_seq * -_loop0_189_rule(Parser *p) +_loop0_191_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36957,7 +37104,7 @@ _loop0_189_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_189[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _loop0_191[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; while ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default @@ -36980,7 +37127,7 @@ _loop0_189_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_189[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_191[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -36997,9 +37144,9 @@ _loop0_189_rule(Parser *p) return _seq; } -// _loop0_191: ',' lambda_param +// _loop0_193: ',' lambda_param static asdl_seq * -_loop0_191_rule(Parser *p) +_loop0_193_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37024,7 +37171,7 @@ _loop0_191_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_191[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' lambda_param")); + D(fprintf(stderr, "%*c> _loop0_193[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' lambda_param")); Token * _literal; arg_ty elem; while ( @@ -37056,7 +37203,7 @@ _loop0_191_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_191[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_193[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' lambda_param")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -37073,9 +37220,9 @@ _loop0_191_rule(Parser *p) return _seq; } -// _gather_190: lambda_param _loop0_191 +// _gather_192: lambda_param _loop0_193 static asdl_seq * -_gather_190_rule(Parser *p) +_gather_192_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37086,27 +37233,27 @@ _gather_190_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // lambda_param _loop0_191 + { // lambda_param _loop0_193 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_190[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_191")); + D(fprintf(stderr, "%*c> _gather_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_193")); arg_ty elem; asdl_seq * seq; if ( (elem = lambda_param_rule(p)) // lambda_param && - (seq = _loop0_191_rule(p)) // _loop0_191 + (seq = _loop0_193_rule(p)) // _loop0_193 ) { - D(fprintf(stderr, "%*c+ _gather_190[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_191")); + D(fprintf(stderr, "%*c+ _gather_192[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_193")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_190[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param _loop0_191")); + D(fprintf(stderr, "%*c%s _gather_192[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param _loop0_193")); } _res = NULL; done: @@ -37114,9 +37261,9 @@ _gather_190_rule(Parser *p) return _res; } -// _tmp_192: lambda_slash_no_default | lambda_slash_with_default +// _tmp_194: lambda_slash_no_default | lambda_slash_with_default static void * -_tmp_192_rule(Parser *p) +_tmp_194_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37132,18 +37279,18 @@ _tmp_192_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + D(fprintf(stderr, "%*c> _tmp_194[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); asdl_arg_seq* lambda_slash_no_default_var; if ( (lambda_slash_no_default_var = lambda_slash_no_default_rule(p)) // lambda_slash_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_192[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + D(fprintf(stderr, "%*c+ _tmp_194[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); _res = lambda_slash_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_192[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_194[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_no_default")); } { // lambda_slash_with_default @@ -37151,18 +37298,18 @@ _tmp_192_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + D(fprintf(stderr, "%*c> _tmp_194[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); SlashWithDefault* lambda_slash_with_default_var; if ( (lambda_slash_with_default_var = lambda_slash_with_default_rule(p)) // lambda_slash_with_default ) { - D(fprintf(stderr, "%*c+ _tmp_192[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + D(fprintf(stderr, "%*c+ _tmp_194[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); _res = lambda_slash_with_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_192[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_194[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_with_default")); } _res = NULL; @@ -37171,9 +37318,9 @@ _tmp_192_rule(Parser *p) return _res; } -// _loop0_193: lambda_param_maybe_default +// _loop0_195: lambda_param_maybe_default static asdl_seq * -_loop0_193_rule(Parser *p) +_loop0_195_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37198,7 +37345,7 @@ _loop0_193_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_193[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_195[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); NameDefaultPair* lambda_param_maybe_default_var; while ( (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default @@ -37221,7 +37368,7 @@ _loop0_193_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_193[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_195[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -37238,9 +37385,9 @@ _loop0_193_rule(Parser *p) return _seq; } -// _tmp_194: ',' | lambda_param_no_default +// _tmp_196: ',' | lambda_param_no_default static void * -_tmp_194_rule(Parser *p) +_tmp_196_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37256,18 +37403,18 @@ _tmp_194_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_194[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_196[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_194[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_196[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_194[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_196[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } { // lambda_param_no_default @@ -37275,18 +37422,18 @@ _tmp_194_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_194[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _tmp_196[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; if ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_194[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c+ _tmp_196[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); _res = lambda_param_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_194[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_196[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } _res = NULL; @@ -37295,9 +37442,9 @@ _tmp_194_rule(Parser *p) return _res; } -// _loop0_195: lambda_param_maybe_default +// _loop0_197: lambda_param_maybe_default static asdl_seq * -_loop0_195_rule(Parser *p) +_loop0_197_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37322,7 +37469,7 @@ _loop0_195_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_195[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_197[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); NameDefaultPair* lambda_param_maybe_default_var; while ( (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default @@ -37345,7 +37492,7 @@ _loop0_195_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_195[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_197[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -37362,9 +37509,9 @@ _loop0_195_rule(Parser *p) return _seq; } -// _loop1_196: lambda_param_maybe_default +// _loop1_198: lambda_param_maybe_default static asdl_seq * -_loop1_196_rule(Parser *p) +_loop1_198_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37389,7 +37536,7 @@ _loop1_196_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_196[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + D(fprintf(stderr, "%*c> _loop1_198[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); NameDefaultPair* lambda_param_maybe_default_var; while ( (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default @@ -37412,7 +37559,7 @@ _loop1_196_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_196[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_198[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } if (_n == 0 || p->error_indicator) { @@ -37434,9 +37581,9 @@ _loop1_196_rule(Parser *p) return _seq; } -// _loop1_197: lambda_param_with_default +// _loop1_199: lambda_param_with_default static asdl_seq * -_loop1_197_rule(Parser *p) +_loop1_199_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37461,7 +37608,7 @@ _loop1_197_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_197[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + D(fprintf(stderr, "%*c> _loop1_199[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); NameDefaultPair* lambda_param_with_default_var; while ( (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default @@ -37484,7 +37631,7 @@ _loop1_197_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_197[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_199[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); } if (_n == 0 || p->error_indicator) { @@ -37506,9 +37653,9 @@ _loop1_197_rule(Parser *p) return _seq; } -// _tmp_198: ':' | ',' (':' | '**') +// _tmp_200: ':' | ',' (':' | '**') static void * -_tmp_198_rule(Parser *p) +_tmp_200_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37524,18 +37671,18 @@ _tmp_198_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_198[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_200[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_198[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_200[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_198[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_200[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } { // ',' (':' | '**') @@ -37543,21 +37690,21 @@ _tmp_198_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_198[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); + D(fprintf(stderr, "%*c> _tmp_200[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); Token * _literal; - void *_tmp_271_var; + void *_tmp_274_var; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_tmp_271_var = _tmp_271_rule(p)) // ':' | '**' + (_tmp_274_var = _tmp_274_rule(p)) // ':' | '**' ) { - D(fprintf(stderr, "%*c+ _tmp_198[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); - _res = _PyPegen_dummy_name(p, _literal, _tmp_271_var); + D(fprintf(stderr, "%*c+ _tmp_200[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); + _res = _PyPegen_dummy_name(p, _literal, _tmp_274_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_198[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_200[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (':' | '**')")); } _res = NULL; @@ -37566,9 +37713,9 @@ _tmp_198_rule(Parser *p) return _res; } -// _tmp_199: lambda_param_no_default | ',' +// _tmp_201: lambda_param_no_default | ',' static void * -_tmp_199_rule(Parser *p) +_tmp_201_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37584,18 +37731,18 @@ _tmp_199_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_199[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _tmp_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; if ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_199[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c+ _tmp_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); _res = lambda_param_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_199[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_201[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } { // ',' @@ -37603,18 +37750,18 @@ _tmp_199_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_199[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_199[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_199[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_201[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; @@ -37623,9 +37770,9 @@ _tmp_199_rule(Parser *p) return _res; } -// _loop0_200: lambda_param_maybe_default +// _loop0_202: lambda_param_maybe_default static asdl_seq * -_loop0_200_rule(Parser *p) +_loop0_202_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37650,7 +37797,7 @@ _loop0_200_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_200[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_202[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); NameDefaultPair* lambda_param_maybe_default_var; while ( (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default @@ -37673,7 +37820,7 @@ _loop0_200_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_200[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_202[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -37690,9 +37837,9 @@ _loop0_200_rule(Parser *p) return _seq; } -// _tmp_201: lambda_param_no_default | ',' +// _tmp_203: lambda_param_no_default | ',' static void * -_tmp_201_rule(Parser *p) +_tmp_203_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37708,18 +37855,18 @@ _tmp_201_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _tmp_203[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; if ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c+ _tmp_203[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); _res = lambda_param_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_201[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_203[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } { // ',' @@ -37727,18 +37874,18 @@ _tmp_201_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_203[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_203[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_201[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_203[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; @@ -37747,9 +37894,9 @@ _tmp_201_rule(Parser *p) return _res; } -// _tmp_202: '*' | '**' | '/' +// _tmp_204: '*' | '**' | '/' static void * -_tmp_202_rule(Parser *p) +_tmp_204_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37765,18 +37912,18 @@ _tmp_202_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_202[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); + D(fprintf(stderr, "%*c> _tmp_204[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' ) { - D(fprintf(stderr, "%*c+ _tmp_202[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); + D(fprintf(stderr, "%*c+ _tmp_204[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_202[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_204[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*'")); } { // '**' @@ -37784,18 +37931,18 @@ _tmp_202_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_202[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c> _tmp_204[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_202[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c+ _tmp_204[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_202[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_204[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } { // '/' @@ -37803,18 +37950,18 @@ _tmp_202_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_202[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'")); + D(fprintf(stderr, "%*c> _tmp_204[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 17)) // token='/' ) { - D(fprintf(stderr, "%*c+ _tmp_202[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'")); + D(fprintf(stderr, "%*c+ _tmp_204[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_202[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_204[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'/'")); } _res = NULL; @@ -37823,9 +37970,9 @@ _tmp_202_rule(Parser *p) return _res; } -// _tmp_203: ',' | ')' | ':' +// _tmp_205: ',' | ')' | ':' static void * -_tmp_203_rule(Parser *p) +_tmp_205_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37841,18 +37988,18 @@ _tmp_203_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_203[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_205[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_203[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_205[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_203[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_205[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } { // ')' @@ -37860,18 +38007,18 @@ _tmp_203_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_203[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_205[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_203[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_205[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_203[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_205[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } { // ':' @@ -37879,18 +38026,18 @@ _tmp_203_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_203[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_205[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_203[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_205[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_203[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_205[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } _res = NULL; @@ -37899,9 +38046,9 @@ _tmp_203_rule(Parser *p) return _res; } -// _loop0_205: ',' dotted_name +// _loop0_207: ',' dotted_name static asdl_seq * -_loop0_205_rule(Parser *p) +_loop0_207_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37926,7 +38073,7 @@ _loop0_205_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_205[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' dotted_name")); + D(fprintf(stderr, "%*c> _loop0_207[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' dotted_name")); Token * _literal; expr_ty elem; while ( @@ -37958,7 +38105,7 @@ _loop0_205_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_205[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_207[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' dotted_name")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -37975,9 +38122,9 @@ _loop0_205_rule(Parser *p) return _seq; } -// _gather_204: dotted_name _loop0_205 +// _gather_206: dotted_name _loop0_207 static asdl_seq * -_gather_204_rule(Parser *p) +_gather_206_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37988,27 +38135,27 @@ _gather_204_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // dotted_name _loop0_205 + { // dotted_name _loop0_207 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_204[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dotted_name _loop0_205")); + D(fprintf(stderr, "%*c> _gather_206[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dotted_name _loop0_207")); expr_ty elem; asdl_seq * seq; if ( (elem = dotted_name_rule(p)) // dotted_name && - (seq = _loop0_205_rule(p)) // _loop0_205 + (seq = _loop0_207_rule(p)) // _loop0_207 ) { - D(fprintf(stderr, "%*c+ _gather_204[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dotted_name _loop0_205")); + D(fprintf(stderr, "%*c+ _gather_206[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dotted_name _loop0_207")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_204[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dotted_name _loop0_205")); + D(fprintf(stderr, "%*c%s _gather_206[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dotted_name _loop0_207")); } _res = NULL; done: @@ -38016,9 +38163,9 @@ _gather_204_rule(Parser *p) return _res; } -// _loop0_207: ',' (expression ['as' star_target]) +// _loop0_209: ',' (expression ['as' star_target]) static asdl_seq * -_loop0_207_rule(Parser *p) +_loop0_209_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38043,13 +38190,13 @@ _loop0_207_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_207[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); + D(fprintf(stderr, "%*c> _loop0_209[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); Token * _literal; void *elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_272_rule(p)) // expression ['as' star_target] + (elem = _tmp_275_rule(p)) // expression ['as' star_target] ) { _res = elem; @@ -38075,7 +38222,7 @@ _loop0_207_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_207[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_209[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expression ['as' star_target])")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -38092,9 +38239,9 @@ _loop0_207_rule(Parser *p) return _seq; } -// _gather_206: (expression ['as' star_target]) _loop0_207 +// _gather_208: (expression ['as' star_target]) _loop0_209 static asdl_seq * -_gather_206_rule(Parser *p) +_gather_208_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38105,27 +38252,27 @@ _gather_206_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // (expression ['as' star_target]) _loop0_207 + { // (expression ['as' star_target]) _loop0_209 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_206[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_207")); + D(fprintf(stderr, "%*c> _gather_208[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_209")); void *elem; asdl_seq * seq; if ( - (elem = _tmp_272_rule(p)) // expression ['as' star_target] + (elem = _tmp_275_rule(p)) // expression ['as' star_target] && - (seq = _loop0_207_rule(p)) // _loop0_207 + (seq = _loop0_209_rule(p)) // _loop0_209 ) { - D(fprintf(stderr, "%*c+ _gather_206[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_207")); + D(fprintf(stderr, "%*c+ _gather_208[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_209")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_206[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_207")); + D(fprintf(stderr, "%*c%s _gather_208[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_209")); } _res = NULL; done: @@ -38133,9 +38280,9 @@ _gather_206_rule(Parser *p) return _res; } -// _loop0_209: ',' (expressions ['as' star_target]) +// _loop0_211: ',' (expressions ['as' star_target]) static asdl_seq * -_loop0_209_rule(Parser *p) +_loop0_211_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38160,13 +38307,13 @@ _loop0_209_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_209[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); + D(fprintf(stderr, "%*c> _loop0_211[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); Token * _literal; void *elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_273_rule(p)) // expressions ['as' star_target] + (elem = _tmp_276_rule(p)) // expressions ['as' star_target] ) { _res = elem; @@ -38192,7 +38339,7 @@ _loop0_209_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_209[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_211[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expressions ['as' star_target])")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -38209,9 +38356,9 @@ _loop0_209_rule(Parser *p) return _seq; } -// _gather_208: (expressions ['as' star_target]) _loop0_209 +// _gather_210: (expressions ['as' star_target]) _loop0_211 static asdl_seq * -_gather_208_rule(Parser *p) +_gather_210_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38222,27 +38369,27 @@ _gather_208_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // (expressions ['as' star_target]) _loop0_209 + { // (expressions ['as' star_target]) _loop0_211 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_208[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_209")); + D(fprintf(stderr, "%*c> _gather_210[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_211")); void *elem; asdl_seq * seq; if ( - (elem = _tmp_273_rule(p)) // expressions ['as' star_target] + (elem = _tmp_276_rule(p)) // expressions ['as' star_target] && - (seq = _loop0_209_rule(p)) // _loop0_209 + (seq = _loop0_211_rule(p)) // _loop0_211 ) { - D(fprintf(stderr, "%*c+ _gather_208[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_209")); + D(fprintf(stderr, "%*c+ _gather_210[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_211")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_208[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_209")); + D(fprintf(stderr, "%*c%s _gather_210[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_211")); } _res = NULL; done: @@ -38250,9 +38397,9 @@ _gather_208_rule(Parser *p) return _res; } -// _loop0_211: ',' (expression ['as' star_target]) +// _loop0_213: ',' (expression ['as' star_target]) static asdl_seq * -_loop0_211_rule(Parser *p) +_loop0_213_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38277,13 +38424,13 @@ _loop0_211_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_211[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); + D(fprintf(stderr, "%*c> _loop0_213[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); Token * _literal; void *elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_274_rule(p)) // expression ['as' star_target] + (elem = _tmp_277_rule(p)) // expression ['as' star_target] ) { _res = elem; @@ -38309,7 +38456,7 @@ _loop0_211_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_211[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_213[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expression ['as' star_target])")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -38326,9 +38473,9 @@ _loop0_211_rule(Parser *p) return _seq; } -// _gather_210: (expression ['as' star_target]) _loop0_211 +// _gather_212: (expression ['as' star_target]) _loop0_213 static asdl_seq * -_gather_210_rule(Parser *p) +_gather_212_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38339,27 +38486,27 @@ _gather_210_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // (expression ['as' star_target]) _loop0_211 + { // (expression ['as' star_target]) _loop0_213 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_210[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_211")); + D(fprintf(stderr, "%*c> _gather_212[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_213")); void *elem; asdl_seq * seq; if ( - (elem = _tmp_274_rule(p)) // expression ['as' star_target] + (elem = _tmp_277_rule(p)) // expression ['as' star_target] && - (seq = _loop0_211_rule(p)) // _loop0_211 + (seq = _loop0_213_rule(p)) // _loop0_213 ) { - D(fprintf(stderr, "%*c+ _gather_210[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_211")); + D(fprintf(stderr, "%*c+ _gather_212[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_213")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_210[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_211")); + D(fprintf(stderr, "%*c%s _gather_212[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_213")); } _res = NULL; done: @@ -38367,9 +38514,9 @@ _gather_210_rule(Parser *p) return _res; } -// _loop0_213: ',' (expressions ['as' star_target]) +// _loop0_215: ',' (expressions ['as' star_target]) static asdl_seq * -_loop0_213_rule(Parser *p) +_loop0_215_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38394,13 +38541,13 @@ _loop0_213_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_213[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); + D(fprintf(stderr, "%*c> _loop0_215[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); Token * _literal; void *elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_275_rule(p)) // expressions ['as' star_target] + (elem = _tmp_278_rule(p)) // expressions ['as' star_target] ) { _res = elem; @@ -38426,7 +38573,7 @@ _loop0_213_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_213[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_215[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expressions ['as' star_target])")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -38443,9 +38590,9 @@ _loop0_213_rule(Parser *p) return _seq; } -// _gather_212: (expressions ['as' star_target]) _loop0_213 +// _gather_214: (expressions ['as' star_target]) _loop0_215 static asdl_seq * -_gather_212_rule(Parser *p) +_gather_214_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38456,27 +38603,27 @@ _gather_212_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // (expressions ['as' star_target]) _loop0_213 + { // (expressions ['as' star_target]) _loop0_215 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_212[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_213")); + D(fprintf(stderr, "%*c> _gather_214[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_215")); void *elem; asdl_seq * seq; if ( - (elem = _tmp_275_rule(p)) // expressions ['as' star_target] + (elem = _tmp_278_rule(p)) // expressions ['as' star_target] && - (seq = _loop0_213_rule(p)) // _loop0_213 + (seq = _loop0_215_rule(p)) // _loop0_215 ) { - D(fprintf(stderr, "%*c+ _gather_212[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_213")); + D(fprintf(stderr, "%*c+ _gather_214[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_215")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_212[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_213")); + D(fprintf(stderr, "%*c%s _gather_214[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_215")); } _res = NULL; done: @@ -38484,9 +38631,9 @@ _gather_212_rule(Parser *p) return _res; } -// _tmp_214: 'except' | 'finally' +// _tmp_216: 'except' | 'finally' static void * -_tmp_214_rule(Parser *p) +_tmp_216_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38502,18 +38649,18 @@ _tmp_214_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_214[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except'")); + D(fprintf(stderr, "%*c> _tmp_216[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except'")); Token * _keyword; if ( (_keyword = _PyPegen_expect_token(p, 656)) // token='except' ) { - D(fprintf(stderr, "%*c+ _tmp_214[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except'")); + D(fprintf(stderr, "%*c+ _tmp_216[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_214[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_216[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'except'")); } { // 'finally' @@ -38521,18 +38668,18 @@ _tmp_214_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_214[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'finally'")); + D(fprintf(stderr, "%*c> _tmp_216[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'finally'")); Token * _keyword; if ( (_keyword = _PyPegen_expect_token(p, 652)) // token='finally' ) { - D(fprintf(stderr, "%*c+ _tmp_214[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'finally'")); + D(fprintf(stderr, "%*c+ _tmp_216[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'finally'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_214[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_216[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'finally'")); } _res = NULL; @@ -38541,9 +38688,9 @@ _tmp_214_rule(Parser *p) return _res; } -// _loop0_215: block +// _loop0_217: block static asdl_seq * -_loop0_215_rule(Parser *p) +_loop0_217_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38568,7 +38715,7 @@ _loop0_215_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_215[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block")); + D(fprintf(stderr, "%*c> _loop0_217[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block")); asdl_stmt_seq* block_var; while ( (block_var = block_rule(p)) // block @@ -38591,7 +38738,7 @@ _loop0_215_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_215[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_217[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "block")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -38608,9 +38755,9 @@ _loop0_215_rule(Parser *p) return _seq; } -// _loop1_216: except_block +// _loop1_218: except_block static asdl_seq * -_loop1_216_rule(Parser *p) +_loop1_218_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38635,7 +38782,7 @@ _loop1_216_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_216[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_block")); + D(fprintf(stderr, "%*c> _loop1_218[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_block")); excepthandler_ty except_block_var; while ( (except_block_var = except_block_rule(p)) // except_block @@ -38658,7 +38805,7 @@ _loop1_216_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_216[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_218[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_block")); } if (_n == 0 || p->error_indicator) { @@ -38680,9 +38827,9 @@ _loop1_216_rule(Parser *p) return _seq; } -// _tmp_217: 'as' NAME +// _tmp_219: 'as' NAME static void * -_tmp_217_rule(Parser *p) +_tmp_219_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38698,7 +38845,7 @@ _tmp_217_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_217[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_219[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty name_var; if ( @@ -38707,12 +38854,12 @@ _tmp_217_rule(Parser *p) (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_217[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_219[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = _PyPegen_dummy_name(p, _keyword, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_217[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_219[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -38721,9 +38868,9 @@ _tmp_217_rule(Parser *p) return _res; } -// _loop0_218: block +// _loop0_220: block static asdl_seq * -_loop0_218_rule(Parser *p) +_loop0_220_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38748,7 +38895,7 @@ _loop0_218_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_218[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block")); + D(fprintf(stderr, "%*c> _loop0_220[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block")); asdl_stmt_seq* block_var; while ( (block_var = block_rule(p)) // block @@ -38771,7 +38918,7 @@ _loop0_218_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_218[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_220[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "block")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -38788,9 +38935,9 @@ _loop0_218_rule(Parser *p) return _seq; } -// _loop1_219: except_star_block +// _loop1_221: except_star_block static asdl_seq * -_loop1_219_rule(Parser *p) +_loop1_221_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38815,7 +38962,7 @@ _loop1_219_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_219[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_star_block")); + D(fprintf(stderr, "%*c> _loop1_221[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_star_block")); excepthandler_ty except_star_block_var; while ( (except_star_block_var = except_star_block_rule(p)) // except_star_block @@ -38838,7 +38985,7 @@ _loop1_219_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_219[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_221[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_star_block")); } if (_n == 0 || p->error_indicator) { @@ -38860,9 +39007,9 @@ _loop1_219_rule(Parser *p) return _seq; } -// _tmp_220: expression ['as' NAME] +// _tmp_222: expression ['as' NAME] static void * -_tmp_220_rule(Parser *p) +_tmp_222_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38878,22 +39025,22 @@ _tmp_220_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_220[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' NAME]")); + D(fprintf(stderr, "%*c> _tmp_222[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' NAME]")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings expr_ty expression_var; if ( (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_276_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var = _tmp_279_rule(p), !p->error_indicator) // ['as' NAME] ) { - D(fprintf(stderr, "%*c+ _tmp_220[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' NAME]")); + D(fprintf(stderr, "%*c+ _tmp_222[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' NAME]")); _res = _PyPegen_dummy_name(p, expression_var, _opt_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_220[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_222[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ['as' NAME]")); } _res = NULL; @@ -38902,9 +39049,9 @@ _tmp_220_rule(Parser *p) return _res; } -// _tmp_221: 'as' NAME +// _tmp_223: 'as' NAME static void * -_tmp_221_rule(Parser *p) +_tmp_223_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38920,7 +39067,7 @@ _tmp_221_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_221[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_223[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty name_var; if ( @@ -38929,12 +39076,12 @@ _tmp_221_rule(Parser *p) (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_221[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_223[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = _PyPegen_dummy_name(p, _keyword, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_221[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_223[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -38943,9 +39090,9 @@ _tmp_221_rule(Parser *p) return _res; } -// _tmp_222: 'as' NAME +// _tmp_224: 'as' NAME static void * -_tmp_222_rule(Parser *p) +_tmp_224_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38961,7 +39108,7 @@ _tmp_222_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_222[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_224[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty name_var; if ( @@ -38970,12 +39117,12 @@ _tmp_222_rule(Parser *p) (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_222[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_224[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = _PyPegen_dummy_name(p, _keyword, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_222[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_224[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -38984,9 +39131,9 @@ _tmp_222_rule(Parser *p) return _res; } -// _tmp_223: NEWLINE | ':' +// _tmp_225: NEWLINE | ':' static void * -_tmp_223_rule(Parser *p) +_tmp_225_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39002,18 +39149,18 @@ _tmp_223_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_223[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE")); + D(fprintf(stderr, "%*c> _tmp_225[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE")); Token * newline_var; if ( (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) { - D(fprintf(stderr, "%*c+ _tmp_223[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE")); + D(fprintf(stderr, "%*c+ _tmp_225[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE")); _res = newline_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_223[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_225[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE")); } { // ':' @@ -39021,18 +39168,18 @@ _tmp_223_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_223[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_225[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_223[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_225[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_223[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_225[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } _res = NULL; @@ -39041,9 +39188,9 @@ _tmp_223_rule(Parser *p) return _res; } -// _tmp_224: 'as' NAME +// _tmp_226: 'as' NAME static void * -_tmp_224_rule(Parser *p) +_tmp_226_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39059,7 +39206,7 @@ _tmp_224_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_224[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_226[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty name_var; if ( @@ -39068,12 +39215,12 @@ _tmp_224_rule(Parser *p) (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_224[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_226[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = _PyPegen_dummy_name(p, _keyword, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_224[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_226[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -39082,9 +39229,9 @@ _tmp_224_rule(Parser *p) return _res; } -// _tmp_225: 'as' NAME +// _tmp_227: 'as' NAME static void * -_tmp_225_rule(Parser *p) +_tmp_227_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39100,7 +39247,7 @@ _tmp_225_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_225[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_227[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty name_var; if ( @@ -39109,12 +39256,12 @@ _tmp_225_rule(Parser *p) (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_225[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_227[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = _PyPegen_dummy_name(p, _keyword, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_225[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_227[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -39123,9 +39270,9 @@ _tmp_225_rule(Parser *p) return _res; } -// _tmp_226: positional_patterns ',' +// _tmp_228: positional_patterns ',' static void * -_tmp_226_rule(Parser *p) +_tmp_228_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39141,7 +39288,7 @@ _tmp_226_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_226[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); + D(fprintf(stderr, "%*c> _tmp_228[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); Token * _literal; asdl_pattern_seq* positional_patterns_var; if ( @@ -39150,12 +39297,12 @@ _tmp_226_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_226[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); + D(fprintf(stderr, "%*c+ _tmp_228[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); _res = _PyPegen_dummy_name(p, positional_patterns_var, _literal); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_226[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_228[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "positional_patterns ','")); } _res = NULL; @@ -39164,9 +39311,9 @@ _tmp_226_rule(Parser *p) return _res; } -// _tmp_227: '->' expression +// _tmp_229: '->' expression static void * -_tmp_227_rule(Parser *p) +_tmp_229_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39182,7 +39329,7 @@ _tmp_227_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_227[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); + D(fprintf(stderr, "%*c> _tmp_229[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); Token * _literal; expr_ty expression_var; if ( @@ -39191,12 +39338,12 @@ _tmp_227_rule(Parser *p) (expression_var = expression_rule(p)) // expression ) { - D(fprintf(stderr, "%*c+ _tmp_227[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'->' expression")); + D(fprintf(stderr, "%*c+ _tmp_229[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'->' expression")); _res = _PyPegen_dummy_name(p, _literal, expression_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_227[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_229[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'->' expression")); } _res = NULL; @@ -39205,9 +39352,9 @@ _tmp_227_rule(Parser *p) return _res; } -// _tmp_228: '(' arguments? ')' +// _tmp_230: '(' arguments? ')' static void * -_tmp_228_rule(Parser *p) +_tmp_230_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39223,7 +39370,7 @@ _tmp_228_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_228[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + D(fprintf(stderr, "%*c> _tmp_230[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); Token * _literal; Token * _literal_1; void *_opt_var; @@ -39236,12 +39383,12 @@ _tmp_228_rule(Parser *p) (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_228[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + D(fprintf(stderr, "%*c+ _tmp_230[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); _res = _PyPegen_dummy_name(p, _literal, _opt_var, _literal_1); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_228[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_230[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' arguments? ')'")); } _res = NULL; @@ -39250,9 +39397,9 @@ _tmp_228_rule(Parser *p) return _res; } -// _tmp_229: '(' arguments? ')' +// _tmp_231: '(' arguments? ')' static void * -_tmp_229_rule(Parser *p) +_tmp_231_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39268,7 +39415,7 @@ _tmp_229_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_229[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + D(fprintf(stderr, "%*c> _tmp_231[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); Token * _literal; Token * _literal_1; void *_opt_var; @@ -39281,12 +39428,12 @@ _tmp_229_rule(Parser *p) (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_229[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + D(fprintf(stderr, "%*c+ _tmp_231[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); _res = _PyPegen_dummy_name(p, _literal, _opt_var, _literal_1); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_229[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_231[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' arguments? ')'")); } _res = NULL; @@ -39295,9 +39442,9 @@ _tmp_229_rule(Parser *p) return _res; } -// _loop0_231: ',' double_starred_kvpair +// _loop0_233: ',' double_starred_kvpair static asdl_seq * -_loop0_231_rule(Parser *p) +_loop0_233_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39322,7 +39469,7 @@ _loop0_231_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_231[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' double_starred_kvpair")); + D(fprintf(stderr, "%*c> _loop0_233[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' double_starred_kvpair")); Token * _literal; KeyValuePair* elem; while ( @@ -39354,7 +39501,7 @@ _loop0_231_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_231[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_233[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' double_starred_kvpair")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -39371,9 +39518,9 @@ _loop0_231_rule(Parser *p) return _seq; } -// _gather_230: double_starred_kvpair _loop0_231 +// _gather_232: double_starred_kvpair _loop0_233 static asdl_seq * -_gather_230_rule(Parser *p) +_gather_232_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39384,27 +39531,27 @@ _gather_230_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // double_starred_kvpair _loop0_231 + { // double_starred_kvpair _loop0_233 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_230[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_231")); + D(fprintf(stderr, "%*c> _gather_232[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_233")); KeyValuePair* elem; asdl_seq * seq; if ( (elem = double_starred_kvpair_rule(p)) // double_starred_kvpair && - (seq = _loop0_231_rule(p)) // _loop0_231 + (seq = _loop0_233_rule(p)) // _loop0_233 ) { - D(fprintf(stderr, "%*c+ _gather_230[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_231")); + D(fprintf(stderr, "%*c+ _gather_232[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_233")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_230[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "double_starred_kvpair _loop0_231")); + D(fprintf(stderr, "%*c%s _gather_232[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "double_starred_kvpair _loop0_233")); } _res = NULL; done: @@ -39412,9 +39559,9 @@ _gather_230_rule(Parser *p) return _res; } -// _tmp_232: '}' | ',' +// _tmp_234: '}' | ',' static void * -_tmp_232_rule(Parser *p) +_tmp_234_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39430,18 +39577,18 @@ _tmp_232_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_232[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 26)) // token='}' ) { - D(fprintf(stderr, "%*c+ _tmp_232[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_232[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_234[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); } { // ',' @@ -39449,18 +39596,18 @@ _tmp_232_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_232[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_232[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_232[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_234[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; @@ -39469,9 +39616,9 @@ _tmp_232_rule(Parser *p) return _res; } -// _tmp_233: '}' | ',' +// _tmp_235: '}' | ',' static void * -_tmp_233_rule(Parser *p) +_tmp_235_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39487,18 +39634,18 @@ _tmp_233_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_233[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c> _tmp_235[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 26)) // token='}' ) { - D(fprintf(stderr, "%*c+ _tmp_233[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c+ _tmp_235[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_233[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_235[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); } { // ',' @@ -39506,18 +39653,18 @@ _tmp_233_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_233[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_235[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_233[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_235[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_233[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_235[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; @@ -39526,9 +39673,9 @@ _tmp_233_rule(Parser *p) return _res; } -// _tmp_234: yield_expr | star_expressions +// _tmp_236: yield_expr | star_expressions static void * -_tmp_234_rule(Parser *p) +_tmp_236_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39544,18 +39691,18 @@ _tmp_234_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_236[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); expr_ty yield_expr_var; if ( (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_236[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); _res = yield_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_234[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_236[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } { // star_expressions @@ -39563,18 +39710,18 @@ _tmp_234_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c> _tmp_236[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); expr_ty star_expressions_var; if ( (star_expressions_var = star_expressions_rule(p)) // star_expressions ) { - D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c+ _tmp_236[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); _res = star_expressions_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_234[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_236[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; @@ -39583,9 +39730,9 @@ _tmp_234_rule(Parser *p) return _res; } -// _tmp_235: yield_expr | star_expressions +// _tmp_237: yield_expr | star_expressions static void * -_tmp_235_rule(Parser *p) +_tmp_237_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39601,18 +39748,18 @@ _tmp_235_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_235[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_237[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); expr_ty yield_expr_var; if ( (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _tmp_235[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_237[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); _res = yield_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_235[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_237[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } { // star_expressions @@ -39620,18 +39767,18 @@ _tmp_235_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_235[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c> _tmp_237[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); expr_ty star_expressions_var; if ( (star_expressions_var = star_expressions_rule(p)) // star_expressions ) { - D(fprintf(stderr, "%*c+ _tmp_235[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c+ _tmp_237[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); _res = star_expressions_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_235[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_237[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; @@ -39640,9 +39787,9 @@ _tmp_235_rule(Parser *p) return _res; } -// _tmp_236: '=' | '!' | ':' | '}' +// _tmp_238: '=' | '!' | ':' | '}' static void * -_tmp_236_rule(Parser *p) +_tmp_238_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39658,18 +39805,18 @@ _tmp_236_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_236[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c> _tmp_238[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_236[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c+ _tmp_238[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_236[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_238[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='")); } { // '!' @@ -39677,18 +39824,18 @@ _tmp_236_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_236[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!'")); + D(fprintf(stderr, "%*c> _tmp_238[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 54)) // token='!' ) { - D(fprintf(stderr, "%*c+ _tmp_236[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!'")); + D(fprintf(stderr, "%*c+ _tmp_238[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_236[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_238[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'!'")); } { // ':' @@ -39696,18 +39843,18 @@ _tmp_236_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_236[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_238[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_236[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_238[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_236[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_238[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } { // '}' @@ -39715,18 +39862,18 @@ _tmp_236_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_236[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c> _tmp_238[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 26)) // token='}' ) { - D(fprintf(stderr, "%*c+ _tmp_236[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c+ _tmp_238[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_236[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_238[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); } _res = NULL; @@ -39735,9 +39882,9 @@ _tmp_236_rule(Parser *p) return _res; } -// _tmp_237: yield_expr | star_expressions +// _tmp_239: yield_expr | star_expressions static void * -_tmp_237_rule(Parser *p) +_tmp_239_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39753,18 +39900,18 @@ _tmp_237_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_237[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_239[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); expr_ty yield_expr_var; if ( (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _tmp_237[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_239[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); _res = yield_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_237[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_239[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } { // star_expressions @@ -39772,18 +39919,18 @@ _tmp_237_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_237[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c> _tmp_239[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); expr_ty star_expressions_var; if ( (star_expressions_var = star_expressions_rule(p)) // star_expressions ) { - D(fprintf(stderr, "%*c+ _tmp_237[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c+ _tmp_239[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); _res = star_expressions_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_237[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_239[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; @@ -39792,9 +39939,9 @@ _tmp_237_rule(Parser *p) return _res; } -// _tmp_238: '!' | ':' | '}' +// _tmp_240: '!' | ':' | '}' static void * -_tmp_238_rule(Parser *p) +_tmp_240_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39810,18 +39957,18 @@ _tmp_238_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_238[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!'")); + D(fprintf(stderr, "%*c> _tmp_240[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 54)) // token='!' ) { - D(fprintf(stderr, "%*c+ _tmp_238[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!'")); + D(fprintf(stderr, "%*c+ _tmp_240[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_238[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_240[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'!'")); } { // ':' @@ -39829,18 +39976,18 @@ _tmp_238_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_238[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_240[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_238[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_240[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_238[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_240[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } { // '}' @@ -39848,18 +39995,18 @@ _tmp_238_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_238[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c> _tmp_240[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 26)) // token='}' ) { - D(fprintf(stderr, "%*c+ _tmp_238[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c+ _tmp_240[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_238[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_240[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); } _res = NULL; @@ -39868,9 +40015,9 @@ _tmp_238_rule(Parser *p) return _res; } -// _tmp_239: yield_expr | star_expressions +// _tmp_241: yield_expr | star_expressions static void * -_tmp_239_rule(Parser *p) +_tmp_241_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39886,18 +40033,18 @@ _tmp_239_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_239[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_241[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); expr_ty yield_expr_var; if ( (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _tmp_239[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_241[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); _res = yield_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_239[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_241[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } { // star_expressions @@ -39905,18 +40052,18 @@ _tmp_239_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_239[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c> _tmp_241[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); expr_ty star_expressions_var; if ( (star_expressions_var = star_expressions_rule(p)) // star_expressions ) { - D(fprintf(stderr, "%*c+ _tmp_239[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c+ _tmp_241[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); _res = star_expressions_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_239[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_241[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; @@ -39925,9 +40072,9 @@ _tmp_239_rule(Parser *p) return _res; } -// _tmp_240: yield_expr | star_expressions +// _tmp_242: yield_expr | star_expressions static void * -_tmp_240_rule(Parser *p) +_tmp_242_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39943,18 +40090,18 @@ _tmp_240_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_240[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_242[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); expr_ty yield_expr_var; if ( (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _tmp_240[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_242[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); _res = yield_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_240[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_242[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } { // star_expressions @@ -39962,18 +40109,18 @@ _tmp_240_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_240[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c> _tmp_242[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); expr_ty star_expressions_var; if ( (star_expressions_var = star_expressions_rule(p)) // star_expressions ) { - D(fprintf(stderr, "%*c+ _tmp_240[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c+ _tmp_242[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); _res = star_expressions_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_240[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_242[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; @@ -39982,9 +40129,9 @@ _tmp_240_rule(Parser *p) return _res; } -// _tmp_241: '!' NAME +// _tmp_243: '!' NAME static void * -_tmp_241_rule(Parser *p) +_tmp_243_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40000,7 +40147,7 @@ _tmp_241_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_241[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!' NAME")); + D(fprintf(stderr, "%*c> _tmp_243[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!' NAME")); Token * _literal; expr_ty name_var; if ( @@ -40009,12 +40156,12 @@ _tmp_241_rule(Parser *p) (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_241[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' NAME")); + D(fprintf(stderr, "%*c+ _tmp_243[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' NAME")); _res = _PyPegen_dummy_name(p, _literal, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_241[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_243[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'!' NAME")); } _res = NULL; @@ -40023,9 +40170,9 @@ _tmp_241_rule(Parser *p) return _res; } -// _tmp_242: ':' | '}' +// _tmp_244: ':' | '}' static void * -_tmp_242_rule(Parser *p) +_tmp_244_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40041,18 +40188,18 @@ _tmp_242_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_242[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_244[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_242[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_244[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_242[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_244[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } { // '}' @@ -40060,18 +40207,18 @@ _tmp_242_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_242[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c> _tmp_244[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 26)) // token='}' ) { - D(fprintf(stderr, "%*c+ _tmp_242[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c+ _tmp_244[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_242[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_244[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); } _res = NULL; @@ -40080,9 +40227,9 @@ _tmp_242_rule(Parser *p) return _res; } -// _tmp_243: yield_expr | star_expressions +// _tmp_245: yield_expr | star_expressions static void * -_tmp_243_rule(Parser *p) +_tmp_245_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40098,18 +40245,18 @@ _tmp_243_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_243[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_245[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); expr_ty yield_expr_var; if ( (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _tmp_243[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_245[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); _res = yield_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_243[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_245[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } { // star_expressions @@ -40117,18 +40264,18 @@ _tmp_243_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_243[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c> _tmp_245[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); expr_ty star_expressions_var; if ( (star_expressions_var = star_expressions_rule(p)) // star_expressions ) { - D(fprintf(stderr, "%*c+ _tmp_243[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c+ _tmp_245[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); _res = star_expressions_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_243[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_245[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; @@ -40137,9 +40284,9 @@ _tmp_243_rule(Parser *p) return _res; } -// _tmp_244: '!' NAME +// _tmp_246: '!' NAME static void * -_tmp_244_rule(Parser *p) +_tmp_246_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40155,7 +40302,7 @@ _tmp_244_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_244[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!' NAME")); + D(fprintf(stderr, "%*c> _tmp_246[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!' NAME")); Token * _literal; expr_ty name_var; if ( @@ -40164,12 +40311,12 @@ _tmp_244_rule(Parser *p) (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_244[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' NAME")); + D(fprintf(stderr, "%*c+ _tmp_246[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' NAME")); _res = _PyPegen_dummy_name(p, _literal, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_244[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_246[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'!' NAME")); } _res = NULL; @@ -40178,9 +40325,9 @@ _tmp_244_rule(Parser *p) return _res; } -// _loop0_245: fstring_format_spec +// _loop0_247: fstring_format_spec static asdl_seq * -_loop0_245_rule(Parser *p) +_loop0_247_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40205,7 +40352,7 @@ _loop0_245_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_245[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring_format_spec")); + D(fprintf(stderr, "%*c> _loop0_247[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring_format_spec")); expr_ty fstring_format_spec_var; while ( (fstring_format_spec_var = fstring_format_spec_rule(p)) // fstring_format_spec @@ -40228,7 +40375,7 @@ _loop0_245_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_245[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_247[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "fstring_format_spec")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -40245,9 +40392,9 @@ _loop0_245_rule(Parser *p) return _seq; } -// _tmp_246: yield_expr | star_expressions +// _tmp_248: yield_expr | star_expressions static void * -_tmp_246_rule(Parser *p) +_tmp_248_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40263,18 +40410,18 @@ _tmp_246_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_246[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_248[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); expr_ty yield_expr_var; if ( (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _tmp_246[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_248[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); _res = yield_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_246[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_248[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } { // star_expressions @@ -40282,18 +40429,18 @@ _tmp_246_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_246[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c> _tmp_248[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); expr_ty star_expressions_var; if ( (star_expressions_var = star_expressions_rule(p)) // star_expressions ) { - D(fprintf(stderr, "%*c+ _tmp_246[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c+ _tmp_248[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); _res = star_expressions_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_246[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_248[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; @@ -40302,9 +40449,9 @@ _tmp_246_rule(Parser *p) return _res; } -// _tmp_247: '!' NAME +// _tmp_249: '!' NAME static void * -_tmp_247_rule(Parser *p) +_tmp_249_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40320,7 +40467,7 @@ _tmp_247_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_247[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!' NAME")); + D(fprintf(stderr, "%*c> _tmp_249[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!' NAME")); Token * _literal; expr_ty name_var; if ( @@ -40329,12 +40476,12 @@ _tmp_247_rule(Parser *p) (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_247[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' NAME")); + D(fprintf(stderr, "%*c+ _tmp_249[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' NAME")); _res = _PyPegen_dummy_name(p, _literal, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_247[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_249[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'!' NAME")); } _res = NULL; @@ -40343,9 +40490,9 @@ _tmp_247_rule(Parser *p) return _res; } -// _tmp_248: ':' | '}' +// _tmp_250: ':' | '}' static void * -_tmp_248_rule(Parser *p) +_tmp_250_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40361,18 +40508,18 @@ _tmp_248_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_248[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_250[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_248[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_250[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_248[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_250[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } { // '}' @@ -40380,18 +40527,18 @@ _tmp_248_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_248[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c> _tmp_250[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 26)) // token='}' ) { - D(fprintf(stderr, "%*c+ _tmp_248[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c+ _tmp_250[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_248[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_250[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); } _res = NULL; @@ -40400,9 +40547,9 @@ _tmp_248_rule(Parser *p) return _res; } -// _tmp_249: '+' | '-' | '*' | '/' | '%' | '//' | '@' +// _tmp_251: '+' | '-' | '*' | '/' | '%' | '//' | '@' static void * -_tmp_249_rule(Parser *p) +_tmp_251_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40418,18 +40565,18 @@ _tmp_249_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_249[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'+'")); + D(fprintf(stderr, "%*c> _tmp_251[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'+'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 14)) // token='+' ) { - D(fprintf(stderr, "%*c+ _tmp_249[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'+'")); + D(fprintf(stderr, "%*c+ _tmp_251[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'+'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_249[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_251[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'+'")); } { // '-' @@ -40437,18 +40584,18 @@ _tmp_249_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_249[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-'")); + D(fprintf(stderr, "%*c> _tmp_251[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 15)) // token='-' ) { - D(fprintf(stderr, "%*c+ _tmp_249[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-'")); + D(fprintf(stderr, "%*c+ _tmp_251[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_249[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_251[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'-'")); } { // '*' @@ -40456,18 +40603,18 @@ _tmp_249_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_249[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); + D(fprintf(stderr, "%*c> _tmp_251[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' ) { - D(fprintf(stderr, "%*c+ _tmp_249[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); + D(fprintf(stderr, "%*c+ _tmp_251[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_249[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_251[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*'")); } { // '/' @@ -40475,18 +40622,18 @@ _tmp_249_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_249[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'")); + D(fprintf(stderr, "%*c> _tmp_251[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 17)) // token='/' ) { - D(fprintf(stderr, "%*c+ _tmp_249[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'")); + D(fprintf(stderr, "%*c+ _tmp_251[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_249[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_251[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'/'")); } { // '%' @@ -40494,18 +40641,18 @@ _tmp_249_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_249[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'%'")); + D(fprintf(stderr, "%*c> _tmp_251[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'%'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 24)) // token='%' ) { - D(fprintf(stderr, "%*c+ _tmp_249[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'%'")); + D(fprintf(stderr, "%*c+ _tmp_251[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'%'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_249[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_251[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'%'")); } { // '//' @@ -40513,18 +40660,18 @@ _tmp_249_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_249[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'//'")); + D(fprintf(stderr, "%*c> _tmp_251[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'//'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 47)) // token='//' ) { - D(fprintf(stderr, "%*c+ _tmp_249[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'//'")); + D(fprintf(stderr, "%*c+ _tmp_251[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'//'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_249[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_251[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'//'")); } { // '@' @@ -40532,18 +40679,18 @@ _tmp_249_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_249[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@'")); + D(fprintf(stderr, "%*c> _tmp_251[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 49)) // token='@' ) { - D(fprintf(stderr, "%*c+ _tmp_249[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@'")); + D(fprintf(stderr, "%*c+ _tmp_251[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_249[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_251[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'@'")); } _res = NULL; @@ -40552,9 +40699,9 @@ _tmp_249_rule(Parser *p) return _res; } -// _tmp_250: '+' | '-' | '~' +// _tmp_252: '+' | '-' | '~' static void * -_tmp_250_rule(Parser *p) +_tmp_252_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40570,18 +40717,18 @@ _tmp_250_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_250[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'+'")); + D(fprintf(stderr, "%*c> _tmp_252[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'+'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 14)) // token='+' ) { - D(fprintf(stderr, "%*c+ _tmp_250[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'+'")); + D(fprintf(stderr, "%*c+ _tmp_252[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'+'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_250[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_252[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'+'")); } { // '-' @@ -40589,18 +40736,18 @@ _tmp_250_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_250[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-'")); + D(fprintf(stderr, "%*c> _tmp_252[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 15)) // token='-' ) { - D(fprintf(stderr, "%*c+ _tmp_250[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-'")); + D(fprintf(stderr, "%*c+ _tmp_252[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_250[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_252[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'-'")); } { // '~' @@ -40608,18 +40755,18 @@ _tmp_250_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_250[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'~'")); + D(fprintf(stderr, "%*c> _tmp_252[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'~'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 31)) // token='~' ) { - D(fprintf(stderr, "%*c+ _tmp_250[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'~'")); + D(fprintf(stderr, "%*c+ _tmp_252[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'~'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_250[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_252[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'~'")); } _res = NULL; @@ -40628,9 +40775,9 @@ _tmp_250_rule(Parser *p) return _res; } -// _tmp_251: star_targets '=' +// _tmp_253: star_targets '=' static void * -_tmp_251_rule(Parser *p) +_tmp_253_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40646,7 +40793,7 @@ _tmp_251_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_251[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c> _tmp_253[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); Token * _literal; expr_ty z; if ( @@ -40655,7 +40802,7 @@ _tmp_251_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_251[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c+ _tmp_253[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -40665,7 +40812,7 @@ _tmp_251_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_251[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_253[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); } _res = NULL; @@ -40674,9 +40821,9 @@ _tmp_251_rule(Parser *p) return _res; } -// _tmp_252: '.' | '...' +// _tmp_254: '.' | '...' static void * -_tmp_252_rule(Parser *p) +_tmp_254_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40692,18 +40839,18 @@ _tmp_252_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_252[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c> _tmp_254[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 23)) // token='.' ) { - D(fprintf(stderr, "%*c+ _tmp_252[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c+ _tmp_254[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_252[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_254[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); } { // '...' @@ -40711,18 +40858,18 @@ _tmp_252_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_252[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c> _tmp_254[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 52)) // token='...' ) { - D(fprintf(stderr, "%*c+ _tmp_252[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c+ _tmp_254[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_252[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_254[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'...'")); } _res = NULL; @@ -40731,9 +40878,9 @@ _tmp_252_rule(Parser *p) return _res; } -// _tmp_253: '.' | '...' +// _tmp_255: '.' | '...' static void * -_tmp_253_rule(Parser *p) +_tmp_255_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40749,18 +40896,18 @@ _tmp_253_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_253[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c> _tmp_255[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 23)) // token='.' ) { - D(fprintf(stderr, "%*c+ _tmp_253[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c+ _tmp_255[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_253[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_255[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); } { // '...' @@ -40768,18 +40915,18 @@ _tmp_253_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_253[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c> _tmp_255[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 52)) // token='...' ) { - D(fprintf(stderr, "%*c+ _tmp_253[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c+ _tmp_255[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_253[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_255[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'...'")); } _res = NULL; @@ -40788,9 +40935,9 @@ _tmp_253_rule(Parser *p) return _res; } -// _tmp_254: '@' named_expression NEWLINE +// _tmp_256: '@' named_expression NEWLINE static void * -_tmp_254_rule(Parser *p) +_tmp_256_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40806,7 +40953,7 @@ _tmp_254_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_254[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); + D(fprintf(stderr, "%*c> _tmp_256[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); Token * _literal; expr_ty f; Token * newline_var; @@ -40818,7 +40965,7 @@ _tmp_254_rule(Parser *p) (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) { - D(fprintf(stderr, "%*c+ _tmp_254[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); + D(fprintf(stderr, "%*c+ _tmp_256[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); _res = f; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -40828,7 +40975,7 @@ _tmp_254_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_254[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_256[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'@' named_expression NEWLINE")); } _res = NULL; @@ -40837,9 +40984,9 @@ _tmp_254_rule(Parser *p) return _res; } -// _tmp_255: ',' expression +// _tmp_257: ',' expression static void * -_tmp_255_rule(Parser *p) +_tmp_257_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40855,7 +41002,7 @@ _tmp_255_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_255[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c> _tmp_257[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); Token * _literal; expr_ty c; if ( @@ -40864,7 +41011,7 @@ _tmp_255_rule(Parser *p) (c = expression_rule(p)) // expression ) { - D(fprintf(stderr, "%*c+ _tmp_255[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c+ _tmp_257[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -40874,7 +41021,7 @@ _tmp_255_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_255[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_257[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); } _res = NULL; @@ -40883,9 +41030,9 @@ _tmp_255_rule(Parser *p) return _res; } -// _tmp_256: ',' star_expression +// _tmp_258: ',' star_expression static void * -_tmp_256_rule(Parser *p) +_tmp_258_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40901,7 +41048,7 @@ _tmp_256_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_256[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_expression")); + D(fprintf(stderr, "%*c> _tmp_258[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_expression")); Token * _literal; expr_ty c; if ( @@ -40910,7 +41057,7 @@ _tmp_256_rule(Parser *p) (c = star_expression_rule(p)) // star_expression ) { - D(fprintf(stderr, "%*c+ _tmp_256[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_expression")); + D(fprintf(stderr, "%*c+ _tmp_258[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_expression")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -40920,7 +41067,7 @@ _tmp_256_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_256[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_258[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_expression")); } _res = NULL; @@ -40929,9 +41076,9 @@ _tmp_256_rule(Parser *p) return _res; } -// _tmp_257: 'or' conjunction +// _tmp_259: 'or' conjunction static void * -_tmp_257_rule(Parser *p) +_tmp_259_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40947,7 +41094,7 @@ _tmp_257_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_257[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); + D(fprintf(stderr, "%*c> _tmp_259[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); Token * _keyword; expr_ty c; if ( @@ -40956,7 +41103,7 @@ _tmp_257_rule(Parser *p) (c = conjunction_rule(p)) // conjunction ) { - D(fprintf(stderr, "%*c+ _tmp_257[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); + D(fprintf(stderr, "%*c+ _tmp_259[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -40966,7 +41113,7 @@ _tmp_257_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_257[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_259[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'or' conjunction")); } _res = NULL; @@ -40975,9 +41122,9 @@ _tmp_257_rule(Parser *p) return _res; } -// _tmp_258: 'and' inversion +// _tmp_260: 'and' inversion static void * -_tmp_258_rule(Parser *p) +_tmp_260_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40993,7 +41140,7 @@ _tmp_258_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_258[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'and' inversion")); + D(fprintf(stderr, "%*c> _tmp_260[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'and' inversion")); Token * _keyword; expr_ty c; if ( @@ -41002,7 +41149,7 @@ _tmp_258_rule(Parser *p) (c = inversion_rule(p)) // inversion ) { - D(fprintf(stderr, "%*c+ _tmp_258[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'and' inversion")); + D(fprintf(stderr, "%*c+ _tmp_260[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'and' inversion")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -41012,7 +41159,7 @@ _tmp_258_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_258[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_260[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'and' inversion")); } _res = NULL; @@ -41021,9 +41168,9 @@ _tmp_258_rule(Parser *p) return _res; } -// _tmp_259: slice | starred_expression +// _tmp_261: slice | starred_expression static void * -_tmp_259_rule(Parser *p) +_tmp_261_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41039,18 +41186,18 @@ _tmp_259_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_259[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slice")); + D(fprintf(stderr, "%*c> _tmp_261[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slice")); expr_ty slice_var; if ( (slice_var = slice_rule(p)) // slice ) { - D(fprintf(stderr, "%*c+ _tmp_259[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slice")); + D(fprintf(stderr, "%*c+ _tmp_261[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slice")); _res = slice_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_259[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_261[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slice")); } { // starred_expression @@ -41058,18 +41205,18 @@ _tmp_259_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_259[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); + D(fprintf(stderr, "%*c> _tmp_261[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); expr_ty starred_expression_var; if ( (starred_expression_var = starred_expression_rule(p)) // starred_expression ) { - D(fprintf(stderr, "%*c+ _tmp_259[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); + D(fprintf(stderr, "%*c+ _tmp_261[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); _res = starred_expression_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_259[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_261[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "starred_expression")); } _res = NULL; @@ -41078,9 +41225,9 @@ _tmp_259_rule(Parser *p) return _res; } -// _tmp_260: fstring | string +// _tmp_262: fstring | string static void * -_tmp_260_rule(Parser *p) +_tmp_262_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41096,18 +41243,18 @@ _tmp_260_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_260[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring")); + D(fprintf(stderr, "%*c> _tmp_262[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring")); expr_ty fstring_var; if ( (fstring_var = fstring_rule(p)) // fstring ) { - D(fprintf(stderr, "%*c+ _tmp_260[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "fstring")); + D(fprintf(stderr, "%*c+ _tmp_262[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "fstring")); _res = fstring_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_260[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_262[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "fstring")); } { // string @@ -41115,18 +41262,18 @@ _tmp_260_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_260[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "string")); + D(fprintf(stderr, "%*c> _tmp_262[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "string")); expr_ty string_var; if ( (string_var = string_rule(p)) // string ) { - D(fprintf(stderr, "%*c+ _tmp_260[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "string")); + D(fprintf(stderr, "%*c+ _tmp_262[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "string")); _res = string_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_260[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_262[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "string")); } _res = NULL; @@ -41135,9 +41282,9 @@ _tmp_260_rule(Parser *p) return _res; } -// _tmp_261: 'if' disjunction +// _tmp_263: 'if' disjunction static void * -_tmp_261_rule(Parser *p) +_tmp_263_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41153,7 +41300,7 @@ _tmp_261_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_261[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c> _tmp_263[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); Token * _keyword; expr_ty z; if ( @@ -41162,7 +41309,7 @@ _tmp_261_rule(Parser *p) (z = disjunction_rule(p)) // disjunction ) { - D(fprintf(stderr, "%*c+ _tmp_261[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c+ _tmp_263[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -41172,7 +41319,7 @@ _tmp_261_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_261[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_263[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' disjunction")); } _res = NULL; @@ -41181,9 +41328,9 @@ _tmp_261_rule(Parser *p) return _res; } -// _tmp_262: 'if' disjunction +// _tmp_264: 'if' disjunction static void * -_tmp_262_rule(Parser *p) +_tmp_264_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41199,7 +41346,7 @@ _tmp_262_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_262[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c> _tmp_264[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); Token * _keyword; expr_ty z; if ( @@ -41208,7 +41355,7 @@ _tmp_262_rule(Parser *p) (z = disjunction_rule(p)) // disjunction ) { - D(fprintf(stderr, "%*c+ _tmp_262[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c+ _tmp_264[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -41218,7 +41365,7 @@ _tmp_262_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_262[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_264[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' disjunction")); } _res = NULL; @@ -41227,9 +41374,9 @@ _tmp_262_rule(Parser *p) return _res; } -// _loop0_263: (',' bitwise_or) +// _loop0_265: (',' bitwise_or) static asdl_seq * -_loop0_263_rule(Parser *p) +_loop0_265_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41254,13 +41401,13 @@ _loop0_263_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_263[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' bitwise_or)")); - void *_tmp_277_var; + D(fprintf(stderr, "%*c> _loop0_265[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' bitwise_or)")); + void *_tmp_280_var; while ( - (_tmp_277_var = _tmp_277_rule(p)) // ',' bitwise_or + (_tmp_280_var = _tmp_280_rule(p)) // ',' bitwise_or ) { - _res = _tmp_277_var; + _res = _tmp_280_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -41277,7 +41424,7 @@ _loop0_263_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_263[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_265[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' bitwise_or)")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -41294,9 +41441,9 @@ _loop0_263_rule(Parser *p) return _seq; } -// _tmp_264: starred_expression | (assignment_expression | expression !':=') !'=' +// _tmp_266: starred_expression | (assignment_expression | expression !':=') !'=' static void * -_tmp_264_rule(Parser *p) +_tmp_266_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41312,18 +41459,18 @@ _tmp_264_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_264[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); + D(fprintf(stderr, "%*c> _tmp_266[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); expr_ty starred_expression_var; if ( (starred_expression_var = starred_expression_rule(p)) // starred_expression ) { - D(fprintf(stderr, "%*c+ _tmp_264[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); + D(fprintf(stderr, "%*c+ _tmp_266[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); _res = starred_expression_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_264[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_266[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "starred_expression")); } { // (assignment_expression | expression !':=') !'=' @@ -41331,20 +41478,20 @@ _tmp_264_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_264[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); - void *_tmp_278_var; + D(fprintf(stderr, "%*c> _tmp_266[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); + void *_tmp_281_var; if ( - (_tmp_278_var = _tmp_278_rule(p)) // assignment_expression | expression !':=' + (_tmp_281_var = _tmp_281_rule(p)) // assignment_expression | expression !':=' && _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 22) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_264[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); - _res = _tmp_278_var; + D(fprintf(stderr, "%*c+ _tmp_266[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); + _res = _tmp_281_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_264[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_266[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(assignment_expression | expression !':=') !'='")); } _res = NULL; @@ -41353,9 +41500,9 @@ _tmp_264_rule(Parser *p) return _res; } -// _tmp_265: ',' star_target +// _tmp_267: ',' star_target static void * -_tmp_265_rule(Parser *p) +_tmp_267_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41371,7 +41518,7 @@ _tmp_265_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_265[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c> _tmp_267[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); Token * _literal; expr_ty c; if ( @@ -41380,7 +41527,7 @@ _tmp_265_rule(Parser *p) (c = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_265[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c+ _tmp_267[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -41390,7 +41537,7 @@ _tmp_265_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_265[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_267[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_target")); } _res = NULL; @@ -41399,9 +41546,9 @@ _tmp_265_rule(Parser *p) return _res; } -// _tmp_266: ',' star_target +// _tmp_268: ',' star_target static void * -_tmp_266_rule(Parser *p) +_tmp_268_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41417,7 +41564,7 @@ _tmp_266_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_266[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c> _tmp_268[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); Token * _literal; expr_ty c; if ( @@ -41426,7 +41573,7 @@ _tmp_266_rule(Parser *p) (c = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_266[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c+ _tmp_268[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -41436,7 +41583,7 @@ _tmp_266_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_266[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_268[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_target")); } _res = NULL; @@ -41445,10 +41592,10 @@ _tmp_266_rule(Parser *p) return _res; } -// _tmp_267: +// _tmp_269: // | ','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs static void * -_tmp_267_rule(Parser *p) +_tmp_269_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41464,24 +41611,24 @@ _tmp_267_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_267[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs")); - asdl_seq * _gather_279_var; + D(fprintf(stderr, "%*c> _tmp_269[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs")); + asdl_seq * _gather_282_var; Token * _literal; asdl_seq* kwargs_var; if ( - (_gather_279_var = _gather_279_rule(p)) // ','.(starred_expression | (assignment_expression | expression !':=') !'=')+ + (_gather_282_var = _gather_282_rule(p)) // ','.(starred_expression | (assignment_expression | expression !':=') !'=')+ && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && (kwargs_var = kwargs_rule(p)) // kwargs ) { - D(fprintf(stderr, "%*c+ _tmp_267[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs")); - _res = _PyPegen_dummy_name(p, _gather_279_var, _literal, kwargs_var); + D(fprintf(stderr, "%*c+ _tmp_269[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs")); + _res = _PyPegen_dummy_name(p, _gather_282_var, _literal, kwargs_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_267[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_269[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs")); } _res = NULL; @@ -41490,9 +41637,49 @@ _tmp_267_rule(Parser *p) return _res; } -// _tmp_268: star_targets '=' +// _tmp_270: starred_expression !'=' static void * -_tmp_268_rule(Parser *p) +_tmp_270_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // starred_expression !'=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_270[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression !'='")); + expr_ty starred_expression_var; + if ( + (starred_expression_var = starred_expression_rule(p)) // starred_expression + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 22) // token='=' + ) + { + D(fprintf(stderr, "%*c+ _tmp_270[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression !'='")); + _res = starred_expression_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_270[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "starred_expression !'='")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_271: star_targets '=' +static void * +_tmp_271_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41508,7 +41695,7 @@ _tmp_268_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_268[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c> _tmp_271[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); Token * _literal; expr_ty star_targets_var; if ( @@ -41517,12 +41704,12 @@ _tmp_268_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_268[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c+ _tmp_271[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); _res = _PyPegen_dummy_name(p, star_targets_var, _literal); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_268[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_271[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); } _res = NULL; @@ -41531,9 +41718,9 @@ _tmp_268_rule(Parser *p) return _res; } -// _tmp_269: star_targets '=' +// _tmp_272: star_targets '=' static void * -_tmp_269_rule(Parser *p) +_tmp_272_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41549,7 +41736,7 @@ _tmp_269_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_269[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c> _tmp_272[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); Token * _literal; expr_ty star_targets_var; if ( @@ -41558,12 +41745,12 @@ _tmp_269_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_269[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c+ _tmp_272[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); _res = _PyPegen_dummy_name(p, star_targets_var, _literal); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_269[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_272[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); } _res = NULL; @@ -41572,9 +41759,9 @@ _tmp_269_rule(Parser *p) return _res; } -// _tmp_270: ')' | '**' +// _tmp_273: ')' | '**' static void * -_tmp_270_rule(Parser *p) +_tmp_273_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41590,18 +41777,18 @@ _tmp_270_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_270[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_273[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_270[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_273[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_270[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_273[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } { // '**' @@ -41609,18 +41796,18 @@ _tmp_270_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_270[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c> _tmp_273[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_270[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c+ _tmp_273[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_270[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_273[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } _res = NULL; @@ -41629,9 +41816,9 @@ _tmp_270_rule(Parser *p) return _res; } -// _tmp_271: ':' | '**' +// _tmp_274: ':' | '**' static void * -_tmp_271_rule(Parser *p) +_tmp_274_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41647,18 +41834,18 @@ _tmp_271_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_271[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_274[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_271[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_274[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_271[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_274[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } { // '**' @@ -41666,18 +41853,18 @@ _tmp_271_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_271[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c> _tmp_274[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_271[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c+ _tmp_274[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_271[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_274[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } _res = NULL; @@ -41686,9 +41873,9 @@ _tmp_271_rule(Parser *p) return _res; } -// _tmp_272: expression ['as' star_target] +// _tmp_275: expression ['as' star_target] static void * -_tmp_272_rule(Parser *p) +_tmp_275_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41704,22 +41891,22 @@ _tmp_272_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_272[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + D(fprintf(stderr, "%*c> _tmp_275[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings expr_ty expression_var; if ( (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_281_rule(p), !p->error_indicator) // ['as' star_target] + (_opt_var = _tmp_284_rule(p), !p->error_indicator) // ['as' star_target] ) { - D(fprintf(stderr, "%*c+ _tmp_272[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + D(fprintf(stderr, "%*c+ _tmp_275[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); _res = _PyPegen_dummy_name(p, expression_var, _opt_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_272[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_275[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ['as' star_target]")); } _res = NULL; @@ -41728,9 +41915,9 @@ _tmp_272_rule(Parser *p) return _res; } -// _tmp_273: expressions ['as' star_target] +// _tmp_276: expressions ['as' star_target] static void * -_tmp_273_rule(Parser *p) +_tmp_276_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41746,22 +41933,22 @@ _tmp_273_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_273[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + D(fprintf(stderr, "%*c> _tmp_276[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings expr_ty expressions_var; if ( (expressions_var = expressions_rule(p)) // expressions && - (_opt_var = _tmp_282_rule(p), !p->error_indicator) // ['as' star_target] + (_opt_var = _tmp_285_rule(p), !p->error_indicator) // ['as' star_target] ) { - D(fprintf(stderr, "%*c+ _tmp_273[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + D(fprintf(stderr, "%*c+ _tmp_276[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); _res = _PyPegen_dummy_name(p, expressions_var, _opt_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_273[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_276[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expressions ['as' star_target]")); } _res = NULL; @@ -41770,9 +41957,9 @@ _tmp_273_rule(Parser *p) return _res; } -// _tmp_274: expression ['as' star_target] +// _tmp_277: expression ['as' star_target] static void * -_tmp_274_rule(Parser *p) +_tmp_277_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41788,22 +41975,22 @@ _tmp_274_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_274[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + D(fprintf(stderr, "%*c> _tmp_277[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings expr_ty expression_var; if ( (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_283_rule(p), !p->error_indicator) // ['as' star_target] + (_opt_var = _tmp_286_rule(p), !p->error_indicator) // ['as' star_target] ) { - D(fprintf(stderr, "%*c+ _tmp_274[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + D(fprintf(stderr, "%*c+ _tmp_277[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); _res = _PyPegen_dummy_name(p, expression_var, _opt_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_274[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_277[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ['as' star_target]")); } _res = NULL; @@ -41812,9 +41999,9 @@ _tmp_274_rule(Parser *p) return _res; } -// _tmp_275: expressions ['as' star_target] +// _tmp_278: expressions ['as' star_target] static void * -_tmp_275_rule(Parser *p) +_tmp_278_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41830,22 +42017,22 @@ _tmp_275_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_275[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + D(fprintf(stderr, "%*c> _tmp_278[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings expr_ty expressions_var; if ( (expressions_var = expressions_rule(p)) // expressions && - (_opt_var = _tmp_284_rule(p), !p->error_indicator) // ['as' star_target] + (_opt_var = _tmp_287_rule(p), !p->error_indicator) // ['as' star_target] ) { - D(fprintf(stderr, "%*c+ _tmp_275[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + D(fprintf(stderr, "%*c+ _tmp_278[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); _res = _PyPegen_dummy_name(p, expressions_var, _opt_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_275[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_278[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expressions ['as' star_target]")); } _res = NULL; @@ -41854,9 +42041,9 @@ _tmp_275_rule(Parser *p) return _res; } -// _tmp_276: 'as' NAME +// _tmp_279: 'as' NAME static void * -_tmp_276_rule(Parser *p) +_tmp_279_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41872,7 +42059,7 @@ _tmp_276_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_276[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_279[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty name_var; if ( @@ -41881,12 +42068,12 @@ _tmp_276_rule(Parser *p) (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_276[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_279[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = _PyPegen_dummy_name(p, _keyword, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_276[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_279[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -41895,9 +42082,9 @@ _tmp_276_rule(Parser *p) return _res; } -// _tmp_277: ',' bitwise_or +// _tmp_280: ',' bitwise_or static void * -_tmp_277_rule(Parser *p) +_tmp_280_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41913,7 +42100,7 @@ _tmp_277_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_277[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' bitwise_or")); + D(fprintf(stderr, "%*c> _tmp_280[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' bitwise_or")); Token * _literal; expr_ty bitwise_or_var; if ( @@ -41922,12 +42109,12 @@ _tmp_277_rule(Parser *p) (bitwise_or_var = bitwise_or_rule(p)) // bitwise_or ) { - D(fprintf(stderr, "%*c+ _tmp_277[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' bitwise_or")); + D(fprintf(stderr, "%*c+ _tmp_280[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' bitwise_or")); _res = _PyPegen_dummy_name(p, _literal, bitwise_or_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_277[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_280[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' bitwise_or")); } _res = NULL; @@ -41936,9 +42123,9 @@ _tmp_277_rule(Parser *p) return _res; } -// _tmp_278: assignment_expression | expression !':=' +// _tmp_281: assignment_expression | expression !':=' static void * -_tmp_278_rule(Parser *p) +_tmp_281_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41954,18 +42141,18 @@ _tmp_278_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_278[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression")); + D(fprintf(stderr, "%*c> _tmp_281[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression")); expr_ty assignment_expression_var; if ( (assignment_expression_var = assignment_expression_rule(p)) // assignment_expression ) { - D(fprintf(stderr, "%*c+ _tmp_278[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment_expression")); + D(fprintf(stderr, "%*c+ _tmp_281[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment_expression")); _res = assignment_expression_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_278[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_281[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "assignment_expression")); } { // expression !':=' @@ -41973,7 +42160,7 @@ _tmp_278_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_278[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); + D(fprintf(stderr, "%*c> _tmp_281[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); expr_ty expression_var; if ( (expression_var = expression_rule(p)) // expression @@ -41981,12 +42168,12 @@ _tmp_278_rule(Parser *p) _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 53) // token=':=' ) { - D(fprintf(stderr, "%*c+ _tmp_278[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='")); + D(fprintf(stderr, "%*c+ _tmp_281[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='")); _res = expression_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_278[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_281[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression !':='")); } _res = NULL; @@ -41995,9 +42182,9 @@ _tmp_278_rule(Parser *p) return _res; } -// _loop0_280: ',' (starred_expression | (assignment_expression | expression !':=') !'=') +// _loop0_283: ',' (starred_expression | (assignment_expression | expression !':=') !'=') static asdl_seq * -_loop0_280_rule(Parser *p) +_loop0_283_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -42022,13 +42209,13 @@ _loop0_280_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_280[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (starred_expression | (assignment_expression | expression !':=') !'=')")); + D(fprintf(stderr, "%*c> _loop0_283[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (starred_expression | (assignment_expression | expression !':=') !'=')")); Token * _literal; void *elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_285_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' + (elem = _tmp_288_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' ) { _res = elem; @@ -42054,7 +42241,7 @@ _loop0_280_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_280[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_283[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (starred_expression | (assignment_expression | expression !':=') !'=')")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -42071,10 +42258,10 @@ _loop0_280_rule(Parser *p) return _seq; } -// _gather_279: -// | (starred_expression | (assignment_expression | expression !':=') !'=') _loop0_280 +// _gather_282: +// | (starred_expression | (assignment_expression | expression !':=') !'=') _loop0_283 static asdl_seq * -_gather_279_rule(Parser *p) +_gather_282_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -42085,27 +42272,27 @@ _gather_279_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // (starred_expression | (assignment_expression | expression !':=') !'=') _loop0_280 + { // (starred_expression | (assignment_expression | expression !':=') !'=') _loop0_283 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_279[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_280")); + D(fprintf(stderr, "%*c> _gather_282[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_283")); void *elem; asdl_seq * seq; if ( - (elem = _tmp_285_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' + (elem = _tmp_288_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' && - (seq = _loop0_280_rule(p)) // _loop0_280 + (seq = _loop0_283_rule(p)) // _loop0_283 ) { - D(fprintf(stderr, "%*c+ _gather_279[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_280")); + D(fprintf(stderr, "%*c+ _gather_282[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_283")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_279[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_280")); + D(fprintf(stderr, "%*c%s _gather_282[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_283")); } _res = NULL; done: @@ -42113,9 +42300,9 @@ _gather_279_rule(Parser *p) return _res; } -// _tmp_281: 'as' star_target +// _tmp_284: 'as' star_target static void * -_tmp_281_rule(Parser *p) +_tmp_284_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -42131,7 +42318,7 @@ _tmp_281_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_281[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c> _tmp_284[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); Token * _keyword; expr_ty star_target_var; if ( @@ -42140,12 +42327,12 @@ _tmp_281_rule(Parser *p) (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_281[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c+ _tmp_284[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); _res = _PyPegen_dummy_name(p, _keyword, star_target_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_281[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_284[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); } _res = NULL; @@ -42154,9 +42341,9 @@ _tmp_281_rule(Parser *p) return _res; } -// _tmp_282: 'as' star_target +// _tmp_285: 'as' star_target static void * -_tmp_282_rule(Parser *p) +_tmp_285_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -42172,7 +42359,7 @@ _tmp_282_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_282[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c> _tmp_285[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); Token * _keyword; expr_ty star_target_var; if ( @@ -42181,12 +42368,12 @@ _tmp_282_rule(Parser *p) (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_282[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c+ _tmp_285[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); _res = _PyPegen_dummy_name(p, _keyword, star_target_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_282[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_285[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); } _res = NULL; @@ -42195,9 +42382,9 @@ _tmp_282_rule(Parser *p) return _res; } -// _tmp_283: 'as' star_target +// _tmp_286: 'as' star_target static void * -_tmp_283_rule(Parser *p) +_tmp_286_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -42213,7 +42400,7 @@ _tmp_283_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_283[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c> _tmp_286[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); Token * _keyword; expr_ty star_target_var; if ( @@ -42222,12 +42409,12 @@ _tmp_283_rule(Parser *p) (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_283[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c+ _tmp_286[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); _res = _PyPegen_dummy_name(p, _keyword, star_target_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_283[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_286[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); } _res = NULL; @@ -42236,9 +42423,9 @@ _tmp_283_rule(Parser *p) return _res; } -// _tmp_284: 'as' star_target +// _tmp_287: 'as' star_target static void * -_tmp_284_rule(Parser *p) +_tmp_287_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -42254,7 +42441,7 @@ _tmp_284_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_284[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c> _tmp_287[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); Token * _keyword; expr_ty star_target_var; if ( @@ -42263,12 +42450,12 @@ _tmp_284_rule(Parser *p) (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_284[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c+ _tmp_287[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); _res = _PyPegen_dummy_name(p, _keyword, star_target_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_284[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_287[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); } _res = NULL; @@ -42277,9 +42464,9 @@ _tmp_284_rule(Parser *p) return _res; } -// _tmp_285: starred_expression | (assignment_expression | expression !':=') !'=' +// _tmp_288: starred_expression | (assignment_expression | expression !':=') !'=' static void * -_tmp_285_rule(Parser *p) +_tmp_288_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -42295,18 +42482,18 @@ _tmp_285_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_285[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); + D(fprintf(stderr, "%*c> _tmp_288[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); expr_ty starred_expression_var; if ( (starred_expression_var = starred_expression_rule(p)) // starred_expression ) { - D(fprintf(stderr, "%*c+ _tmp_285[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); + D(fprintf(stderr, "%*c+ _tmp_288[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); _res = starred_expression_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_285[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_288[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "starred_expression")); } { // (assignment_expression | expression !':=') !'=' @@ -42314,20 +42501,20 @@ _tmp_285_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_285[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); - void *_tmp_286_var; + D(fprintf(stderr, "%*c> _tmp_288[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); + void *_tmp_289_var; if ( - (_tmp_286_var = _tmp_286_rule(p)) // assignment_expression | expression !':=' + (_tmp_289_var = _tmp_289_rule(p)) // assignment_expression | expression !':=' && _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 22) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_285[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); - _res = _tmp_286_var; + D(fprintf(stderr, "%*c+ _tmp_288[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); + _res = _tmp_289_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_285[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_288[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(assignment_expression | expression !':=') !'='")); } _res = NULL; @@ -42336,9 +42523,9 @@ _tmp_285_rule(Parser *p) return _res; } -// _tmp_286: assignment_expression | expression !':=' +// _tmp_289: assignment_expression | expression !':=' static void * -_tmp_286_rule(Parser *p) +_tmp_289_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -42354,18 +42541,18 @@ _tmp_286_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_286[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression")); + D(fprintf(stderr, "%*c> _tmp_289[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression")); expr_ty assignment_expression_var; if ( (assignment_expression_var = assignment_expression_rule(p)) // assignment_expression ) { - D(fprintf(stderr, "%*c+ _tmp_286[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment_expression")); + D(fprintf(stderr, "%*c+ _tmp_289[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment_expression")); _res = assignment_expression_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_286[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_289[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "assignment_expression")); } { // expression !':=' @@ -42373,7 +42560,7 @@ _tmp_286_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_286[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); + D(fprintf(stderr, "%*c> _tmp_289[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); expr_ty expression_var; if ( (expression_var = expression_rule(p)) // expression @@ -42381,12 +42568,12 @@ _tmp_286_rule(Parser *p) _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 53) // token=':=' ) { - D(fprintf(stderr, "%*c+ _tmp_286[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='")); + D(fprintf(stderr, "%*c+ _tmp_289[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='")); _res = expression_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_286[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_289[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression !':='")); } _res = NULL; From c32dc47aca6e8fac152699bc613e015c44ccdba9 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Tue, 2 Apr 2024 11:59:21 +0100 Subject: [PATCH 10/11] GH-115776: Embed the values array into the object, for "normal" Python objects. (GH-116115) --- Include/cpython/pystats.h | 3 +- Include/internal/pycore_code.h | 5 +- Include/internal/pycore_dict.h | 64 ++- Include/internal/pycore_object.h | 48 +- Include/internal/pycore_opcode_metadata.h | 6 +- Include/internal/pycore_uop_ids.h | 2 +- Include/internal/pycore_uop_metadata.h | 10 +- Include/object.h | 7 +- Lib/test/test_capi/test_mem.py | 4 +- Lib/test/test_class.py | 77 ++- Lib/test/test_opcache.py | 13 +- ...-02-24-03-39-09.gh-issue-115776.THJXqg.rst | 4 + Modules/_testbuffer.c | 3 + Modules/_testcapimodule.c | 4 +- Modules/_testinternalcapi.c | 20 +- Objects/dictobject.c | 464 +++++++++--------- Objects/object.c | 100 ++-- Objects/object_layout.md | 91 +++- Objects/object_layout_312.gv | 1 + Objects/object_layout_312.png | Bin 30688 -> 33040 bytes Objects/object_layout_313.gv | 45 ++ Objects/object_layout_313.png | Bin 0 -> 35055 bytes Objects/object_layout_full_313.gv | 25 + Objects/object_layout_full_313.png | Bin 0 -> 16983 bytes Objects/typeobject.c | 84 ++-- Python/bytecodes.c | 52 +- Python/executor_cases.c.h | 44 +- Python/gc.c | 7 +- Python/gc_free_threading.c | 6 +- Python/generated_cases.c.h | 54 +- Python/optimizer_cases.c.h | 2 +- Python/specialize.c | 51 +- Tools/cases_generator/analyzer.py | 7 +- Tools/gdb/libpython.py | 14 +- Tools/scripts/summarize_stats.py | 5 +- 35 files changed, 786 insertions(+), 536 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-02-24-03-39-09.gh-issue-115776.THJXqg.rst create mode 100644 Objects/object_layout_313.gv create mode 100644 Objects/object_layout_313.png create mode 100644 Objects/object_layout_full_313.gv create mode 100644 Objects/object_layout_full_313.png diff --git a/Include/cpython/pystats.h b/Include/cpython/pystats.h index 2fb7723f583cc7..e74fdd4d32e26c 100644 --- a/Include/cpython/pystats.h +++ b/Include/cpython/pystats.h @@ -77,12 +77,11 @@ typedef struct _object_stats { uint64_t frees; uint64_t to_freelist; uint64_t from_freelist; - uint64_t new_values; + uint64_t inline_values; uint64_t dict_materialized_on_request; uint64_t dict_materialized_new_key; uint64_t dict_materialized_too_big; uint64_t dict_materialized_str_subclass; - uint64_t dict_dematerialized; uint64_t type_cache_hits; uint64_t type_cache_misses; uint64_t type_cache_dunder_hits; diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h index e004783ee48198..6c90c9e284103c 100644 --- a/Include/internal/pycore_code.h +++ b/Include/internal/pycore_code.h @@ -79,7 +79,10 @@ typedef struct { typedef struct { uint16_t counter; uint16_t type_version[2]; - uint16_t keys_version[2]; + union { + uint16_t keys_version[2]; + uint16_t dict_offset; + }; uint16_t descr[4]; } _PyLoadMethodCache; diff --git a/Include/internal/pycore_dict.h b/Include/internal/pycore_dict.h index ef59960dbab071..5507bdd539cc42 100644 --- a/Include/internal/pycore_dict.h +++ b/Include/internal/pycore_dict.h @@ -11,7 +11,7 @@ extern "C" { #include "pycore_freelist.h" // _PyFreeListState #include "pycore_identifier.h" // _Py_Identifier -#include "pycore_object.h" // PyDictOrValues +#include "pycore_object.h" // PyManagedDictPointer // Unsafe flavor of PyDict_GetItemWithError(): no error checking extern PyObject* _PyDict_GetItemWithError(PyObject *dp, PyObject *key); @@ -181,6 +181,10 @@ struct _dictkeysobject { * [-1] = prefix size. [-2] = used size. size[-2-n...] = insertion order. */ struct _dictvalues { + uint8_t capacity; + uint8_t size; + uint8_t embedded; + uint8_t valid; PyObject *values[1]; }; @@ -196,6 +200,7 @@ static inline void* _DK_ENTRIES(PyDictKeysObject *dk) { size_t index = (size_t)1 << dk->dk_log2_index_bytes; return (&indices[index]); } + static inline PyDictKeyEntry* DK_ENTRIES(PyDictKeysObject *dk) { assert(dk->dk_kind == DICT_KEYS_GENERAL); return (PyDictKeyEntry*)_DK_ENTRIES(dk); @@ -211,9 +216,6 @@ static inline PyDictUnicodeEntry* DK_UNICODE_ENTRIES(PyDictKeysObject *dk) { #define DICT_WATCHER_MASK ((1 << DICT_MAX_WATCHERS) - 1) #define DICT_WATCHER_AND_MODIFICATION_MASK ((1 << (DICT_MAX_WATCHERS + DICT_WATCHED_MUTATION_BITS)) - 1) -#define DICT_VALUES_SIZE(values) ((uint8_t *)values)[-1] -#define DICT_VALUES_USED_SIZE(values) ((uint8_t *)values)[-2] - #ifdef Py_GIL_DISABLED #define DICT_NEXT_VERSION(INTERP) \ (_Py_atomic_add_uint64(&(INTERP)->dict_state.global_version, DICT_VERSION_INCREMENT) + DICT_VERSION_INCREMENT) @@ -246,25 +248,63 @@ _PyDict_NotifyEvent(PyInterpreterState *interp, return DICT_NEXT_VERSION(interp) | (mp->ma_version_tag & DICT_WATCHER_AND_MODIFICATION_MASK); } -extern PyObject *_PyObject_MakeDictFromInstanceAttributes(PyObject *obj, PyDictValues *values); -PyAPI_FUNC(bool) _PyObject_MakeInstanceAttributesFromDict(PyObject *obj, PyDictOrValues *dorv); +extern PyDictObject *_PyObject_MakeDictFromInstanceAttributes(PyObject *obj); + PyAPI_FUNC(PyObject *)_PyDict_FromItems( PyObject *const *keys, Py_ssize_t keys_offset, PyObject *const *values, Py_ssize_t values_offset, Py_ssize_t length); +static inline uint8_t * +get_insertion_order_array(PyDictValues *values) +{ + return (uint8_t *)&values->values[values->capacity]; +} + static inline void _PyDictValues_AddToInsertionOrder(PyDictValues *values, Py_ssize_t ix) { assert(ix < SHARED_KEYS_MAX_SIZE); - uint8_t *size_ptr = ((uint8_t *)values)-2; - int size = *size_ptr; - assert(size+2 < DICT_VALUES_SIZE(values)); - size++; - size_ptr[-size] = (uint8_t)ix; - *size_ptr = size; + int size = values->size; + uint8_t *array = get_insertion_order_array(values); + assert(size < values->capacity); + assert(((uint8_t)ix) == ix); + array[size] = (uint8_t)ix; + values->size = size+1; +} + +static inline size_t +shared_keys_usable_size(PyDictKeysObject *keys) +{ +#ifdef Py_GIL_DISABLED + // dk_usable will decrease for each instance that is created and each + // value that is added. dk_nentries will increase for each value that + // is added. We want to always return the right value or larger. + // We therefore increase dk_nentries first and we decrease dk_usable + // second, and conversely here we read dk_usable first and dk_entries + // second (to avoid the case where we read entries before the increment + // and read usable after the decrement) + return (size_t)(_Py_atomic_load_ssize_acquire(&keys->dk_usable) + + _Py_atomic_load_ssize_acquire(&keys->dk_nentries)); +#else + return (size_t)keys->dk_nentries + (size_t)keys->dk_usable; +#endif } +static inline size_t +_PyInlineValuesSize(PyTypeObject *tp) +{ + PyDictKeysObject *keys = ((PyHeapTypeObject*)tp)->ht_cached_keys; + assert(keys != NULL); + size_t size = shared_keys_usable_size(keys); + size_t prefix_size = _Py_SIZE_ROUND_UP(size, sizeof(PyObject *)); + assert(prefix_size < 256); + return prefix_size + (size + 1) * sizeof(PyObject *); +} + +int +_PyDict_DetachFromObject(PyDictObject *dict, PyObject *obj); + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index 0b17ddf0c973ef..4fc5e9bf653c1c 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -265,9 +265,8 @@ _PyObject_Init(PyObject *op, PyTypeObject *typeobj) { assert(op != NULL); Py_SET_TYPE(op, typeobj); - if (_PyType_HasFeature(typeobj, Py_TPFLAGS_HEAPTYPE)) { - Py_INCREF(typeobj); - } + assert(_PyType_HasFeature(typeobj, Py_TPFLAGS_HEAPTYPE) || _Py_IsImmortal(typeobj)); + Py_INCREF(typeobj); _Py_NewReference(op); } @@ -611,8 +610,7 @@ extern PyTypeObject* _PyType_CalculateMetaclass(PyTypeObject *, PyObject *); extern PyObject* _PyType_GetDocFromInternalDoc(const char *, const char *); extern PyObject* _PyType_GetTextSignatureFromInternalDoc(const char *, const char *, int); -extern int _PyObject_InitializeDict(PyObject *obj); -int _PyObject_InitInlineValues(PyObject *obj, PyTypeObject *tp); +void _PyObject_InitInlineValues(PyObject *obj, PyTypeObject *tp); extern int _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values, PyObject *name, PyObject *value); PyObject * _PyObject_GetInstanceAttribute(PyObject *obj, PyDictValues *values, @@ -627,46 +625,26 @@ PyObject * _PyObject_GetInstanceAttribute(PyObject *obj, PyDictValues *values, #endif typedef union { - PyObject *dict; - /* Use a char* to generate a warning if directly assigning a PyDictValues */ - char *values; -} PyDictOrValues; + PyDictObject *dict; +} PyManagedDictPointer; -static inline PyDictOrValues * -_PyObject_DictOrValuesPointer(PyObject *obj) +static inline PyManagedDictPointer * +_PyObject_ManagedDictPointer(PyObject *obj) { assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - return (PyDictOrValues *)((char *)obj + MANAGED_DICT_OFFSET); -} - -static inline int -_PyDictOrValues_IsValues(PyDictOrValues dorv) -{ - return ((uintptr_t)dorv.values) & 1; + return (PyManagedDictPointer *)((char *)obj + MANAGED_DICT_OFFSET); } static inline PyDictValues * -_PyDictOrValues_GetValues(PyDictOrValues dorv) -{ - assert(_PyDictOrValues_IsValues(dorv)); - return (PyDictValues *)(dorv.values + 1); -} - -static inline PyObject * -_PyDictOrValues_GetDict(PyDictOrValues dorv) +_PyObject_InlineValues(PyObject *obj) { - assert(!_PyDictOrValues_IsValues(dorv)); - return dorv.dict; -} - -static inline void -_PyDictOrValues_SetValues(PyDictOrValues *ptr, PyDictValues *values) -{ - ptr->values = ((char *)values) - 1; + assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_INLINE_VALUES); + assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + assert(Py_TYPE(obj)->tp_basicsize == sizeof(PyObject)); + return (PyDictValues *)((char *)obj + sizeof(PyObject)); } extern PyObject ** _PyObject_ComputedDictPointer(PyObject *); -extern void _PyObject_FreeInstanceAttributes(PyObject *obj); extern int _PyObject_IsInstanceDictEmpty(PyObject *); // Export for 'math' shared extension diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index de525f72d3523e..aa87dc413876f0 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -1085,7 +1085,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[268] = { [LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG }, [LOAD_ATTR_PROPERTY] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG }, [LOAD_ATTR_SLOT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG }, - [LOAD_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG }, + [LOAD_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG }, [LOAD_BUILD_CLASS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [LOAD_CONST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_CONST_FLAG | HAS_PURE_FLAG }, [LOAD_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, @@ -1269,7 +1269,7 @@ _PyOpcode_macro_expansion[256] = { [LOAD_ATTR] = { .nuops = 1, .uops = { { _LOAD_ATTR, 0, 0 } } }, [LOAD_ATTR_CLASS] = { .nuops = 2, .uops = { { _CHECK_ATTR_CLASS, 2, 1 }, { _LOAD_ATTR_CLASS, 4, 5 } } }, [LOAD_ATTR_INSTANCE_VALUE] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_MANAGED_OBJECT_HAS_VALUES, 0, 0 }, { _LOAD_ATTR_INSTANCE_VALUE, 1, 3 } } }, - [LOAD_ATTR_METHOD_LAZY_DICT] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_ATTR_METHOD_LAZY_DICT, 0, 0 }, { _LOAD_ATTR_METHOD_LAZY_DICT, 4, 5 } } }, + [LOAD_ATTR_METHOD_LAZY_DICT] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_ATTR_METHOD_LAZY_DICT, 1, 3 }, { _LOAD_ATTR_METHOD_LAZY_DICT, 4, 5 } } }, [LOAD_ATTR_METHOD_NO_DICT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_METHOD_NO_DICT, 4, 5 } } }, [LOAD_ATTR_METHOD_WITH_VALUES] = { .nuops = 4, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT, 0, 0 }, { _GUARD_KEYS_VERSION, 2, 3 }, { _LOAD_ATTR_METHOD_WITH_VALUES, 4, 5 } } }, [LOAD_ATTR_MODULE] = { .nuops = 2, .uops = { { _CHECK_ATTR_MODULE, 2, 1 }, { _LOAD_ATTR_MODULE, 1, 3 } } }, @@ -1316,7 +1316,7 @@ _PyOpcode_macro_expansion[256] = { [SET_FUNCTION_ATTRIBUTE] = { .nuops = 1, .uops = { { _SET_FUNCTION_ATTRIBUTE, 0, 0 } } }, [SET_UPDATE] = { .nuops = 1, .uops = { { _SET_UPDATE, 0, 0 } } }, [STORE_ATTR] = { .nuops = 1, .uops = { { _STORE_ATTR, 0, 0 } } }, - [STORE_ATTR_INSTANCE_VALUE] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _GUARD_DORV_VALUES, 0, 0 }, { _STORE_ATTR_INSTANCE_VALUE, 1, 3 } } }, + [STORE_ATTR_INSTANCE_VALUE] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _GUARD_DORV_NO_DICT, 0, 0 }, { _STORE_ATTR_INSTANCE_VALUE, 1, 3 } } }, [STORE_ATTR_SLOT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _STORE_ATTR_SLOT, 1, 3 } } }, [STORE_DEREF] = { .nuops = 1, .uops = { { _STORE_DEREF, 0, 0 } } }, [STORE_FAST] = { .nuops = 1, .uops = { { _STORE_FAST, 0, 0 } } }, diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index bcb10ab723ecba..54dc6dcf408116 100644 --- a/Include/internal/pycore_uop_ids.h +++ b/Include/internal/pycore_uop_ids.h @@ -109,7 +109,7 @@ extern "C" { #define _GUARD_BOTH_INT 347 #define _GUARD_BOTH_UNICODE 348 #define _GUARD_BUILTINS_VERSION 349 -#define _GUARD_DORV_VALUES 350 +#define _GUARD_DORV_NO_DICT 350 #define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 351 #define _GUARD_GLOBALS_VERSION 352 #define _GUARD_IS_FALSE_POP 353 diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index 51206cd4ca2fdf..0f2046fb3d0c3d 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -136,8 +136,8 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = { [_LOAD_ATTR_INSTANCE_VALUE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_OPARG_AND_1_FLAG, [_CHECK_ATTR_MODULE] = HAS_DEOPT_FLAG | HAS_PASSTHROUGH_FLAG, [_LOAD_ATTR_MODULE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG, - [_CHECK_ATTR_WITH_HINT] = HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG | HAS_PASSTHROUGH_FLAG, - [_LOAD_ATTR_WITH_HINT] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG, + [_CHECK_ATTR_WITH_HINT] = HAS_DEOPT_FLAG | HAS_PASSTHROUGH_FLAG, + [_LOAD_ATTR_WITH_HINT] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG, [_LOAD_ATTR_SLOT_0] = HAS_DEOPT_FLAG, [_LOAD_ATTR_SLOT_1] = HAS_DEOPT_FLAG, [_LOAD_ATTR_SLOT] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_OPARG_AND_1_FLAG, @@ -145,7 +145,7 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = { [_LOAD_ATTR_CLASS_0] = 0, [_LOAD_ATTR_CLASS_1] = 0, [_LOAD_ATTR_CLASS] = HAS_ARG_FLAG | HAS_OPARG_AND_1_FLAG, - [_GUARD_DORV_VALUES] = HAS_DEOPT_FLAG | HAS_PASSTHROUGH_FLAG, + [_GUARD_DORV_NO_DICT] = HAS_DEOPT_FLAG | HAS_PASSTHROUGH_FLAG, [_STORE_ATTR_INSTANCE_VALUE] = 0, [_STORE_ATTR_SLOT] = HAS_ESCAPES_FLAG, [_COMPARE_OP] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, @@ -342,7 +342,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = { [_GUARD_BOTH_INT] = "_GUARD_BOTH_INT", [_GUARD_BOTH_UNICODE] = "_GUARD_BOTH_UNICODE", [_GUARD_BUILTINS_VERSION] = "_GUARD_BUILTINS_VERSION", - [_GUARD_DORV_VALUES] = "_GUARD_DORV_VALUES", + [_GUARD_DORV_NO_DICT] = "_GUARD_DORV_NO_DICT", [_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT] = "_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT", [_GUARD_GLOBALS_VERSION] = "_GUARD_GLOBALS_VERSION", [_GUARD_IS_FALSE_POP] = "_GUARD_IS_FALSE_POP", @@ -736,7 +736,7 @@ int _PyUop_num_popped(int opcode, int oparg) return 1; case _LOAD_ATTR_CLASS: return 1; - case _GUARD_DORV_VALUES: + case _GUARD_DORV_NO_DICT: return 1; case _STORE_ATTR_INSTANCE_VALUE: return 2; diff --git a/Include/object.h b/Include/object.h index 96790844a7b9f0..13443329dfb5a2 100644 --- a/Include/object.h +++ b/Include/object.h @@ -629,13 +629,18 @@ given type object has a specified feature. /* Track types initialized using _PyStaticType_InitBuiltin(). */ #define _Py_TPFLAGS_STATIC_BUILTIN (1 << 1) +/* The values array is placed inline directly after the rest of + * the object. Implies Py_TPFLAGS_HAVE_GC. + */ +#define Py_TPFLAGS_INLINE_VALUES (1 << 2) + /* Placement of weakref pointers are managed by the VM, not by the type. * The VM will automatically set tp_weaklistoffset. */ #define Py_TPFLAGS_MANAGED_WEAKREF (1 << 3) /* Placement of dict (and values) pointers are managed by the VM, not by the type. - * The VM will automatically set tp_dictoffset. + * The VM will automatically set tp_dictoffset. Implies Py_TPFLAGS_HAVE_GC. */ #define Py_TPFLAGS_MANAGED_DICT (1 << 4) diff --git a/Lib/test/test_capi/test_mem.py b/Lib/test/test_capi/test_mem.py index 04f17a9ec9e72a..1958ecc0df4a7c 100644 --- a/Lib/test/test_capi/test_mem.py +++ b/Lib/test/test_capi/test_mem.py @@ -148,8 +148,8 @@ class C(): pass self.assertIn(b'MemoryError', out) *_, count = line.split(b' ') count = int(count) - self.assertLessEqual(count, i*5) - self.assertGreaterEqual(count, i*5-2) + self.assertLessEqual(count, i*10) + self.assertGreaterEqual(count, i*10-4) # Py_GIL_DISABLED requires mimalloc (not malloc) diff --git a/Lib/test/test_class.py b/Lib/test/test_class.py index 0cf06243dc8da0..4c1814142736e3 100644 --- a/Lib/test/test_class.py +++ b/Lib/test/test_class.py @@ -2,7 +2,6 @@ import unittest - testmeths = [ # Binary operations @@ -789,5 +788,81 @@ def __init__(self, obj): self.assertEqual(calls, 100) +from _testinternalcapi import has_inline_values + +Py_TPFLAGS_MANAGED_DICT = (1 << 2) + +class Plain: + pass + + +class WithAttrs: + + def __init__(self): + self.a = 1 + self.b = 2 + self.c = 3 + self.d = 4 + + +class TestInlineValues(unittest.TestCase): + + def test_flags(self): + self.assertEqual(Plain.__flags__ & Py_TPFLAGS_MANAGED_DICT, Py_TPFLAGS_MANAGED_DICT) + self.assertEqual(WithAttrs.__flags__ & Py_TPFLAGS_MANAGED_DICT, Py_TPFLAGS_MANAGED_DICT) + + def test_has_inline_values(self): + c = Plain() + self.assertTrue(has_inline_values(c)) + del c.__dict__ + self.assertFalse(has_inline_values(c)) + + def test_instances(self): + self.assertTrue(has_inline_values(Plain())) + self.assertTrue(has_inline_values(WithAttrs())) + + def test_inspect_dict(self): + for cls in (Plain, WithAttrs): + c = cls() + c.__dict__ + self.assertTrue(has_inline_values(c)) + + def test_update_dict(self): + d = { "e": 5, "f": 6 } + for cls in (Plain, WithAttrs): + c = cls() + c.__dict__.update(d) + self.assertTrue(has_inline_values(c)) + + @staticmethod + def set_100(obj): + for i in range(100): + setattr(obj, f"a{i}", i) + + def check_100(self, obj): + for i in range(100): + self.assertEqual(getattr(obj, f"a{i}"), i) + + def test_many_attributes(self): + class C: pass + c = C() + self.assertTrue(has_inline_values(c)) + self.set_100(c) + self.assertFalse(has_inline_values(c)) + self.check_100(c) + c = C() + self.assertTrue(has_inline_values(c)) + + def test_many_attributes_with_dict(self): + class C: pass + c = C() + d = c.__dict__ + self.assertTrue(has_inline_values(c)) + self.set_100(c) + self.assertFalse(has_inline_values(c)) + self.check_100(c) + + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_opcache.py b/Lib/test/test_opcache.py index 5fb4b815c95d07..8829c9a6d88261 100644 --- a/Lib/test/test_opcache.py +++ b/Lib/test/test_opcache.py @@ -1044,20 +1044,13 @@ def test_dict_materialization(self): c.a = 1 c.b = 2 c.__dict__ - self.assertIs( - _testinternalcapi.get_object_dict_values(c), - None - ) + self.assertEqual(c.__dict__, {"a":1, "b": 2}) def test_dict_dematerialization(self): c = C() c.a = 1 c.b = 2 c.__dict__ - self.assertIs( - _testinternalcapi.get_object_dict_values(c), - None - ) for _ in range(100): c.a self.assertEqual( @@ -1072,10 +1065,6 @@ def test_dict_dematerialization_multiple_refs(self): d = c.__dict__ for _ in range(100): c.a - self.assertIs( - _testinternalcapi.get_object_dict_values(c), - None - ) self.assertIs(c.__dict__, d) def test_dict_dematerialization_copy(self): diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-02-24-03-39-09.gh-issue-115776.THJXqg.rst b/Misc/NEWS.d/next/Core and Builtins/2024-02-24-03-39-09.gh-issue-115776.THJXqg.rst new file mode 100644 index 00000000000000..5974b1882acb22 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2024-02-24-03-39-09.gh-issue-115776.THJXqg.rst @@ -0,0 +1,4 @@ +The array of values, the ``PyDictValues`` struct is now embedded in the +object during allocation. This provides better performance in the common +case, and does not degrade as much when the object's ``__dict__`` is +materialized. diff --git a/Modules/_testbuffer.c b/Modules/_testbuffer.c index 5084bcadb10f85..cad21bdb4d85ed 100644 --- a/Modules/_testbuffer.c +++ b/Modules/_testbuffer.c @@ -2820,6 +2820,9 @@ static int _testbuffer_exec(PyObject *mod) { Py_SET_TYPE(&NDArray_Type, &PyType_Type); + if (PyType_Ready(&NDArray_Type)) { + return -1; + } if (PyModule_AddType(mod, &NDArray_Type) < 0) { return -1; } diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index e9db6e5683e344..b2af47d05ee196 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -3869,7 +3869,9 @@ PyInit__testcapi(void) return NULL; Py_SET_TYPE(&_HashInheritanceTester_Type, &PyType_Type); - + if (PyType_Ready(&_HashInheritanceTester_Type) < 0) { + return NULL; + } if (PyType_Ready(&matmulType) < 0) return NULL; Py_INCREF(&matmulType); diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index c07652facc0ae2..d6d50e75b612df 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -15,7 +15,7 @@ #include "pycore_ceval.h" // _PyEval_AddPendingCall() #include "pycore_compile.h" // _PyCompile_CodeGen() #include "pycore_context.h" // _PyContext_NewHamtForTests() -#include "pycore_dict.h" // _PyDictOrValues_GetValues() +#include "pycore_dict.h" // _PyManagedDictPointer_GetValues() #include "pycore_fileutils.h" // _Py_normpath() #include "pycore_frame.h" // _PyInterpreterFrame #include "pycore_gc.h" // PyGC_Head @@ -1297,14 +1297,13 @@ static PyObject * get_object_dict_values(PyObject *self, PyObject *obj) { PyTypeObject *type = Py_TYPE(obj); - if (!_PyType_HasFeature(type, Py_TPFLAGS_MANAGED_DICT)) { + if (!_PyType_HasFeature(type, Py_TPFLAGS_INLINE_VALUES)) { Py_RETURN_NONE; } - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(obj); - if (!_PyDictOrValues_IsValues(dorv)) { + PyDictValues *values = _PyObject_InlineValues(obj); + if (!values->valid) { Py_RETURN_NONE; } - PyDictValues *values = _PyDictOrValues_GetValues(dorv); PyDictKeysObject *keys = ((PyHeapTypeObject *)type)->ht_cached_keys; assert(keys != NULL); int size = (int)keys->dk_nentries; @@ -1784,6 +1783,16 @@ get_py_thread_id(PyObject *self, PyObject *Py_UNUSED(ignored)) } #endif +static PyObject * +has_inline_values(PyObject *self, PyObject *obj) +{ + if ((Py_TYPE(obj)->tp_flags & Py_TPFLAGS_INLINE_VALUES) && + _PyObject_InlineValues(obj)->valid) { + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; +} + static PyMethodDef module_functions[] = { {"get_configs", get_configs, METH_NOARGS}, {"get_recursion_depth", get_recursion_depth, METH_NOARGS}, @@ -1857,6 +1866,7 @@ static PyMethodDef module_functions[] = { _TESTINTERNALCAPI_TEST_LONG_NUMBITS_METHODDEF {"get_rare_event_counters", get_rare_event_counters, METH_NOARGS}, {"reset_rare_event_counters", reset_rare_event_counters, METH_NOARGS}, + {"has_inline_values", has_inline_values, METH_O}, #ifdef Py_GIL_DISABLED {"py_thread_id", get_py_thread_id, METH_NOARGS}, #endif diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 536746ca41eed5..58a3d979339c49 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -361,6 +361,10 @@ static int dict_setdefault_ref_lock_held(PyObject *d, PyObject *key, PyObject *default_value, PyObject **result, int incref_result); +#ifndef NDEBUG +static int _PyObject_InlineValuesConsistencyCheck(PyObject *obj); +#endif + #include "clinic/dictobject.c.h" @@ -624,8 +628,9 @@ static inline int get_index_from_order(PyDictObject *mp, Py_ssize_t i) { assert(mp->ma_used <= SHARED_KEYS_MAX_SIZE); - assert(i < (((char *)mp->ma_values)[-2])); - return ((char *)mp->ma_values)[-3-i]; + assert(i < mp->ma_values->size); + uint8_t *array = get_insertion_order_array(mp->ma_values); + return array[i]; } #ifdef DEBUG_PYDICT @@ -672,6 +677,10 @@ _PyDict_CheckConsistency(PyObject *op, int check_content) else { CHECK(keys->dk_kind == DICT_KEYS_SPLIT); CHECK(mp->ma_used <= SHARED_KEYS_MAX_SIZE); + if (mp->ma_values->embedded) { + CHECK(mp->ma_values->embedded == 1); + CHECK(mp->ma_values->valid == 1); + } } if (check_content) { @@ -821,33 +830,44 @@ free_keys_object(PyDictKeysObject *keys, bool use_qsbr) PyMem_Free(keys); } +static size_t +values_size_from_count(size_t count) +{ + assert(count >= 1); + size_t suffix_size = _Py_SIZE_ROUND_UP(count, sizeof(PyObject *)); + assert(suffix_size < 128); + assert(suffix_size % sizeof(PyObject *) == 0); + return (count + 1) * sizeof(PyObject *) + suffix_size; +} + +#define CACHED_KEYS(tp) (((PyHeapTypeObject*)tp)->ht_cached_keys) + static inline PyDictValues* new_values(size_t size) { - assert(size >= 1); - size_t prefix_size = _Py_SIZE_ROUND_UP(size+2, sizeof(PyObject *)); - assert(prefix_size < 256); - size_t n = prefix_size + size * sizeof(PyObject *); - uint8_t *mem = PyMem_Malloc(n); - if (mem == NULL) { + size_t n = values_size_from_count(size); + PyDictValues *res = (PyDictValues *)PyMem_Malloc(n); + if (res == NULL) { return NULL; } - assert(prefix_size % sizeof(PyObject *) == 0); - mem[prefix_size-1] = (uint8_t)prefix_size; - return (PyDictValues*)(mem + prefix_size); + res->embedded = 0; + res->size = 0; + assert(size < 256); + res->capacity = (uint8_t)size; + return res; } static inline void free_values(PyDictValues *values, bool use_qsbr) { - int prefix_size = DICT_VALUES_SIZE(values); + assert(values->embedded == 0); #ifdef Py_GIL_DISABLED if (use_qsbr) { - _PyMem_FreeDelayed(((char *)values)-prefix_size); + _PyMem_FreeDelayed(values); return; } #endif - PyMem_Free(((char *)values)-prefix_size); + PyMem_Free(values); } /* Consumes a reference to the keys object */ @@ -887,24 +907,6 @@ new_dict(PyInterpreterState *interp, return (PyObject *)mp; } -static inline size_t -shared_keys_usable_size(PyDictKeysObject *keys) -{ -#ifdef Py_GIL_DISABLED - // dk_usable will decrease for each instance that is created and each - // value that is added. dk_nentries will increase for each value that - // is added. We want to always return the right value or larger. - // We therefore increase dk_nentries first and we decrease dk_usable - // second, and conversely here we read dk_usable first and dk_entries - // second (to avoid the case where we read entries before the increment - // and read usable after the decrement) - return (size_t)(_Py_atomic_load_ssize_acquire(&keys->dk_usable) + - _Py_atomic_load_ssize_acquire(&keys->dk_nentries)); -#else - return (size_t)keys->dk_nentries + (size_t)keys->dk_usable; -#endif -} - /* Consumes a reference to the keys object */ static PyObject * new_dict_with_shared_keys(PyInterpreterState *interp, PyDictKeysObject *keys) @@ -915,7 +917,6 @@ new_dict_with_shared_keys(PyInterpreterState *interp, PyDictKeysObject *keys) dictkeys_decref(interp, keys, false); return PyErr_NoMemory(); } - ((char *)values)[-2] = 0; for (size_t i = 0; i < size; i++) { values->values[i] = NULL; } @@ -1419,7 +1420,7 @@ _Py_dict_lookup_threadsafe(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyOb if (values == NULL) goto read_failed; - uint8_t capacity = _Py_atomic_load_uint8_relaxed(&DICT_VALUES_SIZE(values)); + uint8_t capacity = _Py_atomic_load_uint8_relaxed(&values->capacity); if (ix >= (Py_ssize_t)capacity) goto read_failed; @@ -1525,6 +1526,7 @@ _PyDict_MaybeUntrack(PyObject *op) return; mp = (PyDictObject *) op; + ASSERT_CONSISTENT(mp); numentries = mp->ma_keys->dk_nentries; if (_PyDict_HasSplitTable(mp)) { for (i = 0; i < numentries; i++) { @@ -1945,7 +1947,14 @@ dictresize(PyInterpreterState *interp, PyDictObject *mp, set_keys(mp, newkeys); dictkeys_decref(interp, oldkeys, IS_DICT_SHARED(mp)); set_values(mp, NULL); - free_values(oldvalues, IS_DICT_SHARED(mp)); + if (oldvalues->embedded) { + assert(oldvalues->embedded == 1); + assert(oldvalues->valid == 1); + oldvalues->valid = 0; + } + else { + free_values(oldvalues, IS_DICT_SHARED(mp)); + } } else { // oldkeys is combined. if (oldkeys->dk_kind == DICT_KEYS_GENERAL) { @@ -2464,17 +2473,19 @@ _PyDict_SetItem_KnownHash(PyObject *op, PyObject *key, PyObject *value, static void delete_index_from_values(PyDictValues *values, Py_ssize_t ix) { - uint8_t *size_ptr = ((uint8_t *)values)-2; - int size = *size_ptr; + uint8_t *array = get_insertion_order_array(values); + int size = values->size; + assert(size <= values->capacity); int i; - for (i = 1; size_ptr[-i] != ix; i++) { - assert(i <= size); + for (i = 0; array[i] != ix; i++) { + assert(i < size); } - assert(i <= size); + assert(i < size); + size--; for (; i < size; i++) { - size_ptr[-i] = size_ptr[-i-1]; + array[i] = array[i+1]; } - *size_ptr = size -1; + values->size = size; } static int @@ -2669,10 +2680,12 @@ clear_lock_held(PyObject *op) mp->ma_version_tag = new_version; /* ...then clear the keys and values */ if (oldvalues != NULL) { - n = oldkeys->dk_nentries; - for (i = 0; i < n; i++) - Py_CLEAR(oldvalues->values[i]); - free_values(oldvalues, IS_DICT_SHARED(mp)); + if (!oldvalues->embedded) { + n = oldkeys->dk_nentries; + for (i = 0; i < n; i++) + Py_CLEAR(oldvalues->values[i]); + free_values(oldvalues, IS_DICT_SHARED(mp)); + } dictkeys_decref(interp, oldkeys, false); } else { @@ -3059,10 +3072,12 @@ dict_dealloc(PyObject *self) PyObject_GC_UnTrack(mp); Py_TRASHCAN_BEGIN(mp, dict_dealloc) if (values != NULL) { - for (i = 0, n = mp->ma_keys->dk_nentries; i < n; i++) { - Py_XDECREF(values->values[i]); + if (values->embedded == 0) { + for (i = 0, n = mp->ma_keys->dk_nentries; i < n; i++) { + Py_XDECREF(values->values[i]); + } + free_values(values, false); } - free_values(values, false); dictkeys_decref(interp, keys, false); } else if (keys != NULL) { @@ -3595,10 +3610,12 @@ dict_dict_merge(PyInterpreterState *interp, PyDictObject *mp, PyDictObject *othe PyDictKeysObject *okeys = other->ma_keys; // If other is clean, combined, and just allocated, just clone it. - if (other->ma_values == NULL && - other->ma_used == okeys->dk_nentries && - (DK_LOG_SIZE(okeys) == PyDict_LOG_MINSIZE || - USABLE_FRACTION(DK_SIZE(okeys)/2) < other->ma_used)) { + if (mp->ma_values == NULL && + other->ma_values == NULL && + other->ma_used == okeys->dk_nentries && + (DK_LOG_SIZE(okeys) == PyDict_LOG_MINSIZE || + USABLE_FRACTION(DK_SIZE(okeys)/2) < other->ma_used) + ) { uint64_t new_version = _PyDict_NotifyEvent( interp, PyDict_EVENT_CLONED, mp, (PyObject *)other, NULL); PyDictKeysObject *keys = clone_combined_dict_keys(other); @@ -3608,11 +3625,6 @@ dict_dict_merge(PyInterpreterState *interp, PyDictObject *mp, PyDictObject *othe ensure_shared_on_resize(mp); dictkeys_decref(interp, mp->ma_keys, IS_DICT_SHARED(mp)); mp->ma_keys = keys; - if (_PyDict_HasSplitTable(mp)) { - free_values(mp->ma_values, IS_DICT_SHARED(mp)); - mp->ma_values = NULL; - } - mp->ma_used = other->ma_used; mp->ma_version_tag = new_version; ASSERT_CONSISTENT(mp); @@ -3816,6 +3828,27 @@ dict_copy_impl(PyDictObject *self) return PyDict_Copy((PyObject *)self); } +/* Copies the values, but does not change the reference + * counts of the objects in the array. */ +static PyDictValues * +copy_values(PyDictValues *values) +{ + PyDictValues *newvalues = new_values(values->capacity); + if (newvalues == NULL) { + PyErr_NoMemory(); + return NULL; + } + newvalues->size = values->size; + uint8_t *values_order = get_insertion_order_array(values); + uint8_t *new_values_order = get_insertion_order_array(newvalues); + memcpy(new_values_order, values_order, values->capacity); + for (int i = 0; i < values->capacity; i++) { + newvalues->values[i] = values->values[i]; + } + assert(newvalues->embedded == 0); + return newvalues; +} + static PyObject * copy_lock_held(PyObject *o) { @@ -3833,26 +3866,23 @@ copy_lock_held(PyObject *o) if (_PyDict_HasSplitTable(mp)) { PyDictObject *split_copy; - size_t size = shared_keys_usable_size(mp->ma_keys); - PyDictValues *newvalues = new_values(size); - if (newvalues == NULL) + PyDictValues *newvalues = copy_values(mp->ma_values); + if (newvalues == NULL) { return PyErr_NoMemory(); + } split_copy = PyObject_GC_New(PyDictObject, &PyDict_Type); if (split_copy == NULL) { free_values(newvalues, false); return NULL; } - size_t prefix_size = ((uint8_t *)newvalues)[-1]; - memcpy(((char *)newvalues)-prefix_size, ((char *)mp->ma_values)-prefix_size, prefix_size-1); + for (size_t i = 0; i < newvalues->capacity; i++) { + Py_XINCREF(newvalues->values[i]); + } split_copy->ma_values = newvalues; split_copy->ma_keys = mp->ma_keys; split_copy->ma_used = mp->ma_used; split_copy->ma_version_tag = DICT_NEXT_VERSION(interp); dictkeys_incref(mp->ma_keys); - for (size_t i = 0; i < size; i++) { - PyObject *value = mp->ma_values->values[i]; - split_copy->ma_values->values[i] = Py_XNewRef(value); - } if (_PyObject_GC_IS_TRACKED(mp)) _PyObject_GC_TRACK(split_copy); return (PyObject *)split_copy; @@ -4406,8 +4436,10 @@ dict_traverse(PyObject *op, visitproc visit, void *arg) if (DK_IS_UNICODE(keys)) { if (_PyDict_HasSplitTable(mp)) { - for (i = 0; i < n; i++) { - Py_VISIT(mp->ma_values->values[i]); + if (!mp->ma_values->embedded) { + for (i = 0; i < n; i++) { + Py_VISIT(mp->ma_values->values[i]); + } } } else { @@ -5296,12 +5328,6 @@ acquire_key_value(PyObject **key_loc, PyObject *value, PyObject **value_loc, return 0; } -static Py_ssize_t -load_values_used_size(PyDictValues *values) -{ - return (Py_ssize_t)_Py_atomic_load_uint8(&DICT_VALUES_USED_SIZE(values)); -} - static int dictiter_iternext_threadsafe(PyDictObject *d, PyObject *self, PyObject **out_key, PyObject **out_value) @@ -5330,7 +5356,7 @@ dictiter_iternext_threadsafe(PyDictObject *d, PyObject *self, goto concurrent_modification; } - Py_ssize_t used = load_values_used_size(values); + Py_ssize_t used = (Py_ssize_t)_Py_atomic_load_uint8(&values->size); if (i >= used) { goto fail; } @@ -6539,15 +6565,15 @@ _PyDict_NewKeysForClass(void) return keys; } -#define CACHED_KEYS(tp) (((PyHeapTypeObject*)tp)->ht_cached_keys) - -int +void _PyObject_InitInlineValues(PyObject *obj, PyTypeObject *tp) { assert(tp->tp_flags & Py_TPFLAGS_HEAPTYPE); + assert(tp->tp_flags & Py_TPFLAGS_INLINE_VALUES); assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); PyDictKeysObject *keys = CACHED_KEYS(tp); assert(keys != NULL); + OBJECT_STAT_INC(inline_values); #ifdef Py_GIL_DISABLED Py_ssize_t usable = _Py_atomic_load_ssize_relaxed(&keys->dk_usable); if (usable > 1) { @@ -6563,49 +6589,19 @@ _PyObject_InitInlineValues(PyObject *obj, PyTypeObject *tp) } #endif size_t size = shared_keys_usable_size(keys); - PyDictValues *values = new_values(size); - if (values == NULL) { - PyErr_NoMemory(); - return -1; - } - assert(((uint8_t *)values)[-1] >= (size + 2)); - ((uint8_t *)values)[-2] = 0; + PyDictValues *values = _PyObject_InlineValues(obj); + assert(size < 256); + values->capacity = (uint8_t)size; + values->size = 0; + values->embedded = 1; + values->valid = 1; for (size_t i = 0; i < size; i++) { values->values[i] = NULL; } - _PyDictOrValues_SetValues(_PyObject_DictOrValuesPointer(obj), values); - return 0; -} - -int -_PyObject_InitializeDict(PyObject *obj) -{ - PyInterpreterState *interp = _PyInterpreterState_GET(); - PyTypeObject *tp = Py_TYPE(obj); - if (tp->tp_dictoffset == 0) { - return 0; - } - if (tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) { - OBJECT_STAT_INC(new_values); - return _PyObject_InitInlineValues(obj, tp); - } - PyObject *dict; - if (_PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE) && CACHED_KEYS(tp)) { - dictkeys_incref(CACHED_KEYS(tp)); - dict = new_dict_with_shared_keys(interp, CACHED_KEYS(tp)); - } - else { - dict = PyDict_New(); - } - if (dict == NULL) { - return -1; - } - PyObject **dictptr = _PyObject_ComputedDictPointer(obj); - *dictptr = dict; - return 0; + _PyObject_ManagedDictPointer(obj)->dict = NULL; } -static PyObject * +static PyDictObject * make_dict_from_instance_attributes(PyInterpreterState *interp, PyDictKeysObject *keys, PyDictValues *values) { @@ -6620,56 +6616,24 @@ make_dict_from_instance_attributes(PyInterpreterState *interp, track += _PyObject_GC_MAY_BE_TRACKED(val); } } - PyObject *res = new_dict(interp, keys, values, used, 0); + PyDictObject *res = (PyDictObject *)new_dict(interp, keys, values, used, 0); if (track && res) { _PyObject_GC_TRACK(res); } return res; } -PyObject * -_PyObject_MakeDictFromInstanceAttributes(PyObject *obj, PyDictValues *values) +PyDictObject * +_PyObject_MakeDictFromInstanceAttributes(PyObject *obj) { + PyDictValues *values = _PyObject_InlineValues(obj); PyInterpreterState *interp = _PyInterpreterState_GET(); PyDictKeysObject *keys = CACHED_KEYS(Py_TYPE(obj)); OBJECT_STAT_INC(dict_materialized_on_request); return make_dict_from_instance_attributes(interp, keys, values); } -// Return true if the dict was dematerialized, false otherwise. -bool -_PyObject_MakeInstanceAttributesFromDict(PyObject *obj, PyDictOrValues *dorv) -{ - assert(_PyObject_DictOrValuesPointer(obj) == dorv); - assert(!_PyDictOrValues_IsValues(*dorv)); - PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(*dorv); - if (dict == NULL) { - return false; - } - // It's likely that this dict still shares its keys (if it was materialized - // on request and not heavily modified): - if (!PyDict_CheckExact(dict)) { - return false; - } - assert(_PyType_HasFeature(Py_TYPE(obj), Py_TPFLAGS_HEAPTYPE)); - if (dict->ma_keys != CACHED_KEYS(Py_TYPE(obj)) || - !has_unique_reference((PyObject *)dict)) - { - return false; - } - ensure_shared_on_resize(dict); - assert(dict->ma_values); - // We have an opportunity to do something *really* cool: dematerialize it! - _PyDictKeys_DecRef(dict->ma_keys); - _PyDictOrValues_SetValues(dorv, dict->ma_values); - OBJECT_STAT_INC(dict_dematerialized); - // Don't try this at home, kids: - dict->ma_keys = NULL; - dict->ma_values = NULL; - Py_DECREF(dict); - return true; -} int _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values, @@ -6679,7 +6643,7 @@ _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values, PyDictKeysObject *keys = CACHED_KEYS(Py_TYPE(obj)); assert(keys != NULL); assert(values != NULL); - assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_INLINE_VALUES); Py_ssize_t ix = DKIX_EMPTY; if (PyUnicode_CheckExact(name)) { Py_hash_t hash = unicode_get_hash(name); @@ -6717,18 +6681,21 @@ _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values, } #endif } + PyDictObject *dict = _PyObject_ManagedDictPointer(obj)->dict; if (ix == DKIX_EMPTY) { - PyObject *dict = make_dict_from_instance_attributes( - interp, keys, values); if (dict == NULL) { - return -1; + dict = make_dict_from_instance_attributes( + interp, keys, values); + if (dict == NULL) { + return -1; + } + _PyObject_ManagedDictPointer(obj)->dict = (PyDictObject *)dict; } - _PyObject_DictOrValuesPointer(obj)->dict = dict; if (value == NULL) { - return PyDict_DelItem(dict, name); + return PyDict_DelItem((PyObject *)dict, name); } else { - return PyDict_SetItem(dict, name, value); + return PyDict_SetItem((PyObject *)dict, name, value); } } PyObject *old_value = values->values[ix]; @@ -6741,10 +6708,18 @@ _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values, return -1; } _PyDictValues_AddToInsertionOrder(values, ix); + if (dict) { + assert(dict->ma_values == values); + dict->ma_used++; + } } else { if (value == NULL) { delete_index_from_values(values, ix); + if (dict) { + assert(dict->ma_values == values); + dict->ma_used--; + } } Py_DECREF(old_value); } @@ -6760,9 +6735,9 @@ _PyObject_ManagedDictValidityCheck(PyObject *obj) { PyTypeObject *tp = Py_TYPE(obj); CHECK(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(obj); - if (_PyDictOrValues_IsValues(*dorv_ptr)) { - PyDictValues *values = _PyDictOrValues_GetValues(*dorv_ptr); + PyManagedDictPointer *managed_dict = _PyObject_ManagedDictPointer(obj); + if (_PyManagedDictPointer_IsValues(*managed_dict)) { + PyDictValues *values = _PyManagedDictPointer_GetValues(*managed_dict); int size = ((uint8_t *)values)[-2]; int count = 0; PyDictKeysObject *keys = CACHED_KEYS(tp); @@ -6774,8 +6749,8 @@ _PyObject_ManagedDictValidityCheck(PyObject *obj) CHECK(size == count); } else { - if (dorv_ptr->dict != NULL) { - CHECK(PyDict_Check(dorv_ptr->dict)); + if (managed_dict->dict != NULL) { + CHECK(PyDict_Check(managed_dict->dict)); } } return 1; @@ -6804,23 +6779,27 @@ _PyObject_IsInstanceDictEmpty(PyObject *obj) if (tp->tp_dictoffset == 0) { return 1; } - PyObject *dict; - if (tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) { - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(obj); - if (_PyDictOrValues_IsValues(dorv)) { + PyDictObject *dict; + if (tp->tp_flags & Py_TPFLAGS_INLINE_VALUES) { + PyDictValues *values = _PyObject_InlineValues(obj); + if (values->valid) { PyDictKeysObject *keys = CACHED_KEYS(tp); for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { - if (_PyDictOrValues_GetValues(dorv)->values[i] != NULL) { + if (values->values[i] != NULL) { return 0; } } return 1; } - dict = _PyDictOrValues_GetDict(dorv); + dict = _PyObject_ManagedDictPointer(obj)->dict; + } + else if (tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) { + PyManagedDictPointer* managed_dict = _PyObject_ManagedDictPointer(obj); + dict = managed_dict->dict; } else { PyObject **dictptr = _PyObject_ComputedDictPointer(obj); - dict = *dictptr; + dict = (PyDictObject *)*dictptr; } if (dict == NULL) { return 1; @@ -6828,23 +6807,6 @@ _PyObject_IsInstanceDictEmpty(PyObject *obj) return ((PyDictObject *)dict)->ma_used == 0; } -void -_PyObject_FreeInstanceAttributes(PyObject *self) -{ - PyTypeObject *tp = Py_TYPE(self); - assert(Py_TYPE(self)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(self); - if (!_PyDictOrValues_IsValues(dorv)) { - return; - } - PyDictValues *values = _PyDictOrValues_GetValues(dorv); - PyDictKeysObject *keys = CACHED_KEYS(tp); - for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { - Py_XDECREF(values->values[i]); - } - free_values(values, IS_DICT_SHARED((PyDictObject*)self)); -} - int PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg) { @@ -6852,74 +6814,101 @@ PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg) if((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { return 0; } - assert(tp->tp_dictoffset); - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(obj); - if (_PyDictOrValues_IsValues(dorv)) { - PyDictValues *values = _PyDictOrValues_GetValues(dorv); - PyDictKeysObject *keys = CACHED_KEYS(tp); - for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { - Py_VISIT(values->values[i]); + if (tp->tp_flags & Py_TPFLAGS_INLINE_VALUES) { + PyDictValues *values = _PyObject_InlineValues(obj); + if (values->valid) { + for (Py_ssize_t i = 0; i < values->capacity; i++) { + Py_VISIT(values->values[i]); + } + return 0; } } - else { - PyObject *dict = _PyDictOrValues_GetDict(dorv); - Py_VISIT(dict); - } + Py_VISIT(_PyObject_ManagedDictPointer(obj)->dict); return 0; } void PyObject_ClearManagedDict(PyObject *obj) { + assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + assert(_PyObject_InlineValuesConsistencyCheck(obj)); PyTypeObject *tp = Py_TYPE(obj); - if((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { - return; - } - PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(obj); - if (_PyDictOrValues_IsValues(*dorv_ptr)) { - PyDictValues *values = _PyDictOrValues_GetValues(*dorv_ptr); - PyDictKeysObject *keys = CACHED_KEYS(tp); - for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { - Py_CLEAR(values->values[i]); - } - dorv_ptr->dict = NULL; - free_values(values, IS_DICT_SHARED((PyDictObject*)obj)); - } - else { - PyObject *dict = dorv_ptr->dict; + if (tp->tp_flags & Py_TPFLAGS_INLINE_VALUES) { + PyDictObject *dict = _PyObject_ManagedDictPointer(obj)->dict; if (dict) { - dorv_ptr->dict = NULL; + _PyDict_DetachFromObject(dict, obj); + _PyObject_ManagedDictPointer(obj)->dict = NULL; Py_DECREF(dict); } + else { + PyDictValues *values = _PyObject_InlineValues(obj); + if (values->valid) { + for (Py_ssize_t i = 0; i < values->capacity; i++) { + Py_CLEAR(values->values[i]); + } + values->valid = 0; + } + } + } + else { + Py_CLEAR(_PyObject_ManagedDictPointer(obj)->dict); + } + assert(_PyObject_InlineValuesConsistencyCheck(obj)); +} + +int +_PyDict_DetachFromObject(PyDictObject *mp, PyObject *obj) +{ + assert(_PyObject_ManagedDictPointer(obj)->dict == mp); + assert(_PyObject_InlineValuesConsistencyCheck(obj)); + if (mp->ma_values == NULL || mp->ma_values != _PyObject_InlineValues(obj)) { + return 0; + } + assert(mp->ma_values->embedded == 1); + assert(mp->ma_values->valid == 1); + assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_INLINE_VALUES); + Py_BEGIN_CRITICAL_SECTION(mp); + mp->ma_values = copy_values(mp->ma_values); + _PyObject_InlineValues(obj)->valid = 0; + Py_END_CRITICAL_SECTION(); + if (mp->ma_values == NULL) { + return -1; } + assert(_PyObject_InlineValuesConsistencyCheck(obj)); + ASSERT_CONSISTENT(mp); + return 0; } PyObject * PyObject_GenericGetDict(PyObject *obj, void *context) { - PyObject *dict; PyInterpreterState *interp = _PyInterpreterState_GET(); PyTypeObject *tp = Py_TYPE(obj); if (_PyType_HasFeature(tp, Py_TPFLAGS_MANAGED_DICT)) { - PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(obj); - if (_PyDictOrValues_IsValues(*dorv_ptr)) { - PyDictValues *values = _PyDictOrValues_GetValues(*dorv_ptr); + PyManagedDictPointer *managed_dict = _PyObject_ManagedDictPointer(obj); + PyDictObject *dict = managed_dict->dict; + if (dict == NULL && + (tp->tp_flags & Py_TPFLAGS_INLINE_VALUES) && + _PyObject_InlineValues(obj)->valid + ) { + PyDictValues *values = _PyObject_InlineValues(obj); OBJECT_STAT_INC(dict_materialized_on_request); dict = make_dict_from_instance_attributes( interp, CACHED_KEYS(tp), values); if (dict != NULL) { - dorv_ptr->dict = dict; + managed_dict->dict = (PyDictObject *)dict; } } else { - dict = _PyDictOrValues_GetDict(*dorv_ptr); + dict = managed_dict->dict; if (dict == NULL) { dictkeys_incref(CACHED_KEYS(tp)); OBJECT_STAT_INC(dict_materialized_on_request); - dict = new_dict_with_shared_keys(interp, CACHED_KEYS(tp)); - dorv_ptr->dict = dict; + dict = (PyDictObject *)new_dict_with_shared_keys(interp, CACHED_KEYS(tp)); + managed_dict->dict = (PyDictObject *)dict; } } + return Py_XNewRef((PyObject *)dict); } else { PyObject **dictptr = _PyObject_ComputedDictPointer(obj); @@ -6928,7 +6917,7 @@ PyObject_GenericGetDict(PyObject *obj, void *context) "This object has no __dict__"); return NULL; } - dict = *dictptr; + PyObject *dict = *dictptr; if (dict == NULL) { PyTypeObject *tp = Py_TYPE(obj); if (_PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE) && CACHED_KEYS(tp)) { @@ -6940,8 +6929,8 @@ PyObject_GenericGetDict(PyObject *obj, void *context) *dictptr = dict = PyDict_New(); } } + return Py_XNewRef(dict); } - return Py_XNewRef(dict); } int @@ -6958,7 +6947,7 @@ _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr, assert(dictptr != NULL); dict = *dictptr; if (dict == NULL) { - assert(!_PyType_HasFeature(tp, Py_TPFLAGS_MANAGED_DICT)); + assert(!_PyType_HasFeature(tp, Py_TPFLAGS_INLINE_VALUES)); dictkeys_incref(cached); dict = new_dict_with_shared_keys(interp, cached); if (dict == NULL) @@ -7118,3 +7107,24 @@ _PyDict_SendEvent(int watcher_bits, watcher_bits >>= 1; } } + +#ifndef NDEBUG +static int +_PyObject_InlineValuesConsistencyCheck(PyObject *obj) +{ + if ((Py_TYPE(obj)->tp_flags & Py_TPFLAGS_INLINE_VALUES) == 0) { + return 1; + } + assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictObject *dict = (PyDictObject *)_PyObject_ManagedDictPointer(obj)->dict; + if (dict == NULL) { + return 1; + } + if (dict->ma_values == _PyObject_InlineValues(obj) || + _PyObject_InlineValues(obj)->valid == 0) { + return 1; + } + assert(0); + return 0; +} +#endif diff --git a/Objects/object.c b/Objects/object.c index b4f0fd4d7db941..60642d899bcafa 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1396,16 +1396,16 @@ _PyObject_GetDictPtr(PyObject *obj) if ((Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { return _PyObject_ComputedDictPointer(obj); } - PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(obj); - if (_PyDictOrValues_IsValues(*dorv_ptr)) { - PyObject *dict = _PyObject_MakeDictFromInstanceAttributes(obj, _PyDictOrValues_GetValues(*dorv_ptr)); + PyManagedDictPointer *managed_dict = _PyObject_ManagedDictPointer(obj); + if (managed_dict->dict == NULL && Py_TYPE(obj)->tp_flags & Py_TPFLAGS_INLINE_VALUES) { + PyDictObject *dict = (PyDictObject *)_PyObject_MakeDictFromInstanceAttributes(obj); if (dict == NULL) { PyErr_Clear(); return NULL; } - dorv_ptr->dict = dict; + managed_dict->dict = dict; } - return &dorv_ptr->dict; + return (PyObject **)&managed_dict->dict; } PyObject * @@ -1474,21 +1474,19 @@ _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) } } PyObject *dict; - if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT)) { - PyDictOrValues* dorv_ptr = _PyObject_DictOrValuesPointer(obj); - if (_PyDictOrValues_IsValues(*dorv_ptr)) { - PyDictValues *values = _PyDictOrValues_GetValues(*dorv_ptr); - PyObject *attr = _PyObject_GetInstanceAttribute(obj, values, name); - if (attr != NULL) { - *method = attr; - Py_XDECREF(descr); - return 0; - } - dict = NULL; - } - else { - dict = dorv_ptr->dict; + if ((tp->tp_flags & Py_TPFLAGS_INLINE_VALUES) && _PyObject_InlineValues(obj)->valid) { + PyDictValues *values = _PyObject_InlineValues(obj); + PyObject *attr = _PyObject_GetInstanceAttribute(obj, values, name); + if (attr != NULL) { + *method = attr; + Py_XDECREF(descr); + return 0; } + dict = NULL; + } + else if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT)) { + PyManagedDictPointer* managed_dict = _PyObject_ManagedDictPointer(obj); + dict = (PyObject *)managed_dict->dict; } else { PyObject **dictptr = _PyObject_ComputedDictPointer(obj); @@ -1581,29 +1579,27 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, } } if (dict == NULL) { - if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT)) { - PyDictOrValues* dorv_ptr = _PyObject_DictOrValuesPointer(obj); - if (_PyDictOrValues_IsValues(*dorv_ptr)) { - PyDictValues *values = _PyDictOrValues_GetValues(*dorv_ptr); - if (PyUnicode_CheckExact(name)) { - res = _PyObject_GetInstanceAttribute(obj, values, name); - if (res != NULL) { - goto done; - } - } - else { - dict = _PyObject_MakeDictFromInstanceAttributes(obj, values); - if (dict == NULL) { - res = NULL; - goto done; - } - dorv_ptr->dict = dict; + if ((tp->tp_flags & Py_TPFLAGS_INLINE_VALUES) && _PyObject_InlineValues(obj)->valid) { + PyDictValues *values = _PyObject_InlineValues(obj); + if (PyUnicode_CheckExact(name)) { + res = _PyObject_GetInstanceAttribute(obj, values, name); + if (res != NULL) { + goto done; } } else { - dict = _PyDictOrValues_GetDict(*dorv_ptr); + dict = (PyObject *)_PyObject_MakeDictFromInstanceAttributes(obj); + if (dict == NULL) { + res = NULL; + goto done; + } + _PyObject_ManagedDictPointer(obj)->dict = (PyDictObject *)dict; } } + else if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT)) { + PyManagedDictPointer* managed_dict = _PyObject_ManagedDictPointer(obj); + dict = (PyObject *)managed_dict->dict; + } else { PyObject **dictptr = _PyObject_ComputedDictPointer(obj); if (dictptr) { @@ -1697,22 +1693,14 @@ _PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name, if (dict == NULL) { PyObject **dictptr; - if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT)) { - PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(obj); - if (_PyDictOrValues_IsValues(*dorv_ptr)) { - res = _PyObject_StoreInstanceAttribute( - obj, _PyDictOrValues_GetValues(*dorv_ptr), name, value); - goto error_check; - } - dictptr = &dorv_ptr->dict; - if (*dictptr == NULL) { - if (_PyObject_InitInlineValues(obj, tp) < 0) { - goto done; - } - res = _PyObject_StoreInstanceAttribute( - obj, _PyDictOrValues_GetValues(*dorv_ptr), name, value); - goto error_check; - } + if ((tp->tp_flags & Py_TPFLAGS_INLINE_VALUES) && _PyObject_InlineValues(obj)->valid) { + res = _PyObject_StoreInstanceAttribute( + obj, _PyObject_InlineValues(obj), name, value); + goto error_check; + } + else if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT)) { + PyManagedDictPointer *managed_dict = _PyObject_ManagedDictPointer(obj); + dictptr = (PyObject **)&managed_dict->dict; } else { dictptr = _PyObject_ComputedDictPointer(obj); @@ -1783,9 +1771,9 @@ PyObject_GenericSetDict(PyObject *obj, PyObject *value, void *context) { PyObject **dictptr = _PyObject_GetDictPtr(obj); if (dictptr == NULL) { - if (_PyType_HasFeature(Py_TYPE(obj), Py_TPFLAGS_MANAGED_DICT) && - _PyDictOrValues_IsValues(*_PyObject_DictOrValuesPointer(obj))) - { + if (_PyType_HasFeature(Py_TYPE(obj), Py_TPFLAGS_INLINE_VALUES) && + _PyObject_ManagedDictPointer(obj)->dict == NULL + ) { /* Was unable to convert to dict */ PyErr_NoMemory(); } diff --git a/Objects/object_layout.md b/Objects/object_layout.md index 4f379bed8d77e2..352409425ee802 100644 --- a/Objects/object_layout.md +++ b/Objects/object_layout.md @@ -16,7 +16,45 @@ Since the introduction of the cycle GC, there has also been a pre-header. Before 3.11, this pre-header was two words in size. It should be considered opaque to all code except the cycle GC. -## 3.11 pre-header +### 3.13 + +In 3.13, the values array is embedded into the object, so there is no +need for a values pointer (it is just a fixed offset into the object). +So the pre-header is these two fields: + +* weakreflist +* dict_pointer + +If the object has no physical dictionary, then the ``dict_pointer`` +is set to `NULL`. + + +
+ 3.12 + +### 3.12 + +In 3.12, the pointer to the list of weak references is added to the +pre-header. In order to make space for it, the ``dict`` and ``values`` +pointers are combined into a single tagged pointer: + +* weakreflist +* dict_or_values + +If the object has no physical dictionary, then the ``dict_or_values`` +has its low bit set to one, and points to the values array. +If the object has a physical dictionary, then the ``dict_or_values`` +has its low bit set to zero, and points to the dictionary. + +The untagged form is chosen for the dictionary pointer, rather than +the values pointer, to enable the (legacy) C-API function +`_PyObject_GetDictPtr(PyObject *obj)` to work. +
+ +
+ 3.11 + +### 3.11 In 3.11 the pre-header was extended to include pointers to the VM managed ``__dict__``. The reason for moving the ``__dict__`` to the pre-header is that it allows @@ -33,27 +71,49 @@ The values pointer refers to the ``PyDictValues`` array which holds the values of the objects's attributes. Should the dictionary be needed, then ``values`` is set to ``NULL`` and the ``dict`` field points to the dictionary. +
-## 3.12 pre-header +## Layout of a "normal" Python object -In 3.12, the pointer to the list of weak references is added to the -pre-header. In order to make space for it, the ``dict`` and ``values`` -pointers are combined into a single tagged pointer: +A "normal" Python object is one that doesn't inherit from a builtin +class, doesn't have slots. + +### 3.13 + +In 3.13 the values are embedded into the object, as follows: * weakreflist * dict_or_values +* GC 1 +* GC 2 +* ob_refcnt +* ob_type +* Inlined values: + * Flags + * values 0 + * values 1 + * ... + * Insertion order bytes -If the object has no physical dictionary, then the ``dict_or_values`` -has its low bit set to one, and points to the values array. -If the object has a physical dictionary, then the ``dict_or_values`` -has its low bit set to zero, and points to the dictionary. +This has all the advantages of the layout used in 3.12, plus: +* Access to values is even faster as there is one less load +* Fast access is mostly maintained when the `__dict__` is materialized -The untagged form is chosen for the dictionary pointer, rather than -the values pointer, to enable the (legacy) C-API function -`_PyObject_GetDictPtr(PyObject *obj)` to work. +![Layout of "normal" object in 3.13](./object_layout_313.png) + +For objects with opaque parts defined by a C extension, +the layout is much the same as for 3.12 +![Layout of "full" object in 3.13](./object_layout_full_313.png) -## Layout of a "normal" Python object in 3.12: + +
+ 3.12 + +### 3.12: + +In 3.12, the header and pre-header form the entire object for "normal" +Python objects: * weakreflist * dict_or_values @@ -62,9 +122,6 @@ the values pointer, to enable the (legacy) C-API function * ob_refcnt * ob_type -For a "normal" Python object, one that doesn't inherit from a builtin -class or have slots, the header and pre-header form the entire object. - ![Layout of "normal" object in 3.12](./object_layout_312.png) There are several advantages to this layout: @@ -79,4 +136,6 @@ The full layout object, with an opaque part defined by a C extension, and `__slots__` looks like this: ![Layout of "full" object in 3.12](./object_layout_full_312.png) +
+ diff --git a/Objects/object_layout_312.gv b/Objects/object_layout_312.gv index c0068d78568524..731a25332b3ace 100644 --- a/Objects/object_layout_312.gv +++ b/Objects/object_layout_312.gv @@ -20,6 +20,7 @@ digraph ideal { shape = none label = < + diff --git a/Objects/object_layout_312.png b/Objects/object_layout_312.png index 396dab183b3e9b2f39edb49b033a612e66d3a09a..a63d095ea0b19ebebb86ccadb964278bcfe0648b 100644 GIT binary patch literal 33040 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 VMgU89l*m^wF@WUjRBn;ku|o^no_ILnQsw)Q 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 literal 30688 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 +

+ + + + + + + + + + + +
values
Insertion order
values[0]
values[1]
...
object
weakrefs
dict pointer
GC info 0
GC info 1
refcount
__class__
values flags
values[0]
values[1]
...
Insertion order
> + + ] + + class [ + shape = none + label = < + + + + + +
class
...
dict_offset
...
cached_keys
> + ] + + keys [label = "dictionary keys"; fillcolor="lightgreen"; style="filled"] + NULL [ label = " NULL"; shape="plain"] + object:w -> NULL + object:h -> class:head + object:dv -> NULL + class:k -> keys + + oop [ label = "pointer"; shape="plain"] + oop -> object:r +} diff --git a/Objects/object_layout_313.png b/Objects/object_layout_313.png new file mode 100644 index 0000000000000000000000000000000000000000..f7059c286c84e6cd9a71f59b640a628a110d80ac GIT binary patch literal 35055 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 + object + weakrefs + dict pointer + GC info 0 + GC info 1 + refcount + __class__ + opaque (extension) data + ... + __slot__ 0 + ... + > + ] + + oop [ label = "pointer"; shape="plain"] + oop -> object:r +} diff --git a/Objects/object_layout_full_313.png b/Objects/object_layout_full_313.png new file mode 100644 index 0000000000000000000000000000000000000000..7352ec69e5d8db2c59135cf39aa0e6f7dd323cc9 GIT binary patch literal 16983 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 T4t`JsK`0(ok$ZXg{Ehz)XB)p= literal 0 HcmV?d00001 diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 2ef79fbf17b329..6df9986b82e77c 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1861,7 +1861,7 @@ type_call(PyObject *self, PyObject *args, PyObject *kwds) PyObject * _PyType_NewManagedObject(PyTypeObject *type) { - assert(type->tp_flags & Py_TPFLAGS_MANAGED_DICT); + assert(type->tp_flags & Py_TPFLAGS_INLINE_VALUES); assert(_PyType_IS_GC(type)); assert(type->tp_new == PyBaseObject_Type.tp_new); assert(type->tp_alloc == PyType_GenericAlloc); @@ -1870,11 +1870,6 @@ _PyType_NewManagedObject(PyTypeObject *type) if (obj == NULL) { return PyErr_NoMemory(); } - _PyObject_DictOrValuesPointer(obj)->dict = NULL; - if (_PyObject_InitInlineValues(obj, type)) { - Py_DECREF(obj); - return NULL; - } return obj; } @@ -1888,9 +1883,13 @@ _PyType_AllocNoTrack(PyTypeObject *type, Py_ssize_t nitems) * flag to indicate when that is safe) it does not seem worth the memory * savings. An example type that doesn't need the +1 is a subclass of * tuple. See GH-100659 and GH-81381. */ - const size_t size = _PyObject_VAR_SIZE(type, nitems+1); + size_t size = _PyObject_VAR_SIZE(type, nitems+1); const size_t presize = _PyType_PreHeaderSize(type); + if (type->tp_flags & Py_TPFLAGS_INLINE_VALUES) { + assert(type->tp_itemsize == 0); + size += _PyInlineValuesSize(type); + } char *alloc = _PyObject_MallocWithType(type, size + presize); if (alloc == NULL) { return PyErr_NoMemory(); @@ -1911,6 +1910,9 @@ _PyType_AllocNoTrack(PyTypeObject *type, Py_ssize_t nitems) else { _PyObject_InitVar((PyVarObject *)obj, type, nitems); } + if (type->tp_flags & Py_TPFLAGS_INLINE_VALUES) { + _PyObject_InitInlineValues(obj, type); + } return obj; } @@ -2060,6 +2062,10 @@ subtype_clear(PyObject *self) if ((base->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { PyObject_ClearManagedDict(self); } + else { + assert((base->tp_flags & Py_TPFLAGS_INLINE_VALUES) == + (type->tp_flags & Py_TPFLAGS_INLINE_VALUES)); + } } else if (type->tp_dictoffset != base->tp_dictoffset) { PyObject **dictptr = _PyObject_ComputedDictPointer(self); @@ -2210,14 +2216,7 @@ subtype_dealloc(PyObject *self) /* If we added a dict, DECREF it, or free inline values. */ if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { - PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(self); - if (_PyDictOrValues_IsValues(*dorv_ptr)) { - _PyObject_FreeInstanceAttributes(self); - } - else { - Py_XDECREF(_PyDictOrValues_GetDict(*dorv_ptr)); - } - dorv_ptr->values = NULL; + PyObject_ClearManagedDict(self); } else if (type->tp_dictoffset && !base->tp_dictoffset) { PyObject **dictptr = _PyObject_ComputedDictPointer(self); @@ -3161,19 +3160,26 @@ subtype_setdict(PyObject *obj, PyObject *value, void *context) return func(descr, obj, value); } /* Almost like PyObject_GenericSetDict, but allow __dict__ to be deleted. */ - dictptr = _PyObject_GetDictPtr(obj); - if (dictptr == NULL) { - PyErr_SetString(PyExc_AttributeError, - "This object has no __dict__"); - return -1; - } if (value != NULL && !PyDict_Check(value)) { PyErr_Format(PyExc_TypeError, "__dict__ must be set to a dictionary, " "not a '%.200s'", Py_TYPE(value)->tp_name); return -1; } - Py_XSETREF(*dictptr, Py_XNewRef(value)); + if (Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT) { + PyObject_ClearManagedDict(obj); + _PyObject_ManagedDictPointer(obj)->dict = (PyDictObject *)Py_XNewRef(value); + } + else { + dictptr = _PyObject_ComputedDictPointer(obj); + if (dictptr == NULL) { + PyErr_SetString(PyExc_AttributeError, + "This object has no __dict__"); + return -1; + } + Py_CLEAR(*dictptr); + *dictptr = Py_XNewRef(value); + } return 0; } @@ -5849,10 +5855,6 @@ object_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (obj == NULL) { return NULL; } - if (_PyObject_InitializeDict(obj)) { - Py_DECREF(obj); - return NULL; - } return obj; } @@ -6036,6 +6038,11 @@ compatible_for_assignment(PyTypeObject* oldto, PyTypeObject* newto, const char* !same_slots_added(newbase, oldbase))) { goto differs; } + if ((oldto->tp_flags & Py_TPFLAGS_INLINE_VALUES) != + ((newto->tp_flags & Py_TPFLAGS_INLINE_VALUES))) + { + goto differs; + } /* The above does not check for the preheader */ if ((oldto->tp_flags & Py_TPFLAGS_PREHEADER) == ((newto->tp_flags & Py_TPFLAGS_PREHEADER))) @@ -6137,14 +6144,18 @@ object_set_class(PyObject *self, PyObject *value, void *closure) if (compatible_for_assignment(oldto, newto, "__class__")) { /* Changing the class will change the implicit dict keys, * so we must materialize the dictionary first. */ - assert((oldto->tp_flags & Py_TPFLAGS_PREHEADER) == (newto->tp_flags & Py_TPFLAGS_PREHEADER)); - _PyObject_GetDictPtr(self); - if (oldto->tp_flags & Py_TPFLAGS_MANAGED_DICT && - _PyDictOrValues_IsValues(*_PyObject_DictOrValuesPointer(self))) - { - /* Was unable to convert to dict */ - PyErr_NoMemory(); - return -1; + if (oldto->tp_flags & Py_TPFLAGS_INLINE_VALUES) { + PyDictObject *dict = _PyObject_ManagedDictPointer(self)->dict; + if (dict == NULL) { + dict = (PyDictObject *)_PyObject_MakeDictFromInstanceAttributes(self); + if (dict == NULL) { + return -1; + } + _PyObject_ManagedDictPointer(self)->dict = dict; + } + if (_PyDict_DetachFromObject(dict, self)) { + return -1; + } } if (newto->tp_flags & Py_TPFLAGS_HEAPTYPE) { Py_INCREF(newto); @@ -7774,6 +7785,9 @@ type_ready_managed_dict(PyTypeObject *type) return -1; } } + if (type->tp_itemsize == 0 && type->tp_basicsize == sizeof(PyObject)) { + type->tp_flags |= Py_TPFLAGS_INLINE_VALUES; + } return 0; } @@ -7901,6 +7915,8 @@ PyType_Ready(PyTypeObject *type) /* Historically, all static types were immutable. See bpo-43908 */ if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { type->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE; + /* Static types must be immortal */ + _Py_SetImmortalUntracked((PyObject *)type); } int res; diff --git a/Python/bytecodes.c b/Python/bytecodes.c index bfb378c4a41500..ce208aac9c7953 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -1897,14 +1897,12 @@ dummy_func( op(_CHECK_MANAGED_OBJECT_HAS_VALUES, (owner -- owner)) { assert(Py_TYPE(owner)->tp_dictoffset < 0); - assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictOrValues *dorv = _PyObject_DictOrValuesPointer(owner); - DEOPT_IF(!_PyDictOrValues_IsValues(*dorv) && !_PyObject_MakeInstanceAttributesFromDict(owner, dorv)); + assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_INLINE_VALUES); + DEOPT_IF(!_PyObject_InlineValues(owner)->valid); } split op(_LOAD_ATTR_INSTANCE_VALUE, (index/1, owner -- attr, null if (oparg & 1))) { - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); - attr = _PyDictOrValues_GetValues(dorv)->values[index]; + attr = _PyObject_InlineValues(owner)->values[index]; DEOPT_IF(attr == NULL); STAT_INC(LOAD_ATTR, hit); Py_INCREF(attr); @@ -1947,16 +1945,15 @@ dummy_func( op(_CHECK_ATTR_WITH_HINT, (owner -- owner)) { assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); - DEOPT_IF(_PyDictOrValues_IsValues(dorv)); - PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); + PyManagedDictPointer *managed_dict = _PyObject_ManagedDictPointer(owner); + PyDictObject *dict = managed_dict->dict; DEOPT_IF(dict == NULL); assert(PyDict_CheckExact((PyObject *)dict)); } op(_LOAD_ATTR_WITH_HINT, (hint/1, owner -- attr, null if (oparg & 1))) { - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); - PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); + PyManagedDictPointer *managed_dict = _PyObject_ManagedDictPointer(owner); + PyDictObject *dict = managed_dict->dict; DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1); if (DK_IS_UNICODE(dict->ma_keys)) { @@ -2070,16 +2067,17 @@ dummy_func( DISPATCH_INLINED(new_frame); } - op(_GUARD_DORV_VALUES, (owner -- owner)) { - assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); - DEOPT_IF(!_PyDictOrValues_IsValues(dorv)); + op(_GUARD_DORV_NO_DICT, (owner -- owner)) { + assert(Py_TYPE(owner)->tp_dictoffset < 0); + assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_INLINE_VALUES); + DEOPT_IF(_PyObject_ManagedDictPointer(owner)->dict); + DEOPT_IF(_PyObject_InlineValues(owner)->valid == 0); } op(_STORE_ATTR_INSTANCE_VALUE, (index/1, value, owner --)) { - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); STAT_INC(STORE_ATTR, hit); - PyDictValues *values = _PyDictOrValues_GetValues(dorv); + assert(_PyObject_ManagedDictPointer(owner)->dict == NULL); + PyDictValues *values = _PyObject_InlineValues(owner); PyObject *old_value = values->values[index]; values->values[index] = value; if (old_value == NULL) { @@ -2094,7 +2092,7 @@ dummy_func( macro(STORE_ATTR_INSTANCE_VALUE) = unused/1 + _GUARD_TYPE_VERSION + - _GUARD_DORV_VALUES + + _GUARD_DORV_NO_DICT + _STORE_ATTR_INSTANCE_VALUE; inst(STORE_ATTR_WITH_HINT, (unused/1, type_version/2, hint/1, value, owner --)) { @@ -2102,9 +2100,8 @@ dummy_func( assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version); assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); - DEOPT_IF(_PyDictOrValues_IsValues(dorv)); - PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); + PyManagedDictPointer *managed_dict = _PyObject_ManagedDictPointer(owner); + PyDictObject *dict = managed_dict->dict; DEOPT_IF(dict == NULL); assert(PyDict_CheckExact((PyObject *)dict)); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); @@ -2898,9 +2895,8 @@ dummy_func( } op(_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT, (owner -- owner)) { - assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictOrValues *dorv = _PyObject_DictOrValuesPointer(owner); - DEOPT_IF(!_PyDictOrValues_IsValues(*dorv) && !_PyObject_MakeInstanceAttributesFromDict(owner, dorv)); + assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_INLINE_VALUES); + DEOPT_IF(!_PyObject_InlineValues(owner)->valid); } op(_GUARD_KEYS_VERSION, (keys_version/2, owner -- owner)) { @@ -2972,10 +2968,9 @@ dummy_func( unused/2 + _LOAD_ATTR_NONDESCRIPTOR_NO_DICT; - op(_CHECK_ATTR_METHOD_LAZY_DICT, (owner -- owner)) { - Py_ssize_t dictoffset = Py_TYPE(owner)->tp_dictoffset; - assert(dictoffset > 0); - PyObject *dict = *(PyObject **)((char *)owner + dictoffset); + op(_CHECK_ATTR_METHOD_LAZY_DICT, (dictoffset/1, owner -- owner)) { + char *ptr = ((char *)owner) + MANAGED_DICT_OFFSET + dictoffset; + PyObject *dict = *(PyObject **)ptr; /* This object has a __dict__, just not yet created */ DEOPT_IF(dict != NULL); } @@ -2993,7 +2988,7 @@ dummy_func( unused/1 + _GUARD_TYPE_VERSION + _CHECK_ATTR_METHOD_LAZY_DICT + - unused/2 + + unused/1 + _LOAD_ATTR_METHOD_LAZY_DICT; inst(INSTRUMENTED_CALL, (unused/3 -- )) { @@ -3294,6 +3289,7 @@ dummy_func( DEOPT_IF(!PyType_Check(callable)); PyTypeObject *tp = (PyTypeObject *)callable; DEOPT_IF(tp->tp_version_tag != read_u32(cache->func_version)); + assert(tp->tp_flags & Py_TPFLAGS_INLINE_VALUES); PyHeapTypeObject *cls = (PyHeapTypeObject *)callable; PyFunctionObject *init = (PyFunctionObject *)cls->_spec_cache.init; PyCodeObject *code = (PyCodeObject *)init->func_code; diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index ce0dc235c54fcf..82f2171f1ede83 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -1753,9 +1753,8 @@ PyObject *owner; owner = stack_pointer[-1]; assert(Py_TYPE(owner)->tp_dictoffset < 0); - assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictOrValues *dorv = _PyObject_DictOrValuesPointer(owner); - if (!_PyDictOrValues_IsValues(*dorv) && !_PyObject_MakeInstanceAttributesFromDict(owner, dorv)) JUMP_TO_JUMP_TARGET(); + assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_INLINE_VALUES); + if (!_PyObject_InlineValues(owner)->valid) JUMP_TO_JUMP_TARGET(); break; } @@ -1766,8 +1765,7 @@ (void)null; owner = stack_pointer[-1]; uint16_t index = (uint16_t)CURRENT_OPERAND(); - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); - attr = _PyDictOrValues_GetValues(dorv)->values[index]; + attr = _PyObject_InlineValues(owner)->values[index]; if (attr == NULL) JUMP_TO_JUMP_TARGET(); STAT_INC(LOAD_ATTR, hit); Py_INCREF(attr); @@ -1784,8 +1782,7 @@ (void)null; owner = stack_pointer[-1]; uint16_t index = (uint16_t)CURRENT_OPERAND(); - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); - attr = _PyDictOrValues_GetValues(dorv)->values[index]; + attr = _PyObject_InlineValues(owner)->values[index]; if (attr == NULL) JUMP_TO_JUMP_TARGET(); STAT_INC(LOAD_ATTR, hit); Py_INCREF(attr); @@ -1837,9 +1834,8 @@ PyObject *owner; owner = stack_pointer[-1]; assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); - if (_PyDictOrValues_IsValues(dorv)) JUMP_TO_JUMP_TARGET(); - PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); + PyManagedDictPointer *managed_dict = _PyObject_ManagedDictPointer(owner); + PyDictObject *dict = managed_dict->dict; if (dict == NULL) JUMP_TO_JUMP_TARGET(); assert(PyDict_CheckExact((PyObject *)dict)); break; @@ -1852,8 +1848,8 @@ oparg = CURRENT_OPARG(); owner = stack_pointer[-1]; uint16_t hint = (uint16_t)CURRENT_OPERAND(); - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); - PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); + PyManagedDictPointer *managed_dict = _PyObject_ManagedDictPointer(owner); + PyDictObject *dict = managed_dict->dict; if (hint >= (size_t)dict->ma_keys->dk_nentries) JUMP_TO_JUMP_TARGET(); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1); if (DK_IS_UNICODE(dict->ma_keys)) { @@ -1967,12 +1963,13 @@ /* _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN is not a viable micro-op for tier 2 because it uses the 'this_instr' variable */ - case _GUARD_DORV_VALUES: { + case _GUARD_DORV_NO_DICT: { PyObject *owner; owner = stack_pointer[-1]; - assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); - if (!_PyDictOrValues_IsValues(dorv)) JUMP_TO_JUMP_TARGET(); + assert(Py_TYPE(owner)->tp_dictoffset < 0); + assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_INLINE_VALUES); + if (_PyObject_ManagedDictPointer(owner)->dict) JUMP_TO_JUMP_TARGET(); + if (_PyObject_InlineValues(owner)->valid == 0) JUMP_TO_JUMP_TARGET(); break; } @@ -1982,9 +1979,9 @@ owner = stack_pointer[-1]; value = stack_pointer[-2]; uint16_t index = (uint16_t)CURRENT_OPERAND(); - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); STAT_INC(STORE_ATTR, hit); - PyDictValues *values = _PyDictOrValues_GetValues(dorv); + assert(_PyObject_ManagedDictPointer(owner)->dict == NULL); + PyDictValues *values = _PyObject_InlineValues(owner); PyObject *old_value = values->values[index]; values->values[index] = value; if (old_value == NULL) { @@ -2568,9 +2565,8 @@ case _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT: { PyObject *owner; owner = stack_pointer[-1]; - assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictOrValues *dorv = _PyObject_DictOrValuesPointer(owner); - if (!_PyDictOrValues_IsValues(*dorv) && !_PyObject_MakeInstanceAttributesFromDict(owner, dorv)) JUMP_TO_JUMP_TARGET(); + assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_INLINE_VALUES); + if (!_PyObject_InlineValues(owner)->valid) JUMP_TO_JUMP_TARGET(); break; } @@ -2658,9 +2654,9 @@ case _CHECK_ATTR_METHOD_LAZY_DICT: { PyObject *owner; owner = stack_pointer[-1]; - Py_ssize_t dictoffset = Py_TYPE(owner)->tp_dictoffset; - assert(dictoffset > 0); - PyObject *dict = *(PyObject **)((char *)owner + dictoffset); + uint16_t dictoffset = (uint16_t)CURRENT_OPERAND(); + char *ptr = ((char *)owner) + MANAGED_DICT_OFFSET + dictoffset; + PyObject *dict = *(PyObject **)ptr; /* This object has a __dict__, just not yet created */ if (dict != NULL) JUMP_TO_JUMP_TARGET(); break; diff --git a/Python/gc.c b/Python/gc.c index a37c1b144e57e9..a48738835fface 100644 --- a/Python/gc.c +++ b/Python/gc.c @@ -2031,11 +2031,16 @@ gc_alloc(PyTypeObject *tp, size_t basicsize, size_t presize) return op; } + PyObject * _PyObject_GC_New(PyTypeObject *tp) { size_t presize = _PyType_PreHeaderSize(tp); - PyObject *op = gc_alloc(tp, _PyObject_SIZE(tp), presize); + size_t size = _PyObject_SIZE(tp); + if (_PyType_HasFeature(tp, Py_TPFLAGS_INLINE_VALUES)) { + size += _PyInlineValuesSize(tp); + } + PyObject *op = gc_alloc(tp, size, presize); if (op == NULL) { return NULL; } diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c index 4524382e4f689f..7e4137a8e342b1 100644 --- a/Python/gc_free_threading.c +++ b/Python/gc_free_threading.c @@ -1639,7 +1639,11 @@ PyObject * _PyObject_GC_New(PyTypeObject *tp) { size_t presize = _PyType_PreHeaderSize(tp); - PyObject *op = gc_alloc(tp, _PyObject_SIZE(tp), presize); + size_t size = _PyObject_SIZE(tp); + if (_PyType_HasFeature(tp, Py_TPFLAGS_INLINE_VALUES)) { + size += _PyInlineValuesSize(tp); + } + PyObject *op = gc_alloc(tp, size, presize); if (op == NULL) { return NULL; } diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index e8e2397b11cd48..6ee794a05b51d4 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -870,6 +870,7 @@ DEOPT_IF(!PyType_Check(callable), CALL); PyTypeObject *tp = (PyTypeObject *)callable; DEOPT_IF(tp->tp_version_tag != read_u32(cache->func_version), CALL); + assert(tp->tp_flags & Py_TPFLAGS_INLINE_VALUES); PyHeapTypeObject *cls = (PyHeapTypeObject *)callable; PyFunctionObject *init = (PyFunctionObject *)cls->_spec_cache.init; PyCodeObject *code = (PyCodeObject *)init->func_code; @@ -3680,15 +3681,13 @@ // _CHECK_MANAGED_OBJECT_HAS_VALUES { assert(Py_TYPE(owner)->tp_dictoffset < 0); - assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictOrValues *dorv = _PyObject_DictOrValuesPointer(owner); - DEOPT_IF(!_PyDictOrValues_IsValues(*dorv) && !_PyObject_MakeInstanceAttributesFromDict(owner, dorv), LOAD_ATTR); + assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_INLINE_VALUES); + DEOPT_IF(!_PyObject_InlineValues(owner)->valid, LOAD_ATTR); } // _LOAD_ATTR_INSTANCE_VALUE { uint16_t index = read_u16(&this_instr[4].cache); - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); - attr = _PyDictOrValues_GetValues(dorv)->values[index]; + attr = _PyObject_InlineValues(owner)->values[index]; DEOPT_IF(attr == NULL, LOAD_ATTR); STAT_INC(LOAD_ATTR, hit); Py_INCREF(attr); @@ -3721,13 +3720,13 @@ } // _CHECK_ATTR_METHOD_LAZY_DICT { - Py_ssize_t dictoffset = Py_TYPE(owner)->tp_dictoffset; - assert(dictoffset > 0); - PyObject *dict = *(PyObject **)((char *)owner + dictoffset); + uint16_t dictoffset = read_u16(&this_instr[4].cache); + char *ptr = ((char *)owner) + MANAGED_DICT_OFFSET + dictoffset; + PyObject *dict = *(PyObject **)ptr; /* This object has a __dict__, just not yet created */ DEOPT_IF(dict != NULL, LOAD_ATTR); } - /* Skip 2 cache entries */ + /* Skip 1 cache entry */ // _LOAD_ATTR_METHOD_LAZY_DICT { PyObject *descr = read_obj(&this_instr[6].cache); @@ -3798,9 +3797,8 @@ } // _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT { - assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictOrValues *dorv = _PyObject_DictOrValuesPointer(owner); - DEOPT_IF(!_PyDictOrValues_IsValues(*dorv) && !_PyObject_MakeInstanceAttributesFromDict(owner, dorv), LOAD_ATTR); + assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_INLINE_VALUES); + DEOPT_IF(!_PyObject_InlineValues(owner)->valid, LOAD_ATTR); } // _GUARD_KEYS_VERSION { @@ -3914,9 +3912,8 @@ } // _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT { - assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictOrValues *dorv = _PyObject_DictOrValuesPointer(owner); - DEOPT_IF(!_PyDictOrValues_IsValues(*dorv) && !_PyObject_MakeInstanceAttributesFromDict(owner, dorv), LOAD_ATTR); + assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_INLINE_VALUES); + DEOPT_IF(!_PyObject_InlineValues(owner)->valid, LOAD_ATTR); } // _GUARD_KEYS_VERSION { @@ -4026,17 +4023,16 @@ // _CHECK_ATTR_WITH_HINT { assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); - DEOPT_IF(_PyDictOrValues_IsValues(dorv), LOAD_ATTR); - PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); + PyManagedDictPointer *managed_dict = _PyObject_ManagedDictPointer(owner); + PyDictObject *dict = managed_dict->dict; DEOPT_IF(dict == NULL, LOAD_ATTR); assert(PyDict_CheckExact((PyObject *)dict)); } // _LOAD_ATTR_WITH_HINT { uint16_t hint = read_u16(&this_instr[4].cache); - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); - PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); + PyManagedDictPointer *managed_dict = _PyObject_ManagedDictPointer(owner); + PyDictObject *dict = managed_dict->dict; DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, LOAD_ATTR); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1); if (DK_IS_UNICODE(dict->ma_keys)) { @@ -5315,19 +5311,20 @@ assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); } - // _GUARD_DORV_VALUES + // _GUARD_DORV_NO_DICT { - assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); - DEOPT_IF(!_PyDictOrValues_IsValues(dorv), STORE_ATTR); + assert(Py_TYPE(owner)->tp_dictoffset < 0); + assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_INLINE_VALUES); + DEOPT_IF(_PyObject_ManagedDictPointer(owner)->dict, STORE_ATTR); + DEOPT_IF(_PyObject_InlineValues(owner)->valid == 0, STORE_ATTR); } // _STORE_ATTR_INSTANCE_VALUE value = stack_pointer[-2]; { uint16_t index = read_u16(&this_instr[4].cache); - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); STAT_INC(STORE_ATTR, hit); - PyDictValues *values = _PyDictOrValues_GetValues(dorv); + assert(_PyObject_ManagedDictPointer(owner)->dict == NULL); + PyDictValues *values = _PyObject_InlineValues(owner); PyObject *old_value = values->values[index]; values->values[index] = value; if (old_value == NULL) { @@ -5389,9 +5386,8 @@ assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); - DEOPT_IF(_PyDictOrValues_IsValues(dorv), STORE_ATTR); - PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); + PyManagedDictPointer *managed_dict = _PyObject_ManagedDictPointer(owner); + PyDictObject *dict = managed_dict->dict; DEOPT_IF(dict == NULL, STORE_ATTR); assert(PyDict_CheckExact((PyObject *)dict)); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index df73cc091dea26..b4a1da8aec14af 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -1104,7 +1104,7 @@ /* _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN is not a viable micro-op for tier 2 */ - case _GUARD_DORV_VALUES: { + case _GUARD_DORV_NO_DICT: { break; } diff --git a/Python/specialize.c b/Python/specialize.c index c1edf8842faf68..f1e32d05af7707 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -188,7 +188,7 @@ print_object_stats(FILE *out, ObjectStats *stats) fprintf(out, "Object allocations to 4 kbytes: %" PRIu64 "\n", stats->allocations4k); fprintf(out, "Object allocations over 4 kbytes: %" PRIu64 "\n", stats->allocations_big); fprintf(out, "Object frees: %" PRIu64 "\n", stats->frees); - fprintf(out, "Object new values: %" PRIu64 "\n", stats->new_values); + fprintf(out, "Object inline values: %" PRIu64 "\n", stats->inline_values); fprintf(out, "Object interpreter increfs: %" PRIu64 "\n", stats->interpreter_increfs); fprintf(out, "Object interpreter decrefs: %" PRIu64 "\n", stats->interpreter_decrefs); fprintf(out, "Object increfs: %" PRIu64 "\n", stats->increfs); @@ -197,7 +197,6 @@ print_object_stats(FILE *out, ObjectStats *stats) fprintf(out, "Object materialize dict (new key): %" PRIu64 "\n", stats->dict_materialized_new_key); fprintf(out, "Object materialize dict (too big): %" PRIu64 "\n", stats->dict_materialized_too_big); fprintf(out, "Object materialize dict (str subclass): %" PRIu64 "\n", stats->dict_materialized_str_subclass); - fprintf(out, "Object dematerialize dict: %" PRIu64 "\n", stats->dict_dematerialized); fprintf(out, "Object method cache hits: %" PRIu64 "\n", stats->type_cache_hits); fprintf(out, "Object method cache misses: %" PRIu64 "\n", stats->type_cache_misses); fprintf(out, "Object method cache collisions: %" PRIu64 "\n", stats->type_cache_collisions); @@ -479,12 +478,11 @@ _PyCode_Quicken(PyCodeObject *code) #define SPEC_FAIL_ATTR_NOT_MANAGED_DICT 18 #define SPEC_FAIL_ATTR_NON_STRING_OR_SPLIT 19 #define SPEC_FAIL_ATTR_MODULE_ATTR_NOT_FOUND 20 - #define SPEC_FAIL_ATTR_SHADOWED 21 #define SPEC_FAIL_ATTR_BUILTIN_CLASS_METHOD 22 #define SPEC_FAIL_ATTR_CLASS_METHOD_OBJ 23 #define SPEC_FAIL_ATTR_OBJECT_SLOT 24 -#define SPEC_FAIL_ATTR_HAS_MANAGED_DICT 25 + #define SPEC_FAIL_ATTR_INSTANCE_ATTRIBUTE 26 #define SPEC_FAIL_ATTR_METACLASS_ATTRIBUTE 27 #define SPEC_FAIL_ATTR_PROPERTY_NOT_PY_FUNCTION 28 @@ -558,6 +556,7 @@ _PyCode_Quicken(PyCodeObject *code) #define SPEC_FAIL_CALL_OPERATOR_WRAPPER 29 #define SPEC_FAIL_CALL_INIT_NOT_SIMPLE 30 #define SPEC_FAIL_CALL_METACLASS 31 +#define SPEC_FAIL_CALL_INIT_NOT_INLINE_VALUES 32 /* COMPARE_OP */ #define SPEC_FAIL_COMPARE_OP_DIFFERENT_TYPES 12 @@ -829,11 +828,7 @@ specialize_dict_access( return 0; } _PyAttrCache *cache = (_PyAttrCache *)(instr + 1); - PyDictOrValues *dorv = _PyObject_DictOrValuesPointer(owner); - if (_PyDictOrValues_IsValues(*dorv) || - _PyObject_MakeInstanceAttributesFromDict(owner, dorv)) - { - // Virtual dictionary + if (type->tp_flags & Py_TPFLAGS_INLINE_VALUES && _PyObject_InlineValues(owner)->valid) { PyDictKeysObject *keys = ((PyHeapTypeObject *)type)->ht_cached_keys; assert(PyUnicode_CheckExact(name)); Py_ssize_t index = _PyDictKeys_StringLookup(keys, name); @@ -850,7 +845,8 @@ specialize_dict_access( instr->op.code = values_op; } else { - PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(*dorv); + PyManagedDictPointer *managed_dict = _PyObject_ManagedDictPointer(owner); + PyDictObject *dict = managed_dict->dict; if (dict == NULL || !PyDict_CheckExact(dict)) { SPECIALIZATION_FAIL(base_op, SPEC_FAIL_NO_DICT); return 0; @@ -1258,15 +1254,8 @@ PyObject *descr, DescriptorClassification kind, bool is_method) assert(descr != NULL); assert((is_method && kind == METHOD) || (!is_method && kind == NON_DESCRIPTOR)); - if (owner_cls->tp_flags & Py_TPFLAGS_MANAGED_DICT) { - PyDictOrValues *dorv = _PyObject_DictOrValuesPointer(owner); + if (owner_cls->tp_flags & Py_TPFLAGS_INLINE_VALUES) { PyDictKeysObject *keys = ((PyHeapTypeObject *)owner_cls)->ht_cached_keys; - if (!_PyDictOrValues_IsValues(*dorv) && - !_PyObject_MakeInstanceAttributesFromDict(owner, dorv)) - { - SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_HAS_MANAGED_DICT); - return 0; - } Py_ssize_t index = _PyDictKeys_StringLookup(keys, name); if (index != DKIX_EMPTY) { SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_SHADOWED); @@ -1282,10 +1271,16 @@ PyObject *descr, DescriptorClassification kind, bool is_method) instr->op.code = is_method ? LOAD_ATTR_METHOD_WITH_VALUES : LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES; } else { - Py_ssize_t dictoffset = owner_cls->tp_dictoffset; - if (dictoffset < 0 || dictoffset > INT16_MAX) { - SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_RANGE); - return 0; + Py_ssize_t dictoffset; + if (owner_cls->tp_flags & Py_TPFLAGS_MANAGED_DICT) { + dictoffset = MANAGED_DICT_OFFSET; + } + else { + dictoffset = owner_cls->tp_dictoffset; + if (dictoffset < 0 || dictoffset > INT16_MAX + MANAGED_DICT_OFFSET) { + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_RANGE); + return 0; + } } if (dictoffset == 0) { instr->op.code = is_method ? LOAD_ATTR_METHOD_NO_DICT : LOAD_ATTR_NONDESCRIPTOR_NO_DICT; @@ -1296,8 +1291,12 @@ PyObject *descr, DescriptorClassification kind, bool is_method) SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_NOT_MANAGED_DICT); return 0; } - assert(owner_cls->tp_dictoffset > 0); - assert(owner_cls->tp_dictoffset <= INT16_MAX); + /* Cache entries must be unsigned values, so we offset the + * dictoffset by MANAGED_DICT_OFFSET. + * We do the reverese offset in LOAD_ATTR_METHOD_LAZY_DICT */ + dictoffset -= MANAGED_DICT_OFFSET; + assert(((uint16_t)dictoffset) == dictoffset); + cache->dict_offset = (uint16_t)dictoffset; instr->op.code = LOAD_ATTR_METHOD_LAZY_DICT; } else { @@ -1729,8 +1728,8 @@ get_init_for_simple_managed_python_class(PyTypeObject *tp) SPECIALIZATION_FAIL(CALL, SPEC_FAIL_OVERRIDDEN); return NULL; } - if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { - SPECIALIZATION_FAIL(CALL, SPEC_FAIL_NO_DICT); + if ((tp->tp_flags & Py_TPFLAGS_INLINE_VALUES) == 0) { + SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_INIT_NOT_INLINE_VALUES); return NULL; } if (!(tp->tp_flags & Py_TPFLAGS_HEAPTYPE)) { diff --git a/Tools/cases_generator/analyzer.py b/Tools/cases_generator/analyzer.py index ddafcf99ca1e37..4261378d459107 100644 --- a/Tools/cases_generator/analyzer.py +++ b/Tools/cases_generator/analyzer.py @@ -359,11 +359,10 @@ def has_error_without_pop(op: parser.InstDef) -> bool: NON_ESCAPING_FUNCTIONS = ( "Py_INCREF", - "_PyDictOrValues_IsValues", - "_PyObject_DictOrValuesPointer", - "_PyDictOrValues_GetValues", + "_PyManagedDictPointer_IsValues", + "_PyObject_ManagedDictPointer", + "_PyObject_InlineValues", "_PyDictValues_AddToInsertionOrder", - "_PyObject_MakeInstanceAttributesFromDict", "Py_DECREF", "_Py_DECREF_SPECIALIZED", "DECREF_INPUTS_AND_REUSE_FLOAT", diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index 656667ac93970c..74165acd831131 100755 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -66,10 +66,12 @@ def _type_unsigned_short_ptr(): def _type_unsigned_int_ptr(): return gdb.lookup_type('unsigned int').pointer() - def _sizeof_void_p(): return gdb.lookup_type('void').pointer().sizeof +def _sizeof_pyobject(): + return gdb.lookup_type('PyObject').sizeof + def _managed_dict_offset(): # See pycore_object.h pyobj = gdb.lookup_type("PyObject") @@ -79,6 +81,7 @@ def _managed_dict_offset(): return -3 * _sizeof_void_p() +Py_TPFLAGS_INLINE_VALUES = (1 << 2) Py_TPFLAGS_MANAGED_DICT = (1 << 4) Py_TPFLAGS_HEAPTYPE = (1 << 9) Py_TPFLAGS_LONG_SUBCLASS = (1 << 24) @@ -493,11 +496,12 @@ def get_keys_values(self): has_values = int_from_int(typeobj.field('tp_flags')) & Py_TPFLAGS_MANAGED_DICT if not has_values: return None - ptr = self._gdbval.cast(_type_char_ptr()) + _managed_dict_offset() - char_ptr = ptr.cast(_type_char_ptr().pointer()).dereference() - if (int(char_ptr) & 1) == 0: + obj_ptr = self._gdbval.cast(_type_char_ptr()) + dict_ptr_ptr = obj_ptr + _managed_dict_offset() + dict_ptr = dict_ptr_ptr.cast(_type_char_ptr().pointer()).dereference() + if int(dict_ptr): return None - char_ptr += 1 + char_ptr = obj_ptr + _sizeof_pyobject() values_ptr = char_ptr.cast(gdb.lookup_type("PyDictValues").pointer()) values = values_ptr['values'] return PyKeysValuesPair(self.get_cached_keys(), values) diff --git a/Tools/scripts/summarize_stats.py b/Tools/scripts/summarize_stats.py index 8dc590b4b89a88..f7ed98ff6045ab 100644 --- a/Tools/scripts/summarize_stats.py +++ b/Tools/scripts/summarize_stats.py @@ -394,7 +394,7 @@ def get_call_stats(self) -> dict[str, int]: return result def get_object_stats(self) -> dict[str, tuple[int, int]]: - total_materializations = self._data.get("Object new values", 0) + total_materializations = self._data.get("Object inline values", 0) total_allocations = self._data.get("Object allocations", 0) + self._data.get( "Object allocations from freelist", 0 ) @@ -1094,8 +1094,7 @@ def calc_object_stats_table(stats: Stats) -> Rows: Below, "allocations" means "allocations that are not from a freelist". Total allocations = "Allocations from freelist" + "Allocations". - "New values" is the number of values arrays created for objects with - managed dicts. + "Inline values" is the number of values arrays inlined into objects. The cache hit/miss numbers are for the MRO cache, split into dunder and other names. From e3b6f287fc5d195859c29661145873c638c6dc83 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 2 Apr 2024 13:29:39 +0200 Subject: [PATCH 11/11] gh-113317: Argument Clinic: Add libclinic.return_converters (#117451) Move the following converter classes to libclinic.return_converters: * CReturnConverter * CReturnConverterAutoRegister * Py_ssize_t_return_converter * bool_return_converter * double_return_converter * float_return_converter * int_return_converter * long_return_converter * size_t_return_converter * unsigned_int_return_converter * unsigned_long_return_converter Move also the add_c_return_converter() function there. --- Tools/clinic/clinic.py | 183 +------------------- Tools/clinic/libclinic/function.py | 3 +- Tools/clinic/libclinic/return_converters.py | 173 ++++++++++++++++++ 3 files changed, 178 insertions(+), 181 deletions(-) create mode 100644 Tools/clinic/libclinic/return_converters.py diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index a4e004d5b124d1..97b1f46a13411b 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -60,6 +60,9 @@ from libclinic.converters import ( self_converter, defining_class_converter, object_converter, buffer, robuffer, rwbuffer, correct_name_for_self) +from libclinic.return_converters import ( + CReturnConverter, return_converters, + int_return_converter, ReturnConverterType) # TODO: @@ -2088,186 +2091,6 @@ def parse(self, block: Block) -> None: """.strip().split()) -ReturnConverterType = Callable[..., "CReturnConverter"] - - -# maps strings to callables. -# these callables must be of the form: -# def foo(*, ...) -# The callable may have any number of keyword-only parameters. -# The callable must return a CReturnConverter object. -# The callable should not call builtins.print. -ReturnConverterDict = dict[str, ReturnConverterType] -return_converters: ReturnConverterDict = {} - - -def add_c_return_converter( - f: ReturnConverterType, - name: str | None = None -) -> ReturnConverterType: - if not name: - name = f.__name__ - if not name.endswith('_return_converter'): - return f - name = name.removesuffix('_return_converter') - return_converters[name] = f - return f - - -class CReturnConverterAutoRegister(type): - def __init__( - cls: ReturnConverterType, - name: str, - bases: tuple[type[object], ...], - classdict: dict[str, Any] - ) -> None: - add_c_return_converter(cls) - - -class CReturnConverter(metaclass=CReturnConverterAutoRegister): - - # The C type to use for this variable. - # 'type' should be a Python string specifying the type, e.g. "int". - # If this is a pointer type, the type string should end with ' *'. - type = 'PyObject *' - - # The Python default value for this parameter, as a Python value. - # Or the magic value "unspecified" if there is no default. - default: object = None - - def __init__( - self, - *, - py_default: str | None = None, - **kwargs: Any - ) -> None: - self.py_default = py_default - try: - self.return_converter_init(**kwargs) - except TypeError as e: - s = ', '.join(name + '=' + repr(value) for name, value in kwargs.items()) - sys.exit(self.__class__.__name__ + '(' + s + ')\n' + str(e)) - - def return_converter_init(self) -> None: ... - - def declare(self, data: CRenderData) -> None: - line: list[str] = [] - add = line.append - add(self.type) - if not self.type.endswith('*'): - add(' ') - add(data.converter_retval + ';') - data.declarations.append(''.join(line)) - data.return_value = data.converter_retval - - def err_occurred_if( - self, - expr: str, - data: CRenderData - ) -> None: - line = f'if (({expr}) && PyErr_Occurred()) {{\n goto exit;\n}}\n' - data.return_conversion.append(line) - - def err_occurred_if_null_pointer( - self, - variable: str, - data: CRenderData - ) -> None: - line = f'if ({variable} == NULL) {{\n goto exit;\n}}\n' - data.return_conversion.append(line) - - def render( - self, - function: Function, - data: CRenderData - ) -> None: ... - - -add_c_return_converter(CReturnConverter, 'object') - - -class bool_return_converter(CReturnConverter): - type = 'int' - - def render( - self, - function: Function, - data: CRenderData - ) -> None: - self.declare(data) - self.err_occurred_if(f"{data.converter_retval} == -1", data) - data.return_conversion.append( - f'return_value = PyBool_FromLong((long){data.converter_retval});\n' - ) - - -class long_return_converter(CReturnConverter): - type = 'long' - conversion_fn = 'PyLong_FromLong' - cast = '' - unsigned_cast = '' - - def render( - self, - function: Function, - data: CRenderData - ) -> None: - self.declare(data) - self.err_occurred_if(f"{data.converter_retval} == {self.unsigned_cast}-1", data) - data.return_conversion.append( - f'return_value = {self.conversion_fn}({self.cast}{data.converter_retval});\n' - ) - - -class int_return_converter(long_return_converter): - type = 'int' - cast = '(long)' - - -class unsigned_long_return_converter(long_return_converter): - type = 'unsigned long' - conversion_fn = 'PyLong_FromUnsignedLong' - unsigned_cast = '(unsigned long)' - - -class unsigned_int_return_converter(unsigned_long_return_converter): - type = 'unsigned int' - cast = '(unsigned long)' - unsigned_cast = '(unsigned int)' - - -class Py_ssize_t_return_converter(long_return_converter): - type = 'Py_ssize_t' - conversion_fn = 'PyLong_FromSsize_t' - - -class size_t_return_converter(long_return_converter): - type = 'size_t' - conversion_fn = 'PyLong_FromSize_t' - unsigned_cast = '(size_t)' - - -class double_return_converter(CReturnConverter): - type = 'double' - cast = '' - - def render( - self, - function: Function, - data: CRenderData - ) -> None: - self.declare(data) - self.err_occurred_if(f"{data.converter_retval} == -1.0", data) - data.return_conversion.append( - f'return_value = PyFloat_FromDouble({self.cast}{data.converter_retval});\n' - ) - - -class float_return_converter(double_return_converter): - type = 'float' - cast = '(double)' - - def eval_ast_expr( node: ast.expr, *, diff --git a/Tools/clinic/libclinic/function.py b/Tools/clinic/libclinic/function.py index b0dd08446e802d..1bfaad00cd0f08 100644 --- a/Tools/clinic/libclinic/function.py +++ b/Tools/clinic/libclinic/function.py @@ -6,9 +6,10 @@ import inspect from typing import Final, Any, TYPE_CHECKING if TYPE_CHECKING: - from clinic import Clinic, CReturnConverter + from clinic import Clinic from libclinic.converter import CConverter from libclinic.converters import self_converter + from libclinic.return_converters import CReturnConverter from libclinic import VersionTuple, unspecified diff --git a/Tools/clinic/libclinic/return_converters.py b/Tools/clinic/libclinic/return_converters.py new file mode 100644 index 00000000000000..7bdd257cfa3443 --- /dev/null +++ b/Tools/clinic/libclinic/return_converters.py @@ -0,0 +1,173 @@ +import sys +from collections.abc import Callable +from libclinic.crenderdata import CRenderData +from libclinic.function import Function +from typing import Any + + +ReturnConverterType = Callable[..., "CReturnConverter"] + + +# maps strings to callables. +# these callables must be of the form: +# def foo(*, ...) +# The callable may have any number of keyword-only parameters. +# The callable must return a CReturnConverter object. +# The callable should not call builtins.print. +ReturnConverterDict = dict[str, ReturnConverterType] +return_converters: ReturnConverterDict = {} + + +def add_c_return_converter( + f: ReturnConverterType, + name: str | None = None +) -> ReturnConverterType: + if not name: + name = f.__name__ + if not name.endswith('_return_converter'): + return f + name = name.removesuffix('_return_converter') + return_converters[name] = f + return f + + +class CReturnConverterAutoRegister(type): + def __init__( + cls: ReturnConverterType, + name: str, + bases: tuple[type[object], ...], + classdict: dict[str, Any] + ) -> None: + add_c_return_converter(cls) + + +class CReturnConverter(metaclass=CReturnConverterAutoRegister): + + # The C type to use for this variable. + # 'type' should be a Python string specifying the type, e.g. "int". + # If this is a pointer type, the type string should end with ' *'. + type = 'PyObject *' + + # The Python default value for this parameter, as a Python value. + # Or the magic value "unspecified" if there is no default. + default: object = None + + def __init__( + self, + *, + py_default: str | None = None, + **kwargs: Any + ) -> None: + self.py_default = py_default + try: + self.return_converter_init(**kwargs) + except TypeError as e: + s = ', '.join(name + '=' + repr(value) for name, value in kwargs.items()) + sys.exit(self.__class__.__name__ + '(' + s + ')\n' + str(e)) + + def return_converter_init(self) -> None: ... + + def declare(self, data: CRenderData) -> None: + line: list[str] = [] + add = line.append + add(self.type) + if not self.type.endswith('*'): + add(' ') + add(data.converter_retval + ';') + data.declarations.append(''.join(line)) + data.return_value = data.converter_retval + + def err_occurred_if( + self, + expr: str, + data: CRenderData + ) -> None: + line = f'if (({expr}) && PyErr_Occurred()) {{\n goto exit;\n}}\n' + data.return_conversion.append(line) + + def err_occurred_if_null_pointer( + self, + variable: str, + data: CRenderData + ) -> None: + line = f'if ({variable} == NULL) {{\n goto exit;\n}}\n' + data.return_conversion.append(line) + + def render( + self, + function: Function, + data: CRenderData + ) -> None: ... + + +add_c_return_converter(CReturnConverter, 'object') + + +class bool_return_converter(CReturnConverter): + type = 'int' + + def render(self, function: Function, data: CRenderData) -> None: + self.declare(data) + self.err_occurred_if(f"{data.converter_retval} == -1", data) + data.return_conversion.append( + f'return_value = PyBool_FromLong((long){data.converter_retval});\n' + ) + + +class long_return_converter(CReturnConverter): + type = 'long' + conversion_fn = 'PyLong_FromLong' + cast = '' + unsigned_cast = '' + + def render(self, function: Function, data: CRenderData) -> None: + self.declare(data) + self.err_occurred_if(f"{data.converter_retval} == {self.unsigned_cast}-1", data) + data.return_conversion.append( + f'return_value = {self.conversion_fn}({self.cast}{data.converter_retval});\n' + ) + + +class int_return_converter(long_return_converter): + type = 'int' + cast = '(long)' + + +class unsigned_long_return_converter(long_return_converter): + type = 'unsigned long' + conversion_fn = 'PyLong_FromUnsignedLong' + unsigned_cast = '(unsigned long)' + + +class unsigned_int_return_converter(unsigned_long_return_converter): + type = 'unsigned int' + cast = '(unsigned long)' + unsigned_cast = '(unsigned int)' + + +class Py_ssize_t_return_converter(long_return_converter): + type = 'Py_ssize_t' + conversion_fn = 'PyLong_FromSsize_t' + + +class size_t_return_converter(long_return_converter): + type = 'size_t' + conversion_fn = 'PyLong_FromSize_t' + unsigned_cast = '(size_t)' + + +class double_return_converter(CReturnConverter): + type = 'double' + cast = '' + + def render(self, function: Function, data: CRenderData) -> None: + self.declare(data) + self.err_occurred_if(f"{data.converter_retval} == -1.0", data) + data.return_conversion.append( + f'return_value = PyFloat_FromDouble({self.cast}{data.converter_retval});\n' + ) + + +class float_return_converter(double_return_converter): + type = 'float' + cast = '(double)'