Imported Upstream version 3.9.10 upstream/3.9.10
authorDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 25 Jan 2022 23:27:56 +0000 (08:27 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 25 Jan 2022 23:27:56 +0000 (08:27 +0900)
176 files changed:
Doc/Makefile
Doc/c-api/unicode.rst
Doc/conf.py
Doc/copyright.rst
Doc/distutils/sourcedist.rst
Doc/extending/extending.rst
Doc/faq/library.rst
Doc/faq/programming.rst
Doc/howto/logging-cookbook.rst
Doc/library/2to3.rst
Doc/library/asyncio-eventloop.rst
Doc/library/asyncio-future.rst
Doc/library/asyncio-task.rst
Doc/library/concurrent.futures.rst
Doc/library/ctypes.rst
Doc/library/dataclasses.rst
Doc/library/datetime.rst
Doc/library/enum.rst
Doc/library/functions.rst
Doc/library/hashlib.rst
Doc/library/json.rst
Doc/library/logging.config.rst
Doc/library/logging.handlers.rst
Doc/library/logging.rst
Doc/library/multiprocessing.rst
Doc/library/os.path.rst
Doc/library/os.rst
Doc/library/pdb.rst
Doc/library/sqlite3.rst
Doc/library/statistics.rst
Doc/library/stdtypes.rst
Doc/library/sys.rst
Doc/library/sysconfig.rst
Doc/library/typing.rst
Doc/library/unittest.mock.rst
Doc/library/unittest.rst
Doc/library/urllib.parse.rst
Doc/library/warnings.rst
Doc/library/zipimport.rst
Doc/license.rst
Doc/reference/datamodel.rst
Doc/reference/expressions.rst
Doc/requirements.txt
Doc/tools/static/switchers.js [deleted file]
Doc/tools/susp-ignored.csv
Doc/tools/templates/dummy.html
Doc/tools/templates/indexsidebar.html
Doc/tools/templates/layout.html
Doc/tutorial/classes.rst
Doc/tutorial/errors.rst
Doc/tutorial/floatingpoint.rst
Doc/tutorial/stdlib.rst
Include/Python.h
Include/cpython/pystate.h
Include/internal/pycore_ceval.h
Include/patchlevel.h
LICENSE
Lib/argparse.py
Lib/asyncio/base_events.py
Lib/asyncio/events.py
Lib/asyncio/tasks.py
Lib/asyncio/windows_events.py
Lib/concurrent/futures/_base.py
Lib/concurrent/futures/process.py
Lib/ctypes/test/test_functions.py
Lib/dataclasses.py
Lib/functools.py
Lib/importlib/metadata.py
Lib/json/__init__.py
Lib/json/encoder.py
Lib/logging/handlers.py
Lib/pydoc_data/topics.py
Lib/signal.py
Lib/sqlite3/__init__.py
Lib/statistics.py
Lib/test/libregrtest/runtest_mp.py
Lib/test/make_ssl_certs.py
Lib/test/test_argparse.py
Lib/test/test_asyncio/test_base_events.py
Lib/test/test_asyncio/test_locks.py
Lib/test/test_asyncio/test_proactor_events.py
Lib/test/test_asyncio/test_selector_events.py
Lib/test/test_asyncio/test_tasks.py
Lib/test/test_capi.py
Lib/test/test_collections.py
Lib/test/test_concurrent_futures.py
Lib/test/test_dataclasses.py
Lib/test/test_descr.py
Lib/test/test_email/test_email.py
Lib/test/test_exceptions.py
Lib/test/test_functools.py
Lib/test/test_gdb.py
Lib/test/test_hashlib.py
Lib/test/test_imaplib.py
Lib/test/test_importlib/test_metadata_api.py
Lib/test/test_logging.py
Lib/test/test_os.py
Lib/test/test_pathlib.py
Lib/test/test_poplib.py
Lib/test/test_queue.py
Lib/test/test_signal.py
Lib/test/test_smtplib.py
Lib/test/test_ssl.py
Lib/test/test_syntax.py
Lib/test/test_sys.py
Lib/test/test_time.py
Lib/test/test_tools/test_md5sum.py
Lib/test/test_traceback.py
Lib/test/test_types.py
Lib/test/test_typing.py
Lib/test/test_urllib2_localnet.py
Lib/test/test_xml_etree_c.py
Lib/tkinter/test/test_tkinter/test_misc.py
Lib/traceback.py
Lib/turtle.py
Lib/types.py
Lib/unittest/async_case.py
Lib/unittest/case.py
Lib/unittest/runner.py
Lib/unittest/test/test_case.py
Lib/unittest/test/test_program.py
Lib/unittest/test/test_result.py
Lib/unittest/test/testmock/testpatch.py
Lib/venv/__init__.py
Mac/BuildScript/0001-Darwin-platform-allows-to-build-on-releases-before-Y.patch [deleted file]
Mac/BuildScript/bpo-44828-filedialog-crash-monterey.patch [deleted file]
Mac/BuildScript/build-installer.py
Mac/IDLE/IDLE.app/Contents/Info.plist
Mac/PythonLauncher/Info.plist.in
Mac/PythonLauncher/doscript.m
Mac/Resources/app/Info.plist.in
Makefile.pre.in
Misc/NEWS
Misc/README.valgrind
Modules/_asynciomodule.c
Modules/_cursesmodule.c
Modules/_elementtree.c
Modules/_hashopenssl.c
Modules/_testcapimodule.c
Modules/clinic/signalmodule.c.h
Modules/gcmodule.c
Modules/mathmodule.c
Modules/posixmodule.c
Modules/posixmodule.h
Modules/signalmodule.c
Modules/zlibmodule.c
Objects/odictobject.c
PC/launcher.c
PC/layout/support/appxmanifest.py
PC/python_ver_rc.h
PCbuild/Directory.Build.props [new file with mode: 0644]
PCbuild/Directory.Build.targets [new file with mode: 0644]
PCbuild/get_externals.bat
PCbuild/python.props
Parser/pegen/parse.c
Parser/pegen/pegen.c
Python/ceval.c
Python/errors.c
Python/getcopyright.c
Python/pystate.c
Python/pythonrun.c
Python/sysmodule.c
Python/traceback.c
README.rst
Tools/gdb/libpython.py
Tools/peg_generator/pegen/c_generator.py
Tools/peg_generator/pegen/grammar_parser.py
Tools/peg_generator/pegen/python_generator.py
Tools/ssl/multissltests.py
aclocal.m4
config.guess
config.sub
configure
configure.ac
pyconfig.h.in
setup.py

index 57763fc..3cf2040 100644 (file)
@@ -223,12 +223,12 @@ serve:
 
 # for development releases: always build
 autobuild-dev:
-       make dist SPHINXOPTS='$(SPHINXOPTS) -Ea -A daily=1 -A switchers=1'
+       make dist SPHINXOPTS='$(SPHINXOPTS) -Ea -A daily=1'
        -make suspicious
 
 # for quick rebuilds (HTML only)
 autobuild-dev-html:
-       make html SPHINXOPTS='$(SPHINXOPTS) -Ea -A daily=1 -A switchers=1'
+       make html SPHINXOPTS='$(SPHINXOPTS) -Ea -A daily=1'
 
 # for stable releases: only build if not in pre-release stage (alpha, beta)
 # release candidate downloads are okay, since the stable tree can be in that stage
index 8e23704..0d13d94 100644 (file)
@@ -268,57 +268,57 @@ are available through these macros which are mapped to C functions depending on
 the Python configuration.
 
 
-.. c:function:: int Py_UNICODE_ISSPACE(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISSPACE(Py_UCS4 ch)
 
    Return ``1`` or ``0`` depending on whether *ch* is a whitespace character.
 
 
-.. c:function:: int Py_UNICODE_ISLOWER(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISLOWER(Py_UCS4 ch)
 
    Return ``1`` or ``0`` depending on whether *ch* is a lowercase character.
 
 
-.. c:function:: int Py_UNICODE_ISUPPER(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISUPPER(Py_UCS4 ch)
 
    Return ``1`` or ``0`` depending on whether *ch* is an uppercase character.
 
 
-.. c:function:: int Py_UNICODE_ISTITLE(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISTITLE(Py_UCS4 ch)
 
    Return ``1`` or ``0`` depending on whether *ch* is a titlecase character.
 
 
-.. c:function:: int Py_UNICODE_ISLINEBREAK(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISLINEBREAK(Py_UCS4 ch)
 
    Return ``1`` or ``0`` depending on whether *ch* is a linebreak character.
 
 
-.. c:function:: int Py_UNICODE_ISDECIMAL(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISDECIMAL(Py_UCS4 ch)
 
    Return ``1`` or ``0`` depending on whether *ch* is a decimal character.
 
 
-.. c:function:: int Py_UNICODE_ISDIGIT(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISDIGIT(Py_UCS4 ch)
 
    Return ``1`` or ``0`` depending on whether *ch* is a digit character.
 
 
-.. c:function:: int Py_UNICODE_ISNUMERIC(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISNUMERIC(Py_UCS4 ch)
 
    Return ``1`` or ``0`` depending on whether *ch* is a numeric character.
 
 
-.. c:function:: int Py_UNICODE_ISALPHA(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISALPHA(Py_UCS4 ch)
 
    Return ``1`` or ``0`` depending on whether *ch* is an alphabetic character.
 
 
-.. c:function:: int Py_UNICODE_ISALNUM(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISALNUM(Py_UCS4 ch)
 
    Return ``1`` or ``0`` depending on whether *ch* is an alphanumeric character.
 
 
-.. c:function:: int Py_UNICODE_ISPRINTABLE(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISPRINTABLE(Py_UCS4 ch)
 
    Return ``1`` or ``0`` depending on whether *ch* is a printable character.
    Nonprintable characters are those characters defined in the Unicode character
@@ -332,7 +332,7 @@ the Python configuration.
 These APIs can be used for fast direct character conversions:
 
 
-.. c:function:: Py_UNICODE Py_UNICODE_TOLOWER(Py_UNICODE ch)
+.. c:function:: Py_UCS4 Py_UNICODE_TOLOWER(Py_UCS4 ch)
 
    Return the character *ch* converted to lower case.
 
@@ -340,7 +340,7 @@ These APIs can be used for fast direct character conversions:
       This function uses simple case mappings.
 
 
-.. c:function:: Py_UNICODE Py_UNICODE_TOUPPER(Py_UNICODE ch)
+.. c:function:: Py_UCS4 Py_UNICODE_TOUPPER(Py_UCS4 ch)
 
    Return the character *ch* converted to upper case.
 
@@ -348,7 +348,7 @@ These APIs can be used for fast direct character conversions:
       This function uses simple case mappings.
 
 
-.. c:function:: Py_UNICODE Py_UNICODE_TOTITLE(Py_UNICODE ch)
+.. c:function:: Py_UCS4 Py_UNICODE_TOTITLE(Py_UCS4 ch)
 
    Return the character *ch* converted to title case.
 
@@ -356,19 +356,19 @@ These APIs can be used for fast direct character conversions:
       This function uses simple case mappings.
 
 
-.. c:function:: int Py_UNICODE_TODECIMAL(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_TODECIMAL(Py_UCS4 ch)
 
    Return the character *ch* converted to a decimal positive integer.  Return
    ``-1`` if this is not possible.  This macro does not raise exceptions.
 
 
-.. c:function:: int Py_UNICODE_TODIGIT(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_TODIGIT(Py_UCS4 ch)
 
    Return the character *ch* converted to a single digit integer. Return ``-1`` if
    this is not possible.  This macro does not raise exceptions.
 
 
-.. c:function:: double Py_UNICODE_TONUMERIC(Py_UNICODE ch)
+.. c:function:: double Py_UNICODE_TONUMERIC(Py_UCS4 ch)
 
    Return the character *ch* converted to a double. Return ``-1.0`` if this is not
    possible.  This macro does not raise exceptions.
index d2dff7d..7e355ba 100644 (file)
@@ -70,7 +70,8 @@ html_theme = 'python_docs_theme'
 html_theme_path = ['tools']
 html_theme_options = {
     'collapsiblesidebar': True,
-    'issues_url': 'https://docs.python.org/3/bugs.html',
+    'issues_url': '/bugs.html',
+    'license_url': '/license.html',
     'root_include_title': False   # We use the version switcher instead.
 }
 
index 4191c0b..e64a493 100644 (file)
@@ -4,7 +4,7 @@ Copyright
 
 Python and this documentation is:
 
-Copyright © 2001-2021 Python Software Foundation. All rights reserved.
+Copyright © 2001-2022 Python Software Foundation. All rights reserved.
 
 Copyright © 2000 BeOpen.com. All rights reserved.
 
index 0600663..7b1e22f 100644 (file)
@@ -23,25 +23,25 @@ option, for example::
 
 to create a gzipped tarball and a zip file.  The available formats are:
 
-+-----------+-------------------------+---------+
-| Format    | Description             | Notes   |
-+===========+=========================+=========+
-| ``zip``   | zip file (:file:`.zip`) | (1),(3) |
-+-----------+-------------------------+---------+
-| ``gztar`` | gzip'ed tar file        | \(2)    |
-|           | (:file:`.tar.gz`)       |         |
-+-----------+-------------------------+---------+
-| ``bztar`` | bzip2'ed tar file       |         |
-|           | (:file:`.tar.bz2`)      |         |
-+-----------+-------------------------+---------+
-| ``xztar`` | xz'ed tar file          |         |
-|           | (:file:`.tar.xz`)       |         |
-+-----------+-------------------------+---------+
-| ``ztar``  | compressed tar file     | \(4)    |
-|           | (:file:`.tar.Z`)        |         |
-+-----------+-------------------------+---------+
-| ``tar``   | tar file (:file:`.tar`) |         |
-+-----------+-------------------------+---------+
++-----------+-------------------------+-------------+
+| Format    | Description             | Notes       |
++===========+=========================+=============+
+| ``zip``   | zip file (:file:`.zip`) | (1),(3)     |
++-----------+-------------------------+-------------+
+| ``gztar`` | gzip'ed tar file        | \(2)        |
+|           | (:file:`.tar.gz`)       |             |
++-----------+-------------------------+-------------+
+| ``bztar`` | bzip2'ed tar file       | \(5)        |
+|           | (:file:`.tar.bz2`)      |             |
++-----------+-------------------------+-------------+
+| ``xztar`` | xz'ed tar file          | \(5)        |
+|           | (:file:`.tar.xz`)       |             |
++-----------+-------------------------+-------------+
+| ``ztar``  | compressed tar file     | (4),(5)     |
+|           | (:file:`.tar.Z`)        |             |
++-----------+-------------------------+-------------+
+| ``tar``   | tar file (:file:`.tar`) | \(5)        |
++-----------+-------------------------+-------------+
 
 .. versionchanged:: 3.5
    Added support for the ``xztar`` format.
@@ -61,6 +61,9 @@ Notes:
 (4)
    requires the :program:`compress` program. Notice that this format is now
    pending for deprecation and will be removed in the future versions of Python.
+(5)
+  deprecated by `PEP 527 <https://www.python.org/dev/peps/pep-0527/>`_;
+  `PyPI <https://pypi.org>`_ only accepts ``.zip`` and ``.tar.gz`` files.
 
 When using any ``tar`` format (``gztar``, ``bztar``, ``xztar``, ``ztar`` or
 ``tar``), under Unix you can specify the ``owner`` and ``group`` names
index bc85a05..a767670 100644 (file)
@@ -127,13 +127,11 @@ Intermezzo: Errors and Exceptions
 
 An important convention throughout the Python interpreter is the following: when
 a function fails, it should set an exception condition and return an error value
-(usually a ``NULL`` pointer).  Exceptions are stored in a static global variable
-inside the interpreter; if this variable is ``NULL`` no exception has occurred.  A
-second global variable stores the "associated value" of the exception (the
-second argument to :keyword:`raise`).  A third variable contains the stack
-traceback in case the error originated in Python code.  These three variables
-are the C equivalents of the result in Python of :meth:`sys.exc_info` (see the
-section on module :mod:`sys` in the Python Library Reference).  It is important
+(usually ``-1`` or a ``NULL`` pointer).  Exception information is stored in
+three members of the interpreter's thread state.  These are ``NULL`` if
+there is no exception.  Otherwise they are the C equivalents of the members
+of the Python tuple returned by :meth:`sys.exc_info`.  These are the
+exception type, exception instance, and a traceback object.  It is important
 to know about them to understand how errors are passed around.
 
 The Python API defines a number of functions to set various types of exceptions.
index 97058b5..7703d48 100644 (file)
@@ -243,9 +243,6 @@ Be sure to use the :mod:`threading` module and not the :mod:`_thread` module.
 The :mod:`threading` module builds convenient abstractions on top of the
 low-level primitives provided by the :mod:`_thread` module.
 
-Aahz has a set of slides from his threading tutorial that are helpful; see
-http://www.pythoncraft.com/OSCON2001/.
-
 
 None of my threads seem to run: why?
 ------------------------------------
@@ -617,9 +614,9 @@ use ``p.read(n)``.
 How do I access the serial (RS232) port?
 ----------------------------------------
 
-For Win32, POSIX (Linux, BSD, etc.), Jython:
+For Win32, OSX, Linux, BSD, Jython, IronPython:
 
-   http://pyserial.sourceforge.net
+   https://pypi.org/project/pyserial/
 
 For Unix, see a Usenet post by Mitch Chapman:
 
index 5286bbb..d838e61 100644 (file)
@@ -2013,7 +2013,7 @@ Jim Roskind suggests performing steps in the following order in each module:
 * ``import`` statements
 * active code (including globals that are initialized from imported values).
 
-van Rossum doesn't like this approach much because the imports appear in a
+Van Rossum doesn't like this approach much because the imports appear in a
 strange place, but it does work.
 
 Matthias Urlichs recommends restructuring your code so that the recursive import
index 20b02c8..bc9b249 100644 (file)
@@ -541,6 +541,17 @@ alternative there, as well as adapting the above script to use your alternative
 serialization.
 
 
+Running a logging socket listener in production
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+To run a logging listener in production, you may need to use a process-management tool
+such as `Supervisor <http://supervisord.org/>`_. `Here
+<https://gist.github.com/vsajip/4b227eeec43817465ca835ca66f75e2b>`_ is a Gist which
+provides the bare-bones files to run the above functionality using Supervisor: you
+will need to change the `/path/to/` parts in the Gist to reflect the actual paths you
+want to use.
+
+
 .. _context-info:
 
 Adding contextual information to your logging output
@@ -982,6 +993,17 @@ to this (remembering to first import :mod:`concurrent.futures`)::
         for i in range(10):
             executor.submit(worker_process, queue, worker_configurer)
 
+Deploying Web applications using Gunicorn and uWSGI
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When deploying Web applications using `Gunicorn <https://gunicorn.org/>`_ or `uWSGI
+<https://uwsgi-docs.readthedocs.io/en/latest/>`_ (or similar), multiple worker
+processes are created to handle client requests. In such environments, avoid creating
+file-based handlers directly in your web application. Instead, use a
+:class:`SocketHandler` to log from the web application to a listener in a separate
+process. This can be set up using a process management tool such as Supervisor - see
+`Running a logging socket listener in production`_ for more details.
+
 
 Using file rotation
 -------------------
index 1d7bd26..36c051d 100644 (file)
@@ -333,7 +333,8 @@ and off individually.  They are described here in more detail.
 
 .. 2to3fixer:: nonzero
 
-   Renames :meth:`__nonzero__` to :meth:`~object.__bool__`.
+   Renames definitions of methods called :meth:`__nonzero__`
+   to :meth:`~object.__bool__`.
 
 .. 2to3fixer:: numliterals
 
index 4a64475..140851c 100644 (file)
@@ -59,7 +59,7 @@ an event loop:
 
 .. function:: new_event_loop()
 
-   Create a new event loop object.
+   Create and return a new event loop object.
 
 Note that the behaviour of :func:`get_event_loop`, :func:`set_event_loop`,
 and :func:`new_event_loop` functions can be altered by
@@ -626,6 +626,11 @@ Creating network servers
        assumed and a list of multiple sockets will be returned (most likely
        one for IPv4 and another one for IPv6).
 
+   * The *port* parameter can be set to specify which port the server should
+     listen on. If ``0`` or ``None`` (the default), a random unused port will
+     be selected (note that if *host* resolves to multiple network interfaces,
+     a different random port will be selected for each interface).
+
    * *family* can be set to either :data:`socket.AF_INET` or
      :data:`~socket.AF_INET6` to force the socket to use IPv4 or IPv6.
      If not set, the *family* will be determined from host name
@@ -1234,9 +1239,10 @@ async/await code consider using the high-level
 
 .. note::
 
-   The default asyncio event loop on **Windows** does not support
-   subprocesses. See :ref:`Subprocess Support on Windows
-   <asyncio-windows-subprocess>` for details.
+   On Windows, the default event loop :class:`ProactorEventLoop` supports
+   subprocesses, whereas :class:`SelectorEventLoop` does not. See
+   :ref:`Subprocess Support on Windows <asyncio-windows-subprocess>` for
+   details.
 
 .. coroutinemethod:: loop.subprocess_exec(protocol_factory, *args, \
                       stdin=subprocess.PIPE, stdout=subprocess.PIPE, \
index 939d4c1..63c3692 100644 (file)
@@ -54,6 +54,9 @@ Future Functions
       See also the :func:`create_task` function which is the
       preferred way for creating new Tasks.
 
+      Save a reference to the result of this function, to avoid
+      a task disappearing mid execution.
+
    .. versionchanged:: 3.5.1
       The function accepts any :term:`awaitable` object.
 
index ca6e525..e8bee20 100644 (file)
@@ -274,6 +274,11 @@ Creating Tasks
        task = asyncio.ensure_future(coro())
        ...
 
+   .. important::
+
+      Save a reference to the result of this function, to avoid
+      a task disappearing mid execution.
+
    .. versionadded:: 3.7
 
    .. versionchanged:: 3.8
index 897efc2..70a17a2 100644 (file)
@@ -30,7 +30,7 @@ Executor Objects
 
     .. method:: submit(fn, /, *args, **kwargs)
 
-       Schedules the callable, *fn*, to be executed as ``fn(*args **kwargs)``
+       Schedules the callable, *fn*, to be executed as ``fn(*args, **kwargs)``
        and returns a :class:`Future` object representing the execution of the
        callable. ::
 
@@ -435,7 +435,8 @@ Module Functions
 .. function:: wait(fs, timeout=None, return_when=ALL_COMPLETED)
 
    Wait for the :class:`Future` instances (possibly created by different
-   :class:`Executor` instances) given by *fs* to complete.  Returns a named
+   :class:`Executor` instances) given by *fs* to complete. Duplicate futures
+   given to *fs* are removed and will be returned only once. Returns a named
    2-tuple of sets.  The first set, named ``done``, contains the futures that
    completed (finished or cancelled futures) before the wait completed.  The
    second set, named ``not_done``, contains the futures that did not complete
index b186f1d..c10e54f 100644 (file)
@@ -1320,7 +1320,7 @@ There are several ways to load shared libraries into the Python process.  One
 way is to instantiate one of the following classes:
 
 
-.. class:: CDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=0)
+.. class:: CDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=None)
 
    Instances of this class represent loaded shared libraries. Functions in these
    libraries use the standard C calling convention, and are assumed to return
@@ -1342,7 +1342,7 @@ way is to instantiate one of the following classes:
     -- A tool to find DLL dependents.
 
 
-.. class:: OleDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=0)
+.. class:: OleDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=None)
 
    Windows only: Instances of this class represent loaded shared libraries,
    functions in these libraries use the ``stdcall`` calling convention, and are
@@ -1355,7 +1355,7 @@ way is to instantiate one of the following classes:
       :exc:`WindowsError` used to be raised.
 
 
-.. class:: WinDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=0)
+.. class:: WinDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=None)
 
    Windows only: Instances of this class represent loaded shared libraries,
    functions in these libraries use the ``stdcall`` calling convention, and are
index b226cda..808e67b 100644 (file)
@@ -287,12 +287,15 @@ Module-level decorators, classes, and functions
    Raises :exc:`TypeError` if not passed a dataclass or instance of one.
    Does not return pseudo-fields which are ``ClassVar`` or ``InitVar``.
 
-.. function:: asdict(instance, *, dict_factory=dict)
+.. function:: asdict(obj, *, dict_factory=dict)
 
-   Converts the dataclass ``instance`` to a dict (by using the
+   Converts the dataclass ``obj`` to a dict (by using the
    factory function ``dict_factory``).  Each dataclass is converted
    to a dict of its fields, as ``name: value`` pairs.  dataclasses, dicts,
-   lists, and tuples are recursed into.  For example::
+   lists, and tuples are recursed into.  Other objects are copied with
+   :func:`copy.deepcopy`.
+
+   Example of using :func:`asdict` on nested dataclasses::
 
      @dataclass
      class Point:
@@ -309,21 +312,32 @@ Module-level decorators, classes, and functions
      c = C([Point(0, 0), Point(10, 4)])
      assert asdict(c) == {'mylist': [{'x': 0, 'y': 0}, {'x': 10, 'y': 4}]}
 
-   Raises :exc:`TypeError` if ``instance`` is not a dataclass instance.
+   To create a shallow copy, the following workaround may be used::
+
+     dict((field.name, getattr(obj, field.name)) for field in fields(obj))
+
+   :func:`asdict` raises :exc:`TypeError` if ``obj`` is not a dataclass
+   instance.
 
-.. function:: astuple(instance, *, tuple_factory=tuple)
+.. function:: astuple(obj, *, tuple_factory=tuple)
 
-   Converts the dataclass ``instance`` to a tuple (by using the
+   Converts the dataclass ``obj`` to a tuple (by using the
    factory function ``tuple_factory``).  Each dataclass is converted
    to a tuple of its field values.  dataclasses, dicts, lists, and
-   tuples are recursed into.
+   tuples are recursed into. Other objects are copied with
+   :func:`copy.deepcopy`.
 
    Continuing from the previous example::
 
      assert astuple(p) == (10, 20)
      assert astuple(c) == ([(0, 0), (10, 4)],)
 
-   Raises :exc:`TypeError` if ``instance`` is not a dataclass instance.
+   To create a shallow copy, the following workaround may be used::
+
+     tuple(getattr(obj, field.name) for field in dataclasses.fields(obj))
+
+   :func:`astuple` raises :exc:`TypeError` if ``obj`` is not a dataclass
+   instance.
 
 .. function:: make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False)
 
@@ -359,10 +373,10 @@ Module-level decorators, classes, and functions
          def add_one(self):
              return self.x + 1
 
-.. function:: replace(instance, /, **changes)
+.. function:: replace(obj, /, **changes)
 
-   Creates a new object of the same type as ``instance``, replacing
-   fields with values from ``changes``.  If ``instance`` is not a Data
+   Creates a new object of the same type as ``obj``, replacing
+   fields with values from ``changes``.  If ``obj`` is not a Data
    Class, raises :exc:`TypeError`.  If values in ``changes`` do not
    specify fields, raises :exc:`TypeError`.
 
@@ -387,7 +401,7 @@ Module-level decorators, classes, and functions
    ``replace()`` (or similarly named) method which handles instance
    copying.
 
-.. function:: is_dataclass(class_or_instance)
+.. function:: is_dataclass(obj)
 
    Return ``True`` if its parameter is a dataclass or an instance of one,
    otherwise return ``False``.
index 0f8b70c..217cdf2 100644 (file)
@@ -2359,8 +2359,8 @@ requires, and these work on all platforms with a standard C implementation.
 |           | decimal number.                |                        | \(9)  |
 +-----------+--------------------------------+------------------------+-------+
 | ``%f``    | Microsecond as a decimal       | 000000, 000001, ...,   | \(5)  |
-|           | number, zero-padded on the     | 999999                 |       |
-|           | left.                          |                        |       |
+|           | number, zero-padded to 6       | 999999                 |       |
+|           | digits.                        |                        |       |
 +-----------+--------------------------------+------------------------+-------+
 | ``%z``    | UTC offset in the form         | (empty), +0000,        | \(6)  |
 |           | ``±HHMM[SS[.ffffff]]`` (empty  | -0400, +1030,          |       |
index 4e15901..056b9f7 100644 (file)
@@ -1152,7 +1152,7 @@ all-uppercase names for members)::
 
 .. note::
 
-   This behavior is deprecated and will be removed in 3.12.
+   This behavior is deprecated and will be removed in 3.11.
 
 .. versionchanged:: 3.5
 
index 4acbc67..8df557e 100644 (file)
@@ -686,9 +686,9 @@ are always available.  They are listed here in alphabetical order.
 
 .. function:: globals()
 
-   Return a dictionary representing the current global symbol table. This is always
-   the dictionary of the current module (inside a function or method, this is the
-   module where it is defined, not the module from which it is called).
+   Return the dictionary implementing the current module namespace. For code within
+   functions, this is set when the function is defined and remains the same
+   regardless of where the function is called.
 
 
 .. function:: hasattr(object, name)
@@ -1527,7 +1527,7 @@ are always available.  They are listed here in alphabetical order.
    :func:`itertools.islice` for an alternate version that returns an iterator.
 
 
-.. function:: sorted(iterable, *, key=None, reverse=False)
+.. function:: sorted(iterable, /, *, key=None, reverse=False)
 
    Return a new sorted list from the items in *iterable*.
 
index 58ccbbe..bd25f00 100644 (file)
@@ -120,10 +120,10 @@ More condensed:
 
 Using :func:`new` with an algorithm provided by OpenSSL:
 
-   >>> h = hashlib.new('sha512_256')
+   >>> h = hashlib.new('sha256')
    >>> h.update(b"Nobody inspects the spammish repetition")
    >>> h.hexdigest()
-   '19197dc4d03829df858011c6c87600f994a858103bbc19005f20987aa19a97e2'
+   '031edd7d41651593c5fe5c006fa5752b37fddff7bc4e843aa6af0c950f4b9406'
 
 Hashlib provides the following constant attributes:
 
index 6fa89f5..1810e04 100644 (file)
@@ -159,7 +159,7 @@ Basic Usage
 
    If *check_circular* is false (default: ``True``), then the circular
    reference check for container types will be skipped and a circular reference
-   will result in an :exc:`OverflowError` (or worse).
+   will result in an :exc:`RecursionError` (or worse).
 
    If *allow_nan* is false (default: ``True``), then it will be a
    :exc:`ValueError` to serialize out of range :class:`float` values (``nan``,
@@ -432,7 +432,7 @@ Encoders and Decoders
 
    If *check_circular* is true (the default), then lists, dicts, and custom
    encoded objects will be checked for circular references during encoding to
-   prevent an infinite recursion (which would cause an :exc:`OverflowError`).
+   prevent an infinite recursion (which would cause an :exc:`RecursionError`).
    Otherwise, no such check takes place.
 
    If *allow_nan* is true (the default), then ``NaN``, ``Infinity``, and
index d4dc585..afc32e6 100644 (file)
@@ -186,6 +186,20 @@ in :mod:`logging` itself) and defining handlers which are declared either in
    :func:`listen`.
 
 
+Security considerations
+^^^^^^^^^^^^^^^^^^^^^^^
+
+The logging configuration functionality tries to offer convenience, and in part this
+is done by offering the ability to convert text in configuration files into Python
+objects used in logging configuration - for example, as described in
+:ref:`logging-config-dict-userdef`. However, these same mechanisms (importing
+callables from user-defined modules and calling them with parameters from the
+configuration) could be used to invoke any code you like, and for this reason you
+should treat configuration files from untrusted sources with *extreme caution* and
+satisfy yourself that nothing bad can happen if you load them, before actually loading
+them.
+
+
 .. _logging-config-dictschema:
 
 Configuration dictionary schema
index 059ab3d..f16bf32 100644 (file)
@@ -231,6 +231,19 @@ need to override.
          return the same output every time for a given input, otherwise the
          rollover behaviour may not work as expected.
 
+         It's also worth noting that care should be taken when using a namer to
+         preserve certain attributes in the filename which are used during rotation.
+         For example, :class:`RotatingFileHandler` expects to have a set of log files
+         whose names contain successive integers, so that rotation works as expected,
+         and :class:`TimedRotatingFileHandler` deletes old log files (based on the
+         ``backupCount`` parameter passed to the handler's initializer) by determining
+         the oldest files to delete. For this to happen, the filenames should be
+         sortable using the date/time portion of the filename, and a namer needs to
+         respect this. (If a namer is wanted that doesn't respect this scheme, it will
+         need to be used in a subclass of :class:`TimedRotatingFileHandler` which
+         overrides the :meth:`~TimedRotatingFileHandler.getFilesToDelete` method to
+         fit in with the custom naming scheme.)
+
       .. versionadded:: 3.3
 
 
@@ -440,6 +453,10 @@ timed intervals.
 
       Outputs the record to the file, catering for rollover as described above.
 
+   .. method:: getFilesToDelete()
+
+      Returns a list of filenames which should be deleted as part of rollover. These
+      are the absolute paths of the oldest backup log files written by the handler.
 
 .. _socket-handler:
 
index e72a898..9d6167c 100644 (file)
@@ -80,6 +80,15 @@ is the module's name in the Python package namespace.
       If this evaluates to false, logging messages are not passed to the handlers
       of ancestor loggers.
 
+      Spelling it out with an example: If the propagate attribute of the logger named
+      ``A.B.C`` evaluates to true, any event logged to ``A.B.C`` via a method call such as
+      ``logging.getLogger('A.B.C').error(...)`` will [subject to passing that logger's
+      level and filter settings] be passed in turn to any handlers attached to loggers
+      named ``A.B``, ``A`` and the root logger, after first being passed to any handlers
+      attached to ``A.B.C``. If any logger in the chain ``A.B.C``, ``A.B``, ``A`` has its
+      ``propagate`` attribute set to false, then that is the last logger whose handlers
+      are offered the event to handle, and propagation stops at that point.
+
       The constructor sets this attribute to ``True``.
 
       .. note:: If you attach a handler to a logger *and* one or more of its
index 2c7d7d8..96bc6c1 100644 (file)
@@ -2250,8 +2250,9 @@ with the :class:`Pool` class.
 
    .. method:: starmap(func, iterable[, chunksize])
 
-      Like :meth:`map` except that the elements of the *iterable* are expected
-      to be iterables that are unpacked as arguments.
+      Like :meth:`~multiprocessing.pool.Pool.map` except that the
+      elements of the *iterable* are expected to be iterables that are
+      unpacked as arguments.
 
       Hence an *iterable* of ``[(1,2), (3, 4)]`` results in ``[func(1,2),
       func(3,4)]``.
index 7296492..2fb6ea9 100644 (file)
@@ -489,11 +489,16 @@ the :mod:`glob` module.)
 
       >>> splitext('foo.bar.exe')
       ('foo.bar', '.exe')
+      >>> splitext('/foo/bar.exe')
+      ('/foo/bar', '.exe')
 
-   Leading periods on the basename are ignored::
+   Leading periods of the last component of the path are considered to
+   be part of the root::
 
       >>> splitext('.cshrc')
       ('.cshrc', '')
+      >>> splitext('/foo/....jpg')
+      ('/foo/....jpg', '')
 
    .. versionchanged:: 3.6
       Accepts a :term:`path-like object`.
index d4cc296..f8d567a 100644 (file)
@@ -3998,20 +3998,20 @@ written in Python, such as a mail server's external command delivery program.
    Returns the current global process times.
    The return value is an object with five attributes:
 
-   * :attr:`user` - user time
-   * :attr:`system` - system time
-   * :attr:`children_user` - user time of all child processes
-   * :attr:`children_system` - system time of all child processes
-   * :attr:`elapsed` - elapsed real time since a fixed point in the past
+   * :attr:`!user` - user time
+   * :attr:`!system` - system time
+   * :attr:`!children_user` - user time of all child processes
+   * :attr:`!children_system` - system time of all child processes
+   * :attr:`!elapsed` - elapsed real time since a fixed point in the past
 
    For backwards compatibility, this object also behaves like a five-tuple
-   containing :attr:`user`, :attr:`system`, :attr:`children_user`,
-   :attr:`children_system`, and :attr:`elapsed` in that order.
+   containing :attr:`!user`, :attr:`!system`, :attr:`!children_user`,
+   :attr:`!children_system`, and :attr:`!elapsed` in that order.
 
    See the Unix manual page
    :manpage:`times(2)` and :manpage:`times(3)` manual page on Unix or `the GetProcessTimes MSDN
    <https://docs.microsoft.com/windows/win32/api/processthreadsapi/nf-processthreadsapi-getprocesstimes>`_
-   on Windows. On Windows, only :attr:`user` and :attr:`system` are known; the other attributes are zero.
+   on Windows. On Windows, only :attr:`!user` and :attr:`!system` are known; the other attributes are zero.
 
    .. availability:: Unix, Windows.
 
index ed1e971..13e1a19 100644 (file)
@@ -67,14 +67,13 @@ useful than quitting the debugger upon program's exit.
    before the first line of the module.
 
 
-The typical usage to break into the debugger from a running program is to
-insert ::
+The typical usage to break into the debugger is to insert::
 
    import pdb; pdb.set_trace()
 
-at the location you want to break into the debugger.  You can then step through
-the code following this statement, and continue running without the debugger
-using the :pdbcmd:`continue` command.
+at the location you want to break into the debugger, and then run the program.
+You can then step through the code following this statement, and continue
+running without the debugger using the :pdbcmd:`continue` command.
 
 .. versionadded:: 3.7
    The built-in :func:`breakpoint()`, when called with defaults, can be used
index b24a2f0..0ffb8ff 100644 (file)
@@ -20,16 +20,17 @@ PostgreSQL or Oracle.
 The sqlite3 module was written by Gerhard Häring.  It provides a SQL interface
 compliant with the DB-API 2.0 specification described by :pep:`249`.
 
-To use the module, you must first create a :class:`Connection` object that
+To use the module, start by creating a :class:`Connection` object that
 represents the database.  Here the data will be stored in the
 :file:`example.db` file::
 
    import sqlite3
    con = sqlite3.connect('example.db')
 
-You can also supply the special name ``:memory:`` to create a database in RAM.
+The special path name ``:memory:`` can be provided to create a temporary
+database in RAM.
 
-Once you have a :class:`Connection`, you can create a :class:`Cursor`  object
+Once a :class:`Connection` has been established, create a :class:`Cursor` object
 and call its :meth:`~Cursor.execute` method to perform SQL commands::
 
    cur = con.cursor()
@@ -48,16 +49,17 @@ and call its :meth:`~Cursor.execute` method to perform SQL commands::
    # Just be sure any changes have been committed or they will be lost.
    con.close()
 
-The data you've saved is persistent and is available in subsequent sessions::
+The saved data is persistent: it can be reloaded in a subsequent session even
+after restarting the Python interpreter::
 
    import sqlite3
    con = sqlite3.connect('example.db')
    cur = con.cursor()
 
-To retrieve data after executing a SELECT statement, you can either treat the
-cursor as an :term:`iterator`, call the cursor's :meth:`~Cursor.fetchone` method to
-retrieve a single matching row, or call :meth:`~Cursor.fetchall` to get a list of the
-matching rows.
+To retrieve data after executing a SELECT statement, either treat the cursor as
+an :term:`iterator`, call the cursor's :meth:`~Cursor.fetchone` method to
+retrieve a single matching row, or call :meth:`~Cursor.fetchall` to get a list
+of the matching rows.
 
 This example uses the iterator form::
 
@@ -72,27 +74,27 @@ This example uses the iterator form::
 
 .. _sqlite3-placeholders:
 
-Usually your SQL operations will need to use values from Python variables.  You
-shouldn't assemble your query using Python's string operations because doing so
-is insecure; it makes your program vulnerable to an SQL injection attack
-(see the `xkcd webcomic <https://xkcd.com/327/>`_ for a humorous example of
-what can go wrong)::
+SQL operations usually need to use values from Python variables. However,
+beware of using Python's string operations to assemble queries, as they
+are vulnerable to SQL injection attacks (see the `xkcd webcomic
+<https://xkcd.com/327/>`_ for a humorous example of what can go wrong)::
 
    # Never do this -- insecure!
    symbol = 'RHAT'
    cur.execute("SELECT * FROM stocks WHERE symbol = '%s'" % symbol)
 
-Instead, use the DB-API's parameter substitution. Put a placeholder wherever
-you want to use a value, and then provide a tuple of values as the second
-argument to the cursor's :meth:`~Cursor.execute` method. An SQL statement may
+Instead, use the DB-API's parameter substitution. To insert a variable into a
+query string, use a placeholder in the string, and substitute the actual values
+into the query by providing them as a :class:`tuple` of values to the second
+argument of the cursor's :meth:`~Cursor.execute` method. An SQL statement may
 use one of two kinds of placeholders: question marks (qmark style) or named
 placeholders (named style). For the qmark style, ``parameters`` must be a
 :term:`sequence <sequence>`. For the named style, it can be either a
 :term:`sequence <sequence>` or :class:`dict` instance. The length of the
 :term:`sequence <sequence>` must match the number of placeholders, or a
 :exc:`ProgrammingError` is raised. If a :class:`dict` is given, it must contain
-keys for all named parameters. Any extra items are ignored. Here's an example
-of both styles:
+keys for all named parameters. Any extra items are ignored. Here's an example of
+both styles:
 
 .. literalinclude:: ../includes/sqlite3/execute_1.py
 
@@ -754,14 +756,15 @@ Cursor Objects
 
    .. attribute:: lastrowid
 
-      This read-only attribute provides the rowid of the last modified row. It is
-      only set if you issued an ``INSERT`` or a ``REPLACE`` statement using the
-      :meth:`execute` method.  For operations other than ``INSERT`` or
-      ``REPLACE`` or when :meth:`executemany` is called, :attr:`lastrowid` is
-      set to :const:`None`.
+      This read-only attribute provides the row id of the last inserted row. It
+      is only updated after successful ``INSERT`` or ``REPLACE`` statements
+      using the :meth:`execute` method.  For other statements, after
+      :meth:`executemany` or :meth:`executescript`, or if the insertion failed,
+      the value of ``lastrowid`` is left unchanged.  The initial value of
+      ``lastrowid`` is :const:`None`.
 
-      If the ``INSERT`` or ``REPLACE`` statement failed to insert the previous
-      successful rowid is returned.
+      .. note::
+         Inserts into ``WITHOUT ROWID`` tables are not recorded.
 
       .. versionchanged:: 3.6
          Added support for the ``REPLACE`` statement.
index 38a499a..a6cbdd7 100644 (file)
@@ -105,10 +105,11 @@ However, for reading convenience, most of the examples show sorted sequences.
 
    .. note::
 
-      The mean is strongly affected by outliers and is not a robust estimator
-      for central location: the mean is not necessarily a typical example of
-      the data points.  For more robust measures of central location, see
-      :func:`median` and :func:`mode`.
+      The mean is strongly affected by `outliers
+      <https://en.wikipedia.org/wiki/Outlier>`_ and is not necessarily a
+      typical example of the data points. For a more robust, although less
+      efficient, measure of `central tendency
+      <https://en.wikipedia.org/wiki/Central_tendency>`_, see :func:`median`.
 
       The sample mean gives an unbiased estimate of the true population mean,
       so that when taken on average over all the possible samples,
index e0b9285..bfa0e74 100644 (file)
@@ -178,13 +178,14 @@ operators are only defined where they make sense; for example, they raise a
    single: __ge__() (instance method)
 
 Non-identical instances of a class normally compare as non-equal unless the
-class defines the :meth:`__eq__` method.
+class defines the :meth:`~object.__eq__` method.
 
 Instances of a class cannot be ordered with respect to other instances of the
 same class, or other types of object, unless the class defines enough of the
-methods :meth:`__lt__`, :meth:`__le__`, :meth:`__gt__`, and :meth:`__ge__` (in
-general, :meth:`__lt__` and :meth:`__eq__` are sufficient, if you want the
-conventional meanings of the comparison operators).
+methods :meth:`~object.__lt__`, :meth:`~object.__le__`, :meth:`~object.__gt__`, and
+:meth:`~object.__ge__` (in general, :meth:`~object.__lt__` and
+:meth:`~object.__eq__` are sufficient, if you want the conventional meanings of the
+comparison operators).
 
 The behavior of the :keyword:`is` and :keyword:`is not` operators cannot be
 customized; also they can be applied to any two objects and never raise an
@@ -639,7 +640,7 @@ Hashing of numeric types
 ------------------------
 
 For numbers ``x`` and ``y``, possibly of different types, it's a requirement
-that ``hash(x) == hash(y)`` whenever ``x == y`` (see the :meth:`__hash__`
+that ``hash(x) == hash(y)`` whenever ``x == y`` (see the :meth:`~object.__hash__`
 method documentation for more details).  For ease of implementation and
 efficiency across a variety of numeric types (including :class:`int`,
 :class:`float`, :class:`decimal.Decimal` and :class:`fractions.Fraction`)
@@ -1275,7 +1276,7 @@ loops.
            range(start, stop[, step])
 
    The arguments to the range constructor must be integers (either built-in
-   :class:`int` or any object that implements the ``__index__`` special
+   :class:`int` or any object that implements the :meth:`~object.__index__` special
    method).  If the *step* argument is omitted, it defaults to ``1``.
    If the *start* argument is omitted, it defaults to ``0``.
    If *step* is zero, :exc:`ValueError` is raised.
@@ -1403,7 +1404,7 @@ Strings are immutable
 written in a variety of ways:
 
 * Single quotes: ``'allows embedded "double" quotes'``
-* Double quotes: ``"allows embedded 'single' quotes"``.
+* Double quotes: ``"allows embedded 'single' quotes"``
 * Triple quoted: ``'''Three single quotes'''``, ``"""Three double quotes"""``
 
 Triple quoted strings may span multiple lines - all associated whitespace will
@@ -1727,9 +1728,9 @@ expression support in the :mod:`re` module).
       >>> from keyword import iskeyword
 
       >>> 'hello'.isidentifier(), iskeyword('hello')
-      True, False
+      (True, False)
       >>> 'def'.isidentifier(), iskeyword('def')
-      True, True
+      (True, True)
 
 
 .. method:: str.islower()
@@ -1996,7 +1997,7 @@ expression support in the :mod:`re` module).
 .. index::
    single: universal newlines; str.splitlines method
 
-.. method:: str.splitlines([keepends])
+.. method:: str.splitlines(keepends=False)
 
    Return a list of the lines in the string, breaking at line boundaries.  Line
    breaks are not included in the resulting list unless *keepends* is given and
@@ -2409,7 +2410,7 @@ data and are closely related to string objects in a variety of other ways.
    literals, except that a ``b`` prefix is added:
 
    * Single quotes: ``b'still allows embedded "double" quotes'``
-   * Double quotes: ``b"still allows embedded 'single' quotes"``.
+   * Double quotes: ``b"still allows embedded 'single' quotes"``
    * Triple quoted: ``b'''3 single quotes'''``, ``b"""3 double quotes"""``
 
    Only ASCII characters are permitted in bytes literals (regardless of the
@@ -4309,9 +4310,9 @@ Dictionaries can be created by placing a comma-separated list of ``key: value``
 pairs within braces, for example: ``{'jack': 4098, 'sjoerd': 4127}`` or ``{4098:
 'jack', 4127: 'sjoerd'}``, or by the :class:`dict` constructor.
 
-.. class:: dict(**kwarg)
-           dict(mapping, **kwarg)
-           dict(iterable, **kwarg)
+.. class:: dict(**kwargs)
+           dict(mapping, **kwargs)
+           dict(iterable, **kwargs)
 
    Return a new dictionary initialized from an optional positional argument
    and a possibly empty set of keyword arguments.
@@ -4719,9 +4720,9 @@ their implementation of the context management protocol. See the
 Python's :term:`generator`\s and the :class:`contextlib.contextmanager` decorator
 provide a convenient way to implement these protocols.  If a generator function is
 decorated with the :class:`contextlib.contextmanager` decorator, it will return a
-context manager implementing the necessary :meth:`__enter__` and
-:meth:`__exit__` methods, rather than the iterator produced by an undecorated
-generator function.
+context manager implementing the necessary :meth:`~contextmanager.__enter__` and
+:meth:`~contextmanager.__exit__` methods, rather than the iterator produced by an
+undecorated generator function.
 
 Note that there is no specific slot for any of these methods in the type
 structure for Python objects in the Python/C API. Extension types wanting to
index 6b23b6f..9e18282 100644 (file)
@@ -1183,13 +1183,10 @@ always available.
 .. data:: prefix
 
    A string giving the site-specific directory prefix where the platform
-   independent Python files are installed; by default, this is the string
+   independent Python files are installed; on Unix, the default is
    ``'/usr/local'``.  This can be set at build time with the ``--prefix``
-   argument to the :program:`configure` script.  The main collection of Python
-   library modules is installed in the directory :file:`{prefix}/lib/python{X.Y}`
-   while the platform independent header files (all except :file:`pyconfig.h`) are
-   stored in :file:`{prefix}/include/python{X.Y}`, where *X.Y* is the version
-   number of Python, for example ``3.2``.
+   argument to the :program:`configure` script.  See
+   :ref:`installation_paths` for derived paths.
 
    .. note:: If a :ref:`virtual environment <venv-def>` is in effect, this
       value will be changed in ``site.py`` to point to the virtual
index ee27efd..e2ee6db 100644 (file)
@@ -60,6 +60,7 @@ Example of usage::
    >>> sysconfig.get_config_vars('AR', 'CXX')
    ['ar', 'g++']
 
+.. _installation_paths:
 
 Installation paths
 ------------------
@@ -72,7 +73,7 @@ Every new component that is installed using :mod:`distutils` or a
 Distutils-based system will follow the same scheme to copy its file in the right
 places.
 
-Python currently supports seven schemes:
+Python currently supports six schemes:
 
 - *posix_prefix*: scheme for POSIX platforms like Linux or macOS.  This is
   the default scheme used when Python or a component is installed.
@@ -84,6 +85,7 @@ Python currently supports seven schemes:
   located under the user home directory.
 - *nt*: scheme for NT platforms like Windows.
 - *nt_user*: scheme for NT platforms, when the *user* option is used.
+- *osx_framework_user*: scheme for macOS, when the *user* option is used.
 
 Each scheme is itself composed of a series of paths and each path has a unique
 identifier.  Python currently uses eight paths:
index 3b50d76..2da5448 100644 (file)
@@ -223,6 +223,7 @@ called :class:`TypeVar`.
    def first(l: Sequence[T]) -> T:   # Generic function
        return l[0]
 
+.. _user-defined-generics:
 
 User-defined generic types
 ==========================
@@ -357,12 +358,12 @@ value of type :data:`Any` and assign it to any variable::
 
    from typing import Any
 
-   a = None    # type: Any
-   a = []      # OK
-   a = 2       # OK
+   a: Any = None
+   a = []          # OK
+   a = 2           # OK
 
-   s = ''      # type: str
-   s = a       # OK
+   s: str = ''
+   s = a           # OK
 
    def foo(item: Any) -> int:
        # Typechecks; 'item' could be any type,
@@ -1444,11 +1445,10 @@ Asynchronous programming
    correspond to those of :class:`Generator`, for example::
 
       from collections.abc import Coroutine
-      c = None # type: Coroutine[list[str], str, int]
-      ...
-      x = c.send('hi') # type: list[str]
+      c: Coroutine[list[str], str, int]  # Some coroutine defined elsewhere
+      x = c.send('hi')                   # Inferred type of 'x' is list[str]
       async def bar() -> None:
-          x = await c # type: int
+          y = await c                    # Inferred type of 'y' is int
 
    .. versionadded:: 3.5.3
 
index 3c74b61..3fbb1b6 100644 (file)
@@ -1515,7 +1515,7 @@ attribute in a class) that does not exist will fail with :exc:`AttributeError`::
     >>> test()
     Traceback (most recent call last):
       ...
-    AttributeError: <module 'sys' (built-in)> does not have the attribute 'non_existing'
+    AttributeError: <module 'sys' (built-in)> does not have the attribute 'non_existing_attribute'
 
 but adding ``create=True`` in the call to :func:`patch` will make the previous example
 work as expected::
index 392cd24..9080757 100644 (file)
@@ -223,7 +223,7 @@ Command-line options
 
    Only run test methods and classes that match the pattern or substring.
    This option may be used multiple times, in which case all test cases that
-   match of the given patterns are included.
+   match any of the given patterns are included.
 
    Patterns that contain a wildcard character (``*``) are matched against the
    test name using :meth:`fnmatch.fnmatchcase`; otherwise simple case-sensitive
index c037652..b7430e9 100644 (file)
@@ -48,17 +48,29 @@ or on combining URL components into a URL string.
    result, except for a leading slash in the *path* component, which is retained if
    present.  For example:
 
+   .. doctest::
+      :options: +NORMALIZE_WHITESPACE
+
       >>> from urllib.parse import urlparse
-      >>> o = urlparse('http://www.cwi.nl:80/%7Eguido/Python.html')
-      >>> o   # doctest: +NORMALIZE_WHITESPACE
-      ParseResult(scheme='http', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html',
-                  params='', query='', fragment='')
+      >>> urlparse("scheme://netloc/path;parameters?query#fragment")
+      ParseResult(scheme='scheme', netloc='netloc', path='/path;parameters', params='',
+                  query='query', fragment='fragment')
+      >>> o = urlparse("http://docs.python.org:80/3/library/urllib.parse.html?"
+      ...              "highlight=params#url-parsing")
+      >>> o
+      ParseResult(scheme='http', netloc='docs.python.org:80',
+                  path='/3/library/urllib.parse.html', params='',
+                  query='highlight=params', fragment='url-parsing')
       >>> o.scheme
       'http'
+      >>> o.netloc
+      'docs.python.org:80'
+      >>> o.hostname
+      'docs.python.org'
       >>> o.port
       80
-      >>> o.geturl()
-      'http://www.cwi.nl:80/%7Eguido/Python.html'
+      >>> o._replace(fragment="").geturl()
+      'http://docs.python.org:80/3/library/urllib.parse.html?highlight=params'
 
    Following the syntax specifications in :rfc:`1808`, urlparse recognizes
    a netloc only if it is properly introduced by '//'.  Otherwise the
@@ -92,31 +104,30 @@ or on combining URL components into a URL string.
    The return value is a :term:`named tuple`, which means that its items can
    be accessed by index or as named attributes, which are:
 
-   +------------------+-------+--------------------------+----------------------+
-   | Attribute        | Index | Value                    | Value if not present |
-   +==================+=======+==========================+======================+
-   | :attr:`scheme`   | 0     | URL scheme specifier     | *scheme* parameter   |
-   +------------------+-------+--------------------------+----------------------+
-   | :attr:`netloc`   | 1     | Network location part    | empty string         |
-   +------------------+-------+--------------------------+----------------------+
-   | :attr:`path`     | 2     | Hierarchical path        | empty string         |
-   +------------------+-------+--------------------------+----------------------+
-   | :attr:`params`   | 3     | Parameters for last path | empty string         |
-   |                  |       | element                  |                      |
-   +------------------+-------+--------------------------+----------------------+
-   | :attr:`query`    | 4     | Query component          | empty string         |
-   +------------------+-------+--------------------------+----------------------+
-   | :attr:`fragment` | 5     | Fragment identifier      | empty string         |
-   +------------------+-------+--------------------------+----------------------+
-   | :attr:`username` |       | User name                | :const:`None`        |
-   +------------------+-------+--------------------------+----------------------+
-   | :attr:`password` |       | Password                 | :const:`None`        |
-   +------------------+-------+--------------------------+----------------------+
-   | :attr:`hostname` |       | Host name (lower case)   | :const:`None`        |
-   +------------------+-------+--------------------------+----------------------+
-   | :attr:`port`     |       | Port number as integer,  | :const:`None`        |
-   |                  |       | if present               |                      |
-   +------------------+-------+--------------------------+----------------------+
+   +------------------+-------+-------------------------+------------------------+
+   | Attribute        | Index | Value                   | Value if not present   |
+   +==================+=======+=========================+========================+
+   | :attr:`scheme`   | 0     | URL scheme specifier    | *scheme* parameter     |
+   +------------------+-------+-------------------------+------------------------+
+   | :attr:`netloc`   | 1     | Network location part   | empty string           |
+   +------------------+-------+-------------------------+------------------------+
+   | :attr:`path`     | 2     | Hierarchical path       | empty string           |
+   +------------------+-------+-------------------------+------------------------+
+   | :attr:`params`   | 3     | No longer used          | always an empty string |
+   +------------------+-------+-------------------------+------------------------+
+   | :attr:`query`    | 4     | Query component         | empty string           |
+   +------------------+-------+-------------------------+------------------------+
+   | :attr:`fragment` | 5     | Fragment identifier     | empty string           |
+   +------------------+-------+-------------------------+------------------------+
+   | :attr:`username` |       | User name               | :const:`None`          |
+   +------------------+-------+-------------------------+------------------------+
+   | :attr:`password` |       | Password                | :const:`None`          |
+   +------------------+-------+-------------------------+------------------------+
+   | :attr:`hostname` |       | Host name (lower case)  | :const:`None`          |
+   +------------------+-------+-------------------------+------------------------+
+   | :attr:`port`     |       | Port number as integer, | :const:`None`          |
+   |                  |       | if present              |                        |
+   +------------------+-------+-------------------------+------------------------+
 
    Reading the :attr:`port` attribute will raise a :exc:`ValueError` if
    an invalid port is specified in the URL.  See section
index 9c1743c..4f05e14 100644 (file)
@@ -105,7 +105,7 @@ The following warnings category classes are currently defined:
 |                                  | :class:`bytes` and :class:`bytearray`.        |
 +----------------------------------+-----------------------------------------------+
 | :exc:`ResourceWarning`           | Base category for warnings related to         |
-|                                  | resource usage.                               |
+|                                  | resource usage (ignored by default).          |
 +----------------------------------+-----------------------------------------------+
 
 .. versionchanged:: 3.7
index 8ac3fb1..a3a24ec 100644 (file)
@@ -23,8 +23,8 @@ and a path within the archive can be specified to only import from a
 subdirectory.  For example, the path :file:`example.zip/lib/` would only
 import from the :file:`lib/` subdirectory within the archive.
 
-Any files may be present in the ZIP archive, but only files :file:`.py` and
-:file:`.pyc` are available for import.  ZIP import of dynamic modules
+Any files may be present in the ZIP archive, but importers are only invoked for
+:file:`.py` and :file:`.pyc` files.  ZIP import of dynamic modules
 (:file:`.pyd`, :file:`.so`) is disallowed. Note that if an archive only contains
 :file:`.py` files, Python will not attempt to modify the archive by adding the
 corresponding :file:`.pyc` file, meaning that if a ZIP archive
index 4ab04f3..842cf03 100644 (file)
@@ -100,7 +100,7 @@ PSF LICENSE AGREEMENT FOR PYTHON |release|
       analyze, test, perform and/or display publicly, prepare derivative works,
       distribute, and otherwise use Python |release| alone or in any derivative
       version, provided, however, that PSF's License Agreement and PSF's notice of
-      copyright, i.e., "Copyright © 2001-2021 Python Software Foundation; All Rights
+      copyright, i.e., "Copyright © 2001-2022 Python Software Foundation; All Rights
       Reserved" are retained in Python |release| alone or in any derivative version
       prepared by Licensee.
 
index 29a6987..967308b 100644 (file)
@@ -188,7 +188,7 @@ Ellipsis
    representation in computers.
 
    The string representations of the numeric classes, computed by
-   :meth:`__repr__` and :meth:`__str__`, have the following
+   :meth:`~object.__repr__` and :meth:`~object.__str__`, have the following
    properties:
 
    * They are valid numeric literals which, when passed to their
@@ -674,7 +674,8 @@ Callable types
       returns an asynchronous iterator object which can be used in an
       :keyword:`async for` statement to execute the body of the function.
 
-      Calling the asynchronous iterator's :meth:`aiterator.__anext__` method
+      Calling the asynchronous iterator's
+      :meth:`aiterator.__anext__ <object.__anext__>` method
       will return an :term:`awaitable` which when awaited
       will execute until it provides a value using the :keyword:`yield`
       expression.  When the function executes an empty :keyword:`return`
@@ -712,13 +713,13 @@ Callable types
    Classes
       Classes are callable.  These objects normally act as factories for new
       instances of themselves, but variations are possible for class types that
-      override :meth:`__new__`.  The arguments of the call are passed to
-      :meth:`__new__` and, in the typical case, to :meth:`__init__` to
+      override :meth:`~object.__new__`.  The arguments of the call are passed to
+      :meth:`__new__` and, in the typical case, to :meth:`~object.__init__` to
       initialize the new instance.
 
    Class Instances
       Instances of arbitrary classes can be made callable by defining a
-      :meth:`__call__` method in their class.
+      :meth:`~object.__call__` method in their class.
 
 
 Modules
@@ -848,14 +849,14 @@ Class instances
    section :ref:`descriptors` for another way in which attributes of a class
    retrieved via its instances may differ from the objects actually stored in
    the class's :attr:`~object.__dict__`.  If no class attribute is found, and the
-   object's class has a :meth:`__getattr__` method, that is called to satisfy
+   object's class has a :meth:`~object.__getattr__` method, that is called to satisfy
    the lookup.
 
    .. index:: triple: class instance; attribute; assignment
 
    Attribute assignments and deletions update the instance's dictionary, never a
-   class's dictionary.  If the class has a :meth:`__setattr__` or
-   :meth:`__delattr__` method, this is called instead of updating the instance
+   class's dictionary.  If the class has a :meth:`~object.__setattr__` or
+   :meth:`~object.__delattr__` method, this is called instead of updating the instance
    dictionary directly.
 
    .. index::
@@ -1109,7 +1110,8 @@ Internal types
    Slice objects
       .. index:: builtin: slice
 
-      Slice objects are used to represent slices for :meth:`__getitem__`
+      Slice objects are used to represent slices for
+      :meth:`~object.__getitem__`
       methods.  They are also created by the built-in :func:`slice` function.
 
       .. index::
@@ -1163,7 +1165,8 @@ A class can implement certain operations that are invoked by special syntax
 (such as arithmetic operations or subscripting and slicing) by defining methods
 with special names. This is Python's approach to :dfn:`operator overloading`,
 allowing classes to define their own behavior with respect to language
-operators.  For instance, if a class defines a method named :meth:`__getitem__`,
+operators.  For instance, if a class defines a method named
+:meth:`~object.__getitem__`,
 and ``x`` is an instance of this class, then ``x[i]`` is roughly equivalent
 to ``type(x).__getitem__(x, i)``.  Except where mentioned, attempts to execute an
 operation raise an exception when no appropriate method is defined (typically
@@ -1171,9 +1174,9 @@ operation raise an exception when no appropriate method is defined (typically
 
 Setting a special method to ``None`` indicates that the corresponding
 operation is not available.  For example, if a class sets
-:meth:`__iter__` to ``None``, the class is not iterable, so calling
+:meth:`~object.__iter__` to ``None``, the class is not iterable, so calling
 :func:`iter` on its instances will raise a :exc:`TypeError` (without
-falling back to :meth:`__getitem__`). [#]_
+falling back to :meth:`~object.__getitem__`). [#]_
 
 When implementing a class that emulates any built-in type, it is important that
 the emulation only be implemented to the degree that it makes sense for the
@@ -1745,7 +1748,8 @@ Invoking Descriptors
 
 In general, a descriptor is an object attribute with "binding behavior", one
 whose attribute access has been overridden by methods in the descriptor
-protocol:  :meth:`__get__`, :meth:`__set__`, and :meth:`__delete__`. If any of
+protocol:  :meth:`~object.__get__`, :meth:`~object.__set__`, and
+:meth:`~object.__delete__`. If any of
 those methods are defined for an object, it is said to be a descriptor.
 
 The default behavior for attribute access is to get, set, or delete the
@@ -1776,12 +1780,13 @@ Class Binding
 Super Binding
    If ``a`` is an instance of :class:`super`, then the binding ``super(B, obj).m()``
    searches ``obj.__class__.__mro__`` for the base class ``A``
-   immediately preceding ``B`` and then invokes the descriptor with the call:
+   immediately following ``B`` and then invokes the descriptor with the call:
    ``A.__dict__['m'].__get__(obj, obj.__class__)``.
 
 For instance bindings, the precedence of descriptor invocation depends on
 which descriptor methods are defined.  A descriptor can define any combination
-of :meth:`__get__`, :meth:`__set__` and :meth:`__delete__`.  If it does not
+of :meth:`~object.__get__`, :meth:`~object.__set__` and
+:meth:`~object.__delete__`.  If it does not
 define :meth:`__get__`, then accessing the attribute will return the descriptor
 object itself unless there is a value in the object's instance dictionary.  If
 the descriptor defines :meth:`__set__` and/or :meth:`__delete__`, it is a data
@@ -1792,7 +1797,8 @@ descriptors have just the :meth:`__get__` method.  Data descriptors with
 instance dictionary.  In contrast, non-data descriptors can be overridden by
 instances.
 
-Python methods (including :func:`staticmethod` and :func:`classmethod`) are
+Python methods (including those decorated with
+:func:`@staticmethod <staticmethod>` and :func:`@classmethod <classmethod>`) are
 implemented as non-data descriptors.  Accordingly, instances can redefine and
 override methods.  This allows individual instances to acquire behaviors that
 differ from other instances of the same class.
@@ -1807,46 +1813,50 @@ __slots__
 ^^^^^^^^^
 
 *__slots__* allow us to explicitly declare data members (like
-properties) and deny the creation of *__dict__* and *__weakref__*
+properties) and deny the creation of :attr:`~object.__dict__` and *__weakref__*
 (unless explicitly declared in *__slots__* or available in a parent.)
 
-The space saved over using *__dict__* can be significant.
+The space saved over using :attr:`~object.__dict__` can be significant.
 Attribute lookup speed can be significantly improved as well.
 
 .. data:: object.__slots__
 
    This class variable can be assigned a string, iterable, or sequence of
    strings with variable names used by instances.  *__slots__* reserves space
-   for the declared variables and prevents the automatic creation of *__dict__*
+   for the declared variables and prevents the automatic creation of
+   :attr:`~object.__dict__`
    and *__weakref__* for each instance.
 
 
 Notes on using *__slots__*
 """"""""""""""""""""""""""
 
-* When inheriting from a class without *__slots__*, the *__dict__* and
+* When inheriting from a class without *__slots__*, the
+  :attr:`~object.__dict__` and
   *__weakref__* attribute of the instances will always be accessible.
 
-* Without a *__dict__* variable, instances cannot be assigned new variables not
+* Without a :attr:`~object.__dict__` variable, instances cannot be assigned new
+  variables not
   listed in the *__slots__* definition.  Attempts to assign to an unlisted
   variable name raises :exc:`AttributeError`. If dynamic assignment of new
   variables is desired, then add ``'__dict__'`` to the sequence of strings in
   the *__slots__* declaration.
 
 * Without a *__weakref__* variable for each instance, classes defining
-  *__slots__* do not support weak references to its instances. If weak reference
+  *__slots__* do not support :mod:`weak references <weakref>` to its instances.
+  If weak reference
   support is needed, then add ``'__weakref__'`` to the sequence of strings in the
   *__slots__* declaration.
 
-* *__slots__* are implemented at the class level by creating descriptors
-  (:ref:`descriptors`) for each variable name.  As a result, class attributes
+* *__slots__* are implemented at the class level by creating :ref:`descriptors <descriptors>`
+  for each variable name.  As a result, class attributes
   cannot be used to set default values for instance variables defined by
   *__slots__*; otherwise, the class attribute would overwrite the descriptor
   assignment.
 
 * The action of a *__slots__* declaration is not limited to the class
   where it is defined.  *__slots__* declared in parents are available in
-  child classes. However, child subclasses will get a *__dict__*  and
+  child classes. However, child subclasses will get a :attr:`~object.__dict__` and
   *__weakref__* unless they also define *__slots__* (which should only
   contain names of any *additional* slots).
 
@@ -1858,18 +1868,24 @@ Notes on using *__slots__*
 * Nonempty *__slots__* does not work for classes derived from "variable-length"
   built-in types such as :class:`int`, :class:`bytes` and :class:`tuple`.
 
-* Any non-string iterable may be assigned to *__slots__*. Mappings may also be
-  used; however, in the future, special meaning may be assigned to the values
-  corresponding to each key.
+* Any non-string :term:`iterable` may be assigned to *__slots__*.
 
-* *__class__* assignment works only if both classes have the same *__slots__*.
+* If a :class:`dictionary <dict>` is used to assign *__slots__*, the dictionary
+  keys will be used as the slot names. The values of the dictionary can be used
+  to provide per-attribute docstrings that will be recognised by
+  :func:`inspect.getdoc` and displayed in the output of :func:`help`.
 
-* Multiple inheritance with multiple slotted parent classes can be used,
+* :attr:`~instance.__class__` assignment works only if both classes have the
+  same *__slots__*.
+
+* :ref:`Multiple inheritance <tut-multiple>` with multiple slotted parent
+  classes can be used,
   but only one parent is allowed to have attributes created by slots
   (the other bases must have empty slot layouts) - violations raise
   :exc:`TypeError`.
 
-* If an iterator is used for *__slots__* then a descriptor is created for each
+* If an :term:`iterator` is used for *__slots__* then a :term:`descriptor` is
+  created for each
   of the iterator's values. However, the *__slots__* attribute will be an empty
   iterator.
 
@@ -1878,7 +1894,7 @@ Notes on using *__slots__*
 Customizing class creation
 --------------------------
 
-Whenever a class inherits from another class, *__init_subclass__* is
+Whenever a class inherits from another class, :meth:`~object.__init_subclass__` is
 called on that class. This way, it is possible to write classes which
 change the behavior of subclasses. This is closely related to class
 decorators, but where class decorators only affect the specific class they're
@@ -2004,7 +2020,8 @@ Once the appropriate metaclass has been identified, then the class namespace
 is prepared. If the metaclass has a ``__prepare__`` attribute, it is called
 as ``namespace = metaclass.__prepare__(name, bases, **kwds)`` (where the
 additional keyword arguments, if any, come from the class definition). The
-``__prepare__`` method should be implemented as a :func:`classmethod`. The
+``__prepare__`` method should be implemented as a
+:func:`classmethod <classmethod>`. The
 namespace returned by ``__prepare__`` is passed in to ``__new__``, but when
 the final class object is created the namespace is copied into a new ``dict``.
 
@@ -2144,22 +2161,142 @@ case the instance is itself a class.
 Emulating generic types
 -----------------------
 
-One can implement the generic class syntax as specified by :pep:`484`
-(for example ``List[int]``) by defining a special method:
+When using :term:`type annotations<annotation>`, it is often useful to
+*parameterize* a :term:`generic type` using Python's square-brackets notation.
+For example, the annotation ``list[int]`` might be used to signify a
+:class:`list` in which all the elements are of type :class:`int`.
+
+.. seealso::
+
+   :pep:`484` - Type Hints
+      Introducing Python's framework for type annotations
+
+   :ref:`Generic Alias Types<types-genericalias>`
+      Documentation for objects representing parameterized generic classes
+
+   :ref:`Generics`, :ref:`user-defined generics<user-defined-generics>` and :class:`typing.Generic`
+      Documentation on how to implement generic classes that can be
+      parameterized at runtime and understood by static type-checkers.
+
+A class can *generally* only be parameterized if it defines the special
+class method ``__class_getitem__()``.
 
 .. classmethod:: object.__class_getitem__(cls, key)
 
    Return an object representing the specialization of a generic class
    by type arguments found in *key*.
 
-This method is looked up on the class object itself, and when defined in
-the class body, this method is implicitly a class method.  Note, this
-mechanism is primarily reserved for use with static type hints, other usage
-is discouraged.
+   When defined on a class, ``__class_getitem__()`` is automatically a class
+   method. As such, there is no need for it to be decorated with
+   :func:`@classmethod<classmethod>` when it is defined.
 
-.. seealso::
 
-   :pep:`560` - Core support for typing module and generic types
+The purpose of *__class_getitem__*
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The purpose of :meth:`~object.__class_getitem__` is to allow runtime
+parameterization of standard-library generic classes in order to more easily
+apply :term:`type hints<type hint>` to these classes.
+
+To implement custom generic classes that can be parameterized at runtime and
+understood by static type-checkers, users should either inherit from a standard
+library class that already implements :meth:`~object.__class_getitem__`, or
+inherit from :class:`typing.Generic`, which has its own implementation of
+``__class_getitem__()``.
+
+Custom implementations of :meth:`~object.__class_getitem__` on classes defined
+outside of the standard library may not be understood by third-party
+type-checkers such as mypy. Using ``__class_getitem__()`` on any class for
+purposes other than type hinting is discouraged.
+
+
+.. _classgetitem-versus-getitem:
+
+
+*__class_getitem__* versus *__getitem__*
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Usually, the :ref:`subscription<subscriptions>` of an object using square
+brackets will call the :meth:`~object.__getitem__` instance method defined on
+the object's class. However, if the object being subscribed is itself a class,
+the class method :meth:`~object.__class_getitem__` may be called instead.
+``__class_getitem__()`` should return a :ref:`GenericAlias<types-genericalias>`
+object if it is properly defined.
+
+Presented with the :term:`expression` ``obj[x]``, the Python interpreter
+follows something like the following process to decide whether
+:meth:`~object.__getitem__` or :meth:`~object.__class_getitem__` should be
+called::
+
+   from inspect import isclass
+
+   def subscribe(obj, x):
+       """Return the result of the expression `obj[x]`"""
+
+       class_of_obj = type(obj)
+
+       # If the class of obj defines __getitem__,
+       # call class_of_obj.__getitem__(obj, x)
+       if hasattr(class_of_obj, '__getitem__'):
+           return class_of_obj.__getitem__(obj, x)
+
+       # Else, if obj is a class and defines __class_getitem__,
+       # call obj.__class_getitem__(x)
+       elif isclass(obj) and hasattr(obj, '__class_getitem__'):
+           return obj.__class_getitem__(x)
+
+       # Else, raise an exception
+       else:
+           raise TypeError(
+               f"'{class_of_obj.__name__}' object is not subscriptable"
+           )
+
+In Python, all classes are themselves instances of other classes. The class of
+a class is known as that class's :term:`metaclass`, and most classes have the
+:class:`type` class as their metaclass. :class:`type` does not define
+:meth:`~object.__getitem__`, meaning that expressions such as ``list[int]``,
+``dict[str, float]`` and ``tuple[str, bytes]`` all result in
+:meth:`~object.__class_getitem__` being called::
+
+   >>> # list has class "type" as its metaclass, like most classes:
+   >>> type(list)
+   <class 'type'>
+   >>> type(dict) == type(list) == type(tuple) == type(str) == type(bytes)
+   True
+   >>> # "list[int]" calls "list.__class_getitem__(int)"
+   >>> list[int]
+   list[int]
+   >>> # list.__class_getitem__ returns a GenericAlias object:
+   >>> type(list[int])
+   <class 'types.GenericAlias'>
+
+However, if a class has a custom metaclass that defines
+:meth:`~object.__getitem__`, subscribing the class may result in different
+behaviour. An example of this can be found in the :mod:`enum` module::
+
+   >>> from enum import Enum
+   >>> class Menu(Enum):
+   ...     """A breakfast menu"""
+   ...     SPAM = 'spam'
+   ...     BACON = 'bacon'
+   ...
+   >>> # Enum classes have a custom metaclass:
+   >>> type(Menu)
+   <class 'enum.EnumMeta'>
+   >>> # EnumMeta defines __getitem__,
+   >>> # so __class_getitem__ is not called,
+   >>> # and the result is not a GenericAlias object:
+   >>> Menu['SPAM']
+   <Menu.SPAM: 'spam'>
+   >>> type(Menu['SPAM'])
+   <enum 'Menu'>
+
+
+.. seealso::
+   :pep:`560` - Core Support for typing module and generic types
+      Introducing :meth:`~object.__class_getitem__`, and outlining when a
+      :ref:`subscription<subscriptions>` results in ``__class_getitem__()``
+      being called instead of :meth:`~object.__getitem__`
 
 
 .. _callable-types:
@@ -2182,31 +2319,36 @@ Emulating container types
 -------------------------
 
 The following methods can be defined to implement container objects.  Containers
-usually are sequences (such as lists or tuples) or mappings (like dictionaries),
+usually are :term:`sequences <sequence>` (such as :class:`lists <list>` or
+:class:`tuples <tuple>`) or :term:`mappings <mapping>` (like
+:class:`dictionaries <dict>`),
 but can represent other containers as well.  The first set of methods is used
 either to emulate a sequence or to emulate a mapping; the difference is that for
 a sequence, the allowable keys should be the integers *k* for which ``0 <= k <
-N`` where *N* is the length of the sequence, or slice objects, which define a
+N`` where *N* is the length of the sequence, or :class:`slice` objects, which define a
 range of items.  It is also recommended that mappings provide the methods
 :meth:`keys`, :meth:`values`, :meth:`items`, :meth:`get`, :meth:`clear`,
 :meth:`setdefault`, :meth:`pop`, :meth:`popitem`, :meth:`!copy`, and
-:meth:`update` behaving similar to those for Python's standard dictionary
+:meth:`update` behaving similar to those for Python's standard :class:`dictionary <dict>`
 objects.  The :mod:`collections.abc` module provides a
 :class:`~collections.abc.MutableMapping`
-abstract base class to help create those methods from a base set of
-:meth:`__getitem__`, :meth:`__setitem__`, :meth:`__delitem__`, and :meth:`keys`.
+:term:`abstract base class` to help create those methods from a base set of
+:meth:`~object.__getitem__`, :meth:`~object.__setitem__`, :meth:`~object.__delitem__`, and :meth:`keys`.
 Mutable sequences should provide methods :meth:`append`, :meth:`count`,
 :meth:`index`, :meth:`extend`, :meth:`insert`, :meth:`pop`, :meth:`remove`,
-:meth:`reverse` and :meth:`sort`, like Python standard list objects.  Finally,
+:meth:`reverse` and :meth:`sort`, like Python standard :class:`list`
+objects. Finally,
 sequence types should implement addition (meaning concatenation) and
-multiplication (meaning repetition) by defining the methods :meth:`__add__`,
-:meth:`__radd__`, :meth:`__iadd__`, :meth:`__mul__`, :meth:`__rmul__` and
-:meth:`__imul__` described below; they should not define other numerical
+multiplication (meaning repetition) by defining the methods
+:meth:`~object.__add__`, :meth:`~object.__radd__`, :meth:`~object.__iadd__`,
+:meth:`~object.__mul__`, :meth:`~object.__rmul__` and :meth:`~object.__imul__`
+described below; they should not define other numerical
 operators.  It is recommended that both mappings and sequences implement the
-:meth:`__contains__` method to allow efficient use of the ``in`` operator; for
+:meth:`~object.__contains__` method to allow efficient use of the ``in``
+operator; for
 mappings, ``in`` should search the mapping's keys; for sequences, it should
 search through the values.  It is further recommended that both mappings and
-sequences implement the :meth:`__iter__` method to allow efficient iteration
+sequences implement the :meth:`~object.__iter__` method to allow efficient iteration
 through the container; for mappings, :meth:`__iter__` should iterate
 through the object's keys; for sequences, it should iterate through the values.
 
@@ -2259,19 +2401,27 @@ through the object's keys; for sequences, it should iterate through the values.
 
 .. method:: object.__getitem__(self, key)
 
-   Called to implement evaluation of ``self[key]``. For sequence types, the
-   accepted keys should be integers and slice objects.  Note that the special
-   interpretation of negative indexes (if the class wishes to emulate a sequence
-   type) is up to the :meth:`__getitem__` method. If *key* is of an inappropriate
-   type, :exc:`TypeError` may be raised; if of a value outside the set of indexes
-   for the sequence (after any special interpretation of negative values),
-   :exc:`IndexError` should be raised. For mapping types, if *key* is missing (not
-   in the container), :exc:`KeyError` should be raised.
+   Called to implement evaluation of ``self[key]``. For :term:`sequence` types,
+   the accepted keys should be integers and slice objects.  Note that the
+   special interpretation of negative indexes (if the class wishes to emulate a
+   :term:`sequence` type) is up to the :meth:`__getitem__` method. If *key* is
+   of an inappropriate type, :exc:`TypeError` may be raised; if of a value
+   outside the set of indexes for the sequence (after any special
+   interpretation of negative values), :exc:`IndexError` should be raised. For
+   :term:`mapping` types, if *key* is missing (not in the container),
+   :exc:`KeyError` should be raised.
+
+   .. note::
+
+      :keyword:`for` loops expect that an :exc:`IndexError` will be raised for
+      illegal indexes to allow proper detection of the end of the sequence.
 
    .. note::
 
-      :keyword:`for` loops expect that an :exc:`IndexError` will be raised for illegal
-      indexes to allow proper detection of the end of the sequence.
+      When :ref:`subscripting<subscriptions>` a *class*, the special
+      class method :meth:`~object.__class_getitem__` may be called instead of
+      ``__getitem__()``. See :ref:`classgetitem-versus-getitem` for more
+      details.
 
 
 .. method:: object.__setitem__(self, key, value)
@@ -2587,7 +2737,8 @@ exception::
    TypeError: object of type 'C' has no len()
 
 The rationale behind this behaviour lies with a number of special methods such
-as :meth:`__hash__` and :meth:`__repr__` that are implemented by all objects,
+as :meth:`~object.__hash__` and :meth:`~object.__repr__` that are implemented
+by all objects,
 including type objects. If the implicit lookup of these methods used the
 conventional lookup process, they would fail when invoked on the type object
 itself::
@@ -2610,7 +2761,7 @@ the instance when looking up special methods::
 
 In addition to bypassing any instance attributes in the interest of
 correctness, implicit special method lookup generally also bypasses the
-:meth:`__getattribute__` method even of the object's metaclass::
+:meth:`~object.__getattribute__` method even of the object's metaclass::
 
    >>> class Meta(type):
    ...     def __getattribute__(*args):
@@ -2634,7 +2785,7 @@ correctness, implicit special method lookup generally also bypasses the
    >>> len(c)                      # Implicit lookup
    10
 
-Bypassing the :meth:`__getattribute__` machinery in this fashion
+Bypassing the :meth:`~object.__getattribute__` machinery in this fashion
 provides significant scope for speed optimisations within the
 interpreter, at the cost of some flexibility in the handling of
 special methods (the special method *must* be set on the class
@@ -2651,7 +2802,7 @@ Coroutines
 Awaitable Objects
 -----------------
 
-An :term:`awaitable` object generally implements an :meth:`__await__` method.
+An :term:`awaitable` object generally implements an :meth:`~object.__await__` method.
 :term:`Coroutine objects <coroutine>` returned from :keyword:`async def` functions
 are awaitable.
 
@@ -2659,7 +2810,7 @@ are awaitable.
 
    The :term:`generator iterator` objects returned from generators
    decorated with :func:`types.coroutine` or :func:`asyncio.coroutine`
-   are also awaitable, but they do not implement :meth:`__await__`.
+   are also awaitable, but they do not implement :meth:`~object.__await__`.
 
 .. method:: object.__await__(self)
 
@@ -2678,7 +2829,7 @@ Coroutine Objects
 -----------------
 
 :term:`Coroutine objects <coroutine>` are :term:`awaitable` objects.
-A coroutine's execution can be controlled by calling :meth:`__await__` and
+A coroutine's execution can be controlled by calling :meth:`~object.__await__` and
 iterating over the result.  When the coroutine has finished executing and
 returns, the iterator raises :exc:`StopIteration`, and the exception's
 :attr:`~StopIteration.value` attribute holds the return value.  If the
@@ -2697,7 +2848,7 @@ generators, coroutines do not directly support iteration.
 
    Starts or resumes execution of the coroutine.  If *value* is ``None``,
    this is equivalent to advancing the iterator returned by
-   :meth:`__await__`.  If *value* is not ``None``, this method delegates
+   :meth:`~object.__await__`.  If *value* is not ``None``, this method delegates
    to the :meth:`~generator.send` method of the iterator that caused
    the coroutine to suspend.  The result (return value,
    :exc:`StopIteration`, or other exception) is the same as when
@@ -2710,7 +2861,7 @@ generators, coroutines do not directly support iteration.
    the coroutine to suspend, if it has such a method.  Otherwise,
    the exception is raised at the suspension point.  The result
    (return value, :exc:`StopIteration`, or other exception) is the same as
-   when iterating over the :meth:`__await__` return value, described
+   when iterating over the :meth:`~object.__await__` return value, described
    above.  If the exception is not caught in the coroutine, it propagates
    back to the caller.
 
@@ -2764,11 +2915,11 @@ An example of an asynchronous iterable object::
 .. versionadded:: 3.5
 
 .. versionchanged:: 3.7
-   Prior to Python 3.7, ``__aiter__`` could return an *awaitable*
+   Prior to Python 3.7, :meth:`~object.__aiter__` could return an *awaitable*
    that would resolve to an
    :term:`asynchronous iterator <asynchronous iterator>`.
 
-   Starting with Python 3.7, ``__aiter__`` must return an
+   Starting with Python 3.7, :meth:`~object.__aiter__` must return an
    asynchronous iterator object.  Returning anything else
    will result in a :exc:`TypeError` error.
 
@@ -2811,8 +2962,9 @@ An example of an asynchronous context manager class::
    controlled conditions. It generally isn't a good idea though, since it can
    lead to some very strange behaviour if it is handled incorrectly.
 
-.. [#] The :meth:`__hash__`, :meth:`__iter__`, :meth:`__reversed__`, and
-   :meth:`__contains__` methods have special handling for this; others
+.. [#] The :meth:`~object.__hash__`, :meth:`~object.__iter__`,
+   :meth:`~object.__reversed__`, and :meth:`~object.__contains__` methods have
+   special handling for this; others
    will still raise a :exc:`TypeError`, but may do so by relying on
    the behavior that ``None`` is not callable.
 
@@ -2823,5 +2975,6 @@ An example of an asynchronous context manager class::
    *blocking* such fallback.
 
 .. [#] For operands of the same type, it is assumed that if the non-reflected
-   method -- such as :meth:`__add__` -- fails then the overall operation is not
+   method -- such as :meth:`~object.__add__` -- fails then the overall
+   operation is not
    supported, which is why the reflected method is not called.
index 5333de9..606e773 100644 (file)
@@ -422,9 +422,9 @@ Yield expressions
 The yield expression is used when defining a :term:`generator` function
 or an :term:`asynchronous generator` function and
 thus can only be used in the body of a function definition.  Using a yield
-expression in a function's body causes that function to be a generator,
+expression in a function's body causes that function to be a generator function,
 and using it in an :keyword:`async def` function's body causes that
-coroutine function to be an asynchronous generator. For example::
+coroutine function to be an asynchronous generator function. For example::
 
     def gen():  # defines a generator function
         yield 123
index cb21ed2..1b75aed 100644 (file)
@@ -13,4 +13,4 @@ blurb
 
 # The theme used by the documentation is stored separately, so we need
 # to install that as well.
-python-docs-theme
+python-docs-theme>=2022.1
diff --git a/Doc/tools/static/switchers.js b/Doc/tools/static/switchers.js
deleted file mode 100644 (file)
index 1a1c7d0..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-(function() {
-  'use strict';
-
-  // Parses versions in URL segments like:
-  // "3", "dev", "release/2.7" or "3.6rc2"
-  var version_regexs = [
-    '(?:\\d)',
-    '(?:\\d\\.\\d[\\w\\d\\.]*)',
-    '(?:dev)',
-    '(?:release/\\d.\\d[\\x\\d\\.]*)'];
-
-  var all_versions = {
-    '3.10': 'dev (3.10)',
-    '3.9': 'pre (3.9)',
-    '3.8': '3.8',
-    '3.7': '3.7',
-    '3.6': '3.6',
-    '2.7': '2.7',
-  };
-
-  var all_languages = {
-      'en': 'English',
-      'fr': 'French',
-      'ja': 'Japanese',
-      'ko': 'Korean',
-      'pt-br': 'Brazilian Portuguese',
-      'zh-cn': 'Simplified Chinese',
-  };
-
-  function build_version_select(current_version, current_release) {
-    var buf = ['<select>'];
-
-    $.each(all_versions, function(version, title) {
-      buf.push('<option value="' + version + '"');
-      if (version == current_version)
-        buf.push(' selected="selected">' + current_release + '</option>');
-      else
-        buf.push('>' + title + '</option>');
-    });
-
-    buf.push('</select>');
-    return buf.join('');
-  }
-
-  function build_language_select(current_language) {
-    var buf = ['<select>'];
-
-    $.each(all_languages, function(language, title) {
-      if (language == current_language)
-        buf.push('<option value="' + language + '" selected="selected">' +
-                 all_languages[current_language] + '</option>');
-      else
-        buf.push('<option value="' + language + '">' + title + '</option>');
-    });
-    if (!(current_language in all_languages)) {
-        // In case we're browsing a language that is not yet in all_languages.
-        buf.push('<option value="' + current_language + '" selected="selected">' +
-                 current_language + '</option>');
-        all_languages[current_language] = current_language;
-    }
-    buf.push('</select>');
-    return buf.join('');
-  }
-
-  function navigate_to_first_existing(urls) {
-    // Navigate to the first existing URL in urls.
-    var url = urls.shift();
-    if (urls.length == 0) {
-      window.location.href = url;
-      return;
-    }
-    $.ajax({
-      url: url,
-      success: function() {
-        window.location.href = url;
-      },
-      error: function() {
-        navigate_to_first_existing(urls);
-      }
-    });
-  }
-
-  function on_version_switch() {
-    var selected_version = $(this).children('option:selected').attr('value') + '/';
-    var url = window.location.href;
-    var current_language = language_segment_from_url(url);
-    var current_version = version_segment_in_url(url);
-    var new_url = url.replace('.org/' + current_language + current_version,
-                              '.org/' + current_language + selected_version);
-    if (new_url != url) {
-      navigate_to_first_existing([
-        new_url,
-        url.replace('.org/' + current_language + current_version,
-                    '.org/' + selected_version),
-        'https://docs.python.org/' + current_language + selected_version,
-        'https://docs.python.org/' + selected_version,
-        'https://docs.python.org/'
-      ]);
-    }
-  }
-
-  function on_language_switch() {
-    var selected_language = $(this).children('option:selected').attr('value') + '/';
-    var url = window.location.href;
-    var current_language = language_segment_from_url(url);
-    var current_version = version_segment_in_url(url);
-    if (selected_language == 'en/') // Special 'default' case for english.
-      selected_language = '';
-    var new_url = url.replace('.org/' + current_language + current_version,
-                              '.org/' + selected_language + current_version);
-    if (new_url != url) {
-      navigate_to_first_existing([
-        new_url,
-        'https://docs.python.org/'
-      ]);
-    }
-  }
-
-  // Returns the path segment of the language as a string, like 'fr/'
-  // or '' if not found.
-  function language_segment_from_url(url) {
-    var language_regexp = '\.org/([a-z]{2}(?:-[a-z]{2})?/)';
-    var match = url.match(language_regexp);
-    if (match !== null)
-        return match[1];
-    return '';
-  }
-
-  // Returns the path segment of the version as a string, like '3.6/'
-  // or '' if not found.
-  function version_segment_in_url(url) {
-    var language_segment = '(?:[a-z]{2}(?:-[a-z]{2})?/)';
-    var version_segment = '(?:(?:' + version_regexs.join('|') + ')/)';
-    var version_regexp = '\\.org/' + language_segment + '?(' + version_segment + ')';
-    var match = url.match(version_regexp);
-    if (match !== null)
-      return match[1];
-    return ''
-  }
-
-  $(document).ready(function() {
-    var release = DOCUMENTATION_OPTIONS.VERSION;
-    var language_segment = language_segment_from_url(window.location.href);
-    var current_language = language_segment.replace(/\/+$/g, '') || 'en';
-    var version = release.substr(0, 3);
-    var version_select = build_version_select(version, release);
-
-    $('.version_switcher_placeholder').html(version_select);
-    $('.version_switcher_placeholder select').bind('change', on_version_switch);
-
-    var language_select = build_language_select(current_language);
-
-    $('.language_switcher_placeholder').html(language_select);
-    $('.language_switcher_placeholder select').bind('change', on_language_switch);
-  });
-})();
index ad5f55e..02fe917 100644 (file)
@@ -266,6 +266,7 @@ license,,:zooko,mailto:zooko@zooko.com
 reference/expressions,,:index,x[index:index]
 reference/lexical_analysis,,`,$       ?       `
 reference/lexical_analysis,,:fileencoding,# vim:fileencoding=<encoding-name>
+reference/datamodel,,`,    """Return the result of the expression `obj[x]`"""
 tutorial/datastructures,,:value,It is also possible to delete a key:value
 tutorial/datastructures,,:value,key:value pairs within the braces adds initial key:value pairs
 tutorial/stdlib2,,:config,"logging.warning('Warning:config file %s not found', 'server.conf')"
index 68ae3ad..3438b44 100644 (file)
@@ -6,3 +6,12 @@ In extensions/pyspecific.py:
 {% trans %}CPython implementation detail:{% endtrans %}
 {% trans %}Deprecated since version {deprecated}, will be removed in version {removed}{% endtrans %}
 {% trans %}Deprecated since version {deprecated}, removed in version {removed}{% endtrans %}
+
+
+In docsbuild-scripts, when rewriting indexsidebar.html with actual versions:
+
+{% trans %}in development{% endtrans %}
+{% trans %}pre-release{% endtrans %}
+{% trans %}stable{% endtrans %}
+{% trans %}security-fixes{% endtrans %}
+{% trans %}EOL{% endtrans %}
index 1c1cb54..f7bf6d8 100644 (file)
@@ -2,12 +2,8 @@
 <p><a href="{{ pathto('download') }}">{% trans %}Download these documents{% endtrans %}</a></p>
 <h3>{% trans %}Docs by version{% endtrans %}</h3>
 <ul>
-  <li><a href="https://docs.python.org/3.10/">{% trans %}Python 3.10 (in development){% endtrans %}</a></li>
-  <li><a href="https://docs.python.org/3.9/">{% trans %}Python 3.9 (pre-release){% endtrans %}</a></li>
-  <li><a href="https://docs.python.org/3.8/">{% trans %}Python 3.8 (stable){% endtrans %}</a></li>
-  <li><a href="https://docs.python.org/3.7/">{% trans %}Python 3.7 (stable){% endtrans %}</a></li>
-  <li><a href="https://docs.python.org/3.6/">{% trans %}Python 3.6 (security-fixes){% endtrans %}</a></li>
-  <li><a href="https://docs.python.org/2.7/">{% trans %}Python 2.7 (EOL){% endtrans %}</a></li>
+  <li><a href="https://docs.python.org/">{% trans %}Stable{% endtrans %}</a></li>
+  <li><a href="https://docs.python.org/dev/">{% trans %}In development{% endtrans %}</a></li>
   <li><a href="https://www.python.org/doc/versions/">{% trans %}All versions{% endtrans %}</a></li>
 </ul>
 
index 17592d7..98ccf42 100644 (file)
 
 {% block rootrellink %}
 {{ super() }}
-    <li>
-      {%- if switchers is defined %}
-      <span class="language_switcher_placeholder">{{ language or 'en' }}</span>
-      <span class="version_switcher_placeholder">{{ release }}</span>
-      <a href="{{ pathto('index') }}">{% trans %}Documentation {% endtrans %}</a>{{ reldelim1 }}
-      {%- else %}
+    <li id="cpython-language-and-version">
       <a href="{{ pathto('index') }}">{{ shorttitle }}</a>{{ reldelim1 }}
-      {%- endif %}
     </li>
 {% endblock %}
 
 {% block extrahead %}
     <link rel="canonical" href="https://docs.python.org/3/{{pagename}}.html" />
     {% if builder != "htmlhelp" %}
-      {% if switchers is defined and not embedded %}
-      <script type="text/javascript" src="{{ pathto('_static/switchers.js', 1) }}"></script>{% endif %}
       {% if pagename == 'whatsnew/changelog' and not embedded %}
       <script type="text/javascript" src="{{ pathto('_static/changelog_search.js', 1) }}"></script>{% endif %}
     {% endif %}
index 0d780e3..f44cb0b 100644 (file)
@@ -797,7 +797,7 @@ using the :func:`next` built-in function; this example shows how it all works::
    >>> s = 'abc'
    >>> it = iter(s)
    >>> it
-   <iterator object at 0x00A1DB50>
+   <str_iterator object at 0x10c90e650>
    >>> next(it)
    'a'
    >>> next(it)
index 4e2ed1d..542593c 100644 (file)
@@ -326,41 +326,7 @@ be derived from the :exc:`Exception` class, either directly or indirectly.
 
 Exception classes can be defined which do anything any other class can do, but
 are usually kept simple, often only offering a number of attributes that allow
-information about the error to be extracted by handlers for the exception.  When
-creating a module that can raise several distinct errors, a common practice is
-to create a base class for exceptions defined by that module, and subclass that
-to create specific exception classes for different error conditions::
-
-   class Error(Exception):
-       """Base class for exceptions in this module."""
-       pass
-
-   class InputError(Error):
-       """Exception raised for errors in the input.
-
-       Attributes:
-           expression -- input expression in which the error occurred
-           message -- explanation of the error
-       """
-
-       def __init__(self, expression, message):
-           self.expression = expression
-           self.message = message
-
-   class TransitionError(Error):
-       """Raised when an operation attempts a state transition that's not
-       allowed.
-
-       Attributes:
-           previous -- state at beginning of transition
-           next -- attempted new state
-           message -- explanation of why the specific transition is not allowed
-       """
-
-       def __init__(self, previous, next, message):
-           self.previous = previous
-           self.next = next
-           self.message = message
+information about the error to be extracted by handlers for the exception.
 
 Most exceptions are defined with names that end in "Error", similar to the
 naming of the standard exceptions.
index b98de6e..7212b40 100644 (file)
@@ -133,7 +133,7 @@ with inexact values become comparable to one another::
 
 Binary floating-point arithmetic holds many surprises like this.  The problem
 with "0.1" is explained in precise detail below, in the "Representation Error"
-section.  See `The Perils of Floating Point <http://www.lahey.com/float.htm>`_
+section.  See `The Perils of Floating Point <https://www.lahey.com/float.htm>`_
 for a more complete account of other common surprises.
 
 As that says near the end, "there are no easy answers."  Still, don't be unduly
index a52653b..ab64ca6 100644 (file)
@@ -178,13 +178,13 @@ protocols. Two of the simplest are :mod:`urllib.request` for retrieving data
 from URLs and :mod:`smtplib` for sending mail::
 
    >>> from urllib.request import urlopen
-   >>> with urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl') as response:
+   >>> with urlopen('http://worldtimeapi.org/api/timezone/etc/UTC.txt') as response:
    ...     for line in response:
-   ...         line = line.decode('utf-8')  # Decoding the binary data to text.
-   ...         if 'EST' in line or 'EDT' in line:  # look for Eastern Time
-   ...             print(line)
-
-   <BR>Nov. 25, 09:43:32 PM EST
+   ...         line = line.decode()             # Convert bytes to a str
+   ...         if line.startswith('datetime'):
+   ...             print(line.rstrip())         # Remove trailing newline
+   ...
+   datetime: 2022-01-01T01:36:47.689215+00:00
 
    >>> import smtplib
    >>> server = smtplib.SMTP('localhost')
index 6ee52e7..7f7ed59 100644 (file)
 #include "sliceobject.h"
 #include "cellobject.h"
 #include "iterobject.h"
+#include "cpython/initconfig.h"
 #include "genobject.h"
 #include "descrobject.h"
 #include "genericaliasobject.h"
 
 #include "codecs.h"
 #include "pyerrors.h"
-
-#include "cpython/initconfig.h"
 #include "pythread.h"
 #include "pystate.h"
 #include "context.h"
index f292da1..0eb601f 100644 (file)
@@ -6,8 +6,6 @@
 extern "C" {
 #endif
 
-#include "cpython/initconfig.h"
-
 PyAPI_FUNC(int) _PyInterpreterState_RequiresIDRef(PyInterpreterState *);
 PyAPI_FUNC(void) _PyInterpreterState_RequireIDRef(PyInterpreterState *, int);
 
index 18c8f02..e7ace9b 100644 (file)
@@ -90,24 +90,8 @@ static inline int _Py_EnterRecursiveCall_inline(const char *where) {
 
 #define Py_EnterRecursiveCall(where) _Py_EnterRecursiveCall_inline(where)
 
-/* Compute the "lower-water mark" for a recursion limit. When
- * Py_LeaveRecursiveCall() is called with a recursion depth below this mark,
- * the overflowed flag is reset to 0. */
-static inline int _Py_RecursionLimitLowerWaterMark(int limit) {
-    if (limit > 200) {
-        return (limit - 50);
-    }
-    else {
-        return (3 * (limit >> 2));
-    }
-}
-
 static inline void _Py_LeaveRecursiveCall(PyThreadState *tstate)  {
     tstate->recursion_depth--;
-    int limit = tstate->interp->ceval.recursion_limit;
-    if (tstate->recursion_depth < _Py_RecursionLimitLowerWaterMark(limit)) {
-        tstate->overflowed = 0;
-    }
 }
 
 static inline void _Py_LeaveRecursiveCall_inline(void)  {
index 293e51a..23fbd55 100644 (file)
 /*--start constants--*/
 #define PY_MAJOR_VERSION        3
 #define PY_MINOR_VERSION        9
-#define PY_MICRO_VERSION        9
+#define PY_MICRO_VERSION        10
 #define PY_RELEASE_LEVEL        PY_RELEASE_LEVEL_FINAL
 #define PY_RELEASE_SERIAL       0
 
 /* Version as a string */
-#define PY_VERSION              "3.9.9"
+#define PY_VERSION              "3.9.10"
 /*--end constants--*/
 
 /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2.
diff --git a/LICENSE b/LICENSE
index 473861d..739c90c 100644 (file)
--- a/LICENSE
+++ b/LICENSE
@@ -84,7 +84,7 @@ analyze, test, perform and/or display publicly, prepare derivative works,
 distribute, and otherwise use Python alone or in any derivative version,
 provided, however, that PSF's License Agreement and PSF's notice of copyright,
 i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Python Software Foundation;
+2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022 Python Software Foundation;
 All Rights Reserved" are retained in Python alone or in any derivative version
 prepared by Licensee.
 
index 7c28547..4056943 100644 (file)
@@ -392,6 +392,9 @@ class HelpFormatter(object):
         group_actions = set()
         inserts = {}
         for group in groups:
+            if not group._group_actions:
+                raise ValueError(f'empty group {group}')
+
             try:
                 start = actions.index(group._group_actions[0])
             except ValueError:
index bb2f991..8c1fb49 100644 (file)
@@ -1290,8 +1290,8 @@ class BaseEventLoop(events.AbstractEventLoop):
                 addr_infos = {}  # Using order preserving dict
                 for idx, addr in ((0, local_addr), (1, remote_addr)):
                     if addr is not None:
-                        assert isinstance(addr, tuple) and len(addr) == 2, (
-                            '2-tuple is expected')
+                        if not (isinstance(addr, tuple) and len(addr) == 2):
+                            raise TypeError('2-tuple is expected')
 
                         infos = await self._ensure_resolved(
                             addr, family=family, type=socket.SOCK_DGRAM,
index c8e4b40..413ff2a 100644 (file)
@@ -258,13 +258,13 @@ class AbstractEventLoop:
         """Notification that a TimerHandle has been cancelled."""
         raise NotImplementedError
 
-    def call_soon(self, callback, *args):
-        return self.call_later(0, callback, *args)
+    def call_soon(self, callback, *args, context=None):
+        return self.call_later(0, callback, *args, context=context)
 
-    def call_later(self, delay, callback, *args):
+    def call_later(self, delay, callback, *args, context=None):
         raise NotImplementedError
 
-    def call_at(self, when, callback, *args):
+    def call_at(self, when, callback, *args, context=None):
         raise NotImplementedError
 
     def time(self):
@@ -280,7 +280,7 @@ class AbstractEventLoop:
 
     # Methods for interacting with threads.
 
-    def call_soon_threadsafe(self, callback, *args):
+    def call_soon_threadsafe(self, callback, *args, context=None):
         raise NotImplementedError
 
     def run_in_executor(self, executor, func, *args):
index 22ed328..27a3c8c 100644 (file)
@@ -449,11 +449,9 @@ async def wait_for(fut, timeout, *, loop=None):
 
         await _cancel_and_wait(fut, loop=loop)
         try:
-            fut.result()
+            return fut.result()
         except exceptions.CancelledError as exc:
             raise exceptions.TimeoutError() from exc
-        else:
-            raise exceptions.TimeoutError()
 
     waiter = loop.create_future()
     timeout_handle = loop.call_later(timeout, _release_waiter, waiter)
@@ -489,11 +487,9 @@ async def wait_for(fut, timeout, *, loop=None):
             # exception, we should re-raise it
             # See https://bugs.python.org/issue40607
             try:
-                fut.result()
+                return fut.result()
             except exceptions.CancelledError as exc:
                 raise exceptions.TimeoutError() from exc
-            else:
-                raise exceptions.TimeoutError()
     finally:
         timeout_handle.cancel()
 
index 5e7cd79..da81ab4 100644 (file)
@@ -1,5 +1,10 @@
 """Selector and proactor event loops for Windows."""
 
+import sys
+
+if sys.platform != 'win32':  # pragma: no cover
+    raise ImportError('win32 only')
+
 import _overlapped
 import _winapi
 import errno
index 6095026..5c00f2e 100644 (file)
@@ -284,13 +284,14 @@ def wait(fs, timeout=None, return_when=ALL_COMPLETED):
         A named 2-tuple of sets. The first set, named 'done', contains the
         futures that completed (is finished or cancelled) before the wait
         completed. The second set, named 'not_done', contains uncompleted
-        futures.
+        futures. Duplicate futures given to *fs* are removed and will be 
+        returned only once.
     """
+    fs = set(fs)
     with _AcquireFutures(fs):
-        done = set(f for f in fs
-                   if f._state in [CANCELLED_AND_NOTIFIED, FINISHED])
-        not_done = set(fs) - done
-
+        done = {f for f in fs
+                   if f._state in [CANCELLED_AND_NOTIFIED, FINISHED]}
+        not_done = fs - done
         if (return_when == FIRST_COMPLETED) and done:
             return DoneAndNotDoneFutures(done, not_done)
         elif (return_when == FIRST_EXCEPTION) and done:
@@ -309,7 +310,7 @@ def wait(fs, timeout=None, return_when=ALL_COMPLETED):
             f._waiters.remove(waiter)
 
     done.update(waiter.finished_futures)
-    return DoneAndNotDoneFutures(done, set(fs) - done)
+    return DoneAndNotDoneFutures(done, fs - done)
 
 class Future(object):
     """Represents the result of an asynchronous computation."""
index 90bc98b..a29e524 100644 (file)
@@ -373,7 +373,7 @@ class _ExecutorManagerThread(threading.Thread):
         assert not self.thread_wakeup._closed
         wakeup_reader = self.thread_wakeup._reader
         readers = [result_reader, wakeup_reader]
-        worker_sentinels = [p.sentinel for p in self.processes.values()]
+        worker_sentinels = [p.sentinel for p in list(self.processes.values())]
         ready = mp.connection.wait(readers + worker_sentinels)
 
         cause = None
index d3c6536..bdb044e 100644 (file)
@@ -35,34 +35,24 @@ class FunctionTestCase(unittest.TestCase):
         # wasn't checked, and it even crashed Python.
         # Found by Greg Chapman.
 
-        try:
+        with self.assertRaises(TypeError):
             class X(object, Array):
                 _length_ = 5
                 _type_ = "i"
-        except TypeError:
-            pass
-
 
         from _ctypes import _Pointer
-        try:
+        with self.assertRaises(TypeError):
             class X(object, _Pointer):
                 pass
-        except TypeError:
-            pass
 
         from _ctypes import _SimpleCData
-        try:
+        with self.assertRaises(TypeError):
             class X(object, _SimpleCData):
                 _type_ = "i"
-        except TypeError:
-            pass
 
-        try:
+        with self.assertRaises(TypeError):
             class X(object, Structure):
                 _fields_ = []
-        except TypeError:
-            pass
-
 
     @need_symbol('c_wchar')
     def test_wchar_parm(self):
index c98e74d..5ff67ad 100644 (file)
@@ -207,7 +207,7 @@ class InitVar:
         self.type = type
 
     def __repr__(self):
-        if isinstance(self.type, type):
+        if isinstance(self.type, type) and not isinstance(self.type, GenericAlias):
             type_name = self.type.__name__
         else:
             # typing objects, e.g. List[int]
@@ -1047,7 +1047,7 @@ def _is_dataclass_instance(obj):
 def is_dataclass(obj):
     """Returns True if obj is a dataclass or an instance of a
     dataclass."""
-    cls = obj if isinstance(obj, type) else type(obj)
+    cls = obj if isinstance(obj, type) and not isinstance(obj, GenericAlias) else type(obj)
     return hasattr(cls, _FIELDS)
 
 
index 1a290e1..77e5035 100644 (file)
@@ -739,6 +739,7 @@ def _compose_mro(cls, types):
     # Remove entries which are already present in the __mro__ or unrelated.
     def is_related(typ):
         return (typ not in bases and hasattr(typ, '__mro__')
+                                 and not isinstance(typ, GenericAlias)
                                  and issubclass(cls, typ))
     types = [n for n in types if is_related(n)]
     # Remove entries which are strict bases of other entries (they will end up
@@ -836,6 +837,9 @@ def singledispatch(func):
             dispatch_cache[cls] = impl
         return impl
 
+    def _is_valid_dispatch_type(cls):
+        return isinstance(cls, type) and not isinstance(cls, GenericAlias)
+
     def register(cls, func=None):
         """generic_func.register(cls, func) -> func
 
@@ -843,9 +847,15 @@ def singledispatch(func):
 
         """
         nonlocal cache_token
-        if func is None:
-            if isinstance(cls, type):
+        if _is_valid_dispatch_type(cls):
+            if func is None:
                 return lambda f: register(cls, f)
+        else:
+            if func is not None:
+                raise TypeError(
+                    f"Invalid first argument to `register()`. "
+                    f"{cls!r} is not a class."
+                )
             ann = getattr(cls, '__annotations__', {})
             if not ann:
                 raise TypeError(
@@ -858,11 +868,12 @@ def singledispatch(func):
             # only import typing if annotation parsing is necessary
             from typing import get_type_hints
             argname, cls = next(iter(get_type_hints(func).items()))
-            if not isinstance(cls, type):
+            if not _is_valid_dispatch_type(cls):
                 raise TypeError(
                     f"Invalid annotation for {argname!r}. "
                     f"{cls!r} is not a class."
                 )
+
         registry[cls] = func
         if cache_token is None and hasattr(cls, '__abstractmethods__'):
             cache_token = get_cache_token()
index c6c7d31..594986c 100644 (file)
@@ -344,17 +344,26 @@ class Distribution:
         def make_condition(name):
             return name and 'extra == "{name}"'.format(name=name)
 
-        def parse_condition(section):
+        def quoted_marker(section):
             section = section or ''
             extra, sep, markers = section.partition(':')
             if extra and markers:
-                markers = '({markers})'.format(markers=markers)
+                markers = f'({markers})'
             conditions = list(filter(None, [markers, make_condition(extra)]))
             return '; ' + ' and '.join(conditions) if conditions else ''
 
+        def url_req_space(req):
+            """
+            PEP 508 requires a space between the url_spec and the quoted_marker.
+            Ref python/importlib_metadata#357.
+            """
+            # '@' is uniquely indicative of a url_req.
+            return ' ' * ('@' in req)
+
         for section, deps in sections.items():
             for dep in deps:
-                yield dep + parse_condition(section)
+                space = url_req_space(dep)
+                yield dep + space + quoted_marker(section)
 
 
 class DistributionFinder(MetaPathFinder):
index 2c52bde..e4c21da 100644 (file)
@@ -133,7 +133,7 @@ def dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True,
 
     If ``check_circular`` is false, then the circular reference check
     for container types will be skipped and a circular reference will
-    result in an ``OverflowError`` (or worse).
+    result in an ``RecursionError`` (or worse).
 
     If ``allow_nan`` is false, then it will be a ``ValueError`` to
     serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``)
@@ -195,7 +195,7 @@ def dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True,
 
     If ``check_circular`` is false, then the circular reference check
     for container types will be skipped and a circular reference will
-    result in an ``OverflowError`` (or worse).
+    result in an ``RecursionError`` (or worse).
 
     If ``allow_nan`` is false, then it will be a ``ValueError`` to
     serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in
index c8c78b9..21bff2c 100644 (file)
@@ -116,7 +116,7 @@ class JSONEncoder(object):
 
         If check_circular is true, then lists, dicts, and custom encoded
         objects will be checked for circular references during encoding to
-        prevent an infinite recursion (which would cause an OverflowError).
+        prevent an infinite recursion (which would cause an RecursionError).
         Otherwise, no such check takes place.
 
         If allow_nan is true, then NaN, Infinity, and -Infinity will be
index f8040c4..572e370 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright 2001-2016 by Vinay Sajip. All Rights Reserved.
+# Copyright 2001-2021 by Vinay Sajip. All Rights Reserved.
 #
 # Permission to use, copy, modify, and distribute this software and its
 # documentation for any purpose and without fee is hereby granted,
@@ -18,7 +18,7 @@
 Additional handlers for the logging package for Python. The core package is
 based on PEP 282 and comments thereto in comp.lang.python.
 
-Copyright (C) 2001-2016 Vinay Sajip. All Rights Reserved.
+Copyright (C) 2001-2021 Vinay Sajip. All Rights Reserved.
 
 To use, simply 'import logging.handlers' and log away!
 """
@@ -363,9 +363,22 @@ class TimedRotatingFileHandler(BaseRotatingHandler):
         fileNames = os.listdir(dirName)
         result = []
         # See bpo-44753: Don't use the extension when computing the prefix.
-        prefix = os.path.splitext(baseName)[0] + "."
+        n, e = os.path.splitext(baseName)
+        prefix = n + '.'
         plen = len(prefix)
         for fileName in fileNames:
+            if self.namer is None:
+                # Our files will always start with baseName
+                if not fileName.startswith(baseName):
+                    continue
+            else:
+                # Our files could be just about anything after custom naming, but
+                # likely candidates are of the form
+                # foo.log.DATETIME_SUFFIX or foo.DATETIME_SUFFIX.log
+                if (not fileName.startswith(baseName) and fileName.endswith(e) and
+                    len(fileName) > (plen + 1) and not fileName[plen+1].isdigit()):
+                    continue
+
             if fileName[:plen] == prefix:
                 suffix = fileName[plen:]
                 # See bpo-45628: The date/time suffix could be anywhere in the
index 890a616..67a5197 100644 (file)
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-# Autogenerated by Sphinx on Mon Nov 15 18:21:10 2021
+# Autogenerated by Sphinx on Thu Jan 13 21:46:32 2022
 topics = {'assert': 'The "assert" statement\n'
            '**********************\n'
            '\n'
@@ -979,7 +979,7 @@ topics = {'assert': 'The "assert" statement\n'
                      '"super(B,\n'
                      '   obj).m()" searches "obj.__class__.__mro__" for the '
                      'base class "A"\n'
-                     '   immediately preceding "B" and then invokes the '
+                     '   immediately following "B" and then invokes the '
                      'descriptor with the\n'
                      '   call: "A.__dict__[\'m\'].__get__(obj, '
                      'obj.__class__)".\n'
@@ -1010,14 +1010,15 @@ topics = {'assert': 'The "assert" statement\n'
                      'can be\n'
                      'overridden by instances.\n'
                      '\n'
-                     'Python methods (including "staticmethod()" and '
-                     '"classmethod()") are\n'
-                     'implemented as non-data descriptors.  Accordingly, '
-                     'instances can\n'
-                     'redefine and override methods.  This allows individual '
-                     'instances to\n'
-                     'acquire behaviors that differ from other instances of '
-                     'the same class.\n'
+                     'Python methods (including those decorated with '
+                     '"@staticmethod" and\n'
+                     '"@classmethod") are implemented as non-data '
+                     'descriptors.  Accordingly,\n'
+                     'instances can redefine and override methods.  This '
+                     'allows individual\n'
+                     'instances to acquire behaviors that differ from other '
+                     'instances of the\n'
+                     'same class.\n'
                      '\n'
                      'The "property()" function is implemented as a data '
                      'descriptor.\n'
@@ -1030,12 +1031,12 @@ topics = {'assert': 'The "assert" statement\n'
                      '\n'
                      '*__slots__* allow us to explicitly declare data members '
                      '(like\n'
-                     'properties) and deny the creation of *__dict__* and '
+                     'properties) and deny the creation of "__dict__" and '
                      '*__weakref__*\n'
                      '(unless explicitly declared in *__slots__* or available '
                      'in a parent.)\n'
                      '\n'
-                     'The space saved over using *__dict__* can be '
+                     'The space saved over using "__dict__" can be '
                      'significant. Attribute\n'
                      'lookup speed can be significantly improved as well.\n'
                      '\n'
@@ -1047,7 +1048,7 @@ topics = {'assert': 'The "assert" statement\n'
                      '*__slots__*\n'
                      '   reserves space for the declared variables and '
                      'prevents the\n'
-                     '   automatic creation of *__dict__* and *__weakref__* '
+                     '   automatic creation of "__dict__" and *__weakref__* '
                      'for each\n'
                      '   instance.\n'
                      '\n'
@@ -1056,11 +1057,11 @@ topics = {'assert': 'The "assert" statement\n'
                      '--------------------------\n'
                      '\n'
                      '* When inheriting from a class without *__slots__*, the '
-                     '*__dict__* and\n'
+                     '"__dict__" and\n'
                      '  *__weakref__* attribute of the instances will always '
                      'be accessible.\n'
                      '\n'
-                     '* Without a *__dict__* variable, instances cannot be '
+                     '* Without a "__dict__" variable, instances cannot be '
                      'assigned new\n'
                      '  variables not listed in the *__slots__* definition.  '
                      'Attempts to\n'
@@ -1074,28 +1075,28 @@ topics = {'assert': 'The "assert" statement\n'
                      '\n'
                      '* Without a *__weakref__* variable for each instance, '
                      'classes defining\n'
-                     '  *__slots__* do not support weak references to its '
-                     'instances. If weak\n'
-                     '  reference support is needed, then add '
+                     '  *__slots__* do not support "weak references" to its '
+                     'instances. If\n'
+                     '  weak reference support is needed, then add '
                      '"\'__weakref__\'" to the\n'
                      '  sequence of strings in the *__slots__* declaration.\n'
                      '\n'
                      '* *__slots__* are implemented at the class level by '
                      'creating\n'
-                     '  descriptors (Implementing Descriptors) for each '
-                     'variable name.  As a\n'
-                     '  result, class attributes cannot be used to set default '
-                     'values for\n'
-                     '  instance variables defined by *__slots__*; otherwise, '
-                     'the class\n'
-                     '  attribute would overwrite the descriptor assignment.\n'
+                     '  descriptors for each variable name.  As a result, '
+                     'class attributes\n'
+                     '  cannot be used to set default values for instance '
+                     'variables defined\n'
+                     '  by *__slots__*; otherwise, the class attribute would '
+                     'overwrite the\n'
+                     '  descriptor assignment.\n'
                      '\n'
                      '* The action of a *__slots__* declaration is not limited '
                      'to the class\n'
                      '  where it is defined.  *__slots__* declared in parents '
                      'are available\n'
                      '  in child classes. However, child subclasses will get a '
-                     '*__dict__*\n'
+                     '"__dict__"\n'
                      '  and *__weakref__* unless they also define *__slots__* '
                      '(which should\n'
                      '  only contain names of any *additional* slots).\n'
@@ -1115,13 +1116,19 @@ topics = {'assert': 'The "assert" statement\n'
                      '  “variable-length” built-in types such as "int", '
                      '"bytes" and "tuple".\n'
                      '\n'
-                     '* Any non-string iterable may be assigned to '
-                     '*__slots__*. Mappings may\n'
-                     '  also be used; however, in the future, special meaning '
-                     'may be\n'
-                     '  assigned to the values corresponding to each key.\n'
+                     '* Any non-string *iterable* may be assigned to '
+                     '*__slots__*.\n'
                      '\n'
-                     '* *__class__* assignment works only if both classes have '
+                     '* If a "dictionary" is used to assign *__slots__*, the '
+                     'dictionary keys\n'
+                     '  will be used as the slot names. The values of the '
+                     'dictionary can be\n'
+                     '  used to provide per-attribute docstrings that will be '
+                     'recognised by\n'
+                     '  "inspect.getdoc()" and displayed in the output of '
+                     '"help()".\n'
+                     '\n'
+                     '* "__class__" assignment works only if both classes have '
                      'the same\n'
                      '  *__slots__*.\n'
                      '\n'
@@ -1133,10 +1140,10 @@ topics = {'assert': 'The "assert" statement\n'
                      'violations\n'
                      '  raise "TypeError".\n'
                      '\n'
-                     '* If an iterator is used for *__slots__* then a '
-                     'descriptor is created\n'
-                     '  for each of the iterator’s values. However, the '
-                     '*__slots__*\n'
+                     '* If an *iterator* is used for *__slots__* then a '
+                     '*descriptor* is\n'
+                     '  created for each of the iterator’s values. However, '
+                     'the *__slots__*\n'
                      '  attribute will be an empty iterator.\n',
  'attribute-references': 'Attribute references\n'
                          '********************\n'
@@ -3763,17 +3770,16 @@ topics = {'assert': 'The "assert" statement\n'
              'debugger will pause execution just before the first line of the\n'
              'module.\n'
              '\n'
-             'The typical usage to break into the debugger from a running '
-             'program is\n'
-             'to insert\n'
+             'The typical usage to break into the debugger is to insert:\n'
              '\n'
              '   import pdb; pdb.set_trace()\n'
              '\n'
-             'at the location you want to break into the debugger.  You can '
-             'then\n'
-             'step through the code following this statement, and continue '
-             'running\n'
-             'without the debugger using the "continue" command.\n'
+             'at the location you want to break into the debugger, and then '
+             'run the\n'
+             'program. You can then step through the code following this '
+             'statement,\n'
+             'and continue running without the debugger using the "continue"\n'
+             'command.\n'
              '\n'
              'New in version 3.7: The built-in "breakpoint()", when called '
              'with\n'
@@ -7655,61 +7661,62 @@ topics = {'assert': 'The "assert" statement\n'
                    '\n'
                    'The following methods can be defined to implement '
                    'container objects.\n'
-                   'Containers usually are sequences (such as lists or tuples) '
-                   'or mappings\n'
-                   '(like dictionaries), but can represent other containers as '
-                   'well.  The\n'
-                   'first set of methods is used either to emulate a sequence '
-                   'or to\n'
-                   'emulate a mapping; the difference is that for a sequence, '
-                   'the\n'
-                   'allowable keys should be the integers *k* for which "0 <= '
-                   'k < N" where\n'
-                   '*N* is the length of the sequence, or slice objects, which '
-                   'define a\n'
-                   'range of items.  It is also recommended that mappings '
-                   'provide the\n'
-                   'methods "keys()", "values()", "items()", "get()", '
-                   '"clear()",\n'
-                   '"setdefault()", "pop()", "popitem()", "copy()", and '
-                   '"update()"\n'
-                   'behaving similar to those for Python’s standard dictionary '
+                   'Containers usually are *sequences* (such as "lists" or '
+                   '"tuples") or\n'
+                   '*mappings* (like "dictionaries"), but can represent other '
+                   'containers\n'
+                   'as well.  The first set of methods is used either to '
+                   'emulate a\n'
+                   'sequence or to emulate a mapping; the difference is that '
+                   'for a\n'
+                   'sequence, the allowable keys should be the integers *k* '
+                   'for which "0\n'
+                   '<= k < N" where *N* is the length of the sequence, or '
+                   '"slice" objects,\n'
+                   'which define a range of items.  It is also recommended '
+                   'that mappings\n'
+                   'provide the methods "keys()", "values()", "items()", '
+                   '"get()",\n'
+                   '"clear()", "setdefault()", "pop()", "popitem()", "copy()", '
+                   'and\n'
+                   '"update()" behaving similar to those for Python’s '
+                   'standard\n'
+                   '"dictionary" objects.  The "collections.abc" module '
+                   'provides a\n'
+                   '"MutableMapping" *abstract base class* to help create '
+                   'those methods\n'
+                   'from a base set of "__getitem__()", "__setitem__()", '
+                   '"__delitem__()",\n'
+                   'and "keys()". Mutable sequences should provide methods '
+                   '"append()",\n'
+                   '"count()", "index()", "extend()", "insert()", "pop()", '
+                   '"remove()",\n'
+                   '"reverse()" and "sort()", like Python standard "list" '
                    'objects.\n'
-                   'The "collections.abc" module provides a "MutableMapping" '
-                   'abstract base\n'
-                   'class to help create those methods from a base set of '
-                   '"__getitem__()",\n'
-                   '"__setitem__()", "__delitem__()", and "keys()". Mutable '
-                   'sequences\n'
-                   'should provide methods "append()", "count()", "index()", '
-                   '"extend()",\n'
-                   '"insert()", "pop()", "remove()", "reverse()" and "sort()", '
-                   'like Python\n'
-                   'standard list objects.  Finally, sequence types should '
-                   'implement\n'
-                   'addition (meaning concatenation) and multiplication '
+                   'Finally, sequence types should implement addition '
                    '(meaning\n'
-                   'repetition) by defining the methods "__add__()", '
-                   '"__radd__()",\n'
-                   '"__iadd__()", "__mul__()", "__rmul__()" and "__imul__()" '
-                   'described\n'
-                   'below; they should not define other numerical operators.  '
+                   'concatenation) and multiplication (meaning repetition) by '
+                   'defining the\n'
+                   'methods "__add__()", "__radd__()", "__iadd__()", '
+                   '"__mul__()",\n'
+                   '"__rmul__()" and "__imul__()" described below; they should '
+                   'not define\n'
+                   'other numerical operators.  It is recommended that both '
+                   'mappings and\n'
+                   'sequences implement the "__contains__()" method to allow '
+                   'efficient use\n'
+                   'of the "in" operator; for mappings, "in" should search the '
+                   'mapping’s\n'
+                   'keys; for sequences, it should search through the values.  '
                    'It is\n'
-                   'recommended that both mappings and sequences implement '
+                   'further recommended that both mappings and sequences '
+                   'implement the\n'
+                   '"__iter__()" method to allow efficient iteration through '
                    'the\n'
-                   '"__contains__()" method to allow efficient use of the "in" '
-                   'operator;\n'
-                   'for mappings, "in" should search the mapping’s keys; for '
-                   'sequences, it\n'
-                   'should search through the values.  It is further '
-                   'recommended that both\n'
-                   'mappings and sequences implement the "__iter__()" method '
-                   'to allow\n'
-                   'efficient iteration through the container; for mappings, '
-                   '"__iter__()"\n'
-                   'should iterate through the object’s keys; for sequences, '
-                   'it should\n'
-                   'iterate through the values.\n'
+                   'container; for mappings, "__iter__()" should iterate '
+                   'through the\n'
+                   'object’s keys; for sequences, it should iterate through '
+                   'the values.\n'
                    '\n'
                    'object.__len__(self)\n'
                    '\n'
@@ -7768,22 +7775,24 @@ topics = {'assert': 'The "assert" statement\n'
                    'object.__getitem__(self, key)\n'
                    '\n'
                    '   Called to implement evaluation of "self[key]". For '
-                   'sequence types,\n'
-                   '   the accepted keys should be integers and slice '
-                   'objects.  Note that\n'
-                   '   the special interpretation of negative indexes (if the '
-                   'class wishes\n'
-                   '   to emulate a sequence type) is up to the '
-                   '"__getitem__()" method. If\n'
-                   '   *key* is of an inappropriate type, "TypeError" may be '
-                   'raised; if of\n'
-                   '   a value outside the set of indexes for the sequence '
-                   '(after any\n'
-                   '   special interpretation of negative values), '
-                   '"IndexError" should be\n'
-                   '   raised. For mapping types, if *key* is missing (not in '
+                   '*sequence*\n'
+                   '   types, the accepted keys should be integers and slice '
+                   'objects.\n'
+                   '   Note that the special interpretation of negative '
+                   'indexes (if the\n'
+                   '   class wishes to emulate a *sequence* type) is up to '
                    'the\n'
-                   '   container), "KeyError" should be raised.\n'
+                   '   "__getitem__()" method. If *key* is of an inappropriate '
+                   'type,\n'
+                   '   "TypeError" may be raised; if of a value outside the '
+                   'set of indexes\n'
+                   '   for the sequence (after any special interpretation of '
+                   'negative\n'
+                   '   values), "IndexError" should be raised. For *mapping* '
+                   'types, if\n'
+                   '   *key* is missing (not in the container), "KeyError" '
+                   'should be\n'
+                   '   raised.\n'
                    '\n'
                    '   Note:\n'
                    '\n'
@@ -7793,6 +7802,15 @@ topics = {'assert': 'The "assert" statement\n'
                    'of the\n'
                    '     sequence.\n'
                    '\n'
+                   '   Note:\n'
+                   '\n'
+                   '     When subscripting a *class*, the special class '
+                   'method\n'
+                   '     "__class_getitem__()" may be called instead of '
+                   '"__getitem__()".\n'
+                   '     See __class_getitem__ versus __getitem__ for more '
+                   'details.\n'
+                   '\n'
                    'object.__setitem__(self, key, value)\n'
                    '\n'
                    '   Called to implement assignment to "self[key]".  Same '
@@ -8891,7 +8909,7 @@ topics = {'assert': 'The "assert" statement\n'
                  '"super(B,\n'
                  '   obj).m()" searches "obj.__class__.__mro__" for the base '
                  'class "A"\n'
-                 '   immediately preceding "B" and then invokes the descriptor '
+                 '   immediately following "B" and then invokes the descriptor '
                  'with the\n'
                  '   call: "A.__dict__[\'m\'].__get__(obj, obj.__class__)".\n'
                  '\n'
@@ -8921,13 +8939,14 @@ topics = {'assert': 'The "assert" statement\n'
                  'be\n'
                  'overridden by instances.\n'
                  '\n'
-                 'Python methods (including "staticmethod()" and '
-                 '"classmethod()") are\n'
-                 'implemented as non-data descriptors.  Accordingly, instances '
-                 'can\n'
-                 'redefine and override methods.  This allows individual '
-                 'instances to\n'
-                 'acquire behaviors that differ from other instances of the '
+                 'Python methods (including those decorated with '
+                 '"@staticmethod" and\n'
+                 '"@classmethod") are implemented as non-data descriptors.  '
+                 'Accordingly,\n'
+                 'instances can redefine and override methods.  This allows '
+                 'individual\n'
+                 'instances to acquire behaviors that differ from other '
+                 'instances of the\n'
                  'same class.\n'
                  '\n'
                  'The "property()" function is implemented as a data '
@@ -8941,12 +8960,12 @@ topics = {'assert': 'The "assert" statement\n'
                  '\n'
                  '*__slots__* allow us to explicitly declare data members '
                  '(like\n'
-                 'properties) and deny the creation of *__dict__* and '
+                 'properties) and deny the creation of "__dict__" and '
                  '*__weakref__*\n'
                  '(unless explicitly declared in *__slots__* or available in a '
                  'parent.)\n'
                  '\n'
-                 'The space saved over using *__dict__* can be significant. '
+                 'The space saved over using "__dict__" can be significant. '
                  'Attribute\n'
                  'lookup speed can be significantly improved as well.\n'
                  '\n'
@@ -8958,7 +8977,7 @@ topics = {'assert': 'The "assert" statement\n'
                  '*__slots__*\n'
                  '   reserves space for the declared variables and prevents '
                  'the\n'
-                 '   automatic creation of *__dict__* and *__weakref__* for '
+                 '   automatic creation of "__dict__" and *__weakref__* for '
                  'each\n'
                  '   instance.\n'
                  '\n'
@@ -8967,11 +8986,11 @@ topics = {'assert': 'The "assert" statement\n'
                  '~~~~~~~~~~~~~~~~~~~~~~~~~~\n'
                  '\n'
                  '* When inheriting from a class without *__slots__*, the '
-                 '*__dict__* and\n'
+                 '"__dict__" and\n'
                  '  *__weakref__* attribute of the instances will always be '
                  'accessible.\n'
                  '\n'
-                 '* Without a *__dict__* variable, instances cannot be '
+                 '* Without a "__dict__" variable, instances cannot be '
                  'assigned new\n'
                  '  variables not listed in the *__slots__* definition.  '
                  'Attempts to\n'
@@ -8984,28 +9003,28 @@ topics = {'assert': 'The "assert" statement\n'
                  '\n'
                  '* Without a *__weakref__* variable for each instance, '
                  'classes defining\n'
-                 '  *__slots__* do not support weak references to its '
-                 'instances. If weak\n'
-                 '  reference support is needed, then add "\'__weakref__\'" to '
-                 'the\n'
+                 '  *__slots__* do not support "weak references" to its '
+                 'instances. If\n'
+                 '  weak reference support is needed, then add '
+                 '"\'__weakref__\'" to the\n'
                  '  sequence of strings in the *__slots__* declaration.\n'
                  '\n'
                  '* *__slots__* are implemented at the class level by '
                  'creating\n'
-                 '  descriptors (Implementing Descriptors) for each variable '
-                 'name.  As a\n'
-                 '  result, class attributes cannot be used to set default '
-                 'values for\n'
-                 '  instance variables defined by *__slots__*; otherwise, the '
-                 'class\n'
-                 '  attribute would overwrite the descriptor assignment.\n'
+                 '  descriptors for each variable name.  As a result, class '
+                 'attributes\n'
+                 '  cannot be used to set default values for instance '
+                 'variables defined\n'
+                 '  by *__slots__*; otherwise, the class attribute would '
+                 'overwrite the\n'
+                 '  descriptor assignment.\n'
                  '\n'
                  '* The action of a *__slots__* declaration is not limited to '
                  'the class\n'
                  '  where it is defined.  *__slots__* declared in parents are '
                  'available\n'
                  '  in child classes. However, child subclasses will get a '
-                 '*__dict__*\n'
+                 '"__dict__"\n'
                  '  and *__weakref__* unless they also define *__slots__* '
                  '(which should\n'
                  '  only contain names of any *additional* slots).\n'
@@ -9025,13 +9044,18 @@ topics = {'assert': 'The "assert" statement\n'
                  '  “variable-length” built-in types such as "int", "bytes" '
                  'and "tuple".\n'
                  '\n'
-                 '* Any non-string iterable may be assigned to *__slots__*. '
-                 'Mappings may\n'
-                 '  also be used; however, in the future, special meaning may '
-                 'be\n'
-                 '  assigned to the values corresponding to each key.\n'
+                 '* Any non-string *iterable* may be assigned to *__slots__*.\n'
+                 '\n'
+                 '* If a "dictionary" is used to assign *__slots__*, the '
+                 'dictionary keys\n'
+                 '  will be used as the slot names. The values of the '
+                 'dictionary can be\n'
+                 '  used to provide per-attribute docstrings that will be '
+                 'recognised by\n'
+                 '  "inspect.getdoc()" and displayed in the output of '
+                 '"help()".\n'
                  '\n'
-                 '* *__class__* assignment works only if both classes have the '
+                 '* "__class__" assignment works only if both classes have the '
                  'same\n'
                  '  *__slots__*.\n'
                  '\n'
@@ -9043,9 +9067,9 @@ topics = {'assert': 'The "assert" statement\n'
                  'violations\n'
                  '  raise "TypeError".\n'
                  '\n'
-                 '* If an iterator is used for *__slots__* then a descriptor '
-                 'is created\n'
-                 '  for each of the iterator’s values. However, the '
+                 '* If an *iterator* is used for *__slots__* then a '
+                 '*descriptor* is\n'
+                 '  created for each of the iterator’s values. However, the '
                  '*__slots__*\n'
                  '  attribute will be an empty iterator.\n'
                  '\n'
@@ -9054,7 +9078,7 @@ topics = {'assert': 'The "assert" statement\n'
                  '==========================\n'
                  '\n'
                  'Whenever a class inherits from another class, '
-                 '*__init_subclass__* is\n'
+                 '"__init_subclass__()" is\n'
                  'called on that class. This way, it is possible to write '
                  'classes which\n'
                  'change the behavior of subclasses. This is closely related '
@@ -9222,10 +9246,10 @@ topics = {'assert': 'The "assert" statement\n'
                  'come from\n'
                  'the class definition). The "__prepare__" method should be '
                  'implemented\n'
-                 'as a "classmethod()". The namespace returned by '
-                 '"__prepare__" is\n'
-                 'passed in to "__new__", but when the final class object is '
-                 'created the\n'
+                 'as a "classmethod". The namespace returned by "__prepare__" '
+                 'is passed\n'
+                 'in to "__new__", but when the final class object is created '
+                 'the\n'
                  'namespace is copied into a new "dict".\n'
                  '\n'
                  'If the metaclass has no "__prepare__" attribute, then the '
@@ -9413,9 +9437,33 @@ topics = {'assert': 'The "assert" statement\n'
                  'Emulating generic types\n'
                  '=======================\n'
                  '\n'
-                 'One can implement the generic class syntax as specified by '
-                 '**PEP 484**\n'
-                 '(for example "List[int]") by defining a special method:\n'
+                 'When using *type annotations*, it is often useful to '
+                 '*parameterize* a\n'
+                 '*generic type* using Python’s square-brackets notation. For '
+                 'example,\n'
+                 'the annotation "list[int]" might be used to signify a "list" '
+                 'in which\n'
+                 'all the elements are of type "int".\n'
+                 '\n'
+                 'See also:\n'
+                 '\n'
+                 '  **PEP 484** - Type Hints\n'
+                 '     Introducing Python’s framework for type annotations\n'
+                 '\n'
+                 '  Generic Alias Types\n'
+                 '     Documentation for objects representing parameterized '
+                 'generic\n'
+                 '     classes\n'
+                 '\n'
+                 '  Generics, user-defined generics and "typing.Generic"\n'
+                 '     Documentation on how to implement generic classes that '
+                 'can be\n'
+                 '     parameterized at runtime and understood by static '
+                 'type-checkers.\n'
+                 '\n'
+                 'A class can *generally* only be parameterized if it defines '
+                 'the\n'
+                 'special class method "__class_getitem__()".\n'
                  '\n'
                  'classmethod object.__class_getitem__(cls, key)\n'
                  '\n'
@@ -9423,18 +9471,144 @@ topics = {'assert': 'The "assert" statement\n'
                  'generic class\n'
                  '   by type arguments found in *key*.\n'
                  '\n'
-                 'This method is looked up on the class object itself, and '
-                 'when defined\n'
-                 'in the class body, this method is implicitly a class '
-                 'method.  Note,\n'
-                 'this mechanism is primarily reserved for use with static '
-                 'type hints,\n'
-                 'other usage is discouraged.\n'
+                 '   When defined on a class, "__class_getitem__()" is '
+                 'automatically a\n'
+                 '   class method. As such, there is no need for it to be '
+                 'decorated with\n'
+                 '   "@classmethod" when it is defined.\n'
+                 '\n'
+                 '\n'
+                 'The purpose of *__class_getitem__*\n'
+                 '----------------------------------\n'
+                 '\n'
+                 'The purpose of "__class_getitem__()" is to allow runtime\n'
+                 'parameterization of standard-library generic classes in '
+                 'order to more\n'
+                 'easily apply *type hints* to these classes.\n'
+                 '\n'
+                 'To implement custom generic classes that can be '
+                 'parameterized at\n'
+                 'runtime and understood by static type-checkers, users should '
+                 'either\n'
+                 'inherit from a standard library class that already '
+                 'implements\n'
+                 '"__class_getitem__()", or inherit from "typing.Generic", '
+                 'which has its\n'
+                 'own implementation of "__class_getitem__()".\n'
+                 '\n'
+                 'Custom implementations of "__class_getitem__()" on classes '
+                 'defined\n'
+                 'outside of the standard library may not be understood by '
+                 'third-party\n'
+                 'type-checkers such as mypy. Using "__class_getitem__()" on '
+                 'any class\n'
+                 'for purposes other than type hinting is discouraged.\n'
+                 '\n'
+                 '\n'
+                 '*__class_getitem__* versus *__getitem__*\n'
+                 '----------------------------------------\n'
+                 '\n'
+                 'Usually, the subscription of an object using square brackets '
+                 'will call\n'
+                 'the "__getitem__()" instance method defined on the object’s '
+                 'class.\n'
+                 'However, if the object being subscribed is itself a class, '
+                 'the class\n'
+                 'method "__class_getitem__()" may be called instead.\n'
+                 '"__class_getitem__()" should return a GenericAlias object if '
+                 'it is\n'
+                 'properly defined.\n'
+                 '\n'
+                 'Presented with the *expression* "obj[x]", the Python '
+                 'interpreter\n'
+                 'follows something like the following process to decide '
+                 'whether\n'
+                 '"__getitem__()" or "__class_getitem__()" should be called:\n'
+                 '\n'
+                 '   from inspect import isclass\n'
+                 '\n'
+                 '   def subscribe(obj, x):\n'
+                 '       """Return the result of the expression `obj[x]`"""\n'
+                 '\n'
+                 '       class_of_obj = type(obj)\n'
+                 '\n'
+                 '       # If the class of obj defines __getitem__,\n'
+                 '       # call class_of_obj.__getitem__(obj, x)\n'
+                 "       if hasattr(class_of_obj, '__getitem__'):\n"
+                 '           return class_of_obj.__getitem__(obj, x)\n'
+                 '\n'
+                 '       # Else, if obj is a class and defines '
+                 '__class_getitem__,\n'
+                 '       # call obj.__class_getitem__(x)\n'
+                 '       elif isclass(obj) and hasattr(obj, '
+                 "'__class_getitem__'):\n"
+                 '           return obj.__class_getitem__(x)\n'
+                 '\n'
+                 '       # Else, raise an exception\n'
+                 '       else:\n'
+                 '           raise TypeError(\n'
+                 '               f"\'{class_of_obj.__name__}\' object is not '
+                 'subscriptable"\n'
+                 '           )\n'
+                 '\n'
+                 'In Python, all classes are themselves instances of other '
+                 'classes. The\n'
+                 'class of a class is known as that class’s *metaclass*, and '
+                 'most\n'
+                 'classes have the "type" class as their metaclass. "type" '
+                 'does not\n'
+                 'define "__getitem__()", meaning that expressions such as '
+                 '"list[int]",\n'
+                 '"dict[str, float]" and "tuple[str, bytes]" all result in\n'
+                 '"__class_getitem__()" being called:\n'
+                 '\n'
+                 '   >>> # list has class "type" as its metaclass, like most '
+                 'classes:\n'
+                 '   >>> type(list)\n'
+                 "   <class 'type'>\n"
+                 '   >>> type(dict) == type(list) == type(tuple) == type(str) '
+                 '== type(bytes)\n'
+                 '   True\n'
+                 '   >>> # "list[int]" calls "list.__class_getitem__(int)"\n'
+                 '   >>> list[int]\n'
+                 '   list[int]\n'
+                 '   >>> # list.__class_getitem__ returns a GenericAlias '
+                 'object:\n'
+                 '   >>> type(list[int])\n'
+                 "   <class 'types.GenericAlias'>\n"
+                 '\n'
+                 'However, if a class has a custom metaclass that defines\n'
+                 '"__getitem__()", subscribing the class may result in '
+                 'different\n'
+                 'behaviour. An example of this can be found in the "enum" '
+                 'module:\n'
+                 '\n'
+                 '   >>> from enum import Enum\n'
+                 '   >>> class Menu(Enum):\n'
+                 '   ...     """A breakfast menu"""\n'
+                 "   ...     SPAM = 'spam'\n"
+                 "   ...     BACON = 'bacon'\n"
+                 '   ...\n'
+                 '   >>> # Enum classes have a custom metaclass:\n'
+                 '   >>> type(Menu)\n'
+                 "   <class 'enum.EnumMeta'>\n"
+                 '   >>> # EnumMeta defines __getitem__,\n'
+                 '   >>> # so __class_getitem__ is not called,\n'
+                 '   >>> # and the result is not a GenericAlias object:\n'
+                 "   >>> Menu['SPAM']\n"
+                 "   <Menu.SPAM: 'spam'>\n"
+                 "   >>> type(Menu['SPAM'])\n"
+                 "   <enum 'Menu'>\n"
                  '\n'
                  'See also:\n'
                  '\n'
-                 '  **PEP 560** - Core support for typing module and generic '
+                 '  **PEP 560** - Core Support for typing module and generic '
                  'types\n'
+                 '     Introducing "__class_getitem__()", and outlining when '
+                 'a\n'
+                 '     subscription results in "__class_getitem__()" being '
+                 'called\n'
+                 '     instead of "__getitem__()"\n'
                  '\n'
                  '\n'
                  'Emulating callable objects\n'
@@ -9453,60 +9627,60 @@ topics = {'assert': 'The "assert" statement\n'
                  '\n'
                  'The following methods can be defined to implement container '
                  'objects.\n'
-                 'Containers usually are sequences (such as lists or tuples) '
-                 'or mappings\n'
-                 '(like dictionaries), but can represent other containers as '
-                 'well.  The\n'
-                 'first set of methods is used either to emulate a sequence or '
-                 'to\n'
-                 'emulate a mapping; the difference is that for a sequence, '
-                 'the\n'
-                 'allowable keys should be the integers *k* for which "0 <= k '
-                 '< N" where\n'
-                 '*N* is the length of the sequence, or slice objects, which '
-                 'define a\n'
-                 'range of items.  It is also recommended that mappings '
-                 'provide the\n'
-                 'methods "keys()", "values()", "items()", "get()", '
-                 '"clear()",\n'
-                 '"setdefault()", "pop()", "popitem()", "copy()", and '
-                 '"update()"\n'
-                 'behaving similar to those for Python’s standard dictionary '
+                 'Containers usually are *sequences* (such as "lists" or '
+                 '"tuples") or\n'
+                 '*mappings* (like "dictionaries"), but can represent other '
+                 'containers\n'
+                 'as well.  The first set of methods is used either to emulate '
+                 'a\n'
+                 'sequence or to emulate a mapping; the difference is that for '
+                 'a\n'
+                 'sequence, the allowable keys should be the integers *k* for '
+                 'which "0\n'
+                 '<= k < N" where *N* is the length of the sequence, or '
+                 '"slice" objects,\n'
+                 'which define a range of items.  It is also recommended that '
+                 'mappings\n'
+                 'provide the methods "keys()", "values()", "items()", '
+                 '"get()",\n'
+                 '"clear()", "setdefault()", "pop()", "popitem()", "copy()", '
+                 'and\n'
+                 '"update()" behaving similar to those for Python’s standard\n'
+                 '"dictionary" objects.  The "collections.abc" module provides '
+                 'a\n'
+                 '"MutableMapping" *abstract base class* to help create those '
+                 'methods\n'
+                 'from a base set of "__getitem__()", "__setitem__()", '
+                 '"__delitem__()",\n'
+                 'and "keys()". Mutable sequences should provide methods '
+                 '"append()",\n'
+                 '"count()", "index()", "extend()", "insert()", "pop()", '
+                 '"remove()",\n'
+                 '"reverse()" and "sort()", like Python standard "list" '
                  'objects.\n'
-                 'The "collections.abc" module provides a "MutableMapping" '
-                 'abstract base\n'
-                 'class to help create those methods from a base set of '
-                 '"__getitem__()",\n'
-                 '"__setitem__()", "__delitem__()", and "keys()". Mutable '
-                 'sequences\n'
-                 'should provide methods "append()", "count()", "index()", '
-                 '"extend()",\n'
-                 '"insert()", "pop()", "remove()", "reverse()" and "sort()", '
-                 'like Python\n'
-                 'standard list objects.  Finally, sequence types should '
-                 'implement\n'
-                 'addition (meaning concatenation) and multiplication '
-                 '(meaning\n'
-                 'repetition) by defining the methods "__add__()", '
-                 '"__radd__()",\n'
-                 '"__iadd__()", "__mul__()", "__rmul__()" and "__imul__()" '
-                 'described\n'
-                 'below; they should not define other numerical operators.  It '
-                 'is\n'
-                 'recommended that both mappings and sequences implement the\n'
-                 '"__contains__()" method to allow efficient use of the "in" '
-                 'operator;\n'
-                 'for mappings, "in" should search the mapping’s keys; for '
-                 'sequences, it\n'
-                 'should search through the values.  It is further recommended '
-                 'that both\n'
-                 'mappings and sequences implement the "__iter__()" method to '
-                 'allow\n'
-                 'efficient iteration through the container; for mappings, '
-                 '"__iter__()"\n'
-                 'should iterate through the object’s keys; for sequences, it '
-                 'should\n'
-                 'iterate through the values.\n'
+                 'Finally, sequence types should implement addition (meaning\n'
+                 'concatenation) and multiplication (meaning repetition) by '
+                 'defining the\n'
+                 'methods "__add__()", "__radd__()", "__iadd__()", '
+                 '"__mul__()",\n'
+                 '"__rmul__()" and "__imul__()" described below; they should '
+                 'not define\n'
+                 'other numerical operators.  It is recommended that both '
+                 'mappings and\n'
+                 'sequences implement the "__contains__()" method to allow '
+                 'efficient use\n'
+                 'of the "in" operator; for mappings, "in" should search the '
+                 'mapping’s\n'
+                 'keys; for sequences, it should search through the values.  '
+                 'It is\n'
+                 'further recommended that both mappings and sequences '
+                 'implement the\n'
+                 '"__iter__()" method to allow efficient iteration through '
+                 'the\n'
+                 'container; for mappings, "__iter__()" should iterate through '
+                 'the\n'
+                 'object’s keys; for sequences, it should iterate through the '
+                 'values.\n'
                  '\n'
                  'object.__len__(self)\n'
                  '\n'
@@ -9564,22 +9738,23 @@ topics = {'assert': 'The "assert" statement\n'
                  'object.__getitem__(self, key)\n'
                  '\n'
                  '   Called to implement evaluation of "self[key]". For '
-                 'sequence types,\n'
-                 '   the accepted keys should be integers and slice objects.  '
-                 'Note that\n'
-                 '   the special interpretation of negative indexes (if the '
-                 'class wishes\n'
-                 '   to emulate a sequence type) is up to the "__getitem__()" '
-                 'method. If\n'
-                 '   *key* is of an inappropriate type, "TypeError" may be '
-                 'raised; if of\n'
-                 '   a value outside the set of indexes for the sequence '
-                 '(after any\n'
-                 '   special interpretation of negative values), "IndexError" '
+                 '*sequence*\n'
+                 '   types, the accepted keys should be integers and slice '
+                 'objects.\n'
+                 '   Note that the special interpretation of negative indexes '
+                 '(if the\n'
+                 '   class wishes to emulate a *sequence* type) is up to the\n'
+                 '   "__getitem__()" method. If *key* is of an inappropriate '
+                 'type,\n'
+                 '   "TypeError" may be raised; if of a value outside the set '
+                 'of indexes\n'
+                 '   for the sequence (after any special interpretation of '
+                 'negative\n'
+                 '   values), "IndexError" should be raised. For *mapping* '
+                 'types, if\n'
+                 '   *key* is missing (not in the container), "KeyError" '
                  'should be\n'
-                 '   raised. For mapping types, if *key* is missing (not in '
-                 'the\n'
-                 '   container), "KeyError" should be raised.\n'
+                 '   raised.\n'
                  '\n'
                  '   Note:\n'
                  '\n'
@@ -9589,6 +9764,14 @@ topics = {'assert': 'The "assert" statement\n'
                  'the\n'
                  '     sequence.\n'
                  '\n'
+                 '   Note:\n'
+                 '\n'
+                 '     When subscripting a *class*, the special class method\n'
+                 '     "__class_getitem__()" may be called instead of '
+                 '"__getitem__()".\n'
+                 '     See __class_getitem__ versus __getitem__ for more '
+                 'details.\n'
+                 '\n'
                  'object.__setitem__(self, key, value)\n'
                  '\n'
                  '   Called to implement assignment to "self[key]".  Same note '
@@ -10376,9 +10559,9 @@ topics = {'assert': 'The "assert" statement\n'
                    '      >>> from keyword import iskeyword\n'
                    '\n'
                    "      >>> 'hello'.isidentifier(), iskeyword('hello')\n"
-                   '      True, False\n'
+                   '      (True, False)\n'
                    "      >>> 'def'.isidentifier(), iskeyword('def')\n"
-                   '      True, True\n'
+                   '      (True, True)\n'
                    '\n'
                    'str.islower()\n'
                    '\n'
@@ -10729,7 +10912,7 @@ topics = {'assert': 'The "assert" statement\n'
                    "      >>> '   1   2   3   '.split()\n"
                    "      ['1', '2', '3']\n"
                    '\n'
-                   'str.splitlines([keepends])\n'
+                   'str.splitlines(keepends=False)\n'
                    '\n'
                    '   Return a list of the lines in the string, breaking at '
                    'line\n'
@@ -12060,14 +12243,14 @@ topics = {'assert': 'The "assert" statement\n'
           'for"\n'
           '      statement to execute the body of the function.\n'
           '\n'
-          '      Calling the asynchronous iterator’s "aiterator.__anext__()"\n'
-          '      method will return an *awaitable* which when awaited will\n'
-          '      execute until it provides a value using the "yield" '
-          'expression.\n'
-          '      When the function executes an empty "return" statement or '
-          'falls\n'
-          '      off the end, a "StopAsyncIteration" exception is raised and '
+          '      Calling the asynchronous iterator’s "aiterator.__anext__" '
+          'method\n'
+          '      will return an *awaitable* which when awaited will execute '
+          'until\n'
+          '      it provides a value using the "yield" expression.  When the\n'
+          '      function executes an empty "return" statement or falls off '
           'the\n'
+          '      end, a "StopAsyncIteration" exception is raised and the\n'
           '      asynchronous iterator will have reached the end of the set '
           'of\n'
           '      values to be yielded.\n'
@@ -12587,9 +12770,9 @@ topics = {'assert': 'The "assert" statement\n'
                  '"dict"\n'
                  'constructor.\n'
                  '\n'
-                 'class dict(**kwarg)\n'
-                 'class dict(mapping, **kwarg)\n'
-                 'class dict(iterable, **kwarg)\n'
+                 'class dict(**kwargs)\n'
+                 'class dict(mapping, **kwargs)\n'
+                 'class dict(iterable, **kwargs)\n'
                  '\n'
                  '   Return a new dictionary initialized from an optional '
                  'positional\n'
@@ -13694,7 +13877,8 @@ topics = {'assert': 'The "assert" statement\n'
              '\n'
              '   The arguments to the range constructor must be integers '
              '(either\n'
-             '   built-in "int" or any object that implements the "__index__"\n'
+             '   built-in "int" or any object that implements the '
+             '"__index__()"\n'
              '   special method).  If the *step* argument is omitted, it '
              'defaults to\n'
              '   "1". If the *start* argument is omitted, it defaults to "0". '
index d4a6d6f..50b215b 100644 (file)
@@ -1,6 +1,5 @@
 import _signal
 from _signal import *
-from functools import wraps as _wraps
 from enum import IntEnum as _IntEnum
 
 _globals = globals()
@@ -42,6 +41,16 @@ def _enum_to_int(value):
         return value
 
 
+# Similar to functools.wraps(), but only assign __doc__.
+# __module__ should be preserved,
+# __name__ and __qualname__ are already fine,
+# __annotations__ is not set.
+def _wraps(wrapped):
+    def decorator(wrapper):
+        wrapper.__doc__ = wrapped.__doc__
+        return wrapper
+    return decorator
+
 @_wraps(_signal.signal)
 def signal(signalnum, handler):
     handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler))
@@ -59,7 +68,6 @@ if 'pthread_sigmask' in _globals:
     def pthread_sigmask(how, mask):
         sigs_set = _signal.pthread_sigmask(how, mask)
         return set(_int_to_enum(x, Signals) for x in sigs_set)
-    pthread_sigmask.__doc__ = _signal.pthread_sigmask.__doc__
 
 
 if 'sigpending' in _globals:
@@ -73,7 +81,6 @@ if 'sigwait' in _globals:
     def sigwait(sigset):
         retsig = _signal.sigwait(sigset)
         return _int_to_enum(retsig, Signals)
-    sigwait.__doc__ = _signal.sigwait
 
 
 if 'valid_signals' in _globals:
index efdb7f2..1e71745 100644 (file)
 The sqlite3 extension module provides a DB-API 2.0 (PEP 249) compilant
 interface to the SQLite library, and requires SQLite 3.7.15 or newer.
 
-To use the module, you must first create a database Connection object:
+To use the module, start by creating a database Connection object:
 
     import sqlite3
     cx = sqlite3.connect("test.db")  # test.db will be created or opened
 
-You can also use the special database name ":memory:" to connect to a transient
+The special path name ":memory:" can be provided to connect to a transient
 in-memory database:
 
     cx = sqlite3.connect(":memory:")  # connect to a database in RAM
 
-Once you have a Connection object, you can create a Cursor object and call its
-execute() method to perform SQL queries:
+Once a connection has been established, create a Cursor object and call
+its execute() method to perform SQL queries:
 
     cu = cx.cursor()
 
index f9d3802..463ac9e 100644 (file)
@@ -361,7 +361,7 @@ def geometric_mean(data):
         return exp(fmean(map(log, data)))
     except ValueError:
         raise StatisticsError('geometric mean requires a non-empty dataset '
-                              ' containing positive numbers') from None
+                              'containing positive numbers') from None
 
 
 def harmonic_mean(data):
index b9404d5..cef877c 100644 (file)
@@ -396,16 +396,12 @@ class MultiprocessTestRunner:
             worker.wait_stopped(start_time)
 
     def _get_result(self) -> QueueOutput | None:
-        if not any(worker.is_alive() for worker in self.workers):
-            # all worker threads are done: consume pending results
-            try:
-                return self.output.get(timeout=0)
-            except queue.Empty:
-                return None
-
         use_faulthandler = (self.ns.timeout is not None)
         timeout = PROGRESS_UPDATE
-        while True:
+
+        # bpo-46205: check the status of workers every iteration to avoid
+        # waiting forever on an empty queue.
+        while any(worker.is_alive() for worker in self.workers):
             if use_faulthandler:
                 faulthandler.dump_traceback_later(MAIN_PROCESS_TIMEOUT,
                                                   exit=True)
@@ -421,6 +417,12 @@ class MultiprocessTestRunner:
             if running and not self.ns.pgo:
                 self.log('running: %s' % ', '.join(running))
 
+        # all worker threads are done: consume pending results
+        try:
+            return self.output.get(timeout=0)
+        except queue.Empty:
+            return None
+
     def display_result(self, mp_result: MultiprocessResult) -> None:
         result = mp_result.result
 
index c62896f..94a35a6 100644 (file)
@@ -307,6 +307,6 @@ if __name__ == '__main__':
         f.write(cert)
 
     unmake_ca()
-    print("update Lib/test/test_ssl.py and Lib/test/test_asyncio/util.py")
+    print("update Lib/test/test_ssl.py and Lib/test/test_asyncio/utils.py")
     print_cert('keycert.pem')
     print_cert('keycert3.pem')
index d79ac5a..043a9cf 100644 (file)
@@ -2582,6 +2582,13 @@ class TestMutuallyExclusiveGroupErrors(TestCase):
               '''
         self.assertEqual(parser.format_help(), textwrap.dedent(expected))
 
+    def test_empty_group(self):
+        # See issue 26952
+        parser = argparse.ArgumentParser()
+        group = parser.add_mutually_exclusive_group()
+        with self.assertRaises(ValueError):
+            parser.parse_args(['-h'])
+
 class MEMixin(object):
 
     def test_failures_when_not_required(self):
index 533d5cc..4886da2 100644 (file)
@@ -1592,11 +1592,11 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
         coro = self.loop.create_datagram_endpoint(
             MyDatagramProto, local_addr='localhost')
         self.assertRaises(
-            AssertionError, self.loop.run_until_complete, coro)
+            TypeError, self.loop.run_until_complete, coro)
         coro = self.loop.create_datagram_endpoint(
             MyDatagramProto, local_addr=('localhost', 1, 2, 3))
         self.assertRaises(
-            AssertionError, self.loop.run_until_complete, coro)
+            TypeError, self.loop.run_until_complete, coro)
 
     def test_create_datagram_endpoint_connect_err(self):
         self.loop.sock_connect = mock.Mock()
index 8c93fae..b9aae36 100644 (file)
@@ -5,7 +5,6 @@ from unittest import mock
 import re
 
 import asyncio
-from test.test_asyncio import utils as test_utils
 
 STR_RGX_REPR = (
     r'^<(?P<class>.*?) object at (?P<address>.*?)'
@@ -20,86 +19,67 @@ def tearDownModule():
     asyncio.set_event_loop_policy(None)
 
 
-class LockTests(test_utils.TestCase):
+class LockTests(unittest.IsolatedAsyncioTestCase):
 
-    def setUp(self):
-        super().setUp()
-        self.loop = self.new_test_loop()
-
-    def test_ctor_loop(self):
+    async def test_ctor_loop(self):
         loop = mock.Mock()
         with self.assertWarns(DeprecationWarning):
             lock = asyncio.Lock(loop=loop)
         self.assertIs(lock._loop, loop)
 
         with self.assertWarns(DeprecationWarning):
-            lock = asyncio.Lock(loop=self.loop)
-        self.assertIs(lock._loop, self.loop)
+            lock = asyncio.Lock(loop=asyncio.get_running_loop())
+        self.assertIs(lock._loop, asyncio.get_running_loop())
 
-    def test_ctor_noloop(self):
-        asyncio.set_event_loop(self.loop)
+    async def test_ctor_noloop(self):
         lock = asyncio.Lock()
-        self.assertIs(lock._loop, self.loop)
+        self.assertIs(lock._loop, asyncio.get_running_loop())
 
-    def test_repr(self):
+    async def test_repr(self):
         with self.assertWarns(DeprecationWarning):
-            lock = asyncio.Lock(loop=self.loop)
+            lock = asyncio.Lock(loop=asyncio.get_running_loop())
         self.assertTrue(repr(lock).endswith('[unlocked]>'))
         self.assertTrue(RGX_REPR.match(repr(lock)))
 
-        self.loop.run_until_complete(lock.acquire())
+        await lock.acquire()
         self.assertTrue(repr(lock).endswith('[locked]>'))
         self.assertTrue(RGX_REPR.match(repr(lock)))
 
-    def test_lock(self):
-        with self.assertWarns(DeprecationWarning):
-            lock = asyncio.Lock(loop=self.loop)
-
-            @asyncio.coroutine
-            def acquire_lock():
-                return (yield from lock)
+    async def test_lock(self):
+        lock = asyncio.Lock()
 
         with self.assertRaisesRegex(
             TypeError,
-            "object is not iterable"
+            "object Lock can't be used in 'await' expression"
         ):
-            self.loop.run_until_complete(acquire_lock())
+            await lock
 
         self.assertFalse(lock.locked())
 
-    def test_lock_by_with_statement(self):
-        loop = asyncio.new_event_loop()  # don't use TestLoop quirks
-        self.set_event_loop(loop)
-        with self.assertWarns(DeprecationWarning):
-            primitives = [
-                asyncio.Lock(loop=loop),
-                asyncio.Condition(loop=loop),
-                asyncio.Semaphore(loop=loop),
-                asyncio.BoundedSemaphore(loop=loop),
-            ]
-
-            @asyncio.coroutine
-            def test(lock):
-                yield from asyncio.sleep(0.01)
-                self.assertFalse(lock.locked())
-                with self.assertRaisesRegex(
-                    TypeError,
-                    "object is not iterable"
-                ):
-                    with (yield from lock):
-                        pass
-                self.assertFalse(lock.locked())
+    async def test_lock_by_with_statement(self):
+        primitives = [
+            asyncio.Lock(),
+            asyncio.Condition(),
+            asyncio.Semaphore(),
+            asyncio.BoundedSemaphore(),
+        ]
 
-        for primitive in primitives:
-            loop.run_until_complete(test(primitive))
-            self.assertFalse(primitive.locked())
+        for lock in primitives:
+            await asyncio.sleep(0.01)
+            self.assertFalse(lock.locked())
+            with self.assertRaisesRegex(
+                TypeError,
+                r"object \w+ can't be used in 'await' expression"
+            ):
+                with await lock:
+                    pass
+            self.assertFalse(lock.locked())
 
-    def test_acquire(self):
-        with self.assertWarns(DeprecationWarning):
-            lock = asyncio.Lock(loop=self.loop)
+    async def test_acquire(self):
+        lock = asyncio.Lock()
         result = []
 
-        self.assertTrue(self.loop.run_until_complete(lock.acquire()))
+        self.assertTrue(await lock.acquire())
 
         async def c1(result):
             if await lock.acquire():
@@ -116,27 +96,27 @@ class LockTests(test_utils.TestCase):
                 result.append(3)
             return True
 
-        t1 = self.loop.create_task(c1(result))
-        t2 = self.loop.create_task(c2(result))
+        t1 = asyncio.create_task(c1(result))
+        t2 = asyncio.create_task(c2(result))
 
-        test_utils.run_briefly(self.loop)
+        await asyncio.sleep(0)
         self.assertEqual([], result)
 
         lock.release()
-        test_utils.run_briefly(self.loop)
+        await asyncio.sleep(0)
         self.assertEqual([1], result)
 
-        test_utils.run_briefly(self.loop)
+        await asyncio.sleep(0)
         self.assertEqual([1], result)
 
-        t3 = self.loop.create_task(c3(result))
+        t3 = asyncio.create_task(c3(result))
 
         lock.release()
-        test_utils.run_briefly(self.loop)
+        await asyncio.sleep(0)
         self.assertEqual([1, 2], result)
 
         lock.release()
-        test_utils.run_briefly(self.loop)
+        await asyncio.sleep(0)
         self.assertEqual([1, 2, 3], result)
 
         self.assertTrue(t1.done())
@@ -146,19 +126,18 @@ class LockTests(test_utils.TestCase):
         self.assertTrue(t3.done())
         self.assertTrue(t3.result())
 
-    def test_acquire_cancel(self):
+    async def test_acquire_cancel(self):
         with self.assertWarns(DeprecationWarning):
-            lock = asyncio.Lock(loop=self.loop)
-        self.assertTrue(self.loop.run_until_complete(lock.acquire()))
-
-        task = self.loop.create_task(lock.acquire())
-        self.loop.call_soon(task.cancel)
-        self.assertRaises(
-            asyncio.CancelledError,
-            self.loop.run_until_complete, task)
+            lock = asyncio.Lock(loop=asyncio.get_running_loop())
+        self.assertTrue(await lock.acquire())
+
+        task = asyncio.create_task(lock.acquire())
+        asyncio.get_running_loop().call_soon(task.cancel)
+        with self.assertRaises(asyncio.CancelledError):
+            await task
         self.assertFalse(lock._waiters)
 
-    def test_cancel_race(self):
+    async def test_cancel_race(self):
         # Several tasks:
         # - A acquires the lock
         # - B is blocked in acquire()
@@ -174,7 +153,7 @@ class LockTests(test_utils.TestCase):
 
         # Setup: A has the lock, b and c are waiting.
         with self.assertWarns(DeprecationWarning):
-            lock = asyncio.Lock(loop=self.loop)
+            lock = asyncio.Lock(loop=asyncio.get_running_loop())
 
         async def lockit(name, blocker):
             await lock.acquire()
@@ -184,15 +163,15 @@ class LockTests(test_utils.TestCase):
             finally:
                 lock.release()
 
-        fa = self.loop.create_future()
-        ta = self.loop.create_task(lockit('A', fa))
-        test_utils.run_briefly(self.loop)
+        fa = asyncio.get_running_loop().create_future()
+        ta = asyncio.create_task(lockit('A', fa))
+        await asyncio.sleep(0)
         self.assertTrue(lock.locked())
-        tb = self.loop.create_task(lockit('B', None))
-        test_utils.run_briefly(self.loop)
+        tb = asyncio.create_task(lockit('B', None))
+        await asyncio.sleep(0)
         self.assertEqual(len(lock._waiters), 1)
-        tc = self.loop.create_task(lockit('C', None))
-        test_utils.run_briefly(self.loop)
+        tc = asyncio.create_task(lockit('C', None))
+        await asyncio.sleep(0)
         self.assertEqual(len(lock._waiters), 2)
 
         # Create the race and check.
@@ -200,18 +179,19 @@ class LockTests(test_utils.TestCase):
         fa.set_result(None)
         tb.cancel()
         self.assertTrue(lock._waiters[0].cancelled())
-        test_utils.run_briefly(self.loop)
+        await asyncio.sleep(0)
         self.assertFalse(lock.locked())
         self.assertTrue(ta.done())
         self.assertTrue(tb.cancelled())
-        self.assertTrue(tc.done())
+        await tc
 
-    def test_cancel_release_race(self):
+    async def test_cancel_release_race(self):
         # Issue 32734
         # Acquire 4 locks, cancel second, release first
         # and 2 locks are taken at once.
+        loop = asyncio.get_running_loop()
         with self.assertWarns(DeprecationWarning):
-            lock = asyncio.Lock(loop=self.loop)
+            lock = asyncio.Lock(loop=loop)
         lock_count = 0
         call_count = 0
 
@@ -222,27 +202,23 @@ class LockTests(test_utils.TestCase):
             await lock.acquire()
             lock_count += 1
 
-        async def lockandtrigger():
-            await lock.acquire()
-            self.loop.call_soon(trigger)
-
         def trigger():
             t1.cancel()
             lock.release()
 
-        t0 = self.loop.create_task(lockandtrigger())
-        t1 = self.loop.create_task(lockit())
-        t2 = self.loop.create_task(lockit())
-        t3 = self.loop.create_task(lockit())
+        await lock.acquire()
 
-        # First loop acquires all
-        test_utils.run_briefly(self.loop)
-        self.assertTrue(t0.done())
+        t1 = asyncio.create_task(lockit())
+        t2 = asyncio.create_task(lockit())
+        t3 = asyncio.create_task(lockit())
 
-        # Second loop calls trigger
-        test_utils.run_briefly(self.loop)
-        # Third loop calls cancellation
-        test_utils.run_briefly(self.loop)
+        # Start scheduled tasks
+        await asyncio.sleep(0)
+
+        loop.call_soon(trigger)
+        with self.assertRaises(asyncio.CancelledError):
+            # Wait for cancellation
+            await t1
 
         # Make sure only one lock was taken
         self.assertEqual(lock_count, 1)
@@ -252,84 +228,78 @@ class LockTests(test_utils.TestCase):
 
         # Cleanup the task that is stuck on acquire.
         t3.cancel()
-        test_utils.run_briefly(self.loop)
+        await asyncio.sleep(0)
         self.assertTrue(t3.cancelled())
 
-    def test_finished_waiter_cancelled(self):
+    async def test_finished_waiter_cancelled(self):
         with self.assertWarns(DeprecationWarning):
-            lock = asyncio.Lock(loop=self.loop)
+            lock = asyncio.Lock(loop=asyncio.get_running_loop())
 
-        ta = self.loop.create_task(lock.acquire())
-        test_utils.run_briefly(self.loop)
+        await lock.acquire()
         self.assertTrue(lock.locked())
 
-        tb = self.loop.create_task(lock.acquire())
-        test_utils.run_briefly(self.loop)
+        tb = asyncio.create_task(lock.acquire())
+        await asyncio.sleep(0)
         self.assertEqual(len(lock._waiters), 1)
 
         # Create a second waiter, wake up the first, and cancel it.
         # Without the fix, the second was not woken up.
-        tc = self.loop.create_task(lock.acquire())
-        lock.release()
+        tc = asyncio.create_task(lock.acquire())
         tb.cancel()
-        test_utils.run_briefly(self.loop)
+        lock.release()
+        await asyncio.sleep(0)
 
         self.assertTrue(lock.locked())
-        self.assertTrue(ta.done())
         self.assertTrue(tb.cancelled())
 
-    def test_release_not_acquired(self):
+        # Cleanup
+        await tc
+
+    async def test_release_not_acquired(self):
         with self.assertWarns(DeprecationWarning):
-            lock = asyncio.Lock(loop=self.loop)
+            lock = asyncio.Lock(loop=asyncio.get_running_loop())
 
         self.assertRaises(RuntimeError, lock.release)
 
-    def test_release_no_waiters(self):
+    async def test_release_no_waiters(self):
         with self.assertWarns(DeprecationWarning):
-            lock = asyncio.Lock(loop=self.loop)
-        self.loop.run_until_complete(lock.acquire())
+            lock = asyncio.Lock(loop=asyncio.get_running_loop())
+        await lock.acquire()
         self.assertTrue(lock.locked())
 
         lock.release()
         self.assertFalse(lock.locked())
 
-    def test_context_manager(self):
-        async def f():
-            lock = asyncio.Lock()
-            self.assertFalse(lock.locked())
-
-            async with lock:
-                self.assertTrue(lock.locked())
-
-            self.assertFalse(lock.locked())
+    async def test_context_manager(self):
+        lock = asyncio.Lock()
+        self.assertFalse(lock.locked())
 
-        self.loop.run_until_complete(f())
+        async with lock:
+            self.assertTrue(lock.locked())
 
+        self.assertFalse(lock.locked())
 
-class EventTests(test_utils.TestCase):
 
-    def setUp(self):
-        super().setUp()
-        self.loop = self.new_test_loop()
+class EventTests(unittest.IsolatedAsyncioTestCase):
 
-    def test_ctor_loop(self):
+    async def test_ctor_loop(self):
         loop = mock.Mock()
         with self.assertWarns(DeprecationWarning):
             ev = asyncio.Event(loop=loop)
         self.assertIs(ev._loop, loop)
 
         with self.assertWarns(DeprecationWarning):
-            ev = asyncio.Event(loop=self.loop)
-        self.assertIs(ev._loop, self.loop)
+            ev = asyncio.Event(loop=asyncio.get_running_loop())
+        self.assertIs(ev._loop, asyncio.get_running_loop())
 
-    def test_ctor_noloop(self):
-        asyncio.set_event_loop(self.loop)
+    async def test_ctor_noloop(self):
+        asyncio.set_event_loop(asyncio.get_running_loop())
         ev = asyncio.Event()
-        self.assertIs(ev._loop, self.loop)
+        self.assertIs(ev._loop, asyncio.get_running_loop())
 
-    def test_repr(self):
+    async def test_repr(self):
         with self.assertWarns(DeprecationWarning):
-            ev = asyncio.Event(loop=self.loop)
+            ev = asyncio.Event(loop=asyncio.get_running_loop())
         self.assertTrue(repr(ev).endswith('[unset]>'))
         match = RGX_REPR.match(repr(ev))
         self.assertEqual(match.group('extras'), 'unset')
@@ -342,9 +312,9 @@ class EventTests(test_utils.TestCase):
         self.assertTrue('waiters:1' in repr(ev))
         self.assertTrue(RGX_REPR.match(repr(ev)))
 
-    def test_wait(self):
+    async def test_wait(self):
         with self.assertWarns(DeprecationWarning):
-            ev = asyncio.Event(loop=self.loop)
+            ev = asyncio.Event(loop=asyncio.get_running_loop())
         self.assertFalse(ev.is_set())
 
         result = []
@@ -361,16 +331,16 @@ class EventTests(test_utils.TestCase):
             if await ev.wait():
                 result.append(3)
 
-        t1 = self.loop.create_task(c1(result))
-        t2 = self.loop.create_task(c2(result))
+        t1 = asyncio.create_task(c1(result))
+        t2 = asyncio.create_task(c2(result))
 
-        test_utils.run_briefly(self.loop)
+        await asyncio.sleep(0)
         self.assertEqual([], result)
 
-        t3 = self.loop.create_task(c3(result))
+        t3 = asyncio.create_task(c3(result))
 
         ev.set()
-        test_utils.run_briefly(self.loop)
+        await asyncio.sleep(0)
         self.assertEqual([3, 1, 2], result)
 
         self.assertTrue(t1.done())
@@ -380,28 +350,24 @@ class EventTests(test_utils.TestCase):
         self.assertTrue(t3.done())
         self.assertIsNone(t3.result())
 
-    def test_wait_on_set(self):
-        with self.assertWarns(DeprecationWarning):
-            ev = asyncio.Event(loop=self.loop)
+    async def test_wait_on_set(self):
+        ev = asyncio.Event()
         ev.set()
 
-        res = self.loop.run_until_complete(ev.wait())
+        res = await ev.wait()
         self.assertTrue(res)
 
-    def test_wait_cancel(self):
-        with self.assertWarns(DeprecationWarning):
-            ev = asyncio.Event(loop=self.loop)
+    async def test_wait_cancel(self):
+        ev = asyncio.Event()
 
-        wait = self.loop.create_task(ev.wait())
-        self.loop.call_soon(wait.cancel)
-        self.assertRaises(
-            asyncio.CancelledError,
-            self.loop.run_until_complete, wait)
+        wait = asyncio.create_task(ev.wait())
+        asyncio.get_running_loop().call_soon(wait.cancel)
+        with self.assertRaises(asyncio.CancelledError):
+            await wait
         self.assertFalse(ev._waiters)
 
-    def test_clear(self):
-        with self.assertWarns(DeprecationWarning):
-            ev = asyncio.Event(loop=self.loop)
+    async def test_clear(self):
+        ev = asyncio.Event()
         self.assertFalse(ev.is_set())
 
         ev.set()
@@ -410,9 +376,8 @@ class EventTests(test_utils.TestCase):
         ev.clear()
         self.assertFalse(ev.is_set())
 
-    def test_clear_with_waiters(self):
-        with self.assertWarns(DeprecationWarning):
-            ev = asyncio.Event(loop=self.loop)
+    async def test_clear_with_waiters(self):
+        ev = asyncio.Event()
         result = []
 
         async def c1(result):
@@ -420,8 +385,8 @@ class EventTests(test_utils.TestCase):
                 result.append(1)
             return True
 
-        t = self.loop.create_task(c1(result))
-        test_utils.run_briefly(self.loop)
+        t = asyncio.create_task(c1(result))
+        await asyncio.sleep(0)
         self.assertEqual([], result)
 
         ev.set()
@@ -432,7 +397,7 @@ class EventTests(test_utils.TestCase):
         ev.set()
         self.assertEqual(1, len(ev._waiters))
 
-        test_utils.run_briefly(self.loop)
+        await asyncio.sleep(0)
         self.assertEqual([1], result)
         self.assertEqual(0, len(ev._waiters))
 
@@ -440,29 +405,23 @@ class EventTests(test_utils.TestCase):
         self.assertTrue(t.result())
 
 
-class ConditionTests(test_utils.TestCase):
+class ConditionTests(unittest.IsolatedAsyncioTestCase):
 
-    def setUp(self):
-        super().setUp()
-        self.loop = self.new_test_loop()
-
-    def test_ctor_loop(self):
+    async def test_ctor_loop(self):
         loop = mock.Mock()
         with self.assertWarns(DeprecationWarning):
             cond = asyncio.Condition(loop=loop)
             self.assertIs(cond._loop, loop)
 
-            cond = asyncio.Condition(loop=self.loop)
-            self.assertIs(cond._loop, self.loop)
+            cond = asyncio.Condition(loop=asyncio.get_running_loop())
+            self.assertIs(cond._loop, asyncio.get_running_loop())
 
-    def test_ctor_noloop(self):
-        asyncio.set_event_loop(self.loop)
+    async def test_ctor_noloop(self):
         cond = asyncio.Condition()
-        self.assertIs(cond._loop, self.loop)
+        self.assertIs(cond._loop, asyncio.get_running_loop())
 
-    def test_wait(self):
-        with self.assertWarns(DeprecationWarning):
-            cond = asyncio.Condition(loop=self.loop)
+    async def test_wait(self):
+        cond = asyncio.Condition()
         result = []
 
         async def c1(result):
@@ -483,37 +442,37 @@ class ConditionTests(test_utils.TestCase):
                 result.append(3)
             return True
 
-        t1 = self.loop.create_task(c1(result))
-        t2 = self.loop.create_task(c2(result))
-        t3 = self.loop.create_task(c3(result))
+        t1 = asyncio.create_task(c1(result))
+        t2 = asyncio.create_task(c2(result))
+        t3 = asyncio.create_task(c3(result))
 
-        test_utils.run_briefly(self.loop)
+        await asyncio.sleep(0)
         self.assertEqual([], result)
         self.assertFalse(cond.locked())
 
-        self.assertTrue(self.loop.run_until_complete(cond.acquire()))
+        self.assertTrue(await cond.acquire())
         cond.notify()
-        test_utils.run_briefly(self.loop)
+        await asyncio.sleep(0)
         self.assertEqual([], result)
         self.assertTrue(cond.locked())
 
         cond.release()
-        test_utils.run_briefly(self.loop)
+        await asyncio.sleep(0)
         self.assertEqual([1], result)
         self.assertTrue(cond.locked())
 
         cond.notify(2)
-        test_utils.run_briefly(self.loop)
+        await asyncio.sleep(0)
         self.assertEqual([1], result)
         self.assertTrue(cond.locked())
 
         cond.release()
-        test_utils.run_briefly(self.loop)
+        await asyncio.sleep(0)
         self.assertEqual([1, 2], result)
         self.assertTrue(cond.locked())
 
         cond.release()
-        test_utils.run_briefly(self.loop)
+        await asyncio.sleep(0)
         self.assertEqual([1, 2, 3], result)
         self.assertTrue(cond.locked())
 
@@ -524,49 +483,46 @@ class ConditionTests(test_utils.TestCase):
         self.assertTrue(t3.done())
         self.assertTrue(t3.result())
 
-    def test_wait_cancel(self):
-        with self.assertWarns(DeprecationWarning):
-            cond = asyncio.Condition(loop=self.loop)
-        self.loop.run_until_complete(cond.acquire())
-
-        wait = self.loop.create_task(cond.wait())
-        self.loop.call_soon(wait.cancel)
-        self.assertRaises(
-            asyncio.CancelledError,
-            self.loop.run_until_complete, wait)
+    async def test_wait_cancel(self):
+        cond = asyncio.Condition()
+        await cond.acquire()
+
+        wait = asyncio.create_task(cond.wait())
+        asyncio.get_running_loop().call_soon(wait.cancel)
+        with self.assertRaises(asyncio.CancelledError):
+            await wait
         self.assertFalse(cond._waiters)
         self.assertTrue(cond.locked())
 
-    def test_wait_cancel_contested(self):
-        with self.assertWarns(DeprecationWarning):
-            cond = asyncio.Condition(loop=self.loop)
+    async def test_wait_cancel_contested(self):
+        cond = asyncio.Condition()
 
-        self.loop.run_until_complete(cond.acquire())
+        await cond.acquire()
         self.assertTrue(cond.locked())
 
-        wait_task = self.loop.create_task(cond.wait())
-        test_utils.run_briefly(self.loop)
+        wait_task = asyncio.create_task(cond.wait())
+        await asyncio.sleep(0)
         self.assertFalse(cond.locked())
 
         # Notify, but contest the lock before cancelling
-        self.loop.run_until_complete(cond.acquire())
+        await cond.acquire()
         self.assertTrue(cond.locked())
         cond.notify()
-        self.loop.call_soon(wait_task.cancel)
-        self.loop.call_soon(cond.release)
+        asyncio.get_running_loop().call_soon(wait_task.cancel)
+        asyncio.get_running_loop().call_soon(cond.release)
 
         try:
-            self.loop.run_until_complete(wait_task)
+            await wait_task
         except asyncio.CancelledError:
             # Should not happen, since no cancellation points
             pass
 
         self.assertTrue(cond.locked())
 
-    def test_wait_cancel_after_notify(self):
+    async def test_wait_cancel_after_notify(self):
         # See bpo-32841
         with self.assertWarns(DeprecationWarning):
-            cond = asyncio.Condition(loop=self.loop)
+            cond = asyncio.Condition(loop=asyncio.get_running_loop())
         waited = False
 
         async def wait_on_cond():
@@ -575,30 +531,27 @@ class ConditionTests(test_utils.TestCase):
                 waited = True  # Make sure this area was reached
                 await cond.wait()
 
-        waiter = asyncio.ensure_future(wait_on_cond(), loop=self.loop)
-        test_utils.run_briefly(self.loop)  # Start waiting
+        waiter = asyncio.create_task(wait_on_cond())
+        await asyncio.sleep(0)  # Start waiting
 
-        self.loop.run_until_complete(cond.acquire())
+        await cond.acquire()
         cond.notify()
-        test_utils.run_briefly(self.loop)  # Get to acquire()
+        await asyncio.sleep(0)  # Get to acquire()
         waiter.cancel()
-        test_utils.run_briefly(self.loop)  # Activate cancellation
+        await asyncio.sleep(0)  # Activate cancellation
         cond.release()
-        test_utils.run_briefly(self.loop)  # Cancellation should occur
+        await asyncio.sleep(0)  # Cancellation should occur
 
         self.assertTrue(waiter.cancelled())
         self.assertTrue(waited)
 
-    def test_wait_unacquired(self):
-        with self.assertWarns(DeprecationWarning):
-            cond = asyncio.Condition(loop=self.loop)
-        self.assertRaises(
-            RuntimeError,
-            self.loop.run_until_complete, cond.wait())
+    async def test_wait_unacquired(self):
+        cond = asyncio.Condition()
+        with self.assertRaises(RuntimeError):
+            await cond.wait()
 
-    def test_wait_for(self):
-        with self.assertWarns(DeprecationWarning):
-            cond = asyncio.Condition(loop=self.loop)
+    async def test_wait_for(self):
+        cond = asyncio.Condition()
         presult = False
 
         def predicate():
@@ -613,43 +566,39 @@ class ConditionTests(test_utils.TestCase):
                 cond.release()
             return True
 
-        t = self.loop.create_task(c1(result))
+        t = asyncio.create_task(c1(result))
 
-        test_utils.run_briefly(self.loop)
+        await asyncio.sleep(0)
         self.assertEqual([], result)
 
-        self.loop.run_until_complete(cond.acquire())
+        await cond.acquire()
         cond.notify()
         cond.release()
-        test_utils.run_briefly(self.loop)
+        await asyncio.sleep(0)
         self.assertEqual([], result)
 
         presult = True
-        self.loop.run_until_complete(cond.acquire())
+        await cond.acquire()
         cond.notify()
         cond.release()
-        test_utils.run_briefly(self.loop)
+        await asyncio.sleep(0)
         self.assertEqual([1], result)
 
         self.assertTrue(t.done())
         self.assertTrue(t.result())
 
-    def test_wait_for_unacquired(self):
-        with self.assertWarns(DeprecationWarning):
-            cond = asyncio.Condition(loop=self.loop)
+    async def test_wait_for_unacquired(self):
+        cond = asyncio.Condition()
 
         # predicate can return true immediately
-        res = self.loop.run_until_complete(cond.wait_for(lambda: [1, 2, 3]))
+        res = await cond.wait_for(lambda: [1, 2, 3])
         self.assertEqual([1, 2, 3], res)
 
-        self.assertRaises(
-            RuntimeError,
-            self.loop.run_until_complete,
-            cond.wait_for(lambda: False))
+        with self.assertRaises(RuntimeError):
+            await cond.wait_for(lambda: False)
 
-    def test_notify(self):
-        with self.assertWarns(DeprecationWarning):
-            cond = asyncio.Condition(loop=self.loop)
+    async def test_notify(self):
+        cond = asyncio.Condition()
         result = []
 
         async def c1(result):
@@ -673,24 +622,24 @@ class ConditionTests(test_utils.TestCase):
                 cond.release()
             return True
 
-        t1 = self.loop.create_task(c1(result))
-        t2 = self.loop.create_task(c2(result))
-        t3 = self.loop.create_task(c3(result))
+        t1 = asyncio.create_task(c1(result))
+        t2 = asyncio.create_task(c2(result))
+        t3 = asyncio.create_task(c3(result))
 
-        test_utils.run_briefly(self.loop)
+        await asyncio.sleep(0)
         self.assertEqual([], result)
 
-        self.loop.run_until_complete(cond.acquire())
+        await cond.acquire()
         cond.notify(1)
         cond.release()
-        test_utils.run_briefly(self.loop)
+        await asyncio.sleep(0)
         self.assertEqual([1], result)
 
-        self.loop.run_until_complete(cond.acquire())
+        await cond.acquire()
         cond.notify(1)
         cond.notify(2048)
         cond.release()
-        test_utils.run_briefly(self.loop)
+        await asyncio.sleep(0)
         self.assertEqual([1, 2, 3], result)
 
         self.assertTrue(t1.done())
@@ -700,9 +649,8 @@ class ConditionTests(test_utils.TestCase):
         self.assertTrue(t3.done())
         self.assertTrue(t3.result())
 
-    def test_notify_all(self):
-        with self.assertWarns(DeprecationWarning):
-            cond = asyncio.Condition(loop=self.loop)
+    async def test_notify_all(self):
+        cond = asyncio.Condition()
 
         result = []
 
@@ -720,16 +668,16 @@ class ConditionTests(test_utils.TestCase):
                 cond.release()
             return True
 
-        t1 = self.loop.create_task(c1(result))
-        t2 = self.loop.create_task(c2(result))
+        t1 = asyncio.create_task(c1(result))
+        t2 = asyncio.create_task(c2(result))
 
-        test_utils.run_briefly(self.loop)
+        await asyncio.sleep(0)
         self.assertEqual([], result)
 
-        self.loop.run_until_complete(cond.acquire())
+        await cond.acquire()
         cond.notify_all()
         cond.release()
-        test_utils.run_briefly(self.loop)
+        await asyncio.sleep(0)
         self.assertEqual([1, 2], result)
 
         self.assertTrue(t1.done())
@@ -738,22 +686,19 @@ class ConditionTests(test_utils.TestCase):
         self.assertTrue(t2.result())
 
     def test_notify_unacquired(self):
-        with self.assertWarns(DeprecationWarning):
-            cond = asyncio.Condition(loop=self.loop)
+        cond = asyncio.Condition()
         self.assertRaises(RuntimeError, cond.notify)
 
     def test_notify_all_unacquired(self):
-        with self.assertWarns(DeprecationWarning):
-            cond = asyncio.Condition(loop=self.loop)
+        cond = asyncio.Condition()
         self.assertRaises(RuntimeError, cond.notify_all)
 
-    def test_repr(self):
-        with self.assertWarns(DeprecationWarning):
-            cond = asyncio.Condition(loop=self.loop)
+    async def test_repr(self):
+        cond = asyncio.Condition()
         self.assertTrue('unlocked' in repr(cond))
         self.assertTrue(RGX_REPR.match(repr(cond)))
 
-        self.loop.run_until_complete(cond.acquire())
+        await cond.acquire()
         self.assertTrue('locked' in repr(cond))
 
         cond._waiters.append(mock.Mock())
@@ -764,79 +709,107 @@ class ConditionTests(test_utils.TestCase):
         self.assertTrue('waiters:2' in repr(cond))
         self.assertTrue(RGX_REPR.match(repr(cond)))
 
-    def test_context_manager(self):
-        async def f():
-            cond = asyncio.Condition()
+    async def test_context_manager(self):
+        cond = asyncio.Condition()
+        self.assertFalse(cond.locked())
+        async with cond:
+            self.assertTrue(cond.locked())
+        self.assertFalse(cond.locked())
+
+    async def test_explicit_lock(self):
+        async def f(lock=None, cond=None):
+            if lock is None:
+                lock = asyncio.Lock()
+            if cond is None:
+                cond = asyncio.Condition(lock)
+            self.assertIs(cond._lock, lock)
+            self.assertFalse(lock.locked())
             self.assertFalse(cond.locked())
             async with cond:
+                self.assertTrue(lock.locked())
                 self.assertTrue(cond.locked())
+            self.assertFalse(lock.locked())
+            self.assertFalse(cond.locked())
+            async with lock:
+                self.assertTrue(lock.locked())
+                self.assertTrue(cond.locked())
+            self.assertFalse(lock.locked())
             self.assertFalse(cond.locked())
 
-        self.loop.run_until_complete(f())
-
-    def test_explicit_lock(self):
-        with self.assertWarns(DeprecationWarning):
-            lock = asyncio.Lock(loop=self.loop)
-            cond = asyncio.Condition(lock, loop=self.loop)
-
-        self.assertIs(cond._lock, lock)
-        self.assertIs(cond._loop, lock._loop)
-
-    def test_ambiguous_loops(self):
-        loop = self.new_test_loop()
-        self.addCleanup(loop.close)
-        with self.assertWarns(DeprecationWarning):
-            lock = asyncio.Lock(loop=self.loop)
-            with self.assertRaises(ValueError):
-                asyncio.Condition(lock, loop=loop)
+        # All should work in the same way.
+        await f()
+        await f(asyncio.Lock())
+        lock = asyncio.Lock()
+        await f(lock, asyncio.Condition(lock))
 
-    def test_timeout_in_block(self):
+    async def test_ambiguous_loops(self):
         loop = asyncio.new_event_loop()
         self.addCleanup(loop.close)
 
-        async def task_timeout():
-            condition = asyncio.Condition(loop=loop)
-            async with condition:
-                with self.assertRaises(asyncio.TimeoutError):
-                    await asyncio.wait_for(condition.wait(), timeout=0.5)
+        async def wrong_loop_in_lock():
+            with self.assertWarns(DeprecationWarning):
+                asyncio.Lock(loop=loop)
+            lock = asyncio.Lock()
+            lock._loop = loop  # use private API for testing
+            async with lock:
+                # acquired immediately via the fast-path
+                # without interaction with any event loop.
+                # cond.acquire() will trigger waiting on the lock
+                # and it will discover the event loop mismatch.
+                with self.assertRaisesRegex(
+                    ValueError,
+                    "loop argument must agree with lock",
+                ):
+                    asyncio.Condition(lock)
+
+        async def wrong_loop_in_cond():
+            # Same analogy here with the condition's loop.
+            lock = asyncio.Lock()
+            async with lock:
+                with self.assertRaisesRegex(
+                    ValueError,
+                    "loop argument must agree with lock"
+                ):
+                    with self.assertWarns(DeprecationWarning):
+                        asyncio.Condition(lock, loop=loop)
 
-        with self.assertWarns(DeprecationWarning):
-            loop.run_until_complete(task_timeout())
+        await wrong_loop_in_lock()
+        await wrong_loop_in_cond()
 
+    async def test_timeout_in_block(self):
+        condition = asyncio.Condition()
+        async with condition:
+            with self.assertRaises(asyncio.TimeoutError):
+                await asyncio.wait_for(condition.wait(), timeout=0.5)
 
-class SemaphoreTests(test_utils.TestCase):
 
-    def setUp(self):
-        super().setUp()
-        self.loop = self.new_test_loop()
+class SemaphoreTests(unittest.IsolatedAsyncioTestCase):
 
-    def test_ctor_loop(self):
+    async def test_ctor_loop(self):
         loop = mock.Mock()
         with self.assertWarns(DeprecationWarning):
             sem = asyncio.Semaphore(loop=loop)
         self.assertIs(sem._loop, loop)
 
         with self.assertWarns(DeprecationWarning):
-            sem = asyncio.Semaphore(loop=self.loop)
-        self.assertIs(sem._loop, self.loop)
+            sem = asyncio.Semaphore(loop=asyncio.get_running_loop())
+        self.assertIs(sem._loop, asyncio.get_running_loop())
 
-    def test_ctor_noloop(self):
-        asyncio.set_event_loop(self.loop)
+    async def test_ctor_noloop(self):
         sem = asyncio.Semaphore()
-        self.assertIs(sem._loop, self.loop)
+        self.assertIs(sem._loop, asyncio.get_running_loop())
 
-    def test_initial_value_zero(self):
+    async def test_initial_value_zero(self):
         with self.assertWarns(DeprecationWarning):
-            sem = asyncio.Semaphore(0, loop=self.loop)
+            sem = asyncio.Semaphore(0, loop=asyncio.get_running_loop())
         self.assertTrue(sem.locked())
 
-    def test_repr(self):
-        with self.assertWarns(DeprecationWarning):
-            sem = asyncio.Semaphore(loop=self.loop)
+    async def test_repr(self):
+        sem = asyncio.Semaphore()
         self.assertTrue(repr(sem).endswith('[unlocked, value:1]>'))
         self.assertTrue(RGX_REPR.match(repr(sem)))
 
-        self.loop.run_until_complete(sem.acquire())
+        await sem.acquire()
         self.assertTrue(repr(sem).endswith('[locked]>'))
         self.assertTrue('waiters' not in repr(sem))
         self.assertTrue(RGX_REPR.match(repr(sem)))
@@ -849,21 +822,15 @@ class SemaphoreTests(test_utils.TestCase):
         self.assertTrue('waiters:2' in repr(sem))
         self.assertTrue(RGX_REPR.match(repr(sem)))
 
-    def test_semaphore(self):
-        with self.assertWarns(DeprecationWarning):
-            sem = asyncio.Semaphore(loop=self.loop)
+    async def test_semaphore(self):
+        sem = asyncio.Semaphore()
         self.assertEqual(1, sem._value)
 
-        with self.assertWarns(DeprecationWarning):
-            @asyncio.coroutine
-            def acquire_lock():
-                return (yield from sem)
-
         with self.assertRaisesRegex(
             TypeError,
-            "'Semaphore' object is not iterable",
+            "object Semaphore can't be used in 'await' expression",
         ):
-            self.loop.run_until_complete(acquire_lock())
+            await sem
 
         self.assertFalse(sem.locked())
         self.assertEqual(1, sem._value)
@@ -871,13 +838,12 @@ class SemaphoreTests(test_utils.TestCase):
     def test_semaphore_value(self):
         self.assertRaises(ValueError, asyncio.Semaphore, -1)
 
-    def test_acquire(self):
-        with self.assertWarns(DeprecationWarning):
-            sem = asyncio.Semaphore(3, loop=self.loop)
+    async def test_acquire(self):
+        sem = asyncio.Semaphore(3)
         result = []
 
-        self.assertTrue(self.loop.run_until_complete(sem.acquire()))
-        self.assertTrue(self.loop.run_until_complete(sem.acquire()))
+        self.assertTrue(await sem.acquire())
+        self.assertTrue(await sem.acquire())
         self.assertFalse(sem.locked())
 
         async def c1(result):
@@ -900,23 +866,23 @@ class SemaphoreTests(test_utils.TestCase):
             result.append(4)
             return True
 
-        t1 = self.loop.create_task(c1(result))
-        t2 = self.loop.create_task(c2(result))
-        t3 = self.loop.create_task(c3(result))
+        t1 = asyncio.create_task(c1(result))
+        t2 = asyncio.create_task(c2(result))
+        t3 = asyncio.create_task(c3(result))
 
-        test_utils.run_briefly(self.loop)
+        await asyncio.sleep(0)
         self.assertEqual([1], result)
         self.assertTrue(sem.locked())
         self.assertEqual(2, len(sem._waiters))
         self.assertEqual(0, sem._value)
 
-        t4 = self.loop.create_task(c4(result))
+        t4 = asyncio.create_task(c4(result))
 
         sem.release()
         sem.release()
         self.assertEqual(2, sem._value)
 
-        test_utils.run_briefly(self.loop)
+        await asyncio.sleep(0)
         self.assertEqual(0, sem._value)
         self.assertEqual(3, len(result))
         self.assertTrue(sem.locked())
@@ -931,69 +897,65 @@ class SemaphoreTests(test_utils.TestCase):
 
         # cleanup locked semaphore
         sem.release()
-        self.loop.run_until_complete(asyncio.gather(*race_tasks))
+        await asyncio.gather(*race_tasks)
 
-    def test_acquire_cancel(self):
-        with self.assertWarns(DeprecationWarning):
-            sem = asyncio.Semaphore(loop=self.loop)
-        self.loop.run_until_complete(sem.acquire())
-
-        acquire = self.loop.create_task(sem.acquire())
-        self.loop.call_soon(acquire.cancel)
-        self.assertRaises(
-            asyncio.CancelledError,
-            self.loop.run_until_complete, acquire)
+    async def test_acquire_cancel(self):
+        sem = asyncio.Semaphore()
+        await sem.acquire()
+
+        acquire = asyncio.create_task(sem.acquire())
+        asyncio.get_running_loop().call_soon(acquire.cancel)
+        with self.assertRaises(asyncio.CancelledError):
+            await acquire
         self.assertTrue((not sem._waiters) or
                         all(waiter.done() for waiter in sem._waiters))
 
-    def test_acquire_cancel_before_awoken(self):
-        with self.assertWarns(DeprecationWarning):
-            sem = asyncio.Semaphore(value=0, loop=self.loop)
+    async def test_acquire_cancel_before_awoken(self):
+        sem = asyncio.Semaphore(value=0)
 
-        t1 = self.loop.create_task(sem.acquire())
-        t2 = self.loop.create_task(sem.acquire())
-        t3 = self.loop.create_task(sem.acquire())
-        t4 = self.loop.create_task(sem.acquire())
+        t1 = asyncio.create_task(sem.acquire())
+        t2 = asyncio.create_task(sem.acquire())
+        t3 = asyncio.create_task(sem.acquire())
+        t4 = asyncio.create_task(sem.acquire())
 
-        test_utils.run_briefly(self.loop)
+        await asyncio.sleep(0)
 
-        sem.release()
         t1.cancel()
         t2.cancel()
+        sem.release()
 
-        test_utils.run_briefly(self.loop)
+        await asyncio.sleep(0)
         num_done = sum(t.done() for t in [t3, t4])
         self.assertEqual(num_done, 1)
+        self.assertTrue(t3.done())
+        self.assertFalse(t4.done())
 
         t3.cancel()
         t4.cancel()
-        test_utils.run_briefly(self.loop)
-
-    def test_acquire_hang(self):
-        with self.assertWarns(DeprecationWarning):
-            sem = asyncio.Semaphore(value=0, loop=self.loop)
+        await asyncio.sleep(0)
 
-        t1 = self.loop.create_task(sem.acquire())
-        t2 = self.loop.create_task(sem.acquire())
+    async def test_acquire_hang(self):
+        sem = asyncio.Semaphore(value=0)
 
-        test_utils.run_briefly(self.loop)
+        t1 = asyncio.create_task(sem.acquire())
+        t2 = asyncio.create_task(sem.acquire())
+        await asyncio.sleep(0)
 
-        sem.release()
         t1.cancel()
-
-        test_utils.run_briefly(self.loop)
+        sem.release()
+        await asyncio.sleep(0)
         self.assertTrue(sem.locked())
+        self.assertTrue(t2.done())
 
-    def test_release_not_acquired(self):
+    async def test_release_not_acquired(self):
         with self.assertWarns(DeprecationWarning):
-            sem = asyncio.BoundedSemaphore(loop=self.loop)
+            sem = asyncio.BoundedSemaphore(loop=asyncio.get_running_loop())
 
         self.assertRaises(ValueError, sem.release)
 
-    def test_release_no_waiters(self):
-        with self.assertWarns(DeprecationWarning):
-            sem = asyncio.Semaphore(loop=self.loop)
-        self.loop.run_until_complete(sem.acquire())
+    async def test_release_no_waiters(self):
+        sem = asyncio.Semaphore()
+        await sem.acquire()
         self.assertTrue(sem.locked())
 
         sem.release()
index 451f86a..59d5e5b 100644 (file)
@@ -72,6 +72,7 @@ class ProactorSocketTransportTests(test_utils.TestCase):
         self.loop._proactor.recv.assert_called_with(self.sock, 32768)
         self.protocol.data_received.assert_called_with(b'data')
 
+    @unittest.skipIf(sys.flags.optimize, "Assertions are disabled in optimized mode")
     def test_loop_reading_no_data(self):
         res = self.loop.create_future()
         res.set_result(b'')
@@ -853,6 +854,7 @@ class BaseProactorEventLoopTests(test_utils.TestCase):
         self.protocol.datagram_received.assert_called_with(b'data', ('127.0.0.1', 12068))
         close_transport(tr)
 
+    @unittest.skipIf(sys.flags.optimize, "Assertions are disabled in optimized mode")
     def test_datagram_loop_reading_no_data(self):
         res = self.loop.create_future()
         res.set_result((b'', ('127.0.0.1', 12068)))
index 1613c75..b684fab 100644 (file)
@@ -1,5 +1,6 @@
 """Tests for selector_events.py"""
 
+import sys
 import selectors
 import socket
 import unittest
@@ -804,6 +805,7 @@ class SelectorSocketTransportTests(test_utils.TestCase):
         self.sock.close.assert_called_with()
         self.protocol.connection_lost.assert_called_with(None)
 
+    @unittest.skipIf(sys.flags.optimize, "Assertions are disabled in optimized mode")
     def test_write_ready_no_data(self):
         transport = self.socket_transport()
         # This is an internal error.
index 402edae..a6afce0 100644 (file)
@@ -1121,20 +1121,16 @@ class BaseTaskTests:
         self.assertEqual(res, "ok")
 
     def test_wait_for_cancellation_race_condition(self):
-        def gen():
-            yield 0.1
-            yield 0.1
-            yield 0.1
-            yield 0.1
+        async def inner():
+            with contextlib.suppress(asyncio.CancelledError):
+                await asyncio.sleep(1)
+            return 1
 
-        loop = self.new_test_loop(gen)
+        async def main():
+            result = await asyncio.wait_for(inner(), timeout=.01)
+            assert result == 1
 
-        fut = self.new_future(loop)
-        loop.call_later(0.1, fut.set_result, "ok")
-        task = loop.create_task(asyncio.wait_for(fut, timeout=1))
-        loop.call_later(0.1, task.cancel)
-        res = loop.run_until_complete(task)
-        self.assertEqual(res, "ok")
+        asyncio.run(main())
 
     def test_wait_for_waits_for_task_cancellation(self):
         loop = asyncio.new_event_loop()
@@ -1213,24 +1209,6 @@ class BaseTaskTests:
         with self.assertRaises(FooException):
             loop.run_until_complete(foo())
 
-    def test_wait_for_raises_timeout_error_if_returned_during_cancellation(self):
-        loop = asyncio.new_event_loop()
-        self.addCleanup(loop.close)
-
-        async def foo():
-            async def inner():
-                try:
-                    await asyncio.sleep(0.2)
-                except asyncio.CancelledError:
-                    return 42
-
-            inner_task = self.new_task(loop, inner())
-
-            await asyncio.wait_for(inner_task, timeout=_EPSILON)
-
-        with self.assertRaises(asyncio.TimeoutError):
-            loop.run_until_complete(foo())
-
     def test_wait_for_self_cancellation(self):
         loop = asyncio.new_event_loop()
         self.addCleanup(loop.close)
index 6b2fe2f..39b1b64 100644 (file)
@@ -549,6 +549,14 @@ class CAPITest(unittest.TestCase):
         s = _testcapi.pyobject_bytes_from_null()
         self.assertEqual(s, b'<NULL>')
 
+    def test_Py_CompileString(self):
+        # Check that Py_CompileString respects the coding cookie
+        _compile = _testcapi.Py_CompileString
+        code = b"# -*- coding: latin1 -*-\nprint('\xc2\xa4')\n"
+        result = _compile(code)
+        expected = compile(code, "<string>", "exec")
+        self.assertEqual(result.co_consts, expected.co_consts)
+
 
 class TestPendingCalls(unittest.TestCase):
 
@@ -755,8 +763,13 @@ class PyMemDebugTests(unittest.TestCase):
 
     def check(self, code):
         with support.SuppressCrashReport():
-            out = assert_python_failure('-c', code,
-                                        PYTHONMALLOC=self.PYTHONMALLOC)
+            out = assert_python_failure(
+                '-c', code,
+                PYTHONMALLOC=self.PYTHONMALLOC,
+                # FreeBSD: instruct jemalloc to not fill freed() memory
+                # with junk byte 0x5a, see JEMALLOC(3)
+                MALLOC_CONF="junk:false",
+            )
         stderr = out.err
         return stderr.decode('ascii', 'replace')
 
@@ -826,7 +839,11 @@ class PyMemDebugTests(unittest.TestCase):
             except _testcapi.error:
                 os._exit(1)
         ''')
-        assert_python_ok('-c', code, PYTHONMALLOC=self.PYTHONMALLOC)
+        assert_python_ok(
+            '-c', code,
+            PYTHONMALLOC=self.PYTHONMALLOC,
+            MALLOC_CONF="junk:false",
+        )
 
     def test_pyobject_null_is_freed(self):
         self.check_pyobject_is_freed('check_pyobject_null_is_freed')
index 9e11747..e320ef3 100644 (file)
@@ -663,6 +663,7 @@ class TestNamedTuple(unittest.TestCase):
         a.w = 5
         self.assertEqual(a.__dict__, {'w': 5})
 
+    @support.cpython_only
     def test_field_descriptor(self):
         Point = namedtuple('Point', 'x y')
         p = Point(11, 22)
index 48d56d9..d693fb4 100644 (file)
@@ -564,6 +564,14 @@ create_executor_tests(ProcessPoolShutdownTest,
 
 
 class WaitTests:
+    def test_20369(self):
+        # See https://bugs.python.org/issue20369
+        future = self.executor.submit(time.sleep, 1.5)
+        done, not_done = futures.wait([future, future],
+                            return_when=futures.ALL_COMPLETED)
+        self.assertEqual({future}, done)
+        self.assertEqual(set(), not_done)
+
 
     def test_first_completed(self):
         future1 = self.executor.submit(mul, 21, 2)
index ad981d1..9b60134 100644 (file)
@@ -7,6 +7,7 @@ from dataclasses import *
 import pickle
 import inspect
 import builtins
+import types
 import unittest
 from unittest.mock import Mock
 from typing import ClassVar, Any, List, Union, Tuple, Dict, Generic, TypeVar, Optional, Protocol
@@ -1124,6 +1125,8 @@ class TestCase(unittest.TestCase):
         self.assertEqual(repr(InitVar[int]), 'dataclasses.InitVar[int]')
         self.assertEqual(repr(InitVar[List[int]]),
                          'dataclasses.InitVar[typing.List[int]]')
+        self.assertEqual(repr(InitVar[list[int]]),
+                         'dataclasses.InitVar[list[int]]')
 
     def test_init_var_inheritance(self):
         # Note that this deliberately tests that a dataclass need not
@@ -1348,6 +1351,17 @@ class TestCase(unittest.TestCase):
                 with self.assertRaisesRegex(TypeError, 'should be called on dataclass instances'):
                     replace(obj, x=0)
 
+    def test_is_dataclass_genericalias(self):
+        @dataclass
+        class A(types.GenericAlias):
+            origin: type
+            args: type
+        self.assertTrue(is_dataclass(A))
+        a = A(list, int)
+        self.assertTrue(is_dataclass(type(a)))
+        self.assertTrue(is_dataclass(a))
+
+
     def test_helper_fields_with_class_instance(self):
         # Check that we can call fields() on either a class or instance,
         #  and get back the same thing.
index 0e6a784..e5e9f49 100644 (file)
@@ -2531,10 +2531,8 @@ order (MRO) for bases """
         m2instance.b = 2
         m2instance.a = 1
         self.assertEqual(m2instance.__dict__, "Not a dict!")
-        try:
+        with self.assertRaises(TypeError):
             dir(m2instance)
-        except TypeError:
-            pass
 
         # Two essentially featureless objects, (Ellipsis just inherits stuff
         # from object.
@@ -4013,7 +4011,7 @@ order (MRO) for bases """
         except TypeError:
             pass
         else:
-            assert 0, "best_base calculation found wanting"
+            self.fail("best_base calculation found wanting")
 
     def test_unsubclassable_types(self):
         with self.assertRaises(TypeError):
@@ -4399,6 +4397,8 @@ order (MRO) for bases """
             print("Oops!")
         except RuntimeError:
             pass
+        else:
+            self.fail("Didn't raise RuntimeError")
         finally:
             sys.stdout = test_stdout
 
index bc062b5..489cd05 100644 (file)
@@ -2742,6 +2742,20 @@ message 2
         self.assertEqual(str(cm.exception),
                          'There may be at most 1 To headers in a message')
 
+
+# Test the NonMultipart class
+class TestNonMultipart(TestEmailBase):
+    def test_nonmultipart_is_not_multipart(self):
+        msg = MIMENonMultipart('text', 'plain')
+        self.assertFalse(msg.is_multipart())
+
+    def test_attach_raises_exception(self):
+        msg = Message()
+        msg['Subject'] = 'subpart 1'
+        r = MIMENonMultipart('text', 'plain')
+        self.assertRaises(errors.MultipartConversionError, r.attach, msg)
+
+
 # A general test of parser->model->generator idempotency.  IOW, read a message
 # in, parse it into a message object tree, then without touching the tree,
 # regenerate the plain text.  The original text and the transformed text
index 4a7ca60..5168b0b 100644 (file)
@@ -1213,7 +1213,7 @@ class ExceptionTests(unittest.TestCase):
                 # tstate->recursion_depth is equal to (recursion_limit - 1)
                 # and is equal to recursion_limit when _gen_throw() calls
                 # PyErr_NormalizeException().
-                recurse(setrecursionlimit(depth + 2) - depth - 1)
+                recurse(setrecursionlimit(depth + 2) - depth)
             finally:
                 sys.setrecursionlimit(recursionlimit)
                 print('Done.')
@@ -1243,6 +1243,52 @@ class ExceptionTests(unittest.TestCase):
                       b'while normalizing an exception', err)
         self.assertIn(b'Done.', out)
 
+    def test_recursion_in_except_handler(self):
+
+        def set_relative_recursion_limit(n):
+            depth = 1
+            while True:
+                try:
+                    sys.setrecursionlimit(depth)
+                except RecursionError:
+                    depth += 1
+                else:
+                    break
+            sys.setrecursionlimit(depth+n)
+
+        def recurse_in_except():
+            try:
+                1/0
+            except:
+                recurse_in_except()
+
+        def recurse_after_except():
+            try:
+                1/0
+            except:
+                pass
+            recurse_after_except()
+
+        def recurse_in_body_and_except():
+            try:
+                recurse_in_body_and_except()
+            except:
+                recurse_in_body_and_except()
+
+        recursionlimit = sys.getrecursionlimit()
+        try:
+            set_relative_recursion_limit(10)
+            for func in (recurse_in_except, recurse_after_except, recurse_in_body_and_except):
+                with self.subTest(func=func):
+                    try:
+                        func()
+                    except RecursionError:
+                        pass
+                    else:
+                        self.fail("Should have raised a RecursionError")
+        finally:
+            sys.setrecursionlimit(recursionlimit)
+
     @cpython_only
     def test_recursion_normalizing_with_no_memory(self):
         # Issue #30697. Test that in the abort that occurs when there is no
index b2a7e5a..d7dec3f 100644 (file)
@@ -2560,7 +2560,7 @@ class TestSingleDispatch(unittest.TestCase):
 
         self.assertEqual(without_single_dispatch_foo, single_dispatch_foo)
         self.assertEqual(single_dispatch_foo, '5')
-        
+
         self.assertEqual(
             WithoutSingleDispatch.decorated_classmethod(5),
             WithSingleDispatch.decorated_classmethod(5)
@@ -2655,6 +2655,74 @@ class TestSingleDispatch(unittest.TestCase):
         with self.assertRaisesRegex(TypeError, msg):
             f()
 
+    def test_register_genericalias(self):
+        @functools.singledispatch
+        def f(arg):
+            return "default"
+
+        with self.assertRaisesRegex(TypeError, "Invalid first argument to "):
+            f.register(list[int], lambda arg: "types.GenericAlias")
+        with self.assertRaisesRegex(TypeError, "Invalid first argument to "):
+            f.register(typing.List[int], lambda arg: "typing.GenericAlias")
+        with self.assertRaisesRegex(TypeError, "Invalid first argument to "):
+            f.register(typing.Union[list[int], str], lambda arg: "typing.Union[types.GenericAlias]")
+        with self.assertRaisesRegex(TypeError, "Invalid first argument to "):
+            f.register(typing.Union[typing.List[float], bytes], lambda arg: "typing.Union[typing.GenericAlias]")
+        with self.assertRaisesRegex(TypeError, "Invalid first argument to "):
+            f.register(typing.Any, lambda arg: "typing.Any")
+
+        self.assertEqual(f([1]), "default")
+        self.assertEqual(f([1.0]), "default")
+        self.assertEqual(f(""), "default")
+        self.assertEqual(f(b""), "default")
+
+    def test_register_genericalias_decorator(self):
+        @functools.singledispatch
+        def f(arg):
+            return "default"
+
+        with self.assertRaisesRegex(TypeError, "Invalid first argument to "):
+            f.register(list[int])
+        with self.assertRaisesRegex(TypeError, "Invalid first argument to "):
+            f.register(typing.List[int])
+        with self.assertRaisesRegex(TypeError, "Invalid first argument to "):
+            f.register(typing.Union[list[int], str])
+        with self.assertRaisesRegex(TypeError, "Invalid first argument to "):
+            f.register(typing.Union[typing.List[int], str])
+        with self.assertRaisesRegex(TypeError, "Invalid first argument to "):
+            f.register(typing.Any)
+
+    def test_register_genericalias_annotation(self):
+        @functools.singledispatch
+        def f(arg):
+            return "default"
+
+        with self.assertRaisesRegex(TypeError, "Invalid annotation for 'arg'"):
+            @f.register
+            def _(arg: list[int]):
+                return "types.GenericAlias"
+        with self.assertRaisesRegex(TypeError, "Invalid annotation for 'arg'"):
+            @f.register
+            def _(arg: typing.List[float]):
+                return "typing.GenericAlias"
+        with self.assertRaisesRegex(TypeError, "Invalid annotation for 'arg'"):
+            @f.register
+            def _(arg: typing.Union[list[int], str]):
+                return "types.UnionType(types.GenericAlias)"
+        with self.assertRaisesRegex(TypeError, "Invalid annotation for 'arg'"):
+            @f.register
+            def _(arg: typing.Union[typing.List[float], bytes]):
+                return "typing.Union[typing.GenericAlias]"
+        with self.assertRaisesRegex(TypeError, "Invalid annotation for 'arg'"):
+            @f.register
+            def _(arg: typing.Any):
+                return "typing.Any"
+
+        self.assertEqual(f([1]), "default")
+        self.assertEqual(f([1.0]), "default")
+        self.assertEqual(f(""), "default")
+        self.assertEqual(f(b""), "default")
+
 
 class CachedCostItem:
     _cost = 1
index 5f55489..b3aa855 100644 (file)
@@ -955,6 +955,31 @@ id(42)
         self.assertRegex(gdb_output,
                          r"<method-wrapper u?'__init__' of MyList object at ")
 
+    @unittest.skipIf(python_is_optimized(),
+                     "Python was compiled with optimizations")
+    def test_try_finally_lineno(self):
+        cmd = textwrap.dedent('''
+            def foo(x):
+                try:
+                    raise RuntimeError("error")
+                    return x
+                except:
+                    id("break point")
+                finally:
+                    x += 2
+                return x
+            r = foo(3)
+        ''')
+        gdb_output = self.get_stack_trace(cmd,
+                                          cmds_after_breakpoint=["py-bt"])
+        self.assertMultilineMatches(gdb_output,
+                                    r'''^.*
+Traceback \(most recent call first\):
+  <built-in method id of module object .*>
+  File "<string>", line 7, in foo
+  File "<string>", line 11, in <module>
+''')
+
 
 class PyPrintTests(DebuggerTests):
     @unittest.skipIf(python_is_optimized(),
index 86f31a5..969e5e4 100644 (file)
@@ -45,12 +45,15 @@ else:
     builtin_hashlib = None
 
 try:
-    from _hashlib import HASH, HASHXOF, openssl_md_meth_names
+    from _hashlib import HASH, HASHXOF, openssl_md_meth_names, get_fips_mode
 except ImportError:
     HASH = None
     HASHXOF = None
     openssl_md_meth_names = frozenset()
 
+    def get_fips_mode():
+        return 0
+
 try:
     import _blake2
 except ImportError:
@@ -196,10 +199,7 @@ class HashLibTestCase(unittest.TestCase):
 
     @property
     def is_fips_mode(self):
-        if hasattr(self._hashlib, "get_fips_mode"):
-            return self._hashlib.get_fips_mode()
-        else:
-            return None
+        return get_fips_mode()
 
     def test_hash_array(self):
         a = array.array("b", range(10))
@@ -1013,7 +1013,7 @@ class KDFTests(unittest.TestCase):
                     self.assertEqual(out, expected,
                                      (digest_name, password, salt, rounds))
 
-        with self.assertRaisesRegex(ValueError, 'unsupported hash type'):
+        with self.assertRaisesRegex(ValueError, '.*unsupported.*'):
             pbkdf2('unknown', b'pass', b'salt', 1)
 
         if 'sha1' in supported:
@@ -1050,6 +1050,7 @@ class KDFTests(unittest.TestCase):
 
     @unittest.skipUnless(hasattr(hashlib, 'scrypt'),
                      '   test requires OpenSSL > 1.1')
+    @unittest.skipIf(get_fips_mode(), reason="scrypt is blocked in FIPS mode")
     def test_scrypt(self):
         for password, salt, n, r, p, expected in self.scrypt_test_vectors:
             result = hashlib.scrypt(password, salt=salt, n=n, r=r, p=p)
index 914a75a..7055938 100644 (file)
@@ -385,7 +385,7 @@ class NewIMAPTestsMixin():
         self.assertEqual(code, 'OK')
         self.assertEqual(server.response, b'ZmFrZQ==\r\n')  # b64 encoded 'fake'
 
-    @hashlib_helper.requires_hashdigest('md5')
+    @hashlib_helper.requires_hashdigest('md5', openssl=True)
     def test_login_cram_md5_bytes(self):
         class AuthHandler(SimpleIMAPHandler):
             capabilities = 'LOGINDISABLED AUTH=CRAM-MD5'
@@ -403,7 +403,7 @@ class NewIMAPTestsMixin():
         ret, _ = client.login_cram_md5("tim", b"tanstaaftanstaaf")
         self.assertEqual(ret, "OK")
 
-    @hashlib_helper.requires_hashdigest('md5')
+    @hashlib_helper.requires_hashdigest('md5', openssl=True)
     def test_login_cram_md5_plain_text(self):
         class AuthHandler(SimpleIMAPHandler):
             capabilities = 'LOGINDISABLED AUTH=CRAM-MD5'
@@ -849,7 +849,7 @@ class ThreadedNetworkedTests(unittest.TestCase):
                              b'ZmFrZQ==\r\n')  # b64 encoded 'fake'
 
     @reap_threads
-    @hashlib_helper.requires_hashdigest('md5')
+    @hashlib_helper.requires_hashdigest('md5', openssl=True)
     def test_login_cram_md5(self):
 
         class AuthHandler(SimpleIMAPHandler):
index 1d7b29a..420fbfe 100644 (file)
@@ -121,6 +121,7 @@ class APITests(
 
             [extra1]
             dep4
+            dep6@ git+https://example.com/python/dep.git@v1.0.0
 
             [extra2:python_version < "3"]
             dep5
@@ -132,6 +133,7 @@ class APITests(
             'dep3; python_version < "3"',
             'dep4; extra == "extra1"',
             'dep5; (python_version < "3") and extra == "extra2"',
+            'dep6@ git+https://example.com/python/dep.git@v1.0.0 ; extra == "extra1"',
             ]
         # It's important that the environment marker expression be
         # wrapped in parentheses to avoid the following 'and' binding more
index 876c91f..363ea29 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright 2001-2019 by Vinay Sajip. All Rights Reserved.
+# Copyright 2001-2021 by Vinay Sajip. All Rights Reserved.
 #
 # Permission to use, copy, modify, and distribute this software and its
 # documentation for any purpose and without fee is hereby granted,
@@ -16,7 +16,7 @@
 
 """Test harness for the logging module. Run all tests.
 
-Copyright (C) 2001-2019 Vinay Sajip. All Rights Reserved.
+Copyright (C) 2001-2021 Vinay Sajip. All Rights Reserved.
 """
 
 import logging
@@ -36,6 +36,7 @@ import os
 import queue
 import random
 import re
+import shutil
 import socket
 import struct
 import sys
@@ -5284,6 +5285,54 @@ class TimedRotatingFileHandlerTest(BaseFileTest):
             finally:
                 rh.close()
 
+    def test_compute_files_to_delete(self):
+        # See bpo-46063 for background
+        wd = tempfile.mkdtemp(prefix='test_logging_')
+        self.addCleanup(shutil.rmtree, wd)
+        times = []
+        dt = datetime.datetime.now()
+        for i in range(10):
+            times.append(dt.strftime('%Y-%m-%d_%H-%M-%S'))
+            dt += datetime.timedelta(seconds=5)
+        prefixes = ('a.b', 'a.b.c', 'd.e', 'd.e.f')
+        files = []
+        rotators = []
+        for prefix in prefixes:
+            p = os.path.join(wd, '%s.log' % prefix)
+            rotator = logging.handlers.TimedRotatingFileHandler(p, when='s',
+                                                                interval=5,
+                                                                backupCount=7,
+                                                                delay=True)
+            rotators.append(rotator)
+            if prefix.startswith('a.b'):
+                for t in times:
+                    files.append('%s.log.%s' % (prefix, t))
+            else:
+                rotator.namer = lambda name: name.replace('.log', '') + '.log'
+                for t in times:
+                    files.append('%s.%s.log' % (prefix, t))
+        # Create empty files
+        for fn in files:
+            p = os.path.join(wd, fn)
+            with open(p, 'wb') as f:
+                pass
+        # Now the checks that only the correct files are offered up for deletion
+        for i, prefix in enumerate(prefixes):
+            rotator = rotators[i]
+            candidates = rotator.getFilesToDelete()
+            self.assertEqual(len(candidates), 3)
+            if prefix.startswith('a.b'):
+                p = '%s.log.' % prefix
+                for c in candidates:
+                    d, fn = os.path.split(c)
+                    self.assertTrue(fn.startswith(p))
+            else:
+                for c in candidates:
+                    d, fn = os.path.split(c)
+                    self.assertTrue(fn.endswith('.log'))
+                    self.assertTrue(fn.startswith(prefix + '.') and
+                                    fn[len(prefix) + 2].isdigit())
+
 
 def secs(**kw):
     return datetime.timedelta(**kw) // datetime.timedelta(seconds=1)
index 35933e9..59ddf9e 100644 (file)
@@ -4273,6 +4273,22 @@ class TimesTests(unittest.TestCase):
             self.assertEqual(times.elapsed, 0)
 
 
+@requires_os_func('fork')
+class ForkTests(unittest.TestCase):
+    def test_fork(self):
+        # bpo-42540: ensure os.fork() with non-default memory allocator does
+        # not crash on exit.
+        code = """if 1:
+            import os
+            from test import support
+            pid = os.fork()
+            if pid != 0:
+                support.wait_process(pid, exitcode=0)
+        """
+        assert_python_ok("-c", code)
+        assert_python_ok("-c", code, PYTHONMALLOC="malloc_debug")
+
+
 # Only test if the C version is provided, otherwise TestPEP519 already tested
 # the pure Python implementation.
 if hasattr(os, "_fspath"):
index 183c157..1406ed3 100644 (file)
@@ -2443,13 +2443,21 @@ class PosixPathTest(_BasePathTest, unittest.TestCase):
             othername = username
             otherhome = userhome
 
+        fakename = 'fakeuser'
+        # This user can theoretically exist on a test runner. Create unique name:
+        try:
+            while pwd.getpwnam(fakename):
+                fakename += '1'
+        except KeyError:
+            pass  # Non-existent name found
+
         p1 = P('~/Documents')
-        p2 = P('~' + username + '/Documents')
-        p3 = P('~' + othername + '/Documents')
-        p4 = P('../~' + username + '/Documents')
-        p5 = P('/~' + username + '/Documents')
+        p2 = P(f'~{username}/Documents')
+        p3 = P(f'~{othername}/Documents')
+        p4 = P(f'../~{username}/Documents')
+        p5 = P(f'/~{username}/Documents')
         p6 = P('')
-        p7 = P('~fakeuser/Documents')
+        p7 = P(f'~{fakename}/Documents')
 
         with support.EnvironmentVarGuard() as env:
             env.pop('HOME', None)
index 5228fc4..5d9f557 100644 (file)
@@ -313,11 +313,11 @@ class TestPOP3Class(TestCase):
     def test_rpop(self):
         self.assertOK(self.client.rpop('foo'))
 
-    @hashlib_helper.requires_hashdigest('md5')
+    @hashlib_helper.requires_hashdigest('md5', openssl=True)
     def test_apop_normal(self):
         self.assertOK(self.client.apop('foo', 'dummypassword'))
 
-    @hashlib_helper.requires_hashdigest('md5')
+    @hashlib_helper.requires_hashdigest('md5', openssl=True)
     def test_apop_REDOS(self):
         # Replace welcome with very long evil welcome.
         # NB The upper bound on welcome length is currently 2048.
index dd7f0b1..ee58c62 100644 (file)
@@ -418,11 +418,12 @@ class BaseSimpleQueueTest:
     def setUp(self):
         self.q = self.type2test()
 
-    def feed(self, q, seq, rnd):
+    def feed(self, q, seq, rnd, sentinel):
         while True:
             try:
                 val = seq.pop()
             except IndexError:
+                q.put(sentinel)
                 return
             q.put(val)
             if rnd.random() > 0.5:
@@ -461,11 +462,10 @@ class BaseSimpleQueueTest:
                 return
             results.append(val)
 
-    def run_threads(self, n_feeders, n_consumers, q, inputs,
-                    feed_func, consume_func):
+    def run_threads(self, n_threads, q, inputs, feed_func, consume_func):
         results = []
         sentinel = None
-        seq = inputs + [sentinel] * n_consumers
+        seq = inputs.copy()
         seq.reverse()
         rnd = random.Random(42)
 
@@ -479,11 +479,11 @@ class BaseSimpleQueueTest:
             return wrapper
 
         feeders = [threading.Thread(target=log_exceptions(feed_func),
-                                    args=(q, seq, rnd))
-                   for i in range(n_feeders)]
+                                    args=(q, seq, rnd, sentinel))
+                   for i in range(n_threads)]
         consumers = [threading.Thread(target=log_exceptions(consume_func),
                                       args=(q, results, sentinel))
-                     for i in range(n_consumers)]
+                     for i in range(n_threads)]
 
         with support.start_threads(feeders + consumers):
             pass
@@ -541,7 +541,7 @@ class BaseSimpleQueueTest:
         # Test a pair of concurrent put() and get()
         q = self.q
         inputs = list(range(100))
-        results = self.run_threads(1, 1, q, inputs, self.feed, self.consume)
+        results = self.run_threads(1, q, inputs, self.feed, self.consume)
 
         # One producer, one consumer => results appended in well-defined order
         self.assertEqual(results, inputs)
@@ -551,7 +551,7 @@ class BaseSimpleQueueTest:
         N = 50
         q = self.q
         inputs = list(range(10000))
-        results = self.run_threads(N, N, q, inputs, self.feed, self.consume)
+        results = self.run_threads(N, q, inputs, self.feed, self.consume)
 
         # Multiple consumers without synchronization append the
         # results in random order
@@ -562,7 +562,7 @@ class BaseSimpleQueueTest:
         N = 50
         q = self.q
         inputs = list(range(10000))
-        results = self.run_threads(N, N, q, inputs,
+        results = self.run_threads(N, q, inputs,
                                    self.feed, self.consume_nonblock)
 
         self.assertEqual(sorted(results), inputs)
@@ -572,7 +572,7 @@ class BaseSimpleQueueTest:
         N = 50
         q = self.q
         inputs = list(range(1000))
-        results = self.run_threads(N, N, q, inputs,
+        results = self.run_threads(N, q, inputs,
                                    self.feed, self.consume_timeout)
 
         self.assertEqual(sorted(results), inputs)
index f18e72f..f91d332 100644 (file)
@@ -1,4 +1,5 @@
 import errno
+import inspect
 import os
 import random
 import signal
@@ -32,6 +33,14 @@ class GenericTests(unittest.TestCase):
                 self.assertIsInstance(sig, signal.Signals)
                 self.assertEqual(sys.platform, "win32")
 
+    def test_functions_module_attr(self):
+        # Issue #27718: If __all__ is not defined all non-builtin functions
+        # should have correct __module__ to be displayed by pydoc.
+        for name in dir(signal):
+            value = getattr(signal, name)
+            if inspect.isroutine(value) and not inspect.isbuiltin(value):
+                self.assertEqual(value.__module__, 'signal')
+
 
 @unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
 class PosixTests(unittest.TestCase):
index 52e9d6b..2d78019 100644 (file)
@@ -1167,7 +1167,7 @@ class SMTPSimTests(unittest.TestCase):
         finally:
             smtp.close()
 
-    @hashlib_helper.requires_hashdigest('md5')
+    @hashlib_helper.requires_hashdigest('md5', openssl=True)
     def testAUTH_CRAM_MD5(self):
         self.serv.add_feature("AUTH CRAM-MD5")
         smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost',
@@ -1176,7 +1176,7 @@ class SMTPSimTests(unittest.TestCase):
         self.assertEqual(resp, (235, b'Authentication Succeeded'))
         smtp.close()
 
-    @hashlib_helper.requires_hashdigest('md5')
+    @hashlib_helper.requires_hashdigest('md5', openssl=True)
     def testAUTH_multiple(self):
         # Test that multiple authentication methods are tried.
         self.serv.add_feature("AUTH BOGUS PLAIN LOGIN CRAM-MD5")
index 42ebcc0..b5eb40f 100644 (file)
@@ -589,13 +589,16 @@ class BasicSocketTests(unittest.TestCase):
         self.assertLessEqual(patch, 63)
         self.assertGreaterEqual(status, 0)
         self.assertLessEqual(status, 15)
-        # Version string as returned by {Open,Libre}SSL, the format might change
-        if IS_LIBRESSL:
-            self.assertTrue(s.startswith("LibreSSL {:d}".format(major)),
-                            (s, t, hex(n)))
+        libressl_ver = f"LibreSSL {major:d}"
+        if major >= 3:
+            # 3.x uses 0xMNN00PP0L
+            openssl_ver = f"OpenSSL {major:d}.{minor:d}.{patch:d}"
         else:
-            self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
-                            (s, t, hex(n)))
+            openssl_ver = f"OpenSSL {major:d}.{minor:d}.{fix:d}"
+        self.assertTrue(
+            s.startswith((openssl_ver, libressl_ver)),
+            (s, t, hex(n))
+        )
 
     @support.cpython_only
     def test_refcycle(self):
index 46f27d0..2f151b4 100644 (file)
@@ -1004,6 +1004,14 @@ while 1:
 """
         self._check_error(source, "too many statically nested blocks")
 
+    @support.cpython_only
+    def test_error_on_parser_stack_overflow(self):
+        source = "-" * 100000 + "4"
+        for mode in ["exec", "eval", "single"]:
+            with self.subTest(mode=mode):
+                with self.assertRaises(MemoryError):
+                    compile(source, "<string>", mode)
+
 
 def test_main():
     support.run_unittest(SyntaxTestCase)
index 450e392..2f1e5e9 100644 (file)
@@ -260,42 +260,10 @@ class SysModuleTest(unittest.TestCase):
             sys.setrecursionlimit(1000)
 
             for limit in (10, 25, 50, 75, 100, 150, 200):
-                # formula extracted from _Py_RecursionLimitLowerWaterMark()
-                if limit > 200:
-                    depth = limit - 50
-                else:
-                    depth = limit * 3 // 4
-                set_recursion_limit_at_depth(depth, limit)
+                set_recursion_limit_at_depth(limit, limit)
         finally:
             sys.setrecursionlimit(oldlimit)
 
-    # The error message is specific to CPython
-    @test.support.cpython_only
-    def test_recursionlimit_fatalerror(self):
-        # A fatal error occurs if a second recursion limit is hit when recovering
-        # from a first one.
-        code = textwrap.dedent("""
-            import sys
-
-            def f():
-                try:
-                    f()
-                except RecursionError:
-                    f()
-
-            sys.setrecursionlimit(%d)
-            f()""")
-        with test.support.SuppressCrashReport():
-            for i in (50, 1000):
-                sub = subprocess.Popen([sys.executable, '-c', code % i],
-                    stderr=subprocess.PIPE)
-                err = sub.communicate()[1]
-                self.assertTrue(sub.returncode, sub.returncode)
-                self.assertIn(
-                    b"Fatal Python error: _Py_CheckRecursiveCall: "
-                    b"Cannot recover from stack overflow",
-                    err)
-
     def test_getwindowsversion(self):
         # Raise SkipTest if sys doesn't have getwindowsversion attribute
         test.support.get_attribute(sys, "getwindowsversion")
index 90a1238..be9fb5a 100644 (file)
@@ -112,12 +112,13 @@ class TimeTestCase(unittest.TestCase):
         clk_id = time.pthread_getcpuclockid(threading.get_ident())
         self.assertTrue(type(clk_id) is int)
         # when in 32-bit mode AIX only returns the predefined constant
-        if not platform.system() == "AIX":
-            self.assertNotEqual(clk_id, time.CLOCK_THREAD_CPUTIME_ID)
-        elif (sys.maxsize.bit_length() > 32):
-            self.assertNotEqual(clk_id, time.CLOCK_THREAD_CPUTIME_ID)
-        else:
+        if platform.system() == "AIX" and (sys.maxsize.bit_length() <= 32):
             self.assertEqual(clk_id, time.CLOCK_THREAD_CPUTIME_ID)
+        # Solaris returns CLOCK_THREAD_CPUTIME_ID when current thread is given
+        elif sys.platform.startswith("sunos"):
+            self.assertEqual(clk_id, time.CLOCK_THREAD_CPUTIME_ID)
+        else:
+            self.assertNotEqual(clk_id, time.CLOCK_THREAD_CPUTIME_ID)
         t1 = time.clock_gettime(clk_id)
         t2 = time.clock_gettime(clk_id)
         self.assertLessEqual(t1, t2)
index 7321b48..f515378 100644 (file)
@@ -11,7 +11,7 @@ from test.test_tools import scriptsdir, skip_if_missing
 
 skip_if_missing()
 
-@hashlib_helper.requires_hashdigest('md5')
+@hashlib_helper.requires_hashdigest('md5', openssl=True)
 class MD5SumTests(unittest.TestCase):
     @classmethod
     def setUpClass(cls):
index 8d9d514..c0b3388 100644 (file)
@@ -740,6 +740,17 @@ class BaseExceptionReportingTests:
         err = self.get_report(Exception(''))
         self.assertIn('Exception\n', err)
 
+    def test_exception_modulename_not_unicode(self):
+        class X(Exception):
+            def __str__(self):
+                return "I am X"
+
+        X.__module__ = 42
+
+        err = self.get_report(X())
+        exp = f'<unknown>.{X.__qualname__}: I am X\n'
+        self.assertEqual(exp, err)
+
     def test_syntax_error_various_offsets(self):
         for offset in range(-5, 10):
             for add in [0, 2]:
index 49dc5bf..fe432a4 100644 (file)
@@ -7,6 +7,7 @@ import pickle
 import locale
 import sys
 import types
+import typing
 import unittest.mock
 import weakref
 
@@ -888,6 +889,17 @@ class ClassCreationTests(unittest.TestCase):
         self.assertEqual(D.__orig_bases__, (c,))
         self.assertEqual(D.__mro__, (D, A, object))
 
+    def test_new_class_with_mro_entry_genericalias(self):
+        L1 = types.new_class('L1', (typing.List[int],), {})
+        self.assertEqual(L1.__bases__, (list, typing.Generic))
+        self.assertEqual(L1.__orig_bases__, (typing.List[int],))
+        self.assertEqual(L1.__mro__, (L1, list, typing.Generic, object))
+
+        L2 = types.new_class('L2', (list[int],), {})
+        self.assertEqual(L2.__bases__, (list,))
+        self.assertEqual(L2.__orig_bases__, (list[int],))
+        self.assertEqual(L2.__mro__, (L2, list, object))
+
     def test_new_class_with_mro_entry_none(self):
         class A: pass
         class B: pass
@@ -1003,6 +1015,11 @@ class ClassCreationTests(unittest.TestCase):
         for bases in [x, y, z, t]:
             self.assertIs(types.resolve_bases(bases), bases)
 
+    def test_resolve_bases_with_mro_entry(self):
+        self.assertEqual(types.resolve_bases((typing.List[int],)),
+                         (list, typing.Generic))
+        self.assertEqual(types.resolve_bases((list[int],)), (list,))
+
     def test_metaclass_derivation(self):
         # issue1294232: correct metaclass calculation
         new_calls = []  # to check the order of __new__ calls
index 19c38ec..8cdb116 100644 (file)
@@ -2943,6 +2943,12 @@ class GetTypeHintTests(BaseTestCase):
                           'my_inner_a2': mod_generics_cache.B.A,
                           'my_outer_a': mod_generics_cache.A})
 
+    def test_get_type_hints_classes_no_implicit_optional(self):
+        class WithNoneDefault:
+            field: int = None  # most type-checkers won't be happy with it
+
+        self.assertEqual(gth(WithNoneDefault), {'field': int})
+
     def test_respect_no_type_check(self):
         @no_type_check
         class NoTpCheck:
index e73132a..7c71634 100644 (file)
@@ -316,7 +316,7 @@ class BasicAuthTests(unittest.TestCase):
         self.assertRaises(urllib.error.HTTPError, urllib.request.urlopen, self.server_url)
 
 
-@hashlib_helper.requires_hashdigest("md5")
+@hashlib_helper.requires_hashdigest("md5", openssl=True)
 class ProxyAuthTests(unittest.TestCase):
     URL = "http://localhost"
 
index e26e171..82cedfd 100644 (file)
@@ -169,6 +169,18 @@ class MiscTests(unittest.TestCase):
         del parser
         support.gc_collect()
 
+    def test_dict_disappearing_during_get_item(self):
+        # test fix for seg fault reported in issue 27946
+        class X:
+            def __hash__(self):
+                e.attrib = {} # this frees e->extra->attrib
+                [{i: i} for i in range(1000)] # exhaust the dict keys cache
+                return 13
+
+        e = cET.Element("elem", {1: 2})
+        r = e.get(X())
+        self.assertIsNone(r)
+
 
 @unittest.skipUnless(cET, 'requires _elementtree')
 class TestAliasWorking(unittest.TestCase):
index 554ae74..43ffd46 100644 (file)
@@ -193,6 +193,13 @@ class MiscTest(AbstractTkTest, unittest.TestCase):
             root.clipboard_get()
 
     def test_winfo_rgb(self):
+
+        def assertApprox(col1, col2):
+            # A small amount of flexibility is required (bpo-45496)
+            # 33 is ~0.05% of 65535, which is a reasonable margin
+            for col1_channel, col2_channel in zip(col1, col2):
+                self.assertAlmostEqual(col1_channel, col2_channel, delta=33)
+
         root = self.root
         rgb = root.winfo_rgb
 
@@ -202,9 +209,9 @@ class MiscTest(AbstractTkTest, unittest.TestCase):
         # #RGB - extends each 4-bit hex value to be 16-bit.
         self.assertEqual(rgb('#F0F'), (0xFFFF, 0x0000, 0xFFFF))
         # #RRGGBB - extends each 8-bit hex value to be 16-bit.
-        self.assertEqual(rgb('#4a3c8c'), (0x4a4a, 0x3c3c, 0x8c8c))
+        assertApprox(rgb('#4a3c8c'), (0x4a4a, 0x3c3c, 0x8c8c))
         # #RRRRGGGGBBBB
-        self.assertEqual(rgb('#dede14143939'), (0xdede, 0x1414, 0x3939))
+        assertApprox(rgb('#dede14143939'), (0xdede, 0x1414, 0x3939))
         # Invalid string.
         with self.assertRaises(tkinter.TclError):
             rgb('#123456789a')
index d65a609..c771a13 100644 (file)
@@ -574,6 +574,8 @@ class TracebackException:
         stype = self.exc_type.__qualname__
         smod = self.exc_type.__module__
         if smod not in ("__main__", "builtins"):
+            if not isinstance(smod, str):
+                smod = "<unknown>"
             stype = smod + '.' + stype
 
         if not issubclass(self.exc_type, SyntaxError):
index 793b35e..9c8f6ce 100644 (file)
@@ -2877,7 +2877,8 @@ class RawTurtle(TPen, TNavigator):
         between the orientation of the turtleshape and the heading of the
         turtle (its direction of movement).
 
-        Deprecated since Python 3.1
+        (Incorrectly marked as deprecated since Python 3.1, it is really
+        settiltangle that is deprecated.)
 
         Examples (for a Turtle instance named turtle):
         >>> turtle.shape("circle")
index ad2020e..f15fda5 100644 (file)
@@ -82,7 +82,7 @@ def resolve_bases(bases):
     updated = False
     shift = 0
     for i, base in enumerate(bases):
-        if isinstance(base, type):
+        if isinstance(base, type) and not isinstance(base, GenericAlias):
             continue
         if not hasattr(base, "__mro_entries__"):
             continue
index 22cb61b..a2980e7 100644 (file)
@@ -4,7 +4,6 @@ import inspect
 from .case import TestCase
 
 
-
 class IsolatedAsyncioTestCase(TestCase):
     # Names intentionally have a long prefix
     # to reduce a chance of clashing with user-defined attributes
index 34f0362..88f1a40 100644 (file)
@@ -252,7 +252,7 @@ class _AssertWarnsContext(_AssertRaisesBaseContext):
     def __enter__(self):
         # The __warningregistry__'s need to be in a pristine state for tests
         # to work properly.
-        for v in sys.modules.values():
+        for v in list(sys.modules.values()):
             if getattr(v, '__warningregistry__', None):
                 v.__warningregistry__ = {}
         self.warnings_manager = warnings.catch_warnings(record=True)
index 45e7e4c..caf1590 100644 (file)
@@ -59,6 +59,7 @@ class TextTestResult(result.TestResult):
         super(TextTestResult, self).addSuccess(test)
         if self.showAll:
             self.stream.writeln("ok")
+            self.stream.flush()
         elif self.dots:
             self.stream.write('.')
             self.stream.flush()
@@ -67,6 +68,7 @@ class TextTestResult(result.TestResult):
         super(TextTestResult, self).addError(test, err)
         if self.showAll:
             self.stream.writeln("ERROR")
+            self.stream.flush()
         elif self.dots:
             self.stream.write('E')
             self.stream.flush()
@@ -75,6 +77,7 @@ class TextTestResult(result.TestResult):
         super(TextTestResult, self).addFailure(test, err)
         if self.showAll:
             self.stream.writeln("FAIL")
+            self.stream.flush()
         elif self.dots:
             self.stream.write('F')
             self.stream.flush()
@@ -83,6 +86,7 @@ class TextTestResult(result.TestResult):
         super(TextTestResult, self).addSkip(test, reason)
         if self.showAll:
             self.stream.writeln("skipped {0!r}".format(reason))
+            self.stream.flush()
         elif self.dots:
             self.stream.write("s")
             self.stream.flush()
@@ -91,6 +95,7 @@ class TextTestResult(result.TestResult):
         super(TextTestResult, self).addExpectedFailure(test, err)
         if self.showAll:
             self.stream.writeln("expected failure")
+            self.stream.flush()
         elif self.dots:
             self.stream.write("x")
             self.stream.flush()
@@ -99,6 +104,7 @@ class TextTestResult(result.TestResult):
         super(TextTestResult, self).addUnexpectedSuccess(test)
         if self.showAll:
             self.stream.writeln("unexpected success")
+            self.stream.flush()
         elif self.dots:
             self.stream.write("u")
             self.stream.flush()
@@ -106,6 +112,7 @@ class TextTestResult(result.TestResult):
     def printErrors(self):
         if self.dots or self.showAll:
             self.stream.writeln()
+            self.stream.flush()
         self.printErrorList('ERROR', self.errors)
         self.printErrorList('FAIL', self.failures)
 
@@ -115,6 +122,7 @@ class TextTestResult(result.TestResult):
             self.stream.writeln("%s: %s" % (flavour,self.getDescription(test)))
             self.stream.writeln(self.separator2)
             self.stream.writeln("%s" % err)
+            self.stream.flush()
 
 
 class TextTestRunner(object):
@@ -218,4 +226,5 @@ class TextTestRunner(object):
             self.stream.writeln(" (%s)" % (", ".join(infos),))
         else:
             self.stream.write("\n")
+        self.stream.flush()
         return result
index 590dd74..0ce23dd 100644 (file)
@@ -8,6 +8,7 @@ import logging
 import warnings
 import weakref
 import inspect
+import types
 
 from copy import deepcopy
 from test import support
@@ -610,6 +611,8 @@ class Test_TestCase(unittest.TestCase, TestEquality, TestHashing):
                  'Tests shortDescription() for a method with a longer '
                  'docstring.')
 
+    @unittest.skipIf(sys.flags.optimize >= 2,
+                     "Docstrings are omitted with -O2 and above")
     def testShortDescriptionWhitespaceTrimming(self):
         """
             Tests shortDescription() whitespace is trimmed, so that the first
@@ -1350,6 +1353,20 @@ test case
             pass
         self.assertRaises(TypeError, self.assertWarnsRegex, MyWarn, lambda: True)
 
+    def testAssertWarnsModifySysModules(self):
+        # bpo-29620: handle modified sys.modules during iteration
+        class Foo(types.ModuleType):
+            @property
+            def __warningregistry__(self):
+                sys.modules['@bar@'] = 'bar'
+
+        sys.modules['@foo@'] = Foo('foo')
+        try:
+            self.assertWarns(UserWarning, warnings.warn, 'expected')
+        finally:
+            del sys.modules['@foo@']
+            del sys.modules['@bar@']
+
     def testAssertRaisesRegexMismatch(self):
         def Stub():
             raise Exception('Unexpected')
index eef82ff..4746d71 100644 (file)
@@ -6,6 +6,7 @@ import subprocess
 from test import support
 import unittest
 import unittest.test
+from .test_result import BufferedWriter
 
 
 class Test_TestProgram(unittest.TestCase):
@@ -57,9 +58,9 @@ class Test_TestProgram(unittest.TestCase):
 
     class FooBar(unittest.TestCase):
         def testPass(self):
-            assert True
+            pass
         def testFail(self):
-            assert False
+            raise AssertionError
 
     class FooBarLoader(unittest.TestLoader):
         """Test loader that returns a suite containing FooBar."""
@@ -104,30 +105,39 @@ class Test_TestProgram(unittest.TestCase):
                           program.testNames)
 
     def test_NonExit(self):
+        stream = BufferedWriter()
         program = unittest.main(exit=False,
                                 argv=["foobar"],
-                                testRunner=unittest.TextTestRunner(stream=io.StringIO()),
+                                testRunner=unittest.TextTestRunner(stream=stream),
                                 testLoader=self.FooBarLoader())
         self.assertTrue(hasattr(program, 'result'))
+        self.assertIn('\nFAIL: testFail ', stream.getvalue())
+        self.assertTrue(stream.getvalue().endswith('\n\nFAILED (failures=1)\n'))
 
 
     def test_Exit(self):
+        stream = BufferedWriter()
         self.assertRaises(
             SystemExit,
             unittest.main,
             argv=["foobar"],
-            testRunner=unittest.TextTestRunner(stream=io.StringIO()),
+            testRunner=unittest.TextTestRunner(stream=stream),
             exit=True,
             testLoader=self.FooBarLoader())
+        self.assertIn('\nFAIL: testFail ', stream.getvalue())
+        self.assertTrue(stream.getvalue().endswith('\n\nFAILED (failures=1)\n'))
 
 
     def test_ExitAsDefault(self):
+        stream = BufferedWriter()
         self.assertRaises(
             SystemExit,
             unittest.main,
             argv=["foobar"],
-            testRunner=unittest.TextTestRunner(stream=io.StringIO()),
+            testRunner=unittest.TextTestRunner(stream=stream),
             testLoader=self.FooBarLoader())
+        self.assertIn('\nFAIL: testFail ', stream.getvalue())
+        self.assertTrue(stream.getvalue().endswith('\n\nFAILED (failures=1)\n'))
 
 
 class InitialisableProgram(unittest.TestProgram):
index 0f7f3b7..2d29f79 100644 (file)
@@ -34,6 +34,22 @@ def bad_cleanup2():
     raise ValueError('bad cleanup2')
 
 
+class BufferedWriter:
+    def __init__(self):
+        self.result = ''
+        self.buffer = ''
+
+    def write(self, arg):
+        self.buffer += arg
+
+    def flush(self):
+        self.result += self.buffer
+        self.buffer = ''
+
+    def getvalue(self):
+        return self.result
+
+
 class Test_TestResult(unittest.TestCase):
     # Note: there are not separate tests for TestResult.wasSuccessful(),
     # TestResult.errors, TestResult.failures, TestResult.testsRun or
@@ -445,10 +461,13 @@ class Test_TestResult(unittest.TestCase):
         self.assertTrue(result.shouldStop)
 
     def testFailFastSetByRunner(self):
-        runner = unittest.TextTestRunner(stream=io.StringIO(), failfast=True)
+        stream = BufferedWriter()
+        runner = unittest.TextTestRunner(stream=stream, failfast=True)
         def test(result):
             self.assertTrue(result.failfast)
         result = runner.run(test)
+        stream.flush()
+        self.assertTrue(stream.getvalue().endswith('\n\nOK\n'))
 
 
 classDict = dict(unittest.TestResult.__dict__)
index d8c1515..233a5af 100644 (file)
@@ -1875,9 +1875,10 @@ class PatchTest(unittest.TestCase):
             self.assertEqual(foo(), 1)
         self.assertEqual(foo(), 0)
 
+        orig_doc = foo.__doc__
         with patch.object(foo, '__doc__', "FUN"):
             self.assertEqual(foo.__doc__, "FUN")
-        self.assertEqual(foo.__doc__, "TEST")
+        self.assertEqual(foo.__doc__, orig_doc)
 
         with patch.object(foo, '__module__', "testpatch2"):
             self.assertEqual(foo.__module__, "testpatch2")
index ce1f5d7..6f1af29 100644 (file)
@@ -281,8 +281,9 @@ class EnvBuilder:
                         os.path.normcase(f).startswith(('python', 'vcruntime'))
                     ]
             else:
-                suffixes = ['python.exe', 'python_d.exe', 'pythonw.exe',
-                            'pythonw_d.exe']
+                suffixes = {'python.exe', 'python_d.exe', 'pythonw.exe', 'pythonw_d.exe'}
+                base_exe = os.path.basename(context.env_exe)
+                suffixes.add(base_exe)
 
             for suffix in suffixes:
                 src = os.path.join(dirname, suffix)
diff --git a/Mac/BuildScript/0001-Darwin-platform-allows-to-build-on-releases-before-Y.patch b/Mac/BuildScript/0001-Darwin-platform-allows-to-build-on-releases-before-Y.patch
deleted file mode 100644 (file)
index 51ccdc2..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-From cef404f1e7a598166cbc2fd2e0048f7e2d752ad5 Mon Sep 17 00:00:00 2001
-From: David Carlier <devnexen@gmail.com>
-Date: Tue, 24 Aug 2021 22:40:14 +0100
-Subject: [PATCH] Darwin platform allows to build on releases before
- Yosemite/ios 8.
-
-issue #16407 #16408
----
- crypto/rand/rand_unix.c |  5 +----
- include/crypto/rand.h   | 10 ++++++++++
- 2 files changed, 11 insertions(+), 4 deletions(-)
-
-diff --git a/crypto/rand/rand_unix.c b/crypto/rand/rand_unix.c
-index 43f1069d15..0f4525106a 100644
---- a/crypto/rand/rand_unix.c
-+++ b/crypto/rand/rand_unix.c
-@@ -34,9 +34,6 @@
- #if defined(__OpenBSD__)
- # include <sys/param.h>
- #endif
--#if defined(__APPLE__)
--# include <CommonCrypto/CommonRandom.h>
--#endif
- #if defined(OPENSSL_SYS_UNIX) || defined(__DJGPP__)
- # include <sys/types.h>
-@@ -381,7 +378,7 @@ static ssize_t syscall_random(void *buf, size_t buflen)
-         if (errno != ENOSYS)
-             return -1;
-     }
--#  elif defined(__APPLE__)
-+#  elif defined(OPENSSL_APPLE_CRYPTO_RANDOM)
-     if (CCRandomGenerateBytes(buf, buflen) == kCCSuccess)
-           return (ssize_t)buflen;
-diff --git a/include/crypto/rand.h b/include/crypto/rand.h
-index 5350d3a931..674f840fd1 100644
---- a/include/crypto/rand.h
-+++ b/include/crypto/rand.h
-@@ -20,6 +20,16 @@
- # include <openssl/rand.h>
-+# if defined(__APPLE__) && !defined(OPENSSL_NO_APPLE_CRYPTO_RANDOM)
-+#  include <Availability.h>
-+#  if (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000) || \
-+     (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000)
-+#   define OPENSSL_APPLE_CRYPTO_RANDOM 1
-+#   include <CommonCrypto/CommonCryptoError.h>
-+#   include <CommonCrypto/CommonRandom.h>
-+#  endif
-+# endif
-+
- /* forward declaration */
- typedef struct rand_pool_st RAND_POOL;
--- 
-2.33.0
-
diff --git a/Mac/BuildScript/bpo-44828-filedialog-crash-monterey.patch b/Mac/BuildScript/bpo-44828-filedialog-crash-monterey.patch
deleted file mode 100644 (file)
index 0591492..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
---- tk8.6.11/macosx/tkMacOSXDialog.c   2020-12-31 01:46:07.000000000 +0000
-+++ tk8.6.11-patched/macosx/tkMacOSXDialog.c   2021-10-28 15:13:03.000000000 +0000
-@@ -221,7 +221,7 @@
-               returnCode: (NSModalResponse) returnCode
-              contextInfo: (void *) contextInfo
- {
--    FilePanelCallbackInfo *callbackInfo = contextInfo;
-+    FilePanelCallbackInfo *callbackInfo = (FilePanelCallbackInfo *)contextInfo;
-     if (returnCode == modalOK) {
-       Tcl_Obj *resultObj;
-@@ -266,7 +266,7 @@
- - (void) tkAlertDidEnd: (NSAlert *) alert returnCode: (NSInteger) returnCode
-       contextInfo: (void *) contextInfo
- {
--    AlertCallbackInfo *callbackInfo = contextInfo;
-+    AlertCallbackInfo *callbackInfo = (AlertCallbackInfo *)contextInfo;
-     if (returnCode >= NSAlertFirstButtonReturn) {
-       Tcl_Obj *resultObj = Tcl_NewStringObj(alertButtonStrings[
-@@ -350,49 +350,42 @@
-     FilePanelCallbackInfo *callbackInfo)
- {
-     NSInteger modalReturnCode;
-+    int OSVersion = [NSApp macOSVersion];
--    if (parent && ![parent attachedSheet]) {
--      [panel beginSheetModalForWindow:parent
--             completionHandler:^(NSModalResponse returnCode) {
--          [NSApp tkFilePanelDidEnd:panel
--                     returnCode:returnCode
--                     contextInfo:callbackInfo ];
--          }];
--
--      /*
--       * The sheet has been prepared, so now we have to run it as a modal
--       * window.  Using [NSApp runModalForWindow:] on macOS 10.15 or later
--       * generates warnings on stderr.  But using [NSOpenPanel runModal] or
--       * [NSSavePanel runModal] on 10.14 or earler does not cause the
--       * completion handler to run when the panel is closed.
--       */
-+    /*
-+     * Use a sheet if -parent is specified (unless there is already a sheet).
-+     */
--      if ([NSApp macOSVersion] > 101400) {
--          modalReturnCode = [panel runModal];
--      } else {
-+    if (parent && ![parent attachedSheet]) {
-+      if (OSVersion < 101500) {
-+          [panel beginSheetModalForWindow:parent
-+                        completionHandler:^(NSModalResponse returnCode) {
-+                  [NSApp tkFilePanelDidEnd:panel
-+                                returnCode:returnCode
-+                               contextInfo:callbackInfo ];
-+              }];
-           modalReturnCode = [NSApp runModalForWindow:panel];
--      }
--    } else {
--
--      /*
--       * For the standalone file dialog, completion handlers do not work
--       * at all on macOS 10.14 and earlier.
--       */
--
--      if ([NSApp macOSVersion] > 101400) {
--          [panel beginWithCompletionHandler:^(NSModalResponse returnCode) {
-+      } else if (OSVersion < 110000) {
-+          [panel beginSheetModalForWindow:parent
-+                        completionHandler:^(NSModalResponse returnCode) {
-                   [NSApp tkFilePanelDidEnd:panel
--                                returnCode:returnCode
--                               contextInfo:callbackInfo ];
--          }];
-+                                returnCode:returnCode
-+                               contextInfo:callbackInfo ];
-+              }];
-           modalReturnCode = [panel runModal];
-       } else {
-+          [parent beginSheet: panel completionHandler:nil];
-           modalReturnCode = [panel runModal];
-           [NSApp tkFilePanelDidEnd:panel
--                        returnCode:modalReturnCode
--                       contextInfo:callbackInfo ];
--          [panel close];
-+                        returnCode:modalReturnCode
-+                       contextInfo:callbackInfo ];
-+              [parent endSheet:panel];
-       }
-+    } else {
-+      modalReturnCode = [panel runModal];
-+      [NSApp tkFilePanelDidEnd:panel
-+                    returnCode:modalReturnCode
-+                   contextInfo:callbackInfo ];
-     }
-     return callbackInfo->cmdObj ? modalOther : modalReturnCode;
- }
-@@ -422,7 +414,7 @@
-     Tcl_Obj *const objv[])    /* Argument objects. */
- {
-     int result = TCL_ERROR;
--    Tk_Window parent, tkwin = clientData;
-+    Tk_Window parent, tkwin = (Tk_Window)clientData;
-     const char *title = NULL;
-     int i;
-     NSColor *color = nil, *initialColor = nil;
-@@ -677,7 +669,7 @@
-     int objc,                 /* Number of arguments. */
-     Tcl_Obj *const objv[])    /* Argument objects. */
- {
--    Tk_Window tkwin = clientData;
-+    Tk_Window tkwin = (Tk_Window)clientData;
-     char *str;
-     int i, result = TCL_ERROR, haveParentOption = 0;
-     int index, len, multiple = 0;
-@@ -1679,10 +1671,10 @@
-     if (!fontchooserInterp) {
-       return;
-     }
--    fcdPtr = Tcl_GetAssocData(fontchooserInterp, "::tk::fontchooser", NULL);
-+    fcdPtr = (FontchooserData *)Tcl_GetAssocData(fontchooserInterp, "::tk::fontchooser", NULL);
-     switch (kind) {
-     case FontchooserClosed:
--      if (fcdPtr->parent != None) {
-+      if (fcdPtr->parent != NULL) {
-           TkSendVirtualEvent(fcdPtr->parent, "TkFontchooserVisibility", NULL);
-           fontchooserInterp = NULL;
-       }
-@@ -1738,7 +1730,7 @@
-     switch(optionIndex) {
-     case FontchooserParent:
--      if (fcdPtr->parent != None) {
-+      if (fcdPtr->parent != NULL) {
-           resObj = Tcl_NewStringObj(
-                   ((TkWindow *)fcdPtr->parent)->pathName, -1);
-       } else {
-@@ -1801,7 +1793,7 @@
-     Tcl_Obj *const objv[])
- {
-     Tk_Window tkwin = (Tk_Window)clientData;
--    FontchooserData *fcdPtr = Tcl_GetAssocData(interp, "::tk::fontchooser",
-+    FontchooserData *fcdPtr = (FontchooserData *)Tcl_GetAssocData(interp, "::tk::fontchooser",
-           NULL);
-     int i, r = TCL_OK;
-@@ -1858,7 +1850,7 @@
-           Tk_Window parent = Tk_NameToWindow(interp,
-                   Tcl_GetString(objv[i+1]), tkwin);
--          if (parent == None) {
-+          if (parent == NULL) {
-               return TCL_ERROR;
-           }
-           if (fcdPtr->parent) {
-@@ -1885,7 +1877,7 @@
-               fcdPtr->titleObj = NULL;
-           }
-           break;
--      case FontchooserFont:
-+      case FontchooserFont: {
-           Tcl_GetStringFromObj(objv[i+1], &len);
-           if (len) {
-               Tk_Font f = Tk_AllocFontFromObj(interp, tkwin, objv[i+1]);
-@@ -1919,6 +1911,7 @@
-                       "TkFontchooserFontChanged", NULL);
-           }
-           break;
-+      }
-       case FontchooserCmd:
-           if (fcdPtr->cmdObj) {
-               Tcl_DecrRefCount(fcdPtr->cmdObj);
-@@ -1964,10 +1957,10 @@
-     TCL_UNUSED(int),
-     TCL_UNUSED(Tcl_Obj *const *))
- {
--    FontchooserData *fcdPtr = Tcl_GetAssocData(interp, "::tk::fontchooser",
-+    FontchooserData *fcdPtr = (FontchooserData *)Tcl_GetAssocData(interp, "::tk::fontchooser",
-           NULL);
--    if (fcdPtr->parent == None) {
-+    if (fcdPtr->parent == NULL) {
-       fcdPtr->parent = (Tk_Window)clientData;
-       Tk_CreateEventHandler(fcdPtr->parent, StructureNotifyMask,
-               FontchooserParentEventHandler, fcdPtr);
-@@ -2042,7 +2035,7 @@
-     ClientData clientData,
-     XEvent *eventPtr)
- {
--    FontchooserData *fcdPtr = clientData;
-+    FontchooserData *fcdPtr = (FontchooserData *)clientData;
-     if (eventPtr->type == DestroyNotify) {
-       Tk_DeleteEventHandler(fcdPtr->parent, StructureNotifyMask,
-@@ -2074,7 +2067,7 @@
-     ClientData clientData,
-     Tcl_Interp *interp)
- {
--    FontchooserData *fcdPtr = clientData;
-+    FontchooserData *fcdPtr = (FontchooserData *)clientData;
-     if (fcdPtr->titleObj) {
-       Tcl_DecrRefCount(fcdPtr->titleObj);
index 10112fe..3f5acfd 100755 (executable)
@@ -244,10 +244,9 @@ def library_recipes():
 
     result.extend([
           dict(
-              name="OpenSSL 1.1.1l",
-              url="https://www.openssl.org/source/openssl-1.1.1l.tar.gz",
-              checksum='ac0d4387f3ba0ad741b0580dd45f6ff3',
-              patches=['0001-Darwin-platform-allows-to-build-on-releases-before-Y.patch'],
+              name="OpenSSL 1.1.1m",
+              url="https://www.openssl.org/source/openssl-1.1.1m.tar.gz",
+              checksum='8ec70f665c145c3103f6e330f538a9db',
               buildrecipe=build_universal_openssl,
               configure=None,
               install=None,
@@ -263,11 +262,11 @@ def library_recipes():
             tk_patches = ['tk868_on_10_8_10_9.patch']
 
         else:
-            tcl_tk_ver='8.6.11'
-            tcl_checksum='8a4c004f48984a03a7747e9ba06e4da4'
+            tcl_tk_ver='8.6.12'
+            tcl_checksum='87ea890821d2221f2ab5157bc5eb885f'
 
-            tk_checksum='c7ee71a2d05bba78dfffd76528dc17c6'
-            tk_patches = ['bpo-44828-filedialog-crash-monterey.patch']
+            tk_checksum='1d6dcf6120356e3d211e056dff5e462a'
+            tk_patches = [ ]
 
 
         result.extend([
index f6b5cfe..d197c77 100644 (file)
@@ -36,7 +36,7 @@
        <key>CFBundleExecutable</key>
        <string>IDLE</string>
        <key>CFBundleGetInfoString</key>
-       <string>%version%, © 2001-2021 Python Software Foundation</string>
+       <string>%version%, © 2001-2022 Python Software Foundation</string>
        <key>CFBundleIconFile</key>
        <string>IDLE.icns</string>
        <key>CFBundleIdentifier</key>
index 3d8bc3e..dec0a2e 100644 (file)
@@ -3,7 +3,7 @@
 <plist version="1.0">
 <dict>
        <key>CFBundleDevelopmentRegion</key>
-       <string>English</string>
+       <string>en</string>
        <key>CFBundleDocumentTypes</key>
        <array>
                <dict>
        </array>
        <key>CFBundleExecutable</key>
        <string>Python Launcher</string>
+       <key>NSHumanReadableCopyright</key>
+       <string>Copyright © 2001-2022 Python Software Foundation</string>
        <key>CFBundleGetInfoString</key>
-       <string>%VERSION%, © 2001-2021 Python Software Foundation</string>
+       <string>%VERSION%, © 2001-2022 Python Software Foundation</string>
        <key>CFBundleIconFile</key>
        <string>PythonLauncher.icns</string>
        <key>CFBundleIdentifier</key>
@@ -61,5 +63,7 @@
        <string>MainMenu</string>
        <key>NSPrincipalClass</key>
        <string>NSApplication</string>
+       <key>NSAppleEventsUsageDescription</key>
+       <string>Python Launcher uses Apple events to launch your Python script in a Terminal window.</string>
 </dict>
 </plist>
index cbb783b..f07326b 100644 (file)
@@ -19,7 +19,7 @@ doscript(const char *command)
     AEDesc desc;
     OSStatus err;
 
-    [[NSWorkspace sharedWorkspace] launchApplication:@"/Applications/Utilities/Terminal.app/"];
+    [[NSWorkspace sharedWorkspace] launchApplication:@"Terminal.app"];
 
     // Build event
     err = AEBuildAppleEvent(kAECoreSuite, kAEDoScript,
index 2c80133..84843b7 100644 (file)
@@ -37,7 +37,7 @@
        <key>CFBundleInfoDictionaryVersion</key>
        <string>6.0</string>
        <key>CFBundleLongVersionString</key>
-       <string>%version%, (c) 2001-2021 Python Software Foundation.</string>
+       <string>%version%, (c) 2001-2022 Python Software Foundation.</string>
        <key>CFBundleName</key>
        <string>Python</string>
        <key>CFBundlePackageType</key>
index 11230fa..42b1ec6 100644 (file)
@@ -1946,6 +1946,12 @@ funny:
 patchcheck: @DEF_MAKE_RULE@
        $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/patchcheck.py
 
+.PHONY: update-config
+update-config:
+       curl -sL -o config.guess 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD'
+       curl -sL -o config.sub 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD'
+       chmod +x config.guess config.sub
+
 # Dependencies
 
 Python/thread.o: @THREADHEADERS@ $(srcdir)/Python/condvar.h
index 9cebf20..8ba8f2a 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -2,6 +2,226 @@
 Python News
 +++++++++++
 
+What's New in Python 3.9.10 final?
+==================================
+
+*Release date: 2022-01-13*
+
+Core and Builtins
+-----------------
+
+- bpo-46070: :c:func:`Py_EndInterpreter` now explicitly untracks all objects
+  currently tracked by the GC. Previously, if an object was used later by
+  another interpreter, calling :c:func:`PyObject_GC_UnTrack` on the object
+  crashed if the previous or the next object of the :c:type:`PyGC_Head`
+  structure became a dangling pointer. Patch by Victor Stinner.
+
+- bpo-46085: Fix iterator cache mechanism of :class:`OrderedDict`.
+
+- bpo-46110: Add a maximum recursion check to the PEG parser to avoid stack
+  overflow. Patch by Pablo Galindo
+
+- bpo-46000: Improve compatibility of the :mod:`curses` module with NetBSD
+  curses.
+
+- bpo-45614: Fix :mod:`traceback` display for exceptions with invalid module
+  name.
+
+- bpo-45806: Re-introduced fix that allows recovery from stack overflow
+  without crashing the interpreter.  The original fix as part of
+  :issue:`42500` was reverted (see release notes for Python 3.9.4) since it
+  introduced an ABI change in a bugfix release which is not allowed.  The
+  new fix doesn't introduce any ABI changes.  Patch by Mark Shannon.
+
+- bpo-45822: Fixed a bug in the parser that was causing it to not respect
+  :pep:`263` coding cookies when no flags are provided. Patch by Pablo
+  Galindo
+
+- bpo-45820: Fix a segfault when the parser fails without reading any input.
+  Patch by Pablo Galindo
+
+- bpo-42540: Fix crash when :func:`os.fork` is called with an active
+  non-default memory allocator.
+
+Library
+-------
+
+- bpo-40479: Fix :mod:`hashlib` *usedforsecurity* option to work correctly
+  with OpenSSL 3.0.0 in FIPS mode.
+
+- bpo-46070: Fix possible segfault when importing the :mod:`asyncio` module
+  from different sub-interpreters in parallel. Patch by Erlend E. Aasland.
+
+- bpo-46278: Reflect ``context`` argument in ``AbstractEventLoop.call_*()``
+  methods. Loop implementations already support it.
+
+- bpo-46239: Improve error message when importing
+  :mod:`asyncio.windows_events` on non-Windows.
+
+- bpo-20369: :func:`concurrent.futures.wait` no longer blocks forever when
+  given duplicate Futures. Patch by Kumar Aditya.
+
+- bpo-46105: Honor spec when generating requirement specs with urls and
+  extras (importlib_metadata 4.8.3).
+
+- bpo-26952: :mod:`argparse` raises :exc:`ValueError` with clear message
+  when trying to render usage for an empty mutually-exclusive group.
+  Previously it raised a cryptic :exc:`IndexError`.
+
+- bpo-27718: Fix help for the :mod:`signal` module. Some functions (e.g.
+  ``signal()`` and ``getsignal()``) were omitted.
+
+- bpo-46032: The ``registry()`` method of :func:`functools.singledispatch`
+  functions checks now the first argument or the first parameter annotation
+  and raises a TypeError if it is not supported. Previously unsupported
+  "types" were ignored (e.g. ``typing.List[int]``) or caused an error at
+  calling time (e.g. ``list[int]``).
+
+- bpo-46018: Ensure that :func:`math.expm1` does not raise on underflow.
+
+- bpo-27946: Fix possible crash when getting an attribute of
+  class:`xml.etree.ElementTree.Element` simultaneously with replacing the
+  ``attrib`` dict.
+
+- bpo-13236: :class:`unittest.TextTestResult` and
+  :class:`unittest.TextTestRunner` flush now the output stream more often.
+
+- bpo-37658: Fix issue when on certain conditions ``asyncio.wait_for()`` may
+  allow a coroutine to complete successfully, but fail to return the result,
+  potentially causing memory leaks or other issues.
+
+- bpo-45831: :mod:`faulthandler` can now write ASCII-only strings (like
+  filenames and function names) with a single write() syscall when dumping a
+  traceback. It reduces the risk of getting an unreadable dump when two
+  threads or two processes dump a traceback to the same file (like stderr)
+  at the same time. Patch by Victor Stinner.
+
+- bpo-41735: Fix thread lock in ``zlib.Decompress.flush()`` method before
+  ``PyObject_GetBuffer``.
+
+- bpo-45664: Fix :func:`types.resolve_bases` and :func:`types.new_class` for
+  :class:`types.GenericAlias` instance as a base.
+
+- bpo-45663: Fix :func:`dataclasses.is_dataclass` for dataclasses which are
+  subclasses of :class:`types.GenericAlias`.
+
+- bpo-45662: Fix the repr of :data:`dataclasses.InitVar` with a type alias
+  to the built-in class, e.g. ``InitVar[list[int]]``.
+
+- bpo-43498: Avoid a possible *"RuntimeError: dictionary changed size during
+  iteration"* when adjusting the process count of
+  :class:`ProcessPoolExecutor`.
+
+- bpo-29620: :func:`~unittest.TestCase.assertWarns` no longer raises a
+  ``RuntimeException`` when accessing a module's ``__warningregistry__``
+  causes importation of a new module, or when a new module is imported in
+  another thread. Patch by Kernc.
+
+Documentation
+-------------
+
+- bpo-19737: Update the documentation for the :func:`globals` function.
+
+- bpo-45840: Improve cross-references in the documentation for the data
+  model.
+
+- bpo-45788: Link doc for sys.prefix to sysconfig doc on installation paths.
+
+- bpo-25381: In the extending chapter of the extending doc, update a
+  paragraph about the global variables containing exception information.
+
+- bpo-43905: Expanded :func:`~dataclasses.astuple` and
+  :func:`~dataclasses.asdict` docs, warning about deepcopy being applied and
+  providing a workaround.
+
+- bpo-41028: Language and version switchers, previously maintained in every
+  cpython branches, are now handled by docsbuild-script.
+
+Tests
+-----
+
+- bpo-46205: Fix hang in runtest_mp due to race condition
+
+- bpo-46263: Fix test_capi on FreeBSD 14-dev: instruct jemalloc to not fill
+  freed memory with junk byte.
+
+- bpo-46150: Now ``fakename`` in
+  ``test_pathlib.PosixPathTest.test_expanduser`` is checked to be
+  non-existent.
+
+- bpo-46129: Rewrite ``asyncio.locks`` tests with
+  :class:`unittest.IsolatedAsyncioTestCase` usage.
+
+- bpo-23819: Fixed :mod:`asyncio` tests in python optimized mode. Patch by
+  Kumar Aditya.
+
+- bpo-46114: Fix test case for OpenSSL 3.0.1 version. OpenSSL 3.0 uses
+  ``0xMNN00PP0L``.
+
+- bpo-19460: Add new Test for
+  :class:`email.mime.nonmultipart.MIMENonMultipart`.
+
+- bpo-45835: Fix race condition in test_queue tests with multiple "feeder"
+  threads.
+
+Build
+-----
+
+- bpo-46263: ``configure`` no longer sets ``MULTIARCH`` on FreeBSD
+  platforms.
+
+- bpo-46106: Updated OpenSSL to 1.1.1m in Windows builds, macOS installer
+  builds, and CI. Patch by Kumar Aditya.
+
+- bpo-44035: CI now verifies that autoconf files have been regenerated with
+  a current and unpatched autoconf package.
+
+- bpo-33393: Update ``config.guess`` to 2021-06-03 and ``config.sub`` to
+  2021-08-14. ``Makefile`` now has an ``update-config`` target to make
+  updating more convenient.
+
+- bpo-45866: ``make regen-all`` now produces the same output when run from a
+  directory other than the source tree: when building Python out of the
+  source tree. pegen now strips directory of the "generated by pygen from
+  <FILENAME>" header Patch by Victor Stinner.
+
+- bpo-41498: Python now compiles on platforms without ``sigset_t``. Several
+  functions in :mod:`signal` are not available when ``sigset_t`` is missing.
+
+  Based on patch by Roman Yurchak for pyodide.
+
+- bpo-45881: ``setup.py`` now uses ``CC`` from environment first to discover
+  multiarch and cross compile paths.
+
+Windows
+-------
+
+- bpo-45901: When installed through the Microsoft Store and set as the
+  default app for :file:`*.py` files, command line arguments will now be
+  passed to Python when invoking a script without explicitly launching
+  Python (that is, ``script.py args`` rather than ``python script.py
+  args``).
+
+macOS
+-----
+
+- bpo-40477: The Python Launcher app for macOS now properly launches scripts
+  and, if necessary, the Terminal app when running on recent macOS releases.
+
+- bpo-45732: Update python.org macOS installer to use Tcl/Tk 8.6.12.
+
+Tools/Demos
+-----------
+
+- bpo-45838: Fix line number calculation when debugging Python with GDB.
+
+C API
+-----
+
+- bpo-39026: Fix Python.h to build C extensions with Xcode: remove a
+  relative include from ``Include/cpython/pystate.h``.
+
+
 What's New in Python 3.9.9 final?
 =================================
 
index b483b2e..ee9bfdf 100644 (file)
@@ -12,12 +12,9 @@ can be used to force the usage of the malloc() allocator of the C library.
 If you don't want to read about the details of using Valgrind, there
 are still two things you must do to suppress the warnings.  First,
 you must use a suppressions file.  One is supplied in
-Misc/valgrind-python.supp.  Second, you must do one of the following:
-
-  * Uncomment Py_USING_MEMORY_DEBUGGER in Objects/obmalloc.c,
-    then rebuild Python
-  * Uncomment the lines in Misc/valgrind-python.supp that
-    suppress the warnings for PyObject_Free and PyObject_Realloc
+Misc/valgrind-python.supp.  Second, you must uncomment the lines in 
+Misc/valgrind-python.supp that suppress the warnings for PyObject_Free and
+PyObject_Realloc.
 
 If you want to use Valgrind more effectively and catch even more
 memory leaks, you will need to configure python --without-pymalloc.
index 4457d7b..a1421cf 100644 (file)
@@ -3328,17 +3328,14 @@ static int
 module_init(void)
 {
     PyObject *module = NULL;
+    if (module_initialized) {
+        return 0;
+    }
 
     asyncio_mod = PyImport_ImportModule("asyncio");
     if (asyncio_mod == NULL) {
         goto fail;
     }
-    if (module_initialized != 0) {
-        return 0;
-    }
-    else {
-        module_initialized = 1;
-    }
 
     current_tasks = PyDict_New();
     if (current_tasks == NULL) {
@@ -3399,6 +3396,7 @@ module_init(void)
         goto fail;
     }
 
+    module_initialized = 1;
     Py_DECREF(module);
     return 0;
 
index a32cc4b..f95677c 100644 (file)
@@ -1077,8 +1077,8 @@ PyCursesWindow_ChgAt(PyCursesWindowObject *self, PyObject *args)
         return NULL;
     }
 
-    color = (short)((attr >> 8) & 0xff);
-    attr = attr - (color << 8);
+    color = (short) PAIR_NUMBER(attr);
+    attr = attr & A_ATTRIBUTES;
 
     if (use_xy) {
         rtn = mvwchgat(self->win,y,x,num,attr,color,NULL);
index 67a00a3..d9c2a23 100644 (file)
@@ -1393,22 +1393,19 @@ _elementtree_Element_get_impl(ElementObject *self, PyObject *key,
                               PyObject *default_value)
 /*[clinic end generated code: output=523c614142595d75 input=ee153bbf8cdb246e]*/
 {
-    PyObject* value;
-
-    if (!self->extra || !self->extra->attrib)
-        value = default_value;
-    else {
-        value = PyDict_GetItemWithError(self->extra->attrib, key);
-        if (!value) {
-            if (PyErr_Occurred()) {
-                return NULL;
-            }
-            value = default_value;
+    if (self->extra && self->extra->attrib) {
+        PyObject *attrib = self->extra->attrib;
+        Py_INCREF(attrib);
+        PyObject *value = PyDict_GetItemWithError(attrib, key);
+        Py_XINCREF(value);
+        Py_DECREF(attrib);
+        if (value != NULL || PyErr_Occurred()) {
+            return value;
         }
     }
 
-    Py_INCREF(value);
-    return value;
+    Py_INCREF(default_value);
+    return default_value;
 }
 
 static PyObject *
index ff3a1ae..a488945 100644 (file)
 #endif
 #define OPENSSL_NO_DEPRECATED 1
 
+#ifndef Py_BUILD_CORE_BUILTIN
+#  define Py_BUILD_CORE_MODULE 1
+#endif
+
 #define PY_SSIZE_T_CLEAN
 
 #include "Python.h"
+#include "pycore_hashtable.h"
 #include "hashlib.h"
 #include "pystrhex.h"
 
@@ -84,6 +89,168 @@ HMAC_CTX_get_md(const HMAC_CTX *ctx)
 #define PY_OPENSSL_HAS_BLAKE2 1
 #endif
 
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+#define PY_EVP_MD EVP_MD
+#define PY_EVP_MD_fetch(algorithm, properties) EVP_MD_fetch(NULL, algorithm, properties)
+#define PY_EVP_MD_up_ref(md) EVP_MD_up_ref(md)
+#define PY_EVP_MD_free(md) EVP_MD_free(md)
+#else
+#define PY_EVP_MD const EVP_MD
+#define PY_EVP_MD_fetch(algorithm, properties) EVP_get_digestbyname(algorithm)
+#define PY_EVP_MD_up_ref(md) do {} while(0)
+#define PY_EVP_MD_free(md) do {} while(0)
+#endif
+
+/* hash alias map and fast lookup
+ *
+ * Map between Python's preferred names and OpenSSL internal names. Maintain
+ * cache of fetched EVP MD objects. The EVP_get_digestbyname() and
+ * EVP_MD_fetch() API calls have a performance impact.
+ *
+ * The py_hashentry_t items are stored in a _Py_hashtable_t with py_name and
+ * py_alias as keys.
+ */
+
+enum Py_hash_type {
+    Py_ht_evp,            // usedforsecurity=True / default
+    Py_ht_evp_nosecurity, // usedforsecurity=False
+    Py_ht_mac,            // HMAC
+    Py_ht_pbkdf2,         // PKBDF2
+};
+
+typedef struct {
+    const char *py_name;
+    const char *py_alias;
+    const char *ossl_name;
+    int ossl_nid;
+    int refcnt;
+    PY_EVP_MD *evp;
+    PY_EVP_MD *evp_nosecurity;
+} py_hashentry_t;
+
+#define Py_hash_md5 "md5"
+#define Py_hash_sha1 "sha1"
+#define Py_hash_sha224 "sha224"
+#define Py_hash_sha256 "sha256"
+#define Py_hash_sha384 "sha384"
+#define Py_hash_sha512 "sha512"
+#define Py_hash_sha512_224 "sha512_224"
+#define Py_hash_sha512_256 "sha512_256"
+#define Py_hash_sha3_224 "sha3_224"
+#define Py_hash_sha3_256 "sha3_256"
+#define Py_hash_sha3_384 "sha3_384"
+#define Py_hash_sha3_512 "sha3_512"
+#define Py_hash_shake_128 "shake_128"
+#define Py_hash_shake_256 "shake_256"
+#define Py_hash_blake2s "blake2s"
+#define Py_hash_blake2b "blake2b"
+
+#define PY_HASH_ENTRY(py_name, py_alias, ossl_name, ossl_nid) \
+    {py_name, py_alias, ossl_name, ossl_nid, 0, NULL, NULL}
+
+static const py_hashentry_t py_hashes[] = {
+    /* md5 */
+    PY_HASH_ENTRY(Py_hash_md5, "MD5", SN_md5, NID_md5),
+    /* sha1 */
+    PY_HASH_ENTRY(Py_hash_sha1, "SHA1", SN_sha1, NID_sha1),
+    /* sha2 family */
+    PY_HASH_ENTRY(Py_hash_sha224, "SHA224", SN_sha224, NID_sha224),
+    PY_HASH_ENTRY(Py_hash_sha256, "SHA256", SN_sha256, NID_sha256),
+    PY_HASH_ENTRY(Py_hash_sha384, "SHA384", SN_sha384, NID_sha384),
+    PY_HASH_ENTRY(Py_hash_sha512, "SHA512", SN_sha512, NID_sha512),
+    /* truncated sha2 */
+#ifdef NID_sha512_224
+    PY_HASH_ENTRY(Py_hash_sha512_224, "SHA512_224", SN_sha512_224, NID_sha512_224),
+    PY_HASH_ENTRY(Py_hash_sha512_256, "SHA512_256", SN_sha512_256, NID_sha512_256),
+#endif
+    /* sha3 */
+#ifdef PY_OPENSSL_HAS_SHA3
+    PY_HASH_ENTRY(Py_hash_sha3_224, NULL, SN_sha3_224, NID_sha3_224),
+    PY_HASH_ENTRY(Py_hash_sha3_256, NULL, SN_sha3_256, NID_sha3_256),
+    PY_HASH_ENTRY(Py_hash_sha3_384, NULL, SN_sha3_384, NID_sha3_384),
+    PY_HASH_ENTRY(Py_hash_sha3_512, NULL, SN_sha3_512, NID_sha3_512),
+#endif
+    /* sha3 shake */
+#ifdef PY_OPENSSL_HAS_SHAKE
+    PY_HASH_ENTRY(Py_hash_shake_128, NULL, SN_shake128, NID_shake128),
+    PY_HASH_ENTRY(Py_hash_shake_256, NULL, SN_shake256, NID_shake256),
+#endif
+    /* blake2 digest */
+#ifdef PY_OPENSSL_HAS_BLAKE2
+    PY_HASH_ENTRY(Py_hash_blake2s, "blake2s256", SN_blake2s256, NID_blake2s256),
+    PY_HASH_ENTRY(Py_hash_blake2b, "blake2b512", SN_blake2b512, NID_blake2b512),
+#endif
+    PY_HASH_ENTRY(NULL, NULL, NULL, 0),
+};
+
+static Py_uhash_t
+py_hashentry_t_hash_name(const void *key) {
+    return _Py_HashBytes(key, strlen((const char *)key));
+}
+
+static int
+py_hashentry_t_compare_name(const void *key1, const void *key2) {
+    return strcmp((const char *)key1, (const char *)key2) == 0;
+}
+
+static void
+py_hashentry_t_destroy_value(void *entry) {
+    py_hashentry_t *h = (py_hashentry_t *)entry;
+    if (--(h->refcnt) == 0) {
+        if (h->evp != NULL) {
+            PY_EVP_MD_free(h->evp);
+            h->evp = NULL;
+        }
+        if (h->evp_nosecurity != NULL) {
+            PY_EVP_MD_free(h->evp_nosecurity);
+            h->evp_nosecurity = NULL;
+        }
+        PyMem_Free(entry);
+    }
+}
+
+static _Py_hashtable_t *
+py_hashentry_table_new(void) {
+    _Py_hashtable_t *ht = _Py_hashtable_new_full(
+        py_hashentry_t_hash_name,
+        py_hashentry_t_compare_name,
+        NULL,
+        py_hashentry_t_destroy_value,
+        NULL
+    );
+    if (ht == NULL) {
+        return NULL;
+    }
+
+    for (const py_hashentry_t *h = py_hashes; h->py_name != NULL; h++) {
+        py_hashentry_t *entry = (py_hashentry_t *)PyMem_Malloc(sizeof(py_hashentry_t));
+        if (entry == NULL) {
+            goto error;
+        }
+        memcpy(entry, h, sizeof(py_hashentry_t));
+
+        if (_Py_hashtable_set(ht, (const void*)entry->py_name, (void*)entry) < 0) {
+            PyMem_Free(entry);
+            goto error;
+        }
+        entry->refcnt = 1;
+
+        if (h->py_alias != NULL) {
+            if (_Py_hashtable_set(ht, (const void*)entry->py_alias, (void*)entry) < 0) {
+                PyMem_Free(entry);
+                goto error;
+            }
+            entry->refcnt++;
+        }
+    }
+
+    return ht;
+  error:
+    _Py_hashtable_destroy(ht);
+    return NULL;
+}
+
+/* Module state */
 static PyModuleDef _hashlibmodule;
 
 typedef struct {
@@ -92,6 +259,7 @@ typedef struct {
 #ifdef PY_OPENSSL_HAS_SHAKE
     PyTypeObject *EVPXOFtype;
 #endif
+    _Py_hashtable_t *hashtable;
 } _hashlibstate;
 
 static inline _hashlibstate*
@@ -126,16 +294,26 @@ class _hashlib.HMAC "HMACobject *" "((_hashlibstate *)PyModule_GetState(module))
 
 /* LCOV_EXCL_START */
 static PyObject *
-_setException(PyObject *exc)
+_setException(PyObject *exc, const char* altmsg, ...)
 {
-    unsigned long errcode;
+    unsigned long errcode = ERR_peek_last_error();
     const char *lib, *func, *reason;
+    va_list vargs;
 
-    errcode = ERR_peek_last_error();
+#ifdef HAVE_STDARG_PROTOTYPES
+    va_start(vargs, altmsg);
+#else
+    va_start(vargs);
+#endif
     if (!errcode) {
-        PyErr_SetString(exc, "unknown reasons");
+        if (altmsg == NULL) {
+            PyErr_SetString(exc, "no reason supplied");
+        } else {
+            PyErr_FormatV(exc, altmsg, vargs);
+        }
         return NULL;
     }
+    va_end(vargs);
     ERR_clear_error();
 
     lib = ERR_lib_error_string(errcode);
@@ -169,68 +347,15 @@ py_digest_name(const EVP_MD *md)
 {
     int nid = EVP_MD_nid(md);
     const char *name = NULL;
+    const py_hashentry_t *h;
 
-    /* Hard-coded names for well-known hashing algorithms.
-     * OpenSSL uses slightly different names algorithms like SHA3.
-     */
-    switch (nid) {
-    case NID_md5:
-        name = "md5";
-        break;
-    case NID_sha1:
-        name = "sha1";
-        break;
-    case NID_sha224:
-        name ="sha224";
-        break;
-    case NID_sha256:
-        name ="sha256";
-        break;
-    case NID_sha384:
-        name ="sha384";
-        break;
-    case NID_sha512:
-        name ="sha512";
-        break;
-#ifdef NID_sha512_224
-    case NID_sha512_224:
-        name ="sha512_224";
-        break;
-    case NID_sha512_256:
-        name ="sha512_256";
-        break;
-#endif
-#ifdef PY_OPENSSL_HAS_SHA3
-    case NID_sha3_224:
-        name ="sha3_224";
-        break;
-    case NID_sha3_256:
-        name ="sha3_256";
-        break;
-    case NID_sha3_384:
-        name ="sha3_384";
-        break;
-    case NID_sha3_512:
-        name ="sha3_512";
-        break;
-#endif
-#ifdef PY_OPENSSL_HAS_SHAKE
-    case NID_shake128:
-        name ="shake_128";
-        break;
-    case NID_shake256:
-        name ="shake_256";
-        break;
-#endif
-#ifdef PY_OPENSSL_HAS_BLAKE2
-    case NID_blake2s256:
-        name ="blake2s";
-        break;
-    case NID_blake2b512:
-        name ="blake2b";
-        break;
-#endif
-    default:
+    for (h = py_hashes; h->py_name != NULL; h++) {
+        if (h->ossl_nid == nid) {
+            name = h->py_name;
+            break;
+        }
+    }
+    if (name == NULL) {
         /* Ignore aliased names and only use long, lowercase name. The aliases
          * pollute the list and OpenSSL appears to have its own definition of
          * alias as the resulting list still contains duplicate and alternate
@@ -239,62 +364,58 @@ py_digest_name(const EVP_MD *md)
         name = OBJ_nid2ln(nid);
         if (name == NULL)
             name = OBJ_nid2sn(nid);
-        break;
     }
 
     return PyUnicode_FromString(name);
 }
 
-static const EVP_MD*
-py_digest_by_name(const char *name)
+/* Get EVP_MD by HID and purpose */
+static PY_EVP_MD*
+py_digest_by_name(PyObject *module, const char *name, enum Py_hash_type py_ht)
 {
-    const EVP_MD *digest = EVP_get_digestbyname(name);
+    PY_EVP_MD *digest = NULL;
+    _hashlibstate *state = get_hashlib_state(module);
+    py_hashentry_t *entry = (py_hashentry_t *)_Py_hashtable_get(
+        state->hashtable, (const void*)name
+    );
 
-    /* OpenSSL uses dash instead of underscore in names of some algorithms
-     * like SHA3 and SHAKE. Detect different spellings. */
-    if (digest == NULL) {
-        if (0) {}
-#ifdef NID_sha512_224
-        else if (!strcmp(name, "sha512_224") || !strcmp(name, "SHA512_224")) {
-            digest = EVP_sha512_224();
+    if (entry != NULL) {
+        switch (py_ht) {
+        case Py_ht_evp:
+        case Py_ht_mac:
+        case Py_ht_pbkdf2:
+            if (entry->evp == NULL) {
+                entry->evp = PY_EVP_MD_fetch(entry->ossl_name, NULL);
+            }
+            digest = entry->evp;
+            break;
+        case Py_ht_evp_nosecurity:
+            if (entry->evp_nosecurity == NULL) {
+                entry->evp_nosecurity = PY_EVP_MD_fetch(entry->ossl_name, "-fips");
+            }
+            digest = entry->evp_nosecurity;
+            break;
         }
-        else if (!strcmp(name, "sha512_256") || !strcmp(name, "SHA512_256")) {
-            digest = EVP_sha512_256();
-        }
-#endif
-#ifdef PY_OPENSSL_HAS_SHA3
-        /* could be sha3_ or shake_, Python never defined upper case */
-        else if (!strcmp(name, "sha3_224")) {
-            digest = EVP_sha3_224();
-        }
-        else if (!strcmp(name, "sha3_256")) {
-            digest = EVP_sha3_256();
-        }
-        else if (!strcmp(name, "sha3_384")) {
-            digest = EVP_sha3_384();
-        }
-        else if (!strcmp(name, "sha3_512")) {
-            digest = EVP_sha3_512();
-        }
-#endif
-#ifdef PY_OPENSSL_HAS_SHAKE
-        else if (!strcmp(name, "shake_128")) {
-            digest = EVP_shake128();
+        if (digest != NULL) {
+            PY_EVP_MD_up_ref(digest);
         }
-        else if (!strcmp(name, "shake_256")) {
-            digest = EVP_shake256();
-        }
-#endif
-#ifdef PY_OPENSSL_HAS_BLAKE2
-        else if (!strcmp(name, "blake2s256")) {
-            digest = EVP_blake2s256();
-        }
-        else if (!strcmp(name, "blake2b512")) {
-            digest = EVP_blake2b512();
+    } else {
+        // Fall back for looking up an unindexed OpenSSL specific name.
+        switch (py_ht) {
+        case Py_ht_evp:
+        case Py_ht_mac:
+        case Py_ht_pbkdf2:
+            digest = PY_EVP_MD_fetch(name, NULL);
+            break;
+        case Py_ht_evp_nosecurity:
+            digest = PY_EVP_MD_fetch(name, "-fips");
+            break;
         }
-#endif
     }
-
+    if (digest == NULL) {
+        _setException(PyExc_ValueError, "unsupported hash type %s", name);
+        return NULL;
+    }
     return digest;
 }
 
@@ -329,7 +450,7 @@ EVP_hash(EVPobject *self, const void *vp, Py_ssize_t len)
         else
             process = Py_SAFE_DOWNCAST(len, Py_ssize_t, unsigned int);
         if (!EVP_DigestUpdate(self->ctx, (const void*)cp, process)) {
-            _setException(PyExc_ValueError);
+            _setException(PyExc_ValueError, NULL);
             return -1;
         }
         len -= process;
@@ -380,7 +501,7 @@ EVP_copy_impl(EVPobject *self)
 
     if (!locked_EVP_MD_CTX_copy(newobj->ctx, self)) {
         Py_DECREF(newobj);
-        return _setException(PyExc_ValueError);
+        return _setException(PyExc_ValueError, NULL);
     }
     return (PyObject *)newobj;
 }
@@ -407,11 +528,11 @@ EVP_digest_impl(EVPobject *self)
     }
 
     if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) {
-        return _setException(PyExc_ValueError);
+        return _setException(PyExc_ValueError, NULL);
     }
     digest_size = EVP_MD_CTX_size(temp_ctx);
     if (!EVP_DigestFinal(temp_ctx, digest, NULL)) {
-        _setException(PyExc_ValueError);
+        _setException(PyExc_ValueError, NULL);
         return NULL;
     }
 
@@ -442,11 +563,11 @@ EVP_hexdigest_impl(EVPobject *self)
 
     /* Get the raw (binary) digest value */
     if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) {
-        return _setException(PyExc_ValueError);
+        return _setException(PyExc_ValueError, NULL);
     }
     digest_size = EVP_MD_CTX_size(temp_ctx);
     if (!EVP_DigestFinal(temp_ctx, digest, NULL)) {
-        _setException(PyExc_ValueError);
+        _setException(PyExc_ValueError, NULL);
         return NULL;
     }
 
@@ -623,14 +744,14 @@ EVPXOF_digest_impl(EVPobject *self, Py_ssize_t length)
     if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) {
         Py_DECREF(retval);
         EVP_MD_CTX_free(temp_ctx);
-        return _setException(PyExc_ValueError);
+        return _setException(PyExc_ValueError, NULL);
     }
     if (!EVP_DigestFinalXOF(temp_ctx,
                             (unsigned char*)PyBytes_AS_STRING(retval),
                             length)) {
         Py_DECREF(retval);
         EVP_MD_CTX_free(temp_ctx);
-        _setException(PyExc_ValueError);
+        _setException(PyExc_ValueError, NULL);
         return NULL;
     }
 
@@ -671,12 +792,12 @@ EVPXOF_hexdigest_impl(EVPobject *self, Py_ssize_t length)
     if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) {
         PyMem_Free(digest);
         EVP_MD_CTX_free(temp_ctx);
-        return _setException(PyExc_ValueError);
+        return _setException(PyExc_ValueError, NULL);
     }
     if (!EVP_DigestFinalXOF(temp_ctx, digest, length)) {
         PyMem_Free(digest);
         EVP_MD_CTX_free(temp_ctx);
-        _setException(PyExc_ValueError);
+        _setException(PyExc_ValueError, NULL);
         return NULL;
     }
 
@@ -745,55 +866,77 @@ static PyType_Spec EVPXOFtype_spec = {
 
 #endif
 
-static PyObject *
-EVPnew(PyObject *module, const EVP_MD *digest,
-       const unsigned char *cp, Py_ssize_t len, int usedforsecurity)
+static PyObject*
+py_evp_fromname(PyObject *module, const char *digestname, PyObject *data_obj,
+                int usedforsecurity)
 {
-    int result = 0;
-    EVPobject *self;
-    PyTypeObject *type = get_hashlib_state(module)->EVPtype;
+    Py_buffer view = { 0 };
+    PY_EVP_MD *digest = NULL;
+    PyTypeObject *type;
+    EVPobject *self = NULL;
 
-    if (!digest) {
-        PyErr_SetString(PyExc_ValueError, "unsupported hash type");
-        return NULL;
+    if (data_obj != NULL) {
+        GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view);
+    }
+
+    digest = py_digest_by_name(
+        module, digestname, usedforsecurity ? Py_ht_evp : Py_ht_evp_nosecurity
+    );
+    if (digest == NULL) {
+        goto exit;
     }
 
 #ifdef PY_OPENSSL_HAS_SHAKE
     if ((EVP_MD_flags(digest) & EVP_MD_FLAG_XOF) == EVP_MD_FLAG_XOF) {
         type = get_hashlib_state(module)->EVPXOFtype;
-    }
+    } else
 #endif
+    {
+        type = get_hashlib_state(module)->EVPtype;
+    }
 
-    if ((self = newEVPobject(type)) == NULL)
-        return NULL;
+    self = newEVPobject(type);
+    if (self == NULL) {
+        goto exit;
+    }
 
+#if defined(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW) && OPENSSL_VERSION_NUMBER < 0x30000000L
+    // In OpenSSL 1.1.1 the non FIPS allowed flag is context specific while
+    // in 3.0.0 it is a different EVP_MD provider.
     if (!usedforsecurity) {
-#ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
         EVP_MD_CTX_set_flags(self->ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
-#endif
     }
+#endif
 
-
-    if (!EVP_DigestInit_ex(self->ctx, digest, NULL)) {
-        _setException(PyExc_ValueError);
-        Py_DECREF(self);
-        return NULL;
+    int result = EVP_DigestInit_ex(self->ctx, digest, NULL);
+    if (!result) {
+        _setException(PyExc_ValueError, NULL);
+        Py_CLEAR(self);
+        goto exit;
     }
 
-    if (cp && len) {
-        if (len >= HASHLIB_GIL_MINSIZE) {
+    if (view.buf && view.len) {
+        if (view.len >= HASHLIB_GIL_MINSIZE) {
             Py_BEGIN_ALLOW_THREADS
-            result = EVP_hash(self, cp, len);
+            result = EVP_hash(self, view.buf, view.len);
             Py_END_ALLOW_THREADS
         } else {
-            result = EVP_hash(self, cp, len);
+            result = EVP_hash(self, view.buf, view.len);
         }
         if (result == -1) {
-            Py_DECREF(self);
-            return NULL;
+            Py_CLEAR(self);
+            goto exit;
         }
     }
 
+  exit:
+    if (data_obj != NULL) {
+        PyBuffer_Release(&view);
+    }
+    if (digest != NULL) {
+        PY_EVP_MD_free(digest);
+    }
+
     return (PyObject *)self;
 }
 
@@ -821,49 +964,14 @@ EVP_new_impl(PyObject *module, PyObject *name_obj, PyObject *data_obj,
              int usedforsecurity)
 /*[clinic end generated code: output=ddd5053f92dffe90 input=c24554d0337be1b0]*/
 {
-    Py_buffer view = { 0 };
-    PyObject *ret_obj;
     char *name;
-    const EVP_MD *digest = NULL;
-
     if (!PyArg_Parse(name_obj, "s", &name)) {
         PyErr_SetString(PyExc_TypeError, "name must be a string");
         return NULL;
     }
-
-    if (data_obj)
-        GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view);
-
-    digest = py_digest_by_name(name);
-
-    ret_obj = EVPnew(module, digest,
-                     (unsigned char*)view.buf, view.len,
-                     usedforsecurity);
-
-    if (data_obj)
-        PyBuffer_Release(&view);
-    return ret_obj;
+    return py_evp_fromname(module, name, data_obj, usedforsecurity);
 }
 
-static PyObject*
-EVP_fast_new(PyObject *module, PyObject *data_obj, const EVP_MD *digest,
-             int usedforsecurity)
-{
-    Py_buffer view = { 0 };
-    PyObject *ret_obj;
-
-    if (data_obj)
-        GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view);
-
-    ret_obj = EVPnew(module, digest,
-                     (unsigned char*)view.buf, view.len,
-                     usedforsecurity);
-
-    if (data_obj)
-        PyBuffer_Release(&view);
-
-    return ret_obj;
-}
 
 /*[clinic input]
 _hashlib.openssl_md5
@@ -881,7 +989,7 @@ _hashlib_openssl_md5_impl(PyObject *module, PyObject *data_obj,
                           int usedforsecurity)
 /*[clinic end generated code: output=87b0186440a44f8c input=990e36d5e689b16e]*/
 {
-    return EVP_fast_new(module, data_obj, EVP_md5(), usedforsecurity);
+    return py_evp_fromname(module, Py_hash_md5, data_obj, usedforsecurity);
 }
 
 
@@ -901,7 +1009,7 @@ _hashlib_openssl_sha1_impl(PyObject *module, PyObject *data_obj,
                            int usedforsecurity)
 /*[clinic end generated code: output=6813024cf690670d input=948f2f4b6deabc10]*/
 {
-    return EVP_fast_new(module, data_obj, EVP_sha1(), usedforsecurity);
+    return py_evp_fromname(module, Py_hash_sha1, data_obj, usedforsecurity);
 }
 
 
@@ -921,7 +1029,7 @@ _hashlib_openssl_sha224_impl(PyObject *module, PyObject *data_obj,
                              int usedforsecurity)
 /*[clinic end generated code: output=a2dfe7cc4eb14ebb input=f9272821fadca505]*/
 {
-    return EVP_fast_new(module, data_obj, EVP_sha224(), usedforsecurity);
+    return py_evp_fromname(module, Py_hash_sha224, data_obj, usedforsecurity);
 }
 
 
@@ -941,7 +1049,7 @@ _hashlib_openssl_sha256_impl(PyObject *module, PyObject *data_obj,
                              int usedforsecurity)
 /*[clinic end generated code: output=1f874a34870f0a68 input=549fad9d2930d4c5]*/
 {
-    return EVP_fast_new(module, data_obj, EVP_sha256(), usedforsecurity);
+    return py_evp_fromname(module, Py_hash_sha256, data_obj, usedforsecurity);
 }
 
 
@@ -961,7 +1069,7 @@ _hashlib_openssl_sha384_impl(PyObject *module, PyObject *data_obj,
                              int usedforsecurity)
 /*[clinic end generated code: output=58529eff9ca457b2 input=48601a6e3bf14ad7]*/
 {
-    return EVP_fast_new(module, data_obj, EVP_sha384(), usedforsecurity);
+    return py_evp_fromname(module, Py_hash_sha384, data_obj, usedforsecurity);
 }
 
 
@@ -981,7 +1089,7 @@ _hashlib_openssl_sha512_impl(PyObject *module, PyObject *data_obj,
                              int usedforsecurity)
 /*[clinic end generated code: output=2c744c9e4a40d5f6 input=c5c46a2a817aa98f]*/
 {
-    return EVP_fast_new(module, data_obj, EVP_sha512(), usedforsecurity);
+    return py_evp_fromname(module, Py_hash_sha512, data_obj, usedforsecurity);
 }
 
 
@@ -1003,7 +1111,7 @@ _hashlib_openssl_sha3_224_impl(PyObject *module, PyObject *data_obj,
                                int usedforsecurity)
 /*[clinic end generated code: output=144641c1d144b974 input=e3a01b2888916157]*/
 {
-    return EVP_fast_new(module, data_obj, EVP_sha3_224(), usedforsecurity);
+    return py_evp_fromname(module, Py_hash_sha3_224, data_obj, usedforsecurity);
 }
 
 /*[clinic input]
@@ -1022,7 +1130,7 @@ _hashlib_openssl_sha3_256_impl(PyObject *module, PyObject *data_obj,
                                int usedforsecurity)
 /*[clinic end generated code: output=c61f1ab772d06668 input=e2908126c1b6deed]*/
 {
-    return EVP_fast_new(module, data_obj, EVP_sha3_256(), usedforsecurity);
+    return py_evp_fromname(module, Py_hash_sha3_256, data_obj , usedforsecurity);
 }
 
 /*[clinic input]
@@ -1041,7 +1149,7 @@ _hashlib_openssl_sha3_384_impl(PyObject *module, PyObject *data_obj,
                                int usedforsecurity)
 /*[clinic end generated code: output=f68e4846858cf0ee input=ec0edf5c792f8252]*/
 {
-    return EVP_fast_new(module, data_obj, EVP_sha3_384(), usedforsecurity);
+    return py_evp_fromname(module, Py_hash_sha3_384, data_obj , usedforsecurity);
 }
 
 /*[clinic input]
@@ -1060,7 +1168,7 @@ _hashlib_openssl_sha3_512_impl(PyObject *module, PyObject *data_obj,
                                int usedforsecurity)
 /*[clinic end generated code: output=2eede478c159354a input=64e2cc0c094d56f4]*/
 {
-    return EVP_fast_new(module, data_obj, EVP_sha3_512(), usedforsecurity);
+    return py_evp_fromname(module, Py_hash_sha3_512, data_obj , usedforsecurity);
 }
 #endif /* PY_OPENSSL_HAS_SHA3 */
 
@@ -1081,7 +1189,7 @@ _hashlib_openssl_shake_128_impl(PyObject *module, PyObject *data_obj,
                                 int usedforsecurity)
 /*[clinic end generated code: output=bc49cdd8ada1fa97 input=6c9d67440eb33ec8]*/
 {
-    return EVP_fast_new(module, data_obj, EVP_shake128(), usedforsecurity);
+    return py_evp_fromname(module, Py_hash_shake_128, data_obj , usedforsecurity);
 }
 
 /*[clinic input]
@@ -1100,7 +1208,7 @@ _hashlib_openssl_shake_256_impl(PyObject *module, PyObject *data_obj,
                                 int usedforsecurity)
 /*[clinic end generated code: output=358d213be8852df7 input=479cbe9fefd4a9f8]*/
 {
-    return EVP_fast_new(module, data_obj, EVP_shake256(), usedforsecurity);
+    return py_evp_fromname(module, Py_hash_shake_256, data_obj , usedforsecurity);
 }
 #endif /* PY_OPENSSL_HAS_SHAKE */
 
@@ -1126,9 +1234,8 @@ pbkdf2_hmac_impl(PyObject *module, const char *hash_name,
     char *key;
     long dklen;
     int retval;
-    const EVP_MD *digest;
 
-    digest = py_digest_by_name(hash_name);
+    PY_EVP_MD *digest = py_digest_by_name(module, hash_name, Py_ht_pbkdf2);
     if (digest == NULL) {
         PyErr_SetString(PyExc_ValueError, "unsupported hash type");
         goto end;
@@ -1192,11 +1299,14 @@ pbkdf2_hmac_impl(PyObject *module, const char *hash_name,
 
     if (!retval) {
         Py_CLEAR(key_obj);
-        _setException(PyExc_ValueError);
+        _setException(PyExc_ValueError, NULL);
         goto end;
     }
 
   end:
+    if (digest != NULL) {
+        PY_EVP_MD_free(digest);
+    }
     return key_obj;
 }
 
@@ -1296,9 +1406,7 @@ _hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt,
     /* let OpenSSL validate the rest */
     retval = EVP_PBE_scrypt(NULL, 0, NULL, 0, n, r, p, maxmem, NULL, 0);
     if (!retval) {
-        /* sorry, can't do much better */
-        PyErr_SetString(PyExc_ValueError,
-                        "Invalid parameter combination for n, r, p, maxmem.");
+        _setException(PyExc_ValueError, "Invalid parameter combination for n, r, p, maxmem.");
         return NULL;
    }
 
@@ -1319,7 +1427,7 @@ _hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt,
 
     if (!retval) {
         Py_CLEAR(key_obj);
-        _setException(PyExc_ValueError);
+        _setException(PyExc_ValueError, NULL);
         return NULL;
     }
     return key_obj;
@@ -1347,11 +1455,10 @@ _hashlib_hmac_singleshot_impl(PyObject *module, Py_buffer *key,
     unsigned char md[EVP_MAX_MD_SIZE] = {0};
     unsigned int md_len = 0;
     unsigned char *result;
-    const EVP_MD *evp;
+    PY_EVP_MD *evp;
 
-    evp = py_digest_by_name(digest);
+    evp = py_digest_by_name(module, digest, Py_ht_mac);
     if (evp == NULL) {
-        PyErr_SetString(PyExc_ValueError, "unsupported hash type");
         return NULL;
     }
     if (key->len > INT_MAX) {
@@ -1365,6 +1472,11 @@ _hashlib_hmac_singleshot_impl(PyObject *module, Py_buffer *key,
         return NULL;
     }
 
+    evp = py_digest_by_name(module, digest, Py_ht_mac);
+    if (evp == NULL) {
+        return NULL;
+    }
+
     Py_BEGIN_ALLOW_THREADS
     result = HMAC(
         evp,
@@ -1373,9 +1485,10 @@ _hashlib_hmac_singleshot_impl(PyObject *module, Py_buffer *key,
         md, &md_len
     );
     Py_END_ALLOW_THREADS
+    PY_EVP_MD_free(evp);
 
     if (result == NULL) {
-        _setException(PyExc_ValueError);
+        _setException(PyExc_ValueError, NULL);
         return NULL;
     }
     return PyBytes_FromStringAndSize((const char*)md, md_len);
@@ -1402,7 +1515,7 @@ _hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, PyObject *msg_obj,
 /*[clinic end generated code: output=9a35673be0cbea1b input=a0878868eb190134]*/
 {
     PyTypeObject *type = get_hashlib_state(module)->HMACtype;
-    const EVP_MD *digest;
+    PY_EVP_MD *digest;
     HMAC_CTX *ctx = NULL;
     HMACobject *self = NULL;
     int r;
@@ -1419,15 +1532,14 @@ _hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, PyObject *msg_obj,
         return NULL;
     }
 
-    digest = py_digest_by_name(digestmod);
+    digest = py_digest_by_name(module, digestmod, Py_ht_mac);
     if (!digest) {
-        PyErr_SetString(PyExc_ValueError, "unknown hash function");
         return NULL;
     }
 
     ctx = HMAC_CTX_new();
     if (ctx == NULL) {
-        _setException(PyExc_ValueError);
+        _setException(PyExc_ValueError, NULL);
         goto error;
     }
 
@@ -1437,8 +1549,9 @@ _hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, PyObject *msg_obj,
         (int)key->len,
         digest,
         NULL /*impl*/);
+    PY_EVP_MD_free(digest);
     if (r == 0) {
-        _setException(PyExc_ValueError);
+        _setException(PyExc_ValueError, NULL);
         goto error;
     }
 
@@ -1508,7 +1621,7 @@ _hmac_update(HMACobject *self, PyObject *obj)
     PyBuffer_Release(&view);
 
     if (r == 0) {
-        _setException(PyExc_ValueError);
+        _setException(PyExc_ValueError, NULL);
         return 0;
     }
     return 1;
@@ -1528,11 +1641,11 @@ _hashlib_HMAC_copy_impl(HMACobject *self)
 
     HMAC_CTX *ctx = HMAC_CTX_new();
     if (ctx == NULL) {
-        return _setException(PyExc_ValueError);
+        return _setException(PyExc_ValueError, NULL);
     }
     if (!locked_HMAC_CTX_copy(ctx, self)) {
         HMAC_CTX_free(ctx);
-        return _setException(PyExc_ValueError);
+        return _setException(PyExc_ValueError, NULL);
     }
 
     retval = (HMACobject *)PyObject_New(HMACobject, Py_TYPE(self));
@@ -1598,13 +1711,13 @@ _hmac_digest(HMACobject *self, unsigned char *buf, unsigned int len)
         return 0;
     }
     if (!locked_HMAC_CTX_copy(temp_ctx, self)) {
-        _setException(PyExc_ValueError);
+        _setException(PyExc_ValueError, NULL);
         return 0;
     }
     int r = HMAC_Final(temp_ctx, buf, &len);
     HMAC_CTX_free(temp_ctx);
     if (r == 0) {
-        _setException(PyExc_ValueError);
+        _setException(PyExc_ValueError, NULL);
         return 0;
     }
     return 1;
@@ -1622,7 +1735,7 @@ _hashlib_HMAC_digest_impl(HMACobject *self)
     unsigned char digest[EVP_MAX_MD_SIZE];
     unsigned int digest_size = _hmac_digest_size(self);
     if (digest_size == 0) {
-        return _setException(PyExc_ValueError);
+        return _setException(PyExc_ValueError, NULL);
     }
     int r = _hmac_digest(self, digest, digest_size);
     if (r == 0) {
@@ -1647,7 +1760,7 @@ _hashlib_HMAC_hexdigest_impl(HMACobject *self)
     unsigned char digest[EVP_MAX_MD_SIZE];
     unsigned int digest_size = _hmac_digest_size(self);
     if (digest_size == 0) {
-        return _setException(PyExc_ValueError);
+        return _setException(PyExc_ValueError, NULL);
     }
     int r = _hmac_digest(self, digest, digest_size);
     if (r == 0) {
@@ -1661,7 +1774,7 @@ _hashlib_hmac_get_digest_size(HMACobject *self, void *closure)
 {
     unsigned int digest_size = _hmac_digest_size(self);
     if (digest_size == 0) {
-        return _setException(PyExc_ValueError);
+        return _setException(PyExc_ValueError, NULL);
     }
     return PyLong_FromLong(digest_size);
 }
@@ -1671,7 +1784,7 @@ _hashlib_hmac_get_block_size(HMACobject *self, void *closure)
 {
     const EVP_MD *md = HMAC_CTX_get_md(self->ctx);
     if (md == NULL) {
-        return _setException(PyExc_ValueError);
+        return _setException(PyExc_ValueError, NULL);
     }
     return PyLong_FromLong(EVP_MD_block_size(md));
 }
@@ -1831,7 +1944,7 @@ _hashlib_get_fips_mode_impl(PyObject *module)
         // But 0 is also a valid result value.
         unsigned long errcode = ERR_peek_last_error();
         if (errcode) {
-            _setException(PyExc_ValueError);
+            _setException(PyExc_ValueError, NULL);
             return -1;
         }
     }
@@ -2004,6 +2117,10 @@ hashlib_clear(PyObject *m)
 #ifdef PY_OPENSSL_HAS_SHAKE
     Py_CLEAR(state->EVPXOFtype);
 #endif
+    if (state->hashtable != NULL) {
+        _Py_hashtable_destroy(state->hashtable);
+        state->hashtable = NULL;
+    }
     return 0;
 }
 
@@ -2026,6 +2143,19 @@ hashlib_openssl_legacy_init(PyObject *module)
 }
 
 static int
+hashlib_init_hashtable(PyObject *module)
+{
+    _hashlibstate *state = get_hashlib_state(module);
+
+    state->hashtable = py_hashentry_table_new();
+    if (state->hashtable == NULL) {
+        PyErr_NoMemory();
+        return -1;
+    }
+    return 0;
+}
+
+static int
 hashlib_init_evptype(PyObject *module)
 {
     _hashlibstate *state = get_hashlib_state(module);
@@ -2089,6 +2219,7 @@ hashlib_init_hmactype(PyObject *module)
 static PyModuleDef_Slot hashlib_slots[] = {
     /* OpenSSL 1.0.2 and LibreSSL */
     {Py_mod_exec, hashlib_openssl_legacy_init},
+    {Py_mod_exec, hashlib_init_hashtable},
     {Py_mod_exec, hashlib_init_evptype},
     {Py_mod_exec, hashlib_init_evpxoftype},
     {Py_mod_exec, hashlib_init_hmactype},
@@ -2127,6 +2258,10 @@ PyInit__hashlib(void)
         Py_DECREF(m);
         return NULL;
     }
+    if (hashlib_init_hashtable(m) < 0) {
+        Py_DECREF(m);
+        return NULL;
+    }
     if (hashlib_init_evptype(m) < 0) {
         Py_DECREF(m);
         return NULL;
index ae12841..ad1b074 100644 (file)
@@ -330,6 +330,19 @@ static PyTypeObject _HashInheritanceTester_Type = {
 };
 
 static PyObject*
+pycompilestring(PyObject* self, PyObject *obj) {
+    if (PyBytes_CheckExact(obj) == 0) {
+        PyErr_SetString(PyExc_ValueError, "Argument must be a bytes object");
+        return NULL;
+    }
+    const char *the_string = PyBytes_AsString(obj);
+    if (the_string == NULL) {
+        return NULL;
+    }
+    return Py_CompileString(the_string, "<string>", Py_file_input);
+}
+
+static PyObject*
 test_lazy_hash_inheritance(PyObject* self, PyObject *Py_UNUSED(ignored))
 {
     PyTypeObject *type;
@@ -5537,6 +5550,7 @@ static PyMethodDef TestMethods[] = {
         return_null_without_error, METH_NOARGS},
     {"return_result_with_error",
         return_result_with_error, METH_NOARGS},
+    {"Py_CompileString",     pycompilestring, METH_O},
     {"PyTime_FromSeconds", test_pytime_fromseconds,  METH_VARARGS},
     {"PyTime_FromSecondsObject", test_pytime_fromsecondsobject,  METH_VARARGS},
     {"PyTime_AsSecondsDouble", test_pytime_assecondsdouble, METH_VARARGS},
index 7f60e28..0fb25d5 100644 (file)
@@ -363,7 +363,7 @@ exit:
 
 #endif /* defined(HAVE_GETITIMER) */
 
-#if defined(PYPTHREAD_SIGMASK)
+#if defined(HAVE_SIGSET_T) && defined(PYPTHREAD_SIGMASK)
 
 PyDoc_STRVAR(signal_pthread_sigmask__doc__,
 "pthread_sigmask($module, how, mask, /)\n"
@@ -405,9 +405,9 @@ exit:
     return return_value;
 }
 
-#endif /* defined(PYPTHREAD_SIGMASK) */
+#endif /* defined(HAVE_SIGSET_T) && defined(PYPTHREAD_SIGMASK) */
 
-#if defined(HAVE_SIGPENDING)
+#if defined(HAVE_SIGSET_T) && defined(HAVE_SIGPENDING)
 
 PyDoc_STRVAR(signal_sigpending__doc__,
 "sigpending($module, /)\n"
@@ -430,9 +430,9 @@ signal_sigpending(PyObject *module, PyObject *Py_UNUSED(ignored))
     return signal_sigpending_impl(module);
 }
 
-#endif /* defined(HAVE_SIGPENDING) */
+#endif /* defined(HAVE_SIGSET_T) && defined(HAVE_SIGPENDING) */
 
-#if defined(HAVE_SIGWAIT)
+#if defined(HAVE_SIGSET_T) && defined(HAVE_SIGWAIT)
 
 PyDoc_STRVAR(signal_sigwait__doc__,
 "sigwait($module, sigset, /)\n"
@@ -465,9 +465,9 @@ exit:
     return return_value;
 }
 
-#endif /* defined(HAVE_SIGWAIT) */
+#endif /* defined(HAVE_SIGSET_T) && defined(HAVE_SIGWAIT) */
 
-#if (defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS))
+#if ((defined(HAVE_SIGFILLSET) && defined(HAVE_SIGSET_T)) || defined(MS_WINDOWS))
 
 PyDoc_STRVAR(signal_valid_signals__doc__,
 "valid_signals($module, /)\n"
@@ -490,9 +490,9 @@ signal_valid_signals(PyObject *module, PyObject *Py_UNUSED(ignored))
     return signal_valid_signals_impl(module);
 }
 
-#endif /* (defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS)) */
+#endif /* ((defined(HAVE_SIGFILLSET) && defined(HAVE_SIGSET_T)) || defined(MS_WINDOWS)) */
 
-#if defined(HAVE_SIGWAITINFO)
+#if defined(HAVE_SIGSET_T) && defined(HAVE_SIGWAITINFO)
 
 PyDoc_STRVAR(signal_sigwaitinfo__doc__,
 "sigwaitinfo($module, sigset, /)\n"
@@ -523,9 +523,9 @@ exit:
     return return_value;
 }
 
-#endif /* defined(HAVE_SIGWAITINFO) */
+#endif /* defined(HAVE_SIGSET_T) && defined(HAVE_SIGWAITINFO) */
 
-#if defined(HAVE_SIGTIMEDWAIT)
+#if defined(HAVE_SIGSET_T) && defined(HAVE_SIGTIMEDWAIT)
 
 PyDoc_STRVAR(signal_sigtimedwait__doc__,
 "sigtimedwait($module, sigset, timeout, /)\n"
@@ -562,7 +562,7 @@ exit:
     return return_value;
 }
 
-#endif /* defined(HAVE_SIGTIMEDWAIT) */
+#endif /* defined(HAVE_SIGSET_T) && defined(HAVE_SIGTIMEDWAIT) */
 
 #if defined(HAVE_PTHREAD_KILL)
 
@@ -732,4 +732,4 @@ exit:
 #ifndef SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF
     #define SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF
 #endif /* !defined(SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF) */
-/*[clinic end generated code: output=b41b4b6bd9ad4da2 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=3c8b80f14df17563 input=a9049054013a1b77]*/
index 2c6ef92..3cf1a00 100644 (file)
@@ -2149,12 +2149,36 @@ _PyGC_DumpShutdownStats(PyThreadState *tstate)
     }
 }
 
+
+static void
+gc_fini_untrack(PyGC_Head *list)
+{
+    PyGC_Head *gc;
+    for (gc = GC_NEXT(list); gc != list; gc = GC_NEXT(list)) {
+        PyObject *op = FROM_GC(gc);
+        _PyObject_GC_UNTRACK(op);
+    }
+}
+
+
 void
 _PyGC_Fini(PyThreadState *tstate)
 {
     GCState *gcstate = &tstate->interp->gc;
     Py_CLEAR(gcstate->garbage);
     Py_CLEAR(gcstate->callbacks);
+
+    if (!_Py_IsMainInterpreter(tstate)) {
+        // bpo-46070: Explicitly untrack all objects currently tracked by the
+        // GC. Otherwise, if an object is used later by another interpreter,
+        // calling PyObject_GC_UnTrack() on the object crashs if the previous
+        // or the next object of the PyGC_Head structure became a dangling
+        // pointer.
+        for (int i = 0; i < NUM_GENERATIONS; i++) {
+            PyGC_Head *gen = GEN_HEAD(gcstate, i);
+            gc_fini_untrack(gen);
+        }
+    }
 }
 
 /* for debugging */
index c974601..1f16849 100644 (file)
@@ -971,9 +971,13 @@ is_error(double x)
          * On some platforms (Ubuntu/ia64) it seems that errno can be
          * set to ERANGE for subnormal results that do *not* underflow
          * to zero.  So to be safe, we'll ignore ERANGE whenever the
-         * function result is less than one in absolute value.
+         * function result is less than 1.5 in absolute value.
+         *
+         * bpo-46018: Changed to 1.5 to ensure underflows in expm1()
+         * are correctly detected, since the function may underflow
+         * toward -1.0 rather than 0.0.
          */
-        if (fabs(x) < 1.0)
+        if (fabs(x) < 1.5)
             result = 0;
         else
             PyErr_SetString(PyExc_OverflowError,
index f2dcf96..29d6126 100644 (file)
@@ -5882,6 +5882,7 @@ parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpg
 
     }
 
+#ifdef HAVE_SIGSET_T
    if (setsigmask) {
         sigset_t set;
         if (!_Py_Sigset_Converter(setsigmask, &set)) {
@@ -5907,6 +5908,13 @@ parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpg
         }
         all_flags |= POSIX_SPAWN_SETSIGDEF;
     }
+#else
+    if (setsigmask || setsigdef) {
+        PyErr_SetString(PyExc_NotImplementedError,
+                        "sigset is not supported on this platform");
+        goto fail;
+    }
+#endif
 
     if (scheduler) {
 #ifdef POSIX_SPAWN_SETSCHEDULER
index 711ac68..5452ffb 100644 (file)
@@ -23,9 +23,7 @@ PyAPI_FUNC(int) _Py_Gid_Converter(PyObject *, gid_t *);
 # define HAVE_SIGSET_T
 #endif
 
-#ifdef HAVE_SIGSET_T
 PyAPI_FUNC(int) _Py_Sigset_Converter(PyObject *, void *);
-#endif /* HAVE_SIGSET_T */
 #endif /* Py_LIMITED_API */
 
 #ifdef __cplusplus
index de564c2..e396a4a 100644 (file)
@@ -68,6 +68,8 @@ module signal
 [clinic start generated code]*/
 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=b0301a3bde5fe9d3]*/
 
+#ifdef HAVE_SETSIG_T
+
 /*[python input]
 
 class sigset_t_converter(CConverter):
@@ -76,6 +78,7 @@ class sigset_t_converter(CConverter):
 
 [python start generated code]*/
 /*[python end generated code: output=da39a3ee5e6b4b0d input=b5689d14466b6823]*/
+#endif
 
 /*
    NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS
@@ -880,6 +883,7 @@ signal_getitimer_impl(PyObject *module, int which)
 
 #endif
 
+#ifdef HAVE_SIGSET_T
 #if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGPENDING)
 static PyObject*
 sigset_to_set(sigset_t mask)
@@ -1011,9 +1015,9 @@ signal_sigwait_impl(PyObject *module, sigset_t sigset)
 }
 
 #endif   /* #ifdef HAVE_SIGWAIT */
+#endif   /* #ifdef HAVE_SIGSET_T */
 
-
-#if defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS)
+#if (defined(HAVE_SIGFILLSET) && defined(HAVE_SIGSET_T)) || defined(MS_WINDOWS)
 
 /*[clinic input]
 signal.valid_signals
@@ -1051,7 +1055,8 @@ signal_valid_signals_impl(PyObject *module)
 #endif
 }
 
-#endif   /* #if defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS) */
+#endif   /* #if (defined(HAVE_SIGFILLSET) && defined(HAVE_SIGSET_T)) || defined(MS_WINDOWS) */
+
 
 
 #if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
@@ -1117,6 +1122,7 @@ fill_siginfo(siginfo_t *si)
 }
 #endif
 
+#ifdef HAVE_SIGSET_T
 #ifdef HAVE_SIGWAITINFO
 
 /*[clinic input]
@@ -1219,6 +1225,7 @@ signal_sigtimedwait_impl(PyObject *module, sigset_t sigset,
 }
 
 #endif   /* #ifdef HAVE_SIGTIMEDWAIT */
+#endif   /* #ifdef HAVE_SIGSET_T */
 
 
 #if defined(HAVE_PTHREAD_KILL)
index 8f8bcd8..4dfd4ae 100644 (file)
@@ -1134,11 +1134,13 @@ zlib_Decompress_flush_impl(compobject *self, Py_ssize_t length)
         return NULL;
     }
 
-    if (PyObject_GetBuffer(self->unconsumed_tail, &data, PyBUF_SIMPLE) == -1)
-        return NULL;
-
     ENTER_ZLIB(self);
 
+    if (PyObject_GetBuffer(self->unconsumed_tail, &data, PyBUF_SIMPLE) == -1) {
+        LEAVE_ZLIB(self);
+        return NULL;
+    }
+
     self->zst.next_in = data.buf;
     ibuflen = data.len;
 
index b9f2169..f3980ab 100644 (file)
@@ -1290,6 +1290,7 @@ PyDoc_STRVAR(odict_reversed__doc__, "od.__reversed__() <==> reversed(od)");
 #define _odict_ITER_REVERSED 1
 #define _odict_ITER_KEYS 2
 #define _odict_ITER_VALUES 4
+#define _odict_ITER_ITEMS (_odict_ITER_KEYS|_odict_ITER_VALUES)
 
 /* forward */
 static PyObject * odictiter_new(PyODictObject *, int);
@@ -1708,7 +1709,7 @@ odictiter_dealloc(odictiterobject *di)
     _PyObject_GC_UNTRACK(di);
     Py_XDECREF(di->di_odict);
     Py_XDECREF(di->di_current);
-    if (di->kind & (_odict_ITER_KEYS | _odict_ITER_VALUES)) {
+    if ((di->kind & _odict_ITER_ITEMS) == _odict_ITER_ITEMS) {
         Py_DECREF(di->di_result);
     }
     PyObject_GC_Del(di);
@@ -1914,15 +1915,16 @@ odictiter_new(PyODictObject *od, int kind)
     if (di == NULL)
         return NULL;
 
-    if (kind & (_odict_ITER_KEYS | _odict_ITER_VALUES)){
+    if ((kind & _odict_ITER_ITEMS) == _odict_ITER_ITEMS) {
         di->di_result = PyTuple_Pack(2, Py_None, Py_None);
         if (di->di_result == NULL) {
             Py_DECREF(di);
             return NULL;
         }
     }
-    else
+    else {
         di->di_result = NULL;
+    }
 
     di->kind = kind;
     node = reversed ? _odict_LAST(od) : _odict_FIRST(od);
index 106fc66..11249d7 100644 (file)
@@ -344,7 +344,7 @@ _locate_pythons_for_key(HKEY root, LPCWSTR subkey, REGSAM flags, int bits,
                     }
                     else if (attrs & FILE_ATTRIBUTE_DIRECTORY) {
                         debug(L"locate_pythons_for_key: '%ls' is a directory\n",
-                              ip->executable, attrs);
+                              ip->executable);
                     }
                     else if (find_existing_python(ip->executable)) {
                         debug(L"locate_pythons_for_key: %ls: already found\n",
index 747c97a..15119b0 100644 (file)
@@ -430,7 +430,7 @@ def get_appxmanifest(ns):
         ["python", "python{}".format(VER_MAJOR), "python{}".format(VER_DOT)],
         PYTHON_VE_DATA,
         "console",
-        ("python.file", [".py"], '"%1"', "Python File", PY_PNG),
+        ("python.file", [".py"], '"%1" %*', "Python File", PY_PNG),
     )
 
     add_application(
@@ -441,7 +441,7 @@ def get_appxmanifest(ns):
         ["pythonw", "pythonw{}".format(VER_MAJOR), "pythonw{}".format(VER_DOT)],
         PYTHONW_VE_DATA,
         "windows",
-        ("python.windowedfile", [".pyw"], '"%1"', "Python File (no console)", PY_PNG),
+        ("python.windowedfile", [".pyw"], '"%1" %*', "Python File (no console)", PY_PNG),
     )
 
     if ns.include_pip and ns.include_launchers:
index 90fc6ba..e6c1d24 100644 (file)
@@ -5,7 +5,7 @@
 #include "winver.h"
 
 #define PYTHON_COMPANY   "Python Software Foundation"
-#define PYTHON_COPYRIGHT "Copyright \xA9 2001-2021 Python Software Foundation. Copyright \xA9 2000 BeOpen.com. Copyright \xA9 1995-2001 CNRI. Copyright \xA9 1991-1995 SMC."
+#define PYTHON_COPYRIGHT "Copyright \xA9 2001-2022 Python Software Foundation. Copyright \xA9 2000 BeOpen.com. Copyright \xA9 1995-2001 CNRI. Copyright \xA9 1991-1995 SMC."
 
 #define MS_WINDOWS
 #include "modsupport.h"
diff --git a/PCbuild/Directory.Build.props b/PCbuild/Directory.Build.props
new file mode 100644 (file)
index 0000000..4464f46
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <!-- This is intentionally left blank but exists to avoid being imported from some directory above -->\r
+</Project>\r
diff --git a/PCbuild/Directory.Build.targets b/PCbuild/Directory.Build.targets
new file mode 100644 (file)
index 0000000..3d2fe55
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <!-- This is intentionally left blank but exists to avoid being imported from some directory above -->
+</Project>
index 9dd0866..89fbf0d 100644 (file)
@@ -53,7 +53,7 @@ echo.Fetching external libraries...
 set libraries=\r
 set libraries=%libraries%                                       bzip2-1.0.6\r
 if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries%  libffi-3.3.0\r
-if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries%     openssl-1.1.1l\r
+if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries%     openssl-1.1.1m\r
 set libraries=%libraries%                                       sqlite-3.35.5.0\r
 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.12.0\r
 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.12.0\r
@@ -77,7 +77,7 @@ echo.Fetching external binaries...
 \r
 set binaries=\r
 if NOT "%IncludeLibffi%"=="false"  set binaries=%binaries% libffi-3.3.0\r
-if NOT "%IncludeSSL%"=="false"     set binaries=%binaries% openssl-bin-1.1.1l\r
+if NOT "%IncludeSSL%"=="false"     set binaries=%binaries% openssl-bin-1.1.1m\r
 if NOT "%IncludeTkinter%"=="false" set binaries=%binaries% tcltk-8.6.12.0\r
 if NOT "%IncludeSSLSrc%"=="false"  set binaries=%binaries% nasm-2.11.06\r
 \r
index 733e64b..801077b 100644 (file)
@@ -11,8 +11,8 @@
 \r
     We set BasePlatformToolset for ICC's benefit, it's otherwise ignored.\r
     -->\r
-    <BasePlatformToolset Condition="'$(BasePlatformToolset)' == '' and ('$(MSBuildToolsVersion)' == '17.0' or '$(VisualStudioVersion)' == '17.0')">v142</BasePlatformToolset>\r
-    <BasePlatformToolset Condition="'$(BasePlatformToolset)' == '' and ('$(MSBuildToolsVersion)' == '16.0' or '$(VisualStudioVersion)' == '16.0')">v142</BasePlatformToolset>\r
+    <BasePlatformToolset Condition="'$(BasePlatformToolset)' == '' and '$(VisualStudioVersion)' == '17.0'">v142</BasePlatformToolset>\r
+    <BasePlatformToolset Condition="'$(BasePlatformToolset)' == '' and '$(VisualStudioVersion)' == '16.0'">v142</BasePlatformToolset>\r
     <BasePlatformToolset Condition="'$(BasePlatformToolset)' == '' and ('$(MSBuildToolsVersion)' == '15.0' or '$(VisualStudioVersion)' == '15.0')">v141</BasePlatformToolset>\r
     <BasePlatformToolset Condition="'$(BasePlatformToolset)' == '' and '$(VCTargetsPath14)' != ''">v140</BasePlatformToolset>\r
     <BasePlatformToolset Condition="'$(BasePlatformToolset)' == '' and '$(VCTargetsPath12)' != ''">v120</BasePlatformToolset>\r
@@ -63,8 +63,8 @@
     <libffiDir>$(ExternalsDir)libffi-3.3.0\</libffiDir>\r
     <libffiOutDir>$(ExternalsDir)libffi-3.3.0\$(ArchName)\</libffiOutDir>\r
     <libffiIncludeDir>$(libffiOutDir)include</libffiIncludeDir>\r
-    <opensslDir>$(ExternalsDir)openssl-1.1.1l\</opensslDir>\r
-    <opensslOutDir>$(ExternalsDir)openssl-bin-1.1.1l\$(ArchName)\</opensslOutDir>\r
+    <opensslDir>$(ExternalsDir)openssl-1.1.1m\</opensslDir>\r
+    <opensslOutDir>$(ExternalsDir)openssl-bin-1.1.1m\$(ArchName)\</opensslOutDir>\r
     <opensslIncludeDir>$(opensslOutDir)include</opensslIncludeDir>\r
     <nasmDir>$(ExternalsDir)\nasm-2.11.06\</nasmDir>\r
     <zlibDir>$(ExternalsDir)\zlib-1.2.11\</zlibDir>\r
index 611257d..105b0fa 100644 (file)
@@ -1,4 +1,4 @@
-// @generated by pegen.py from ./Grammar/python.gram
+// @generated by pegen.py from python.gram
 #include "pegen.h"
 
 #if defined(Py_DEBUG) && defined(Py_BUILD_CORE)
@@ -7,6 +7,8 @@ extern int Py_DebugFlag;
 #else
 #define D(x)
 #endif
+
+# define MAXSTACK 6000
 static const int n_keyword_lists = 15;
 static KeywordToken *reserved_keywords[] = {
     (KeywordToken[]) {{NULL, -1}},
@@ -712,16 +714,19 @@ static void *_tmp_155_rule(Parser *p);
 static mod_ty
 file_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     mod_ty _res = NULL;
     int _mark = p->mark;
     { // statements? $
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> file[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "statements? $"));
@@ -737,7 +742,7 @@ file_rule(Parser *p)
             _res = _PyPegen_make_module ( p , a );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -748,7 +753,7 @@ file_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -756,16 +761,19 @@ file_rule(Parser *p)
 static mod_ty
 interactive_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     mod_ty _res = NULL;
     int _mark = p->mark;
     { // statement_newline
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> interactive[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "statement_newline"));
@@ -778,7 +786,7 @@ interactive_rule(Parser *p)
             _res = Interactive ( a , p -> arena );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -789,7 +797,7 @@ interactive_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -797,16 +805,19 @@ interactive_rule(Parser *p)
 static mod_ty
 eval_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     mod_ty _res = NULL;
     int _mark = p->mark;
     { // expressions NEWLINE* $
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> eval[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions NEWLINE* $"));
@@ -825,7 +836,7 @@ eval_rule(Parser *p)
             _res = Expression ( a , p -> arena );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -836,7 +847,7 @@ eval_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -844,16 +855,19 @@ eval_rule(Parser *p)
 static mod_ty
 func_type_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     mod_ty _res = NULL;
     int _mark = p->mark;
     { // '(' type_expressions? ')' '->' expression NEWLINE* $
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> func_type[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' type_expressions? ')' '->' expression NEWLINE* $"));
@@ -884,7 +898,7 @@ func_type_rule(Parser *p)
             _res = FunctionType ( a , b , p -> arena );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -895,7 +909,7 @@ func_type_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -903,16 +917,19 @@ func_type_rule(Parser *p)
 static expr_ty
 fstring_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     { // star_expressions
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> fstring[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions"));
@@ -931,7 +948,7 @@ fstring_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -946,16 +963,19 @@ fstring_rule(Parser *p)
 static asdl_seq*
 type_expressions_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq* _res = NULL;
     int _mark = p->mark;
     { // ','.expression+ ',' '*' expression ',' '**' expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.expression+ ',' '*' expression ',' '**' expression"));
@@ -986,7 +1006,7 @@ type_expressions_rule(Parser *p)
             _res = _PyPegen_seq_append_to_end ( p , CHECK ( _PyPegen_seq_append_to_end ( p , a , b ) ) , c );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -997,7 +1017,7 @@ type_expressions_rule(Parser *p)
     }
     { // ','.expression+ ',' '*' expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.expression+ ',' '*' expression"));
@@ -1019,7 +1039,7 @@ type_expressions_rule(Parser *p)
             _res = _PyPegen_seq_append_to_end ( p , a , b );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -1030,7 +1050,7 @@ type_expressions_rule(Parser *p)
     }
     { // ','.expression+ ',' '**' expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.expression+ ',' '**' expression"));
@@ -1052,7 +1072,7 @@ type_expressions_rule(Parser *p)
             _res = _PyPegen_seq_append_to_end ( p , a , b );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -1063,7 +1083,7 @@ type_expressions_rule(Parser *p)
     }
     { // '*' expression ',' '**' expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' expression ',' '**' expression"));
@@ -1088,7 +1108,7 @@ type_expressions_rule(Parser *p)
             _res = _PyPegen_seq_append_to_end ( p , CHECK ( _PyPegen_singleton_seq ( p , a ) ) , b );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -1099,7 +1119,7 @@ type_expressions_rule(Parser *p)
     }
     { // '*' expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' expression"));
@@ -1115,7 +1135,7 @@ type_expressions_rule(Parser *p)
             _res = _PyPegen_singleton_seq ( p , a );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -1126,7 +1146,7 @@ type_expressions_rule(Parser *p)
     }
     { // '**' expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' expression"));
@@ -1142,7 +1162,7 @@ type_expressions_rule(Parser *p)
             _res = _PyPegen_singleton_seq ( p , a );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -1153,7 +1173,7 @@ type_expressions_rule(Parser *p)
     }
     { // ','.expression+
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.expression+"));
@@ -1172,7 +1192,7 @@ type_expressions_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -1180,16 +1200,19 @@ type_expressions_rule(Parser *p)
 static asdl_seq*
 statements_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq* _res = NULL;
     int _mark = p->mark;
     { // statement+
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> statements[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "statement+"));
@@ -1202,7 +1225,7 @@ statements_rule(Parser *p)
             _res = _PyPegen_seq_flatten ( p , a );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -1213,7 +1236,7 @@ statements_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -1221,16 +1244,19 @@ statements_rule(Parser *p)
 static asdl_seq*
 statement_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq* _res = NULL;
     int _mark = p->mark;
     { // compound_stmt
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> statement[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "compound_stmt"));
@@ -1243,7 +1269,7 @@ statement_rule(Parser *p)
             _res = _PyPegen_singleton_seq ( p , a );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -1254,7 +1280,7 @@ statement_rule(Parser *p)
     }
     { // simple_stmt
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> statement[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "simple_stmt"));
@@ -1273,7 +1299,7 @@ statement_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -1281,16 +1307,19 @@ statement_rule(Parser *p)
 static asdl_seq*
 statement_newline_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq* _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -1299,7 +1328,7 @@ statement_newline_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // compound_stmt NEWLINE
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> statement_newline[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "compound_stmt NEWLINE"));
@@ -1315,7 +1344,7 @@ statement_newline_rule(Parser *p)
             _res = _PyPegen_singleton_seq ( p , a );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -1326,7 +1355,7 @@ statement_newline_rule(Parser *p)
     }
     { // simple_stmt
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> statement_newline[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "simple_stmt"));
@@ -1345,7 +1374,7 @@ statement_newline_rule(Parser *p)
     }
     { // NEWLINE
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> statement_newline[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE"));
@@ -1357,7 +1386,7 @@ statement_newline_rule(Parser *p)
             D(fprintf(stderr, "%*c+ statement_newline[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -1367,7 +1396,7 @@ statement_newline_rule(Parser *p)
             _res = _PyPegen_singleton_seq ( p , CHECK ( _Py_Pass ( EXTRA ) ) );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -1378,7 +1407,7 @@ statement_newline_rule(Parser *p)
     }
     { // $
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> statement_newline[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "$"));
@@ -1391,7 +1420,7 @@ statement_newline_rule(Parser *p)
             _res = _PyPegen_interactive_exit ( p );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -1402,7 +1431,7 @@ statement_newline_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -1410,16 +1439,19 @@ statement_newline_rule(Parser *p)
 static asdl_seq*
 simple_stmt_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq* _res = NULL;
     int _mark = p->mark;
     { // small_stmt !';' NEWLINE
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "small_stmt !';' NEWLINE"));
@@ -1437,7 +1469,7 @@ simple_stmt_rule(Parser *p)
             _res = _PyPegen_singleton_seq ( p , a );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -1448,7 +1480,7 @@ simple_stmt_rule(Parser *p)
     }
     { // ';'.small_stmt+ ';'? NEWLINE
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "';'.small_stmt+ ';'? NEWLINE"));
@@ -1468,7 +1500,7 @@ simple_stmt_rule(Parser *p)
             _res = a;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -1479,7 +1511,7 @@ simple_stmt_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -1500,20 +1532,23 @@ simple_stmt_rule(Parser *p)
 static stmt_ty
 small_stmt_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     stmt_ty _res = NULL;
     if (_PyPegen_is_memoized(p, small_stmt_type, &_res)) {
-        D(p->level--);
+        p->level--;
         return _res;
     }
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -1522,7 +1557,7 @@ small_stmt_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // assignment
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> small_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment"));
@@ -1541,7 +1576,7 @@ small_stmt_rule(Parser *p)
     }
     { // star_expressions
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> small_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions"));
@@ -1553,7 +1588,7 @@ small_stmt_rule(Parser *p)
             D(fprintf(stderr, "%*c+ small_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -1563,7 +1598,7 @@ small_stmt_rule(Parser *p)
             _res = _Py_Expr ( e , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -1574,7 +1609,7 @@ small_stmt_rule(Parser *p)
     }
     { // &'return' return_stmt
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> small_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'return' return_stmt"));
@@ -1595,7 +1630,7 @@ small_stmt_rule(Parser *p)
     }
     { // &('import' | 'from') import_stmt
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> small_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&('import' | 'from') import_stmt"));
@@ -1616,7 +1651,7 @@ small_stmt_rule(Parser *p)
     }
     { // &'raise' raise_stmt
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> small_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'raise' raise_stmt"));
@@ -1637,7 +1672,7 @@ small_stmt_rule(Parser *p)
     }
     { // 'pass'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> small_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'pass'"));
@@ -1649,7 +1684,7 @@ small_stmt_rule(Parser *p)
             D(fprintf(stderr, "%*c+ small_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'pass'"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -1659,7 +1694,7 @@ small_stmt_rule(Parser *p)
             _res = _Py_Pass ( EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -1670,7 +1705,7 @@ small_stmt_rule(Parser *p)
     }
     { // &'del' del_stmt
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> small_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'del' del_stmt"));
@@ -1691,7 +1726,7 @@ small_stmt_rule(Parser *p)
     }
     { // &'yield' yield_stmt
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> small_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'yield' yield_stmt"));
@@ -1712,7 +1747,7 @@ small_stmt_rule(Parser *p)
     }
     { // &'assert' assert_stmt
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> small_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'assert' assert_stmt"));
@@ -1733,7 +1768,7 @@ small_stmt_rule(Parser *p)
     }
     { // 'break'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> small_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'break'"));
@@ -1745,7 +1780,7 @@ small_stmt_rule(Parser *p)
             D(fprintf(stderr, "%*c+ small_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'break'"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -1755,7 +1790,7 @@ small_stmt_rule(Parser *p)
             _res = _Py_Break ( EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -1766,7 +1801,7 @@ small_stmt_rule(Parser *p)
     }
     { // 'continue'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> small_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'continue'"));
@@ -1778,7 +1813,7 @@ small_stmt_rule(Parser *p)
             D(fprintf(stderr, "%*c+ small_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'continue'"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -1788,7 +1823,7 @@ small_stmt_rule(Parser *p)
             _res = _Py_Continue ( EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -1799,7 +1834,7 @@ small_stmt_rule(Parser *p)
     }
     { // &'global' global_stmt
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> small_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'global' global_stmt"));
@@ -1820,7 +1855,7 @@ small_stmt_rule(Parser *p)
     }
     { // &'nonlocal' nonlocal_stmt
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> small_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'nonlocal' nonlocal_stmt"));
@@ -1842,7 +1877,7 @@ small_stmt_rule(Parser *p)
     _res = NULL;
   done:
     _PyPegen_insert_memo(p, _mark, small_stmt_type, _res);
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -1857,16 +1892,19 @@ small_stmt_rule(Parser *p)
 static stmt_ty
 compound_stmt_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     stmt_ty _res = NULL;
     int _mark = p->mark;
     { // &('def' | '@' | ASYNC) function_def
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&('def' | '@' | ASYNC) function_def"));
@@ -1887,7 +1925,7 @@ compound_stmt_rule(Parser *p)
     }
     { // &'if' if_stmt
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'if' if_stmt"));
@@ -1908,7 +1946,7 @@ compound_stmt_rule(Parser *p)
     }
     { // &('class' | '@') class_def
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&('class' | '@') class_def"));
@@ -1929,7 +1967,7 @@ compound_stmt_rule(Parser *p)
     }
     { // &('with' | ASYNC) with_stmt
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&('with' | ASYNC) with_stmt"));
@@ -1950,7 +1988,7 @@ compound_stmt_rule(Parser *p)
     }
     { // &('for' | ASYNC) for_stmt
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&('for' | ASYNC) for_stmt"));
@@ -1971,7 +2009,7 @@ compound_stmt_rule(Parser *p)
     }
     { // &'try' try_stmt
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'try' try_stmt"));
@@ -1992,7 +2030,7 @@ compound_stmt_rule(Parser *p)
     }
     { // &'while' while_stmt
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'while' while_stmt"));
@@ -2013,7 +2051,7 @@ compound_stmt_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -2026,16 +2064,19 @@ compound_stmt_rule(Parser *p)
 static stmt_ty
 assignment_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     stmt_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -2044,7 +2085,7 @@ assignment_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // NAME ':' expression ['=' annotated_rhs]
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME ':' expression ['=' annotated_rhs]"));
@@ -2065,7 +2106,7 @@ assignment_rule(Parser *p)
             D(fprintf(stderr, "%*c+ assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME ':' expression ['=' annotated_rhs]"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -2075,7 +2116,7 @@ assignment_rule(Parser *p)
             _res = CHECK_VERSION ( 6 , "Variable annotation syntax is" , _Py_AnnAssign ( CHECK ( _PyPegen_set_expr_context ( p , a , Store ) ) , b , c , 1 , EXTRA ) );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -2086,7 +2127,7 @@ assignment_rule(Parser *p)
     }
     { // ('(' single_target ')' | single_subscript_attribute_target) ':' expression ['=' annotated_rhs]
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('(' single_target ')' | single_subscript_attribute_target) ':' expression ['=' annotated_rhs]"));
@@ -2107,7 +2148,7 @@ assignment_rule(Parser *p)
             D(fprintf(stderr, "%*c+ assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "('(' single_target ')' | single_subscript_attribute_target) ':' expression ['=' annotated_rhs]"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -2117,7 +2158,7 @@ assignment_rule(Parser *p)
             _res = CHECK_VERSION ( 6 , "Variable annotations syntax is" , _Py_AnnAssign ( a , b , c , 0 , EXTRA ) );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -2128,7 +2169,7 @@ assignment_rule(Parser *p)
     }
     { // ((star_targets '='))+ (yield_expr | star_expressions) !'=' TYPE_COMMENT?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))+ (yield_expr | star_expressions) !'=' TYPE_COMMENT?"));
@@ -2148,7 +2189,7 @@ assignment_rule(Parser *p)
             D(fprintf(stderr, "%*c+ assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "((star_targets '='))+ (yield_expr | star_expressions) !'=' TYPE_COMMENT?"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -2158,7 +2199,7 @@ assignment_rule(Parser *p)
             _res = _Py_Assign ( a , b , NEW_TYPE_COMMENT ( p , tc ) , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -2169,7 +2210,7 @@ assignment_rule(Parser *p)
     }
     { // single_target augassign ~ (yield_expr | star_expressions)
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "single_target augassign ~ (yield_expr | star_expressions)"));
@@ -2190,7 +2231,7 @@ assignment_rule(Parser *p)
             D(fprintf(stderr, "%*c+ assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "single_target augassign ~ (yield_expr | star_expressions)"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -2200,7 +2241,7 @@ assignment_rule(Parser *p)
             _res = _Py_AugAssign ( a , b -> kind , c , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -2209,13 +2250,13 @@ assignment_rule(Parser *p)
         D(fprintf(stderr, "%*c%s assignment[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "single_target augassign ~ (yield_expr | star_expressions)"));
         if (_cut_var) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
     }
     if (p->call_invalid_rules) { // invalid_assignment
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_assignment"));
@@ -2234,7 +2275,7 @@ assignment_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -2255,16 +2296,19 @@ assignment_rule(Parser *p)
 static AugOperator*
 augassign_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     AugOperator* _res = NULL;
     int _mark = p->mark;
     { // '+='
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'+='"));
@@ -2277,7 +2321,7 @@ augassign_rule(Parser *p)
             _res = _PyPegen_augoperator ( p , Add );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -2288,7 +2332,7 @@ augassign_rule(Parser *p)
     }
     { // '-='
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-='"));
@@ -2301,7 +2345,7 @@ augassign_rule(Parser *p)
             _res = _PyPegen_augoperator ( p , Sub );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -2312,7 +2356,7 @@ augassign_rule(Parser *p)
     }
     { // '*='
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*='"));
@@ -2325,7 +2369,7 @@ augassign_rule(Parser *p)
             _res = _PyPegen_augoperator ( p , Mult );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -2336,7 +2380,7 @@ augassign_rule(Parser *p)
     }
     { // '@='
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@='"));
@@ -2349,7 +2393,7 @@ augassign_rule(Parser *p)
             _res = CHECK_VERSION ( 5 , "The '@' operator is" , _PyPegen_augoperator ( p , MatMult ) );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -2360,7 +2404,7 @@ augassign_rule(Parser *p)
     }
     { // '/='
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/='"));
@@ -2373,7 +2417,7 @@ augassign_rule(Parser *p)
             _res = _PyPegen_augoperator ( p , Div );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -2384,7 +2428,7 @@ augassign_rule(Parser *p)
     }
     { // '%='
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'%='"));
@@ -2397,7 +2441,7 @@ augassign_rule(Parser *p)
             _res = _PyPegen_augoperator ( p , Mod );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -2408,7 +2452,7 @@ augassign_rule(Parser *p)
     }
     { // '&='
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'&='"));
@@ -2421,7 +2465,7 @@ augassign_rule(Parser *p)
             _res = _PyPegen_augoperator ( p , BitAnd );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -2432,7 +2476,7 @@ augassign_rule(Parser *p)
     }
     { // '|='
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'|='"));
@@ -2445,7 +2489,7 @@ augassign_rule(Parser *p)
             _res = _PyPegen_augoperator ( p , BitOr );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -2456,7 +2500,7 @@ augassign_rule(Parser *p)
     }
     { // '^='
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'^='"));
@@ -2469,7 +2513,7 @@ augassign_rule(Parser *p)
             _res = _PyPegen_augoperator ( p , BitXor );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -2480,7 +2524,7 @@ augassign_rule(Parser *p)
     }
     { // '<<='
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'<<='"));
@@ -2493,7 +2537,7 @@ augassign_rule(Parser *p)
             _res = _PyPegen_augoperator ( p , LShift );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -2504,7 +2548,7 @@ augassign_rule(Parser *p)
     }
     { // '>>='
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'>>='"));
@@ -2517,7 +2561,7 @@ augassign_rule(Parser *p)
             _res = _PyPegen_augoperator ( p , RShift );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -2528,7 +2572,7 @@ augassign_rule(Parser *p)
     }
     { // '**='
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**='"));
@@ -2541,7 +2585,7 @@ augassign_rule(Parser *p)
             _res = _PyPegen_augoperator ( p , Pow );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -2552,7 +2596,7 @@ augassign_rule(Parser *p)
     }
     { // '//='
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'//='"));
@@ -2565,7 +2609,7 @@ augassign_rule(Parser *p)
             _res = _PyPegen_augoperator ( p , FloorDiv );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -2576,7 +2620,7 @@ augassign_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -2584,16 +2628,19 @@ augassign_rule(Parser *p)
 static stmt_ty
 global_stmt_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     stmt_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -2602,7 +2649,7 @@ global_stmt_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // 'global' ','.NAME+
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> global_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'global' ','.NAME+"));
@@ -2617,7 +2664,7 @@ global_stmt_rule(Parser *p)
             D(fprintf(stderr, "%*c+ global_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'global' ','.NAME+"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -2627,7 +2674,7 @@ global_stmt_rule(Parser *p)
             _res = _Py_Global ( CHECK ( _PyPegen_map_names_to_ids ( p , a ) ) , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -2638,7 +2685,7 @@ global_stmt_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -2646,16 +2693,19 @@ global_stmt_rule(Parser *p)
 static stmt_ty
 nonlocal_stmt_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     stmt_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -2664,7 +2714,7 @@ nonlocal_stmt_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // 'nonlocal' ','.NAME+
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> nonlocal_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'nonlocal' ','.NAME+"));
@@ -2679,7 +2729,7 @@ nonlocal_stmt_rule(Parser *p)
             D(fprintf(stderr, "%*c+ nonlocal_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'nonlocal' ','.NAME+"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -2689,7 +2739,7 @@ nonlocal_stmt_rule(Parser *p)
             _res = _Py_Nonlocal ( CHECK ( _PyPegen_map_names_to_ids ( p , a ) ) , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -2700,7 +2750,7 @@ nonlocal_stmt_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -2708,16 +2758,19 @@ nonlocal_stmt_rule(Parser *p)
 static stmt_ty
 yield_stmt_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     stmt_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -2726,7 +2779,7 @@ yield_stmt_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // yield_expr
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> yield_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr"));
@@ -2738,7 +2791,7 @@ yield_stmt_rule(Parser *p)
             D(fprintf(stderr, "%*c+ yield_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -2748,7 +2801,7 @@ yield_stmt_rule(Parser *p)
             _res = _Py_Expr ( y , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -2759,7 +2812,7 @@ yield_stmt_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -2767,16 +2820,19 @@ yield_stmt_rule(Parser *p)
 static stmt_ty
 assert_stmt_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     stmt_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -2785,7 +2841,7 @@ assert_stmt_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // 'assert' expression [',' expression]
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> assert_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'assert' expression [',' expression]"));
@@ -2803,7 +2859,7 @@ assert_stmt_rule(Parser *p)
             D(fprintf(stderr, "%*c+ assert_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'assert' expression [',' expression]"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -2813,7 +2869,7 @@ assert_stmt_rule(Parser *p)
             _res = _Py_Assert ( a , b , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -2824,7 +2880,7 @@ assert_stmt_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -2832,16 +2888,19 @@ assert_stmt_rule(Parser *p)
 static stmt_ty
 del_stmt_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     stmt_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -2850,7 +2909,7 @@ del_stmt_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // 'del' del_targets &(';' | NEWLINE)
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> del_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'del' del_targets &(';' | NEWLINE)"));
@@ -2867,7 +2926,7 @@ del_stmt_rule(Parser *p)
             D(fprintf(stderr, "%*c+ del_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'del' del_targets &(';' | NEWLINE)"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -2877,7 +2936,7 @@ del_stmt_rule(Parser *p)
             _res = _Py_Delete ( a , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -2888,7 +2947,7 @@ del_stmt_rule(Parser *p)
     }
     if (p->call_invalid_rules) { // invalid_del_stmt
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> del_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_del_stmt"));
@@ -2907,7 +2966,7 @@ del_stmt_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -2915,16 +2974,19 @@ del_stmt_rule(Parser *p)
 static stmt_ty
 import_stmt_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     stmt_ty _res = NULL;
     int _mark = p->mark;
     { // import_name
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> import_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "import_name"));
@@ -2943,7 +3005,7 @@ import_stmt_rule(Parser *p)
     }
     { // import_from
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> import_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "import_from"));
@@ -2962,7 +3024,7 @@ import_stmt_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -2970,16 +3032,19 @@ import_stmt_rule(Parser *p)
 static stmt_ty
 import_name_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     stmt_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -2988,7 +3053,7 @@ import_name_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // 'import' dotted_as_names
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> import_name[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'import' dotted_as_names"));
@@ -3003,7 +3068,7 @@ import_name_rule(Parser *p)
             D(fprintf(stderr, "%*c+ import_name[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'import' dotted_as_names"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -3013,7 +3078,7 @@ import_name_rule(Parser *p)
             _res = _Py_Import ( a , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -3024,7 +3089,7 @@ import_name_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -3034,16 +3099,19 @@ import_name_rule(Parser *p)
 static stmt_ty
 import_from_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     stmt_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -3052,7 +3120,7 @@ import_from_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // 'from' (('.' | '...'))* dotted_name 'import' import_from_targets
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> import_from[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'from' (('.' | '...'))* dotted_name 'import' import_from_targets"));
@@ -3076,7 +3144,7 @@ import_from_rule(Parser *p)
             D(fprintf(stderr, "%*c+ import_from[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'from' (('.' | '...'))* dotted_name 'import' import_from_targets"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -3086,7 +3154,7 @@ import_from_rule(Parser *p)
             _res = _Py_ImportFrom ( b -> v . Name . id , c , _PyPegen_seq_count_dots ( a ) , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -3097,7 +3165,7 @@ import_from_rule(Parser *p)
     }
     { // 'from' (('.' | '...'))+ 'import' import_from_targets
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> import_from[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'from' (('.' | '...'))+ 'import' import_from_targets"));
@@ -3118,7 +3186,7 @@ import_from_rule(Parser *p)
             D(fprintf(stderr, "%*c+ import_from[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'from' (('.' | '...'))+ 'import' import_from_targets"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -3128,7 +3196,7 @@ import_from_rule(Parser *p)
             _res = _Py_ImportFrom ( NULL , b , _PyPegen_seq_count_dots ( a ) , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -3139,7 +3207,7 @@ import_from_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -3151,16 +3219,19 @@ import_from_rule(Parser *p)
 static asdl_seq*
 import_from_targets_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq* _res = NULL;
     int _mark = p->mark;
     { // '(' import_from_as_names ','? ')'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> import_from_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' import_from_as_names ','? ')'"));
@@ -3183,7 +3254,7 @@ import_from_targets_rule(Parser *p)
             _res = a;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -3194,7 +3265,7 @@ import_from_targets_rule(Parser *p)
     }
     { // import_from_as_names !','
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> import_from_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "import_from_as_names !','"));
@@ -3215,7 +3286,7 @@ import_from_targets_rule(Parser *p)
     }
     { // '*'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> import_from_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'"));
@@ -3228,7 +3299,7 @@ import_from_targets_rule(Parser *p)
             _res = _PyPegen_singleton_seq ( p , CHECK ( _PyPegen_alias_for_star ( p ) ) );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -3239,7 +3310,7 @@ import_from_targets_rule(Parser *p)
     }
     if (p->call_invalid_rules) { // invalid_import_from_targets
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> import_from_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_import_from_targets"));
@@ -3258,7 +3329,7 @@ import_from_targets_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -3266,16 +3337,19 @@ import_from_targets_rule(Parser *p)
 static asdl_seq*
 import_from_as_names_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq* _res = NULL;
     int _mark = p->mark;
     { // ','.import_from_as_name+
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> import_from_as_names[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.import_from_as_name+"));
@@ -3288,7 +3362,7 @@ import_from_as_names_rule(Parser *p)
             _res = a;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -3299,7 +3373,7 @@ import_from_as_names_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -3307,16 +3381,19 @@ import_from_as_names_rule(Parser *p)
 static alias_ty
 import_from_as_name_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     alias_ty _res = NULL;
     int _mark = p->mark;
     { // NAME ['as' NAME]
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> import_from_as_name[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME ['as' NAME]"));
@@ -3332,7 +3409,7 @@ import_from_as_name_rule(Parser *p)
             _res = _Py_alias ( a -> v . Name . id , ( b ) ? ( ( expr_ty ) b ) -> v . Name . id : NULL , p -> arena );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -3343,7 +3420,7 @@ import_from_as_name_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -3351,16 +3428,19 @@ import_from_as_name_rule(Parser *p)
 static asdl_seq*
 dotted_as_names_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq* _res = NULL;
     int _mark = p->mark;
     { // ','.dotted_as_name+
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> dotted_as_names[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.dotted_as_name+"));
@@ -3373,7 +3453,7 @@ dotted_as_names_rule(Parser *p)
             _res = a;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -3384,7 +3464,7 @@ dotted_as_names_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -3392,16 +3472,19 @@ dotted_as_names_rule(Parser *p)
 static alias_ty
 dotted_as_name_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     alias_ty _res = NULL;
     int _mark = p->mark;
     { // dotted_name ['as' NAME]
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> dotted_as_name[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dotted_name ['as' NAME]"));
@@ -3417,7 +3500,7 @@ dotted_as_name_rule(Parser *p)
             _res = _Py_alias ( a -> v . Name . id , ( b ) ? ( ( expr_ty ) b ) -> v . Name . id : NULL , p -> arena );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -3428,7 +3511,7 @@ dotted_as_name_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -3438,10 +3521,13 @@ static expr_ty dotted_name_raw(Parser *);
 static expr_ty
 dotted_name_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     expr_ty _res = NULL;
     if (_PyPegen_is_memoized(p, dotted_name_type, &_res)) {
-        D(p->level--);
+        p->level--;
         return _res;
     }
     int _mark = p->mark;
@@ -3449,35 +3535,40 @@ dotted_name_rule(Parser *p)
     while (1) {
         int tmpvar_0 = _PyPegen_update_memo(p, _mark, dotted_name_type, _res);
         if (tmpvar_0) {
-            D(p->level--);
+            p->level--;
             return _res;
         }
         p->mark = _mark;
         void *_raw = dotted_name_raw(p);
-        if (p->error_indicator)
+        if (p->error_indicator) {
+            p->level--;
             return NULL;
+        }
         if (_raw == NULL || p->mark <= _resmark)
             break;
         _resmark = p->mark;
         _res = _raw;
     }
     p->mark = _resmark;
-    D(p->level--);
+    p->level--;
     return _res;
 }
 static expr_ty
 dotted_name_raw(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     { // dotted_name '.' NAME
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> dotted_name[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dotted_name '.' NAME"));
@@ -3496,7 +3587,7 @@ dotted_name_raw(Parser *p)
             _res = _PyPegen_join_names_with_dot ( p , a , b );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -3507,7 +3598,7 @@ dotted_name_raw(Parser *p)
     }
     { // NAME
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> dotted_name[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME"));
@@ -3526,7 +3617,7 @@ dotted_name_raw(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -3536,16 +3627,19 @@ dotted_name_raw(Parser *p)
 static stmt_ty
 if_stmt_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     stmt_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -3554,7 +3648,7 @@ if_stmt_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // 'if' named_expression ':' block elif_stmt
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> if_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' named_expression ':' block elif_stmt"));
@@ -3578,7 +3672,7 @@ if_stmt_rule(Parser *p)
             D(fprintf(stderr, "%*c+ if_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' named_expression ':' block elif_stmt"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -3588,7 +3682,7 @@ if_stmt_rule(Parser *p)
             _res = _Py_If ( a , b , CHECK ( _PyPegen_singleton_seq ( p , c ) ) , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -3599,7 +3693,7 @@ if_stmt_rule(Parser *p)
     }
     { // 'if' named_expression ':' block else_block?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> if_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' named_expression ':' block else_block?"));
@@ -3623,7 +3717,7 @@ if_stmt_rule(Parser *p)
             D(fprintf(stderr, "%*c+ if_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' named_expression ':' block else_block?"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -3633,7 +3727,7 @@ if_stmt_rule(Parser *p)
             _res = _Py_If ( a , b , c , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -3644,7 +3738,7 @@ if_stmt_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -3654,16 +3748,19 @@ if_stmt_rule(Parser *p)
 static stmt_ty
 elif_stmt_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     stmt_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -3672,7 +3769,7 @@ elif_stmt_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // 'elif' named_expression ':' block elif_stmt
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> elif_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'elif' named_expression ':' block elif_stmt"));
@@ -3696,7 +3793,7 @@ elif_stmt_rule(Parser *p)
             D(fprintf(stderr, "%*c+ elif_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'elif' named_expression ':' block elif_stmt"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -3706,7 +3803,7 @@ elif_stmt_rule(Parser *p)
             _res = _Py_If ( a , b , CHECK ( _PyPegen_singleton_seq ( p , c ) ) , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -3717,7 +3814,7 @@ elif_stmt_rule(Parser *p)
     }
     { // 'elif' named_expression ':' block else_block?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> elif_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'elif' named_expression ':' block else_block?"));
@@ -3741,7 +3838,7 @@ elif_stmt_rule(Parser *p)
             D(fprintf(stderr, "%*c+ elif_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'elif' named_expression ':' block else_block?"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -3751,7 +3848,7 @@ elif_stmt_rule(Parser *p)
             _res = _Py_If ( a , b , c , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -3762,7 +3859,7 @@ elif_stmt_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -3770,16 +3867,19 @@ elif_stmt_rule(Parser *p)
 static asdl_seq*
 else_block_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq* _res = NULL;
     int _mark = p->mark;
     { // 'else' ':' block
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> else_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'else' ':' block"));
@@ -3798,7 +3898,7 @@ else_block_rule(Parser *p)
             _res = b;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -3809,7 +3909,7 @@ else_block_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -3817,16 +3917,19 @@ else_block_rule(Parser *p)
 static stmt_ty
 while_stmt_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     stmt_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -3835,7 +3938,7 @@ while_stmt_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // 'while' named_expression ':' block else_block?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> while_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'while' named_expression ':' block else_block?"));
@@ -3859,7 +3962,7 @@ while_stmt_rule(Parser *p)
             D(fprintf(stderr, "%*c+ while_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'while' named_expression ':' block else_block?"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -3869,7 +3972,7 @@ while_stmt_rule(Parser *p)
             _res = _Py_While ( a , b , c , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -3880,7 +3983,7 @@ while_stmt_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -3891,16 +3994,19 @@ while_stmt_rule(Parser *p)
 static stmt_ty
 for_stmt_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     stmt_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -3909,7 +4015,7 @@ for_stmt_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // 'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> for_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block?"));
@@ -3945,7 +4051,7 @@ for_stmt_rule(Parser *p)
             D(fprintf(stderr, "%*c+ for_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block?"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -3955,7 +4061,7 @@ for_stmt_rule(Parser *p)
             _res = _Py_For ( t , ex , b , el , NEW_TYPE_COMMENT ( p , tc ) , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -3964,13 +4070,13 @@ for_stmt_rule(Parser *p)
         D(fprintf(stderr, "%*c%s for_stmt[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block?"));
         if (_cut_var) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
     }
     { // ASYNC 'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> for_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block?"));
@@ -4009,7 +4115,7 @@ for_stmt_rule(Parser *p)
             D(fprintf(stderr, "%*c+ for_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block?"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -4019,7 +4125,7 @@ for_stmt_rule(Parser *p)
             _res = CHECK_VERSION ( 5 , "Async for loops are" , _Py_AsyncFor ( t , ex , b , el , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ) );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -4028,13 +4134,13 @@ for_stmt_rule(Parser *p)
         D(fprintf(stderr, "%*c%s for_stmt[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block?"));
         if (_cut_var) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
     }
     if (p->call_invalid_rules) { // invalid_for_target
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> for_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_for_target"));
@@ -4053,7 +4159,7 @@ for_stmt_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -4065,16 +4171,19 @@ for_stmt_rule(Parser *p)
 static stmt_ty
 with_stmt_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     stmt_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -4083,7 +4192,7 @@ with_stmt_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // 'with' '(' ','.with_item+ ','? ')' ':' block
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'with' '(' ','.with_item+ ','? ')' ':' block"));
@@ -4114,7 +4223,7 @@ with_stmt_rule(Parser *p)
             D(fprintf(stderr, "%*c+ with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'with' '(' ','.with_item+ ','? ')' ':' block"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -4124,7 +4233,7 @@ with_stmt_rule(Parser *p)
             _res = _Py_With ( a , b , NULL , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -4135,7 +4244,7 @@ with_stmt_rule(Parser *p)
     }
     { // 'with' ','.with_item+ ':' TYPE_COMMENT? block
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'with' ','.with_item+ ':' TYPE_COMMENT? block"));
@@ -4159,7 +4268,7 @@ with_stmt_rule(Parser *p)
             D(fprintf(stderr, "%*c+ with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'with' ','.with_item+ ':' TYPE_COMMENT? block"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -4169,7 +4278,7 @@ with_stmt_rule(Parser *p)
             _res = _Py_With ( a , b , NEW_TYPE_COMMENT ( p , tc ) , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -4180,7 +4289,7 @@ with_stmt_rule(Parser *p)
     }
     { // ASYNC 'with' '(' ','.with_item+ ','? ')' ':' block
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC 'with' '(' ','.with_item+ ','? ')' ':' block"));
@@ -4214,7 +4323,7 @@ with_stmt_rule(Parser *p)
             D(fprintf(stderr, "%*c+ with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC 'with' '(' ','.with_item+ ','? ')' ':' block"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -4224,7 +4333,7 @@ with_stmt_rule(Parser *p)
             _res = CHECK_VERSION ( 5 , "Async with statements are" , _Py_AsyncWith ( a , b , NULL , EXTRA ) );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -4235,7 +4344,7 @@ with_stmt_rule(Parser *p)
     }
     { // ASYNC 'with' ','.with_item+ ':' TYPE_COMMENT? block
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC 'with' ','.with_item+ ':' TYPE_COMMENT? block"));
@@ -4262,7 +4371,7 @@ with_stmt_rule(Parser *p)
             D(fprintf(stderr, "%*c+ with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC 'with' ','.with_item+ ':' TYPE_COMMENT? block"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -4272,7 +4381,7 @@ with_stmt_rule(Parser *p)
             _res = CHECK_VERSION ( 5 , "Async with statements are" , _Py_AsyncWith ( a , b , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ) );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -4283,7 +4392,7 @@ with_stmt_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -4294,16 +4403,19 @@ with_stmt_rule(Parser *p)
 static withitem_ty
 with_item_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     withitem_ty _res = NULL;
     int _mark = p->mark;
     { // expression 'as' star_target &(',' | ')' | ':')
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> with_item[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression 'as' star_target &(',' | ')' | ':')"));
@@ -4324,7 +4436,7 @@ with_item_rule(Parser *p)
             _res = _Py_withitem ( e , t , p -> arena );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -4335,7 +4447,7 @@ with_item_rule(Parser *p)
     }
     if (p->call_invalid_rules) { // invalid_with_item
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> with_item[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_with_item"));
@@ -4354,7 +4466,7 @@ with_item_rule(Parser *p)
     }
     { // expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> with_item[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression"));
@@ -4367,7 +4479,7 @@ with_item_rule(Parser *p)
             _res = _Py_withitem ( e , NULL , p -> arena );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -4378,7 +4490,7 @@ with_item_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -4388,16 +4500,19 @@ with_item_rule(Parser *p)
 static stmt_ty
 try_stmt_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     stmt_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -4406,7 +4521,7 @@ try_stmt_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // 'try' ':' block finally_block
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> try_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'try' ':' block finally_block"));
@@ -4427,7 +4542,7 @@ try_stmt_rule(Parser *p)
             D(fprintf(stderr, "%*c+ try_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'try' ':' block finally_block"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -4437,7 +4552,7 @@ try_stmt_rule(Parser *p)
             _res = _Py_Try ( b , NULL , NULL , f , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -4448,7 +4563,7 @@ try_stmt_rule(Parser *p)
     }
     { // 'try' ':' block except_block+ else_block? finally_block?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> try_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'try' ':' block except_block+ else_block? finally_block?"));
@@ -4475,7 +4590,7 @@ try_stmt_rule(Parser *p)
             D(fprintf(stderr, "%*c+ try_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'try' ':' block except_block+ else_block? finally_block?"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -4485,7 +4600,7 @@ try_stmt_rule(Parser *p)
             _res = _Py_Try ( b , ex , el , f , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -4496,7 +4611,7 @@ try_stmt_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -4504,16 +4619,19 @@ try_stmt_rule(Parser *p)
 static excepthandler_ty
 except_block_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     excepthandler_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -4522,7 +4640,7 @@ except_block_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // 'except' expression ['as' NAME] ':' block
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> except_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' expression ['as' NAME] ':' block"));
@@ -4546,7 +4664,7 @@ except_block_rule(Parser *p)
             D(fprintf(stderr, "%*c+ except_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' expression ['as' NAME] ':' block"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -4556,7 +4674,7 @@ except_block_rule(Parser *p)
             _res = _Py_ExceptHandler ( e , ( t ) ? ( ( expr_ty ) t ) -> v . Name . id : NULL , b , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -4567,7 +4685,7 @@ except_block_rule(Parser *p)
     }
     { // 'except' ':' block
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> except_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' ':' block"));
@@ -4585,7 +4703,7 @@ except_block_rule(Parser *p)
             D(fprintf(stderr, "%*c+ except_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' ':' block"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -4595,7 +4713,7 @@ except_block_rule(Parser *p)
             _res = _Py_ExceptHandler ( NULL , NULL , b , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -4606,7 +4724,7 @@ except_block_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -4614,16 +4732,19 @@ except_block_rule(Parser *p)
 static asdl_seq*
 finally_block_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq* _res = NULL;
     int _mark = p->mark;
     { // 'finally' ':' block
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> finally_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'finally' ':' block"));
@@ -4642,7 +4763,7 @@ finally_block_rule(Parser *p)
             _res = a;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -4653,7 +4774,7 @@ finally_block_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -4661,16 +4782,19 @@ finally_block_rule(Parser *p)
 static stmt_ty
 return_stmt_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     stmt_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -4679,7 +4803,7 @@ return_stmt_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // 'return' star_expressions?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> return_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'return' star_expressions?"));
@@ -4694,7 +4818,7 @@ return_stmt_rule(Parser *p)
             D(fprintf(stderr, "%*c+ return_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'return' star_expressions?"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -4704,7 +4828,7 @@ return_stmt_rule(Parser *p)
             _res = _Py_Return ( a , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -4715,7 +4839,7 @@ return_stmt_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -4723,16 +4847,19 @@ return_stmt_rule(Parser *p)
 static stmt_ty
 raise_stmt_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     stmt_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -4741,7 +4868,7 @@ raise_stmt_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // 'raise' expression ['from' expression]
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> raise_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'raise' expression ['from' expression]"));
@@ -4759,7 +4886,7 @@ raise_stmt_rule(Parser *p)
             D(fprintf(stderr, "%*c+ raise_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'raise' expression ['from' expression]"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -4769,7 +4896,7 @@ raise_stmt_rule(Parser *p)
             _res = _Py_Raise ( a , b , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -4780,7 +4907,7 @@ raise_stmt_rule(Parser *p)
     }
     { // 'raise'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> raise_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'raise'"));
@@ -4792,7 +4919,7 @@ raise_stmt_rule(Parser *p)
             D(fprintf(stderr, "%*c+ raise_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'raise'"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -4802,7 +4929,7 @@ raise_stmt_rule(Parser *p)
             _res = _Py_Raise ( NULL , NULL , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -4813,7 +4940,7 @@ raise_stmt_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -4821,16 +4948,19 @@ raise_stmt_rule(Parser *p)
 static stmt_ty
 function_def_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     stmt_ty _res = NULL;
     int _mark = p->mark;
     { // decorators function_def_raw
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> function_def[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "decorators function_def_raw"));
@@ -4846,7 +4976,7 @@ function_def_rule(Parser *p)
             _res = _PyPegen_function_def_decorators ( p , d , f );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -4857,7 +4987,7 @@ function_def_rule(Parser *p)
     }
     { // function_def_raw
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> function_def[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "function_def_raw"));
@@ -4876,7 +5006,7 @@ function_def_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -4886,16 +5016,19 @@ function_def_rule(Parser *p)
 static stmt_ty
 function_def_raw_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     stmt_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -4904,7 +5037,7 @@ function_def_raw_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // 'def' NAME '(' params? ')' ['->' expression] ':' func_type_comment? block
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> function_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'def' NAME '(' params? ')' ['->' expression] ':' func_type_comment? block"));
@@ -4940,7 +5073,7 @@ function_def_raw_rule(Parser *p)
             D(fprintf(stderr, "%*c+ function_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'def' NAME '(' params? ')' ['->' expression] ':' func_type_comment? block"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -4950,7 +5083,7 @@ function_def_raw_rule(Parser *p)
             _res = _Py_FunctionDef ( n -> v . Name . id , ( params ) ? params : CHECK ( _PyPegen_empty_arguments ( p ) ) , b , NULL , a , NEW_TYPE_COMMENT ( p , tc ) , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -4961,7 +5094,7 @@ function_def_raw_rule(Parser *p)
     }
     { // ASYNC 'def' NAME '(' params? ')' ['->' expression] ':' func_type_comment? block
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> function_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC 'def' NAME '(' params? ')' ['->' expression] ':' func_type_comment? block"));
@@ -5000,7 +5133,7 @@ function_def_raw_rule(Parser *p)
             D(fprintf(stderr, "%*c+ function_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC 'def' NAME '(' params? ')' ['->' expression] ':' func_type_comment? block"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -5010,7 +5143,7 @@ function_def_raw_rule(Parser *p)
             _res = CHECK_VERSION ( 5 , "Async functions are" , _Py_AsyncFunctionDef ( n -> v . Name . id , ( params ) ? params : CHECK ( _PyPegen_empty_arguments ( p ) ) , b , NULL , a , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ) );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -5021,7 +5154,7 @@ function_def_raw_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -5032,16 +5165,19 @@ function_def_raw_rule(Parser *p)
 static Token*
 func_type_comment_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     Token* _res = NULL;
     int _mark = p->mark;
     { // NEWLINE TYPE_COMMENT &(NEWLINE INDENT)
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> func_type_comment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE TYPE_COMMENT &(NEWLINE INDENT)"));
@@ -5059,7 +5195,7 @@ func_type_comment_rule(Parser *p)
             _res = t;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -5070,7 +5206,7 @@ func_type_comment_rule(Parser *p)
     }
     if (p->call_invalid_rules) { // invalid_double_type_comments
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> func_type_comment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_double_type_comments"));
@@ -5089,7 +5225,7 @@ func_type_comment_rule(Parser *p)
     }
     { // TYPE_COMMENT
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> func_type_comment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "TYPE_COMMENT"));
@@ -5108,7 +5244,7 @@ func_type_comment_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -5116,16 +5252,19 @@ func_type_comment_rule(Parser *p)
 static arguments_ty
 params_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     arguments_ty _res = NULL;
     int _mark = p->mark;
     if (p->call_invalid_rules) { // invalid_parameters
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> params[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_parameters"));
@@ -5144,7 +5283,7 @@ params_rule(Parser *p)
     }
     { // parameters
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> params[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "parameters"));
@@ -5163,7 +5302,7 @@ params_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -5176,16 +5315,19 @@ params_rule(Parser *p)
 static arguments_ty
 parameters_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     arguments_ty _res = NULL;
     int _mark = p->mark;
     { // slash_no_default param_no_default* param_with_default* star_etc?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default param_no_default* param_with_default* star_etc?"));
@@ -5207,7 +5349,7 @@ parameters_rule(Parser *p)
             _res = _PyPegen_make_arguments ( p , a , NULL , b , c , d );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -5218,7 +5360,7 @@ parameters_rule(Parser *p)
     }
     { // slash_with_default param_with_default* star_etc?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default param_with_default* star_etc?"));
@@ -5237,7 +5379,7 @@ parameters_rule(Parser *p)
             _res = _PyPegen_make_arguments ( p , NULL , a , NULL , b , c );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -5248,7 +5390,7 @@ parameters_rule(Parser *p)
     }
     { // param_no_default+ param_with_default* star_etc?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default+ param_with_default* star_etc?"));
@@ -5267,7 +5409,7 @@ parameters_rule(Parser *p)
             _res = _PyPegen_make_arguments ( p , NULL , NULL , a , b , c );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -5278,7 +5420,7 @@ parameters_rule(Parser *p)
     }
     { // param_with_default+ star_etc?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default+ star_etc?"));
@@ -5294,7 +5436,7 @@ parameters_rule(Parser *p)
             _res = _PyPegen_make_arguments ( p , NULL , NULL , NULL , a , b );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -5305,7 +5447,7 @@ parameters_rule(Parser *p)
     }
     { // star_etc
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_etc"));
@@ -5318,7 +5460,7 @@ parameters_rule(Parser *p)
             _res = _PyPegen_make_arguments ( p , NULL , NULL , NULL , NULL , a );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -5329,7 +5471,7 @@ parameters_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -5337,16 +5479,19 @@ parameters_rule(Parser *p)
 static asdl_seq*
 slash_no_default_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq* _res = NULL;
     int _mark = p->mark;
     { // param_no_default+ '/' ','
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> slash_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default+ '/' ','"));
@@ -5365,7 +5510,7 @@ slash_no_default_rule(Parser *p)
             _res = a;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -5376,7 +5521,7 @@ slash_no_default_rule(Parser *p)
     }
     { // param_no_default+ '/' &')'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> slash_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default+ '/' &')'"));
@@ -5394,7 +5539,7 @@ slash_no_default_rule(Parser *p)
             _res = a;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -5405,7 +5550,7 @@ slash_no_default_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -5415,16 +5560,19 @@ slash_no_default_rule(Parser *p)
 static SlashWithDefault*
 slash_with_default_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     SlashWithDefault* _res = NULL;
     int _mark = p->mark;
     { // param_no_default* param_with_default+ '/' ','
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> slash_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default* param_with_default+ '/' ','"));
@@ -5446,7 +5594,7 @@ slash_with_default_rule(Parser *p)
             _res = _PyPegen_slash_with_default ( p , a , b );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -5457,7 +5605,7 @@ slash_with_default_rule(Parser *p)
     }
     { // param_no_default* param_with_default+ '/' &')'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> slash_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default* param_with_default+ '/' &')'"));
@@ -5478,7 +5626,7 @@ slash_with_default_rule(Parser *p)
             _res = _PyPegen_slash_with_default ( p , a , b );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -5489,7 +5637,7 @@ slash_with_default_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -5501,16 +5649,19 @@ slash_with_default_rule(Parser *p)
 static StarEtc*
 star_etc_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     StarEtc* _res = NULL;
     int _mark = p->mark;
     { // '*' param_no_default param_maybe_default* kwds?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' param_no_default param_maybe_default* kwds?"));
@@ -5532,7 +5683,7 @@ star_etc_rule(Parser *p)
             _res = _PyPegen_star_etc ( p , a , b , c );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -5543,7 +5694,7 @@ star_etc_rule(Parser *p)
     }
     { // '*' ',' param_maybe_default+ kwds?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' ',' param_maybe_default+ kwds?"));
@@ -5565,7 +5716,7 @@ star_etc_rule(Parser *p)
             _res = _PyPegen_star_etc ( p , NULL , b , c );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -5576,7 +5727,7 @@ star_etc_rule(Parser *p)
     }
     { // kwds
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwds"));
@@ -5589,7 +5740,7 @@ star_etc_rule(Parser *p)
             _res = _PyPegen_star_etc ( p , NULL , NULL , a );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -5600,7 +5751,7 @@ star_etc_rule(Parser *p)
     }
     if (p->call_invalid_rules) { // invalid_star_etc
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_star_etc"));
@@ -5619,7 +5770,7 @@ star_etc_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -5627,16 +5778,19 @@ star_etc_rule(Parser *p)
 static arg_ty
 kwds_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     arg_ty _res = NULL;
     int _mark = p->mark;
     { // '**' param_no_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> kwds[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' param_no_default"));
@@ -5652,7 +5806,7 @@ kwds_rule(Parser *p)
             _res = a;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -5663,7 +5817,7 @@ kwds_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -5671,16 +5825,19 @@ kwds_rule(Parser *p)
 static arg_ty
 param_no_default_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     arg_ty _res = NULL;
     int _mark = p->mark;
     { // param ',' TYPE_COMMENT?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> param_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param ',' TYPE_COMMENT?"));
@@ -5699,7 +5856,7 @@ param_no_default_rule(Parser *p)
             _res = _PyPegen_add_type_comment_to_arg ( p , a , tc );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -5710,7 +5867,7 @@ param_no_default_rule(Parser *p)
     }
     { // param TYPE_COMMENT? &')'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> param_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param TYPE_COMMENT? &')'"));
@@ -5728,7 +5885,7 @@ param_no_default_rule(Parser *p)
             _res = _PyPegen_add_type_comment_to_arg ( p , a , tc );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -5739,7 +5896,7 @@ param_no_default_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -5747,16 +5904,19 @@ param_no_default_rule(Parser *p)
 static NameDefaultPair*
 param_with_default_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     NameDefaultPair* _res = NULL;
     int _mark = p->mark;
     { // param default ',' TYPE_COMMENT?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> param_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param default ',' TYPE_COMMENT?"));
@@ -5778,7 +5938,7 @@ param_with_default_rule(Parser *p)
             _res = _PyPegen_name_default_pair ( p , a , c , tc );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -5789,7 +5949,7 @@ param_with_default_rule(Parser *p)
     }
     { // param default TYPE_COMMENT? &')'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> param_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param default TYPE_COMMENT? &')'"));
@@ -5810,7 +5970,7 @@ param_with_default_rule(Parser *p)
             _res = _PyPegen_name_default_pair ( p , a , c , tc );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -5821,7 +5981,7 @@ param_with_default_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -5831,16 +5991,19 @@ param_with_default_rule(Parser *p)
 static NameDefaultPair*
 param_maybe_default_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     NameDefaultPair* _res = NULL;
     int _mark = p->mark;
     { // param default? ',' TYPE_COMMENT?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> param_maybe_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param default? ',' TYPE_COMMENT?"));
@@ -5862,7 +6025,7 @@ param_maybe_default_rule(Parser *p)
             _res = _PyPegen_name_default_pair ( p , a , c , tc );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -5873,7 +6036,7 @@ param_maybe_default_rule(Parser *p)
     }
     { // param default? TYPE_COMMENT? &')'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> param_maybe_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param default? TYPE_COMMENT? &')'"));
@@ -5894,7 +6057,7 @@ param_maybe_default_rule(Parser *p)
             _res = _PyPegen_name_default_pair ( p , a , c , tc );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -5905,7 +6068,7 @@ param_maybe_default_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -5913,16 +6076,19 @@ param_maybe_default_rule(Parser *p)
 static arg_ty
 param_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     arg_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -5931,7 +6097,7 @@ param_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // NAME annotation?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> param[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME annotation?"));
@@ -5946,7 +6112,7 @@ param_rule(Parser *p)
             D(fprintf(stderr, "%*c+ param[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME annotation?"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -5956,7 +6122,7 @@ param_rule(Parser *p)
             _res = _Py_arg ( a -> v . Name . id , b , NULL , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -5967,7 +6133,7 @@ param_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -5975,16 +6141,19 @@ param_rule(Parser *p)
 static expr_ty
 annotation_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     { // ':' expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> annotation[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':' expression"));
@@ -6000,7 +6169,7 @@ annotation_rule(Parser *p)
             _res = a;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -6011,7 +6180,7 @@ annotation_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -6019,16 +6188,19 @@ annotation_rule(Parser *p)
 static expr_ty
 default_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     { // '=' expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'=' expression"));
@@ -6044,7 +6216,7 @@ default_rule(Parser *p)
             _res = a;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -6055,7 +6227,7 @@ default_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -6063,16 +6235,19 @@ default_rule(Parser *p)
 static asdl_seq*
 decorators_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq* _res = NULL;
     int _mark = p->mark;
     { // (('@' named_expression NEWLINE))+
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> decorators[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(('@' named_expression NEWLINE))+"));
@@ -6085,7 +6260,7 @@ decorators_rule(Parser *p)
             _res = a;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -6096,7 +6271,7 @@ decorators_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -6104,16 +6279,19 @@ decorators_rule(Parser *p)
 static stmt_ty
 class_def_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     stmt_ty _res = NULL;
     int _mark = p->mark;
     { // decorators class_def_raw
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> class_def[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "decorators class_def_raw"));
@@ -6129,7 +6307,7 @@ class_def_rule(Parser *p)
             _res = _PyPegen_class_def_decorators ( p , a , b );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -6140,7 +6318,7 @@ class_def_rule(Parser *p)
     }
     { // class_def_raw
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> class_def[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "class_def_raw"));
@@ -6159,7 +6337,7 @@ class_def_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -6167,16 +6345,19 @@ class_def_rule(Parser *p)
 static stmt_ty
 class_def_raw_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     stmt_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -6185,7 +6366,7 @@ class_def_raw_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // 'class' NAME ['(' arguments? ')'] ':' block
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> class_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'class' NAME ['(' arguments? ')'] ':' block"));
@@ -6209,7 +6390,7 @@ class_def_raw_rule(Parser *p)
             D(fprintf(stderr, "%*c+ class_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'class' NAME ['(' arguments? ')'] ':' block"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -6219,7 +6400,7 @@ class_def_raw_rule(Parser *p)
             _res = _Py_ClassDef ( a -> v . Name . id , ( b ) ? ( ( expr_ty ) b ) -> v . Call . args : NULL , ( b ) ? ( ( expr_ty ) b ) -> v . Call . keywords : NULL , c , NULL , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -6230,7 +6411,7 @@ class_def_raw_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -6238,20 +6419,23 @@ class_def_raw_rule(Parser *p)
 static asdl_seq*
 block_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq* _res = NULL;
     if (_PyPegen_is_memoized(p, block_type, &_res)) {
-        D(p->level--);
+        p->level--;
         return _res;
     }
     int _mark = p->mark;
     { // NEWLINE INDENT statements DEDENT
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE INDENT statements DEDENT"));
@@ -6273,7 +6457,7 @@ block_rule(Parser *p)
             _res = a;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -6284,7 +6468,7 @@ block_rule(Parser *p)
     }
     { // simple_stmt
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "simple_stmt"));
@@ -6303,7 +6487,7 @@ block_rule(Parser *p)
     }
     if (p->call_invalid_rules) { // invalid_block
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_block"));
@@ -6323,7 +6507,7 @@ block_rule(Parser *p)
     _res = NULL;
   done:
     _PyPegen_insert_memo(p, _mark, block_type, _res);
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -6334,16 +6518,19 @@ block_rule(Parser *p)
 static expr_ty
 star_expressions_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -6352,7 +6539,7 @@ star_expressions_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // star_expression ((',' star_expression))+ ','?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> star_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expression ((',' star_expression))+ ','?"));
@@ -6371,7 +6558,7 @@ star_expressions_rule(Parser *p)
             D(fprintf(stderr, "%*c+ star_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expression ((',' star_expression))+ ','?"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -6381,7 +6568,7 @@ star_expressions_rule(Parser *p)
             _res = _Py_Tuple ( CHECK ( _PyPegen_seq_insert_in_front ( p , a , b ) ) , Load , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -6392,7 +6579,7 @@ star_expressions_rule(Parser *p)
     }
     { // star_expression ','
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> star_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expression ','"));
@@ -6407,7 +6594,7 @@ star_expressions_rule(Parser *p)
             D(fprintf(stderr, "%*c+ star_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expression ','"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -6417,7 +6604,7 @@ star_expressions_rule(Parser *p)
             _res = _Py_Tuple ( CHECK ( _PyPegen_singleton_seq ( p , a ) ) , Load , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -6428,7 +6615,7 @@ star_expressions_rule(Parser *p)
     }
     { // star_expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> star_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expression"));
@@ -6447,7 +6634,7 @@ star_expressions_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -6455,20 +6642,23 @@ star_expressions_rule(Parser *p)
 static expr_ty
 star_expression_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     if (_PyPegen_is_memoized(p, star_expression_type, &_res)) {
-        D(p->level--);
+        p->level--;
         return _res;
     }
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -6477,7 +6667,7 @@ star_expression_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // '*' bitwise_or
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> star_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' bitwise_or"));
@@ -6492,7 +6682,7 @@ star_expression_rule(Parser *p)
             D(fprintf(stderr, "%*c+ star_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' bitwise_or"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -6502,7 +6692,7 @@ star_expression_rule(Parser *p)
             _res = _Py_Starred ( a , Load , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -6513,7 +6703,7 @@ star_expression_rule(Parser *p)
     }
     { // expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> star_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression"));
@@ -6533,7 +6723,7 @@ star_expression_rule(Parser *p)
     _res = NULL;
   done:
     _PyPegen_insert_memo(p, _mark, star_expression_type, _res);
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -6541,16 +6731,19 @@ star_expression_rule(Parser *p)
 static asdl_seq*
 star_named_expressions_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq* _res = NULL;
     int _mark = p->mark;
     { // ','.star_named_expression+ ','?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> star_named_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.star_named_expression+ ','?"));
@@ -6567,7 +6760,7 @@ star_named_expressions_rule(Parser *p)
             _res = a;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -6578,7 +6771,7 @@ star_named_expressions_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -6586,16 +6779,19 @@ star_named_expressions_rule(Parser *p)
 static expr_ty
 star_named_expression_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -6604,7 +6800,7 @@ star_named_expression_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // '*' bitwise_or
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> star_named_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' bitwise_or"));
@@ -6619,7 +6815,7 @@ star_named_expression_rule(Parser *p)
             D(fprintf(stderr, "%*c+ star_named_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' bitwise_or"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -6629,7 +6825,7 @@ star_named_expression_rule(Parser *p)
             _res = _Py_Starred ( a , Load , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -6640,7 +6836,7 @@ star_named_expression_rule(Parser *p)
     }
     { // named_expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> star_named_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "named_expression"));
@@ -6659,7 +6855,7 @@ star_named_expression_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -6667,16 +6863,19 @@ star_named_expression_rule(Parser *p)
 static expr_ty
 named_expression_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -6685,7 +6884,7 @@ named_expression_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // NAME ':=' ~ expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> named_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME ':=' ~ expression"));
@@ -6706,7 +6905,7 @@ named_expression_rule(Parser *p)
             D(fprintf(stderr, "%*c+ named_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME ':=' ~ expression"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -6716,7 +6915,7 @@ named_expression_rule(Parser *p)
             _res = _Py_NamedExpr ( CHECK ( _PyPegen_set_expr_context ( p , a , Store ) ) , b , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -6725,13 +6924,13 @@ named_expression_rule(Parser *p)
         D(fprintf(stderr, "%*c%s named_expression[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME ':=' ~ expression"));
         if (_cut_var) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
     }
     { // expression !':='
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> named_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='"));
@@ -6752,7 +6951,7 @@ named_expression_rule(Parser *p)
     }
     if (p->call_invalid_rules) { // invalid_named_expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> named_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_named_expression"));
@@ -6771,7 +6970,7 @@ named_expression_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -6779,16 +6978,19 @@ named_expression_rule(Parser *p)
 static expr_ty
 annotated_rhs_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     { // yield_expr
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> annotated_rhs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr"));
@@ -6807,7 +7009,7 @@ annotated_rhs_rule(Parser *p)
     }
     { // star_expressions
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> annotated_rhs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions"));
@@ -6826,7 +7028,7 @@ annotated_rhs_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -6834,16 +7036,19 @@ annotated_rhs_rule(Parser *p)
 static expr_ty
 expressions_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -6852,7 +7057,7 @@ expressions_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // expression ((',' expression))+ ','?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ((',' expression))+ ','?"));
@@ -6871,7 +7076,7 @@ expressions_rule(Parser *p)
             D(fprintf(stderr, "%*c+ expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ((',' expression))+ ','?"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -6881,7 +7086,7 @@ expressions_rule(Parser *p)
             _res = _Py_Tuple ( CHECK ( _PyPegen_seq_insert_in_front ( p , a , b ) ) , Load , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -6892,7 +7097,7 @@ expressions_rule(Parser *p)
     }
     { // expression ','
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ','"));
@@ -6907,7 +7112,7 @@ expressions_rule(Parser *p)
             D(fprintf(stderr, "%*c+ expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ','"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -6917,7 +7122,7 @@ expressions_rule(Parser *p)
             _res = _Py_Tuple ( CHECK ( _PyPegen_singleton_seq ( p , a ) ) , Load , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -6928,7 +7133,7 @@ expressions_rule(Parser *p)
     }
     { // expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression"));
@@ -6947,7 +7152,7 @@ expressions_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -6955,20 +7160,23 @@ expressions_rule(Parser *p)
 static expr_ty
 expression_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     if (_PyPegen_is_memoized(p, expression_type, &_res)) {
-        D(p->level--);
+        p->level--;
         return _res;
     }
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -6977,7 +7185,7 @@ expression_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // disjunction 'if' disjunction 'else' expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "disjunction 'if' disjunction 'else' expression"));
@@ -7001,7 +7209,7 @@ expression_rule(Parser *p)
             D(fprintf(stderr, "%*c+ expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "disjunction 'if' disjunction 'else' expression"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -7011,7 +7219,7 @@ expression_rule(Parser *p)
             _res = _Py_IfExp ( b , a , c , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -7022,7 +7230,7 @@ expression_rule(Parser *p)
     }
     { // disjunction
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "disjunction"));
@@ -7041,7 +7249,7 @@ expression_rule(Parser *p)
     }
     { // lambdef
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambdef"));
@@ -7061,7 +7269,7 @@ expression_rule(Parser *p)
     _res = NULL;
   done:
     _PyPegen_insert_memo(p, _mark, expression_type, _res);
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -7069,16 +7277,19 @@ expression_rule(Parser *p)
 static expr_ty
 lambdef_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -7087,7 +7298,7 @@ lambdef_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // 'lambda' lambda_params? ':' expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> lambdef[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'lambda' lambda_params? ':' expression"));
@@ -7108,7 +7319,7 @@ lambdef_rule(Parser *p)
             D(fprintf(stderr, "%*c+ lambdef[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'lambda' lambda_params? ':' expression"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -7118,7 +7329,7 @@ lambdef_rule(Parser *p)
             _res = _Py_Lambda ( ( a ) ? a : CHECK ( _PyPegen_empty_arguments ( p ) ) , b , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -7129,7 +7340,7 @@ lambdef_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -7137,16 +7348,19 @@ lambdef_rule(Parser *p)
 static arguments_ty
 lambda_params_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     arguments_ty _res = NULL;
     int _mark = p->mark;
     if (p->call_invalid_rules) { // invalid_lambda_parameters
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> lambda_params[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_lambda_parameters"));
@@ -7165,7 +7379,7 @@ lambda_params_rule(Parser *p)
     }
     { // lambda_parameters
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> lambda_params[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_parameters"));
@@ -7184,7 +7398,7 @@ lambda_params_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -7197,16 +7411,19 @@ lambda_params_rule(Parser *p)
 static arguments_ty
 lambda_parameters_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     arguments_ty _res = NULL;
     int _mark = p->mark;
     { // lambda_slash_no_default lambda_param_no_default* lambda_param_with_default* lambda_star_etc?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default lambda_param_no_default* lambda_param_with_default* lambda_star_etc?"));
@@ -7228,7 +7445,7 @@ lambda_parameters_rule(Parser *p)
             _res = _PyPegen_make_arguments ( p , a , NULL , b , c , d );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -7239,7 +7456,7 @@ lambda_parameters_rule(Parser *p)
     }
     { // lambda_slash_with_default lambda_param_with_default* lambda_star_etc?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default lambda_param_with_default* lambda_star_etc?"));
@@ -7258,7 +7475,7 @@ lambda_parameters_rule(Parser *p)
             _res = _PyPegen_make_arguments ( p , NULL , a , NULL , b , c );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -7269,7 +7486,7 @@ lambda_parameters_rule(Parser *p)
     }
     { // lambda_param_no_default+ lambda_param_with_default* lambda_star_etc?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default+ lambda_param_with_default* lambda_star_etc?"));
@@ -7288,7 +7505,7 @@ lambda_parameters_rule(Parser *p)
             _res = _PyPegen_make_arguments ( p , NULL , NULL , a , b , c );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -7299,7 +7516,7 @@ lambda_parameters_rule(Parser *p)
     }
     { // lambda_param_with_default+ lambda_star_etc?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+ lambda_star_etc?"));
@@ -7315,7 +7532,7 @@ lambda_parameters_rule(Parser *p)
             _res = _PyPegen_make_arguments ( p , NULL , NULL , NULL , a , b );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -7326,7 +7543,7 @@ lambda_parameters_rule(Parser *p)
     }
     { // lambda_star_etc
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_star_etc"));
@@ -7339,7 +7556,7 @@ lambda_parameters_rule(Parser *p)
             _res = _PyPegen_make_arguments ( p , NULL , NULL , NULL , NULL , a );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -7350,7 +7567,7 @@ lambda_parameters_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -7360,16 +7577,19 @@ lambda_parameters_rule(Parser *p)
 static asdl_seq*
 lambda_slash_no_default_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq* _res = NULL;
     int _mark = p->mark;
     { // lambda_param_no_default+ '/' ','
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> lambda_slash_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default+ '/' ','"));
@@ -7388,7 +7608,7 @@ lambda_slash_no_default_rule(Parser *p)
             _res = a;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -7399,7 +7619,7 @@ lambda_slash_no_default_rule(Parser *p)
     }
     { // lambda_param_no_default+ '/' &':'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> lambda_slash_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default+ '/' &':'"));
@@ -7417,7 +7637,7 @@ lambda_slash_no_default_rule(Parser *p)
             _res = a;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -7428,7 +7648,7 @@ lambda_slash_no_default_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -7438,16 +7658,19 @@ lambda_slash_no_default_rule(Parser *p)
 static SlashWithDefault*
 lambda_slash_with_default_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     SlashWithDefault* _res = NULL;
     int _mark = p->mark;
     { // lambda_param_no_default* lambda_param_with_default+ '/' ','
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> lambda_slash_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* lambda_param_with_default+ '/' ','"));
@@ -7469,7 +7692,7 @@ lambda_slash_with_default_rule(Parser *p)
             _res = _PyPegen_slash_with_default ( p , a , b );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -7480,7 +7703,7 @@ lambda_slash_with_default_rule(Parser *p)
     }
     { // lambda_param_no_default* lambda_param_with_default+ '/' &':'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> lambda_slash_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* lambda_param_with_default+ '/' &':'"));
@@ -7501,7 +7724,7 @@ lambda_slash_with_default_rule(Parser *p)
             _res = _PyPegen_slash_with_default ( p , a , b );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -7512,7 +7735,7 @@ lambda_slash_with_default_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -7524,16 +7747,19 @@ lambda_slash_with_default_rule(Parser *p)
 static StarEtc*
 lambda_star_etc_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     StarEtc* _res = NULL;
     int _mark = p->mark;
     { // '*' lambda_param_no_default lambda_param_maybe_default* lambda_kwds?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' lambda_param_no_default lambda_param_maybe_default* lambda_kwds?"));
@@ -7555,7 +7781,7 @@ lambda_star_etc_rule(Parser *p)
             _res = _PyPegen_star_etc ( p , a , b , c );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -7566,7 +7792,7 @@ lambda_star_etc_rule(Parser *p)
     }
     { // '*' ',' lambda_param_maybe_default+ lambda_kwds?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' ',' lambda_param_maybe_default+ lambda_kwds?"));
@@ -7588,7 +7814,7 @@ lambda_star_etc_rule(Parser *p)
             _res = _PyPegen_star_etc ( p , NULL , b , c );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -7599,7 +7825,7 @@ lambda_star_etc_rule(Parser *p)
     }
     { // lambda_kwds
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_kwds"));
@@ -7612,7 +7838,7 @@ lambda_star_etc_rule(Parser *p)
             _res = _PyPegen_star_etc ( p , NULL , NULL , a );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -7623,7 +7849,7 @@ lambda_star_etc_rule(Parser *p)
     }
     if (p->call_invalid_rules) { // invalid_lambda_star_etc
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_lambda_star_etc"));
@@ -7642,7 +7868,7 @@ lambda_star_etc_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -7650,16 +7876,19 @@ lambda_star_etc_rule(Parser *p)
 static arg_ty
 lambda_kwds_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     arg_ty _res = NULL;
     int _mark = p->mark;
     { // '**' lambda_param_no_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> lambda_kwds[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' lambda_param_no_default"));
@@ -7675,7 +7904,7 @@ lambda_kwds_rule(Parser *p)
             _res = a;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -7686,7 +7915,7 @@ lambda_kwds_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -7694,16 +7923,19 @@ lambda_kwds_rule(Parser *p)
 static arg_ty
 lambda_param_no_default_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     arg_ty _res = NULL;
     int _mark = p->mark;
     { // lambda_param ','
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> lambda_param_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param ','"));
@@ -7719,7 +7951,7 @@ lambda_param_no_default_rule(Parser *p)
             _res = a;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -7730,7 +7962,7 @@ lambda_param_no_default_rule(Parser *p)
     }
     { // lambda_param &':'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> lambda_param_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param &':'"));
@@ -7745,7 +7977,7 @@ lambda_param_no_default_rule(Parser *p)
             _res = a;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -7756,7 +7988,7 @@ lambda_param_no_default_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -7764,16 +7996,19 @@ lambda_param_no_default_rule(Parser *p)
 static NameDefaultPair*
 lambda_param_with_default_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     NameDefaultPair* _res = NULL;
     int _mark = p->mark;
     { // lambda_param default ','
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> lambda_param_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param default ','"));
@@ -7792,7 +8027,7 @@ lambda_param_with_default_rule(Parser *p)
             _res = _PyPegen_name_default_pair ( p , a , c , NULL );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -7803,7 +8038,7 @@ lambda_param_with_default_rule(Parser *p)
     }
     { // lambda_param default &':'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> lambda_param_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param default &':'"));
@@ -7821,7 +8056,7 @@ lambda_param_with_default_rule(Parser *p)
             _res = _PyPegen_name_default_pair ( p , a , c , NULL );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -7832,7 +8067,7 @@ lambda_param_with_default_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -7840,16 +8075,19 @@ lambda_param_with_default_rule(Parser *p)
 static NameDefaultPair*
 lambda_param_maybe_default_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     NameDefaultPair* _res = NULL;
     int _mark = p->mark;
     { // lambda_param default? ','
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> lambda_param_maybe_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param default? ','"));
@@ -7868,7 +8106,7 @@ lambda_param_maybe_default_rule(Parser *p)
             _res = _PyPegen_name_default_pair ( p , a , c , NULL );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -7879,7 +8117,7 @@ lambda_param_maybe_default_rule(Parser *p)
     }
     { // lambda_param default? &':'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> lambda_param_maybe_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param default? &':'"));
@@ -7897,7 +8135,7 @@ lambda_param_maybe_default_rule(Parser *p)
             _res = _PyPegen_name_default_pair ( p , a , c , NULL );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -7908,7 +8146,7 @@ lambda_param_maybe_default_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -7916,16 +8154,19 @@ lambda_param_maybe_default_rule(Parser *p)
 static arg_ty
 lambda_param_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     arg_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -7934,7 +8175,7 @@ lambda_param_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // NAME
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> lambda_param[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME"));
@@ -7946,7 +8187,7 @@ lambda_param_rule(Parser *p)
             D(fprintf(stderr, "%*c+ lambda_param[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -7956,7 +8197,7 @@ lambda_param_rule(Parser *p)
             _res = _Py_arg ( a -> v . Name . id , NULL , NULL , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -7967,7 +8208,7 @@ lambda_param_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -7975,20 +8216,23 @@ lambda_param_rule(Parser *p)
 static expr_ty
 disjunction_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     if (_PyPegen_is_memoized(p, disjunction_type, &_res)) {
-        D(p->level--);
+        p->level--;
         return _res;
     }
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -7997,7 +8241,7 @@ disjunction_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // conjunction (('or' conjunction))+
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> disjunction[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "conjunction (('or' conjunction))+"));
@@ -8012,7 +8256,7 @@ disjunction_rule(Parser *p)
             D(fprintf(stderr, "%*c+ disjunction[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "conjunction (('or' conjunction))+"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -8022,7 +8266,7 @@ disjunction_rule(Parser *p)
             _res = _Py_BoolOp ( Or , CHECK ( _PyPegen_seq_insert_in_front ( p , a , b ) ) , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -8033,7 +8277,7 @@ disjunction_rule(Parser *p)
     }
     { // conjunction
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> disjunction[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "conjunction"));
@@ -8053,7 +8297,7 @@ disjunction_rule(Parser *p)
     _res = NULL;
   done:
     _PyPegen_insert_memo(p, _mark, disjunction_type, _res);
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -8061,20 +8305,23 @@ disjunction_rule(Parser *p)
 static expr_ty
 conjunction_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     if (_PyPegen_is_memoized(p, conjunction_type, &_res)) {
-        D(p->level--);
+        p->level--;
         return _res;
     }
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -8083,7 +8330,7 @@ conjunction_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // inversion (('and' inversion))+
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> conjunction[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "inversion (('and' inversion))+"));
@@ -8098,7 +8345,7 @@ conjunction_rule(Parser *p)
             D(fprintf(stderr, "%*c+ conjunction[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "inversion (('and' inversion))+"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -8108,7 +8355,7 @@ conjunction_rule(Parser *p)
             _res = _Py_BoolOp ( And , CHECK ( _PyPegen_seq_insert_in_front ( p , a , b ) ) , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -8119,7 +8366,7 @@ conjunction_rule(Parser *p)
     }
     { // inversion
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> conjunction[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "inversion"));
@@ -8139,7 +8386,7 @@ conjunction_rule(Parser *p)
     _res = NULL;
   done:
     _PyPegen_insert_memo(p, _mark, conjunction_type, _res);
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -8147,20 +8394,23 @@ conjunction_rule(Parser *p)
 static expr_ty
 inversion_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     if (_PyPegen_is_memoized(p, inversion_type, &_res)) {
-        D(p->level--);
+        p->level--;
         return _res;
     }
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -8169,7 +8419,7 @@ inversion_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // 'not' inversion
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> inversion[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'not' inversion"));
@@ -8184,7 +8434,7 @@ inversion_rule(Parser *p)
             D(fprintf(stderr, "%*c+ inversion[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'not' inversion"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -8194,7 +8444,7 @@ inversion_rule(Parser *p)
             _res = _Py_UnaryOp ( Not , a , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -8205,7 +8455,7 @@ inversion_rule(Parser *p)
     }
     { // comparison
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> inversion[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "comparison"));
@@ -8225,7 +8475,7 @@ inversion_rule(Parser *p)
     _res = NULL;
   done:
     _PyPegen_insert_memo(p, _mark, inversion_type, _res);
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -8233,16 +8483,19 @@ inversion_rule(Parser *p)
 static expr_ty
 comparison_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -8251,7 +8504,7 @@ comparison_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // bitwise_or compare_op_bitwise_or_pair+
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> comparison[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "bitwise_or compare_op_bitwise_or_pair+"));
@@ -8266,7 +8519,7 @@ comparison_rule(Parser *p)
             D(fprintf(stderr, "%*c+ comparison[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "bitwise_or compare_op_bitwise_or_pair+"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -8276,7 +8529,7 @@ comparison_rule(Parser *p)
             _res = _Py_Compare ( a , CHECK ( _PyPegen_get_cmpops ( p , b ) ) , CHECK ( _PyPegen_get_exprs ( p , b ) ) , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -8287,7 +8540,7 @@ comparison_rule(Parser *p)
     }
     { // bitwise_or
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> comparison[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "bitwise_or"));
@@ -8306,7 +8559,7 @@ comparison_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -8324,16 +8577,19 @@ comparison_rule(Parser *p)
 static CmpopExprPair*
 compare_op_bitwise_or_pair_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     CmpopExprPair* _res = NULL;
     int _mark = p->mark;
     { // eq_bitwise_or
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "eq_bitwise_or"));
@@ -8352,7 +8608,7 @@ compare_op_bitwise_or_pair_rule(Parser *p)
     }
     { // noteq_bitwise_or
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "noteq_bitwise_or"));
@@ -8371,7 +8627,7 @@ compare_op_bitwise_or_pair_rule(Parser *p)
     }
     { // lte_bitwise_or
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lte_bitwise_or"));
@@ -8390,7 +8646,7 @@ compare_op_bitwise_or_pair_rule(Parser *p)
     }
     { // lt_bitwise_or
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lt_bitwise_or"));
@@ -8409,7 +8665,7 @@ compare_op_bitwise_or_pair_rule(Parser *p)
     }
     { // gte_bitwise_or
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "gte_bitwise_or"));
@@ -8428,7 +8684,7 @@ compare_op_bitwise_or_pair_rule(Parser *p)
     }
     { // gt_bitwise_or
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "gt_bitwise_or"));
@@ -8447,7 +8703,7 @@ compare_op_bitwise_or_pair_rule(Parser *p)
     }
     { // notin_bitwise_or
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "notin_bitwise_or"));
@@ -8466,7 +8722,7 @@ compare_op_bitwise_or_pair_rule(Parser *p)
     }
     { // in_bitwise_or
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "in_bitwise_or"));
@@ -8485,7 +8741,7 @@ compare_op_bitwise_or_pair_rule(Parser *p)
     }
     { // isnot_bitwise_or
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "isnot_bitwise_or"));
@@ -8504,7 +8760,7 @@ compare_op_bitwise_or_pair_rule(Parser *p)
     }
     { // is_bitwise_or
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "is_bitwise_or"));
@@ -8523,7 +8779,7 @@ compare_op_bitwise_or_pair_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -8531,16 +8787,19 @@ compare_op_bitwise_or_pair_rule(Parser *p)
 static CmpopExprPair*
 eq_bitwise_or_rule(Parser *p)
 {
-    D(p->level++);
-    if (p->error_indicator) {
-        D(p->level--);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
+    if (p->error_indicator) {
+        p->level--;
         return NULL;
     }
     CmpopExprPair* _res = NULL;
     int _mark = p->mark;
     { // '==' bitwise_or
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> eq_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'==' bitwise_or"));
@@ -8556,7 +8815,7 @@ eq_bitwise_or_rule(Parser *p)
             _res = _PyPegen_cmpop_expr_pair ( p , Eq , a );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -8567,7 +8826,7 @@ eq_bitwise_or_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -8575,16 +8834,19 @@ eq_bitwise_or_rule(Parser *p)
 static CmpopExprPair*
 noteq_bitwise_or_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     CmpopExprPair* _res = NULL;
     int _mark = p->mark;
     { // ('!=') bitwise_or
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> noteq_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('!=') bitwise_or"));
@@ -8600,7 +8862,7 @@ noteq_bitwise_or_rule(Parser *p)
             _res = _PyPegen_cmpop_expr_pair ( p , NotEq , a );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -8611,7 +8873,7 @@ noteq_bitwise_or_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -8619,16 +8881,19 @@ noteq_bitwise_or_rule(Parser *p)
 static CmpopExprPair*
 lte_bitwise_or_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     CmpopExprPair* _res = NULL;
     int _mark = p->mark;
     { // '<=' bitwise_or
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> lte_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'<=' bitwise_or"));
@@ -8644,7 +8909,7 @@ lte_bitwise_or_rule(Parser *p)
             _res = _PyPegen_cmpop_expr_pair ( p , LtE , a );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -8655,7 +8920,7 @@ lte_bitwise_or_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -8663,16 +8928,19 @@ lte_bitwise_or_rule(Parser *p)
 static CmpopExprPair*
 lt_bitwise_or_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     CmpopExprPair* _res = NULL;
     int _mark = p->mark;
     { // '<' bitwise_or
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> lt_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'<' bitwise_or"));
@@ -8688,7 +8956,7 @@ lt_bitwise_or_rule(Parser *p)
             _res = _PyPegen_cmpop_expr_pair ( p , Lt , a );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -8699,7 +8967,7 @@ lt_bitwise_or_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -8707,16 +8975,19 @@ lt_bitwise_or_rule(Parser *p)
 static CmpopExprPair*
 gte_bitwise_or_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     CmpopExprPair* _res = NULL;
     int _mark = p->mark;
     { // '>=' bitwise_or
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> gte_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'>=' bitwise_or"));
@@ -8732,7 +9003,7 @@ gte_bitwise_or_rule(Parser *p)
             _res = _PyPegen_cmpop_expr_pair ( p , GtE , a );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -8743,7 +9014,7 @@ gte_bitwise_or_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -8751,16 +9022,19 @@ gte_bitwise_or_rule(Parser *p)
 static CmpopExprPair*
 gt_bitwise_or_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     CmpopExprPair* _res = NULL;
     int _mark = p->mark;
     { // '>' bitwise_or
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> gt_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'>' bitwise_or"));
@@ -8776,7 +9050,7 @@ gt_bitwise_or_rule(Parser *p)
             _res = _PyPegen_cmpop_expr_pair ( p , Gt , a );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -8787,7 +9061,7 @@ gt_bitwise_or_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -8795,16 +9069,19 @@ gt_bitwise_or_rule(Parser *p)
 static CmpopExprPair*
 notin_bitwise_or_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     CmpopExprPair* _res = NULL;
     int _mark = p->mark;
     { // 'not' 'in' bitwise_or
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> notin_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'not' 'in' bitwise_or"));
@@ -8823,7 +9100,7 @@ notin_bitwise_or_rule(Parser *p)
             _res = _PyPegen_cmpop_expr_pair ( p , NotIn , a );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -8834,7 +9111,7 @@ notin_bitwise_or_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -8842,16 +9119,19 @@ notin_bitwise_or_rule(Parser *p)
 static CmpopExprPair*
 in_bitwise_or_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     CmpopExprPair* _res = NULL;
     int _mark = p->mark;
     { // 'in' bitwise_or
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> in_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'in' bitwise_or"));
@@ -8867,7 +9147,7 @@ in_bitwise_or_rule(Parser *p)
             _res = _PyPegen_cmpop_expr_pair ( p , In , a );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -8878,7 +9158,7 @@ in_bitwise_or_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -8886,16 +9166,19 @@ in_bitwise_or_rule(Parser *p)
 static CmpopExprPair*
 isnot_bitwise_or_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     CmpopExprPair* _res = NULL;
     int _mark = p->mark;
     { // 'is' 'not' bitwise_or
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> isnot_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'is' 'not' bitwise_or"));
@@ -8914,7 +9197,7 @@ isnot_bitwise_or_rule(Parser *p)
             _res = _PyPegen_cmpop_expr_pair ( p , IsNot , a );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -8925,7 +9208,7 @@ isnot_bitwise_or_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -8933,16 +9216,19 @@ isnot_bitwise_or_rule(Parser *p)
 static CmpopExprPair*
 is_bitwise_or_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     CmpopExprPair* _res = NULL;
     int _mark = p->mark;
     { // 'is' bitwise_or
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> is_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'is' bitwise_or"));
@@ -8958,7 +9244,7 @@ is_bitwise_or_rule(Parser *p)
             _res = _PyPegen_cmpop_expr_pair ( p , Is , a );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -8969,7 +9255,7 @@ is_bitwise_or_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -8979,10 +9265,13 @@ static expr_ty bitwise_or_raw(Parser *);
 static expr_ty
 bitwise_or_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     expr_ty _res = NULL;
     if (_PyPegen_is_memoized(p, bitwise_or_type, &_res)) {
-        D(p->level--);
+        p->level--;
         return _res;
     }
     int _mark = p->mark;
@@ -8990,35 +9279,40 @@ bitwise_or_rule(Parser *p)
     while (1) {
         int tmpvar_1 = _PyPegen_update_memo(p, _mark, bitwise_or_type, _res);
         if (tmpvar_1) {
-            D(p->level--);
+            p->level--;
             return _res;
         }
         p->mark = _mark;
         void *_raw = bitwise_or_raw(p);
-        if (p->error_indicator)
+        if (p->error_indicator) {
+            p->level--;
             return NULL;
+        }
         if (_raw == NULL || p->mark <= _resmark)
             break;
         _resmark = p->mark;
         _res = _raw;
     }
     p->mark = _resmark;
-    D(p->level--);
+    p->level--;
     return _res;
 }
 static expr_ty
 bitwise_or_raw(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -9027,7 +9321,7 @@ bitwise_or_raw(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // bitwise_or '|' bitwise_xor
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "bitwise_or '|' bitwise_xor"));
@@ -9045,7 +9339,7 @@ bitwise_or_raw(Parser *p)
             D(fprintf(stderr, "%*c+ bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "bitwise_or '|' bitwise_xor"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -9055,7 +9349,7 @@ bitwise_or_raw(Parser *p)
             _res = _Py_BinOp ( a , BitOr , b , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -9066,7 +9360,7 @@ bitwise_or_raw(Parser *p)
     }
     { // bitwise_xor
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "bitwise_xor"));
@@ -9085,7 +9379,7 @@ bitwise_or_raw(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -9095,10 +9389,13 @@ static expr_ty bitwise_xor_raw(Parser *);
 static expr_ty
 bitwise_xor_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     expr_ty _res = NULL;
     if (_PyPegen_is_memoized(p, bitwise_xor_type, &_res)) {
-        D(p->level--);
+        p->level--;
         return _res;
     }
     int _mark = p->mark;
@@ -9106,35 +9403,40 @@ bitwise_xor_rule(Parser *p)
     while (1) {
         int tmpvar_2 = _PyPegen_update_memo(p, _mark, bitwise_xor_type, _res);
         if (tmpvar_2) {
-            D(p->level--);
+            p->level--;
             return _res;
         }
         p->mark = _mark;
         void *_raw = bitwise_xor_raw(p);
-        if (p->error_indicator)
+        if (p->error_indicator) {
+            p->level--;
             return NULL;
+        }
         if (_raw == NULL || p->mark <= _resmark)
             break;
         _resmark = p->mark;
         _res = _raw;
     }
     p->mark = _resmark;
-    D(p->level--);
+    p->level--;
     return _res;
 }
 static expr_ty
 bitwise_xor_raw(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -9143,7 +9445,7 @@ bitwise_xor_raw(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // bitwise_xor '^' bitwise_and
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> bitwise_xor[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "bitwise_xor '^' bitwise_and"));
@@ -9161,7 +9463,7 @@ bitwise_xor_raw(Parser *p)
             D(fprintf(stderr, "%*c+ bitwise_xor[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "bitwise_xor '^' bitwise_and"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -9171,7 +9473,7 @@ bitwise_xor_raw(Parser *p)
             _res = _Py_BinOp ( a , BitXor , b , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -9182,7 +9484,7 @@ bitwise_xor_raw(Parser *p)
     }
     { // bitwise_and
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> bitwise_xor[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "bitwise_and"));
@@ -9201,7 +9503,7 @@ bitwise_xor_raw(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -9211,10 +9513,13 @@ static expr_ty bitwise_and_raw(Parser *);
 static expr_ty
 bitwise_and_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     expr_ty _res = NULL;
     if (_PyPegen_is_memoized(p, bitwise_and_type, &_res)) {
-        D(p->level--);
+        p->level--;
         return _res;
     }
     int _mark = p->mark;
@@ -9222,35 +9527,40 @@ bitwise_and_rule(Parser *p)
     while (1) {
         int tmpvar_3 = _PyPegen_update_memo(p, _mark, bitwise_and_type, _res);
         if (tmpvar_3) {
-            D(p->level--);
+            p->level--;
             return _res;
         }
         p->mark = _mark;
         void *_raw = bitwise_and_raw(p);
-        if (p->error_indicator)
+        if (p->error_indicator) {
+            p->level--;
             return NULL;
+        }
         if (_raw == NULL || p->mark <= _resmark)
             break;
         _resmark = p->mark;
         _res = _raw;
     }
     p->mark = _resmark;
-    D(p->level--);
+    p->level--;
     return _res;
 }
 static expr_ty
 bitwise_and_raw(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -9259,7 +9569,7 @@ bitwise_and_raw(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // bitwise_and '&' shift_expr
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> bitwise_and[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "bitwise_and '&' shift_expr"));
@@ -9277,7 +9587,7 @@ bitwise_and_raw(Parser *p)
             D(fprintf(stderr, "%*c+ bitwise_and[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "bitwise_and '&' shift_expr"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -9287,7 +9597,7 @@ bitwise_and_raw(Parser *p)
             _res = _Py_BinOp ( a , BitAnd , b , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -9298,7 +9608,7 @@ bitwise_and_raw(Parser *p)
     }
     { // shift_expr
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> bitwise_and[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "shift_expr"));
@@ -9317,7 +9627,7 @@ bitwise_and_raw(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -9327,10 +9637,13 @@ static expr_ty shift_expr_raw(Parser *);
 static expr_ty
 shift_expr_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     expr_ty _res = NULL;
     if (_PyPegen_is_memoized(p, shift_expr_type, &_res)) {
-        D(p->level--);
+        p->level--;
         return _res;
     }
     int _mark = p->mark;
@@ -9338,35 +9651,40 @@ shift_expr_rule(Parser *p)
     while (1) {
         int tmpvar_4 = _PyPegen_update_memo(p, _mark, shift_expr_type, _res);
         if (tmpvar_4) {
-            D(p->level--);
+            p->level--;
             return _res;
         }
         p->mark = _mark;
         void *_raw = shift_expr_raw(p);
-        if (p->error_indicator)
+        if (p->error_indicator) {
+            p->level--;
             return NULL;
+        }
         if (_raw == NULL || p->mark <= _resmark)
             break;
         _resmark = p->mark;
         _res = _raw;
     }
     p->mark = _resmark;
-    D(p->level--);
+    p->level--;
     return _res;
 }
 static expr_ty
 shift_expr_raw(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -9375,7 +9693,7 @@ shift_expr_raw(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // shift_expr '<<' sum
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> shift_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "shift_expr '<<' sum"));
@@ -9393,7 +9711,7 @@ shift_expr_raw(Parser *p)
             D(fprintf(stderr, "%*c+ shift_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "shift_expr '<<' sum"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -9403,7 +9721,7 @@ shift_expr_raw(Parser *p)
             _res = _Py_BinOp ( a , LShift , b , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -9414,7 +9732,7 @@ shift_expr_raw(Parser *p)
     }
     { // shift_expr '>>' sum
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> shift_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "shift_expr '>>' sum"));
@@ -9432,7 +9750,7 @@ shift_expr_raw(Parser *p)
             D(fprintf(stderr, "%*c+ shift_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "shift_expr '>>' sum"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -9442,7 +9760,7 @@ shift_expr_raw(Parser *p)
             _res = _Py_BinOp ( a , RShift , b , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -9453,7 +9771,7 @@ shift_expr_raw(Parser *p)
     }
     { // sum
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> shift_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "sum"));
@@ -9472,7 +9790,7 @@ shift_expr_raw(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -9482,10 +9800,13 @@ static expr_ty sum_raw(Parser *);
 static expr_ty
 sum_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     expr_ty _res = NULL;
     if (_PyPegen_is_memoized(p, sum_type, &_res)) {
-        D(p->level--);
+        p->level--;
         return _res;
     }
     int _mark = p->mark;
@@ -9493,35 +9814,40 @@ sum_rule(Parser *p)
     while (1) {
         int tmpvar_5 = _PyPegen_update_memo(p, _mark, sum_type, _res);
         if (tmpvar_5) {
-            D(p->level--);
+            p->level--;
             return _res;
         }
         p->mark = _mark;
         void *_raw = sum_raw(p);
-        if (p->error_indicator)
+        if (p->error_indicator) {
+            p->level--;
             return NULL;
+        }
         if (_raw == NULL || p->mark <= _resmark)
             break;
         _resmark = p->mark;
         _res = _raw;
     }
     p->mark = _resmark;
-    D(p->level--);
+    p->level--;
     return _res;
 }
 static expr_ty
 sum_raw(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -9530,7 +9856,7 @@ sum_raw(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // sum '+' term
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> sum[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "sum '+' term"));
@@ -9548,7 +9874,7 @@ sum_raw(Parser *p)
             D(fprintf(stderr, "%*c+ sum[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "sum '+' term"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -9558,7 +9884,7 @@ sum_raw(Parser *p)
             _res = _Py_BinOp ( a , Add , b , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -9569,7 +9895,7 @@ sum_raw(Parser *p)
     }
     { // sum '-' term
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> sum[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "sum '-' term"));
@@ -9587,7 +9913,7 @@ sum_raw(Parser *p)
             D(fprintf(stderr, "%*c+ sum[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "sum '-' term"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -9597,7 +9923,7 @@ sum_raw(Parser *p)
             _res = _Py_BinOp ( a , Sub , b , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -9608,7 +9934,7 @@ sum_raw(Parser *p)
     }
     { // term
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> sum[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "term"));
@@ -9627,7 +9953,7 @@ sum_raw(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -9643,10 +9969,13 @@ static expr_ty term_raw(Parser *);
 static expr_ty
 term_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     expr_ty _res = NULL;
     if (_PyPegen_is_memoized(p, term_type, &_res)) {
-        D(p->level--);
+        p->level--;
         return _res;
     }
     int _mark = p->mark;
@@ -9654,35 +9983,40 @@ term_rule(Parser *p)
     while (1) {
         int tmpvar_6 = _PyPegen_update_memo(p, _mark, term_type, _res);
         if (tmpvar_6) {
-            D(p->level--);
+            p->level--;
             return _res;
         }
         p->mark = _mark;
         void *_raw = term_raw(p);
-        if (p->error_indicator)
+        if (p->error_indicator) {
+            p->level--;
             return NULL;
+        }
         if (_raw == NULL || p->mark <= _resmark)
             break;
         _resmark = p->mark;
         _res = _raw;
     }
     p->mark = _resmark;
-    D(p->level--);
+    p->level--;
     return _res;
 }
 static expr_ty
 term_raw(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -9691,7 +10025,7 @@ term_raw(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // term '*' factor
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> term[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "term '*' factor"));
@@ -9709,7 +10043,7 @@ term_raw(Parser *p)
             D(fprintf(stderr, "%*c+ term[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "term '*' factor"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -9719,7 +10053,7 @@ term_raw(Parser *p)
             _res = _Py_BinOp ( a , Mult , b , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -9730,7 +10064,7 @@ term_raw(Parser *p)
     }
     { // term '/' factor
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> term[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "term '/' factor"));
@@ -9748,7 +10082,7 @@ term_raw(Parser *p)
             D(fprintf(stderr, "%*c+ term[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "term '/' factor"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -9758,7 +10092,7 @@ term_raw(Parser *p)
             _res = _Py_BinOp ( a , Div , b , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -9769,7 +10103,7 @@ term_raw(Parser *p)
     }
     { // term '//' factor
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> term[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "term '//' factor"));
@@ -9787,7 +10121,7 @@ term_raw(Parser *p)
             D(fprintf(stderr, "%*c+ term[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "term '//' factor"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -9797,7 +10131,7 @@ term_raw(Parser *p)
             _res = _Py_BinOp ( a , FloorDiv , b , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -9808,7 +10142,7 @@ term_raw(Parser *p)
     }
     { // term '%' factor
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> term[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "term '%' factor"));
@@ -9826,7 +10160,7 @@ term_raw(Parser *p)
             D(fprintf(stderr, "%*c+ term[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "term '%' factor"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -9836,7 +10170,7 @@ term_raw(Parser *p)
             _res = _Py_BinOp ( a , Mod , b , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -9847,7 +10181,7 @@ term_raw(Parser *p)
     }
     { // term '@' factor
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> term[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "term '@' factor"));
@@ -9865,7 +10199,7 @@ term_raw(Parser *p)
             D(fprintf(stderr, "%*c+ term[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "term '@' factor"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -9875,7 +10209,7 @@ term_raw(Parser *p)
             _res = CHECK_VERSION ( 5 , "The '@' operator is" , _Py_BinOp ( a , MatMult , b , EXTRA ) );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -9886,7 +10220,7 @@ term_raw(Parser *p)
     }
     { // factor
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> term[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "factor"));
@@ -9905,7 +10239,7 @@ term_raw(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -9913,20 +10247,23 @@ term_raw(Parser *p)
 static expr_ty
 factor_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     if (_PyPegen_is_memoized(p, factor_type, &_res)) {
-        D(p->level--);
+        p->level--;
         return _res;
     }
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -9935,7 +10272,7 @@ factor_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // '+' factor
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> factor[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'+' factor"));
@@ -9950,7 +10287,7 @@ factor_rule(Parser *p)
             D(fprintf(stderr, "%*c+ factor[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'+' factor"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -9960,7 +10297,7 @@ factor_rule(Parser *p)
             _res = _Py_UnaryOp ( UAdd , a , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -9971,7 +10308,7 @@ factor_rule(Parser *p)
     }
     { // '-' factor
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> factor[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-' factor"));
@@ -9986,7 +10323,7 @@ factor_rule(Parser *p)
             D(fprintf(stderr, "%*c+ factor[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-' factor"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -9996,7 +10333,7 @@ factor_rule(Parser *p)
             _res = _Py_UnaryOp ( USub , a , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -10007,7 +10344,7 @@ factor_rule(Parser *p)
     }
     { // '~' factor
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> factor[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'~' factor"));
@@ -10022,7 +10359,7 @@ factor_rule(Parser *p)
             D(fprintf(stderr, "%*c+ factor[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'~' factor"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -10032,7 +10369,7 @@ factor_rule(Parser *p)
             _res = _Py_UnaryOp ( Invert , a , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -10043,7 +10380,7 @@ factor_rule(Parser *p)
     }
     { // power
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> factor[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "power"));
@@ -10063,7 +10400,7 @@ factor_rule(Parser *p)
     _res = NULL;
   done:
     _PyPegen_insert_memo(p, _mark, factor_type, _res);
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -10071,16 +10408,19 @@ factor_rule(Parser *p)
 static expr_ty
 power_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -10089,7 +10429,7 @@ power_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // await_primary '**' factor
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> power[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "await_primary '**' factor"));
@@ -10107,7 +10447,7 @@ power_rule(Parser *p)
             D(fprintf(stderr, "%*c+ power[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "await_primary '**' factor"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -10117,7 +10457,7 @@ power_rule(Parser *p)
             _res = _Py_BinOp ( a , Pow , b , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -10128,7 +10468,7 @@ power_rule(Parser *p)
     }
     { // await_primary
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> power[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "await_primary"));
@@ -10147,7 +10487,7 @@ power_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -10155,20 +10495,23 @@ power_rule(Parser *p)
 static expr_ty
 await_primary_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     if (_PyPegen_is_memoized(p, await_primary_type, &_res)) {
-        D(p->level--);
+        p->level--;
         return _res;
     }
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -10177,7 +10520,7 @@ await_primary_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // AWAIT primary
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> await_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "AWAIT primary"));
@@ -10192,7 +10535,7 @@ await_primary_rule(Parser *p)
             D(fprintf(stderr, "%*c+ await_primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "AWAIT primary"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -10202,7 +10545,7 @@ await_primary_rule(Parser *p)
             _res = CHECK_VERSION ( 5 , "Await expressions are" , _Py_Await ( a , EXTRA ) );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -10213,7 +10556,7 @@ await_primary_rule(Parser *p)
     }
     { // primary
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> await_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "primary"));
@@ -10233,7 +10576,7 @@ await_primary_rule(Parser *p)
     _res = NULL;
   done:
     _PyPegen_insert_memo(p, _mark, await_primary_type, _res);
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -10249,10 +10592,13 @@ static expr_ty primary_raw(Parser *);
 static expr_ty
 primary_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     expr_ty _res = NULL;
     if (_PyPegen_is_memoized(p, primary_type, &_res)) {
-        D(p->level--);
+        p->level--;
         return _res;
     }
     int _mark = p->mark;
@@ -10260,35 +10606,40 @@ primary_rule(Parser *p)
     while (1) {
         int tmpvar_7 = _PyPegen_update_memo(p, _mark, primary_type, _res);
         if (tmpvar_7) {
-            D(p->level--);
+            p->level--;
             return _res;
         }
         p->mark = _mark;
         void *_raw = primary_raw(p);
-        if (p->error_indicator)
+        if (p->error_indicator) {
+            p->level--;
             return NULL;
+        }
         if (_raw == NULL || p->mark <= _resmark)
             break;
         _resmark = p->mark;
         _res = _raw;
     }
     p->mark = _resmark;
-    D(p->level--);
+    p->level--;
     return _res;
 }
 static expr_ty
 primary_raw(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -10297,7 +10648,7 @@ primary_raw(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     if (p->call_invalid_rules) { // invalid_primary
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_primary"));
@@ -10316,7 +10667,7 @@ primary_raw(Parser *p)
     }
     { // primary '.' NAME
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "primary '.' NAME"));
@@ -10334,7 +10685,7 @@ primary_raw(Parser *p)
             D(fprintf(stderr, "%*c+ primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "primary '.' NAME"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -10344,7 +10695,7 @@ primary_raw(Parser *p)
             _res = _Py_Attribute ( a , b -> v . Name . id , Load , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -10355,7 +10706,7 @@ primary_raw(Parser *p)
     }
     { // primary genexp
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "primary genexp"));
@@ -10370,7 +10721,7 @@ primary_raw(Parser *p)
             D(fprintf(stderr, "%*c+ primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "primary genexp"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -10380,7 +10731,7 @@ primary_raw(Parser *p)
             _res = _Py_Call ( a , CHECK ( _PyPegen_singleton_seq ( p , b ) ) , NULL , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -10391,7 +10742,7 @@ primary_raw(Parser *p)
     }
     { // primary '(' arguments? ')'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "primary '(' arguments? ')'"));
@@ -10412,7 +10763,7 @@ primary_raw(Parser *p)
             D(fprintf(stderr, "%*c+ primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "primary '(' arguments? ')'"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -10422,7 +10773,7 @@ primary_raw(Parser *p)
             _res = _Py_Call ( a , ( b ) ? ( ( expr_ty ) b ) -> v . Call . args : NULL , ( b ) ? ( ( expr_ty ) b ) -> v . Call . keywords : NULL , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -10433,7 +10784,7 @@ primary_raw(Parser *p)
     }
     { // primary '[' slices ']'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "primary '[' slices ']'"));
@@ -10454,7 +10805,7 @@ primary_raw(Parser *p)
             D(fprintf(stderr, "%*c+ primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "primary '[' slices ']'"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -10464,7 +10815,7 @@ primary_raw(Parser *p)
             _res = _Py_Subscript ( a , b , Load , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -10475,7 +10826,7 @@ primary_raw(Parser *p)
     }
     { // atom
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "atom"));
@@ -10494,7 +10845,7 @@ primary_raw(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -10502,16 +10853,19 @@ primary_raw(Parser *p)
 static expr_ty
 slices_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -10520,7 +10874,7 @@ slices_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // slice !','
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> slices[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slice !','"));
@@ -10535,7 +10889,7 @@ slices_rule(Parser *p)
             _res = a;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -10546,7 +10900,7 @@ slices_rule(Parser *p)
     }
     { // ','.slice+ ','?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> slices[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.slice+ ','?"));
@@ -10562,7 +10916,7 @@ slices_rule(Parser *p)
             D(fprintf(stderr, "%*c+ slices[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.slice+ ','?"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -10572,7 +10926,7 @@ slices_rule(Parser *p)
             _res = _Py_Tuple ( a , Load , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -10583,7 +10937,7 @@ slices_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -10591,16 +10945,19 @@ slices_rule(Parser *p)
 static expr_ty
 slice_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -10609,7 +10966,7 @@ slice_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // expression? ':' expression? [':' expression?]
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> slice[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression? ':' expression? [':' expression?]"));
@@ -10630,7 +10987,7 @@ slice_rule(Parser *p)
             D(fprintf(stderr, "%*c+ slice[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression? ':' expression? [':' expression?]"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -10640,7 +10997,7 @@ slice_rule(Parser *p)
             _res = _Py_Slice ( a , b , c , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -10651,7 +11008,7 @@ slice_rule(Parser *p)
     }
     { // expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> slice[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression"));
@@ -10664,7 +11021,7 @@ slice_rule(Parser *p)
             _res = a;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -10675,7 +11032,7 @@ slice_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -10694,16 +11051,19 @@ slice_rule(Parser *p)
 static expr_ty
 atom_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -10712,7 +11072,7 @@ atom_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // NAME
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME"));
@@ -10731,7 +11091,7 @@ atom_rule(Parser *p)
     }
     { // 'True'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'"));
@@ -10743,7 +11103,7 @@ atom_rule(Parser *p)
             D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -10753,7 +11113,7 @@ atom_rule(Parser *p)
             _res = _Py_Constant ( Py_True , NULL , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -10764,7 +11124,7 @@ atom_rule(Parser *p)
     }
     { // 'False'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'"));
@@ -10776,7 +11136,7 @@ atom_rule(Parser *p)
             D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -10786,7 +11146,7 @@ atom_rule(Parser *p)
             _res = _Py_Constant ( Py_False , NULL , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -10797,7 +11157,7 @@ atom_rule(Parser *p)
     }
     { // 'None'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'"));
@@ -10809,7 +11169,7 @@ atom_rule(Parser *p)
             D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -10819,7 +11179,7 @@ atom_rule(Parser *p)
             _res = _Py_Constant ( Py_None , NULL , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -10830,7 +11190,7 @@ atom_rule(Parser *p)
     }
     { // '__peg_parser__'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'__peg_parser__'"));
@@ -10843,7 +11203,7 @@ atom_rule(Parser *p)
             _res = RAISE_SYNTAX_ERROR ( "You found it!" );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -10854,7 +11214,7 @@ atom_rule(Parser *p)
     }
     { // &STRING strings
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&STRING strings"));
@@ -10875,7 +11235,7 @@ atom_rule(Parser *p)
     }
     { // NUMBER
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NUMBER"));
@@ -10894,7 +11254,7 @@ atom_rule(Parser *p)
     }
     { // &'(' (tuple | group | genexp)
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'(' (tuple | group | genexp)"));
@@ -10915,7 +11275,7 @@ atom_rule(Parser *p)
     }
     { // &'[' (list | listcomp)
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'[' (list | listcomp)"));
@@ -10936,7 +11296,7 @@ atom_rule(Parser *p)
     }
     { // &'{' (dict | set | dictcomp | setcomp)
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'{' (dict | set | dictcomp | setcomp)"));
@@ -10957,7 +11317,7 @@ atom_rule(Parser *p)
     }
     { // '...'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'"));
@@ -10969,7 +11329,7 @@ atom_rule(Parser *p)
             D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -10979,7 +11339,7 @@ atom_rule(Parser *p)
             _res = _Py_Constant ( Py_Ellipsis , NULL , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -10990,7 +11350,7 @@ atom_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -10998,20 +11358,23 @@ atom_rule(Parser *p)
 static expr_ty
 strings_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     if (_PyPegen_is_memoized(p, strings_type, &_res)) {
-        D(p->level--);
+        p->level--;
         return _res;
     }
     int _mark = p->mark;
     { // STRING+
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> strings[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "STRING+"));
@@ -11024,7 +11387,7 @@ strings_rule(Parser *p)
             _res = _PyPegen_concatenate_strings ( p , a );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -11036,7 +11399,7 @@ strings_rule(Parser *p)
     _res = NULL;
   done:
     _PyPegen_insert_memo(p, _mark, strings_type, _res);
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -11044,16 +11407,19 @@ strings_rule(Parser *p)
 static expr_ty
 list_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -11062,7 +11428,7 @@ list_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // '[' star_named_expressions? ']'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> list[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'[' star_named_expressions? ']'"));
@@ -11080,7 +11446,7 @@ list_rule(Parser *p)
             D(fprintf(stderr, "%*c+ list[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'[' star_named_expressions? ']'"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -11090,7 +11456,7 @@ list_rule(Parser *p)
             _res = _Py_List ( a , Load , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -11101,7 +11467,7 @@ list_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -11109,16 +11475,19 @@ list_rule(Parser *p)
 static expr_ty
 listcomp_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -11127,7 +11496,7 @@ listcomp_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // '[' named_expression ~ for_if_clauses ']'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> listcomp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'[' named_expression ~ for_if_clauses ']'"));
@@ -11151,7 +11520,7 @@ listcomp_rule(Parser *p)
             D(fprintf(stderr, "%*c+ listcomp[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'[' named_expression ~ for_if_clauses ']'"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -11161,7 +11530,7 @@ listcomp_rule(Parser *p)
             _res = _Py_ListComp ( a , b , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -11170,13 +11539,13 @@ listcomp_rule(Parser *p)
         D(fprintf(stderr, "%*c%s listcomp[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'[' named_expression ~ for_if_clauses ']'"));
         if (_cut_var) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
     }
     if (p->call_invalid_rules) { // invalid_comprehension
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> listcomp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_comprehension"));
@@ -11195,7 +11564,7 @@ listcomp_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -11203,16 +11572,19 @@ listcomp_rule(Parser *p)
 static expr_ty
 tuple_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -11221,7 +11593,7 @@ tuple_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // '(' [star_named_expression ',' star_named_expressions?] ')'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> tuple[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' [star_named_expression ',' star_named_expressions?] ')'"));
@@ -11239,7 +11611,7 @@ tuple_rule(Parser *p)
             D(fprintf(stderr, "%*c+ tuple[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' [star_named_expression ',' star_named_expressions?] ')'"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -11249,7 +11621,7 @@ tuple_rule(Parser *p)
             _res = _Py_Tuple ( a , Load , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -11260,7 +11632,7 @@ tuple_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -11268,16 +11640,19 @@ tuple_rule(Parser *p)
 static expr_ty
 group_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     { // '(' (yield_expr | named_expression) ')'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> group[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' (yield_expr | named_expression) ')'"));
@@ -11296,7 +11671,7 @@ group_rule(Parser *p)
             _res = a;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -11307,7 +11682,7 @@ group_rule(Parser *p)
     }
     if (p->call_invalid_rules) { // invalid_group
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> group[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_group"));
@@ -11326,7 +11701,7 @@ group_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -11334,16 +11709,19 @@ group_rule(Parser *p)
 static expr_ty
 genexp_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -11352,7 +11730,7 @@ genexp_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // '(' named_expression ~ for_if_clauses ')'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> genexp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' named_expression ~ for_if_clauses ')'"));
@@ -11376,7 +11754,7 @@ genexp_rule(Parser *p)
             D(fprintf(stderr, "%*c+ genexp[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' named_expression ~ for_if_clauses ')'"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -11386,7 +11764,7 @@ genexp_rule(Parser *p)
             _res = _Py_GeneratorExp ( a , b , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -11395,13 +11773,13 @@ genexp_rule(Parser *p)
         D(fprintf(stderr, "%*c%s genexp[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' named_expression ~ for_if_clauses ')'"));
         if (_cut_var) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
     }
     if (p->call_invalid_rules) { // invalid_comprehension
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> genexp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_comprehension"));
@@ -11420,7 +11798,7 @@ genexp_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -11428,16 +11806,19 @@ genexp_rule(Parser *p)
 static expr_ty
 set_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -11446,7 +11827,7 @@ set_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // '{' star_named_expressions '}'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> set[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' star_named_expressions '}'"));
@@ -11464,7 +11845,7 @@ set_rule(Parser *p)
             D(fprintf(stderr, "%*c+ set[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' star_named_expressions '}'"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -11474,7 +11855,7 @@ set_rule(Parser *p)
             _res = _Py_Set ( a , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -11485,7 +11866,7 @@ set_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -11493,16 +11874,19 @@ set_rule(Parser *p)
 static expr_ty
 setcomp_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -11511,7 +11895,7 @@ setcomp_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // '{' named_expression ~ for_if_clauses '}'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> setcomp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' named_expression ~ for_if_clauses '}'"));
@@ -11535,7 +11919,7 @@ setcomp_rule(Parser *p)
             D(fprintf(stderr, "%*c+ setcomp[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' named_expression ~ for_if_clauses '}'"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -11545,7 +11929,7 @@ setcomp_rule(Parser *p)
             _res = _Py_SetComp ( a , b , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -11554,13 +11938,13 @@ setcomp_rule(Parser *p)
         D(fprintf(stderr, "%*c%s setcomp[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{' named_expression ~ for_if_clauses '}'"));
         if (_cut_var) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
     }
     if (p->call_invalid_rules) { // invalid_comprehension
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> setcomp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_comprehension"));
@@ -11579,7 +11963,7 @@ setcomp_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -11587,16 +11971,19 @@ setcomp_rule(Parser *p)
 static expr_ty
 dict_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -11605,7 +11992,7 @@ dict_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // '{' double_starred_kvpairs? '}'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> dict[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' double_starred_kvpairs? '}'"));
@@ -11623,7 +12010,7 @@ dict_rule(Parser *p)
             D(fprintf(stderr, "%*c+ dict[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' double_starred_kvpairs? '}'"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -11633,7 +12020,7 @@ dict_rule(Parser *p)
             _res = _Py_Dict ( CHECK ( _PyPegen_get_keys ( p , a ) ) , CHECK ( _PyPegen_get_values ( p , a ) ) , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -11644,7 +12031,7 @@ dict_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -11652,16 +12039,19 @@ dict_rule(Parser *p)
 static expr_ty
 dictcomp_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -11670,7 +12060,7 @@ dictcomp_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // '{' kvpair for_if_clauses '}'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> dictcomp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' kvpair for_if_clauses '}'"));
@@ -11691,7 +12081,7 @@ dictcomp_rule(Parser *p)
             D(fprintf(stderr, "%*c+ dictcomp[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' kvpair for_if_clauses '}'"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -11701,7 +12091,7 @@ dictcomp_rule(Parser *p)
             _res = _Py_DictComp ( a -> key , a -> value , b , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -11712,7 +12102,7 @@ dictcomp_rule(Parser *p)
     }
     if (p->call_invalid_rules) { // invalid_dict_comprehension
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> dictcomp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_dict_comprehension"));
@@ -11731,7 +12121,7 @@ dictcomp_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -11739,16 +12129,19 @@ dictcomp_rule(Parser *p)
 static asdl_seq*
 double_starred_kvpairs_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq* _res = NULL;
     int _mark = p->mark;
     { // ','.double_starred_kvpair+ ','?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> double_starred_kvpairs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.double_starred_kvpair+ ','?"));
@@ -11765,7 +12158,7 @@ double_starred_kvpairs_rule(Parser *p)
             _res = a;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -11776,7 +12169,7 @@ double_starred_kvpairs_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -11784,16 +12177,19 @@ double_starred_kvpairs_rule(Parser *p)
 static KeyValuePair*
 double_starred_kvpair_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     KeyValuePair* _res = NULL;
     int _mark = p->mark;
     { // '**' bitwise_or
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> double_starred_kvpair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' bitwise_or"));
@@ -11809,7 +12205,7 @@ double_starred_kvpair_rule(Parser *p)
             _res = _PyPegen_key_value_pair ( p , NULL , a );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -11820,7 +12216,7 @@ double_starred_kvpair_rule(Parser *p)
     }
     { // kvpair
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> double_starred_kvpair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kvpair"));
@@ -11839,7 +12235,7 @@ double_starred_kvpair_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -11847,16 +12243,19 @@ double_starred_kvpair_rule(Parser *p)
 static KeyValuePair*
 kvpair_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     KeyValuePair* _res = NULL;
     int _mark = p->mark;
     { // expression ':' expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> kvpair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ':' expression"));
@@ -11875,7 +12274,7 @@ kvpair_rule(Parser *p)
             _res = _PyPegen_key_value_pair ( p , a , b );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -11886,7 +12285,7 @@ kvpair_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -11894,16 +12293,19 @@ kvpair_rule(Parser *p)
 static asdl_seq*
 for_if_clauses_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq* _res = NULL;
     int _mark = p->mark;
     { // for_if_clause+
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> for_if_clauses[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "for_if_clause+"));
@@ -11922,7 +12324,7 @@ for_if_clauses_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -11933,16 +12335,19 @@ for_if_clauses_rule(Parser *p)
 static comprehension_ty
 for_if_clause_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     comprehension_ty _res = NULL;
     int _mark = p->mark;
     { // ASYNC 'for' star_targets 'in' ~ disjunction (('if' disjunction))*
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> for_if_clause[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ disjunction (('if' disjunction))*"));
@@ -11973,7 +12378,7 @@ for_if_clause_rule(Parser *p)
             _res = CHECK_VERSION ( 6 , "Async comprehensions are" , _Py_comprehension ( a , b , c , 1 , p -> arena ) );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -11982,13 +12387,13 @@ for_if_clause_rule(Parser *p)
         D(fprintf(stderr, "%*c%s for_if_clause[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ disjunction (('if' disjunction))*"));
         if (_cut_var) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
     }
     { // 'for' star_targets 'in' ~ disjunction (('if' disjunction))*
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> for_if_clause[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'for' star_targets 'in' ~ disjunction (('if' disjunction))*"));
@@ -12016,7 +12421,7 @@ for_if_clause_rule(Parser *p)
             _res = _Py_comprehension ( a , b , c , 0 , p -> arena );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -12025,13 +12430,13 @@ for_if_clause_rule(Parser *p)
         D(fprintf(stderr, "%*c%s for_if_clause[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'for' star_targets 'in' ~ disjunction (('if' disjunction))*"));
         if (_cut_var) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
     }
     if (p->call_invalid_rules) { // invalid_for_target
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> for_if_clause[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_for_target"));
@@ -12050,7 +12455,7 @@ for_if_clause_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -12058,16 +12463,19 @@ for_if_clause_rule(Parser *p)
 static expr_ty
 yield_expr_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -12076,7 +12484,7 @@ yield_expr_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // 'yield' 'from' expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> yield_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'yield' 'from' expression"));
@@ -12094,7 +12502,7 @@ yield_expr_rule(Parser *p)
             D(fprintf(stderr, "%*c+ yield_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'yield' 'from' expression"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -12104,7 +12512,7 @@ yield_expr_rule(Parser *p)
             _res = _Py_YieldFrom ( a , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -12115,7 +12523,7 @@ yield_expr_rule(Parser *p)
     }
     { // 'yield' star_expressions?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> yield_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'yield' star_expressions?"));
@@ -12130,7 +12538,7 @@ yield_expr_rule(Parser *p)
             D(fprintf(stderr, "%*c+ yield_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'yield' star_expressions?"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -12140,7 +12548,7 @@ yield_expr_rule(Parser *p)
             _res = _Py_Yield ( a , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -12151,7 +12559,7 @@ yield_expr_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -12159,20 +12567,23 @@ yield_expr_rule(Parser *p)
 static expr_ty
 arguments_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     if (_PyPegen_is_memoized(p, arguments_type, &_res)) {
-        D(p->level--);
+        p->level--;
         return _res;
     }
     int _mark = p->mark;
     { // args ','? &')'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args ','? &')'"));
@@ -12191,7 +12602,7 @@ arguments_rule(Parser *p)
             _res = a;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -12202,7 +12613,7 @@ arguments_rule(Parser *p)
     }
     if (p->call_invalid_rules) { // invalid_arguments
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_arguments"));
@@ -12222,7 +12633,7 @@ arguments_rule(Parser *p)
     _res = NULL;
   done:
     _PyPegen_insert_memo(p, _mark, arguments_type, _res);
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -12230,16 +12641,19 @@ arguments_rule(Parser *p)
 static expr_ty
 args_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -12248,7 +12662,7 @@ args_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // ','.(starred_expression | named_expression !'=')+ [',' kwargs]
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> args[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.(starred_expression | named_expression !'=')+ [',' kwargs]"));
@@ -12263,7 +12677,7 @@ args_rule(Parser *p)
             D(fprintf(stderr, "%*c+ args[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.(starred_expression | named_expression !'=')+ [',' kwargs]"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -12273,7 +12687,7 @@ args_rule(Parser *p)
             _res = _PyPegen_collect_call_seqs ( p , a , b , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -12284,7 +12698,7 @@ args_rule(Parser *p)
     }
     { // kwargs
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> args[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwargs"));
@@ -12296,7 +12710,7 @@ args_rule(Parser *p)
             D(fprintf(stderr, "%*c+ args[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwargs"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -12306,7 +12720,7 @@ args_rule(Parser *p)
             _res = _Py_Call ( _PyPegen_dummy_name ( p ) , CHECK_NULL_ALLOWED ( _PyPegen_seq_extract_starred_exprs ( p , a ) ) , CHECK_NULL_ALLOWED ( _PyPegen_seq_delete_starred_exprs ( p , a ) ) , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -12317,7 +12731,7 @@ args_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -12328,16 +12742,19 @@ args_rule(Parser *p)
 static asdl_seq*
 kwargs_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq* _res = NULL;
     int _mark = p->mark;
     { // ','.kwarg_or_starred+ ',' ','.kwarg_or_double_starred+
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> kwargs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_starred+ ',' ','.kwarg_or_double_starred+"));
@@ -12356,7 +12773,7 @@ kwargs_rule(Parser *p)
             _res = _PyPegen_join_sequences ( p , a , b );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -12367,7 +12784,7 @@ kwargs_rule(Parser *p)
     }
     { // ','.kwarg_or_starred+
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> kwargs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_starred+"));
@@ -12386,7 +12803,7 @@ kwargs_rule(Parser *p)
     }
     { // ','.kwarg_or_double_starred+
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> kwargs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_double_starred+"));
@@ -12405,7 +12822,7 @@ kwargs_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -12413,16 +12830,19 @@ kwargs_rule(Parser *p)
 static expr_ty
 starred_expression_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -12431,7 +12851,7 @@ starred_expression_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // '*' expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> starred_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' expression"));
@@ -12446,7 +12866,7 @@ starred_expression_rule(Parser *p)
             D(fprintf(stderr, "%*c+ starred_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' expression"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -12456,7 +12876,7 @@ starred_expression_rule(Parser *p)
             _res = _Py_Starred ( a , Load , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -12467,7 +12887,7 @@ starred_expression_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -12475,16 +12895,19 @@ starred_expression_rule(Parser *p)
 static KeywordOrStarred*
 kwarg_or_starred_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     KeywordOrStarred* _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -12493,7 +12916,7 @@ kwarg_or_starred_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // NAME '=' expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> kwarg_or_starred[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '=' expression"));
@@ -12511,7 +12934,7 @@ kwarg_or_starred_rule(Parser *p)
             D(fprintf(stderr, "%*c+ kwarg_or_starred[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '=' expression"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -12521,7 +12944,7 @@ kwarg_or_starred_rule(Parser *p)
             _res = _PyPegen_keyword_or_starred ( p , CHECK ( _Py_keyword ( a -> v . Name . id , b , EXTRA ) ) , 1 );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -12532,7 +12955,7 @@ kwarg_or_starred_rule(Parser *p)
     }
     { // starred_expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> kwarg_or_starred[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression"));
@@ -12545,7 +12968,7 @@ kwarg_or_starred_rule(Parser *p)
             _res = _PyPegen_keyword_or_starred ( p , a , 0 );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -12556,7 +12979,7 @@ kwarg_or_starred_rule(Parser *p)
     }
     if (p->call_invalid_rules) { // invalid_kwarg
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> kwarg_or_starred[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_kwarg"));
@@ -12575,7 +12998,7 @@ kwarg_or_starred_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -12583,16 +13006,19 @@ kwarg_or_starred_rule(Parser *p)
 static KeywordOrStarred*
 kwarg_or_double_starred_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     KeywordOrStarred* _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -12601,7 +13027,7 @@ kwarg_or_double_starred_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // NAME '=' expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> kwarg_or_double_starred[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '=' expression"));
@@ -12619,7 +13045,7 @@ kwarg_or_double_starred_rule(Parser *p)
             D(fprintf(stderr, "%*c+ kwarg_or_double_starred[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '=' expression"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -12629,7 +13055,7 @@ kwarg_or_double_starred_rule(Parser *p)
             _res = _PyPegen_keyword_or_starred ( p , CHECK ( _Py_keyword ( a -> v . Name . id , b , EXTRA ) ) , 1 );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -12640,7 +13066,7 @@ kwarg_or_double_starred_rule(Parser *p)
     }
     { // '**' expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> kwarg_or_double_starred[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' expression"));
@@ -12655,7 +13081,7 @@ kwarg_or_double_starred_rule(Parser *p)
             D(fprintf(stderr, "%*c+ kwarg_or_double_starred[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' expression"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -12665,7 +13091,7 @@ kwarg_or_double_starred_rule(Parser *p)
             _res = _PyPegen_keyword_or_starred ( p , CHECK ( _Py_keyword ( NULL , a , EXTRA ) ) , 1 );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -12676,7 +13102,7 @@ kwarg_or_double_starred_rule(Parser *p)
     }
     if (p->call_invalid_rules) { // invalid_kwarg
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> kwarg_or_double_starred[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_kwarg"));
@@ -12695,7 +13121,7 @@ kwarg_or_double_starred_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -12703,16 +13129,19 @@ kwarg_or_double_starred_rule(Parser *p)
 static expr_ty
 star_targets_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -12721,7 +13150,7 @@ star_targets_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // star_target !','
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> star_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_target !','"));
@@ -12736,7 +13165,7 @@ star_targets_rule(Parser *p)
             _res = a;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -12747,7 +13176,7 @@ star_targets_rule(Parser *p)
     }
     { // star_target ((',' star_target))* ','?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> star_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_target ((',' star_target))* ','?"));
@@ -12766,7 +13195,7 @@ star_targets_rule(Parser *p)
             D(fprintf(stderr, "%*c+ star_targets[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_target ((',' star_target))* ','?"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -12776,7 +13205,7 @@ star_targets_rule(Parser *p)
             _res = _Py_Tuple ( CHECK ( _PyPegen_seq_insert_in_front ( p , a , b ) ) , Store , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -12787,7 +13216,7 @@ star_targets_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -12795,16 +13224,19 @@ star_targets_rule(Parser *p)
 static asdl_seq*
 star_targets_list_seq_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq* _res = NULL;
     int _mark = p->mark;
     { // ','.star_target+ ','?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> star_targets_list_seq[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.star_target+ ','?"));
@@ -12821,7 +13253,7 @@ star_targets_list_seq_rule(Parser *p)
             _res = a;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -12832,7 +13264,7 @@ star_targets_list_seq_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -12840,16 +13272,19 @@ star_targets_list_seq_rule(Parser *p)
 static asdl_seq*
 star_targets_tuple_seq_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq* _res = NULL;
     int _mark = p->mark;
     { // star_target ((',' star_target))+ ','?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> star_targets_tuple_seq[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_target ((',' star_target))+ ','?"));
@@ -12869,7 +13304,7 @@ star_targets_tuple_seq_rule(Parser *p)
             _res = _PyPegen_seq_insert_in_front ( p , a , b );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -12880,7 +13315,7 @@ star_targets_tuple_seq_rule(Parser *p)
     }
     { // star_target ','
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> star_targets_tuple_seq[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_target ','"));
@@ -12896,7 +13331,7 @@ star_targets_tuple_seq_rule(Parser *p)
             _res = _PyPegen_singleton_seq ( p , a );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -12907,7 +13342,7 @@ star_targets_tuple_seq_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -12915,20 +13350,23 @@ star_targets_tuple_seq_rule(Parser *p)
 static expr_ty
 star_target_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     if (_PyPegen_is_memoized(p, star_target_type, &_res)) {
-        D(p->level--);
+        p->level--;
         return _res;
     }
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -12937,7 +13375,7 @@ star_target_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // '*' (!'*' star_target)
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> star_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (!'*' star_target)"));
@@ -12952,7 +13390,7 @@ star_target_rule(Parser *p)
             D(fprintf(stderr, "%*c+ star_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (!'*' star_target)"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -12962,7 +13400,7 @@ star_target_rule(Parser *p)
             _res = _Py_Starred ( CHECK ( _PyPegen_set_expr_context ( p , a , Store ) ) , Store , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -12973,7 +13411,7 @@ star_target_rule(Parser *p)
     }
     { // target_with_star_atom
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> star_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "target_with_star_atom"));
@@ -12993,7 +13431,7 @@ star_target_rule(Parser *p)
     _res = NULL;
   done:
     _PyPegen_insert_memo(p, _mark, star_target_type, _res);
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -13004,20 +13442,23 @@ star_target_rule(Parser *p)
 static expr_ty
 target_with_star_atom_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     if (_PyPegen_is_memoized(p, target_with_star_atom_type, &_res)) {
-        D(p->level--);
+        p->level--;
         return _res;
     }
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -13026,7 +13467,7 @@ target_with_star_atom_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // t_primary '.' NAME !t_lookahead
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> target_with_star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME !t_lookahead"));
@@ -13046,7 +13487,7 @@ target_with_star_atom_rule(Parser *p)
             D(fprintf(stderr, "%*c+ target_with_star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME !t_lookahead"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -13056,7 +13497,7 @@ target_with_star_atom_rule(Parser *p)
             _res = _Py_Attribute ( a , b -> v . Name . id , Store , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -13067,7 +13508,7 @@ target_with_star_atom_rule(Parser *p)
     }
     { // t_primary '[' slices ']' !t_lookahead
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> target_with_star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' !t_lookahead"));
@@ -13090,7 +13531,7 @@ target_with_star_atom_rule(Parser *p)
             D(fprintf(stderr, "%*c+ target_with_star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' !t_lookahead"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -13100,7 +13541,7 @@ target_with_star_atom_rule(Parser *p)
             _res = _Py_Subscript ( a , b , Store , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -13111,7 +13552,7 @@ target_with_star_atom_rule(Parser *p)
     }
     { // star_atom
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> target_with_star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_atom"));
@@ -13131,7 +13572,7 @@ target_with_star_atom_rule(Parser *p)
     _res = NULL;
   done:
     _PyPegen_insert_memo(p, _mark, target_with_star_atom_type, _res);
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -13143,16 +13584,19 @@ target_with_star_atom_rule(Parser *p)
 static expr_ty
 star_atom_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -13161,7 +13605,7 @@ star_atom_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // NAME
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME"));
@@ -13174,7 +13618,7 @@ star_atom_rule(Parser *p)
             _res = _PyPegen_set_expr_context ( p , a , Store );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -13185,7 +13629,7 @@ star_atom_rule(Parser *p)
     }
     { // '(' target_with_star_atom ')'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' target_with_star_atom ')'"));
@@ -13204,7 +13648,7 @@ star_atom_rule(Parser *p)
             _res = _PyPegen_set_expr_context ( p , a , Store );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -13215,7 +13659,7 @@ star_atom_rule(Parser *p)
     }
     { // '(' star_targets_tuple_seq? ')'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' star_targets_tuple_seq? ')'"));
@@ -13233,7 +13677,7 @@ star_atom_rule(Parser *p)
             D(fprintf(stderr, "%*c+ star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' star_targets_tuple_seq? ')'"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -13243,7 +13687,7 @@ star_atom_rule(Parser *p)
             _res = _Py_Tuple ( a , Store , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -13254,7 +13698,7 @@ star_atom_rule(Parser *p)
     }
     { // '[' star_targets_list_seq? ']'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'[' star_targets_list_seq? ']'"));
@@ -13272,7 +13716,7 @@ star_atom_rule(Parser *p)
             D(fprintf(stderr, "%*c+ star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'[' star_targets_list_seq? ']'"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -13282,7 +13726,7 @@ star_atom_rule(Parser *p)
             _res = _Py_List ( a , Store , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -13293,7 +13737,7 @@ star_atom_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -13301,16 +13745,19 @@ star_atom_rule(Parser *p)
 static expr_ty
 single_target_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     { // single_subscript_attribute_target
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> single_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "single_subscript_attribute_target"));
@@ -13329,7 +13776,7 @@ single_target_rule(Parser *p)
     }
     { // NAME
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> single_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME"));
@@ -13342,7 +13789,7 @@ single_target_rule(Parser *p)
             _res = _PyPegen_set_expr_context ( p , a , Store );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -13353,7 +13800,7 @@ single_target_rule(Parser *p)
     }
     { // '(' single_target ')'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> single_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' single_target ')'"));
@@ -13372,7 +13819,7 @@ single_target_rule(Parser *p)
             _res = a;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -13383,7 +13830,7 @@ single_target_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -13393,16 +13840,19 @@ single_target_rule(Parser *p)
 static expr_ty
 single_subscript_attribute_target_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -13411,7 +13861,7 @@ single_subscript_attribute_target_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // t_primary '.' NAME !t_lookahead
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> single_subscript_attribute_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME !t_lookahead"));
@@ -13431,7 +13881,7 @@ single_subscript_attribute_target_rule(Parser *p)
             D(fprintf(stderr, "%*c+ single_subscript_attribute_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME !t_lookahead"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -13441,7 +13891,7 @@ single_subscript_attribute_target_rule(Parser *p)
             _res = _Py_Attribute ( a , b -> v . Name . id , Store , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -13452,7 +13902,7 @@ single_subscript_attribute_target_rule(Parser *p)
     }
     { // t_primary '[' slices ']' !t_lookahead
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> single_subscript_attribute_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' !t_lookahead"));
@@ -13475,7 +13925,7 @@ single_subscript_attribute_target_rule(Parser *p)
             D(fprintf(stderr, "%*c+ single_subscript_attribute_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' !t_lookahead"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -13485,7 +13935,7 @@ single_subscript_attribute_target_rule(Parser *p)
             _res = _Py_Subscript ( a , b , Store , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -13496,7 +13946,7 @@ single_subscript_attribute_target_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -13504,16 +13954,19 @@ single_subscript_attribute_target_rule(Parser *p)
 static asdl_seq*
 del_targets_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq* _res = NULL;
     int _mark = p->mark;
     { // ','.del_target+ ','?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> del_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.del_target+ ','?"));
@@ -13530,7 +13983,7 @@ del_targets_rule(Parser *p)
             _res = a;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -13541,7 +13994,7 @@ del_targets_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -13552,20 +14005,23 @@ del_targets_rule(Parser *p)
 static expr_ty
 del_target_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     if (_PyPegen_is_memoized(p, del_target_type, &_res)) {
-        D(p->level--);
+        p->level--;
         return _res;
     }
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -13574,7 +14030,7 @@ del_target_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // t_primary '.' NAME !t_lookahead
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> del_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME !t_lookahead"));
@@ -13594,7 +14050,7 @@ del_target_rule(Parser *p)
             D(fprintf(stderr, "%*c+ del_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME !t_lookahead"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -13604,7 +14060,7 @@ del_target_rule(Parser *p)
             _res = _Py_Attribute ( a , b -> v . Name . id , Del , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -13615,7 +14071,7 @@ del_target_rule(Parser *p)
     }
     { // t_primary '[' slices ']' !t_lookahead
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> del_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' !t_lookahead"));
@@ -13638,7 +14094,7 @@ del_target_rule(Parser *p)
             D(fprintf(stderr, "%*c+ del_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' !t_lookahead"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -13648,7 +14104,7 @@ del_target_rule(Parser *p)
             _res = _Py_Subscript ( a , b , Del , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -13659,7 +14115,7 @@ del_target_rule(Parser *p)
     }
     { // del_t_atom
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> del_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "del_t_atom"));
@@ -13679,7 +14135,7 @@ del_target_rule(Parser *p)
     _res = NULL;
   done:
     _PyPegen_insert_memo(p, _mark, del_target_type, _res);
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -13687,16 +14143,19 @@ del_target_rule(Parser *p)
 static expr_ty
 del_t_atom_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -13705,7 +14164,7 @@ del_t_atom_rule(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // NAME
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> del_t_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME"));
@@ -13718,7 +14177,7 @@ del_t_atom_rule(Parser *p)
             _res = _PyPegen_set_expr_context ( p , a , Del );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -13729,7 +14188,7 @@ del_t_atom_rule(Parser *p)
     }
     { // '(' del_target ')'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> del_t_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' del_target ')'"));
@@ -13748,7 +14207,7 @@ del_t_atom_rule(Parser *p)
             _res = _PyPegen_set_expr_context ( p , a , Del );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -13759,7 +14218,7 @@ del_t_atom_rule(Parser *p)
     }
     { // '(' del_targets? ')'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> del_t_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' del_targets? ')'"));
@@ -13777,7 +14236,7 @@ del_t_atom_rule(Parser *p)
             D(fprintf(stderr, "%*c+ del_t_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' del_targets? ')'"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -13787,7 +14246,7 @@ del_t_atom_rule(Parser *p)
             _res = _Py_Tuple ( a , Del , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -13798,7 +14257,7 @@ del_t_atom_rule(Parser *p)
     }
     { // '[' del_targets? ']'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> del_t_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'[' del_targets? ']'"));
@@ -13816,7 +14275,7 @@ del_t_atom_rule(Parser *p)
             D(fprintf(stderr, "%*c+ del_t_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'[' del_targets? ']'"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -13826,7 +14285,7 @@ del_t_atom_rule(Parser *p)
             _res = _Py_List ( a , Del , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -13837,7 +14296,7 @@ del_t_atom_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -13852,10 +14311,13 @@ static expr_ty t_primary_raw(Parser *);
 static expr_ty
 t_primary_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     expr_ty _res = NULL;
     if (_PyPegen_is_memoized(p, t_primary_type, &_res)) {
-        D(p->level--);
+        p->level--;
         return _res;
     }
     int _mark = p->mark;
@@ -13863,35 +14325,40 @@ t_primary_rule(Parser *p)
     while (1) {
         int tmpvar_8 = _PyPegen_update_memo(p, _mark, t_primary_type, _res);
         if (tmpvar_8) {
-            D(p->level--);
+            p->level--;
             return _res;
         }
         p->mark = _mark;
         void *_raw = t_primary_raw(p);
-        if (p->error_indicator)
+        if (p->error_indicator) {
+            p->level--;
             return NULL;
+        }
         if (_raw == NULL || p->mark <= _resmark)
             break;
         _resmark = p->mark;
         _res = _raw;
     }
     p->mark = _resmark;
-    D(p->level--);
+    p->level--;
     return _res;
 }
 static expr_ty
 t_primary_raw(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
         p->error_indicator = 1;
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     int _start_lineno = p->tokens[_mark]->lineno;
@@ -13900,7 +14367,7 @@ t_primary_raw(Parser *p)
     UNUSED(_start_col_offset); // Only used by EXTRA macro
     { // t_primary '.' NAME &t_lookahead
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> t_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME &t_lookahead"));
@@ -13920,7 +14387,7 @@ t_primary_raw(Parser *p)
             D(fprintf(stderr, "%*c+ t_primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME &t_lookahead"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -13930,7 +14397,7 @@ t_primary_raw(Parser *p)
             _res = _Py_Attribute ( a , b -> v . Name . id , Load , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -13941,7 +14408,7 @@ t_primary_raw(Parser *p)
     }
     { // t_primary '[' slices ']' &t_lookahead
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> t_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' &t_lookahead"));
@@ -13964,7 +14431,7 @@ t_primary_raw(Parser *p)
             D(fprintf(stderr, "%*c+ t_primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' &t_lookahead"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -13974,7 +14441,7 @@ t_primary_raw(Parser *p)
             _res = _Py_Subscript ( a , b , Load , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -13985,7 +14452,7 @@ t_primary_raw(Parser *p)
     }
     { // t_primary genexp &t_lookahead
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> t_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary genexp &t_lookahead"));
@@ -14002,7 +14469,7 @@ t_primary_raw(Parser *p)
             D(fprintf(stderr, "%*c+ t_primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary genexp &t_lookahead"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -14012,7 +14479,7 @@ t_primary_raw(Parser *p)
             _res = _Py_Call ( a , CHECK ( _PyPegen_singleton_seq ( p , b ) ) , NULL , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -14023,7 +14490,7 @@ t_primary_raw(Parser *p)
     }
     { // t_primary '(' arguments? ')' &t_lookahead
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> t_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '(' arguments? ')' &t_lookahead"));
@@ -14046,7 +14513,7 @@ t_primary_raw(Parser *p)
             D(fprintf(stderr, "%*c+ t_primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '(' arguments? ')' &t_lookahead"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             int _end_lineno = _token->end_lineno;
@@ -14056,7 +14523,7 @@ t_primary_raw(Parser *p)
             _res = _Py_Call ( a , ( b ) ? ( ( expr_ty ) b ) -> v . Call . args : NULL , ( b ) ? ( ( expr_ty ) b ) -> v . Call . keywords : NULL , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -14067,7 +14534,7 @@ t_primary_raw(Parser *p)
     }
     { // atom &t_lookahead
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> t_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "atom &t_lookahead"));
@@ -14082,7 +14549,7 @@ t_primary_raw(Parser *p)
             _res = a;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -14093,7 +14560,7 @@ t_primary_raw(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -14101,16 +14568,19 @@ t_primary_raw(Parser *p)
 static void *
 t_lookahead_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // '('
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> t_lookahead[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('"));
@@ -14129,7 +14599,7 @@ t_lookahead_rule(Parser *p)
     }
     { // '['
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> t_lookahead[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['"));
@@ -14148,7 +14618,7 @@ t_lookahead_rule(Parser *p)
     }
     { // '.'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> t_lookahead[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'"));
@@ -14167,7 +14637,7 @@ t_lookahead_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -14180,16 +14650,19 @@ t_lookahead_rule(Parser *p)
 static void *
 invalid_arguments_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // args ',' '*'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args ',' '*'"));
@@ -14208,7 +14681,7 @@ invalid_arguments_rule(Parser *p)
             _res = RAISE_SYNTAX_ERROR ( "iterable argument unpacking follows keyword argument unpacking" );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -14219,7 +14692,7 @@ invalid_arguments_rule(Parser *p)
     }
     { // expression for_if_clauses ',' [args | expression for_if_clauses]
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses ',' [args | expression for_if_clauses]"));
@@ -14242,7 +14715,7 @@ invalid_arguments_rule(Parser *p)
             _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "Generator expression must be parenthesized" );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -14253,7 +14726,7 @@ invalid_arguments_rule(Parser *p)
     }
     { // args for_if_clauses
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args for_if_clauses"));
@@ -14269,7 +14742,7 @@ invalid_arguments_rule(Parser *p)
             _res = _PyPegen_nonparen_genexp_in_call ( p , a );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -14280,7 +14753,7 @@ invalid_arguments_rule(Parser *p)
     }
     { // args ',' expression for_if_clauses
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args ',' expression for_if_clauses"));
@@ -14302,7 +14775,7 @@ invalid_arguments_rule(Parser *p)
             _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "Generator expression must be parenthesized" );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -14313,7 +14786,7 @@ invalid_arguments_rule(Parser *p)
     }
     { // args ',' args
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args ',' args"));
@@ -14332,7 +14805,7 @@ invalid_arguments_rule(Parser *p)
             _res = _PyPegen_arguments_parsing_error ( p , a );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -14343,7 +14816,7 @@ invalid_arguments_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -14351,16 +14824,19 @@ invalid_arguments_rule(Parser *p)
 static void *
 invalid_kwarg_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // !(NAME '=') expression '='
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_kwarg[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "!(NAME '=') expression '='"));
@@ -14378,7 +14854,7 @@ invalid_kwarg_rule(Parser *p)
             _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "expression cannot contain assignment, perhaps you meant \"==\"?" );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -14389,7 +14865,7 @@ invalid_kwarg_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -14397,16 +14873,19 @@ invalid_kwarg_rule(Parser *p)
 static void *
 invalid_named_expression_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // expression ':=' expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_named_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ':=' expression"));
@@ -14425,7 +14904,7 @@ invalid_named_expression_rule(Parser *p)
             _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot use assignment expressions with %s" , _PyPegen_get_expr_name ( a ) );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -14436,7 +14915,7 @@ invalid_named_expression_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -14450,16 +14929,19 @@ invalid_named_expression_rule(Parser *p)
 static void *
 invalid_assignment_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // invalid_ann_assign_target ':' expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_ann_assign_target ':' expression"));
@@ -14478,7 +14960,7 @@ invalid_assignment_rule(Parser *p)
             _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "only single target (not %s) can be annotated" , _PyPegen_get_expr_name ( a ) );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -14489,7 +14971,7 @@ invalid_assignment_rule(Parser *p)
     }
     { // star_named_expression ',' star_named_expressions* ':' expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions* ':' expression"));
@@ -14514,7 +14996,7 @@ invalid_assignment_rule(Parser *p)
             _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "only single target (not tuple) can be annotated" );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -14525,7 +15007,7 @@ invalid_assignment_rule(Parser *p)
     }
     { // expression ':' expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ':' expression"));
@@ -14544,7 +15026,7 @@ invalid_assignment_rule(Parser *p)
             _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "illegal target for annotation" );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -14555,7 +15037,7 @@ invalid_assignment_rule(Parser *p)
     }
     { // ((star_targets '='))* star_expressions '='
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* star_expressions '='"));
@@ -14574,7 +15056,7 @@ invalid_assignment_rule(Parser *p)
             _res = RAISE_SYNTAX_ERROR_INVALID_TARGET ( STAR_TARGETS , a );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -14585,7 +15067,7 @@ invalid_assignment_rule(Parser *p)
     }
     { // ((star_targets '='))* yield_expr '='
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* yield_expr '='"));
@@ -14604,7 +15086,7 @@ invalid_assignment_rule(Parser *p)
             _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "assignment to yield expression not possible" );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -14615,7 +15097,7 @@ invalid_assignment_rule(Parser *p)
     }
     { // star_expressions augassign (yield_expr | star_expressions)
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions augassign (yield_expr | star_expressions)"));
@@ -14634,7 +15116,7 @@ invalid_assignment_rule(Parser *p)
             _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "'%s' is an illegal expression for augmented assignment" , _PyPegen_get_expr_name ( a ) );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -14645,7 +15127,7 @@ invalid_assignment_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -14653,16 +15135,19 @@ invalid_assignment_rule(Parser *p)
 static expr_ty
 invalid_ann_assign_target_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     expr_ty _res = NULL;
     int _mark = p->mark;
     { // list
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_ann_assign_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "list"));
@@ -14681,7 +15166,7 @@ invalid_ann_assign_target_rule(Parser *p)
     }
     { // tuple
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_ann_assign_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "tuple"));
@@ -14700,7 +15185,7 @@ invalid_ann_assign_target_rule(Parser *p)
     }
     { // '(' invalid_ann_assign_target ')'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_ann_assign_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' invalid_ann_assign_target ')'"));
@@ -14719,7 +15204,7 @@ invalid_ann_assign_target_rule(Parser *p)
             _res = a;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -14730,7 +15215,7 @@ invalid_ann_assign_target_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -14738,16 +15223,19 @@ invalid_ann_assign_target_rule(Parser *p)
 static void *
 invalid_del_stmt_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // 'del' star_expressions
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_del_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'del' star_expressions"));
@@ -14763,7 +15251,7 @@ invalid_del_stmt_rule(Parser *p)
             _res = RAISE_SYNTAX_ERROR_INVALID_TARGET ( DEL_TARGETS , a );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -14774,7 +15262,7 @@ invalid_del_stmt_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -14782,16 +15270,19 @@ invalid_del_stmt_rule(Parser *p)
 static void *
 invalid_block_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // NEWLINE !INDENT
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE !INDENT"));
@@ -14806,7 +15297,7 @@ invalid_block_rule(Parser *p)
             _res = RAISE_INDENTATION_ERROR ( "expected an indented block" );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -14817,7 +15308,7 @@ invalid_block_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -14826,16 +15317,19 @@ invalid_block_rule(Parser *p)
 static void *
 invalid_primary_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // primary '{'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "primary '{'"));
@@ -14851,7 +15345,7 @@ invalid_primary_rule(Parser *p)
             _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "invalid syntax" );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -14862,7 +15356,7 @@ invalid_primary_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -14870,16 +15364,19 @@ invalid_primary_rule(Parser *p)
 static void *
 invalid_comprehension_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // ('[' | '(' | '{') starred_expression for_if_clauses
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('[' | '(' | '{') starred_expression for_if_clauses"));
@@ -14898,7 +15395,7 @@ invalid_comprehension_rule(Parser *p)
             _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "iterable unpacking cannot be used in comprehension" );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -14909,7 +15406,7 @@ invalid_comprehension_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -14917,16 +15414,19 @@ invalid_comprehension_rule(Parser *p)
 static void *
 invalid_dict_comprehension_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // '{' '**' bitwise_or for_if_clauses '}'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_dict_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' '**' bitwise_or for_if_clauses '}'"));
@@ -14951,7 +15451,7 @@ invalid_dict_comprehension_rule(Parser *p)
             _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "dict unpacking cannot be used in dict comprehension" );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -14962,7 +15462,7 @@ invalid_dict_comprehension_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -14971,16 +15471,19 @@ invalid_dict_comprehension_rule(Parser *p)
 static void *
 invalid_parameters_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // param_no_default* (slash_with_default | param_with_default+) param_no_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default* (slash_with_default | param_with_default+) param_no_default"));
@@ -14999,7 +15502,7 @@ invalid_parameters_rule(Parser *p)
             _res = RAISE_SYNTAX_ERROR ( "non-default argument follows default argument" );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -15010,7 +15513,7 @@ invalid_parameters_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -15019,16 +15522,19 @@ invalid_parameters_rule(Parser *p)
 static void *
 invalid_lambda_parameters_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // lambda_param_no_default* (lambda_slash_with_default | lambda_param_with_default+) lambda_param_no_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* (lambda_slash_with_default | lambda_param_with_default+) lambda_param_no_default"));
@@ -15047,7 +15553,7 @@ invalid_lambda_parameters_rule(Parser *p)
             _res = RAISE_SYNTAX_ERROR ( "non-default argument follows default argument" );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -15058,7 +15564,7 @@ invalid_lambda_parameters_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -15066,16 +15572,19 @@ invalid_lambda_parameters_rule(Parser *p)
 static void *
 invalid_star_etc_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // '*' (')' | ',' (')' | '**'))
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))"));
@@ -15091,7 +15600,7 @@ invalid_star_etc_rule(Parser *p)
             _res = RAISE_SYNTAX_ERROR ( "named arguments must follow bare *" );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -15102,7 +15611,7 @@ invalid_star_etc_rule(Parser *p)
     }
     { // '*' ',' TYPE_COMMENT
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' ',' TYPE_COMMENT"));
@@ -15121,7 +15630,7 @@ invalid_star_etc_rule(Parser *p)
             _res = RAISE_SYNTAX_ERROR ( "bare * has associated type comment" );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -15132,7 +15641,7 @@ invalid_star_etc_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -15140,16 +15649,19 @@ invalid_star_etc_rule(Parser *p)
 static void *
 invalid_lambda_star_etc_rule(Parser *p)
 {
-    D(p->level++);
-    if (p->error_indicator) {
-        D(p->level--);
-        return NULL;
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
+    if (p->error_indicator) {
+        p->level--;
+        return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // '*' (':' | ',' (':' | '**'))
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))"));
@@ -15165,7 +15677,7 @@ invalid_lambda_star_etc_rule(Parser *p)
             _res = RAISE_SYNTAX_ERROR ( "named arguments must follow bare *" );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -15176,7 +15688,7 @@ invalid_lambda_star_etc_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -15184,16 +15696,19 @@ invalid_lambda_star_etc_rule(Parser *p)
 static void *
 invalid_double_type_comments_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // TYPE_COMMENT NEWLINE TYPE_COMMENT NEWLINE INDENT
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_double_type_comments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "TYPE_COMMENT NEWLINE TYPE_COMMENT NEWLINE INDENT"));
@@ -15218,7 +15733,7 @@ invalid_double_type_comments_rule(Parser *p)
             _res = RAISE_SYNTAX_ERROR ( "Cannot have two type comments on def" );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -15229,7 +15744,7 @@ invalid_double_type_comments_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -15237,16 +15752,19 @@ invalid_double_type_comments_rule(Parser *p)
 static void *
 invalid_with_item_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // expression 'as' expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_with_item[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression 'as' expression"));
@@ -15265,7 +15783,7 @@ invalid_with_item_rule(Parser *p)
             _res = RAISE_SYNTAX_ERROR_INVALID_TARGET ( STAR_TARGETS , a );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -15276,7 +15794,7 @@ invalid_with_item_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -15284,16 +15802,19 @@ invalid_with_item_rule(Parser *p)
 static void *
 invalid_for_target_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // ASYNC? 'for' star_expressions
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_for_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'for' star_expressions"));
@@ -15313,7 +15834,7 @@ invalid_for_target_rule(Parser *p)
             _res = RAISE_SYNTAX_ERROR_INVALID_TARGET ( FOR_TARGETS , a );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -15324,7 +15845,7 @@ invalid_for_target_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -15332,16 +15853,19 @@ invalid_for_target_rule(Parser *p)
 static void *
 invalid_group_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // '(' starred_expression ')'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_group[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' starred_expression ')'"));
@@ -15360,7 +15884,7 @@ invalid_group_rule(Parser *p)
             _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "can't use starred expression here" );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -15371,7 +15895,7 @@ invalid_group_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -15379,16 +15903,19 @@ invalid_group_rule(Parser *p)
 static void *
 invalid_import_from_targets_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // import_from_as_names ',' NEWLINE
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_import_from_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "import_from_as_names ',' NEWLINE"));
@@ -15407,7 +15934,7 @@ invalid_import_from_targets_rule(Parser *p)
             _res = RAISE_SYNTAX_ERROR ( "trailing comma not allowed without surrounding parentheses" );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -15418,7 +15945,7 @@ invalid_import_from_targets_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -15426,9 +15953,12 @@ invalid_import_from_targets_rule(Parser *p)
 static asdl_seq *
 _loop0_1_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -15438,14 +15968,14 @@ _loop0_1_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // NEWLINE
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_1[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE"));
@@ -15461,7 +15991,7 @@ _loop0_1_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -15478,13 +16008,13 @@ _loop0_1_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_1_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -15492,9 +16022,12 @@ _loop0_1_rule(Parser *p)
 static asdl_seq *
 _loop0_2_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -15504,14 +16037,14 @@ _loop0_2_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // NEWLINE
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_2[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE"));
@@ -15527,7 +16060,7 @@ _loop0_2_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -15544,13 +16077,13 @@ _loop0_2_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_2_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -15558,9 +16091,12 @@ _loop0_2_rule(Parser *p)
 static asdl_seq *
 _loop0_4_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -15570,14 +16106,14 @@ _loop0_4_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // ',' expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_4[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression"));
@@ -15593,7 +16129,7 @@ _loop0_4_rule(Parser *p)
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
                 PyMem_Free(_children);
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             if (_n == _children_capacity) {
@@ -15602,7 +16138,7 @@ _loop0_4_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -15619,13 +16155,13 @@ _loop0_4_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_4_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -15633,16 +16169,19 @@ _loop0_4_rule(Parser *p)
 static asdl_seq *
 _gather_3_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
     { // expression _loop0_4
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _gather_3[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_4"));
@@ -15664,7 +16203,7 @@ _gather_3_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -15672,9 +16211,12 @@ _gather_3_rule(Parser *p)
 static asdl_seq *
 _loop0_6_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -15684,14 +16226,14 @@ _loop0_6_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // ',' expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_6[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression"));
@@ -15707,7 +16249,7 @@ _loop0_6_rule(Parser *p)
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
                 PyMem_Free(_children);
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             if (_n == _children_capacity) {
@@ -15716,7 +16258,7 @@ _loop0_6_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -15733,13 +16275,13 @@ _loop0_6_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_6_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -15747,16 +16289,19 @@ _loop0_6_rule(Parser *p)
 static asdl_seq *
 _gather_5_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
     { // expression _loop0_6
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _gather_5[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_6"));
@@ -15778,7 +16323,7 @@ _gather_5_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -15786,9 +16331,12 @@ _gather_5_rule(Parser *p)
 static asdl_seq *
 _loop0_8_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -15798,14 +16346,14 @@ _loop0_8_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // ',' expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_8[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression"));
@@ -15821,7 +16369,7 @@ _loop0_8_rule(Parser *p)
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
                 PyMem_Free(_children);
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             if (_n == _children_capacity) {
@@ -15830,7 +16378,7 @@ _loop0_8_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -15847,13 +16395,13 @@ _loop0_8_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_8_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -15861,16 +16409,19 @@ _loop0_8_rule(Parser *p)
 static asdl_seq *
 _gather_7_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
     { // expression _loop0_8
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _gather_7[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_8"));
@@ -15892,7 +16443,7 @@ _gather_7_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -15900,9 +16451,12 @@ _gather_7_rule(Parser *p)
 static asdl_seq *
 _loop0_10_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -15912,14 +16466,14 @@ _loop0_10_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // ',' expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_10[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression"));
@@ -15935,7 +16489,7 @@ _loop0_10_rule(Parser *p)
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
                 PyMem_Free(_children);
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             if (_n == _children_capacity) {
@@ -15944,7 +16498,7 @@ _loop0_10_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -15961,13 +16515,13 @@ _loop0_10_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_10_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -15975,16 +16529,19 @@ _loop0_10_rule(Parser *p)
 static asdl_seq *
 _gather_9_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
     { // expression _loop0_10
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _gather_9[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_10"));
@@ -16006,7 +16563,7 @@ _gather_9_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -16014,9 +16571,12 @@ _gather_9_rule(Parser *p)
 static asdl_seq *
 _loop1_11_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -16026,14 +16586,14 @@ _loop1_11_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // statement
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_11[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "statement"));
@@ -16049,7 +16609,7 @@ _loop1_11_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -16063,7 +16623,7 @@ _loop1_11_rule(Parser *p)
     }
     if (_n == 0 || p->error_indicator) {
         PyMem_Free(_children);
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
@@ -16071,13 +16631,13 @@ _loop1_11_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop1_11_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -16085,9 +16645,12 @@ _loop1_11_rule(Parser *p)
 static asdl_seq *
 _loop0_13_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -16097,14 +16660,14 @@ _loop0_13_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // ';' small_stmt
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_13[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "';' small_stmt"));
@@ -16120,7 +16683,7 @@ _loop0_13_rule(Parser *p)
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
                 PyMem_Free(_children);
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             if (_n == _children_capacity) {
@@ -16129,7 +16692,7 @@ _loop0_13_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -16146,13 +16709,13 @@ _loop0_13_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_13_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -16160,16 +16723,19 @@ _loop0_13_rule(Parser *p)
 static asdl_seq *
 _gather_12_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
     { // small_stmt _loop0_13
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _gather_12[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "small_stmt _loop0_13"));
@@ -16191,7 +16757,7 @@ _gather_12_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -16199,16 +16765,19 @@ _gather_12_rule(Parser *p)
 static void *
 _tmp_14_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // 'import'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_14[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'import'"));
@@ -16227,7 +16796,7 @@ _tmp_14_rule(Parser *p)
     }
     { // 'from'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_14[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'from'"));
@@ -16246,7 +16815,7 @@ _tmp_14_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -16254,16 +16823,19 @@ _tmp_14_rule(Parser *p)
 static void *
 _tmp_15_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // 'def'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_15[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'def'"));
@@ -16282,7 +16854,7 @@ _tmp_15_rule(Parser *p)
     }
     { // '@'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_15[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@'"));
@@ -16301,7 +16873,7 @@ _tmp_15_rule(Parser *p)
     }
     { // ASYNC
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_15[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC"));
@@ -16320,7 +16892,7 @@ _tmp_15_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -16328,16 +16900,19 @@ _tmp_15_rule(Parser *p)
 static void *
 _tmp_16_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // 'class'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_16[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'class'"));
@@ -16356,7 +16931,7 @@ _tmp_16_rule(Parser *p)
     }
     { // '@'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_16[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@'"));
@@ -16375,7 +16950,7 @@ _tmp_16_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -16383,16 +16958,19 @@ _tmp_16_rule(Parser *p)
 static void *
 _tmp_17_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // 'with'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_17[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'with'"));
@@ -16411,7 +16989,7 @@ _tmp_17_rule(Parser *p)
     }
     { // ASYNC
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_17[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC"));
@@ -16430,7 +17008,7 @@ _tmp_17_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -16438,16 +17016,19 @@ _tmp_17_rule(Parser *p)
 static void *
 _tmp_18_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // 'for'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_18[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'for'"));
@@ -16466,7 +17047,7 @@ _tmp_18_rule(Parser *p)
     }
     { // ASYNC
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_18[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC"));
@@ -16485,7 +17066,7 @@ _tmp_18_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -16493,16 +17074,19 @@ _tmp_18_rule(Parser *p)
 static void *
 _tmp_19_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // '=' annotated_rhs
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_19[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'=' annotated_rhs"));
@@ -16518,7 +17102,7 @@ _tmp_19_rule(Parser *p)
             _res = d;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -16529,7 +17113,7 @@ _tmp_19_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -16537,16 +17121,19 @@ _tmp_19_rule(Parser *p)
 static void *
 _tmp_20_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // '(' single_target ')'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_20[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' single_target ')'"));
@@ -16565,7 +17152,7 @@ _tmp_20_rule(Parser *p)
             _res = b;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -16576,7 +17163,7 @@ _tmp_20_rule(Parser *p)
     }
     { // single_subscript_attribute_target
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_20[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "single_subscript_attribute_target"));
@@ -16595,7 +17182,7 @@ _tmp_20_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -16603,16 +17190,19 @@ _tmp_20_rule(Parser *p)
 static void *
 _tmp_21_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // '=' annotated_rhs
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_21[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'=' annotated_rhs"));
@@ -16628,7 +17218,7 @@ _tmp_21_rule(Parser *p)
             _res = d;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -16639,7 +17229,7 @@ _tmp_21_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -16647,9 +17237,12 @@ _tmp_21_rule(Parser *p)
 static asdl_seq *
 _loop1_22_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -16659,14 +17252,14 @@ _loop1_22_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // (star_targets '=')
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_22[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')"));
@@ -16682,7 +17275,7 @@ _loop1_22_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -16696,7 +17289,7 @@ _loop1_22_rule(Parser *p)
     }
     if (_n == 0 || p->error_indicator) {
         PyMem_Free(_children);
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
@@ -16704,13 +17297,13 @@ _loop1_22_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop1_22_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -16718,16 +17311,19 @@ _loop1_22_rule(Parser *p)
 static void *
 _tmp_23_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // yield_expr
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_23[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr"));
@@ -16746,7 +17342,7 @@ _tmp_23_rule(Parser *p)
     }
     { // star_expressions
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_23[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions"));
@@ -16765,7 +17361,7 @@ _tmp_23_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -16773,16 +17369,19 @@ _tmp_23_rule(Parser *p)
 static void *
 _tmp_24_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // yield_expr
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_24[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr"));
@@ -16801,7 +17400,7 @@ _tmp_24_rule(Parser *p)
     }
     { // star_expressions
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_24[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions"));
@@ -16820,7 +17419,7 @@ _tmp_24_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -16828,9 +17427,12 @@ _tmp_24_rule(Parser *p)
 static asdl_seq *
 _loop0_26_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -16840,14 +17442,14 @@ _loop0_26_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // ',' NAME
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_26[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' NAME"));
@@ -16863,7 +17465,7 @@ _loop0_26_rule(Parser *p)
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
                 PyMem_Free(_children);
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             if (_n == _children_capacity) {
@@ -16872,7 +17474,7 @@ _loop0_26_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -16889,13 +17491,13 @@ _loop0_26_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_26_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -16903,16 +17505,19 @@ _loop0_26_rule(Parser *p)
 static asdl_seq *
 _gather_25_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
     { // NAME _loop0_26
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _gather_25[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME _loop0_26"));
@@ -16934,7 +17539,7 @@ _gather_25_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -16942,9 +17547,12 @@ _gather_25_rule(Parser *p)
 static asdl_seq *
 _loop0_28_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -16954,14 +17562,14 @@ _loop0_28_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // ',' NAME
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_28[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' NAME"));
@@ -16977,7 +17585,7 @@ _loop0_28_rule(Parser *p)
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
                 PyMem_Free(_children);
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             if (_n == _children_capacity) {
@@ -16986,7 +17594,7 @@ _loop0_28_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -17003,13 +17611,13 @@ _loop0_28_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_28_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -17017,16 +17625,19 @@ _loop0_28_rule(Parser *p)
 static asdl_seq *
 _gather_27_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
     { // NAME _loop0_28
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _gather_27[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME _loop0_28"));
@@ -17048,7 +17659,7 @@ _gather_27_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -17056,16 +17667,19 @@ _gather_27_rule(Parser *p)
 static void *
 _tmp_29_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // ',' expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_29[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression"));
@@ -17081,7 +17695,7 @@ _tmp_29_rule(Parser *p)
             _res = z;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -17092,7 +17706,7 @@ _tmp_29_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -17100,16 +17714,19 @@ _tmp_29_rule(Parser *p)
 static void *
 _tmp_30_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // ';'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_30[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "';'"));
@@ -17128,7 +17745,7 @@ _tmp_30_rule(Parser *p)
     }
     { // NEWLINE
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_30[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE"));
@@ -17147,7 +17764,7 @@ _tmp_30_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -17155,9 +17772,12 @@ _tmp_30_rule(Parser *p)
 static asdl_seq *
 _loop0_31_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -17167,14 +17787,14 @@ _loop0_31_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // ('.' | '...')
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_31[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')"));
@@ -17190,7 +17810,7 @@ _loop0_31_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -17207,13 +17827,13 @@ _loop0_31_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_31_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -17221,9 +17841,12 @@ _loop0_31_rule(Parser *p)
 static asdl_seq *
 _loop1_32_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -17233,14 +17856,14 @@ _loop1_32_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // ('.' | '...')
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_32[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')"));
@@ -17256,7 +17879,7 @@ _loop1_32_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -17270,7 +17893,7 @@ _loop1_32_rule(Parser *p)
     }
     if (_n == 0 || p->error_indicator) {
         PyMem_Free(_children);
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
@@ -17278,13 +17901,13 @@ _loop1_32_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop1_32_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -17292,9 +17915,12 @@ _loop1_32_rule(Parser *p)
 static asdl_seq *
 _loop0_34_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -17304,14 +17930,14 @@ _loop0_34_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // ',' import_from_as_name
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_34[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' import_from_as_name"));
@@ -17327,7 +17953,7 @@ _loop0_34_rule(Parser *p)
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
                 PyMem_Free(_children);
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             if (_n == _children_capacity) {
@@ -17336,7 +17962,7 @@ _loop0_34_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -17353,13 +17979,13 @@ _loop0_34_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_34_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -17367,16 +17993,19 @@ _loop0_34_rule(Parser *p)
 static asdl_seq *
 _gather_33_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
     { // import_from_as_name _loop0_34
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _gather_33[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "import_from_as_name _loop0_34"));
@@ -17398,7 +18027,7 @@ _gather_33_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -17406,16 +18035,19 @@ _gather_33_rule(Parser *p)
 static void *
 _tmp_35_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // 'as' NAME
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_35[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME"));
@@ -17431,7 +18063,7 @@ _tmp_35_rule(Parser *p)
             _res = z;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -17442,7 +18074,7 @@ _tmp_35_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -17450,9 +18082,12 @@ _tmp_35_rule(Parser *p)
 static asdl_seq *
 _loop0_37_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -17462,14 +18097,14 @@ _loop0_37_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // ',' dotted_as_name
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_37[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' dotted_as_name"));
@@ -17485,7 +18120,7 @@ _loop0_37_rule(Parser *p)
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
                 PyMem_Free(_children);
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             if (_n == _children_capacity) {
@@ -17494,7 +18129,7 @@ _loop0_37_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -17511,13 +18146,13 @@ _loop0_37_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_37_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -17525,16 +18160,19 @@ _loop0_37_rule(Parser *p)
 static asdl_seq *
 _gather_36_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
     { // dotted_as_name _loop0_37
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _gather_36[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dotted_as_name _loop0_37"));
@@ -17556,7 +18194,7 @@ _gather_36_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -17564,16 +18202,19 @@ _gather_36_rule(Parser *p)
 static void *
 _tmp_38_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // 'as' NAME
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_38[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME"));
@@ -17589,7 +18230,7 @@ _tmp_38_rule(Parser *p)
             _res = z;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -17600,7 +18241,7 @@ _tmp_38_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -17608,9 +18249,12 @@ _tmp_38_rule(Parser *p)
 static asdl_seq *
 _loop0_40_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -17620,14 +18264,14 @@ _loop0_40_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // ',' with_item
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_40[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item"));
@@ -17643,7 +18287,7 @@ _loop0_40_rule(Parser *p)
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
                 PyMem_Free(_children);
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             if (_n == _children_capacity) {
@@ -17652,7 +18296,7 @@ _loop0_40_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -17669,13 +18313,13 @@ _loop0_40_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_40_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -17683,16 +18327,19 @@ _loop0_40_rule(Parser *p)
 static asdl_seq *
 _gather_39_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
     { // with_item _loop0_40
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _gather_39[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_40"));
@@ -17714,7 +18361,7 @@ _gather_39_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -17722,9 +18369,12 @@ _gather_39_rule(Parser *p)
 static asdl_seq *
 _loop0_42_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -17734,14 +18384,14 @@ _loop0_42_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // ',' with_item
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_42[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item"));
@@ -17757,7 +18407,7 @@ _loop0_42_rule(Parser *p)
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
                 PyMem_Free(_children);
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             if (_n == _children_capacity) {
@@ -17766,7 +18416,7 @@ _loop0_42_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -17783,13 +18433,13 @@ _loop0_42_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_42_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -17797,16 +18447,19 @@ _loop0_42_rule(Parser *p)
 static asdl_seq *
 _gather_41_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
     { // with_item _loop0_42
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _gather_41[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_42"));
@@ -17828,7 +18481,7 @@ _gather_41_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -17836,9 +18489,12 @@ _gather_41_rule(Parser *p)
 static asdl_seq *
 _loop0_44_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -17848,14 +18504,14 @@ _loop0_44_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // ',' with_item
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_44[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item"));
@@ -17871,7 +18527,7 @@ _loop0_44_rule(Parser *p)
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
                 PyMem_Free(_children);
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             if (_n == _children_capacity) {
@@ -17880,7 +18536,7 @@ _loop0_44_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -17897,13 +18553,13 @@ _loop0_44_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_44_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -17911,16 +18567,19 @@ _loop0_44_rule(Parser *p)
 static asdl_seq *
 _gather_43_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
     { // with_item _loop0_44
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _gather_43[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_44"));
@@ -17942,7 +18601,7 @@ _gather_43_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -17950,9 +18609,12 @@ _gather_43_rule(Parser *p)
 static asdl_seq *
 _loop0_46_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -17962,14 +18624,14 @@ _loop0_46_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // ',' with_item
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_46[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item"));
@@ -17985,7 +18647,7 @@ _loop0_46_rule(Parser *p)
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
                 PyMem_Free(_children);
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             if (_n == _children_capacity) {
@@ -17994,7 +18656,7 @@ _loop0_46_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -18011,13 +18673,13 @@ _loop0_46_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_46_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -18025,16 +18687,19 @@ _loop0_46_rule(Parser *p)
 static asdl_seq *
 _gather_45_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
     { // with_item _loop0_46
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _gather_45[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_46"));
@@ -18056,7 +18721,7 @@ _gather_45_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -18064,16 +18729,19 @@ _gather_45_rule(Parser *p)
 static void *
 _tmp_47_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // ','
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_47[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','"));
@@ -18092,7 +18760,7 @@ _tmp_47_rule(Parser *p)
     }
     { // ')'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_47[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'"));
@@ -18111,7 +18779,7 @@ _tmp_47_rule(Parser *p)
     }
     { // ':'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_47[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'"));
@@ -18130,7 +18798,7 @@ _tmp_47_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -18138,9 +18806,12 @@ _tmp_47_rule(Parser *p)
 static asdl_seq *
 _loop1_48_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -18150,14 +18821,14 @@ _loop1_48_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // except_block
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_48[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_block"));
@@ -18173,7 +18844,7 @@ _loop1_48_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -18187,7 +18858,7 @@ _loop1_48_rule(Parser *p)
     }
     if (_n == 0 || p->error_indicator) {
         PyMem_Free(_children);
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
@@ -18195,13 +18866,13 @@ _loop1_48_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop1_48_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -18209,16 +18880,19 @@ _loop1_48_rule(Parser *p)
 static void *
 _tmp_49_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // 'as' NAME
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_49[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME"));
@@ -18234,7 +18908,7 @@ _tmp_49_rule(Parser *p)
             _res = z;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -18245,7 +18919,7 @@ _tmp_49_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -18253,16 +18927,19 @@ _tmp_49_rule(Parser *p)
 static void *
 _tmp_50_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // 'from' expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_50[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'from' expression"));
@@ -18278,7 +18955,7 @@ _tmp_50_rule(Parser *p)
             _res = z;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -18289,7 +18966,7 @@ _tmp_50_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -18297,16 +18974,19 @@ _tmp_50_rule(Parser *p)
 static void *
 _tmp_51_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // '->' expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_51[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression"));
@@ -18322,7 +19002,7 @@ _tmp_51_rule(Parser *p)
             _res = z;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -18333,7 +19013,7 @@ _tmp_51_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -18341,16 +19021,19 @@ _tmp_51_rule(Parser *p)
 static void *
 _tmp_52_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // '->' expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_52[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression"));
@@ -18366,7 +19049,7 @@ _tmp_52_rule(Parser *p)
             _res = z;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -18377,7 +19060,7 @@ _tmp_52_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -18385,16 +19068,19 @@ _tmp_52_rule(Parser *p)
 static void *
 _tmp_53_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // NEWLINE INDENT
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_53[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE INDENT"));
@@ -18416,7 +19102,7 @@ _tmp_53_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -18424,9 +19110,12 @@ _tmp_53_rule(Parser *p)
 static asdl_seq *
 _loop0_54_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -18436,14 +19125,14 @@ _loop0_54_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // param_no_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_54[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default"));
@@ -18459,7 +19148,7 @@ _loop0_54_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -18476,13 +19165,13 @@ _loop0_54_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_54_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -18490,9 +19179,12 @@ _loop0_54_rule(Parser *p)
 static asdl_seq *
 _loop0_55_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -18502,14 +19194,14 @@ _loop0_55_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // param_with_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_55[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default"));
@@ -18525,7 +19217,7 @@ _loop0_55_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -18542,13 +19234,13 @@ _loop0_55_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_55_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -18556,9 +19248,12 @@ _loop0_55_rule(Parser *p)
 static asdl_seq *
 _loop0_56_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -18568,14 +19263,14 @@ _loop0_56_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // param_with_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_56[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default"));
@@ -18591,7 +19286,7 @@ _loop0_56_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -18608,13 +19303,13 @@ _loop0_56_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_56_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -18622,9 +19317,12 @@ _loop0_56_rule(Parser *p)
 static asdl_seq *
 _loop1_57_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -18634,14 +19332,14 @@ _loop1_57_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // param_no_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_57[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default"));
@@ -18657,7 +19355,7 @@ _loop1_57_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -18671,7 +19369,7 @@ _loop1_57_rule(Parser *p)
     }
     if (_n == 0 || p->error_indicator) {
         PyMem_Free(_children);
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
@@ -18679,13 +19377,13 @@ _loop1_57_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop1_57_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -18693,9 +19391,12 @@ _loop1_57_rule(Parser *p)
 static asdl_seq *
 _loop0_58_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -18705,14 +19406,14 @@ _loop0_58_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // param_with_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_58[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default"));
@@ -18728,7 +19429,7 @@ _loop0_58_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -18745,13 +19446,13 @@ _loop0_58_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_58_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -18759,9 +19460,12 @@ _loop0_58_rule(Parser *p)
 static asdl_seq *
 _loop1_59_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -18771,14 +19475,14 @@ _loop1_59_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // param_with_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_59[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default"));
@@ -18794,7 +19498,7 @@ _loop1_59_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -18808,7 +19512,7 @@ _loop1_59_rule(Parser *p)
     }
     if (_n == 0 || p->error_indicator) {
         PyMem_Free(_children);
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
@@ -18816,13 +19520,13 @@ _loop1_59_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop1_59_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -18830,9 +19534,12 @@ _loop1_59_rule(Parser *p)
 static asdl_seq *
 _loop1_60_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -18842,14 +19549,14 @@ _loop1_60_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // param_no_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_60[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default"));
@@ -18865,7 +19572,7 @@ _loop1_60_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -18879,7 +19586,7 @@ _loop1_60_rule(Parser *p)
     }
     if (_n == 0 || p->error_indicator) {
         PyMem_Free(_children);
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
@@ -18887,13 +19594,13 @@ _loop1_60_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop1_60_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -18901,9 +19608,12 @@ _loop1_60_rule(Parser *p)
 static asdl_seq *
 _loop1_61_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -18913,14 +19623,14 @@ _loop1_61_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // param_no_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_61[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default"));
@@ -18936,7 +19646,7 @@ _loop1_61_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -18950,7 +19660,7 @@ _loop1_61_rule(Parser *p)
     }
     if (_n == 0 || p->error_indicator) {
         PyMem_Free(_children);
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
@@ -18958,13 +19668,13 @@ _loop1_61_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop1_61_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -18972,9 +19682,12 @@ _loop1_61_rule(Parser *p)
 static asdl_seq *
 _loop0_62_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -18984,14 +19697,14 @@ _loop0_62_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // param_no_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_62[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default"));
@@ -19007,7 +19720,7 @@ _loop0_62_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -19024,13 +19737,13 @@ _loop0_62_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_62_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -19038,9 +19751,12 @@ _loop0_62_rule(Parser *p)
 static asdl_seq *
 _loop1_63_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -19050,14 +19766,14 @@ _loop1_63_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // param_with_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_63[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default"));
@@ -19073,7 +19789,7 @@ _loop1_63_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -19087,7 +19803,7 @@ _loop1_63_rule(Parser *p)
     }
     if (_n == 0 || p->error_indicator) {
         PyMem_Free(_children);
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
@@ -19095,13 +19811,13 @@ _loop1_63_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop1_63_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -19109,9 +19825,12 @@ _loop1_63_rule(Parser *p)
 static asdl_seq *
 _loop0_64_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -19121,14 +19840,14 @@ _loop0_64_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // param_no_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_64[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default"));
@@ -19144,7 +19863,7 @@ _loop0_64_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -19161,13 +19880,13 @@ _loop0_64_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_64_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -19175,9 +19894,12 @@ _loop0_64_rule(Parser *p)
 static asdl_seq *
 _loop1_65_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -19187,14 +19909,14 @@ _loop1_65_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // param_with_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_65[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default"));
@@ -19210,7 +19932,7 @@ _loop1_65_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -19224,7 +19946,7 @@ _loop1_65_rule(Parser *p)
     }
     if (_n == 0 || p->error_indicator) {
         PyMem_Free(_children);
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
@@ -19232,13 +19954,13 @@ _loop1_65_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop1_65_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -19246,9 +19968,12 @@ _loop1_65_rule(Parser *p)
 static asdl_seq *
 _loop0_66_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -19258,14 +19983,14 @@ _loop0_66_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // param_maybe_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_66[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default"));
@@ -19281,7 +20006,7 @@ _loop0_66_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -19298,13 +20023,13 @@ _loop0_66_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_66_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -19312,9 +20037,12 @@ _loop0_66_rule(Parser *p)
 static asdl_seq *
 _loop1_67_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -19324,14 +20052,14 @@ _loop1_67_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // param_maybe_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_67[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default"));
@@ -19347,7 +20075,7 @@ _loop1_67_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -19361,7 +20089,7 @@ _loop1_67_rule(Parser *p)
     }
     if (_n == 0 || p->error_indicator) {
         PyMem_Free(_children);
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
@@ -19369,13 +20097,13 @@ _loop1_67_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop1_67_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -19383,9 +20111,12 @@ _loop1_67_rule(Parser *p)
 static asdl_seq *
 _loop1_68_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -19395,14 +20126,14 @@ _loop1_68_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // ('@' named_expression NEWLINE)
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_68[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('@' named_expression NEWLINE)"));
@@ -19418,7 +20149,7 @@ _loop1_68_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -19432,7 +20163,7 @@ _loop1_68_rule(Parser *p)
     }
     if (_n == 0 || p->error_indicator) {
         PyMem_Free(_children);
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
@@ -19440,13 +20171,13 @@ _loop1_68_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop1_68_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -19454,16 +20185,19 @@ _loop1_68_rule(Parser *p)
 static void *
 _tmp_69_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // '(' arguments? ')'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_69[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'"));
@@ -19482,7 +20216,7 @@ _tmp_69_rule(Parser *p)
             _res = z;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -19493,7 +20227,7 @@ _tmp_69_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -19501,9 +20235,12 @@ _tmp_69_rule(Parser *p)
 static asdl_seq *
 _loop1_70_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -19513,14 +20250,14 @@ _loop1_70_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // (',' star_expression)
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_70[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_expression)"));
@@ -19536,7 +20273,7 @@ _loop1_70_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -19550,7 +20287,7 @@ _loop1_70_rule(Parser *p)
     }
     if (_n == 0 || p->error_indicator) {
         PyMem_Free(_children);
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
@@ -19558,13 +20295,13 @@ _loop1_70_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop1_70_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -19572,9 +20309,12 @@ _loop1_70_rule(Parser *p)
 static asdl_seq *
 _loop0_72_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -19584,14 +20324,14 @@ _loop0_72_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // ',' star_named_expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_72[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_named_expression"));
@@ -19607,7 +20347,7 @@ _loop0_72_rule(Parser *p)
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
                 PyMem_Free(_children);
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             if (_n == _children_capacity) {
@@ -19616,7 +20356,7 @@ _loop0_72_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -19633,13 +20373,13 @@ _loop0_72_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_72_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -19647,16 +20387,19 @@ _loop0_72_rule(Parser *p)
 static asdl_seq *
 _gather_71_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
     { // star_named_expression _loop0_72
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _gather_71[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression _loop0_72"));
@@ -19678,7 +20421,7 @@ _gather_71_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -19686,9 +20429,12 @@ _gather_71_rule(Parser *p)
 static asdl_seq *
 _loop1_73_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -19698,14 +20444,14 @@ _loop1_73_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // (',' expression)
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_73[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' expression)"));
@@ -19721,7 +20467,7 @@ _loop1_73_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -19735,7 +20481,7 @@ _loop1_73_rule(Parser *p)
     }
     if (_n == 0 || p->error_indicator) {
         PyMem_Free(_children);
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
@@ -19743,13 +20489,13 @@ _loop1_73_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop1_73_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -19757,9 +20503,12 @@ _loop1_73_rule(Parser *p)
 static asdl_seq *
 _loop0_74_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -19769,14 +20518,14 @@ _loop0_74_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // lambda_param_no_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_74[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
@@ -19792,7 +20541,7 @@ _loop0_74_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -19809,13 +20558,13 @@ _loop0_74_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_74_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -19823,9 +20572,12 @@ _loop0_74_rule(Parser *p)
 static asdl_seq *
 _loop0_75_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -19835,14 +20587,14 @@ _loop0_75_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // lambda_param_with_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_75[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default"));
@@ -19858,7 +20610,7 @@ _loop0_75_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -19875,13 +20627,13 @@ _loop0_75_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_75_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -19889,9 +20641,12 @@ _loop0_75_rule(Parser *p)
 static asdl_seq *
 _loop0_76_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -19901,14 +20656,14 @@ _loop0_76_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // lambda_param_with_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_76[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default"));
@@ -19924,7 +20679,7 @@ _loop0_76_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -19941,13 +20696,13 @@ _loop0_76_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_76_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -19955,9 +20710,12 @@ _loop0_76_rule(Parser *p)
 static asdl_seq *
 _loop1_77_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -19967,14 +20725,14 @@ _loop1_77_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // lambda_param_no_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_77[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
@@ -19990,7 +20748,7 @@ _loop1_77_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -20004,7 +20762,7 @@ _loop1_77_rule(Parser *p)
     }
     if (_n == 0 || p->error_indicator) {
         PyMem_Free(_children);
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
@@ -20012,13 +20770,13 @@ _loop1_77_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop1_77_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -20026,9 +20784,12 @@ _loop1_77_rule(Parser *p)
 static asdl_seq *
 _loop0_78_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -20038,14 +20799,14 @@ _loop0_78_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // lambda_param_with_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_78[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default"));
@@ -20061,7 +20822,7 @@ _loop0_78_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -20078,13 +20839,13 @@ _loop0_78_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_78_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -20092,9 +20853,12 @@ _loop0_78_rule(Parser *p)
 static asdl_seq *
 _loop1_79_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -20104,14 +20868,14 @@ _loop1_79_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // lambda_param_with_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_79[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default"));
@@ -20127,7 +20891,7 @@ _loop1_79_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -20141,7 +20905,7 @@ _loop1_79_rule(Parser *p)
     }
     if (_n == 0 || p->error_indicator) {
         PyMem_Free(_children);
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
@@ -20149,13 +20913,13 @@ _loop1_79_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop1_79_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -20163,9 +20927,12 @@ _loop1_79_rule(Parser *p)
 static asdl_seq *
 _loop1_80_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -20175,14 +20942,14 @@ _loop1_80_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // lambda_param_no_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_80[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
@@ -20198,7 +20965,7 @@ _loop1_80_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -20212,7 +20979,7 @@ _loop1_80_rule(Parser *p)
     }
     if (_n == 0 || p->error_indicator) {
         PyMem_Free(_children);
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
@@ -20220,13 +20987,13 @@ _loop1_80_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop1_80_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -20234,9 +21001,12 @@ _loop1_80_rule(Parser *p)
 static asdl_seq *
 _loop1_81_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -20246,14 +21016,14 @@ _loop1_81_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // lambda_param_no_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_81[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
@@ -20269,7 +21039,7 @@ _loop1_81_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -20283,7 +21053,7 @@ _loop1_81_rule(Parser *p)
     }
     if (_n == 0 || p->error_indicator) {
         PyMem_Free(_children);
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
@@ -20291,13 +21061,13 @@ _loop1_81_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop1_81_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -20305,9 +21075,12 @@ _loop1_81_rule(Parser *p)
 static asdl_seq *
 _loop0_82_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -20317,14 +21090,14 @@ _loop0_82_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // lambda_param_no_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_82[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
@@ -20340,7 +21113,7 @@ _loop0_82_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -20357,13 +21130,13 @@ _loop0_82_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_82_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -20371,9 +21144,12 @@ _loop0_82_rule(Parser *p)
 static asdl_seq *
 _loop1_83_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -20383,14 +21159,14 @@ _loop1_83_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // lambda_param_with_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_83[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default"));
@@ -20406,7 +21182,7 @@ _loop1_83_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -20420,7 +21196,7 @@ _loop1_83_rule(Parser *p)
     }
     if (_n == 0 || p->error_indicator) {
         PyMem_Free(_children);
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
@@ -20428,13 +21204,13 @@ _loop1_83_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop1_83_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -20442,9 +21218,12 @@ _loop1_83_rule(Parser *p)
 static asdl_seq *
 _loop0_84_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -20454,14 +21233,14 @@ _loop0_84_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // lambda_param_no_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_84[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
@@ -20477,7 +21256,7 @@ _loop0_84_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -20494,13 +21273,13 @@ _loop0_84_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_84_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -20508,9 +21287,12 @@ _loop0_84_rule(Parser *p)
 static asdl_seq *
 _loop1_85_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -20520,14 +21302,14 @@ _loop1_85_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // lambda_param_with_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_85[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default"));
@@ -20543,7 +21325,7 @@ _loop1_85_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -20557,7 +21339,7 @@ _loop1_85_rule(Parser *p)
     }
     if (_n == 0 || p->error_indicator) {
         PyMem_Free(_children);
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
@@ -20565,13 +21347,13 @@ _loop1_85_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop1_85_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -20579,9 +21361,12 @@ _loop1_85_rule(Parser *p)
 static asdl_seq *
 _loop0_86_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -20591,14 +21376,14 @@ _loop0_86_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // lambda_param_maybe_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_86[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default"));
@@ -20614,7 +21399,7 @@ _loop0_86_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -20631,13 +21416,13 @@ _loop0_86_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_86_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -20645,9 +21430,12 @@ _loop0_86_rule(Parser *p)
 static asdl_seq *
 _loop1_87_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -20657,14 +21445,14 @@ _loop1_87_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // lambda_param_maybe_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_87[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default"));
@@ -20680,7 +21468,7 @@ _loop1_87_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -20694,7 +21482,7 @@ _loop1_87_rule(Parser *p)
     }
     if (_n == 0 || p->error_indicator) {
         PyMem_Free(_children);
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
@@ -20702,13 +21490,13 @@ _loop1_87_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop1_87_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -20716,9 +21504,12 @@ _loop1_87_rule(Parser *p)
 static asdl_seq *
 _loop1_88_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -20728,14 +21519,14 @@ _loop1_88_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // ('or' conjunction)
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_88[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('or' conjunction)"));
@@ -20751,7 +21542,7 @@ _loop1_88_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -20765,7 +21556,7 @@ _loop1_88_rule(Parser *p)
     }
     if (_n == 0 || p->error_indicator) {
         PyMem_Free(_children);
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
@@ -20773,13 +21564,13 @@ _loop1_88_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop1_88_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -20787,9 +21578,12 @@ _loop1_88_rule(Parser *p)
 static asdl_seq *
 _loop1_89_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -20799,14 +21593,14 @@ _loop1_89_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // ('and' inversion)
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_89[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('and' inversion)"));
@@ -20822,7 +21616,7 @@ _loop1_89_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -20836,7 +21630,7 @@ _loop1_89_rule(Parser *p)
     }
     if (_n == 0 || p->error_indicator) {
         PyMem_Free(_children);
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
@@ -20844,13 +21638,13 @@ _loop1_89_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop1_89_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -20858,9 +21652,12 @@ _loop1_89_rule(Parser *p)
 static asdl_seq *
 _loop1_90_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -20870,14 +21667,14 @@ _loop1_90_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // compare_op_bitwise_or_pair
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_90[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "compare_op_bitwise_or_pair"));
@@ -20893,7 +21690,7 @@ _loop1_90_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -20907,7 +21704,7 @@ _loop1_90_rule(Parser *p)
     }
     if (_n == 0 || p->error_indicator) {
         PyMem_Free(_children);
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
@@ -20915,13 +21712,13 @@ _loop1_90_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop1_90_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -20929,16 +21726,19 @@ _loop1_90_rule(Parser *p)
 static void *
 _tmp_91_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // '!='
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_91[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!='"));
@@ -20951,7 +21751,7 @@ _tmp_91_rule(Parser *p)
             _res = _PyPegen_check_barry_as_flufl ( p , tok ) ? NULL : tok;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -20962,7 +21762,7 @@ _tmp_91_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -20970,9 +21770,12 @@ _tmp_91_rule(Parser *p)
 static asdl_seq *
 _loop0_93_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -20982,14 +21785,14 @@ _loop0_93_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // ',' slice
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_93[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' slice"));
@@ -21005,7 +21808,7 @@ _loop0_93_rule(Parser *p)
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
                 PyMem_Free(_children);
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             if (_n == _children_capacity) {
@@ -21014,7 +21817,7 @@ _loop0_93_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -21031,13 +21834,13 @@ _loop0_93_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_93_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -21045,16 +21848,19 @@ _loop0_93_rule(Parser *p)
 static asdl_seq *
 _gather_92_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
     { // slice _loop0_93
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _gather_92[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slice _loop0_93"));
@@ -21076,7 +21882,7 @@ _gather_92_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -21084,16 +21890,19 @@ _gather_92_rule(Parser *p)
 static void *
 _tmp_94_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // ':' expression?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_94[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':' expression?"));
@@ -21109,7 +21918,7 @@ _tmp_94_rule(Parser *p)
             _res = d;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -21120,7 +21929,7 @@ _tmp_94_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -21128,16 +21937,19 @@ _tmp_94_rule(Parser *p)
 static void *
 _tmp_95_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // tuple
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_95[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "tuple"));
@@ -21156,7 +21968,7 @@ _tmp_95_rule(Parser *p)
     }
     { // group
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_95[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "group"));
@@ -21175,7 +21987,7 @@ _tmp_95_rule(Parser *p)
     }
     { // genexp
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_95[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "genexp"));
@@ -21194,7 +22006,7 @@ _tmp_95_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -21202,16 +22014,19 @@ _tmp_95_rule(Parser *p)
 static void *
 _tmp_96_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // list
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_96[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "list"));
@@ -21230,7 +22045,7 @@ _tmp_96_rule(Parser *p)
     }
     { // listcomp
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_96[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "listcomp"));
@@ -21249,7 +22064,7 @@ _tmp_96_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -21257,16 +22072,19 @@ _tmp_96_rule(Parser *p)
 static void *
 _tmp_97_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // dict
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_97[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dict"));
@@ -21285,7 +22103,7 @@ _tmp_97_rule(Parser *p)
     }
     { // set
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_97[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "set"));
@@ -21304,7 +22122,7 @@ _tmp_97_rule(Parser *p)
     }
     { // dictcomp
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_97[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dictcomp"));
@@ -21323,7 +22141,7 @@ _tmp_97_rule(Parser *p)
     }
     { // setcomp
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_97[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "setcomp"));
@@ -21342,7 +22160,7 @@ _tmp_97_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -21350,9 +22168,12 @@ _tmp_97_rule(Parser *p)
 static asdl_seq *
 _loop1_98_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -21362,14 +22183,14 @@ _loop1_98_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // STRING
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_98[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "STRING"));
@@ -21385,7 +22206,7 @@ _loop1_98_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -21399,7 +22220,7 @@ _loop1_98_rule(Parser *p)
     }
     if (_n == 0 || p->error_indicator) {
         PyMem_Free(_children);
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
@@ -21407,13 +22228,13 @@ _loop1_98_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop1_98_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -21421,16 +22242,19 @@ _loop1_98_rule(Parser *p)
 static void *
 _tmp_99_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // star_named_expression ',' star_named_expressions?
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_99[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions?"));
@@ -21449,7 +22273,7 @@ _tmp_99_rule(Parser *p)
             _res = _PyPegen_seq_insert_in_front ( p , y , z );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -21460,7 +22284,7 @@ _tmp_99_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -21468,16 +22292,19 @@ _tmp_99_rule(Parser *p)
 static void *
 _tmp_100_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // yield_expr
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_100[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr"));
@@ -21496,7 +22323,7 @@ _tmp_100_rule(Parser *p)
     }
     { // named_expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_100[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "named_expression"));
@@ -21515,7 +22342,7 @@ _tmp_100_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -21523,9 +22350,12 @@ _tmp_100_rule(Parser *p)
 static asdl_seq *
 _loop0_102_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -21535,14 +22365,14 @@ _loop0_102_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // ',' double_starred_kvpair
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_102[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' double_starred_kvpair"));
@@ -21558,7 +22388,7 @@ _loop0_102_rule(Parser *p)
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
                 PyMem_Free(_children);
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             if (_n == _children_capacity) {
@@ -21567,7 +22397,7 @@ _loop0_102_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -21584,13 +22414,13 @@ _loop0_102_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_102_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -21598,16 +22428,19 @@ _loop0_102_rule(Parser *p)
 static asdl_seq *
 _gather_101_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
     { // double_starred_kvpair _loop0_102
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _gather_101[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_102"));
@@ -21629,7 +22462,7 @@ _gather_101_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -21637,9 +22470,12 @@ _gather_101_rule(Parser *p)
 static asdl_seq *
 _loop1_103_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -21649,14 +22485,14 @@ _loop1_103_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // for_if_clause
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_103[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "for_if_clause"));
@@ -21672,7 +22508,7 @@ _loop1_103_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -21686,7 +22522,7 @@ _loop1_103_rule(Parser *p)
     }
     if (_n == 0 || p->error_indicator) {
         PyMem_Free(_children);
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
@@ -21694,13 +22530,13 @@ _loop1_103_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop1_103_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -21708,9 +22544,12 @@ _loop1_103_rule(Parser *p)
 static asdl_seq *
 _loop0_104_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -21720,14 +22559,14 @@ _loop0_104_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // ('if' disjunction)
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_104[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)"));
@@ -21743,7 +22582,7 @@ _loop0_104_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -21760,13 +22599,13 @@ _loop0_104_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_104_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -21774,9 +22613,12 @@ _loop0_104_rule(Parser *p)
 static asdl_seq *
 _loop0_105_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -21786,14 +22628,14 @@ _loop0_105_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // ('if' disjunction)
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_105[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)"));
@@ -21809,7 +22651,7 @@ _loop0_105_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -21826,13 +22668,13 @@ _loop0_105_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_105_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -21840,9 +22682,12 @@ _loop0_105_rule(Parser *p)
 static asdl_seq *
 _loop0_107_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -21852,14 +22697,14 @@ _loop0_107_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // ',' (starred_expression | named_expression !'=')
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_107[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (starred_expression | named_expression !'=')"));
@@ -21875,7 +22720,7 @@ _loop0_107_rule(Parser *p)
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
                 PyMem_Free(_children);
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             if (_n == _children_capacity) {
@@ -21884,7 +22729,7 @@ _loop0_107_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -21901,13 +22746,13 @@ _loop0_107_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_107_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -21915,16 +22760,19 @@ _loop0_107_rule(Parser *p)
 static asdl_seq *
 _gather_106_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
     { // (starred_expression | named_expression !'=') _loop0_107
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _gather_106[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(starred_expression | named_expression !'=') _loop0_107"));
@@ -21946,7 +22794,7 @@ _gather_106_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -21954,16 +22802,19 @@ _gather_106_rule(Parser *p)
 static void *
 _tmp_108_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // ',' kwargs
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_108[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwargs"));
@@ -21979,7 +22830,7 @@ _tmp_108_rule(Parser *p)
             _res = k;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -21990,7 +22841,7 @@ _tmp_108_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -21998,9 +22849,12 @@ _tmp_108_rule(Parser *p)
 static asdl_seq *
 _loop0_110_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -22010,14 +22864,14 @@ _loop0_110_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // ',' kwarg_or_starred
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_110[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_starred"));
@@ -22033,7 +22887,7 @@ _loop0_110_rule(Parser *p)
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
                 PyMem_Free(_children);
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             if (_n == _children_capacity) {
@@ -22042,7 +22896,7 @@ _loop0_110_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -22059,13 +22913,13 @@ _loop0_110_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_110_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -22073,16 +22927,19 @@ _loop0_110_rule(Parser *p)
 static asdl_seq *
 _gather_109_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
     { // kwarg_or_starred _loop0_110
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _gather_109[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_110"));
@@ -22104,7 +22961,7 @@ _gather_109_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -22112,9 +22969,12 @@ _gather_109_rule(Parser *p)
 static asdl_seq *
 _loop0_112_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -22124,14 +22984,14 @@ _loop0_112_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // ',' kwarg_or_double_starred
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_112[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_double_starred"));
@@ -22147,7 +23007,7 @@ _loop0_112_rule(Parser *p)
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
                 PyMem_Free(_children);
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             if (_n == _children_capacity) {
@@ -22156,7 +23016,7 @@ _loop0_112_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -22173,13 +23033,13 @@ _loop0_112_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_112_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -22187,16 +23047,19 @@ _loop0_112_rule(Parser *p)
 static asdl_seq *
 _gather_111_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
     { // kwarg_or_double_starred _loop0_112
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _gather_111[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_112"));
@@ -22218,7 +23081,7 @@ _gather_111_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -22226,9 +23089,12 @@ _gather_111_rule(Parser *p)
 static asdl_seq *
 _loop0_114_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -22238,14 +23104,14 @@ _loop0_114_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // ',' kwarg_or_starred
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_114[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_starred"));
@@ -22261,7 +23127,7 @@ _loop0_114_rule(Parser *p)
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
                 PyMem_Free(_children);
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             if (_n == _children_capacity) {
@@ -22270,7 +23136,7 @@ _loop0_114_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -22287,13 +23153,13 @@ _loop0_114_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_114_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -22301,16 +23167,19 @@ _loop0_114_rule(Parser *p)
 static asdl_seq *
 _gather_113_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
     { // kwarg_or_starred _loop0_114
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _gather_113[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_114"));
@@ -22332,7 +23201,7 @@ _gather_113_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -22340,9 +23209,12 @@ _gather_113_rule(Parser *p)
 static asdl_seq *
 _loop0_116_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -22352,14 +23224,14 @@ _loop0_116_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // ',' kwarg_or_double_starred
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_116[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_double_starred"));
@@ -22375,7 +23247,7 @@ _loop0_116_rule(Parser *p)
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
                 PyMem_Free(_children);
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             if (_n == _children_capacity) {
@@ -22384,7 +23256,7 @@ _loop0_116_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -22401,13 +23273,13 @@ _loop0_116_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_116_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -22415,16 +23287,19 @@ _loop0_116_rule(Parser *p)
 static asdl_seq *
 _gather_115_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
     { // kwarg_or_double_starred _loop0_116
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _gather_115[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_116"));
@@ -22446,7 +23321,7 @@ _gather_115_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -22454,9 +23329,12 @@ _gather_115_rule(Parser *p)
 static asdl_seq *
 _loop0_117_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -22466,14 +23344,14 @@ _loop0_117_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // (',' star_target)
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_117[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)"));
@@ -22489,7 +23367,7 @@ _loop0_117_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -22506,13 +23384,13 @@ _loop0_117_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_117_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -22520,9 +23398,12 @@ _loop0_117_rule(Parser *p)
 static asdl_seq *
 _loop0_119_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -22532,14 +23413,14 @@ _loop0_119_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // ',' star_target
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_119[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target"));
@@ -22555,7 +23436,7 @@ _loop0_119_rule(Parser *p)
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
                 PyMem_Free(_children);
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             if (_n == _children_capacity) {
@@ -22564,7 +23445,7 @@ _loop0_119_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -22581,13 +23462,13 @@ _loop0_119_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_119_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -22595,16 +23476,19 @@ _loop0_119_rule(Parser *p)
 static asdl_seq *
 _gather_118_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
     { // star_target _loop0_119
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _gather_118[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_target _loop0_119"));
@@ -22626,7 +23510,7 @@ _gather_118_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -22634,9 +23518,12 @@ _gather_118_rule(Parser *p)
 static asdl_seq *
 _loop1_120_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -22646,14 +23533,14 @@ _loop1_120_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // (',' star_target)
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_120[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)"));
@@ -22669,7 +23556,7 @@ _loop1_120_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -22683,7 +23570,7 @@ _loop1_120_rule(Parser *p)
     }
     if (_n == 0 || p->error_indicator) {
         PyMem_Free(_children);
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
@@ -22691,13 +23578,13 @@ _loop1_120_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop1_120_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -22705,16 +23592,19 @@ _loop1_120_rule(Parser *p)
 static void *
 _tmp_121_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // !'*' star_target
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_121[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "!'*' star_target"));
@@ -22735,7 +23625,7 @@ _tmp_121_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -22743,9 +23633,12 @@ _tmp_121_rule(Parser *p)
 static asdl_seq *
 _loop0_123_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -22755,14 +23648,14 @@ _loop0_123_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // ',' del_target
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_123[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' del_target"));
@@ -22778,7 +23671,7 @@ _loop0_123_rule(Parser *p)
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
                 PyMem_Free(_children);
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             if (_n == _children_capacity) {
@@ -22787,7 +23680,7 @@ _loop0_123_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -22804,13 +23697,13 @@ _loop0_123_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_123_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -22818,16 +23711,19 @@ _loop0_123_rule(Parser *p)
 static asdl_seq *
 _gather_122_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
     { // del_target _loop0_123
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _gather_122[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "del_target _loop0_123"));
@@ -22849,7 +23745,7 @@ _gather_122_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -22857,16 +23753,19 @@ _gather_122_rule(Parser *p)
 static void *
 _tmp_124_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // args
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_124[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args"));
@@ -22885,7 +23784,7 @@ _tmp_124_rule(Parser *p)
     }
     { // expression for_if_clauses
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_124[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses"));
@@ -22907,7 +23806,7 @@ _tmp_124_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -22915,16 +23814,19 @@ _tmp_124_rule(Parser *p)
 static void *
 _tmp_125_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // NAME '='
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_125[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '='"));
@@ -22946,7 +23848,7 @@ _tmp_125_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -22954,9 +23856,12 @@ _tmp_125_rule(Parser *p)
 static asdl_seq *
 _loop0_126_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -22966,14 +23871,14 @@ _loop0_126_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // star_named_expressions
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_126[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expressions"));
@@ -22989,7 +23894,7 @@ _loop0_126_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -23006,13 +23911,13 @@ _loop0_126_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_126_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -23020,9 +23925,12 @@ _loop0_126_rule(Parser *p)
 static asdl_seq *
 _loop0_127_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -23032,14 +23940,14 @@ _loop0_127_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // (star_targets '=')
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_127[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')"));
@@ -23055,7 +23963,7 @@ _loop0_127_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -23072,13 +23980,13 @@ _loop0_127_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_127_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -23086,9 +23994,12 @@ _loop0_127_rule(Parser *p)
 static asdl_seq *
 _loop0_128_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -23098,14 +24009,14 @@ _loop0_128_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // (star_targets '=')
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_128[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')"));
@@ -23121,7 +24032,7 @@ _loop0_128_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -23138,13 +24049,13 @@ _loop0_128_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_128_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -23152,16 +24063,19 @@ _loop0_128_rule(Parser *p)
 static void *
 _tmp_129_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // yield_expr
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_129[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr"));
@@ -23180,7 +24094,7 @@ _tmp_129_rule(Parser *p)
     }
     { // star_expressions
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_129[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions"));
@@ -23199,7 +24113,7 @@ _tmp_129_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -23207,16 +24121,19 @@ _tmp_129_rule(Parser *p)
 static void *
 _tmp_130_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // '['
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_130[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['"));
@@ -23235,7 +24152,7 @@ _tmp_130_rule(Parser *p)
     }
     { // '('
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_130[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('"));
@@ -23254,7 +24171,7 @@ _tmp_130_rule(Parser *p)
     }
     { // '{'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_130[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'"));
@@ -23273,7 +24190,7 @@ _tmp_130_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -23281,9 +24198,12 @@ _tmp_130_rule(Parser *p)
 static asdl_seq *
 _loop0_131_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -23293,14 +24213,14 @@ _loop0_131_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // param_no_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_131[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default"));
@@ -23316,7 +24236,7 @@ _loop0_131_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -23333,13 +24253,13 @@ _loop0_131_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_131_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -23347,16 +24267,19 @@ _loop0_131_rule(Parser *p)
 static void *
 _tmp_132_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // slash_with_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_132[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default"));
@@ -23375,7 +24298,7 @@ _tmp_132_rule(Parser *p)
     }
     { // param_with_default+
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_132[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default+"));
@@ -23394,7 +24317,7 @@ _tmp_132_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -23402,9 +24325,12 @@ _tmp_132_rule(Parser *p)
 static asdl_seq *
 _loop0_133_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -23414,14 +24340,14 @@ _loop0_133_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // lambda_param_no_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_133[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
@@ -23437,7 +24363,7 @@ _loop0_133_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -23454,13 +24380,13 @@ _loop0_133_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop0_133_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -23468,16 +24394,19 @@ _loop0_133_rule(Parser *p)
 static void *
 _tmp_134_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // lambda_slash_with_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_134[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default"));
@@ -23496,7 +24425,7 @@ _tmp_134_rule(Parser *p)
     }
     { // lambda_param_with_default+
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_134[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+"));
@@ -23515,7 +24444,7 @@ _tmp_134_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -23523,16 +24452,19 @@ _tmp_134_rule(Parser *p)
 static void *
 _tmp_135_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // ')'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_135[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'"));
@@ -23551,7 +24483,7 @@ _tmp_135_rule(Parser *p)
     }
     { // ',' (')' | '**')
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_135[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')"));
@@ -23573,7 +24505,7 @@ _tmp_135_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -23581,16 +24513,19 @@ _tmp_135_rule(Parser *p)
 static void *
 _tmp_136_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // ':'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_136[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'"));
@@ -23609,7 +24544,7 @@ _tmp_136_rule(Parser *p)
     }
     { // ',' (':' | '**')
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_136[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')"));
@@ -23631,7 +24566,7 @@ _tmp_136_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -23639,16 +24574,19 @@ _tmp_136_rule(Parser *p)
 static void *
 _tmp_137_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // star_targets '='
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_137[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='"));
@@ -23664,7 +24602,7 @@ _tmp_137_rule(Parser *p)
             _res = z;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -23675,7 +24613,7 @@ _tmp_137_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -23683,16 +24621,19 @@ _tmp_137_rule(Parser *p)
 static void *
 _tmp_138_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // '.'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_138[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'"));
@@ -23711,7 +24652,7 @@ _tmp_138_rule(Parser *p)
     }
     { // '...'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_138[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'"));
@@ -23730,7 +24671,7 @@ _tmp_138_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -23738,16 +24679,19 @@ _tmp_138_rule(Parser *p)
 static void *
 _tmp_139_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // '.'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_139[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'"));
@@ -23766,7 +24710,7 @@ _tmp_139_rule(Parser *p)
     }
     { // '...'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_139[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'"));
@@ -23785,7 +24729,7 @@ _tmp_139_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -23793,16 +24737,19 @@ _tmp_139_rule(Parser *p)
 static void *
 _tmp_140_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // '@' named_expression NEWLINE
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_140[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE"));
@@ -23821,7 +24768,7 @@ _tmp_140_rule(Parser *p)
             _res = f;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -23832,7 +24779,7 @@ _tmp_140_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -23840,16 +24787,19 @@ _tmp_140_rule(Parser *p)
 static void *
 _tmp_141_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // ',' star_expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_141[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_expression"));
@@ -23865,7 +24815,7 @@ _tmp_141_rule(Parser *p)
             _res = c;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -23876,7 +24826,7 @@ _tmp_141_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -23884,16 +24834,19 @@ _tmp_141_rule(Parser *p)
 static void *
 _tmp_142_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // ',' expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_142[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression"));
@@ -23909,7 +24862,7 @@ _tmp_142_rule(Parser *p)
             _res = c;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -23920,7 +24873,7 @@ _tmp_142_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -23928,16 +24881,19 @@ _tmp_142_rule(Parser *p)
 static void *
 _tmp_143_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // 'or' conjunction
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_143[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'or' conjunction"));
@@ -23953,7 +24909,7 @@ _tmp_143_rule(Parser *p)
             _res = c;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -23964,7 +24920,7 @@ _tmp_143_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -23972,16 +24928,19 @@ _tmp_143_rule(Parser *p)
 static void *
 _tmp_144_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // 'and' inversion
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_144[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'and' inversion"));
@@ -23997,7 +24956,7 @@ _tmp_144_rule(Parser *p)
             _res = c;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -24008,7 +24967,7 @@ _tmp_144_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -24016,16 +24975,19 @@ _tmp_144_rule(Parser *p)
 static void *
 _tmp_145_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // 'if' disjunction
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_145[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction"));
@@ -24041,7 +25003,7 @@ _tmp_145_rule(Parser *p)
             _res = z;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -24052,7 +25014,7 @@ _tmp_145_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -24060,16 +25022,19 @@ _tmp_145_rule(Parser *p)
 static void *
 _tmp_146_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // 'if' disjunction
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_146[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction"));
@@ -24085,7 +25050,7 @@ _tmp_146_rule(Parser *p)
             _res = z;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -24096,7 +25061,7 @@ _tmp_146_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -24104,16 +25069,19 @@ _tmp_146_rule(Parser *p)
 static void *
 _tmp_147_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // starred_expression
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression"));
@@ -24132,7 +25100,7 @@ _tmp_147_rule(Parser *p)
     }
     { // named_expression !'='
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "named_expression !'='"));
@@ -24153,7 +25121,7 @@ _tmp_147_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -24161,16 +25129,19 @@ _tmp_147_rule(Parser *p)
 static void *
 _tmp_148_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // ',' star_target
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target"));
@@ -24186,7 +25157,7 @@ _tmp_148_rule(Parser *p)
             _res = c;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -24197,7 +25168,7 @@ _tmp_148_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -24205,16 +25176,19 @@ _tmp_148_rule(Parser *p)
 static void *
 _tmp_149_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // ',' star_target
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_149[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target"));
@@ -24230,7 +25204,7 @@ _tmp_149_rule(Parser *p)
             _res = c;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
-                D(p->level--);
+                p->level--;
                 return NULL;
             }
             goto done;
@@ -24241,7 +25215,7 @@ _tmp_149_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -24249,16 +25223,19 @@ _tmp_149_rule(Parser *p)
 static void *
 _tmp_150_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // star_targets '='
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='"));
@@ -24280,7 +25257,7 @@ _tmp_150_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -24288,16 +25265,19 @@ _tmp_150_rule(Parser *p)
 static void *
 _tmp_151_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // star_targets '='
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='"));
@@ -24319,7 +25299,7 @@ _tmp_151_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -24327,9 +25307,12 @@ _tmp_151_rule(Parser *p)
 static asdl_seq *
 _loop1_152_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -24339,14 +25322,14 @@ _loop1_152_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // param_with_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default"));
@@ -24362,7 +25345,7 @@ _loop1_152_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -24376,7 +25359,7 @@ _loop1_152_rule(Parser *p)
     }
     if (_n == 0 || p->error_indicator) {
         PyMem_Free(_children);
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
@@ -24384,13 +25367,13 @@ _loop1_152_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop1_152_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -24398,9 +25381,12 @@ _loop1_152_rule(Parser *p)
 static asdl_seq *
 _loop1_153_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void *_res = NULL;
@@ -24410,14 +25396,14 @@ _loop1_153_rule(Parser *p)
     if (!_children) {
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     ssize_t _children_capacity = 1;
     ssize_t _n = 0;
     { // lambda_param_with_default
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default"));
@@ -24433,7 +25419,7 @@ _loop1_153_rule(Parser *p)
                 if (!_new_children) {
                     p->error_indicator = 1;
                     PyErr_NoMemory();
-                    D(p->level--);
+                    p->level--;
                     return NULL;
                 }
                 _children = _new_children;
@@ -24447,7 +25433,7 @@ _loop1_153_rule(Parser *p)
     }
     if (_n == 0 || p->error_indicator) {
         PyMem_Free(_children);
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);
@@ -24455,13 +25441,13 @@ _loop1_153_rule(Parser *p)
         PyMem_Free(_children);
         p->error_indicator = 1;
         PyErr_NoMemory();
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);
     PyMem_Free(_children);
     _PyPegen_insert_memo(p, _start_mark, _loop1_153_type, _seq);
-    D(p->level--);
+    p->level--;
     return _seq;
 }
 
@@ -24469,16 +25455,19 @@ _loop1_153_rule(Parser *p)
 static void *
 _tmp_154_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // ')'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'"));
@@ -24497,7 +25486,7 @@ _tmp_154_rule(Parser *p)
     }
     { // '**'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'"));
@@ -24516,7 +25505,7 @@ _tmp_154_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
@@ -24524,16 +25513,19 @@ _tmp_154_rule(Parser *p)
 static void *
 _tmp_155_rule(Parser *p)
 {
-    D(p->level++);
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
     if (p->error_indicator) {
-        D(p->level--);
+        p->level--;
         return NULL;
     }
     void * _res = NULL;
     int _mark = p->mark;
     { // ':'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'"));
@@ -24552,7 +25544,7 @@ _tmp_155_rule(Parser *p)
     }
     { // '**'
         if (p->error_indicator) {
-            D(p->level--);
+            p->level--;
             return NULL;
         }
         D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'"));
@@ -24571,7 +25563,7 @@ _tmp_155_rule(Parser *p)
     }
     _res = NULL;
   done:
-    D(p->level--);
+    p->level--;
     return _res;
 }
 
index efcf9ac..cdfbc12 100644 (file)
@@ -364,6 +364,14 @@ tokenizer_error(Parser *p)
 void *
 _PyPegen_raise_error(Parser *p, PyObject *errtype, const char *errmsg, ...)
 {
+    if (p->fill == 0) {
+        va_list va;
+        va_start(va, errmsg);
+        _PyPegen_raise_error_known_location(p, errtype, 0, 0, errmsg, va);
+        va_end(va);
+        return NULL;
+    }
+
     Token *t = p->known_err_token != NULL ? p->known_err_token : p->tokens[p->fill - 1];
     Py_ssize_t col_offset;
     if (t->col_offset == -1) {
@@ -1225,7 +1233,7 @@ _PyPegen_run_parser_from_string(const char *str, int start_rule, PyObject *filen
     int exec_input = start_rule == Py_file_input;
 
     struct tok_state *tok;
-    if (flags == NULL || flags->cf_flags & PyCF_IGNORE_COOKIE) {
+    if (flags != NULL && flags->cf_flags & PyCF_IGNORE_COOKIE) {
         tok = PyTokenizer_FromUTF8(str, exec_input);
     } else {
         tok = PyTokenizer_FromString(str, exec_input);
index 86a5d81..9a61f8a 100644 (file)
@@ -797,19 +797,21 @@ _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where)
         /* Somebody asked that we don't check for recursion. */
         return 0;
     if (tstate->overflowed) {
-        if (tstate->recursion_depth > recursion_limit + 50) {
+        if (tstate->recursion_depth > recursion_limit + 50 || tstate->overflowed > 50) {
             /* Overflowing while handling an overflow. Give up. */
             Py_FatalError("Cannot recover from stack overflow.");
         }
-        return 0;
     }
-    if (tstate->recursion_depth > recursion_limit) {
-        --tstate->recursion_depth;
-        tstate->overflowed = 1;
-        _PyErr_Format(tstate, PyExc_RecursionError,
-                      "maximum recursion depth exceeded%s",
-                      where);
-        return -1;
+    else {
+        if (tstate->recursion_depth > recursion_limit) {
+            tstate->overflowed++;
+            _PyErr_Format(tstate, PyExc_RecursionError,
+                        "maximum recursion depth exceeded%s",
+                        where);
+            tstate->overflowed--;
+            --tstate->recursion_depth;
+            return -1;
+        }
     }
     return 0;
 }
index 40d8e68..7927876 100644 (file)
@@ -317,12 +317,14 @@ _PyErr_NormalizeException(PyThreadState *tstate, PyObject **exc,
                           PyObject **val, PyObject **tb)
 {
     int recursion_depth = 0;
+    tstate->overflowed++;
     PyObject *type, *value, *initial_tb;
 
   restart:
     type = *exc;
     if (type == NULL) {
         /* There was no exception, so nothing to do. */
+        tstate->overflowed--;
         return;
     }
 
@@ -374,6 +376,7 @@ _PyErr_NormalizeException(PyThreadState *tstate, PyObject **exc,
     }
     *exc = type;
     *val = value;
+    tstate->overflowed--;
     return;
 
   error:
index 7fdeb31..88d1d05 100644 (file)
@@ -4,7 +4,7 @@
 
 static const char cprt[] =
 "\
-Copyright (c) 2001-2021 Python Software Foundation.\n\
+Copyright (c) 2001-2022 Python Software Foundation.\n\
 All Rights Reserved.\n\
 \n\
 Copyright (c) 2000 BeOpen.com.\n\
index 9beefa8..c3520c3 100644 (file)
@@ -139,11 +139,14 @@ _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime)
     _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
 
     int interp_mutex = _PyThread_at_fork_reinit(&runtime->interpreters.mutex);
-    int main_interp_id_mutex = _PyThread_at_fork_reinit(&runtime->interpreters.main->id_mutex);
     int xidregistry_mutex = _PyThread_at_fork_reinit(&runtime->xidregistry.mutex);
 
     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
 
+    /* bpo-42540: id_mutex is freed by _PyInterpreterState_Delete, which does
+     * not force the default allocator. */
+    int main_interp_id_mutex = _PyThread_at_fork_reinit(&runtime->interpreters.main->id_mutex);
+
     if (interp_mutex < 0) {
         Py_FatalError("Can't initialize lock for runtime interpreters");
     }
index 50c59b6..364101e 100644 (file)
@@ -903,7 +903,7 @@ print_exception(PyObject *f, PyObject *value)
         {
             Py_XDECREF(modulename);
             PyErr_Clear();
-            err = PyFile_WriteString("<unknown>", f);
+            err = PyFile_WriteString("<unknown>.", f);
         }
         else {
             if (!_PyUnicode_EqualToASCIIId(modulename, &PyId_builtins))
index 3e4115f..a52b299 100644 (file)
@@ -17,7 +17,7 @@ Data members:
 #include "Python.h"
 #include "code.h"
 #include "frameobject.h"          // PyFrame_GetBack()
-#include "pycore_ceval.h"         // _Py_RecursionLimitLowerWaterMark()
+#include "pycore_ceval.h"
 #include "pycore_initconfig.h"
 #include "pycore_object.h"
 #include "pycore_pathconfig.h"
@@ -1160,7 +1160,6 @@ static PyObject *
 sys_setrecursionlimit_impl(PyObject *module, int new_limit)
 /*[clinic end generated code: output=35e1c64754800ace input=b0f7a23393924af3]*/
 {
-    int mark;
     PyThreadState *tstate = _PyThreadState_GET();
 
     if (new_limit < 1) {
@@ -1178,8 +1177,7 @@ sys_setrecursionlimit_impl(PyObject *module, int new_limit)
        Reject too low new limit if the current recursion depth is higher than
        the new low-water mark. Otherwise it may not be possible anymore to
        reset the overflowed flag to 0. */
-    mark = _Py_RecursionLimitLowerWaterMark(new_limit);
-    if (tstate->recursion_depth >= mark) {
+    if (tstate->recursion_depth >= new_limit) {
         _PyErr_Format(tstate, PyExc_RecursionError,
                       "cannot set the recursion limit to %i at "
                       "the recursion depth %i: the limit is too low",
index 83f3074..23d0e38 100644 (file)
@@ -719,6 +719,26 @@ _Py_DumpASCII(int fd, PyObject *text)
         truncated = 0;
     }
 
+    // Is an ASCII string?
+    if (ascii->state.ascii) {
+        assert(kind == PyUnicode_1BYTE_KIND);
+        char *str = data;
+
+        int need_escape = 0;
+        for (i=0; i < size; i++) {
+            ch = str[i];
+            if (!(' ' <= ch && ch <= 126)) {
+                need_escape = 1;
+                break;
+            }
+        }
+        if (!need_escape) {
+            // The string can be written with a single write() syscall
+            _Py_write_noraise(fd, str, size);
+            goto done;
+        }
+    }
+
     for (i=0; i < size; i++) {
         if (kind != PyUnicode_WCHAR_KIND)
             ch = PyUnicode_READ(kind, data, i);
@@ -742,6 +762,8 @@ _Py_DumpASCII(int fd, PyObject *text)
             _Py_DumpHexadecimal(fd, ch, 8);
         }
     }
+
+done:
     if (truncated) {
         PUTS(fd, "...");
     }
index b808463..2d921be 100644 (file)
@@ -1,5 +1,5 @@
-This is Python version 3.9.9
-============================
+This is Python version 3.9.10
+=============================
 
 .. image:: https://travis-ci.org/python/cpython.svg?branch=3.9
    :alt: CPython build status on Travis CI
@@ -22,7 +22,7 @@ This is Python version 3.9.9
    :target: https://discuss.python.org/
 
 
-Copyright (c) 2001-2021 Python Software Foundation.  All rights reserved.
+Copyright (c) 2001-2022 Python Software Foundation.  All rights reserved.
 
 See the end of this file for further copyright and license information.
 
@@ -251,7 +251,7 @@ See :pep:`596` for Python 3.9 release details.
 Copyright and License Information
 ---------------------------------
 
-Copyright (c) 2001-2021 Python Software Foundation.  All rights reserved.
+Copyright (c) 2001-2022 Python Software Foundation.  All rights reserved.
 
 Copyright (c) 2000 BeOpen.com.  All rights reserved.
 
index aeaa63e..45be5ab 100755 (executable)
@@ -659,7 +659,10 @@ class PyCodeObjectPtr(PyObjectPtr):
             addr += ord(addr_incr)
             if addr > addrq:
                 return lineno
-            lineno += ord(line_incr)
+            line_delta = ord(line_incr)
+            if line_delta >= 128:
+                line_delta -= 256
+            lineno += line_delta
         return lineno
 
 
index b5836f6..99090c0 100644 (file)
@@ -1,5 +1,6 @@
 import ast
 from dataclasses import field, dataclass
+import os.path
 import re
 from typing import Any, Dict, IO, Optional, List, Text, Tuple, Set
 from enum import Enum
@@ -36,6 +37,8 @@ extern int Py_DebugFlag;
 #define D(x)
 #endif
 
+# define MAXSTACK 6000
+
 """
 
 
@@ -330,10 +333,14 @@ class CParserGenerator(ParserGenerator, GrammarVisitor):
         self.skip_actions = skip_actions
 
     def add_level(self) -> None:
-        self.print("D(p->level++);")
+        self.print("if (p->level++ == MAXSTACK) {")
+        with self.indent():
+            self.print("p->error_indicator = 1;")
+            self.print("PyErr_NoMemory();")
+        self.print("}")
 
     def remove_level(self) -> None:
-        self.print("D(p->level--);")
+        self.print("p->level--;")
 
     def add_return(self, ret_val: str) -> None:
         self.remove_level()
@@ -379,7 +386,8 @@ class CParserGenerator(ParserGenerator, GrammarVisitor):
 
     def generate(self, filename: str) -> None:
         self.collect_todo()
-        self.print(f"// @generated by pegen.py from {filename}")
+        basename = os.path.basename(filename)
+        self.print(f"// @generated by pegen.py from {basename}")
         header = self.grammar.metas.get("header", EXTENSION_PREFIX)
         if header:
             self.print(header.rstrip("\n"))
@@ -496,9 +504,10 @@ class CParserGenerator(ParserGenerator, GrammarVisitor):
                 )
                 self.print("p->mark = _mark;")
                 self.print(f"void *_raw = {node.name}_raw(p);")
-                self.print("if (p->error_indicator)")
+                self.print("if (p->error_indicator) {")
                 with self.indent():
-                    self.print("return NULL;")
+                    self.add_return("NULL")
+                self.print("}")
                 self.print("if (_raw == NULL || p->mark <= _resmark)")
                 with self.indent():
                     self.print("break;")
index c784cfd..50a2153 100644 (file)
@@ -1,5 +1,5 @@
 #!/usr/bin/env python3.8
-# @generated by pegen from ./Tools/peg_generator/pegen/metagrammar.gram
+# @generated by pegen from metagrammar.gram
 
 import ast
 import sys
index b786de7..530cf11 100644 (file)
@@ -1,3 +1,4 @@
+import os.path
 import token
 from typing import Any, Dict, Optional, IO, Text, Tuple
 
@@ -142,7 +143,8 @@ class PythonParserGenerator(ParserGenerator, GrammarVisitor):
     def generate(self, filename: str) -> None:
         header = self.grammar.metas.get("header", MODULE_PREFIX)
         if header is not None:
-            self.print(header.rstrip("\n").format(filename=filename))
+            basename = os.path.basename(filename)
+            self.print(header.rstrip("\n").format(filename=basename))
         subheader = self.grammar.metas.get("subheader", "")
         if subheader:
             self.print(subheader.format(filename=filename))
index 8888c4a..437efb2 100755 (executable)
@@ -49,8 +49,8 @@ OPENSSL_OLD_VERSIONS = [
 ]
 
 OPENSSL_RECENT_VERSIONS = [
-    "1.1.1l",
-    "3.0.0"
+    "1.1.1m",
+    "3.0.1"
 ]
 
 LIBRESSL_OLD_VERSIONS = [
index 04342a4..e5e8042 100644 (file)
@@ -1,4 +1,4 @@
-# generated automatically by aclocal 1.16.2 -*- Autoconf -*-
+# generated automatically by aclocal 1.16.3 -*- Autoconf -*-
 
 # Copyright (C) 1996-2020 Free Software Foundation, Inc.
 
index 256083a..e81d3ae 100755 (executable)
@@ -1,8 +1,10 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
-#   Copyright 1992-2018 Free Software Foundation, Inc.
+#   Copyright 1992-2021 Free Software Foundation, Inc.
 
-timestamp='2018-03-08'
+# shellcheck disable=SC2006,SC2268 # see below for rationale
+
+timestamp='2021-06-03'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -27,11 +29,19 @@ timestamp='2018-03-08'
 # Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
 #
 # You can get the latest version of this script from:
-# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
+# https://git.savannah.gnu.org/cgit/config.git/plain/config.guess
 #
 # Please send patches to <config-patches@gnu.org>.
 
 
+# The "shellcheck disable" line above the timestamp inhibits complaints
+# about features and limitations of the classic Bourne shell that were
+# superseded or lifted in POSIX.  However, this script identifies a wide
+# variety of pre-POSIX systems that do not have POSIX shells at all, and
+# even some reasonably current systems (Solaris 10 as case-in-point) still
+# have a pre-POSIX /bin/sh.
+
+
 me=`echo "$0" | sed -e 's,.*/,,'`
 
 usage="\
@@ -50,7 +60,7 @@ version="\
 GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
-Copyright 1992-2018 Free Software Foundation, Inc.
+Copyright 1992-2021 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -84,7 +94,8 @@ if test $# != 0; then
   exit 1
 fi
 
-trap 'exit 1' 1 2 15
+# Just in case it came from the environment.
+GUESS=
 
 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a
 # compiler to aid in system detection is discouraged as it requires
@@ -96,73 +107,90 @@ trap 'exit 1' 1 2 15
 
 # Portable tmp directory creation inspired by the Autoconf team.
 
-set_cc_for_build='
-trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
-trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
-: ${TMPDIR=/tmp} ;
- { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
- { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
- { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
- { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
-dummy=$tmp/dummy ;
-tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
-case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,)    echo "int x;" > "$dummy.c" ;
-       for c in cc gcc c89 c99 ; do
-         if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
-            CC_FOR_BUILD="$c"; break ;
-         fi ;
-       done ;
-       if test x"$CC_FOR_BUILD" = x ; then
-         CC_FOR_BUILD=no_compiler_found ;
-       fi
-       ;;
- ,,*)   CC_FOR_BUILD=$CC ;;
- ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
-esac ; set_cc_for_build= ;'
+tmp=
+# shellcheck disable=SC2172
+trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15
+
+set_cc_for_build() {
+    # prevent multiple calls if $tmp is already set
+    test "$tmp" && return 0
+    : "${TMPDIR=/tmp}"
+    # shellcheck disable=SC2039,SC3028
+    { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+       { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } ||
+       { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+       { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; }
+    dummy=$tmp/dummy
+    case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in
+       ,,)    echo "int x;" > "$dummy.c"
+              for driver in cc gcc c89 c99 ; do
+                  if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
+                      CC_FOR_BUILD=$driver
+                      break
+                  fi
+              done
+              if test x"$CC_FOR_BUILD" = x ; then
+                  CC_FOR_BUILD=no_compiler_found
+              fi
+              ;;
+       ,,*)   CC_FOR_BUILD=$CC ;;
+       ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+    esac
+}
 
 # This is needed to find uname on a Pyramid OSx when run in the BSD universe.
 # (ghazi@noc.rutgers.edu 1994-08-24)
-if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+if test -f /.attbin/uname ; then
        PATH=$PATH:/.attbin ; export PATH
 fi
 
 UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
 UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
-UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
 UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
 
-case "$UNAME_SYSTEM" in
+case $UNAME_SYSTEM in
 Linux|GNU|GNU/*)
-       # If the system lacks a compiler, then just pick glibc.
-       # We could probably try harder.
-       LIBC=gnu
+       LIBC=unknown
 
-       eval "$set_cc_for_build"
+       set_cc_for_build
        cat <<-EOF > "$dummy.c"
        #include <features.h>
        #if defined(__UCLIBC__)
        LIBC=uclibc
        #elif defined(__dietlibc__)
        LIBC=dietlibc
-       #else
+       #elif defined(__GLIBC__)
        LIBC=gnu
+       #else
+       #include <stdarg.h>
+       /* First heuristic to detect musl libc.  */
+       #ifdef __DEFINED_va_list
+       LIBC=musl
+       #endif
        #endif
        EOF
-       eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`"
+       cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+       eval "$cc_set_libc"
 
-       # If ldd exists, use it to detect musl libc.
-       if command -v ldd >/dev/null && \
-               ldd --version 2>&1 | grep -q ^musl
-       then
-           LIBC=musl
+       # Second heuristic to detect musl libc.
+       if [ "$LIBC" = unknown ] &&
+          command -v ldd >/dev/null &&
+          ldd --version 2>&1 | grep -q ^musl; then
+               LIBC=musl
+       fi
+
+       # If the system lacks a compiler, then just pick glibc.
+       # We could probably try harder.
+       if [ "$LIBC" = unknown ]; then
+               LIBC=gnu
        fi
        ;;
 esac
 
 # Note: order is significant - the case branches are not exclusive.
 
-case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
+case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in
     *:NetBSD:*:*)
        # NetBSD (nbsd) targets should (where applicable) match one or
        # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
@@ -174,12 +202,12 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
        #
        # Note: NetBSD doesn't particularly care about the vendor
        # portion of the name.  We always set it to "unknown".
-       sysctl="sysctl -n hw.machine_arch"
        UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
-           "/sbin/$sysctl" 2>/dev/null || \
-           "/usr/sbin/$sysctl" 2>/dev/null || \
+           /sbin/sysctl -n hw.machine_arch 2>/dev/null || \
+           /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \
            echo unknown)`
-       case "$UNAME_MACHINE_ARCH" in
+       case $UNAME_MACHINE_ARCH in
+           aarch64eb) machine=aarch64_be-unknown ;;
            armeb) machine=armeb-unknown ;;
            arm*) machine=arm-unknown ;;
            sh3el) machine=shl-unknown ;;
@@ -188,18 +216,18 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
            earmv*)
                arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
                endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'`
-               machine="${arch}${endian}"-unknown
+               machine=${arch}${endian}-unknown
                ;;
-           *) machine="$UNAME_MACHINE_ARCH"-unknown ;;
+           *) machine=$UNAME_MACHINE_ARCH-unknown ;;
        esac
        # The Operating System including object format, if it has switched
        # to ELF recently (or will in the future) and ABI.
-       case "$UNAME_MACHINE_ARCH" in
+       case $UNAME_MACHINE_ARCH in
            earm*)
                os=netbsdelf
                ;;
            arm*|i386|m68k|ns32k|sh3*|sparc|vax)
-               eval "$set_cc_for_build"
+               set_cc_for_build
                if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
                        | grep -q __ELF__
                then
@@ -215,7 +243,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
                ;;
        esac
        # Determine ABI tags.
-       case "$UNAME_MACHINE_ARCH" in
+       case $UNAME_MACHINE_ARCH in
            earm*)
                expr='s/^earmv[0-9]/-eabi/;s/eb$//'
                abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"`
@@ -226,7 +254,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
        # thus, need a distinct triplet. However, they do not need
        # kernel version information, so it can be replaced with a
        # suitable tag, in the style of linux-gnu.
-       case "$UNAME_VERSION" in
+       case $UNAME_VERSION in
            Debian*)
                release='-gnu'
                ;;
@@ -237,45 +265,57 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
        # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
        # contains redundant information, the shorter form:
        # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
-       echo "$machine-${os}${release}${abi}"
-       exit ;;
+       GUESS=$machine-${os}${release}${abi-}
+       ;;
     *:Bitrig:*:*)
        UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
-       echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE"
-       exit ;;
+       GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE
+       ;;
     *:OpenBSD:*:*)
        UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
-       echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE"
-       exit ;;
+       GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE
+       ;;
+    *:SecBSD:*:*)
+       UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'`
+       GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE
+       ;;
     *:LibertyBSD:*:*)
        UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
-       echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE"
-       exit ;;
+       GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE
+       ;;
     *:MidnightBSD:*:*)
-       echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE"
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE
+       ;;
     *:ekkoBSD:*:*)
-       echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE"
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE
+       ;;
     *:SolidBSD:*:*)
-       echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE"
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE
+       ;;
+    *:OS108:*:*)
+       GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE
+       ;;
     macppc:MirBSD:*:*)
-       echo powerpc-unknown-mirbsd"$UNAME_RELEASE"
-       exit ;;
+       GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE
+       ;;
     *:MirBSD:*:*)
-       echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE"
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE
+       ;;
     *:Sortix:*:*)
-       echo "$UNAME_MACHINE"-unknown-sortix
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-sortix
+       ;;
+    *:Twizzler:*:*)
+       GUESS=$UNAME_MACHINE-unknown-twizzler
+       ;;
     *:Redox:*:*)
-       echo "$UNAME_MACHINE"-unknown-redox
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-redox
+       ;;
     mips:OSF1:*.*)
-        echo mips-dec-osf1
-        exit ;;
+       GUESS=mips-dec-osf1
+       ;;
     alpha:OSF1:*:*)
+       # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+       trap '' 0
        case $UNAME_RELEASE in
        *4.0)
                UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
@@ -289,7 +329,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
        # covers most systems running today.  This code pipes the CPU
        # types through head -n 1, so we only detect the type of CPU 0.
        ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
-       case "$ALPHA_CPU_TYPE" in
+       case $ALPHA_CPU_TYPE in
            "EV4 (21064)")
                UNAME_MACHINE=alpha ;;
            "EV4.5 (21064)")
@@ -326,75 +366,76 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
        # A Tn.n version is a released field test version.
        # A Xn.n version is an unreleased experimental baselevel.
        # 1.2 uses "1.2" for uname -r.
-       echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`"
-       # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
-       exitcode=$?
-       trap '' 0
-       exit $exitcode ;;
+       OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+       GUESS=$UNAME_MACHINE-dec-osf$OSF_REL
+       ;;
     Amiga*:UNIX_System_V:4.0:*)
-       echo m68k-unknown-sysv4
-       exit ;;
+       GUESS=m68k-unknown-sysv4
+       ;;
     *:[Aa]miga[Oo][Ss]:*:*)
-       echo "$UNAME_MACHINE"-unknown-amigaos
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-amigaos
+       ;;
     *:[Mm]orph[Oo][Ss]:*:*)
-       echo "$UNAME_MACHINE"-unknown-morphos
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-morphos
+       ;;
     *:OS/390:*:*)
-       echo i370-ibm-openedition
-       exit ;;
+       GUESS=i370-ibm-openedition
+       ;;
     *:z/VM:*:*)
-       echo s390-ibm-zvmoe
-       exit ;;
+       GUESS=s390-ibm-zvmoe
+       ;;
     *:OS400:*:*)
-       echo powerpc-ibm-os400
-       exit ;;
+       GUESS=powerpc-ibm-os400
+       ;;
     arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
-       echo arm-acorn-riscix"$UNAME_RELEASE"
-       exit ;;
+       GUESS=arm-acorn-riscix$UNAME_RELEASE
+       ;;
     arm*:riscos:*:*|arm*:RISCOS:*:*)
-       echo arm-unknown-riscos
-       exit ;;
+       GUESS=arm-unknown-riscos
+       ;;
     SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
-       echo hppa1.1-hitachi-hiuxmpp
-       exit ;;
+       GUESS=hppa1.1-hitachi-hiuxmpp
+       ;;
     Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
        # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
-       if test "`(/bin/universe) 2>/dev/null`" = att ; then
-               echo pyramid-pyramid-sysv3
-       else
-               echo pyramid-pyramid-bsd
-       fi
-       exit ;;
+       case `(/bin/universe) 2>/dev/null` in
+           att) GUESS=pyramid-pyramid-sysv3 ;;
+           *)   GUESS=pyramid-pyramid-bsd   ;;
+       esac
+       ;;
     NILE*:*:*:dcosx)
-       echo pyramid-pyramid-svr4
-       exit ;;
+       GUESS=pyramid-pyramid-svr4
+       ;;
     DRS?6000:unix:4.0:6*)
-       echo sparc-icl-nx6
-       exit ;;
+       GUESS=sparc-icl-nx6
+       ;;
     DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
        case `/usr/bin/uname -p` in
-           sparc) echo sparc-icl-nx7; exit ;;
-       esac ;;
+           sparc) GUESS=sparc-icl-nx7 ;;
+       esac
+       ;;
     s390x:SunOS:*:*)
-       echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
-       exit ;;
+       SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+       GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL
+       ;;
     sun4H:SunOS:5.*:*)
-       echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
-       exit ;;
+       SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+       GUESS=sparc-hal-solaris2$SUN_REL
+       ;;
     sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
-       echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
-       exit ;;
+       SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+       GUESS=sparc-sun-solaris2$SUN_REL
+       ;;
     i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
-       echo i386-pc-auroraux"$UNAME_RELEASE"
-       exit ;;
+       GUESS=i386-pc-auroraux$UNAME_RELEASE
+       ;;
     i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
-       eval "$set_cc_for_build"
+       set_cc_for_build
        SUN_ARCH=i386
        # If there is a compiler, see if it is configured for 64-bit objects.
        # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
        # This test works for both compilers.
-       if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
+       if test "$CC_FOR_BUILD" != no_compiler_found; then
            if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
                (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
                grep IS_64BIT_ARCH >/dev/null
@@ -402,41 +443,44 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
                SUN_ARCH=x86_64
            fi
        fi
-       echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
-       exit ;;
+       SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+       GUESS=$SUN_ARCH-pc-solaris2$SUN_REL
+       ;;
     sun4*:SunOS:6*:*)
        # According to config.sub, this is the proper way to canonicalize
        # SunOS6.  Hard to guess exactly what SunOS6 will be like, but
        # it's likely to be more like Solaris than SunOS4.
-       echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
-       exit ;;
+       SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+       GUESS=sparc-sun-solaris3$SUN_REL
+       ;;
     sun4*:SunOS:*:*)
-       case "`/usr/bin/arch -k`" in
+       case `/usr/bin/arch -k` in
            Series*|S4*)
                UNAME_RELEASE=`uname -v`
                ;;
        esac
        # Japanese Language versions have a version number like `4.1.3-JL'.
-       echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`"
-       exit ;;
+       SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'`
+       GUESS=sparc-sun-sunos$SUN_REL
+       ;;
     sun3*:SunOS:*:*)
-       echo m68k-sun-sunos"$UNAME_RELEASE"
-       exit ;;
+       GUESS=m68k-sun-sunos$UNAME_RELEASE
+       ;;
     sun*:*:4.2BSD:*)
        UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
        test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3
-       case "`/bin/arch`" in
+       case `/bin/arch` in
            sun3)
-               echo m68k-sun-sunos"$UNAME_RELEASE"
+               GUESS=m68k-sun-sunos$UNAME_RELEASE
                ;;
            sun4)
-               echo sparc-sun-sunos"$UNAME_RELEASE"
+               GUESS=sparc-sun-sunos$UNAME_RELEASE
                ;;
        esac
-       exit ;;
+       ;;
     aushp:SunOS:*:*)
-       echo sparc-auspex-sunos"$UNAME_RELEASE"
-       exit ;;
+       GUESS=sparc-auspex-sunos$UNAME_RELEASE
+       ;;
     # The situation for MiNT is a little confusing.  The machine name
     # can be virtually everything (everything which is not
     # "atarist" or "atariste" at least should have a processor
@@ -446,43 +490,43 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
     # MiNT.  But MiNT is downward compatible to TOS, so this should
     # be no problem.
     atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
-       echo m68k-atari-mint"$UNAME_RELEASE"
-       exit ;;
+       GUESS=m68k-atari-mint$UNAME_RELEASE
+       ;;
     atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
-       echo m68k-atari-mint"$UNAME_RELEASE"
-       exit ;;
+       GUESS=m68k-atari-mint$UNAME_RELEASE
+       ;;
     *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
-       echo m68k-atari-mint"$UNAME_RELEASE"
-       exit ;;
+       GUESS=m68k-atari-mint$UNAME_RELEASE
+       ;;
     milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
-       echo m68k-milan-mint"$UNAME_RELEASE"
-       exit ;;
+       GUESS=m68k-milan-mint$UNAME_RELEASE
+       ;;
     hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
-       echo m68k-hades-mint"$UNAME_RELEASE"
-       exit ;;
+       GUESS=m68k-hades-mint$UNAME_RELEASE
+       ;;
     *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
-       echo m68k-unknown-mint"$UNAME_RELEASE"
-       exit ;;
+       GUESS=m68k-unknown-mint$UNAME_RELEASE
+       ;;
     m68k:machten:*:*)
-       echo m68k-apple-machten"$UNAME_RELEASE"
-       exit ;;
+       GUESS=m68k-apple-machten$UNAME_RELEASE
+       ;;
     powerpc:machten:*:*)
-       echo powerpc-apple-machten"$UNAME_RELEASE"
-       exit ;;
+       GUESS=powerpc-apple-machten$UNAME_RELEASE
+       ;;
     RISC*:Mach:*:*)
-       echo mips-dec-mach_bsd4.3
-       exit ;;
+       GUESS=mips-dec-mach_bsd4.3
+       ;;
     RISC*:ULTRIX:*:*)
-       echo mips-dec-ultrix"$UNAME_RELEASE"
-       exit ;;
+       GUESS=mips-dec-ultrix$UNAME_RELEASE
+       ;;
     VAX*:ULTRIX*:*:*)
-       echo vax-dec-ultrix"$UNAME_RELEASE"
-       exit ;;
+       GUESS=vax-dec-ultrix$UNAME_RELEASE
+       ;;
     2020:CLIX:*:* | 2430:CLIX:*:*)
-       echo clipper-intergraph-clix"$UNAME_RELEASE"
-       exit ;;
+       GUESS=clipper-intergraph-clix$UNAME_RELEASE
+       ;;
     mips:*:*:UMIPS | mips:*:*:RISCos)
-       eval "$set_cc_for_build"
+       set_cc_for_build
        sed 's/^        //' << EOF > "$dummy.c"
 #ifdef __cplusplus
 #include <stdio.h>  /* for printf() prototype */
@@ -508,78 +552,79 @@ EOF
          dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` &&
          SYSTEM_NAME=`"$dummy" "$dummyarg"` &&
            { echo "$SYSTEM_NAME"; exit; }
-       echo mips-mips-riscos"$UNAME_RELEASE"
-       exit ;;
+       GUESS=mips-mips-riscos$UNAME_RELEASE
+       ;;
     Motorola:PowerMAX_OS:*:*)
-       echo powerpc-motorola-powermax
-       exit ;;
+       GUESS=powerpc-motorola-powermax
+       ;;
     Motorola:*:4.3:PL8-*)
-       echo powerpc-harris-powermax
-       exit ;;
+       GUESS=powerpc-harris-powermax
+       ;;
     Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
-       echo powerpc-harris-powermax
-       exit ;;
+       GUESS=powerpc-harris-powermax
+       ;;
     Night_Hawk:Power_UNIX:*:*)
-       echo powerpc-harris-powerunix
-       exit ;;
+       GUESS=powerpc-harris-powerunix
+       ;;
     m88k:CX/UX:7*:*)
-       echo m88k-harris-cxux7
-       exit ;;
+       GUESS=m88k-harris-cxux7
+       ;;
     m88k:*:4*:R4*)
-       echo m88k-motorola-sysv4
-       exit ;;
+       GUESS=m88k-motorola-sysv4
+       ;;
     m88k:*:3*:R3*)
-       echo m88k-motorola-sysv3
-       exit ;;
+       GUESS=m88k-motorola-sysv3
+       ;;
     AViiON:dgux:*:*)
        # DG/UX returns AViiON for all architectures
        UNAME_PROCESSOR=`/usr/bin/uname -p`
-       if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ]
+       if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110
        then
-           if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \
-              [ "$TARGET_BINARY_INTERFACE"x = x ]
+           if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \
+              test "$TARGET_BINARY_INTERFACE"x = x
            then
-               echo m88k-dg-dgux"$UNAME_RELEASE"
+               GUESS=m88k-dg-dgux$UNAME_RELEASE
            else
-               echo m88k-dg-dguxbcs"$UNAME_RELEASE"
+               GUESS=m88k-dg-dguxbcs$UNAME_RELEASE
            fi
        else
-           echo i586-dg-dgux"$UNAME_RELEASE"
+           GUESS=i586-dg-dgux$UNAME_RELEASE
        fi
-       exit ;;
+       ;;
     M88*:DolphinOS:*:*)        # DolphinOS (SVR3)
-       echo m88k-dolphin-sysv3
-       exit ;;
+       GUESS=m88k-dolphin-sysv3
+       ;;
     M88*:*:R3*:*)
        # Delta 88k system running SVR3
-       echo m88k-motorola-sysv3
-       exit ;;
+       GUESS=m88k-motorola-sysv3
+       ;;
     XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
-       echo m88k-tektronix-sysv3
-       exit ;;
+       GUESS=m88k-tektronix-sysv3
+       ;;
     Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
-       echo m68k-tektronix-bsd
-       exit ;;
+       GUESS=m68k-tektronix-bsd
+       ;;
     *:IRIX*:*:*)
-       echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`"
-       exit ;;
+       IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'`
+       GUESS=mips-sgi-irix$IRIX_REL
+       ;;
     ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
-       echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
-       exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+       GUESS=romp-ibm-aix    # uname -m gives an 8 hex-code CPU id
+       ;;                    # Note that: echo "'`uname -s`'" gives 'AIX '
     i*86:AIX:*:*)
-       echo i386-ibm-aix
-       exit ;;
+       GUESS=i386-ibm-aix
+       ;;
     ia64:AIX:*:*)
-       if [ -x /usr/bin/oslevel ] ; then
+       if test -x /usr/bin/oslevel ; then
                IBM_REV=`/usr/bin/oslevel`
        else
-               IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
+               IBM_REV=$UNAME_VERSION.$UNAME_RELEASE
        fi
-       echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV"
-       exit ;;
+       GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV
+       ;;
     *:AIX:2:3)
        if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
-               eval "$set_cc_for_build"
+               set_cc_for_build
                sed 's/^                //' << EOF > "$dummy.c"
                #include <sys/systemcfg.h>
 
@@ -593,16 +638,16 @@ EOF
 EOF
                if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"`
                then
-                       echo "$SYSTEM_NAME"
+                       GUESS=$SYSTEM_NAME
                else
-                       echo rs6000-ibm-aix3.2.5
+                       GUESS=rs6000-ibm-aix3.2.5
                fi
        elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
-               echo rs6000-ibm-aix3.2.4
+               GUESS=rs6000-ibm-aix3.2.4
        else
-               echo rs6000-ibm-aix3.2
+               GUESS=rs6000-ibm-aix3.2
        fi
-       exit ;;
+       ;;
     *:AIX:*:[4567])
        IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
        if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then
@@ -610,57 +655,57 @@ EOF
        else
                IBM_ARCH=powerpc
        fi
-       if [ -x /usr/bin/lslpp ] ; then
-               IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
+       if test -x /usr/bin/lslpp ; then
+               IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \
                           awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
        else
-               IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
+               IBM_REV=$UNAME_VERSION.$UNAME_RELEASE
        fi
-       echo "$IBM_ARCH"-ibm-aix"$IBM_REV"
-       exit ;;
+       GUESS=$IBM_ARCH-ibm-aix$IBM_REV
+       ;;
     *:AIX:*:*)
-       echo rs6000-ibm-aix
-       exit ;;
+       GUESS=rs6000-ibm-aix
+       ;;
     ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*)
-       echo romp-ibm-bsd4.4
-       exit ;;
+       GUESS=romp-ibm-bsd4.4
+       ;;
     ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
-       echo romp-ibm-bsd"$UNAME_RELEASE"   # 4.3 with uname added to
-       exit ;;                             # report: romp-ibm BSD 4.3
+       GUESS=romp-ibm-bsd$UNAME_RELEASE    # 4.3 with uname added to
+       ;;                                  # report: romp-ibm BSD 4.3
     *:BOSX:*:*)
-       echo rs6000-bull-bosx
-       exit ;;
+       GUESS=rs6000-bull-bosx
+       ;;
     DPX/2?00:B.O.S.:*:*)
-       echo m68k-bull-sysv3
-       exit ;;
+       GUESS=m68k-bull-sysv3
+       ;;
     9000/[34]??:4.3bsd:1.*:*)
-       echo m68k-hp-bsd
-       exit ;;
+       GUESS=m68k-hp-bsd
+       ;;
     hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
-       echo m68k-hp-bsd4.4
-       exit ;;
+       GUESS=m68k-hp-bsd4.4
+       ;;
     9000/[34678]??:HP-UX:*:*)
-       HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
-       case "$UNAME_MACHINE" in
+       HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'`
+       case $UNAME_MACHINE in
            9000/31?)            HP_ARCH=m68000 ;;
            9000/[34]??)         HP_ARCH=m68k ;;
            9000/[678][0-9][0-9])
-               if [ -x /usr/bin/getconf ]; then
+               if test -x /usr/bin/getconf; then
                    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
-                   case "$sc_cpu_version" in
+                   case $sc_cpu_version in
                      523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
                      528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
                      532)                      # CPU_PA_RISC2_0
-                       case "$sc_kernel_bits" in
+                       case $sc_kernel_bits in
                          32) HP_ARCH=hppa2.0n ;;
                          64) HP_ARCH=hppa2.0w ;;
                          '') HP_ARCH=hppa2.0 ;;   # HP-UX 10.20
                        esac ;;
                    esac
                fi
-               if [ "$HP_ARCH" = "" ]; then
-                   eval "$set_cc_for_build"
+               if test "$HP_ARCH" = ""; then
+                   set_cc_for_build
                    sed 's/^            //' << EOF > "$dummy.c"
 
                #define _HPUX_SOURCE
@@ -698,9 +743,9 @@ EOF
                    test -z "$HP_ARCH" && HP_ARCH=hppa
                fi ;;
        esac
-       if [ "$HP_ARCH" = hppa2.0w ]
+       if test "$HP_ARCH" = hppa2.0w
        then
-           eval "$set_cc_for_build"
+           set_cc_for_build
 
            # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
            # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
@@ -719,14 +764,14 @@ EOF
                HP_ARCH=hppa64
            fi
        fi
-       echo "$HP_ARCH"-hp-hpux"$HPUX_REV"
-       exit ;;
+       GUESS=$HP_ARCH-hp-hpux$HPUX_REV
+       ;;
     ia64:HP-UX:*:*)
-       HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
-       echo ia64-hp-hpux"$HPUX_REV"
-       exit ;;
+       HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'`
+       GUESS=ia64-hp-hpux$HPUX_REV
+       ;;
     3050*:HI-UX:*:*)
-       eval "$set_cc_for_build"
+       set_cc_for_build
        sed 's/^        //' << EOF > "$dummy.c"
        #include <unistd.h>
        int
@@ -754,36 +799,36 @@ EOF
 EOF
        $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` &&
                { echo "$SYSTEM_NAME"; exit; }
-       echo unknown-hitachi-hiuxwe2
-       exit ;;
+       GUESS=unknown-hitachi-hiuxwe2
+       ;;
     9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*)
-       echo hppa1.1-hp-bsd
-       exit ;;
+       GUESS=hppa1.1-hp-bsd
+       ;;
     9000/8??:4.3bsd:*:*)
-       echo hppa1.0-hp-bsd
-       exit ;;
+       GUESS=hppa1.0-hp-bsd
+       ;;
     *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
-       echo hppa1.0-hp-mpeix
-       exit ;;
+       GUESS=hppa1.0-hp-mpeix
+       ;;
     hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*)
-       echo hppa1.1-hp-osf
-       exit ;;
+       GUESS=hppa1.1-hp-osf
+       ;;
     hp8??:OSF1:*:*)
-       echo hppa1.0-hp-osf
-       exit ;;
+       GUESS=hppa1.0-hp-osf
+       ;;
     i*86:OSF1:*:*)
-       if [ -x /usr/sbin/sysversion ] ; then
-           echo "$UNAME_MACHINE"-unknown-osf1mk
+       if test -x /usr/sbin/sysversion ; then
+           GUESS=$UNAME_MACHINE-unknown-osf1mk
        else
-           echo "$UNAME_MACHINE"-unknown-osf1
+           GUESS=$UNAME_MACHINE-unknown-osf1
        fi
-       exit ;;
+       ;;
     parisc*:Lites*:*:*)
-       echo hppa1.1-hp-lites
-       exit ;;
+       GUESS=hppa1.1-hp-lites
+       ;;
     C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
-       echo c1-convex-bsd
-       exit ;;
+       GUESS=c1-convex-bsd
+       ;;
     C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
        if getsysinfo -f scalar_acc
        then echo c32-convex-bsd
@@ -791,17 +836,18 @@ EOF
        fi
        exit ;;
     C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
-       echo c34-convex-bsd
-       exit ;;
+       GUESS=c34-convex-bsd
+       ;;
     C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
-       echo c38-convex-bsd
-       exit ;;
+       GUESS=c38-convex-bsd
+       ;;
     C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
-       echo c4-convex-bsd
-       exit ;;
+       GUESS=c4-convex-bsd
+       ;;
     CRAY*Y-MP:*:*:*)
-       echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
-       exit ;;
+       CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+       GUESS=ymp-cray-unicos$CRAY_REL
+       ;;
     CRAY*[A-Z]90:*:*:*)
        echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \
        | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
@@ -809,103 +855,126 @@ EOF
              -e 's/\.[^.]*$/.X/'
        exit ;;
     CRAY*TS:*:*:*)
-       echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
-       exit ;;
+       CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+       GUESS=t90-cray-unicos$CRAY_REL
+       ;;
     CRAY*T3E:*:*:*)
-       echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
-       exit ;;
+       CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+       GUESS=alphaev5-cray-unicosmk$CRAY_REL
+       ;;
     CRAY*SV1:*:*:*)
-       echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
-       exit ;;
+       CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+       GUESS=sv1-cray-unicos$CRAY_REL
+       ;;
     *:UNICOS/mp:*:*)
-       echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
-       exit ;;
+       CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+       GUESS=craynv-cray-unicosmp$CRAY_REL
+       ;;
     F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
        FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
        FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
        FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'`
-       echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
-       exit ;;
+       GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}
+       ;;
     5000:UNIX_System_V:4.*:*)
        FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
        FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
-       echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
-       exit ;;
+       GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}
+       ;;
     i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
-       echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE"
-       exit ;;
+       GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE
+       ;;
     sparc*:BSD/OS:*:*)
-       echo sparc-unknown-bsdi"$UNAME_RELEASE"
-       exit ;;
+       GUESS=sparc-unknown-bsdi$UNAME_RELEASE
+       ;;
     *:BSD/OS:*:*)
-       echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE"
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE
+       ;;
+    arm:FreeBSD:*:*)
+       UNAME_PROCESSOR=`uname -p`
+       set_cc_for_build
+       if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+           | grep -q __ARM_PCS_VFP
+       then
+           FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+           GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi
+       else
+           FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+           GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf
+       fi
+       ;;
     *:FreeBSD:*:*)
        UNAME_PROCESSOR=`/usr/bin/uname -p`
-       case "$UNAME_PROCESSOR" in
+       case $UNAME_PROCESSOR in
            amd64)
                UNAME_PROCESSOR=x86_64 ;;
            i386)
                UNAME_PROCESSOR=i586 ;;
        esac
-       echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`"
-       exit ;;
+       FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+       GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL
+       ;;
     i*:CYGWIN*:*)
-       echo "$UNAME_MACHINE"-pc-cygwin
-       exit ;;
+       GUESS=$UNAME_MACHINE-pc-cygwin
+       ;;
     *:MINGW64*:*)
-       echo "$UNAME_MACHINE"-pc-mingw64
-       exit ;;
+       GUESS=$UNAME_MACHINE-pc-mingw64
+       ;;
     *:MINGW*:*)
-       echo "$UNAME_MACHINE"-pc-mingw32
-       exit ;;
+       GUESS=$UNAME_MACHINE-pc-mingw32
+       ;;
     *:MSYS*:*)
-       echo "$UNAME_MACHINE"-pc-msys
-       exit ;;
+       GUESS=$UNAME_MACHINE-pc-msys
+       ;;
     i*:PW*:*)
-       echo "$UNAME_MACHINE"-pc-pw32
-       exit ;;
+       GUESS=$UNAME_MACHINE-pc-pw32
+       ;;
     *:Interix*:*)
-       case "$UNAME_MACHINE" in
+       case $UNAME_MACHINE in
            x86)
-               echo i586-pc-interix"$UNAME_RELEASE"
-               exit ;;
+               GUESS=i586-pc-interix$UNAME_RELEASE
+               ;;
            authenticamd | genuineintel | EM64T)
-               echo x86_64-unknown-interix"$UNAME_RELEASE"
-               exit ;;
+               GUESS=x86_64-unknown-interix$UNAME_RELEASE
+               ;;
            IA64)
-               echo ia64-unknown-interix"$UNAME_RELEASE"
-               exit ;;
+               GUESS=ia64-unknown-interix$UNAME_RELEASE
+               ;;
        esac ;;
     i*:UWIN*:*)
-       echo "$UNAME_MACHINE"-pc-uwin
-       exit ;;
+       GUESS=$UNAME_MACHINE-pc-uwin
+       ;;
     amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
-       echo x86_64-unknown-cygwin
-       exit ;;
+       GUESS=x86_64-pc-cygwin
+       ;;
     prep*:SunOS:5.*:*)
-       echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
-       exit ;;
+       SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+       GUESS=powerpcle-unknown-solaris2$SUN_REL
+       ;;
     *:GNU:*:*)
        # the GNU system
-       echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`"
-       exit ;;
+       GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'`
+       GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'`
+       GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL
+       ;;
     *:GNU/*:*:*)
        # other systems with GNU libc and userland
-       echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC"
-       exit ;;
-    i*86:Minix:*:*)
-       echo "$UNAME_MACHINE"-pc-minix
-       exit ;;
+       GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"`
+       GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+       GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC
+       ;;
+    *:Minix:*:*)
+       GUESS=$UNAME_MACHINE-unknown-minix
+       ;;
     aarch64:Linux:*:*)
-       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+       ;;
     aarch64_be:Linux:*:*)
        UNAME_MACHINE=aarch64_be
-       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+       ;;
     alpha:Linux:*:*)
-       case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+       case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in
          EV5)   UNAME_MACHINE=alphaev5 ;;
          EV56)  UNAME_MACHINE=alphaev56 ;;
          PCA56) UNAME_MACHINE=alphapca56 ;;
@@ -916,183 +985,225 @@ EOF
        esac
        objdump --private-headers /bin/sh | grep -q ld.so.1
        if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
-       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-       exit ;;
-    arc:Linux:*:* | arceb:Linux:*:*)
-       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+       ;;
+    arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*)
+       GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+       ;;
     arm*:Linux:*:*)
-       eval "$set_cc_for_build"
+       set_cc_for_build
        if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
            | grep -q __ARM_EABI__
        then
-           echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+           GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
        else
            if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
                | grep -q __ARM_PCS_VFP
            then
-               echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi
+               GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi
            else
-               echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf
+               GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf
            fi
        fi
-       exit ;;
+       ;;
     avr32*:Linux:*:*)
-       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+       ;;
     cris:Linux:*:*)
-       echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
-       exit ;;
+       GUESS=$UNAME_MACHINE-axis-linux-$LIBC
+       ;;
     crisv32:Linux:*:*)
-       echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
-       exit ;;
+       GUESS=$UNAME_MACHINE-axis-linux-$LIBC
+       ;;
     e2k:Linux:*:*)
-       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+       ;;
     frv:Linux:*:*)
-       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+       ;;
     hexagon:Linux:*:*)
-       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+       ;;
     i*86:Linux:*:*)
-       echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
-       exit ;;
+       GUESS=$UNAME_MACHINE-pc-linux-$LIBC
+       ;;
     ia64:Linux:*:*)
-       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+       ;;
     k1om:Linux:*:*)
-       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+       ;;
+    loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*)
+       GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+       ;;
     m32r*:Linux:*:*)
-       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+       ;;
     m68*:Linux:*:*)
-       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+       ;;
     mips:Linux:*:* | mips64:Linux:*:*)
-       eval "$set_cc_for_build"
+       set_cc_for_build
+       IS_GLIBC=0
+       test x"${LIBC}" = xgnu && IS_GLIBC=1
        sed 's/^        //' << EOF > "$dummy.c"
        #undef CPU
-       #undef ${UNAME_MACHINE}
-       #undef ${UNAME_MACHINE}el
+       #undef mips
+       #undef mipsel
+       #undef mips64
+       #undef mips64el
+       #if ${IS_GLIBC} && defined(_ABI64)
+       LIBCABI=gnuabi64
+       #else
+       #if ${IS_GLIBC} && defined(_ABIN32)
+       LIBCABI=gnuabin32
+       #else
+       LIBCABI=${LIBC}
+       #endif
+       #endif
+
+       #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6
+       CPU=mipsisa64r6
+       #else
+       #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6
+       CPU=mipsisa32r6
+       #else
+       #if defined(__mips64)
+       CPU=mips64
+       #else
+       CPU=mips
+       #endif
+       #endif
+       #endif
+
        #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
-       CPU=${UNAME_MACHINE}el
+       MIPS_ENDIAN=el
        #else
        #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
-       CPU=${UNAME_MACHINE}
+       MIPS_ENDIAN=
        #else
-       CPU=
+       MIPS_ENDIAN=
        #endif
        #endif
 EOF
-       eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`"
-       test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; }
+       cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`
+       eval "$cc_set_vars"
+       test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; }
        ;;
     mips64el:Linux:*:*)
-       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+       ;;
     openrisc*:Linux:*:*)
-       echo or1k-unknown-linux-"$LIBC"
-       exit ;;
+       GUESS=or1k-unknown-linux-$LIBC
+       ;;
     or32:Linux:*:* | or1k*:Linux:*:*)
-       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+       ;;
     padre:Linux:*:*)
-       echo sparc-unknown-linux-"$LIBC"
-       exit ;;
+       GUESS=sparc-unknown-linux-$LIBC
+       ;;
     parisc64:Linux:*:* | hppa64:Linux:*:*)
-       echo hppa64-unknown-linux-"$LIBC"
-       exit ;;
+       GUESS=hppa64-unknown-linux-$LIBC
+       ;;
     parisc:Linux:*:* | hppa:Linux:*:*)
        # Look for CPU level
        case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
-         PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;;
-         PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;;
-         *)    echo hppa-unknown-linux-"$LIBC" ;;
+         PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;;
+         PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;;
+         *)    GUESS=hppa-unknown-linux-$LIBC ;;
        esac
-       exit ;;
+       ;;
     ppc64:Linux:*:*)
-       echo powerpc64-unknown-linux-"$LIBC"
-       exit ;;
+       GUESS=powerpc64-unknown-linux-$LIBC
+       ;;
     ppc:Linux:*:*)
-       echo powerpc-unknown-linux-"$LIBC"
-       exit ;;
+       GUESS=powerpc-unknown-linux-$LIBC
+       ;;
     ppc64le:Linux:*:*)
-       echo powerpc64le-unknown-linux-"$LIBC"
-       exit ;;
+       GUESS=powerpc64le-unknown-linux-$LIBC
+       ;;
     ppcle:Linux:*:*)
-       echo powerpcle-unknown-linux-"$LIBC"
-       exit ;;
-    riscv32:Linux:*:* | riscv64:Linux:*:*)
-       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-       exit ;;
+       GUESS=powerpcle-unknown-linux-$LIBC
+       ;;
+    riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*)
+       GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+       ;;
     s390:Linux:*:* | s390x:Linux:*:*)
-       echo "$UNAME_MACHINE"-ibm-linux-"$LIBC"
-       exit ;;
+       GUESS=$UNAME_MACHINE-ibm-linux-$LIBC
+       ;;
     sh64*:Linux:*:*)
-       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+       ;;
     sh*:Linux:*:*)
-       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+       ;;
     sparc:Linux:*:* | sparc64:Linux:*:*)
-       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+       ;;
     tile*:Linux:*:*)
-       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+       ;;
     vax:Linux:*:*)
-       echo "$UNAME_MACHINE"-dec-linux-"$LIBC"
-       exit ;;
+       GUESS=$UNAME_MACHINE-dec-linux-$LIBC
+       ;;
     x86_64:Linux:*:*)
-       echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
-       exit ;;
+       set_cc_for_build
+       LIBCABI=$LIBC
+       if test "$CC_FOR_BUILD" != no_compiler_found; then
+           if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \
+               (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+               grep IS_X32 >/dev/null
+           then
+               LIBCABI=${LIBC}x32
+           fi
+       fi
+       GUESS=$UNAME_MACHINE-pc-linux-$LIBCABI
+       ;;
     xtensa*:Linux:*:*)
-       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+       ;;
     i*86:DYNIX/ptx:4*:*)
        # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
        # earlier versions are messed up and put the nodename in both
        # sysname and nodename.
-       echo i386-sequent-sysv4
-       exit ;;
+       GUESS=i386-sequent-sysv4
+       ;;
     i*86:UNIX_SV:4.2MP:2.*)
        # Unixware is an offshoot of SVR4, but it has its own version
        # number series starting with 2...
        # I am not positive that other SVR4 systems won't match this,
        # I just have to hope.  -- rms.
        # Use sysv4.2uw... so that sysv4* matches it.
-       echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION"
-       exit ;;
+       GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION
+       ;;
     i*86:OS/2:*:*)
        # If we were able to find `uname', then EMX Unix compatibility
        # is probably installed.
-       echo "$UNAME_MACHINE"-pc-os2-emx
-       exit ;;
+       GUESS=$UNAME_MACHINE-pc-os2-emx
+       ;;
     i*86:XTS-300:*:STOP)
-       echo "$UNAME_MACHINE"-unknown-stop
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-stop
+       ;;
     i*86:atheos:*:*)
-       echo "$UNAME_MACHINE"-unknown-atheos
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-atheos
+       ;;
     i*86:syllable:*:*)
-       echo "$UNAME_MACHINE"-pc-syllable
-       exit ;;
+       GUESS=$UNAME_MACHINE-pc-syllable
+       ;;
     i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
-       echo i386-unknown-lynxos"$UNAME_RELEASE"
-       exit ;;
+       GUESS=i386-unknown-lynxos$UNAME_RELEASE
+       ;;
     i*86:*DOS:*:*)
-       echo "$UNAME_MACHINE"-pc-msdosdjgpp
-       exit ;;
+       GUESS=$UNAME_MACHINE-pc-msdosdjgpp
+       ;;
     i*86:*:4.*:*)
        UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'`
        if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
-               echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL"
+               GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL
        else
-               echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL"
+               GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL
        fi
-       exit ;;
+       ;;
     i*86:*:5:[678]*)
        # UnixWare 7.x, OpenUNIX and OpenServer 6.
        case `/bin/uname -X | grep "^Machine"` in
@@ -1100,12 +1211,12 @@ EOF
            *Pentium)        UNAME_MACHINE=i586 ;;
            *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
        esac
-       echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}"
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+       ;;
     i*86:*:3.2:*)
        if test -f /usr/options/cb.name; then
                UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
-               echo "$UNAME_MACHINE"-pc-isc"$UNAME_REL"
+               GUESS=$UNAME_MACHINE-pc-isc$UNAME_REL
        elif /bin/uname -X 2>/dev/null >/dev/null ; then
                UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
                (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
@@ -1115,11 +1226,11 @@ EOF
                        && UNAME_MACHINE=i686
                (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
                        && UNAME_MACHINE=i686
-               echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL"
+               GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL
        else
-               echo "$UNAME_MACHINE"-pc-sysv32
+               GUESS=$UNAME_MACHINE-pc-sysv32
        fi
-       exit ;;
+       ;;
     pc:*:*:*)
        # Left here for compatibility:
        # uname -m prints for DJGPP always 'pc', but it prints nothing about
@@ -1127,31 +1238,31 @@ EOF
        # Note: whatever this is, it MUST be the same as what config.sub
        # prints for the "djgpp" host, or else GDB configure will decide that
        # this is a cross-build.
-       echo i586-pc-msdosdjgpp
-       exit ;;
+       GUESS=i586-pc-msdosdjgpp
+       ;;
     Intel:Mach:3*:*)
-       echo i386-pc-mach3
-       exit ;;
+       GUESS=i386-pc-mach3
+       ;;
     paragon:*:*:*)
-       echo i860-intel-osf1
-       exit ;;
+       GUESS=i860-intel-osf1
+       ;;
     i860:*:4.*:*) # i860-SVR4
        if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
-         echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4
+         GUESS=i860-stardent-sysv$UNAME_RELEASE    # Stardent Vistra i860-SVR4
        else # Add other i860-SVR4 vendors below as they are discovered.
-         echo i860-unknown-sysv"$UNAME_RELEASE"  # Unknown i860-SVR4
+         GUESS=i860-unknown-sysv$UNAME_RELEASE     # Unknown i860-SVR4
        fi
-       exit ;;
+       ;;
     mini*:CTIX:SYS*5:*)
        # "miniframe"
-       echo m68010-convergent-sysv
-       exit ;;
+       GUESS=m68010-convergent-sysv
+       ;;
     mc68k:UNIX:SYSTEM5:3.51m)
-       echo m68k-convergent-sysv
-       exit ;;
+       GUESS=m68k-convergent-sysv
+       ;;
     M680?0:D-NIX:5.3:*)
-       echo m68k-diab-dnix
-       exit ;;
+       GUESS=m68k-diab-dnix
+       ;;
     M68*:*:R3V[5678]*:*)
        test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
     3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
@@ -1176,249 +1287,401 @@ EOF
        /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
            && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
     m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
-       echo m68k-unknown-lynxos"$UNAME_RELEASE"
-       exit ;;
+       GUESS=m68k-unknown-lynxos$UNAME_RELEASE
+       ;;
     mc68030:UNIX_System_V:4.*:*)
-       echo m68k-atari-sysv4
-       exit ;;
+       GUESS=m68k-atari-sysv4
+       ;;
     TSUNAMI:LynxOS:2.*:*)
-       echo sparc-unknown-lynxos"$UNAME_RELEASE"
-       exit ;;
+       GUESS=sparc-unknown-lynxos$UNAME_RELEASE
+       ;;
     rs6000:LynxOS:2.*:*)
-       echo rs6000-unknown-lynxos"$UNAME_RELEASE"
-       exit ;;
+       GUESS=rs6000-unknown-lynxos$UNAME_RELEASE
+       ;;
     PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
-       echo powerpc-unknown-lynxos"$UNAME_RELEASE"
-       exit ;;
+       GUESS=powerpc-unknown-lynxos$UNAME_RELEASE
+       ;;
     SM[BE]S:UNIX_SV:*:*)
-       echo mips-dde-sysv"$UNAME_RELEASE"
-       exit ;;
+       GUESS=mips-dde-sysv$UNAME_RELEASE
+       ;;
     RM*:ReliantUNIX-*:*:*)
-       echo mips-sni-sysv4
-       exit ;;
+       GUESS=mips-sni-sysv4
+       ;;
     RM*:SINIX-*:*:*)
-       echo mips-sni-sysv4
-       exit ;;
+       GUESS=mips-sni-sysv4
+       ;;
     *:SINIX-*:*:*)
        if uname -p 2>/dev/null >/dev/null ; then
                UNAME_MACHINE=`(uname -p) 2>/dev/null`
-               echo "$UNAME_MACHINE"-sni-sysv4
+               GUESS=$UNAME_MACHINE-sni-sysv4
        else
-               echo ns32k-sni-sysv
+               GUESS=ns32k-sni-sysv
        fi
-       exit ;;
+       ;;
     PENTIUM:*:4.0*:*)  # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
                        # says <Richard.M.Bartel@ccMail.Census.GOV>
-       echo i586-unisys-sysv4
-       exit ;;
+       GUESS=i586-unisys-sysv4
+       ;;
     *:UNIX_System_V:4*:FTX*)
        # From Gerald Hewes <hewes@openmarket.com>.
        # How about differentiating between stratus architectures? -djm
-       echo hppa1.1-stratus-sysv4
-       exit ;;
+       GUESS=hppa1.1-stratus-sysv4
+       ;;
     *:*:*:FTX*)
        # From seanf@swdc.stratus.com.
-       echo i860-stratus-sysv4
-       exit ;;
+       GUESS=i860-stratus-sysv4
+       ;;
     i*86:VOS:*:*)
        # From Paul.Green@stratus.com.
-       echo "$UNAME_MACHINE"-stratus-vos
-       exit ;;
+       GUESS=$UNAME_MACHINE-stratus-vos
+       ;;
     *:VOS:*:*)
        # From Paul.Green@stratus.com.
-       echo hppa1.1-stratus-vos
-       exit ;;
+       GUESS=hppa1.1-stratus-vos
+       ;;
     mc68*:A/UX:*:*)
-       echo m68k-apple-aux"$UNAME_RELEASE"
-       exit ;;
+       GUESS=m68k-apple-aux$UNAME_RELEASE
+       ;;
     news*:NEWS-OS:6*:*)
-       echo mips-sony-newsos6
-       exit ;;
+       GUESS=mips-sony-newsos6
+       ;;
     R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
-       if [ -d /usr/nec ]; then
-               echo mips-nec-sysv"$UNAME_RELEASE"
+       if test -d /usr/nec; then
+               GUESS=mips-nec-sysv$UNAME_RELEASE
        else
-               echo mips-unknown-sysv"$UNAME_RELEASE"
+               GUESS=mips-unknown-sysv$UNAME_RELEASE
        fi
-       exit ;;
+       ;;
     BeBox:BeOS:*:*)    # BeOS running on hardware made by Be, PPC only.
-       echo powerpc-be-beos
-       exit ;;
+       GUESS=powerpc-be-beos
+       ;;
     BeMac:BeOS:*:*)    # BeOS running on Mac or Mac clone, PPC only.
-       echo powerpc-apple-beos
-       exit ;;
+       GUESS=powerpc-apple-beos
+       ;;
     BePC:BeOS:*:*)     # BeOS running on Intel PC compatible.
-       echo i586-pc-beos
-       exit ;;
+       GUESS=i586-pc-beos
+       ;;
     BePC:Haiku:*:*)    # Haiku running on Intel PC compatible.
-       echo i586-pc-haiku
-       exit ;;
+       GUESS=i586-pc-haiku
+       ;;
     x86_64:Haiku:*:*)
-       echo x86_64-unknown-haiku
-       exit ;;
+       GUESS=x86_64-unknown-haiku
+       ;;
     SX-4:SUPER-UX:*:*)
-       echo sx4-nec-superux"$UNAME_RELEASE"
-       exit ;;
+       GUESS=sx4-nec-superux$UNAME_RELEASE
+       ;;
     SX-5:SUPER-UX:*:*)
-       echo sx5-nec-superux"$UNAME_RELEASE"
-       exit ;;
+       GUESS=sx5-nec-superux$UNAME_RELEASE
+       ;;
     SX-6:SUPER-UX:*:*)
-       echo sx6-nec-superux"$UNAME_RELEASE"
-       exit ;;
+       GUESS=sx6-nec-superux$UNAME_RELEASE
+       ;;
     SX-7:SUPER-UX:*:*)
-       echo sx7-nec-superux"$UNAME_RELEASE"
-       exit ;;
+       GUESS=sx7-nec-superux$UNAME_RELEASE
+       ;;
     SX-8:SUPER-UX:*:*)
-       echo sx8-nec-superux"$UNAME_RELEASE"
-       exit ;;
+       GUESS=sx8-nec-superux$UNAME_RELEASE
+       ;;
     SX-8R:SUPER-UX:*:*)
-       echo sx8r-nec-superux"$UNAME_RELEASE"
-       exit ;;
+       GUESS=sx8r-nec-superux$UNAME_RELEASE
+       ;;
     SX-ACE:SUPER-UX:*:*)
-       echo sxace-nec-superux"$UNAME_RELEASE"
-       exit ;;
+       GUESS=sxace-nec-superux$UNAME_RELEASE
+       ;;
     Power*:Rhapsody:*:*)
-       echo powerpc-apple-rhapsody"$UNAME_RELEASE"
-       exit ;;
+       GUESS=powerpc-apple-rhapsody$UNAME_RELEASE
+       ;;
     *:Rhapsody:*:*)
-       echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE"
-       exit ;;
+       GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE
+       ;;
+    arm64:Darwin:*:*)
+       GUESS=aarch64-apple-darwin$UNAME_RELEASE
+       ;;
     *:Darwin:*:*)
-       UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
-       eval "$set_cc_for_build"
-       if test "$UNAME_PROCESSOR" = unknown ; then
-           UNAME_PROCESSOR=powerpc
+       UNAME_PROCESSOR=`uname -p`
+       case $UNAME_PROCESSOR in
+           unknown) UNAME_PROCESSOR=powerpc ;;
+       esac
+       if command -v xcode-select > /dev/null 2> /dev/null && \
+               ! xcode-select --print-path > /dev/null 2> /dev/null ; then
+           # Avoid executing cc if there is no toolchain installed as
+           # cc will be a stub that puts up a graphical alert
+           # prompting the user to install developer tools.
+           CC_FOR_BUILD=no_compiler_found
+       else
+           set_cc_for_build
        fi
-       if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then
-           if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
-               if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
-                      (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
-                      grep IS_64BIT_ARCH >/dev/null
-               then
-                   case $UNAME_PROCESSOR in
-                       i386) UNAME_PROCESSOR=x86_64 ;;
-                       powerpc) UNAME_PROCESSOR=powerpc64 ;;
-                   esac
-               fi
-               # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc
-               if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \
-                      (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
-                      grep IS_PPC >/dev/null
-               then
-                   UNAME_PROCESSOR=powerpc
-               fi
+       if test "$CC_FOR_BUILD" != no_compiler_found; then
+           if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+                  (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+                  grep IS_64BIT_ARCH >/dev/null
+           then
+               case $UNAME_PROCESSOR in
+                   i386) UNAME_PROCESSOR=x86_64 ;;
+                   powerpc) UNAME_PROCESSOR=powerpc64 ;;
+               esac
+           fi
+           # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc
+           if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \
+                  (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+                  grep IS_PPC >/dev/null
+           then
+               UNAME_PROCESSOR=powerpc
            fi
        elif test "$UNAME_PROCESSOR" = i386 ; then
-           # Avoid executing cc on OS X 10.9, as it ships with a stub
-           # that puts up a graphical alert prompting to install
-           # developer tools.  Any system running Mac OS X 10.7 or
-           # later (Darwin 11 and later) is required to have a 64-bit
-           # processor. This is not true of the ARM version of Darwin
-           # that Apple uses in portable devices.
-           UNAME_PROCESSOR=x86_64
+           # uname -m returns i386 or x86_64
+           UNAME_PROCESSOR=$UNAME_MACHINE
        fi
-       echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE"
-       exit ;;
+       GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE
+       ;;
     *:procnto*:*:* | *:QNX:[0123456789]*:*)
        UNAME_PROCESSOR=`uname -p`
        if test "$UNAME_PROCESSOR" = x86; then
                UNAME_PROCESSOR=i386
                UNAME_MACHINE=pc
        fi
-       echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE"
-       exit ;;
+       GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE
+       ;;
     *:QNX:*:4*)
-       echo i386-pc-qnx
-       exit ;;
+       GUESS=i386-pc-qnx
+       ;;
     NEO-*:NONSTOP_KERNEL:*:*)
-       echo neo-tandem-nsk"$UNAME_RELEASE"
-       exit ;;
+       GUESS=neo-tandem-nsk$UNAME_RELEASE
+       ;;
     NSE-*:NONSTOP_KERNEL:*:*)
-       echo nse-tandem-nsk"$UNAME_RELEASE"
-       exit ;;
+       GUESS=nse-tandem-nsk$UNAME_RELEASE
+       ;;
     NSR-*:NONSTOP_KERNEL:*:*)
-       echo nsr-tandem-nsk"$UNAME_RELEASE"
-       exit ;;
+       GUESS=nsr-tandem-nsk$UNAME_RELEASE
+       ;;
     NSV-*:NONSTOP_KERNEL:*:*)
-       echo nsv-tandem-nsk"$UNAME_RELEASE"
-       exit ;;
+       GUESS=nsv-tandem-nsk$UNAME_RELEASE
+       ;;
     NSX-*:NONSTOP_KERNEL:*:*)
-       echo nsx-tandem-nsk"$UNAME_RELEASE"
-       exit ;;
+       GUESS=nsx-tandem-nsk$UNAME_RELEASE
+       ;;
     *:NonStop-UX:*:*)
-       echo mips-compaq-nonstopux
-       exit ;;
+       GUESS=mips-compaq-nonstopux
+       ;;
     BS2000:POSIX*:*:*)
-       echo bs2000-siemens-sysv
-       exit ;;
+       GUESS=bs2000-siemens-sysv
+       ;;
     DS/*:UNIX_System_V:*:*)
-       echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE"
-       exit ;;
+       GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE
+       ;;
     *:Plan9:*:*)
        # "uname -m" is not consistent, so use $cputype instead. 386
        # is converted to i386 for consistency with other x86
        # operating systems.
-       if test "$cputype" = 386; then
+       if test "${cputype-}" = 386; then
            UNAME_MACHINE=i386
-       else
-           UNAME_MACHINE="$cputype"
+       elif test "x${cputype-}" != x; then
+           UNAME_MACHINE=$cputype
        fi
-       echo "$UNAME_MACHINE"-unknown-plan9
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-plan9
+       ;;
     *:TOPS-10:*:*)
-       echo pdp10-unknown-tops10
-       exit ;;
+       GUESS=pdp10-unknown-tops10
+       ;;
     *:TENEX:*:*)
-       echo pdp10-unknown-tenex
-       exit ;;
+       GUESS=pdp10-unknown-tenex
+       ;;
     KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
-       echo pdp10-dec-tops20
-       exit ;;
+       GUESS=pdp10-dec-tops20
+       ;;
     XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
-       echo pdp10-xkl-tops20
-       exit ;;
+       GUESS=pdp10-xkl-tops20
+       ;;
     *:TOPS-20:*:*)
-       echo pdp10-unknown-tops20
-       exit ;;
+       GUESS=pdp10-unknown-tops20
+       ;;
     *:ITS:*:*)
-       echo pdp10-unknown-its
-       exit ;;
+       GUESS=pdp10-unknown-its
+       ;;
     SEI:*:*:SEIUX)
-       echo mips-sei-seiux"$UNAME_RELEASE"
-       exit ;;
+       GUESS=mips-sei-seiux$UNAME_RELEASE
+       ;;
     *:DragonFly:*:*)
-       echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`"
-       exit ;;
+       DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+       GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL
+       ;;
     *:*VMS:*:*)
        UNAME_MACHINE=`(uname -p) 2>/dev/null`
-       case "$UNAME_MACHINE" in
-           A*) echo alpha-dec-vms ; exit ;;
-           I*) echo ia64-dec-vms ; exit ;;
-           V*) echo vax-dec-vms ; exit ;;
+       case $UNAME_MACHINE in
+           A*) GUESS=alpha-dec-vms ;;
+           I*) GUESS=ia64-dec-vms ;;
+           V*) GUESS=vax-dec-vms ;;
        esac ;;
     *:XENIX:*:SysV)
-       echo i386-pc-xenix
-       exit ;;
+       GUESS=i386-pc-xenix
+       ;;
     i*86:skyos:*:*)
-       echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`"
-       exit ;;
+       SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`
+       GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL
+       ;;
     i*86:rdos:*:*)
-       echo "$UNAME_MACHINE"-pc-rdos
-       exit ;;
-    i*86:AROS:*:*)
-       echo "$UNAME_MACHINE"-pc-aros
-       exit ;;
+       GUESS=$UNAME_MACHINE-pc-rdos
+       ;;
+    *:AROS:*:*)
+       GUESS=$UNAME_MACHINE-unknown-aros
+       ;;
     x86_64:VMkernel:*:*)
-       echo "$UNAME_MACHINE"-unknown-esx
-       exit ;;
+       GUESS=$UNAME_MACHINE-unknown-esx
+       ;;
     amd64:Isilon\ OneFS:*:*)
-       echo x86_64-unknown-onefs
-       exit ;;
+       GUESS=x86_64-unknown-onefs
+       ;;
+    *:Unleashed:*:*)
+       GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE
+       ;;
 esac
 
+# Do we have a guess based on uname results?
+if test "x$GUESS" != x; then
+    echo "$GUESS"
+    exit
+fi
+
+# No uname command or uname output not recognized.
+set_cc_for_build
+cat > "$dummy.c" <<EOF
+#ifdef _SEQUENT_
+#include <sys/types.h>
+#include <sys/utsname.h>
+#endif
+#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__)
+#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)
+#include <signal.h>
+#if defined(_SIZE_T_) || defined(SIGLOST)
+#include <sys/utsname.h>
+#endif
+#endif
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+  "4"
+#else
+  ""
+#endif
+  ); exit (0);
+#endif
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+  struct utsname un;
+
+  uname(&un);
+  if (strncmp(un.version, "V2", 2) == 0) {
+    printf ("i386-sequent-ptx2\n"); exit (0);
+  }
+  if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+    printf ("i386-sequent-ptx1\n"); exit (0);
+  }
+  printf ("i386-sequent-ptx\n"); exit (0);
+#endif
+
+#if defined (vax)
+#if !defined (ultrix)
+#include <sys/param.h>
+#if defined (BSD)
+#if BSD == 43
+  printf ("vax-dec-bsd4.3\n"); exit (0);
+#else
+#if BSD == 199006
+  printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#else
+  printf ("vax-dec-bsd\n"); exit (0);
+#endif
+#endif
+#else
+  printf ("vax-dec-bsd\n"); exit (0);
+#endif
+#else
+#if defined(_SIZE_T_) || defined(SIGLOST)
+  struct utsname un;
+  uname (&un);
+  printf ("vax-dec-ultrix%s\n", un.release); exit (0);
+#else
+  printf ("vax-dec-ultrix\n"); exit (0);
+#endif
+#endif
+#endif
+#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__)
+#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)
+#if defined(_SIZE_T_) || defined(SIGLOST)
+  struct utsname *un;
+  uname (&un);
+  printf ("mips-dec-ultrix%s\n", un.release); exit (0);
+#else
+  printf ("mips-dec-ultrix\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` &&
+       { echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; }
+
 echo "$0: unable to guess system type" >&2
 
-case "$UNAME_MACHINE:$UNAME_SYSTEM" in
+case $UNAME_MACHINE:$UNAME_SYSTEM in
     mips:Linux | mips64:Linux)
        # If we got here on MIPS GNU/Linux, output extra information.
        cat >&2 <<EOF
@@ -1435,9 +1698,17 @@ This script (version $timestamp), has failed to recognize the
 operating system you are using. If your script is old, overwrite *all*
 copies of config.guess and config.sub with the latest versions from:
 
-  https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
+  https://git.savannah.gnu.org/cgit/config.git/plain/config.guess
 and
-  https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+  https://git.savannah.gnu.org/cgit/config.git/plain/config.sub
+EOF
+
+our_year=`echo $timestamp | sed 's,-.*,,'`
+thisyear=`date +%Y`
+# shellcheck disable=SC2003
+script_age=`expr "$thisyear" - "$our_year"`
+if test "$script_age" -lt 3 ; then
+   cat >&2 <<EOF
 
 If $0 has already been updated, send the following data and any
 information you think might be pertinent to config-patches@gnu.org to
@@ -1465,6 +1736,7 @@ UNAME_RELEASE = "$UNAME_RELEASE"
 UNAME_SYSTEM  = "$UNAME_SYSTEM"
 UNAME_VERSION = "$UNAME_VERSION"
 EOF
+fi
 
 exit 1
 
index ba37cf9..d74fb6d 100755 (executable)
@@ -1,8 +1,10 @@
 #! /bin/sh
 # Configuration validation subroutine script.
-#   Copyright 1992-2018 Free Software Foundation, Inc.
+#   Copyright 1992-2021 Free Software Foundation, Inc.
 
-timestamp='2018-04-24'
+# shellcheck disable=SC2006,SC2268 # see below for rationale
+
+timestamp='2021-08-14'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -33,7 +35,7 @@ timestamp='2018-04-24'
 # Otherwise, we print the canonical config type on stdout and succeed.
 
 # You can get the latest version of this script from:
-# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+# https://git.savannah.gnu.org/cgit/config.git/plain/config.sub
 
 # This file is supposed to be the same for all GNU packages
 # and recognize all the CPU types, system types and aliases
@@ -50,6 +52,13 @@ timestamp='2018-04-24'
 #      CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
 # It is wrong to echo any other type of specification.
 
+# The "shellcheck disable" line above the timestamp inhibits complaints
+# about features and limitations of the classic Bourne shell that were
+# superseded or lifted in POSIX.  However, this script identifies a wide
+# variety of pre-POSIX systems that do not have POSIX shells at all, and
+# even some reasonably current systems (Solaris 10 as case-in-point) still
+# have a pre-POSIX /bin/sh.
+
 me=`echo "$0" | sed -e 's,.*/,,'`
 
 usage="\
@@ -67,7 +76,7 @@ Report bugs and patches to <config-patches@gnu.org>."
 version="\
 GNU config.sub ($timestamp)
 
-Copyright 1992-2018 Free Software Foundation, Inc.
+Copyright 1992-2021 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -89,7 +98,7 @@ while test $# -gt 0 ; do
     - )        # Use stdin as input.
        break ;;
     -* )
-       echo "$me: invalid option $1$help"
+       echo "$me: invalid option $1$help" >&2
        exit 1 ;;
 
     *local*)
@@ -110,1227 +119,1181 @@ case $# in
     exit 1;;
 esac
 
-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
-# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
-case $maybe_os in
-  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
-  linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
-  knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
-  kopensolaris*-gnu* | cloudabi*-eabi* | \
-  storm-chaos* | os2-emx* | rtmk-nova*)
-    os=-$maybe_os
-    basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
-    ;;
-  android-linux)
-    os=-linux-android
-    basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
-    ;;
-  *)
-    basic_machine=`echo "$1" | sed 's/-[^-]*$//'`
-    if [ "$basic_machine" != "$1" ]
-    then os=`echo "$1" | sed 's/.*-/-/'`
-    else os=; fi
-    ;;
-esac
+# Split fields of configuration type
+# shellcheck disable=SC2162
+saved_IFS=$IFS
+IFS="-" read field1 field2 field3 field4 <<EOF
+$1
+EOF
+IFS=$saved_IFS
 
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work.  We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
-       -sun*os*)
-               # Prevent following clause from handling this invalid input.
-               ;;
-       -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
-       -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
-       -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
-       -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-       -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-       -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-       -apple | -axis | -knuth | -cray | -microblaze*)
-               os=
-               basic_machine=$1
-               ;;
-       -bluegene*)
-               os=-cnk
-               ;;
-       -sim | -cisco | -oki | -wec | -winbond)
-               os=
-               basic_machine=$1
-               ;;
-       -scout)
-               ;;
-       -wrs)
-               os=-vxworks
-               basic_machine=$1
-               ;;
-       -chorusos*)
-               os=-chorusos
-               basic_machine=$1
-               ;;
-       -chorusrdb)
-               os=-chorusrdb
-               basic_machine=$1
-               ;;
-       -hiux*)
-               os=-hiuxwe2
-               ;;
-       -sco6)
-               os=-sco5v6
-               basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -sco5)
-               os=-sco3.2v5
-               basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -sco4)
-               os=-sco3.2v4
-               basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -sco3.2.[4-9]*)
-               os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
-               basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -sco3.2v[4-9]*)
-               # Don't forget version if it is 3.2v4 or newer.
-               basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -sco5v6*)
-               # Don't forget version if it is 3.2v4 or newer.
-               basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -sco*)
-               os=-sco3.2v2
-               basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -udk*)
-               basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -isc)
-               os=-isc2.2
-               basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -clix*)
-               basic_machine=clipper-intergraph
-               ;;
-       -isc*)
-               basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -lynx*178)
-               os=-lynxos178
-               ;;
-       -lynx*5)
-               os=-lynxos5
+# Separate into logical components for further validation
+case $1 in
+       *-*-*-*-*)
+               echo Invalid configuration \`"$1"\': more than four components >&2
+               exit 1
                ;;
-       -lynx*)
-               os=-lynxos
+       *-*-*-*)
+               basic_machine=$field1-$field2
+               basic_os=$field3-$field4
                ;;
-       -ptx*)
-               basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'`
+       *-*-*)
+               # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two
+               # parts
+               maybe_os=$field2-$field3
+               case $maybe_os in
+                       nto-qnx* | linux-* | uclinux-uclibc* \
+                       | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \
+                       | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \
+                       | storm-chaos* | os2-emx* | rtmk-nova*)
+                               basic_machine=$field1
+                               basic_os=$maybe_os
+                               ;;
+                       android-linux)
+                               basic_machine=$field1-unknown
+                               basic_os=linux-android
+                               ;;
+                       *)
+                               basic_machine=$field1-$field2
+                               basic_os=$field3
+                               ;;
+               esac
                ;;
-       -psos*)
-               os=-psos
+       *-*)
+               # A lone config we happen to match not fitting any pattern
+               case $field1-$field2 in
+                       decstation-3100)
+                               basic_machine=mips-dec
+                               basic_os=
+                               ;;
+                       *-*)
+                               # Second component is usually, but not always the OS
+                               case $field2 in
+                                       # Prevent following clause from handling this valid os
+                                       sun*os*)
+                                               basic_machine=$field1
+                                               basic_os=$field2
+                                               ;;
+                                       zephyr*)
+                                               basic_machine=$field1-unknown
+                                               basic_os=$field2
+                                               ;;
+                                       # Manufacturers
+                                       dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \
+                                       | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \
+                                       | unicom* | ibm* | next | hp | isi* | apollo | altos* \
+                                       | convergent* | ncr* | news | 32* | 3600* | 3100* \
+                                       | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \
+                                       | ultra | tti* | harris | dolphin | highlevel | gould \
+                                       | cbm | ns | masscomp | apple | axis | knuth | cray \
+                                       | microblaze* | sim | cisco \
+                                       | oki | wec | wrs | winbond)
+                                               basic_machine=$field1-$field2
+                                               basic_os=
+                                               ;;
+                                       *)
+                                               basic_machine=$field1
+                                               basic_os=$field2
+                                               ;;
+                               esac
+                       ;;
+               esac
                ;;
-       -mint | -mint[0-9]*)
-               basic_machine=m68k-atari
-               os=-mint
+       *)
+               # Convert single-component short-hands not valid as part of
+               # multi-component configurations.
+               case $field1 in
+                       386bsd)
+                               basic_machine=i386-pc
+                               basic_os=bsd
+                               ;;
+                       a29khif)
+                               basic_machine=a29k-amd
+                               basic_os=udi
+                               ;;
+                       adobe68k)
+                               basic_machine=m68010-adobe
+                               basic_os=scout
+                               ;;
+                       alliant)
+                               basic_machine=fx80-alliant
+                               basic_os=
+                               ;;
+                       altos | altos3068)
+                               basic_machine=m68k-altos
+                               basic_os=
+                               ;;
+                       am29k)
+                               basic_machine=a29k-none
+                               basic_os=bsd
+                               ;;
+                       amdahl)
+                               basic_machine=580-amdahl
+                               basic_os=sysv
+                               ;;
+                       amiga)
+                               basic_machine=m68k-unknown
+                               basic_os=
+                               ;;
+                       amigaos | amigados)
+                               basic_machine=m68k-unknown
+                               basic_os=amigaos
+                               ;;
+                       amigaunix | amix)
+                               basic_machine=m68k-unknown
+                               basic_os=sysv4
+                               ;;
+                       apollo68)
+                               basic_machine=m68k-apollo
+                               basic_os=sysv
+                               ;;
+                       apollo68bsd)
+                               basic_machine=m68k-apollo
+                               basic_os=bsd
+                               ;;
+                       aros)
+                               basic_machine=i386-pc
+                               basic_os=aros
+                               ;;
+                       aux)
+                               basic_machine=m68k-apple
+                               basic_os=aux
+                               ;;
+                       balance)
+                               basic_machine=ns32k-sequent
+                               basic_os=dynix
+                               ;;
+                       blackfin)
+                               basic_machine=bfin-unknown
+                               basic_os=linux
+                               ;;
+                       cegcc)
+                               basic_machine=arm-unknown
+                               basic_os=cegcc
+                               ;;
+                       convex-c1)
+                               basic_machine=c1-convex
+                               basic_os=bsd
+                               ;;
+                       convex-c2)
+                               basic_machine=c2-convex
+                               basic_os=bsd
+                               ;;
+                       convex-c32)
+                               basic_machine=c32-convex
+                               basic_os=bsd
+                               ;;
+                       convex-c34)
+                               basic_machine=c34-convex
+                               basic_os=bsd
+                               ;;
+                       convex-c38)
+                               basic_machine=c38-convex
+                               basic_os=bsd
+                               ;;
+                       cray)
+                               basic_machine=j90-cray
+                               basic_os=unicos
+                               ;;
+                       crds | unos)
+                               basic_machine=m68k-crds
+                               basic_os=
+                               ;;
+                       da30)
+                               basic_machine=m68k-da30
+                               basic_os=
+                               ;;
+                       decstation | pmax | pmin | dec3100 | decstatn)
+                               basic_machine=mips-dec
+                               basic_os=
+                               ;;
+                       delta88)
+                               basic_machine=m88k-motorola
+                               basic_os=sysv3
+                               ;;
+                       dicos)
+                               basic_machine=i686-pc
+                               basic_os=dicos
+                               ;;
+                       djgpp)
+                               basic_machine=i586-pc
+                               basic_os=msdosdjgpp
+                               ;;
+                       ebmon29k)
+                               basic_machine=a29k-amd
+                               basic_os=ebmon
+                               ;;
+                       es1800 | OSE68k | ose68k | ose | OSE)
+                               basic_machine=m68k-ericsson
+                               basic_os=ose
+                               ;;
+                       gmicro)
+                               basic_machine=tron-gmicro
+                               basic_os=sysv
+                               ;;
+                       go32)
+                               basic_machine=i386-pc
+                               basic_os=go32
+                               ;;
+                       h8300hms)
+                               basic_machine=h8300-hitachi
+                               basic_os=hms
+                               ;;
+                       h8300xray)
+                               basic_machine=h8300-hitachi
+                               basic_os=xray
+                               ;;
+                       h8500hms)
+                               basic_machine=h8500-hitachi
+                               basic_os=hms
+                               ;;
+                       harris)
+                               basic_machine=m88k-harris
+                               basic_os=sysv3
+                               ;;
+                       hp300 | hp300hpux)
+                               basic_machine=m68k-hp
+                               basic_os=hpux
+                               ;;
+                       hp300bsd)
+                               basic_machine=m68k-hp
+                               basic_os=bsd
+                               ;;
+                       hppaosf)
+                               basic_machine=hppa1.1-hp
+                               basic_os=osf
+                               ;;
+                       hppro)
+                               basic_machine=hppa1.1-hp
+                               basic_os=proelf
+                               ;;
+                       i386mach)
+                               basic_machine=i386-mach
+                               basic_os=mach
+                               ;;
+                       isi68 | isi)
+                               basic_machine=m68k-isi
+                               basic_os=sysv
+                               ;;
+                       m68knommu)
+                               basic_machine=m68k-unknown
+                               basic_os=linux
+                               ;;
+                       magnum | m3230)
+                               basic_machine=mips-mips
+                               basic_os=sysv
+                               ;;
+                       merlin)
+                               basic_machine=ns32k-utek
+                               basic_os=sysv
+                               ;;
+                       mingw64)
+                               basic_machine=x86_64-pc
+                               basic_os=mingw64
+                               ;;
+                       mingw32)
+                               basic_machine=i686-pc
+                               basic_os=mingw32
+                               ;;
+                       mingw32ce)
+                               basic_machine=arm-unknown
+                               basic_os=mingw32ce
+                               ;;
+                       monitor)
+                               basic_machine=m68k-rom68k
+                               basic_os=coff
+                               ;;
+                       morphos)
+                               basic_machine=powerpc-unknown
+                               basic_os=morphos
+                               ;;
+                       moxiebox)
+                               basic_machine=moxie-unknown
+                               basic_os=moxiebox
+                               ;;
+                       msdos)
+                               basic_machine=i386-pc
+                               basic_os=msdos
+                               ;;
+                       msys)
+                               basic_machine=i686-pc
+                               basic_os=msys
+                               ;;
+                       mvs)
+                               basic_machine=i370-ibm
+                               basic_os=mvs
+                               ;;
+                       nacl)
+                               basic_machine=le32-unknown
+                               basic_os=nacl
+                               ;;
+                       ncr3000)
+                               basic_machine=i486-ncr
+                               basic_os=sysv4
+                               ;;
+                       netbsd386)
+                               basic_machine=i386-pc
+                               basic_os=netbsd
+                               ;;
+                       netwinder)
+                               basic_machine=armv4l-rebel
+                               basic_os=linux
+                               ;;
+                       news | news700 | news800 | news900)
+                               basic_machine=m68k-sony
+                               basic_os=newsos
+                               ;;
+                       news1000)
+                               basic_machine=m68030-sony
+                               basic_os=newsos
+                               ;;
+                       necv70)
+                               basic_machine=v70-nec
+                               basic_os=sysv
+                               ;;
+                       nh3000)
+                               basic_machine=m68k-harris
+                               basic_os=cxux
+                               ;;
+                       nh[45]000)
+                               basic_machine=m88k-harris
+                               basic_os=cxux
+                               ;;
+                       nindy960)
+                               basic_machine=i960-intel
+                               basic_os=nindy
+                               ;;
+                       mon960)
+                               basic_machine=i960-intel
+                               basic_os=mon960
+                               ;;
+                       nonstopux)
+                               basic_machine=mips-compaq
+                               basic_os=nonstopux
+                               ;;
+                       os400)
+                               basic_machine=powerpc-ibm
+                               basic_os=os400
+                               ;;
+                       OSE68000 | ose68000)
+                               basic_machine=m68000-ericsson
+                               basic_os=ose
+                               ;;
+                       os68k)
+                               basic_machine=m68k-none
+                               basic_os=os68k
+                               ;;
+                       paragon)
+                               basic_machine=i860-intel
+                               basic_os=osf
+                               ;;
+                       parisc)
+                               basic_machine=hppa-unknown
+                               basic_os=linux
+                               ;;
+                       psp)
+                               basic_machine=mipsallegrexel-sony
+                               basic_os=psp
+                               ;;
+                       pw32)
+                               basic_machine=i586-unknown
+                               basic_os=pw32
+                               ;;
+                       rdos | rdos64)
+                               basic_machine=x86_64-pc
+                               basic_os=rdos
+                               ;;
+                       rdos32)
+                               basic_machine=i386-pc
+                               basic_os=rdos
+                               ;;
+                       rom68k)
+                               basic_machine=m68k-rom68k
+                               basic_os=coff
+                               ;;
+                       sa29200)
+                               basic_machine=a29k-amd
+                               basic_os=udi
+                               ;;
+                       sei)
+                               basic_machine=mips-sei
+                               basic_os=seiux
+                               ;;
+                       sequent)
+                               basic_machine=i386-sequent
+                               basic_os=
+                               ;;
+                       sps7)
+                               basic_machine=m68k-bull
+                               basic_os=sysv2
+                               ;;
+                       st2000)
+                               basic_machine=m68k-tandem
+                               basic_os=
+                               ;;
+                       stratus)
+                               basic_machine=i860-stratus
+                               basic_os=sysv4
+                               ;;
+                       sun2)
+                               basic_machine=m68000-sun
+                               basic_os=
+                               ;;
+                       sun2os3)
+                               basic_machine=m68000-sun
+                               basic_os=sunos3
+                               ;;
+                       sun2os4)
+                               basic_machine=m68000-sun
+                               basic_os=sunos4
+                               ;;
+                       sun3)
+                               basic_machine=m68k-sun
+                               basic_os=
+                               ;;
+                       sun3os3)
+                               basic_machine=m68k-sun
+                               basic_os=sunos3
+                               ;;
+                       sun3os4)
+                               basic_machine=m68k-sun
+                               basic_os=sunos4
+                               ;;
+                       sun4)
+                               basic_machine=sparc-sun
+                               basic_os=
+                               ;;
+                       sun4os3)
+                               basic_machine=sparc-sun
+                               basic_os=sunos3
+                               ;;
+                       sun4os4)
+                               basic_machine=sparc-sun
+                               basic_os=sunos4
+                               ;;
+                       sun4sol2)
+                               basic_machine=sparc-sun
+                               basic_os=solaris2
+                               ;;
+                       sun386 | sun386i | roadrunner)
+                               basic_machine=i386-sun
+                               basic_os=
+                               ;;
+                       sv1)
+                               basic_machine=sv1-cray
+                               basic_os=unicos
+                               ;;
+                       symmetry)
+                               basic_machine=i386-sequent
+                               basic_os=dynix
+                               ;;
+                       t3e)
+                               basic_machine=alphaev5-cray
+                               basic_os=unicos
+                               ;;
+                       t90)
+                               basic_machine=t90-cray
+                               basic_os=unicos
+                               ;;
+                       toad1)
+                               basic_machine=pdp10-xkl
+                               basic_os=tops20
+                               ;;
+                       tpf)
+                               basic_machine=s390x-ibm
+                               basic_os=tpf
+                               ;;
+                       udi29k)
+                               basic_machine=a29k-amd
+                               basic_os=udi
+                               ;;
+                       ultra3)
+                               basic_machine=a29k-nyu
+                               basic_os=sym1
+                               ;;
+                       v810 | necv810)
+                               basic_machine=v810-nec
+                               basic_os=none
+                               ;;
+                       vaxv)
+                               basic_machine=vax-dec
+                               basic_os=sysv
+                               ;;
+                       vms)
+                               basic_machine=vax-dec
+                               basic_os=vms
+                               ;;
+                       vsta)
+                               basic_machine=i386-pc
+                               basic_os=vsta
+                               ;;
+                       vxworks960)
+                               basic_machine=i960-wrs
+                               basic_os=vxworks
+                               ;;
+                       vxworks68)
+                               basic_machine=m68k-wrs
+                               basic_os=vxworks
+                               ;;
+                       vxworks29k)
+                               basic_machine=a29k-wrs
+                               basic_os=vxworks
+                               ;;
+                       xbox)
+                               basic_machine=i686-pc
+                               basic_os=mingw32
+                               ;;
+                       ymp)
+                               basic_machine=ymp-cray
+                               basic_os=unicos
+                               ;;
+                       *)
+                               basic_machine=$1
+                               basic_os=
+                               ;;
+               esac
                ;;
 esac
 
-# Decode aliases for certain CPU-COMPANY combinations.
+# Decode 1-component or ad-hoc basic machines
 case $basic_machine in
-       # Recognize the basic CPU types without company name.
-       # Some are omitted here because they have special meanings below.
-       1750a | 580 \
-       | a29k \
-       | aarch64 | aarch64_be \
-       | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
-       | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
-       | am33_2.0 \
-       | arc | arceb \
-       | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv6m | armv[78][arm] \
-       | avr | avr32 \
-       | ba \
-       | be32 | be64 \
-       | bfin \
-       | c4x | c8051 | clipper | csky \
-       | d10v | d30v | dlx | dsp16xx \
-       | e2k | epiphany \
-       | fido | fr30 | frv | ft32 \
-       | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
-       | hexagon \
-       | i370 | i860 | i960 | ia16 | ia64 \
-       | ip2k | iq2000 \
-       | k1om \
-       | le32 | le64 \
-       | lm32 \
-       | m32c | m32r | m32rle | m68000 | m68k | m88k \
-       | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
-       | mips | mipsbe | mipseb | mipsel | mipsle \
-       | mips16 \
-       | mips64 | mips64el \
-       | mips64octeon | mips64octeonel \
-       | mips64orion | mips64orionel \
-       | mips64r5900 | mips64r5900el \
-       | mips64vr | mips64vrel \
-       | mips64vr4100 | mips64vr4100el \
-       | mips64vr4300 | mips64vr4300el \
-       | mips64vr5000 | mips64vr5000el \
-       | mips64vr5900 | mips64vr5900el \
-       | mipsisa32 | mipsisa32el \
-       | mipsisa32r2 | mipsisa32r2el \
-       | mipsisa32r6 | mipsisa32r6el \
-       | mipsisa64 | mipsisa64el \
-       | mipsisa64r2 | mipsisa64r2el \
-       | mipsisa64r6 | mipsisa64r6el \
-       | mipsisa64sb1 | mipsisa64sb1el \
-       | mipsisa64sr71k | mipsisa64sr71kel \
-       | mipsr5900 | mipsr5900el \
-       | mipstx39 | mipstx39el \
-       | mn10200 | mn10300 \
-       | moxie \
-       | mt \
-       | msp430 \
-       | nds32 | nds32le | nds32be \
-       | nios | nios2 | nios2eb | nios2el \
-       | ns16k | ns32k \
-       | open8 | or1k | or1knd | or32 \
-       | pdp10 | pj | pjl \
-       | powerpc | powerpc64 | powerpc64le | powerpcle \
-       | pru \
-       | pyramid \
-       | riscv32 | riscv64 \
-       | rl78 | rx \
-       | score \
-       | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
-       | sh64 | sh64le \
-       | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
-       | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
-       | spu \
-       | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
-       | ubicom32 \
-       | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
-       | visium \
-       | wasm32 \
-       | x86 | xc16x | xstormy16 | xtensa \
-       | z8k | z80)
-               basic_machine=$basic_machine-unknown
-               ;;
-       c54x)
-               basic_machine=tic54x-unknown
-               ;;
-       c55x)
-               basic_machine=tic55x-unknown
-               ;;
-       c6x)
-               basic_machine=tic6x-unknown
-               ;;
-       leon|leon[3-9])
-               basic_machine=sparc-$basic_machine
-               ;;
-       m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
-               basic_machine=$basic_machine-unknown
-               os=-none
-               ;;
-       m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65)
+       # Here we handle the default manufacturer of certain CPU types.  It is in
+       # some cases the only manufacturer, in others, it is the most popular.
+       w89k)
+               cpu=hppa1.1
+               vendor=winbond
                ;;
-       m9s12z | m68hcs12z | hcs12z | s12z)
-               basic_machine=s12z-unknown
-               os=-none
+       op50n)
+               cpu=hppa1.1
+               vendor=oki
                ;;
-       ms1)
-               basic_machine=mt-unknown
+       op60c)
+               cpu=hppa1.1
+               vendor=oki
                ;;
-
-       strongarm | thumb | xscale)
-               basic_machine=arm-unknown
+       ibm*)
+               cpu=i370
+               vendor=ibm
                ;;
-       xgate)
-               basic_machine=$basic_machine-unknown
-               os=-none
+       orion105)
+               cpu=clipper
+               vendor=highlevel
                ;;
-       xscaleeb)
-               basic_machine=armeb-unknown
+       mac | mpw | mac-mpw)
+               cpu=m68k
+               vendor=apple
                ;;
-
-       xscaleel)
-               basic_machine=armel-unknown
+       pmac | pmac-mpw)
+               cpu=powerpc
+               vendor=apple
                ;;
 
-       # We use `pc' rather than `unknown'
-       # because (1) that's what they normally are, and
-       # (2) the word "unknown" tends to confuse beginning users.
-       i*86 | x86_64)
-         basic_machine=$basic_machine-pc
-         ;;
-       # Object if more than one company name word.
-       *-*-*)
-               echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
-               exit 1
-               ;;
-       # Recognize the basic CPU types with company name.
-       580-* \
-       | a29k-* \
-       | aarch64-* | aarch64_be-* \
-       | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
-       | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
-       | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
-       | arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
-       | avr-* | avr32-* \
-       | ba-* \
-       | be32-* | be64-* \
-       | bfin-* | bs2000-* \
-       | c[123]* | c30-* | [cjt]90-* | c4x-* \
-       | c8051-* | clipper-* | craynv-* | csky-* | cydra-* \
-       | d10v-* | d30v-* | dlx-* \
-       | e2k-* | elxsi-* \
-       | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
-       | h8300-* | h8500-* \
-       | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
-       | hexagon-* \
-       | i*86-* | i860-* | i960-* | ia16-* | ia64-* \
-       | ip2k-* | iq2000-* \
-       | k1om-* \
-       | le32-* | le64-* \
-       | lm32-* \
-       | m32c-* | m32r-* | m32rle-* \
-       | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
-       | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
-       | microblaze-* | microblazeel-* \
-       | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
-       | mips16-* \
-       | mips64-* | mips64el-* \
-       | mips64octeon-* | mips64octeonel-* \
-       | mips64orion-* | mips64orionel-* \
-       | mips64r5900-* | mips64r5900el-* \
-       | mips64vr-* | mips64vrel-* \
-       | mips64vr4100-* | mips64vr4100el-* \
-       | mips64vr4300-* | mips64vr4300el-* \
-       | mips64vr5000-* | mips64vr5000el-* \
-       | mips64vr5900-* | mips64vr5900el-* \
-       | mipsisa32-* | mipsisa32el-* \
-       | mipsisa32r2-* | mipsisa32r2el-* \
-       | mipsisa32r6-* | mipsisa32r6el-* \
-       | mipsisa64-* | mipsisa64el-* \
-       | mipsisa64r2-* | mipsisa64r2el-* \
-       | mipsisa64r6-* | mipsisa64r6el-* \
-       | mipsisa64sb1-* | mipsisa64sb1el-* \
-       | mipsisa64sr71k-* | mipsisa64sr71kel-* \
-       | mipsr5900-* | mipsr5900el-* \
-       | mipstx39-* | mipstx39el-* \
-       | mmix-* \
-       | mt-* \
-       | msp430-* \
-       | nds32-* | nds32le-* | nds32be-* \
-       | nios-* | nios2-* | nios2eb-* | nios2el-* \
-       | none-* | np1-* | ns16k-* | ns32k-* \
-       | open8-* \
-       | or1k*-* \
-       | orion-* \
-       | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
-       | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
-       | pru-* \
-       | pyramid-* \
-       | riscv32-* | riscv64-* \
-       | rl78-* | romp-* | rs6000-* | rx-* \
-       | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
-       | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
-       | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
-       | sparclite-* \
-       | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
-       | tahoe-* \
-       | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
-       | tile*-* \
-       | tron-* \
-       | ubicom32-* \
-       | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
-       | vax-* \
-       | visium-* \
-       | wasm32-* \
-       | we32k-* \
-       | x86-* | x86_64-* | xc16x-* | xps100-* \
-       | xstormy16-* | xtensa*-* \
-       | ymp-* \
-       | z8k-* | z80-*)
-               ;;
-       # Recognize the basic CPU types without company name, with glob match.
-       xtensa*)
-               basic_machine=$basic_machine-unknown
-               ;;
        # Recognize the various machine names and aliases which stand
        # for a CPU type and a company and sometimes even an OS.
-       386bsd)
-               basic_machine=i386-pc
-               os=-bsd
-               ;;
        3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
-               basic_machine=m68000-att
+               cpu=m68000
+               vendor=att
                ;;
        3b*)
-               basic_machine=we32k-att
-               ;;
-       a29khif)
-               basic_machine=a29k-amd
-               os=-udi
-               ;;
-       abacus)
-               basic_machine=abacus-unknown
-               ;;
-       adobe68k)
-               basic_machine=m68010-adobe
-               os=-scout
-               ;;
-       alliant | fx80)
-               basic_machine=fx80-alliant
-               ;;
-       altos | altos3068)
-               basic_machine=m68k-altos
-               ;;
-       am29k)
-               basic_machine=a29k-none
-               os=-bsd
-               ;;
-       amd64)
-               basic_machine=x86_64-pc
-               ;;
-       amd64-*)
-               basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-               ;;
-       amdahl)
-               basic_machine=580-amdahl
-               os=-sysv
-               ;;
-       amiga | amiga-*)
-               basic_machine=m68k-unknown
-               ;;
-       amigaos | amigados)
-               basic_machine=m68k-unknown
-               os=-amigaos
-               ;;
-       amigaunix | amix)
-               basic_machine=m68k-unknown
-               os=-sysv4
-               ;;
-       apollo68)
-               basic_machine=m68k-apollo
-               os=-sysv
-               ;;
-       apollo68bsd)
-               basic_machine=m68k-apollo
-               os=-bsd
-               ;;
-       aros)
-               basic_machine=i386-pc
-               os=-aros
-               ;;
-       asmjs)
-               basic_machine=asmjs-unknown
-               ;;
-       aux)
-               basic_machine=m68k-apple
-               os=-aux
-               ;;
-       balance)
-               basic_machine=ns32k-sequent
-               os=-dynix
-               ;;
-       blackfin)
-               basic_machine=bfin-unknown
-               os=-linux
-               ;;
-       blackfin-*)
-               basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-               os=-linux
+               cpu=we32k
+               vendor=att
                ;;
        bluegene*)
-               basic_machine=powerpc-ibm
-               os=-cnk
-               ;;
-       c54x-*)
-               basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-               ;;
-       c55x-*)
-               basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-               ;;
-       c6x-*)
-               basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-               ;;
-       c90)
-               basic_machine=c90-cray
-               os=-unicos
-               ;;
-       cegcc)
-               basic_machine=arm-unknown
-               os=-cegcc
-               ;;
-       convex-c1)
-               basic_machine=c1-convex
-               os=-bsd
-               ;;
-       convex-c2)
-               basic_machine=c2-convex
-               os=-bsd
-               ;;
-       convex-c32)
-               basic_machine=c32-convex
-               os=-bsd
-               ;;
-       convex-c34)
-               basic_machine=c34-convex
-               os=-bsd
-               ;;
-       convex-c38)
-               basic_machine=c38-convex
-               os=-bsd
-               ;;
-       cray | j90)
-               basic_machine=j90-cray
-               os=-unicos
-               ;;
-       craynv)
-               basic_machine=craynv-cray
-               os=-unicosmp
-               ;;
-       cr16 | cr16-*)
-               basic_machine=cr16-unknown
-               os=-elf
-               ;;
-       crds | unos)
-               basic_machine=m68k-crds
-               ;;
-       crisv32 | crisv32-* | etraxfs*)
-               basic_machine=crisv32-axis
-               ;;
-       cris | cris-* | etrax*)
-               basic_machine=cris-axis
-               ;;
-       crx)
-               basic_machine=crx-unknown
-               os=-elf
-               ;;
-       da30 | da30-*)
-               basic_machine=m68k-da30
-               ;;
-       decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
-               basic_machine=mips-dec
+               cpu=powerpc
+               vendor=ibm
+               basic_os=cnk
                ;;
        decsystem10* | dec10*)
-               basic_machine=pdp10-dec
-               os=-tops10
+               cpu=pdp10
+               vendor=dec
+               basic_os=tops10
                ;;
        decsystem20* | dec20*)
-               basic_machine=pdp10-dec
-               os=-tops20
+               cpu=pdp10
+               vendor=dec
+               basic_os=tops20
                ;;
        delta | 3300 | motorola-3300 | motorola-delta \
              | 3300-motorola | delta-motorola)
-               basic_machine=m68k-motorola
-               ;;
-       delta88)
-               basic_machine=m88k-motorola
-               os=-sysv3
-               ;;
-       dicos)
-               basic_machine=i686-pc
-               os=-dicos
-               ;;
-       djgpp)
-               basic_machine=i586-pc
-               os=-msdosdjgpp
-               ;;
-       dpx20 | dpx20-*)
-               basic_machine=rs6000-bull
-               os=-bosx
+               cpu=m68k
+               vendor=motorola
                ;;
        dpx2*)
-               basic_machine=m68k-bull
-               os=-sysv3
-               ;;
-       e500v[12])
-               basic_machine=powerpc-unknown
-               os=$os"spe"
-               ;;
-       e500v[12]-*)
-               basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-               os=$os"spe"
-               ;;
-       ebmon29k)
-               basic_machine=a29k-amd
-               os=-ebmon
-               ;;
-       elxsi)
-               basic_machine=elxsi-elxsi
-               os=-bsd
+               cpu=m68k
+               vendor=bull
+               basic_os=sysv3
                ;;
        encore | umax | mmax)
-               basic_machine=ns32k-encore
+               cpu=ns32k
+               vendor=encore
                ;;
-       es1800 | OSE68k | ose68k | ose | OSE)
-               basic_machine=m68k-ericsson
-               os=-ose
+       elxsi)
+               cpu=elxsi
+               vendor=elxsi
+               basic_os=${basic_os:-bsd}
                ;;
        fx2800)
-               basic_machine=i860-alliant
+               cpu=i860
+               vendor=alliant
                ;;
        genix)
-               basic_machine=ns32k-ns
-               ;;
-       gmicro)
-               basic_machine=tron-gmicro
-               os=-sysv
-               ;;
-       go32)
-               basic_machine=i386-pc
-               os=-go32
+               cpu=ns32k
+               vendor=ns
                ;;
        h3050r* | hiux*)
-               basic_machine=hppa1.1-hitachi
-               os=-hiuxwe2
-               ;;
-       h8300hms)
-               basic_machine=h8300-hitachi
-               os=-hms
-               ;;
-       h8300xray)
-               basic_machine=h8300-hitachi
-               os=-xray
-               ;;
-       h8500hms)
-               basic_machine=h8500-hitachi
-               os=-hms
-               ;;
-       harris)
-               basic_machine=m88k-harris
-               os=-sysv3
-               ;;
-       hp300-*)
-               basic_machine=m68k-hp
-               ;;
-       hp300bsd)
-               basic_machine=m68k-hp
-               os=-bsd
-               ;;
-       hp300hpux)
-               basic_machine=m68k-hp
-               os=-hpux
+               cpu=hppa1.1
+               vendor=hitachi
+               basic_os=hiuxwe2
                ;;
        hp3k9[0-9][0-9] | hp9[0-9][0-9])
-               basic_machine=hppa1.0-hp
+               cpu=hppa1.0
+               vendor=hp
                ;;
        hp9k2[0-9][0-9] | hp9k31[0-9])
-               basic_machine=m68000-hp
+               cpu=m68000
+               vendor=hp
                ;;
        hp9k3[2-9][0-9])
-               basic_machine=m68k-hp
+               cpu=m68k
+               vendor=hp
                ;;
        hp9k6[0-9][0-9] | hp6[0-9][0-9])
-               basic_machine=hppa1.0-hp
+               cpu=hppa1.0
+               vendor=hp
                ;;
        hp9k7[0-79][0-9] | hp7[0-79][0-9])
-               basic_machine=hppa1.1-hp
+               cpu=hppa1.1
+               vendor=hp
                ;;
        hp9k78[0-9] | hp78[0-9])
                # FIXME: really hppa2.0-hp
-               basic_machine=hppa1.1-hp
+               cpu=hppa1.1
+               vendor=hp
                ;;
        hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
                # FIXME: really hppa2.0-hp
-               basic_machine=hppa1.1-hp
+               cpu=hppa1.1
+               vendor=hp
                ;;
        hp9k8[0-9][13679] | hp8[0-9][13679])
-               basic_machine=hppa1.1-hp
+               cpu=hppa1.1
+               vendor=hp
                ;;
        hp9k8[0-9][0-9] | hp8[0-9][0-9])
-               basic_machine=hppa1.0-hp
-               ;;
-       hppaosf)
-               basic_machine=hppa1.1-hp
-               os=-osf
-               ;;
-       hppro)
-               basic_machine=hppa1.1-hp
-               os=-proelf
-               ;;
-       i370-ibm* | ibm*)
-               basic_machine=i370-ibm
+               cpu=hppa1.0
+               vendor=hp
                ;;
        i*86v32)
-               basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
-               os=-sysv32
+               cpu=`echo "$1" | sed -e 's/86.*/86/'`
+               vendor=pc
+               basic_os=sysv32
                ;;
        i*86v4*)
-               basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
-               os=-sysv4
+               cpu=`echo "$1" | sed -e 's/86.*/86/'`
+               vendor=pc
+               basic_os=sysv4
                ;;
        i*86v)
-               basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
-               os=-sysv
+               cpu=`echo "$1" | sed -e 's/86.*/86/'`
+               vendor=pc
+               basic_os=sysv
                ;;
        i*86sol2)
-               basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
-               os=-solaris2
-               ;;
-       i386mach)
-               basic_machine=i386-mach
-               os=-mach
+               cpu=`echo "$1" | sed -e 's/86.*/86/'`
+               vendor=pc
+               basic_os=solaris2
                ;;
-       vsta)
-               basic_machine=i386-unknown
-               os=-vsta
+       j90 | j90-cray)
+               cpu=j90
+               vendor=cray
+               basic_os=${basic_os:-unicos}
                ;;
        iris | iris4d)
-               basic_machine=mips-sgi
-               case $os in
-                   -irix*)
+               cpu=mips
+               vendor=sgi
+               case $basic_os in
+                   irix*)
                        ;;
                    *)
-                       os=-irix4
+                       basic_os=irix4
                        ;;
                esac
                ;;
-       isi68 | isi)
-               basic_machine=m68k-isi
-               os=-sysv
-               ;;
-       leon-*|leon[3-9]-*)
-               basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'`
-               ;;
-       m68knommu)
-               basic_machine=m68k-unknown
-               os=-linux
-               ;;
-       m68knommu-*)
-               basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-               os=-linux
-               ;;
-       magnum | m3230)
-               basic_machine=mips-mips
-               os=-sysv
-               ;;
-       merlin)
-               basic_machine=ns32k-utek
-               os=-sysv
-               ;;
-       microblaze*)
-               basic_machine=microblaze-xilinx
-               ;;
-       mingw64)
-               basic_machine=x86_64-pc
-               os=-mingw64
-               ;;
-       mingw32)
-               basic_machine=i686-pc
-               os=-mingw32
-               ;;
-       mingw32ce)
-               basic_machine=arm-unknown
-               os=-mingw32ce
-               ;;
        miniframe)
-               basic_machine=m68000-convergent
-               ;;
-       *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
-               basic_machine=m68k-atari
-               os=-mint
-               ;;
-       mips3*-*)
-               basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`
-               ;;
-       mips3*)
-               basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown
-               ;;
-       monitor)
-               basic_machine=m68k-rom68k
-               os=-coff
-               ;;
-       morphos)
-               basic_machine=powerpc-unknown
-               os=-morphos
-               ;;
-       moxiebox)
-               basic_machine=moxie-unknown
-               os=-moxiebox
+               cpu=m68000
+               vendor=convergent
                ;;
-       msdos)
-               basic_machine=i386-pc
-               os=-msdos
-               ;;
-       ms1-*)
-               basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'`
-               ;;
-       msys)
-               basic_machine=i686-pc
-               os=-msys
-               ;;
-       mvs)
-               basic_machine=i370-ibm
-               os=-mvs
-               ;;
-       nacl)
-               basic_machine=le32-unknown
-               os=-nacl
-               ;;
-       ncr3000)
-               basic_machine=i486-ncr
-               os=-sysv4
-               ;;
-       netbsd386)
-               basic_machine=i386-unknown
-               os=-netbsd
-               ;;
-       netwinder)
-               basic_machine=armv4l-rebel
-               os=-linux
-               ;;
-       news | news700 | news800 | news900)
-               basic_machine=m68k-sony
-               os=-newsos
-               ;;
-       news1000)
-               basic_machine=m68030-sony
-               os=-newsos
+       *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*)
+               cpu=m68k
+               vendor=atari
+               basic_os=mint
                ;;
        news-3600 | risc-news)
-               basic_machine=mips-sony
-               os=-newsos
-               ;;
-       necv70)
-               basic_machine=v70-nec
-               os=-sysv
+               cpu=mips
+               vendor=sony
+               basic_os=newsos
                ;;
        next | m*-next)
-               basic_machine=m68k-next
-               case $os in
-                   -nextstep* )
+               cpu=m68k
+               vendor=next
+               case $basic_os in
+                   openstep*)
+                       ;;
+                   nextstep*)
                        ;;
-                   -ns2*)
-                     os=-nextstep2
+                   ns2*)
+                     basic_os=nextstep2
                        ;;
                    *)
-                     os=-nextstep3
+                     basic_os=nextstep3
                        ;;
                esac
                ;;
-       nh3000)
-               basic_machine=m68k-harris
-               os=-cxux
-               ;;
-       nh[45]000)
-               basic_machine=m88k-harris
-               os=-cxux
-               ;;
-       nindy960)
-               basic_machine=i960-intel
-               os=-nindy
-               ;;
-       mon960)
-               basic_machine=i960-intel
-               os=-mon960
-               ;;
-       nonstopux)
-               basic_machine=mips-compaq
-               os=-nonstopux
-               ;;
        np1)
-               basic_machine=np1-gould
-               ;;
-       neo-tandem)
-               basic_machine=neo-tandem
-               ;;
-       nse-tandem)
-               basic_machine=nse-tandem
-               ;;
-       nsr-tandem)
-               basic_machine=nsr-tandem
-               ;;
-       nsv-tandem)
-               basic_machine=nsv-tandem
-               ;;
-       nsx-tandem)
-               basic_machine=nsx-tandem
+               cpu=np1
+               vendor=gould
                ;;
        op50n-* | op60c-*)
-               basic_machine=hppa1.1-oki
-               os=-proelf
-               ;;
-       openrisc | openrisc-*)
-               basic_machine=or32-unknown
-               ;;
-       os400)
-               basic_machine=powerpc-ibm
-               os=-os400
-               ;;
-       OSE68000 | ose68000)
-               basic_machine=m68000-ericsson
-               os=-ose
-               ;;
-       os68k)
-               basic_machine=m68k-none
-               os=-os68k
+               cpu=hppa1.1
+               vendor=oki
+               basic_os=proelf
                ;;
        pa-hitachi)
-               basic_machine=hppa1.1-hitachi
-               os=-hiuxwe2
-               ;;
-       paragon)
-               basic_machine=i860-intel
-               os=-osf
-               ;;
-       parisc)
-               basic_machine=hppa-unknown
-               os=-linux
-               ;;
-       parisc-*)
-               basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-               os=-linux
+               cpu=hppa1.1
+               vendor=hitachi
+               basic_os=hiuxwe2
                ;;
        pbd)
-               basic_machine=sparc-tti
+               cpu=sparc
+               vendor=tti
                ;;
        pbb)
-               basic_machine=m68k-tti
-               ;;
-       pc532 | pc532-*)
-               basic_machine=ns32k-pc532
-               ;;
-       pc98)
-               basic_machine=i386-pc
+               cpu=m68k
+               vendor=tti
                ;;
-       pc98-*)
-               basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-               ;;
-       pentium | p5 | k5 | k6 | nexgen | viac3)
-               basic_machine=i586-pc
-               ;;
-       pentiumpro | p6 | 6x86 | athlon | athlon_*)
-               basic_machine=i686-pc
-               ;;
-       pentiumii | pentium2 | pentiumiii | pentium3)
-               basic_machine=i686-pc
-               ;;
-       pentium4)
-               basic_machine=i786-pc
-               ;;
-       pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
-               basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-               ;;
-       pentiumpro-* | p6-* | 6x86-* | athlon-*)
-               basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-               ;;
-       pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
-               basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-               ;;
-       pentium4-*)
-               basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+       pc532)
+               cpu=ns32k
+               vendor=pc532
                ;;
        pn)
-               basic_machine=pn-gould
-               ;;
-       power)  basic_machine=power-ibm
-               ;;
-       ppc | ppcbe)    basic_machine=powerpc-unknown
+               cpu=pn
+               vendor=gould
                ;;
-       ppc-* | ppcbe-*)
-               basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-               ;;
-       ppcle | powerpclittle)
-               basic_machine=powerpcle-unknown
-               ;;
-       ppcle-* | powerpclittle-*)
-               basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+       power)
+               cpu=power
+               vendor=ibm
                ;;
-       ppc64)  basic_machine=powerpc64-unknown
+       ps2)
+               cpu=i386
+               vendor=ibm
                ;;
-       ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+       rm[46]00)
+               cpu=mips
+               vendor=siemens
                ;;
-       ppc64le | powerpc64little)
-               basic_machine=powerpc64le-unknown
+       rtpc | rtpc-*)
+               cpu=romp
+               vendor=ibm
                ;;
-       ppc64le-* | powerpc64little-*)
-               basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+       sde)
+               cpu=mipsisa32
+               vendor=sde
+               basic_os=${basic_os:-elf}
                ;;
-       ps2)
-               basic_machine=i386-ibm
+       simso-wrs)
+               cpu=sparclite
+               vendor=wrs
+               basic_os=vxworks
                ;;
-       pw32)
-               basic_machine=i586-unknown
-               os=-pw32
+       tower | tower-32)
+               cpu=m68k
+               vendor=ncr
                ;;
-       rdos | rdos64)
-               basic_machine=x86_64-pc
-               os=-rdos
+       vpp*|vx|vx-*)
+               cpu=f301
+               vendor=fujitsu
                ;;
-       rdos32)
-               basic_machine=i386-pc
-               os=-rdos
+       w65)
+               cpu=w65
+               vendor=wdc
                ;;
-       rom68k)
-               basic_machine=m68k-rom68k
-               os=-coff
+       w89k-*)
+               cpu=hppa1.1
+               vendor=winbond
+               basic_os=proelf
                ;;
-       rm[46]00)
-               basic_machine=mips-siemens
+       none)
+               cpu=none
+               vendor=none
                ;;
-       rtpc | rtpc-*)
-               basic_machine=romp-ibm
+       leon|leon[3-9])
+               cpu=sparc
+               vendor=$basic_machine
                ;;
-       s390 | s390-*)
-               basic_machine=s390-ibm
+       leon-*|leon[3-9]-*)
+               cpu=sparc
+               vendor=`echo "$basic_machine" | sed 's/-.*//'`
                ;;
-       s390x | s390x-*)
-               basic_machine=s390x-ibm
+
+       *-*)
+               # shellcheck disable=SC2162
+               saved_IFS=$IFS
+               IFS="-" read cpu vendor <<EOF
+$basic_machine
+EOF
+               IFS=$saved_IFS
                ;;
-       sa29200)
-               basic_machine=a29k-amd
-               os=-udi
+       # We use `pc' rather than `unknown'
+       # because (1) that's what they normally are, and
+       # (2) the word "unknown" tends to confuse beginning users.
+       i*86 | x86_64)
+               cpu=$basic_machine
+               vendor=pc
                ;;
-       sb1)
-               basic_machine=mipsisa64sb1-unknown
+       # These rules are duplicated from below for sake of the special case above;
+       # i.e. things that normalized to x86 arches should also default to "pc"
+       pc98)
+               cpu=i386
+               vendor=pc
                ;;
-       sb1el)
-               basic_machine=mipsisa64sb1el-unknown
+       x64 | amd64)
+               cpu=x86_64
+               vendor=pc
                ;;
-       sde)
-               basic_machine=mipsisa32-sde
-               os=-elf
+       # Recognize the basic CPU types without company name.
+       *)
+               cpu=$basic_machine
+               vendor=unknown
                ;;
-       sei)
-               basic_machine=mips-sei
-               os=-seiux
+esac
+
+unset -v basic_machine
+
+# Decode basic machines in the full and proper CPU-Company form.
+case $cpu-$vendor in
+       # Here we handle the default manufacturer of certain CPU types in canonical form. It is in
+       # some cases the only manufacturer, in others, it is the most popular.
+       craynv-unknown)
+               vendor=cray
+               basic_os=${basic_os:-unicosmp}
                ;;
-       sequent)
-               basic_machine=i386-sequent
+       c90-unknown | c90-cray)
+               vendor=cray
+               basic_os=${Basic_os:-unicos}
                ;;
-       sh5el)
-               basic_machine=sh5le-unknown
+       fx80-unknown)
+               vendor=alliant
                ;;
-       simso-wrs)
-               basic_machine=sparclite-wrs
-               os=-vxworks
+       romp-unknown)
+               vendor=ibm
                ;;
-       sps7)
-               basic_machine=m68k-bull
-               os=-sysv2
+       mmix-unknown)
+               vendor=knuth
                ;;
-       spur)
-               basic_machine=spur-unknown
+       microblaze-unknown | microblazeel-unknown)
+               vendor=xilinx
                ;;
-       st2000)
-               basic_machine=m68k-tandem
+       rs6000-unknown)
+               vendor=ibm
                ;;
-       stratus)
-               basic_machine=i860-stratus
-               os=-sysv4
+       vax-unknown)
+               vendor=dec
                ;;
-       strongarm-* | thumb-*)
-               basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+       pdp11-unknown)
+               vendor=dec
                ;;
-       sun2)
-               basic_machine=m68000-sun
+       we32k-unknown)
+               vendor=att
                ;;
-       sun2os3)
-               basic_machine=m68000-sun
-               os=-sunos3
+       cydra-unknown)
+               vendor=cydrome
                ;;
-       sun2os4)
-               basic_machine=m68000-sun
-               os=-sunos4
+       i370-ibm*)
+               vendor=ibm
                ;;
-       sun3os3)
-               basic_machine=m68k-sun
-               os=-sunos3
+       orion-unknown)
+               vendor=highlevel
                ;;
-       sun3os4)
-               basic_machine=m68k-sun
-               os=-sunos4
+       xps-unknown | xps100-unknown)
+               cpu=xps100
+               vendor=honeywell
                ;;
-       sun4os3)
-               basic_machine=sparc-sun
-               os=-sunos3
+
+       # Here we normalize CPU types with a missing or matching vendor
+       dpx20-unknown | dpx20-bull)
+               cpu=rs6000
+               vendor=bull
+               basic_os=${basic_os:-bosx}
                ;;
-       sun4os4)
-               basic_machine=sparc-sun
-               os=-sunos4
+
+       # Here we normalize CPU types irrespective of the vendor
+       amd64-*)
+               cpu=x86_64
                ;;
-       sun4sol2)
-               basic_machine=sparc-sun
-               os=-solaris2
+       blackfin-*)
+               cpu=bfin
+               basic_os=linux
                ;;
-       sun3 | sun3-*)
-               basic_machine=m68k-sun
+       c54x-*)
+               cpu=tic54x
                ;;
-       sun4)
-               basic_machine=sparc-sun
+       c55x-*)
+               cpu=tic55x
                ;;
-       sun386 | sun386i | roadrunner)
-               basic_machine=i386-sun
+       c6x-*)
+               cpu=tic6x
                ;;
-       sv1)
-               basic_machine=sv1-cray
-               os=-unicos
+       e500v[12]-*)
+               cpu=powerpc
+               basic_os=${basic_os}"spe"
                ;;
-       symmetry)
-               basic_machine=i386-sequent
-               os=-dynix
+       mips3*-*)
+               cpu=mips64
                ;;
-       t3e)
-               basic_machine=alphaev5-cray
-               os=-unicos
+       ms1-*)
+               cpu=mt
                ;;
-       t90)
-               basic_machine=t90-cray
-               os=-unicos
+       m68knommu-*)
+               cpu=m68k
+               basic_os=linux
                ;;
-       tile*)
-               basic_machine=$basic_machine-unknown
-               os=-linux-gnu
+       m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*)
+               cpu=s12z
                ;;
-       tx39)
-               basic_machine=mipstx39-unknown
+       openrisc-*)
+               cpu=or32
                ;;
-       tx39el)
-               basic_machine=mipstx39el-unknown
+       parisc-*)
+               cpu=hppa
+               basic_os=linux
                ;;
-       toad1)
-               basic_machine=pdp10-xkl
-               os=-tops20
+       pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+               cpu=i586
                ;;
-       tower | tower-32)
-               basic_machine=m68k-ncr
+       pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*)
+               cpu=i686
                ;;
-       tpf)
-               basic_machine=s390x-ibm
-               os=-tpf
+       pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+               cpu=i686
                ;;
-       udi29k)
-               basic_machine=a29k-amd
-               os=-udi
+       pentium4-*)
+               cpu=i786
                ;;
-       ultra3)
-               basic_machine=a29k-nyu
-               os=-sym1
+       pc98-*)
+               cpu=i386
                ;;
-       v810 | necv810)
-               basic_machine=v810-nec
-               os=-none
+       ppc-* | ppcbe-*)
+               cpu=powerpc
                ;;
-       vaxv)
-               basic_machine=vax-dec
-               os=-sysv
+       ppcle-* | powerpclittle-*)
+               cpu=powerpcle
                ;;
-       vms)
-               basic_machine=vax-dec
-               os=-vms
+       ppc64-*)
+               cpu=powerpc64
                ;;
-       vpp*|vx|vx-*)
-               basic_machine=f301-fujitsu
+       ppc64le-* | powerpc64little-*)
+               cpu=powerpc64le
                ;;
-       vxworks960)
-               basic_machine=i960-wrs
-               os=-vxworks
+       sb1-*)
+               cpu=mipsisa64sb1
                ;;
-       vxworks68)
-               basic_machine=m68k-wrs
-               os=-vxworks
+       sb1el-*)
+               cpu=mipsisa64sb1el
                ;;
-       vxworks29k)
-               basic_machine=a29k-wrs
-               os=-vxworks
+       sh5e[lb]-*)
+               cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'`
                ;;
-       w65*)
-               basic_machine=w65-wdc
-               os=-none
+       spur-*)
+               cpu=spur
                ;;
-       w89k-*)
-               basic_machine=hppa1.1-winbond
-               os=-proelf
+       strongarm-* | thumb-*)
+               cpu=arm
                ;;
-       x64)
-               basic_machine=x86_64-pc
+       tx39-*)
+               cpu=mipstx39
                ;;
-       xbox)
-               basic_machine=i686-pc
-               os=-mingw32
+       tx39el-*)
+               cpu=mipstx39el
                ;;
-       xps | xps100)
-               basic_machine=xps100-honeywell
+       x64-*)
+               cpu=x86_64
                ;;
        xscale-* | xscalee[bl]-*)
-               basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'`
-               ;;
-       ymp)
-               basic_machine=ymp-cray
-               os=-unicos
+               cpu=`echo "$cpu" | sed 's/^xscale/arm/'`
                ;;
-       none)
-               basic_machine=none-none
-               os=-none
+       arm64-*)
+               cpu=aarch64
                ;;
 
-# Here we handle the default manufacturer of certain CPU types.  It is in
-# some cases the only manufacturer, in others, it is the most popular.
-       w89k)
-               basic_machine=hppa1.1-winbond
-               ;;
-       op50n)
-               basic_machine=hppa1.1-oki
-               ;;
-       op60c)
-               basic_machine=hppa1.1-oki
-               ;;
-       romp)
-               basic_machine=romp-ibm
-               ;;
-       mmix)
-               basic_machine=mmix-knuth
+       # Recognize the canonical CPU Types that limit and/or modify the
+       # company names they are paired with.
+       cr16-*)
+               basic_os=${basic_os:-elf}
                ;;
-       rs6000)
-               basic_machine=rs6000-ibm
+       crisv32-* | etraxfs*-*)
+               cpu=crisv32
+               vendor=axis
                ;;
-       vax)
-               basic_machine=vax-dec
+       cris-* | etrax*-*)
+               cpu=cris
+               vendor=axis
                ;;
-       pdp11)
-               basic_machine=pdp11-dec
+       crx-*)
+               basic_os=${basic_os:-elf}
                ;;
-       we32k)
-               basic_machine=we32k-att
+       neo-tandem)
+               cpu=neo
+               vendor=tandem
                ;;
-       sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
-               basic_machine=sh-unknown
+       nse-tandem)
+               cpu=nse
+               vendor=tandem
                ;;
-       cydra)
-               basic_machine=cydra-cydrome
+       nsr-tandem)
+               cpu=nsr
+               vendor=tandem
                ;;
-       orion)
-               basic_machine=orion-highlevel
+       nsv-tandem)
+               cpu=nsv
+               vendor=tandem
                ;;
-       orion105)
-               basic_machine=clipper-highlevel
+       nsx-tandem)
+               cpu=nsx
+               vendor=tandem
                ;;
-       mac | mpw | mac-mpw)
-               basic_machine=m68k-apple
+       mipsallegrexel-sony)
+               cpu=mipsallegrexel
+               vendor=sony
                ;;
-       pmac | pmac-mpw)
-               basic_machine=powerpc-apple
-               ;;
-       *-unknown)
-               # Make sure to match an already-canonicalized machine name.
+       tile*-*)
+               basic_os=${basic_os:-linux-gnu}
                ;;
+
        *)
-               echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
-               exit 1
+               # Recognize the canonical CPU types that are allowed with any
+               # company name.
+               case $cpu in
+                       1750a | 580 \
+                       | a29k \
+                       | aarch64 | aarch64_be \
+                       | abacus \
+                       | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \
+                       | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \
+                       | alphapca5[67] | alpha64pca5[67] \
+                       | am33_2.0 \
+                       | amdgcn \
+                       | arc | arceb | arc32 | arc64 \
+                       | arm | arm[lb]e | arme[lb] | armv* \
+                       | avr | avr32 \
+                       | asmjs \
+                       | ba \
+                       | be32 | be64 \
+                       | bfin | bpf | bs2000 \
+                       | c[123]* | c30 | [cjt]90 | c4x \
+                       | c8051 | clipper | craynv | csky | cydra \
+                       | d10v | d30v | dlx | dsp16xx \
+                       | e2k | elxsi | epiphany \
+                       | f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \
+                       | h8300 | h8500 \
+                       | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+                       | hexagon \
+                       | i370 | i*86 | i860 | i960 | ia16 | ia64 \
+                       | ip2k | iq2000 \
+                       | k1om \
+                       | le32 | le64 \
+                       | lm32 \
+                       | loongarch32 | loongarch64 | loongarchx32 \
+                       | m32c | m32r | m32rle \
+                       | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \
+                       | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \
+                       | m88110 | m88k | maxq | mb | mcore | mep | metag \
+                       | microblaze | microblazeel \
+                       | mips | mipsbe | mipseb | mipsel | mipsle \
+                       | mips16 \
+                       | mips64 | mips64eb | mips64el \
+                       | mips64octeon | mips64octeonel \
+                       | mips64orion | mips64orionel \
+                       | mips64r5900 | mips64r5900el \
+                       | mips64vr | mips64vrel \
+                       | mips64vr4100 | mips64vr4100el \
+                       | mips64vr4300 | mips64vr4300el \
+                       | mips64vr5000 | mips64vr5000el \
+                       | mips64vr5900 | mips64vr5900el \
+                       | mipsisa32 | mipsisa32el \
+                       | mipsisa32r2 | mipsisa32r2el \
+                       | mipsisa32r3 | mipsisa32r3el \
+                       | mipsisa32r5 | mipsisa32r5el \
+                       | mipsisa32r6 | mipsisa32r6el \
+                       | mipsisa64 | mipsisa64el \
+                       | mipsisa64r2 | mipsisa64r2el \
+                       | mipsisa64r3 | mipsisa64r3el \
+                       | mipsisa64r5 | mipsisa64r5el \
+                       | mipsisa64r6 | mipsisa64r6el \
+                       | mipsisa64sb1 | mipsisa64sb1el \
+                       | mipsisa64sr71k | mipsisa64sr71kel \
+                       | mipsr5900 | mipsr5900el \
+                       | mipstx39 | mipstx39el \
+                       | mmix \
+                       | mn10200 | mn10300 \
+                       | moxie \
+                       | mt \
+                       | msp430 \
+                       | nds32 | nds32le | nds32be \
+                       | nfp \
+                       | nios | nios2 | nios2eb | nios2el \
+                       | none | np1 | ns16k | ns32k | nvptx \
+                       | open8 \
+                       | or1k* \
+                       | or32 \
+                       | orion \
+                       | picochip \
+                       | pdp10 | pdp11 | pj | pjl | pn | power \
+                       | powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \
+                       | pru \
+                       | pyramid \
+                       | riscv | riscv32 | riscv32be | riscv64 | riscv64be \
+                       | rl78 | romp | rs6000 | rx \
+                       | s390 | s390x \
+                       | score \
+                       | sh | shl \
+                       | sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \
+                       | sh[1234]e[lb] |  sh[12345][lb]e | sh[23]ele | sh64 | sh64le \
+                       | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \
+                       | sparclite \
+                       | sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \
+                       | spu \
+                       | tahoe \
+                       | thumbv7* \
+                       | tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \
+                       | tron \
+                       | ubicom32 \
+                       | v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \
+                       | vax \
+                       | visium \
+                       | w65 \
+                       | wasm32 | wasm64 \
+                       | we32k \
+                       | x86 | x86_64 | xc16x | xgate | xps100 \
+                       | xstormy16 | xtensa* \
+                       | ymp \
+                       | z8k | z80)
+                               ;;
+
+                       *)
+                               echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2
+                               exit 1
+                               ;;
+               esac
                ;;
 esac
 
 # Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
-       *-digital*)
-               basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'`
+case $vendor in
+       digital*)
+               vendor=dec
                ;;
-       *-commodore*)
-               basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'`
+       commodore*)
+               vendor=cbm
                ;;
        *)
                ;;
@@ -1338,203 +1301,215 @@ esac
 
 # Decode manufacturer-specific aliases for certain operating systems.
 
-if [ x"$os" != x"" ]
+if test x$basic_os != x
 then
+
+# First recognize some ad-hoc caes, or perhaps split kernel-os, or else just
+# set os.
+case $basic_os in
+       gnu/linux*)
+               kernel=linux
+               os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'`
+               ;;
+       os2-emx)
+               kernel=os2
+               os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'`
+               ;;
+       nto-qnx*)
+               kernel=nto
+               os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'`
+               ;;
+       *-*)
+               # shellcheck disable=SC2162
+               saved_IFS=$IFS
+               IFS="-" read kernel os <<EOF
+$basic_os
+EOF
+               IFS=$saved_IFS
+               ;;
+       # Default OS when just kernel was specified
+       nto*)
+               kernel=nto
+               os=`echo "$basic_os" | sed -e 's|nto|qnx|'`
+               ;;
+       linux*)
+               kernel=linux
+               os=`echo "$basic_os" | sed -e 's|linux|gnu|'`
+               ;;
+       *)
+               kernel=
+               os=$basic_os
+               ;;
+esac
+
+# Now, normalize the OS (knowing we just have one component, it's not a kernel,
+# etc.)
 case $os in
        # First match some system type aliases that might get confused
        # with valid system types.
-       # -solaris* is a basic system type, with this one exception.
-       -auroraux)
-               os=-auroraux
+       # solaris* is a basic system type, with this one exception.
+       auroraux)
+               os=auroraux
                ;;
-       -solaris1 | -solaris1.*)
-               os=`echo $os | sed -e 's|solaris1|sunos4|'`
+       bluegene*)
+               os=cnk
                ;;
-       -solaris)
-               os=-solaris2
+       solaris1 | solaris1.*)
+               os=`echo "$os" | sed -e 's|solaris1|sunos4|'`
                ;;
-       -unixware*)
-               os=-sysv4.2uw
+       solaris)
+               os=solaris2
                ;;
-       -gnu/linux*)
-               os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+       unixware*)
+               os=sysv4.2uw
                ;;
        # es1800 is here to avoid being matched by es* (a different OS)
-       -es1800*)
-               os=-ose
+       es1800*)
+               os=ose
                ;;
-       # Now accept the basic system types.
-       # The portable systems comes first.
-       # Each alternative MUST end in a * to match a version number.
-       # -sysv* is not here because it comes later, after sysvr4.
-       -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
-             | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
-             | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
-             | -sym* | -kopensolaris* | -plan9* \
-             | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
-             | -aos* | -aros* | -cloudabi* | -sortix* \
-             | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
-             | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
-             | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \
-             | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
-             | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
-             | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
-             | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
-             | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* | -hcos* \
-             | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \
-             | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-             | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
-             | -linux-newlib* | -linux-musl* | -linux-uclibc* \
-             | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
-             | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \
-             | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
-             | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
-             | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
-             | -morphos* | -superux* | -rtmk* | -windiss* \
-             | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
-             | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
-             | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \
-             | -midnightbsd*)
-       # Remember, each alternative MUST END IN *, to match a version number.
-               ;;
-       -qnx*)
-               case $basic_machine in
-                   x86-* | i*86-*)
-                       ;;
-                   *)
-                       os=-nto$os
-                       ;;
-               esac
+       # Some version numbers need modification
+       chorusos*)
+               os=chorusos
                ;;
-       -nto-qnx*)
+       isc)
+               os=isc2.2
                ;;
-       -nto*)
-               os=`echo $os | sed -e 's|nto|nto-qnx|'`
+       sco6)
+               os=sco5v6
                ;;
-       -sim | -xray | -os68k* | -v88r* \
-             | -windows* | -osx | -abug | -netware* | -os9* \
-             | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+       sco5)
+               os=sco3.2v5
                ;;
-       -mac*)
-               os=`echo "$os" | sed -e 's|mac|macos|'`
+       sco4)
+               os=sco3.2v4
                ;;
-       -linux-dietlibc)
-               os=-linux-dietlibc
+       sco3.2.[4-9]*)
+               os=`echo "$os" | sed -e 's/sco3.2./sco3.2v/'`
                ;;
-       -linux*)
-               os=`echo $os | sed -e 's|linux|linux-gnu|'`
+       sco*v* | scout)
+               # Don't match below
                ;;
-       -sunos5*)
-               os=`echo "$os" | sed -e 's|sunos5|solaris2|'`
+       sco*)
+               os=sco3.2v2
                ;;
-       -sunos6*)
-               os=`echo "$os" | sed -e 's|sunos6|solaris3|'`
+       psos*)
+               os=psos
                ;;
-       -opened*)
-               os=-openedition
+       qnx*)
+               os=qnx
                ;;
-       -os400*)
-               os=-os400
+       hiux*)
+               os=hiuxwe2
                ;;
-       -wince*)
-               os=-wince
+       lynx*178)
+               os=lynxos178
                ;;
-       -utek*)
-               os=-bsd
+       lynx*5)
+               os=lynxos5
                ;;
-       -dynix*)
-               os=-bsd
+       lynxos*)
+               # don't get caught up in next wildcard
                ;;
-       -acis*)
-               os=-aos
+       lynx*)
+               os=lynxos
                ;;
-       -atheos*)
-               os=-atheos
+       mac[0-9]*)
+               os=`echo "$os" | sed -e 's|mac|macos|'`
                ;;
-       -syllable*)
-               os=-syllable
+       opened*)
+               os=openedition
                ;;
-       -386bsd)
-               os=-bsd
+       os400*)
+               os=os400
                ;;
-       -ctix* | -uts*)
-               os=-sysv
+       sunos5*)
+               os=`echo "$os" | sed -e 's|sunos5|solaris2|'`
                ;;
-       -nova*)
-               os=-rtmk-nova
+       sunos6*)
+               os=`echo "$os" | sed -e 's|sunos6|solaris3|'`
                ;;
-       -ns2)
-               os=-nextstep2
+       wince*)
+               os=wince
                ;;
-       -nsk*)
-               os=-nsk
+       utek*)
+               os=bsd
                ;;
-       # Preserve the version number of sinix5.
-       -sinix5.*)
-               os=`echo $os | sed -e 's|sinix|sysv|'`
+       dynix*)
+               os=bsd
                ;;
-       -sinix*)
-               os=-sysv4
+       acis*)
+               os=aos
                ;;
-       -tpf*)
-               os=-tpf
+       atheos*)
+               os=atheos
                ;;
-       -triton*)
-               os=-sysv3
+       syllable*)
+               os=syllable
+               ;;
+       386bsd)
+               os=bsd
+               ;;
+       ctix* | uts*)
+               os=sysv
+               ;;
+       nova*)
+               os=rtmk-nova
+               ;;
+       ns2)
+               os=nextstep2
+               ;;
+       # Preserve the version number of sinix5.
+       sinix5.*)
+               os=`echo "$os" | sed -e 's|sinix|sysv|'`
                ;;
-       -oss*)
-               os=-sysv3
+       sinix*)
+               os=sysv4
                ;;
-       -svr4*)
-               os=-sysv4
+       tpf*)
+               os=tpf
                ;;
-       -svr3)
-               os=-sysv3
+       triton*)
+               os=sysv3
                ;;
-       -sysvr4)
-               os=-sysv4
+       oss*)
+               os=sysv3
                ;;
-       # This must come after -sysvr4.
-       -sysv*)
+       svr4*)
+               os=sysv4
                ;;
-       -ose*)
-               os=-ose
+       svr3)
+               os=sysv3
                ;;
-       -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
-               os=-mint
+       sysvr4)
+               os=sysv4
                ;;
-       -zvmoe)
-               os=-zvmoe
+       ose*)
+               os=ose
                ;;
-       -dicos*)
-               os=-dicos
+       *mint | mint[0-9]* | *MiNT | MiNT[0-9]*)
+               os=mint
                ;;
-       -pikeos*)
+       dicos*)
+               os=dicos
+               ;;
+       pikeos*)
                # Until real need of OS specific support for
                # particular features comes up, bare metal
                # configurations are quite functional.
-               case $basic_machine in
+               case $cpu in
                    arm*)
-                       os=-eabi
+                       os=eabi
                        ;;
                    *)
-                       os=-elf
+                       os=elf
                        ;;
                esac
                ;;
-       -nacl*)
-               ;;
-       -ios)
-               ;;
-       -none)
-               ;;
        *)
-               # Get rid of the `-' at the beginning of $os.
-               os=`echo $os | sed 's/[^-]*-//'`
-               echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2
-               exit 1
+               # No normalization, but not necessarily accepted, that comes below.
                ;;
 esac
+
 else
 
 # Here we handle the default operating systems that come with various machines.
@@ -1547,254 +1522,358 @@ else
 # will signal an error saying that MANUFACTURER isn't an operating
 # system, and we'll never get to this point.
 
-case $basic_machine in
+kernel=
+case $cpu-$vendor in
        score-*)
-               os=-elf
+               os=elf
                ;;
        spu-*)
-               os=-elf
+               os=elf
                ;;
        *-acorn)
-               os=-riscix1.2
+               os=riscix1.2
                ;;
        arm*-rebel)
-               os=-linux
+               kernel=linux
+               os=gnu
                ;;
        arm*-semi)
-               os=-aout
+               os=aout
                ;;
        c4x-* | tic4x-*)
-               os=-coff
+               os=coff
                ;;
        c8051-*)
-               os=-elf
+               os=elf
+               ;;
+       clipper-intergraph)
+               os=clix
                ;;
        hexagon-*)
-               os=-elf
+               os=elf
                ;;
        tic54x-*)
-               os=-coff
+               os=coff
                ;;
        tic55x-*)
-               os=-coff
+               os=coff
                ;;
        tic6x-*)
-               os=-coff
+               os=coff
                ;;
        # This must come before the *-dec entry.
        pdp10-*)
-               os=-tops20
+               os=tops20
                ;;
        pdp11-*)
-               os=-none
+               os=none
                ;;
        *-dec | vax-*)
-               os=-ultrix4.2
+               os=ultrix4.2
                ;;
        m68*-apollo)
-               os=-domain
+               os=domain
                ;;
        i386-sun)
-               os=-sunos4.0.2
+               os=sunos4.0.2
                ;;
        m68000-sun)
-               os=-sunos3
+               os=sunos3
                ;;
        m68*-cisco)
-               os=-aout
+               os=aout
                ;;
        mep-*)
-               os=-elf
+               os=elf
                ;;
        mips*-cisco)
-               os=-elf
+               os=elf
                ;;
        mips*-*)
-               os=-elf
+               os=elf
                ;;
        or32-*)
-               os=-coff
+               os=coff
                ;;
        *-tti)  # must be before sparc entry or we get the wrong os.
-               os=-sysv3
+               os=sysv3
                ;;
        sparc-* | *-sun)
-               os=-sunos4.1.1
+               os=sunos4.1.1
                ;;
        pru-*)
-               os=-elf
+               os=elf
                ;;
        *-be)
-               os=-beos
+               os=beos
                ;;
        *-ibm)
-               os=-aix
+               os=aix
                ;;
        *-knuth)
-               os=-mmixware
+               os=mmixware
                ;;
        *-wec)
-               os=-proelf
+               os=proelf
                ;;
        *-winbond)
-               os=-proelf
+               os=proelf
                ;;
        *-oki)
-               os=-proelf
+               os=proelf
                ;;
        *-hp)
-               os=-hpux
+               os=hpux
                ;;
        *-hitachi)
-               os=-hiux
+               os=hiux
                ;;
        i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
-               os=-sysv
+               os=sysv
                ;;
        *-cbm)
-               os=-amigaos
+               os=amigaos
                ;;
        *-dg)
-               os=-dgux
+               os=dgux
                ;;
        *-dolphin)
-               os=-sysv3
+               os=sysv3
                ;;
        m68k-ccur)
-               os=-rtu
+               os=rtu
                ;;
        m88k-omron*)
-               os=-luna
+               os=luna
                ;;
        *-next)
-               os=-nextstep
+               os=nextstep
                ;;
        *-sequent)
-               os=-ptx
+               os=ptx
                ;;
        *-crds)
-               os=-unos
+               os=unos
                ;;
        *-ns)
-               os=-genix
+               os=genix
                ;;
        i370-*)
-               os=-mvs
+               os=mvs
                ;;
        *-gould)
-               os=-sysv
+               os=sysv
                ;;
        *-highlevel)
-               os=-bsd
+               os=bsd
                ;;
        *-encore)
-               os=-bsd
+               os=bsd
                ;;
        *-sgi)
-               os=-irix
+               os=irix
                ;;
        *-siemens)
-               os=-sysv4
+               os=sysv4
                ;;
        *-masscomp)
-               os=-rtu
+               os=rtu
                ;;
        f30[01]-fujitsu | f700-fujitsu)
-               os=-uxpv
+               os=uxpv
                ;;
        *-rom68k)
-               os=-coff
+               os=coff
                ;;
        *-*bug)
-               os=-coff
+               os=coff
                ;;
        *-apple)
-               os=-macos
+               os=macos
                ;;
        *-atari*)
-               os=-mint
+               os=mint
+               ;;
+       *-wrs)
+               os=vxworks
                ;;
        *)
-               os=-none
+               os=none
                ;;
 esac
+
 fi
 
+# Now, validate our (potentially fixed-up) OS.
+case $os in
+       # Sometimes we do "kernel-libc", so those need to count as OSes.
+       musl* | newlib* | relibc* | uclibc*)
+               ;;
+       # Likewise for "kernel-abi"
+       eabi* | gnueabi*)
+               ;;
+       # VxWorks passes extra cpu info in the 4th filed.
+       simlinux | simwindows | spe)
+               ;;
+       # Now accept the basic system types.
+       # The portable systems comes first.
+       # Each alternative MUST end in a * to match a version number.
+       gnu* | android* | bsd* | mach* | minix* | genix* | ultrix* | irix* \
+            | *vms* | esix* | aix* | cnk* | sunos | sunos[34]* \
+            | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \
+            | sym* |  plan9* | psp* | sim* | xray* | os68k* | v88r* \
+            | hiux* | abug | nacl* | netware* | windows* \
+            | os9* | macos* | osx* | ios* \
+            | mpw* | magic* | mmixware* | mon960* | lnews* \
+            | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \
+            | aos* | aros* | cloudabi* | sortix* | twizzler* \
+            | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \
+            | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \
+            | mirbsd* | netbsd* | dicos* | openedition* | ose* \
+            | bitrig* | openbsd* | secbsd* | solidbsd* | libertybsd* | os108* \
+            | ekkobsd* | freebsd* | riscix* | lynxos* | os400* \
+            | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \
+            | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \
+            | udi* | lites* | ieee* | go32* | aux* | hcos* \
+            | chorusrdb* | cegcc* | glidix* | serenity* \
+            | cygwin* | msys* | pe* | moss* | proelf* | rtems* \
+            | midipix* | mingw32* | mingw64* | mint* \
+            | uxpv* | beos* | mpeix* | udk* | moxiebox* \
+            | interix* | uwin* | mks* | rhapsody* | darwin* \
+            | openstep* | oskit* | conix* | pw32* | nonstopux* \
+            | storm-chaos* | tops10* | tenex* | tops20* | its* \
+            | os2* | vos* | palmos* | uclinux* | nucleus* | morphos* \
+            | scout* | superux* | sysv* | rtmk* | tpf* | windiss* \
+            | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \
+            | skyos* | haiku* | rdos* | toppers* | drops* | es* \
+            | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
+            | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
+            | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr*)
+               ;;
+       # This one is extra strict with allowed versions
+       sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
+               # Don't forget version if it is 3.2v4 or newer.
+               ;;
+       none)
+               ;;
+       *)
+               echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+
+# As a final step for OS-related things, validate the OS-kernel combination
+# (given a valid OS), if there is a kernel.
+case $kernel-$os in
+       linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \
+                  | linux-musl* | linux-relibc* | linux-uclibc* )
+               ;;
+       uclinux-uclibc* )
+               ;;
+       -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* )
+               # These are just libc implementations, not actual OSes, and thus
+               # require a kernel.
+               echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2
+               exit 1
+               ;;
+       kfreebsd*-gnu* | kopensolaris*-gnu*)
+               ;;
+       vxworks-simlinux | vxworks-simwindows | vxworks-spe)
+               ;;
+       nto-qnx*)
+               ;;
+       os2-emx)
+               ;;
+       *-eabi* | *-gnueabi*)
+               ;;
+       -*)
+               # Blank kernel with real OS is always fine.
+               ;;
+       *-*)
+               echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2
+               exit 1
+               ;;
+esac
+
 # Here we handle the case where we know the os, and the CPU type, but not the
 # manufacturer.  We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
-       *-unknown)
-               case $os in
-                       -riscix*)
+case $vendor in
+       unknown)
+               case $cpu-$os in
+                       *-riscix*)
                                vendor=acorn
                                ;;
-                       -sunos*)
+                       *-sunos*)
                                vendor=sun
                                ;;
-                       -cnk*|-aix*)
+                       *-cnk* | *-aix*)
                                vendor=ibm
                                ;;
-                       -beos*)
+                       *-beos*)
                                vendor=be
                                ;;
-                       -hpux*)
+                       *-hpux*)
                                vendor=hp
                                ;;
-                       -mpeix*)
+                       *-mpeix*)
                                vendor=hp
                                ;;
-                       -hiux*)
+                       *-hiux*)
                                vendor=hitachi
                                ;;
-                       -unos*)
+                       *-unos*)
                                vendor=crds
                                ;;
-                       -dgux*)
+                       *-dgux*)
                                vendor=dg
                                ;;
-                       -luna*)
+                       *-luna*)
                                vendor=omron
                                ;;
-                       -genix*)
+                       *-genix*)
                                vendor=ns
                                ;;
-                       -mvs* | -opened*)
+                       *-clix*)
+                               vendor=intergraph
+                               ;;
+                       *-mvs* | *-opened*)
+                               vendor=ibm
+                               ;;
+                       *-os400*)
                                vendor=ibm
                                ;;
-                       -os400*)
+                       s390-* | s390x-*)
                                vendor=ibm
                                ;;
-                       -ptx*)
+                       *-ptx*)
                                vendor=sequent
                                ;;
-                       -tpf*)
+                       *-tpf*)
                                vendor=ibm
                                ;;
-                       -vxsim* | -vxworks* | -windiss*)
+                       *-vxsim* | *-vxworks* | *-windiss*)
                                vendor=wrs
                                ;;
-                       -aux*)
+                       *-aux*)
                                vendor=apple
                                ;;
-                       -hms*)
+                       *-hms*)
                                vendor=hitachi
                                ;;
-                       -mpw* | -macos*)
+                       *-mpw* | *-macos*)
                                vendor=apple
                                ;;
-                       -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+                       *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*)
                                vendor=atari
                                ;;
-                       -vos*)
+                       *-vos*)
                                vendor=stratus
                                ;;
                esac
-               basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"`
                ;;
 esac
 
-echo "$basic_machine$os"
+echo "$cpu-$vendor-${kernel:+$kernel-}$os"
 exit
 
 # Local variables:
index 33ecb16..d078887 100755 (executable)
--- a/configure
+++ b/configure
@@ -788,6 +788,7 @@ infodir
 docdir
 oldincludedir
 includedir
+runstatedir
 localstatedir
 sharedstatedir
 sysconfdir
@@ -905,6 +906,7 @@ datadir='${datarootdir}'
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
 docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -1157,6 +1159,15 @@ do
   | -silent | --silent | --silen | --sile | --sil)
     silent=yes ;;
 
+  -runstatedir | --runstatedir | --runstatedi | --runstated \
+  | --runstate | --runstat | --runsta | --runst | --runs \
+  | --run | --ru | --r)
+    ac_prev=runstatedir ;;
+  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+  | --run=* | --ru=* | --r=*)
+    runstatedir=$ac_optarg ;;
+
   -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
     ac_prev=sbindir ;;
   -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1294,7 +1305,7 @@ fi
 for ac_var in  exec_prefix prefix bindir sbindir libexecdir datarootdir \
                datadir sysconfdir sharedstatedir localstatedir includedir \
                oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
-               libdir localedir mandir
+               libdir localedir mandir runstatedir
 do
   eval ac_val=\$$ac_var
   # Remove trailing slashes.
@@ -1447,6 +1458,7 @@ Fine tuning of the installation directories:
   --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
   --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
   --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
   --libdir=DIR            object code libraries [EPREFIX/lib]
   --includedir=DIR        C header files [PREFIX/include]
   --oldincludedir=DIR     C header files for non-gcc [/usr/include]
@@ -5354,10 +5366,20 @@ $as_echo "none" >&6; }
 fi
 rm -f conftest.c conftest.out
 
-if test x$PLATFORM_TRIPLET != xdarwin; then
-  MULTIARCH=$($CC --print-multiarch 2>/dev/null)
-fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for multiarch" >&5
+$as_echo_n "checking for multiarch... " >&6; }
+case $ac_sys_system in #(
+  Darwin*) :
+    MULTIARCH="" ;; #(
+  FreeBSD*) :
+    MULTIARCH="" ;; #(
+  *) :
+    MULTIARCH=$($CC --print-multiarch 2>/dev/null)
+ ;;
+esac
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MULTIARCH" >&5
+$as_echo "$MULTIARCH" >&6; }
 
 if test x$PLATFORM_TRIPLET != x && test x$MULTIARCH != x; then
   if test x$PLATFORM_TRIPLET != x$MULTIARCH; then
@@ -5367,6 +5389,7 @@ elif test x$PLATFORM_TRIPLET != x && test x$MULTIARCH = x; then
   MULTIARCH=$PLATFORM_TRIPLET
 fi
 
+
 if test x$MULTIARCH != x; then
   MULTIARCH_CPPFLAGS="-DMULTIARCH=\\\"$MULTIARCH\\\""
 fi
@@ -9920,13 +9943,15 @@ $as_echo "no" >&6; }
 fi
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 
+# check for libuuid from util-linux
 save_LIBS=$LIBS
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing uuid_generate_time_safe" >&5
-$as_echo_n "checking for library containing uuid_generate_time_safe... " >&6; }
-if ${ac_cv_search_uuid_generate_time_safe+:} false; then :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_generate_time in -luuid" >&5
+$as_echo_n "checking for uuid_generate_time in -luuid... " >&6; }
+if ${ac_cv_lib_uuid_uuid_generate_time+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  ac_func_search_save_LIBS=$LIBS
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-luuid  $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
@@ -9936,61 +9961,39 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 #ifdef __cplusplus
 extern "C"
 #endif
-char uuid_generate_time_safe ();
+char uuid_generate_time ();
 int
 main ()
 {
-return uuid_generate_time_safe ();
+return uuid_generate_time ();
   ;
   return 0;
 }
 _ACEOF
-for ac_lib in '' uuid; do
-  if test -z "$ac_lib"; then
-    ac_res="none required"
-  else
-    ac_res=-l$ac_lib
-    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
-  fi
-  if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_search_uuid_generate_time_safe=$ac_res
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext
-  if ${ac_cv_search_uuid_generate_time_safe+:} false; then :
-  break
-fi
-done
-if ${ac_cv_search_uuid_generate_time_safe+:} false; then :
-
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_uuid_uuid_generate_time=yes
 else
-  ac_cv_search_uuid_generate_time_safe=no
+  ac_cv_lib_uuid_uuid_generate_time=no
 fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_uuid_generate_time_safe" >&5
-$as_echo "$ac_cv_search_uuid_generate_time_safe" >&6; }
-ac_res=$ac_cv_search_uuid_generate_time_safe
-if test "$ac_res" != no; then :
-  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-
-
-$as_echo "#define HAVE_LIBUUID 1" >>confdefs.h
-,
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_generate_time" >&5
+$as_echo "$ac_cv_lib_uuid_uuid_generate_time" >&6; }
+if test "x$ac_cv_lib_uuid_uuid_generate_time" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBUUID 1
+_ACEOF
 
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  LIBS="-luuid $LIBS"
 
 fi
 
 LIBS=$save_LIBS
 
 # AIX provides support for RFC4122 (uuid) in libc.a starting with AIX 6.1 (anno 2007)
-# FreeBSD and OpenBSD provides support as well
+# FreeBSD and OpenBSD provides support in libc as well.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_create" >&5
 $as_echo_n "checking for uuid_create... " >&6; }
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
index 823252b..431d661 100644 (file)
@@ -882,10 +882,14 @@ else
 fi
 rm -f conftest.c conftest.out
 
-if test x$PLATFORM_TRIPLET != xdarwin; then
-  MULTIARCH=$($CC --print-multiarch 2>/dev/null)
-fi
-AC_SUBST(MULTIARCH)
+AC_MSG_CHECKING([for multiarch])
+AS_CASE([$ac_sys_system],
+  [Darwin*], [MULTIARCH=""],
+  [FreeBSD*], [MULTIARCH=""],
+  [MULTIARCH=$($CC --print-multiarch 2>/dev/null)]
+)
+AC_SUBST([MULTIARCH])
+AC_MSG_RESULT([$MULTIARCH])
 
 if test x$PLATFORM_TRIPLET != x && test x$MULTIARCH != x; then
   if test x$PLATFORM_TRIPLET != x$MULTIARCH; then
@@ -895,6 +899,7 @@ elif test x$PLATFORM_TRIPLET != x && test x$MULTIARCH = x; then
   MULTIARCH=$PLATFORM_TRIPLET
 fi
 AC_SUBST(PLATFORM_TRIPLET)
+
 if test x$MULTIARCH != x; then
   MULTIARCH_CPPFLAGS="-DMULTIARCH=\\\"$MULTIARCH\\\""
 fi
index 63b0138..188faee 100644 (file)
 /* Define to 1 if you have the <libutil.h> header file. */
 #undef HAVE_LIBUTIL_H
 
-/* Define you have libuuid. */
+/* Define to 1 if you have the `uuid' library (-luuid). */
 #undef HAVE_LIBUUID
 
 /* Define if you have the 'link' function. */
index 9a5887b..c6023e1 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -65,6 +65,9 @@ CYGWIN = (HOST_PLATFORM == 'cygwin')
 MACOS = (HOST_PLATFORM == 'darwin')
 AIX = (HOST_PLATFORM.startswith('aix'))
 VXWORKS = ('vxworks' in HOST_PLATFORM)
+CC = os.environ.get("CC")
+if not CC:
+    CC = sysconfig.get_config_var("CC")
 
 
 SUMMARY = """
@@ -443,6 +446,9 @@ class PyBuildExt(build_ext):
 
     def build_extensions(self):
         self.set_srcdir()
+        self.set_compiler_executables()
+        self.configure_compiler()
+        self.init_inc_lib_dirs()
 
         # Detect which modules should be compiled
         self.detect_modules()
@@ -451,7 +457,6 @@ class PyBuildExt(build_ext):
 
         self.update_sources_depends()
         mods_built, mods_disabled = self.remove_configured_extensions()
-        self.set_compiler_executables()
 
         build_ext.build_extensions(self)
 
@@ -631,12 +636,11 @@ class PyBuildExt(build_ext):
     def add_multiarch_paths(self):
         # Debian/Ubuntu multiarch support.
         # https://wiki.ubuntu.com/MultiarchSpec
-        cc = sysconfig.get_config_var('CC')
         tmpfile = os.path.join(self.build_temp, 'multiarch')
         if not os.path.exists(self.build_temp):
             os.makedirs(self.build_temp)
         ret = run_command(
-            '%s -print-multiarch > %s 2> /dev/null' % (cc, tmpfile))
+            '%s -print-multiarch > %s 2> /dev/null' % (CC, tmpfile))
         multiarch_path_component = ''
         try:
             if ret == 0:
@@ -675,11 +679,10 @@ class PyBuildExt(build_ext):
             os.unlink(tmpfile)
 
     def add_cross_compiling_paths(self):
-        cc = sysconfig.get_config_var('CC')
         tmpfile = os.path.join(self.build_temp, 'ccpaths')
         if not os.path.exists(self.build_temp):
             os.makedirs(self.build_temp)
-        ret = run_command('%s -E -v - </dev/null 2>%s 1>/dev/null' % (cc, tmpfile))
+        ret = run_command('%s -E -v - </dev/null 2>%s 1>/dev/null' % (CC, tmpfile))
         is_gcc = False
         is_clang = False
         in_incdirs = False
@@ -1783,9 +1786,6 @@ class PyBuildExt(build_ext):
             self.missing.append('_uuid')
 
     def detect_modules(self):
-        self.configure_compiler()
-        self.init_inc_lib_dirs()
-
         self.detect_simple_extensions()
         if TEST_EXTENSIONS:
             self.detect_test_extensions()