diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 416507a..8fd9eb9 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -109,7 +109,7 @@ jobs: - uses: actions/checkout@v4.1.7 - name: Set up Python - uses: actions/setup-python@v5.1.1 + uses: actions/setup-python@v5.2.0 with: # Appending -dev ensures that we can always build the dev release. # It's a no-op for versions that have been published. @@ -121,7 +121,7 @@ jobs: make ${{ matrix.target }} BUILD_NUMBER=${{ needs.config.outputs.BUILD_NUMBER }} - name: Upload build artefacts - uses: actions/upload-artifact@v4.3.5 + uses: actions/upload-artifact@v4.4.0 with: name: Python-${{ needs.config.outputs.PYTHON_VER }}-${{ matrix.target }}-support.${{ needs.config.outputs.BUILD_NUMBER }}.tar.gz path: dist/Python-${{ needs.config.outputs.PYTHON_VER }}-${{ matrix.target }}-support.${{ needs.config.outputs.BUILD_NUMBER }}.tar.gz @@ -131,20 +131,15 @@ jobs: with: repository: beeware/Python-support-testbed path: Python-support-testbed - # TODO - remove the py3.13 reference option. - ref: py3.13-support - name: Install dependencies if: matrix.run-tests run: | - # TODO - Revert to the development version of Briefcase # Use the development version of Briefcase - # python -m pip install git+https://github.com/beeware/briefcase.git - python -m pip install git+https://github.com/freakboy3742/briefcase.git@version-bumps + python -m pip install git+https://github.com/beeware/briefcase.git - name: Run support testbed check if: matrix.run-tests timeout-minutes: 10 working-directory: Python-support-testbed - # TODO - remove the template_branch option. - run: briefcase run ${{ matrix.target }} Xcode --test ${{ matrix.briefcase-run-args }} -C support_package=\'../dist/Python-${{ needs.config.outputs.PYTHON_VER }}-${{ matrix.target }}-support.${{ needs.config.outputs.BUILD_NUMBER }}.tar.gz\' -C template_branch=\'framework-lib\' + run: briefcase run ${{ matrix.target }} Xcode --test ${{ matrix.briefcase-run-args }} -C support_package=\'../dist/Python-${{ needs.config.outputs.PYTHON_VER }}-${{ matrix.target }}-support.${{ needs.config.outputs.BUILD_NUMBER }}.tar.gz\' diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index e1b09da..e90bf31 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -11,7 +11,7 @@ jobs: - uses: actions/checkout@v4 - name: Set up Python environment - uses: actions/setup-python@v5.1.1 + uses: actions/setup-python@v5.2.0 with: python-version: "3.X" diff --git a/Makefile b/Makefile index c59b6e5..30e3b52 100644 --- a/Makefile +++ b/Makefile @@ -29,8 +29,8 @@ PYTHON_VER=$(basename $(PYTHON_VERSION)) BZIP2_VERSION=1.0.8-1 LIBFFI_VERSION=3.4.6-1 MPDECIMAL_VERSION=4.0.0-1 -OPENSSL_VERSION=3.0.14-1 -XZ_VERSION=5.4.7-1 +OPENSSL_VERSION=3.0.15-1 +XZ_VERSION=5.6.2-1 # Supported OS OS_LIST=macOS iOS tvOS watchOS @@ -158,7 +158,7 @@ downloads/bzip2-$(BZIP2_VERSION)-$(target).tar.gz: $$(BZIP2_LIB-$(target)): downloads/bzip2-$(BZIP2_VERSION)-$(target).tar.gz @echo ">>> Install BZip2 for $(target)" mkdir -p $$(BZIP2_INSTALL-$(target)) - cd $$(BZIP2_INSTALL-$(target)) && tar zxvf $(PROJECT_DIR)/downloads/bzip2-$(BZIP2_VERSION)-$(target).tar.gz + cd $$(BZIP2_INSTALL-$(target)) && tar zxvf $(PROJECT_DIR)/downloads/bzip2-$(BZIP2_VERSION)-$(target).tar.gz --exclude="*.dylib" # Ensure the target is marked as clean. touch $$(BZIP2_LIB-$(target)) @@ -178,7 +178,7 @@ downloads/xz-$(XZ_VERSION)-$(target).tar.gz: $$(XZ_LIB-$(target)): downloads/xz-$(XZ_VERSION)-$(target).tar.gz @echo ">>> Install XZ for $(target)" mkdir -p $$(XZ_INSTALL-$(target)) - cd $$(XZ_INSTALL-$(target)) && tar zxvf $(PROJECT_DIR)/downloads/xz-$(XZ_VERSION)-$(target).tar.gz + cd $$(XZ_INSTALL-$(target)) && tar zxvf $(PROJECT_DIR)/downloads/xz-$(XZ_VERSION)-$(target).tar.gz --exclude="*.dylib" # Ensure the target is marked as clean. touch $$(XZ_LIB-$(target)) @@ -198,7 +198,7 @@ downloads/mpdecimal-$(MPDECIMAL_VERSION)-$(target).tar.gz: $$(MPDECIMAL_LIB-$(target)): downloads/mpdecimal-$(MPDECIMAL_VERSION)-$(target).tar.gz @echo ">>> Install mpdecimal for $(target)" mkdir -p $$(MPDECIMAL_INSTALL-$(target)) - cd $$(MPDECIMAL_INSTALL-$(target)) && tar zxvf $(PROJECT_DIR)/downloads/mpdecimal-$(MPDECIMAL_VERSION)-$(target).tar.gz + cd $$(MPDECIMAL_INSTALL-$(target)) && tar zxvf $(PROJECT_DIR)/downloads/mpdecimal-$(MPDECIMAL_VERSION)-$(target).tar.gz --exclude="*.dylib" # Ensure the target is marked as clean. touch $$(MPDECIMAL_LIB-$(target)) @@ -218,7 +218,7 @@ downloads/openssl-$(OPENSSL_VERSION)-$(target).tar.gz: $$(OPENSSL_SSL_LIB-$(target)): downloads/openssl-$(OPENSSL_VERSION)-$(target).tar.gz @echo ">>> Install OpenSSL for $(target)" mkdir -p $$(OPENSSL_INSTALL-$(target)) - cd $$(OPENSSL_INSTALL-$(target)) && tar zxvf $(PROJECT_DIR)/downloads/openssl-$(OPENSSL_VERSION)-$(target).tar.gz + cd $$(OPENSSL_INSTALL-$(target)) && tar zxvf $(PROJECT_DIR)/downloads/openssl-$(OPENSSL_VERSION)-$(target).tar.gz --exclude="*.dylib" # Ensure the target is marked as clean. touch $$(OPENSSL_SSL_LIB-$(target)) @@ -243,7 +243,7 @@ downloads/libffi-$(LIBFFI_VERSION)-$(target).tar.gz: $$(LIBFFI_LIB-$(target)): downloads/libffi-$(LIBFFI_VERSION)-$(target).tar.gz @echo ">>> Install libFFI for $(target)" mkdir -p $$(LIBFFI_INSTALL-$(target)) - cd $$(LIBFFI_INSTALL-$(target)) && tar zxvf $(PROJECT_DIR)/downloads/libffi-$(LIBFFI_VERSION)-$(target).tar.gz + cd $$(LIBFFI_INSTALL-$(target)) && tar zxvf $(PROJECT_DIR)/downloads/libffi-$(LIBFFI_VERSION)-$(target).tar.gz --exclude="*.dylib" # Ensure the target is marked as clean. touch $$(LIBFFI_LIB-$(target)) diff --git a/README.rst b/README.rst index 0417f0e..eb9dded 100644 --- a/README.rst +++ b/README.rst @@ -4,7 +4,7 @@ Python Apple Support This is a meta-package for building a version of Python that can be embedded into a macOS, iOS, tvOS or watchOS project. -**This branch builds a packaged version of Python 3.11.6**. +**This branch builds a packaged version of Python 3.11.9**. Other Python versions are available by cloning other branches of the main repository: diff --git a/patch/Python/Python.patch b/patch/Python/Python.patch index 2bdad51..6485f7a 100644 --- a/patch/Python/Python.patch +++ b/patch/Python/Python.patch @@ -15,14 +15,43 @@ index e680e1f9b43..c1b79d2a4a0 100644 +++ b/Doc/includes/wasm-notavail.rst @@ -1,7 +1,6 @@ .. include for modules that don't work on WASM - + -.. availability:: not Emscripten, not WASI. +.. availability:: not WASI. - + - This module does not work or is not available on WebAssembly platforms - ``wasm32-emscripten`` and ``wasm32-wasi``. See + This module does not work or is not available on WebAssembly. See :ref:`wasm-availability` for more information. +diff --git a/Doc/library/asyncio.rst b/Doc/library/asyncio.rst +index 5f33c6813e7..eec97c2da36 100644 +--- a/Doc/library/asyncio.rst ++++ b/Doc/library/asyncio.rst +@@ -56,8 +56,12 @@ + * :ref:`bridge ` callback-based libraries and code + with async/await syntax. + ++.. include:: ../includes/wasm-notavail.rst ++ + .. _asyncio-cli: + ++.. rubric:: asyncio REPL ++ + You can experiment with an ``asyncio`` concurrent context in the REPL: + + .. code-block:: pycon +@@ -70,7 +74,10 @@ + >>> await asyncio.sleep(10, result='hello') + 'hello' + +-.. include:: ../includes/wasm-notavail.rst ++.. audit-event:: cpython.run_stdin "" "" ++ ++.. versionchanged:: 3.11.10 (also 3.10.15, 3.9.20, and 3.8.20) ++ Emits audit events. + + .. We use the "rubric" directive here to avoid creating + the "Reference" subsection in the TOC. diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst index 0d743efd28e..dfd71112231 100644 --- a/Doc/library/curses.rst @@ -30,11 +59,11 @@ index 0d743efd28e..dfd71112231 100644 @@ -21,6 +21,8 @@ designed to match the API of ncurses, an open-source curses library hosted on Linux and the BSD variants of Unix. - + +.. include:: ../includes/wasm-ios-notavail.rst + .. note:: - + Whenever the documentation mentions a *character* it can be specified diff --git a/Doc/library/dbm.rst b/Doc/library/dbm.rst index 74f96b6c433..30b7738a08e 100644 @@ -43,16 +72,116 @@ index 74f96b6c433..30b7738a08e 100644 @@ -14,6 +14,7 @@ is a `third party interface `_ to the Oracle Berkeley DB. - + +.. include:: ../includes/wasm-ios-notavail.rst - + .. exception:: error - + @@ -398,4 +399,3 @@ .. method:: dumbdbm.close() - + Close the database. - +diff --git a/Doc/library/email.errors.rst b/Doc/library/email.errors.rst +index 56aea6598b8..27b0481a85a 100644 +--- a/Doc/library/email.errors.rst ++++ b/Doc/library/email.errors.rst +@@ -58,6 +58,13 @@ + :class:`~email.mime.nonmultipart.MIMENonMultipart` (e.g. + :class:`~email.mime.image.MIMEImage`). + ++ ++.. exception:: HeaderWriteError() ++ ++ Raised when an error occurs when the :mod:`~email.generator` outputs ++ headers. ++ ++ + .. exception:: MessageDefect() + + This is the base class for all defects found when parsing email messages. +diff --git a/Doc/library/email.policy.rst b/Doc/library/email.policy.rst +index bb406c5a56c..3edba4028b1 100644 +--- a/Doc/library/email.policy.rst ++++ b/Doc/library/email.policy.rst +@@ -228,6 +228,24 @@ + + .. versionadded:: 3.6 + ++ ++ .. attribute:: verify_generated_headers ++ ++ If ``True`` (the default), the generator will raise ++ :exc:`~email.errors.HeaderWriteError` instead of writing a header ++ that is improperly folded or delimited, such that it would ++ be parsed as multiple headers or joined with adjacent data. ++ Such headers can be generated by custom header classes or bugs ++ in the ``email`` module. ++ ++ As it's a security feature, this defaults to ``True`` even in the ++ :class:`~email.policy.Compat32` policy. ++ For backwards compatible, but unsafe, behavior, it must be set to ++ ``False`` explicitly. ++ ++ .. versionadded:: 3.11.10 ++ ++ + The following :class:`Policy` method is intended to be called by code using + the email library to create policy instances with custom settings: + +diff --git a/Doc/library/email.utils.rst b/Doc/library/email.utils.rst +index 0e266b6a457..97ddf492617 100644 +--- a/Doc/library/email.utils.rst ++++ b/Doc/library/email.utils.rst +@@ -60,13 +60,18 @@ + begins with angle brackets, they are stripped off. + + +-.. function:: parseaddr(address) ++.. function:: parseaddr(address, *, strict=True) + + Parse address -- which should be the value of some address-containing field such + as :mailheader:`To` or :mailheader:`Cc` -- into its constituent *realname* and + *email address* parts. Returns a tuple of that information, unless the parse + fails, in which case a 2-tuple of ``('', '')`` is returned. + ++ If *strict* is true, use a strict parser which rejects malformed inputs. ++ ++ .. versionchanged:: 3.11.10 ++ Add *strict* optional parameter and reject malformed inputs by default. ++ + + .. function:: formataddr(pair, charset='utf-8') + +@@ -84,12 +89,15 @@ + Added the *charset* option. + + +-.. function:: getaddresses(fieldvalues) ++.. function:: getaddresses(fieldvalues, *, strict=True) + + This method returns a list of 2-tuples of the form returned by ``parseaddr()``. + *fieldvalues* is a sequence of header field values as might be returned by +- :meth:`Message.get_all `. Here's a simple +- example that gets all the recipients of a message:: ++ :meth:`Message.get_all `. ++ ++ If *strict* is true, use a strict parser which rejects malformed inputs. ++ ++ Here's a simple example that gets all the recipients of a message:: + + from email.utils import getaddresses + +@@ -99,6 +107,9 @@ + resent_ccs = msg.get_all('resent-cc', []) + all_recipients = getaddresses(tos + ccs + resent_tos + resent_ccs) + ++ .. versionchanged:: 3.11.10 ++ Add *strict* optional parameter and reject malformed inputs by default. ++ + + .. function:: parsedate(date) + diff --git a/Doc/library/ensurepip.rst b/Doc/library/ensurepip.rst index de3b93f5e61..168e45cfd6f 100644 --- a/Doc/library/ensurepip.rst @@ -60,10 +189,10 @@ index de3b93f5e61..168e45cfd6f 100644 @@ -38,7 +38,7 @@ :pep:`453`: Explicit bootstrapping of pip in Python installations The original rationale and specification for this module. - + -.. include:: ../includes/wasm-notavail.rst +.. include:: ../includes/wasm-ios-notavail.rst - + Command line interface ---------------------- diff --git a/Doc/library/fcntl.rst b/Doc/library/fcntl.rst @@ -73,10 +202,10 @@ index 1836f60ca5c..a36974b1594 100644 @@ -18,7 +18,7 @@ See the :manpage:`fcntl(2)` and :manpage:`ioctl(2)` Unix manual pages for full details. - + -.. availability:: Unix, not Emscripten, not WASI. +.. availability:: Unix, not WASI. - + All functions in this module take a file descriptor *fd* as their first argument. This can be an integer file descriptor, such as returned by diff --git a/Doc/library/grp.rst b/Doc/library/grp.rst @@ -86,20 +215,35 @@ index ee55b12ea86..80260fec8d3 100644 @@ -10,7 +10,7 @@ This module provides access to the Unix group database. It is available on all Unix versions. - + -.. availability:: Unix, not Emscripten, not WASI. +.. availability:: Unix, not WASI, not iOS. - + Group database entries are reported as a tuple-like object, whose attributes correspond to the members of the ``group`` structure (Attribute field below, see +diff --git a/Doc/library/gzip.rst b/Doc/library/gzip.rst +index 5af667a17d0..aa2c8e717a3 100644 +--- a/Doc/library/gzip.rst ++++ b/Doc/library/gzip.rst +@@ -190,7 +190,9 @@ + .. versionchanged:: 3.11 + Speed is improved by compressing all data at once instead of in a + streamed fashion. Calls with *mtime* set to ``0`` are delegated to +- :func:`zlib.compress` for better speed. ++ :func:`zlib.compress` for better speed. In this situation the ++ output may contain a gzip header "OS" byte value other than 255 ++ "unknown" as supplied by the underlying zlib implementation. + + .. function:: decompress(data) + diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index e9200dd1e2d..5f57362e557 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -1202,6 +1202,69 @@ and how the module's :attr:`__file__` is populated. - - + + +.. class:: AppleFrameworkLoader(name, path) + + A specialization of :class:`importlib.machinery.ExtensionFileLoader` that @@ -165,18 +309,18 @@ index e9200dd1e2d..5f57362e557 100644 + :mod:`importlib.util` -- Utility code for importers --------------------------------------------------- - + diff --git a/Doc/library/intro.rst b/Doc/library/intro.rst index 5a4c9b8b16a..ffc8939d211 100644 --- a/Doc/library/intro.rst +++ b/Doc/library/intro.rst @@ -58,7 +58,7 @@ operating system. - + * If not separately noted, all functions that claim "Availability: Unix" are - supported on macOS, which builds on a Unix core. + supported on macOS and iOS, both of which build on a Unix core. - + * If an availability note contains both a minimum Kernel version and a minimum libc version, then both conditions must hold. For example a feature with note @@ -119,3 +119,44 @@ @@ -224,27 +368,89 @@ index 5a4c9b8b16a..ffc8939d211 100644 + + As a result, Python library that involve console manipulation (such as + :mod:`curses` and :mod:`readline`) are not available on iOS. +diff --git a/Doc/library/ipaddress.rst b/Doc/library/ipaddress.rst +index 03dc956cd13..f57fa15aa5b 100644 +--- a/Doc/library/ipaddress.rst ++++ b/Doc/library/ipaddress.rst +@@ -178,18 +178,53 @@ + + .. attribute:: is_private + +- ``True`` if the address is allocated for private networks. See ++ ``True`` if the address is defined as not globally reachable by + iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_ +- (for IPv6). ++ (for IPv6) with the following exceptions: ++ ++ * ``is_private`` is ``False`` for the shared address space (``100.64.0.0/10``) ++ * For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the ++ semantics of the underlying IPv4 addresses and the following condition holds ++ (see :attr:`IPv6Address.ipv4_mapped`):: ++ ++ address.is_private == address.ipv4_mapped.is_private ++ ++ ``is_private`` has value opposite to :attr:`is_global`, except for the shared address space ++ (``100.64.0.0/10`` range) where they are both ``False``. ++ ++ .. versionchanged:: 3.11.10 ++ ++ Fixed some false positives and false negatives. ++ ++ * ``192.0.0.0/24`` is considered private with the exception of ``192.0.0.9/32`` and ++ ``192.0.0.10/32`` (previously: only the ``192.0.0.0/29`` sub-range was considered private). ++ * ``64:ff9b:1::/48`` is considered private. ++ * ``2002::/16`` is considered private. ++ * There are exceptions within ``2001::/23`` (otherwise considered private): ``2001:1::1/128``, ++ ``2001:1::2/128``, ``2001:3::/32``, ``2001:4:112::/48``, ``2001:20::/28``, ``2001:30::/28``. ++ The exceptions are not considered private. + + .. attribute:: is_global + +- ``True`` if the address is allocated for public networks. See ++ ``True`` if the address is defined as globally reachable by + iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_ +- (for IPv6). ++ (for IPv6) with the following exception: ++ ++ For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the ++ semantics of the underlying IPv4 addresses and the following condition holds ++ (see :attr:`IPv6Address.ipv4_mapped`):: ++ ++ address.is_global == address.ipv4_mapped.is_global ++ ++ ``is_global`` has value opposite to :attr:`is_private`, except for the shared address space ++ (``100.64.0.0/10`` range) where they are both ``False``. + + .. versionadded:: 3.4 + ++ .. versionchanged:: 3.11.10 ++ ++ Fixed some false positives and false negatives, see :attr:`is_private` for details. ++ + .. attribute:: is_unspecified + + ``True`` if the address is unspecified. See :RFC:`5735` (for IPv4) diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index ffd690148f1..4173d76d4fb 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -8,7 +8,7 @@ - + -------------- - + -.. include:: ../includes/wasm-notavail.rst +.. include:: ../includes/wasm-ios-notavail.rst - + Introduction ------------ diff --git a/Doc/library/os.rst b/Doc/library/os.rst -index 5fefee382fd..5dda3fc6882 100644 +index 5fefee382fd..6cd6fb018ff 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -34,12 +34,13 @@ - + * On VxWorks, os.popen, os.fork, os.execv and os.spawn*p* are not supported. - + -* On WebAssembly platforms ``wasm32-emscripten`` and ``wasm32-wasi``, large - parts of the :mod:`os` module are not available or behave differently. API - related to processes (e.g. :func:`~os.fork`, :func:`~os.execve`), signals @@ -258,34 +464,55 @@ index 5fefee382fd..5dda3fc6882 100644 + Others like :func:`~os.getuid` and :func:`~os.getpid` are emulated or stubs. + WebAssembly platforms also lack support for signals (e.g. :func:`~os.kill`, + :func:`~os.wait`). - - + + .. note:: @@ -735,6 +736,11 @@ :func:`socket.gethostname` or even ``socket.gethostbyaddr(socket.gethostname())``. - + + On macOS, iOS and Android, this returns the *kernel* name and version (i.e., + ``'Darwin'`` on macOS and iOS; ``'Linux'`` on Android). :func:`platform.uname()` + can be used to get the user-facing operating system name and version on iOS and + Android. + .. availability:: Unix. - + .. versionchanged:: 3.3 -@@ -3761,7 +3767,7 @@ - +@@ -2178,6 +2184,10 @@ + platform-dependent. On some platforms, they are ignored and you should call + :func:`chmod` explicitly to set them. + ++ On Windows, a *mode* of ``0o700`` is specifically handled to apply access ++ control to the new directory such that only the current user and ++ administrators have access. Other values of *mode* are ignored. ++ + This function can also support :ref:`paths relative to directory descriptors + `. + +@@ -2192,6 +2202,9 @@ + .. versionchanged:: 3.6 + Accepts a :term:`path-like object`. + ++ .. versionchanged:: 3.11.10 ++ Windows now handles a *mode* of ``0o700``. ++ + + .. function:: makedirs(name, mode=0o777, exist_ok=False) + +@@ -3761,7 +3774,7 @@ + .. audit-event:: os.exec path,args,env os.execl - + - .. availability:: Unix, Windows, not Emscripten, not WASI. + .. availability:: Unix, Windows, not Emscripten, not WASI, not iOS. - + .. versionchanged:: 3.3 Added support for specifying *path* as an open file descriptor -@@ -3941,7 +3947,16 @@ - +@@ -3941,7 +3954,16 @@ + See :mod:`ssl` for applications that use the SSL module with fork(). - + - .. availability:: Unix, not Emscripten, not WASI. + Users of macOS or users of libc or malloc implementations other + than those typically found in glibc to date are among those @@ -297,13 +524,13 @@ index 5fefee382fd..5dda3fc6882 100644 + platform compatibility problem to developers. + + .. availability:: POSIX, not Emscripten, not WASI, not iOS. - - + + .. function:: forkpty() -@@ -3963,7 +3978,12 @@ +@@ -3963,7 +3985,12 @@ Calling ``forkpty()`` in a subinterpreter is no longer supported (:exc:`RuntimeError` is raised). - + - .. availability:: Unix, not Emscripten, not WASI. + .. versionchanged:: 3.12 + If Python is able to detect that your process has multiple @@ -311,289 +538,289 @@ index 5fefee382fd..5dda3fc6882 100644 + longer explanation on :func:`os.fork`. + + .. availability:: Unix, not Emscripten, not WASI, not iOS. - - + + .. function:: kill(pid, sig, /) -@@ -3987,7 +4007,7 @@ - +@@ -3987,7 +4014,7 @@ + .. audit-event:: os.kill pid,sig os.kill - + - .. availability:: Unix, Windows, not Emscripten, not WASI. + .. availability:: Unix, Windows, not Emscripten, not WASI, not iOS. - + .. versionchanged:: 3.2 Added Windows support. -@@ -4003,7 +4023,7 @@ - +@@ -4003,7 +4030,7 @@ + .. audit-event:: os.killpg pgid,sig os.killpg - + - .. availability:: Unix, not Emscripten, not WASI. + .. availability:: Unix, not Emscripten, not WASI, not iOS. - - + + .. function:: nice(increment, /) -@@ -4031,7 +4051,7 @@ +@@ -4031,7 +4058,7 @@ Lock program segments into memory. The value of *op* (defined in ````) determines which segments are locked. - + - .. availability:: Unix, not Emscripten, not WASI. + .. availability:: Unix, not Emscripten, not WASI, not iOS. - - + + .. function:: popen(cmd, mode='r', buffering=-1) -@@ -4063,7 +4083,7 @@ +@@ -4063,7 +4090,7 @@ documentation for more powerful ways to manage and communicate with subprocesses. - + - .. availability:: not Emscripten, not WASI. + .. availability:: not Emscripten, not WASI, not iOS. - + .. note:: The :ref:`Python UTF-8 Mode ` affects encodings used -@@ -4158,7 +4178,7 @@ - +@@ -4158,7 +4185,7 @@ + .. versionadded:: 3.8 - + - .. availability:: Unix, not Emscripten, not WASI. + .. availability:: Unix, not Emscripten, not WASI, not iOS. - + .. function:: posix_spawnp(path, argv, env, *, file_actions=None, \ setpgroup=None, resetids=False, setsid=False, setsigmask=(), \ -@@ -4174,7 +4194,7 @@ - +@@ -4174,7 +4201,7 @@ + .. versionadded:: 3.8 - + - .. availability:: POSIX, not Emscripten, not WASI. + .. availability:: POSIX, not Emscripten, not WASI, not iOS. - + See :func:`posix_spawn` documentation. - -@@ -4207,7 +4227,7 @@ - + +@@ -4207,7 +4234,7 @@ + There is no way to unregister a function. - + - .. availability:: Unix, not Emscripten, not WASI. + .. availability:: Unix, not Emscripten, not WASI, not iOS. - + .. versionadded:: 3.7 - -@@ -4276,7 +4296,7 @@ - + +@@ -4276,7 +4303,7 @@ + .. audit-event:: os.spawn mode,path,args,env os.spawnl - + - .. availability:: Unix, Windows, not Emscripten, not WASI. + .. availability:: Unix, Windows, not Emscripten, not WASI, not iOS. - + :func:`spawnlp`, :func:`spawnlpe`, :func:`spawnvp` and :func:`spawnvpe` are not available on Windows. :func:`spawnle` and -@@ -4400,7 +4420,7 @@ - +@@ -4400,7 +4427,7 @@ + .. audit-event:: os.system command os.system - + - .. availability:: Unix, Windows, not Emscripten, not WASI. + .. availability:: Unix, Windows, not Emscripten, not WASI, not iOS. - - + + .. function:: times() -@@ -4444,7 +4464,7 @@ +@@ -4444,7 +4471,7 @@ :func:`waitstatus_to_exitcode` can be used to convert the exit status into an exit code. - + - .. availability:: Unix, not Emscripten, not WASI. + .. availability:: Unix, not Emscripten, not WASI, not iOS. - + .. seealso:: - -@@ -4478,7 +4498,10 @@ + +@@ -4478,7 +4505,10 @@ Otherwise, if there are no matching children that could be waited for, :exc:`ChildProcessError` is raised. - + - .. availability:: Unix, not Emscripten, not WASI. + .. availability:: Unix, not Emscripten, not WASI, not iOS. + + .. note:: + This function is not available on macOS. - + .. note:: This function is not available on macOS. -@@ -4519,7 +4542,7 @@ +@@ -4519,7 +4549,7 @@ :func:`waitstatus_to_exitcode` can be used to convert the exit status into an exit code. - + - .. availability:: Unix, Windows, not Emscripten, not WASI. + .. availability:: Unix, Windows, not Emscripten, not WASI, not iOS. - + .. versionchanged:: 3.5 If the system call is interrupted and the signal handler does not raise an -@@ -4539,7 +4562,7 @@ +@@ -4539,7 +4569,7 @@ :func:`waitstatus_to_exitcode` can be used to convert the exit status into an exitcode. - + - .. availability:: Unix, not Emscripten, not WASI. + .. availability:: Unix, not Emscripten, not WASI, not iOS. - - + + .. function:: wait4(pid, options) -@@ -4553,7 +4576,7 @@ +@@ -4553,7 +4583,7 @@ :func:`waitstatus_to_exitcode` can be used to convert the exit status into an exitcode. - + - .. availability:: Unix, not Emscripten, not WASI. + .. availability:: Unix, not Emscripten, not WASI, not iOS. - - + + .. data:: P_PID -@@ -4570,7 +4593,7 @@ +@@ -4570,7 +4600,7 @@ * :data:`!P_PIDFD` - wait for the child identified by the file descriptor *id* (a process file descriptor created with :func:`pidfd_open`). - + - .. availability:: Unix, not Emscripten, not WASI. + .. availability:: Unix, not Emscripten, not WASI, not iOS. - + .. note:: :data:`!P_PIDFD` is only available on Linux >= 5.4. - -@@ -4585,7 +4608,7 @@ + +@@ -4585,7 +4615,7 @@ :func:`waitid` causes child processes to be reported if they have been continued from a job control stop since they were last reported. - + - .. availability:: Unix, not Emscripten, not WASI. + .. availability:: Unix, not Emscripten, not WASI, not iOS. - - + + .. data:: WEXITED -@@ -4596,7 +4619,7 @@ +@@ -4596,7 +4626,7 @@ The other ``wait*`` functions always report children that have terminated, so this option is not available for them. - + - .. availability:: Unix, not Emscripten, not WASI. + .. availability:: Unix, not Emscripten, not WASI, not iOS. - + .. versionadded:: 3.3 - -@@ -4608,7 +4631,7 @@ - + +@@ -4608,7 +4638,7 @@ + This option is not available for the other ``wait*`` functions. - + - .. availability:: Unix, not Emscripten, not WASI. + .. availability:: Unix, not Emscripten, not WASI, not iOS. - + .. versionadded:: 3.3 - -@@ -4621,7 +4644,7 @@ - + +@@ -4621,7 +4651,7 @@ + This option is not available for :func:`waitid`. - + - .. availability:: Unix, not Emscripten, not WASI. + .. availability:: Unix, not Emscripten, not WASI, not iOS. - - + + .. data:: WNOHANG -@@ -4630,7 +4653,7 @@ +@@ -4630,7 +4660,7 @@ :func:`waitid` to return right away if no child process status is available immediately. - + - .. availability:: Unix, not Emscripten, not WASI. + .. availability:: Unix, not Emscripten, not WASI, not iOS. - - + + .. data:: WNOWAIT -@@ -4640,7 +4663,7 @@ - +@@ -4640,7 +4670,7 @@ + This option is not available for the other ``wait*`` functions. - + - .. availability:: Unix, not Emscripten, not WASI. + .. availability:: Unix, not Emscripten, not WASI, not iOS. - - + + .. data:: CLD_EXITED -@@ -4653,7 +4676,7 @@ +@@ -4653,7 +4683,7 @@ These are the possible values for :attr:`!si_code` in the result returned by :func:`waitid`. - + - .. availability:: Unix, not Emscripten, not WASI. + .. availability:: Unix, not Emscripten, not WASI, not iOS. - + .. versionadded:: 3.3 - -@@ -4688,7 +4711,7 @@ + +@@ -4688,7 +4718,7 @@ :func:`WIFEXITED`, :func:`WEXITSTATUS`, :func:`WIFSIGNALED`, :func:`WTERMSIG`, :func:`WIFSTOPPED`, :func:`WSTOPSIG` functions. - + - .. availability:: Unix, Windows, not Emscripten, not WASI. + .. availability:: Unix, Windows, not Emscripten, not WASI, not iOS. - + .. versionadded:: 3.9 - -@@ -4704,7 +4727,7 @@ - + +@@ -4704,7 +4734,7 @@ + This function should be employed only if :func:`WIFSIGNALED` is true. - + - .. availability:: Unix, not Emscripten, not WASI. + .. availability:: Unix, not Emscripten, not WASI, not iOS. - - + + .. function:: WIFCONTINUED(status) -@@ -4715,7 +4738,7 @@ - +@@ -4715,7 +4745,7 @@ + See :data:`WCONTINUED` option. - + - .. availability:: Unix, not Emscripten, not WASI. + .. availability:: Unix, not Emscripten, not WASI, not iOS. - - + + .. function:: WIFSTOPPED(status) -@@ -4727,14 +4750,14 @@ +@@ -4727,14 +4757,14 @@ done using :data:`WUNTRACED` option or when the process is being traced (see :manpage:`ptrace(2)`). - + - .. availability:: Unix, not Emscripten, not WASI. + .. availability:: Unix, not Emscripten, not WASI, not iOS. - + .. function:: WIFSIGNALED(status) - + Return ``True`` if the process was terminated by a signal, otherwise return ``False``. - + - .. availability:: Unix, not Emscripten, not WASI. + .. availability:: Unix, not Emscripten, not WASI, not iOS. - - + + .. function:: WIFEXITED(status) -@@ -4743,7 +4766,7 @@ +@@ -4743,7 +4773,7 @@ by calling ``exit()`` or ``_exit()``, or by returning from ``main()``; otherwise return ``False``. - + - .. availability:: Unix, not Emscripten, not WASI. + .. availability:: Unix, not Emscripten, not WASI, not iOS. - - + + .. function:: WEXITSTATUS(status) -@@ -4752,7 +4775,7 @@ - +@@ -4752,7 +4782,7 @@ + This function should be employed only if :func:`WIFEXITED` is true. - + - .. availability:: Unix, not Emscripten, not WASI. + .. availability:: Unix, not Emscripten, not WASI, not iOS. - - + + .. function:: WSTOPSIG(status) -@@ -4761,7 +4784,7 @@ - +@@ -4761,7 +4791,7 @@ + This function should be employed only if :func:`WIFSTOPPED` is true. - + - .. availability:: Unix, not Emscripten, not WASI. + .. availability:: Unix, not Emscripten, not WASI, not iOS. - - + + .. function:: WTERMSIG(status) -@@ -4770,7 +4793,7 @@ - +@@ -4770,7 +4800,7 @@ + This function should be employed only if :func:`WIFSIGNALED` is true. - + - .. availability:: Unix, not Emscripten, not WASI. + .. availability:: Unix, not Emscripten, not WASI, not iOS. - - + + Interface to the scheduler diff --git a/Doc/library/platform.rst b/Doc/library/platform.rst index 60cd6b88084..316b693eece 100644 @@ -602,34 +829,34 @@ index 60cd6b88084..316b693eece 100644 @@ -148,6 +148,9 @@ Returns the system/OS name, such as ``'Linux'``, ``'Darwin'``, ``'Java'``, ``'Windows'``. An empty string is returned if the value cannot be determined. - + + On iOS and Android, this returns the user-facing OS name (i.e, ``'iOS``, + ``'iPadOS'`` or ``'Android'``). To obtain the kernel name (``'Darwin'`` or + ``'Linux'``), use :func:`os.uname()`. - + .. function:: system_alias(system, release, version) - + @@ -161,6 +164,8 @@ Returns the system's release version, e.g. ``'#3 on degas'``. An empty string is returned if the value cannot be determined. - + + On iOS and Android, this is the user-facing OS version. To obtain the + Darwin or Linux kernel version, use :func:`os.uname()`. - + .. function:: uname() - + @@ -230,7 +235,6 @@ macOS Platform -------------- - + - .. function:: mac_ver(release='', versioninfo=('','',''), machine='') - + Get macOS version information and return it as tuple ``(release, versioninfo, @@ -240,6 +244,24 @@ Entries which cannot be determined are set to ``''``. All tuple entries are strings. - + +iOS Platform +------------ + @@ -648,7 +875,7 @@ index 60cd6b88084..316b693eece 100644 + Entries which cannot be determined are set to the defaults given as + parameters. + - + Unix Platforms -------------- diff --git a/Doc/library/pwd.rst b/Doc/library/pwd.rst @@ -658,10 +885,10 @@ index 755f0d29ac7..b6d212e93b5 100644 @@ -10,7 +10,7 @@ This module provides access to the Unix user account and password database. It is available on all Unix versions. - + -.. availability:: Unix, not Emscripten, not WASI. +.. availability:: Unix, not WASI, not iOS. - + Password database entries are reported as a tuple-like object, whose attributes correspond to the members of the ``passwd`` structure (Attribute field below, diff --git a/Doc/library/readline.rst b/Doc/library/readline.rst @@ -671,11 +898,11 @@ index 3fb5ceef086..758b89b4612 100644 @@ -24,6 +24,8 @@ allowable constructs of that file, and the capabilities of the Readline library in general. - + +.. include:: ../includes/wasm-ios-notavail.rst + .. note:: - + The underlying Readline library API may be implemented by diff --git a/Doc/library/resource.rst b/Doc/library/resource.rst index 389a63f089d..4fea8d5cb71 100644 @@ -684,10 +911,10 @@ index 389a63f089d..4fea8d5cb71 100644 @@ -13,7 +13,7 @@ This module provides basic mechanisms for measuring and controlling system resources utilized by a program. - + -.. availability:: Unix, not Emscripten, not WASI. +.. availability:: Unix, not WASI. - + Symbolic constants are used to specify particular system resources and to request usage information about either the current process or its children. diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst @@ -697,14 +924,14 @@ index 85a073aad23..05ef45c123b 100644 @@ -26,9 +26,9 @@ underlying implementation), with the exception of the handler for :const:`SIGCHLD`, which follows the underlying implementation. - + -On WebAssembly platforms ``wasm32-emscripten`` and ``wasm32-wasi``, signals -are emulated and therefore behave differently. Several functions and signals -are not available on these platforms. +On WebAssembly platforms, signals are emulated and therefore behave +differently. Several functions and signals are not available on these +platforms. - + Execution of Python signal handlers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst @@ -714,79 +941,105 @@ index 3a5368717ac..de47e1f6e5f 100644 @@ -1109,7 +1109,7 @@ buffer. Raises :exc:`OverflowError` if *length* is outside the permissible range of values. - + - .. availability:: Unix, not Emscripten, not WASI. + .. availability:: Unix, not WASI. - + Most Unix platforms. - + @@ -1132,7 +1132,7 @@ amount of ancillary data that can be received, since additional data may be able to fit into the padding area. - + - .. availability:: Unix, not Emscripten, not WASI. + .. availability:: Unix, not WASI. - + most Unix platforms. - + @@ -1172,7 +1172,7 @@ (index int, name string) tuples. :exc:`OSError` if the system call fails. - + - .. availability:: Unix, Windows, not Emscripten, not WASI. + .. availability:: Unix, Windows, not WASI. - + .. versionadded:: 3.3 - + @@ -1199,7 +1199,7 @@ interface name. :exc:`OSError` if no interface with the given name exists. - + - .. availability:: Unix, Windows, not Emscripten, not WASI. + .. availability:: Unix, Windows, not WASI. - + .. versionadded:: 3.3 - + @@ -1216,7 +1216,7 @@ interface index number. :exc:`OSError` if no interface with the given index exists. - + - .. availability:: Unix, Windows, not Emscripten, not WASI. + .. availability:: Unix, Windows, not WASI. - + .. versionadded:: 3.3 - + @@ -1233,7 +1233,7 @@ The *fds* parameter is a sequence of file descriptors. Consult :meth:`~socket.sendmsg` for the documentation of these parameters. - + - .. availability:: Unix, Windows, not Emscripten, not WASI. + .. availability:: Unix, Windows, not WASI. - + Unix platforms supporting :meth:`~socket.sendmsg` and :const:`SCM_RIGHTS` mechanism. @@ -1247,7 +1247,7 @@ Return ``(msg, list(fds), flags, addr)``. Consult :meth:`~socket.recvmsg` for the documentation of these parameters. - + - .. availability:: Unix, Windows, not Emscripten, not WASI. + .. availability:: Unix, Windows, not WASI. - + Unix platforms supporting :meth:`~socket.sendmsg` and :const:`SCM_RIGHTS` mechanism. diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst -index f2d0f83bb68..8d39c94660b 100644 +index f2d0f83bb68..7009a7e8314 100644 --- a/Doc/library/subprocess.rst +++ b/Doc/library/subprocess.rst @@ -25,7 +25,7 @@ - + :pep:`324` -- PEP proposing the subprocess module - + -.. include:: ../includes/wasm-notavail.rst +.. include:: ../includes/wasm-ios-notavail.rst - + Using the :mod:`subprocess` Module ---------------------------------- +@@ -756,8 +756,8 @@ + Security Considerations + ----------------------- + +-Unlike some other popen functions, this implementation will never +-implicitly call a system shell. This means that all characters, ++Unlike some other popen functions, this library will not ++implicitly choose to call a system shell. This means that all characters, + including shell metacharacters, can safely be passed to child processes. + If the shell is invoked explicitly, via ``shell=True``, it is the application's + responsibility to ensure that all whitespace and metacharacters are +@@ -766,6 +766,14 @@ + vulnerabilities. On :ref:`some platforms `, it is possible + to use :func:`shlex.quote` for this escaping. + ++On Windows, batch files (:file:`*.bat` or :file:`*.cmd`) may be launched by the ++operating system in a system shell regardless of the arguments passed to this ++library. This could result in arguments being parsed according to shell rules, ++but without any escaping added by Python. If you are intentionally launching a ++batch file with arguments from untrusted sources, consider passing ++``shell=True`` to allow Python to escape special characters. See :gh:`114539` ++for additional discussion. ++ + + Popen Objects + ------------- diff --git a/Doc/library/syslog.rst b/Doc/library/syslog.rst index 889bbb39d58..6c7c0907143 100644 --- a/Doc/library/syslog.rst @@ -794,10 +1047,10 @@ index 889bbb39d58..6c7c0907143 100644 @@ -11,7 +11,7 @@ Refer to the Unix manual pages for a detailed description of the ``syslog`` facility. - + -.. availability:: Unix, not Emscripten, not WASI. +.. availability:: Unix, not WASI, not iOS. - + This module wraps the system ``syslog`` family of routines. A pure Python library that can speak to a syslog server is available in the diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst @@ -805,7 +1058,7 @@ index 9f90418bc96..c198c5798e9 100644 --- a/Doc/library/urllib.parse.rst +++ b/Doc/library/urllib.parse.rst @@ -22,11 +22,19 @@ - + The module has been designed to match the internet RFC on Relative Uniform Resource Locators. It supports the following URL schemes: ``file``, ``ftp``, -``gopher``, ``hdl``, ``http``, ``https``, ``imap``, ``mailto``, ``mms``, @@ -813,7 +1066,7 @@ index 9f90418bc96..c198c5798e9 100644 ``news``, ``nntp``, ``prospero``, ``rsync``, ``rtsp``, ``rtsps``, ``rtspu``, ``sftp``, ``shttp``, ``sip``, ``sips``, ``snews``, ``svn``, ``svn+ssh``, ``telnet``, ``wais``, ``ws``, ``wss``. - + +.. impl-detail:: + + The inclusion of the ``itms-services`` URL scheme can prevent an app from @@ -832,10 +1085,10 @@ index ce6d093b741..822cead8050 100644 @@ -56,7 +56,7 @@ `Python Packaging User Guide: Creating and using virtual environments `__ - + -.. include:: ../includes/wasm-notavail.rst +.. include:: ../includes/wasm-ios-notavail.rst - + Creating virtual environments ----------------------------- diff --git a/Doc/library/webbrowser.rst b/Doc/library/webbrowser.rst @@ -845,7 +1098,7 @@ index 734b6321e5a..b709e511afa 100644 @@ -33,6 +33,13 @@ browsers are not available on Unix, the controlling process will launch a new browser and wait. - + +On iOS, the :envvar:`BROWSER` environment variable, as well as any arguments +controlling autoraise, browser preference, and new tab/window creation will be +ignored. Web pages will *always* be opened in the user's preferred browser, in @@ -862,12 +1115,12 @@ index 734b6321e5a..b709e511afa 100644 +------------------------+-----------------------------------------+-------+ +| ``'iosbrowser'`` | ``IOSBrowser`` | \(4) | ++------------------------+-----------------------------------------+-------+ - + Notes: - + @@ -171,7 +180,11 @@ Only on Windows platforms. - + (3) - Only on macOS platform. + Only on macOS. @@ -875,19 +1128,32 @@ index 734b6321e5a..b709e511afa 100644 +(4) + Only on iOS. + - + .. versionadded:: 3.3 Support for Chrome/Chromium has been added. @@ -179,6 +192,9 @@ .. deprecated-removed:: 3.11 3.13 :class:`MacOSX` is deprecated, use :class:`MacOSXOSAScript` instead. - + +.. versionchanged:: 3.13 + Support for iOS has been added. + Here are some simple examples:: - + url = 'https://docs.python.org/' +diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst +index 9f3f80294dd..31035bce934 100644 +--- a/Doc/reference/datamodel.rst ++++ b/Doc/reference/datamodel.rst +@@ -1217,7 +1217,7 @@ + + The iterator returns :class:`tuple`\s containing the ``(start_line, end_line, + start_column, end_column)``. The *i-th* tuple corresponds to the +- position of the source code that compiled to the *i-th* instruction. ++ position of the source code that compiled to the *i-th* code unit. + Column information is 0-indexed utf-8 byte offsets on the given source + line. + diff --git a/Doc/tools/extensions/pyspecific.py b/Doc/tools/extensions/pyspecific.py index c849a4d3875..4b8252cb590 100644 --- a/Doc/tools/extensions/pyspecific.py @@ -902,14 +1168,30 @@ index c849a4d3875..4b8252cb590 100644 "BSD libc", "glibc", "musl", # POSIX platforms with pthreads @@ -169,7 +169,7 @@ - + Example:: - + - .. availability:: Windows, Linux >= 4.2, not Emscripten, not WASI + .. availability:: Windows, Linux >= 4.2, not WASI - + Arguments like "Linux >= 3.17 with glibc >= 2.27" are currently not parsed into separate tokens. +diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst +index fa2e6d08fb1..a1a7073cf5b 100644 +--- a/Doc/using/cmdline.rst ++++ b/Doc/using/cmdline.rst +@@ -697,6 +697,11 @@ + This variable can also be modified by Python code using :data:`os.environ` + to force inspect mode on program termination. + ++ .. audit-event:: cpython.run_stdin "" "" ++ ++ .. versionchanged:: 3.11.10 (also 3.10.15, 3.9.20, and 3.8.20) ++ Emits audit events. ++ + + .. envvar:: PYTHONUNBUFFERED + diff --git a/Doc/using/configure.rst b/Doc/using/configure.rst index e45a5a4791e..26ac341bc98 100644 --- a/Doc/using/configure.rst @@ -917,16 +1199,16 @@ index e45a5a4791e..26ac341bc98 100644 @@ -527,7 +527,7 @@ macOS Options ------------- - + -See ``Mac/README.rst``. +See :source:`Mac/README.rst`. - + .. option:: --enable-universalsdk .. option:: --enable-universalsdk=SDKDIR @@ -562,6 +562,31 @@ Specify the name for the python framework on macOS only valid when :option:`--enable-framework` is set (default: ``Python``). - + +.. option:: --with-app-store-compliance +.. option:: --with-app-store-compliance=PATCH-FILE + @@ -952,7 +1234,7 @@ index e45a5a4791e..26ac341bc98 100644 + + Specify the name for the framework (default: ``Python``). + - + Cross Compiling Options ----------------------- diff --git a/Doc/using/index.rst b/Doc/using/index.rst @@ -1318,7 +1600,7 @@ index 986d693d03f..da45aabca28 100644 @@ -188,6 +188,28 @@ * `PyInstaller `__: A cross-platform packaging tool that creates a single file or folder as a distributable artifact. - + +App Store Compliance +-------------------- + @@ -1343,7 +1625,137 @@ index 986d693d03f..da45aabca28 100644 + Other Resources =============== - + +diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst +index f670fa1f097..583a408cace 100644 +--- a/Doc/whatsnew/3.11.rst ++++ b/Doc/whatsnew/3.11.rst +@@ -769,6 +769,21 @@ + (Contributed by Yurii Karabas in :issue:`46014`.) + + ++.. _whatsnew311-gzip: ++ ++gzip ++---- ++ ++* The :func:`gzip.compress` function is now faster when used with the ++ **mtime=0** argument as it delegates the compression entirely to a single ++ :func:`zlib.compress` operation. There is one side effect of this change: The ++ gzip file header contains an "OS" byte in its header. That was traditionally ++ always set to a value of 255 representing "unknown" by the :mod:`gzip` ++ module. Now, when using :func:`~gzip.compress` with **mtime=0**, it may be ++ set to a different value by the underlying zlib C library Python was linked ++ against. ++ (See :gh:`112346` for details on the side effect.) ++ + .. _whatsnew311-hashlib: + + hashlib +@@ -899,6 +914,13 @@ + instead of ``CryptGenRandom()`` which is deprecated. + (Contributed by Donghee Na in :issue:`44611`.) + ++* As of 3.11.10, :func:`os.mkdir` and :func:`os.makedirs` on Windows ++ now support passing a *mode* value of ``0o700`` to apply access ++ control to the new directory. This implicitly affects ++ :func:`tempfile.mkdtemp` and is a mitigation for CVE-2024-4030. ++ Other values for *mode* continue to be ignored. ++ (Contributed by Steve Dower in :gh:`118486`.) ++ + + .. _whatsnew311-pathlib: + +@@ -1059,6 +1081,11 @@ + such as compression modules. + (Contributed by Carey Metcalfe in :gh:`70363`.) + ++* As of 3.11.10 on Windows, the default mode ``0o700`` used by ++ :func:`tempfile.mkdtemp` now limits access to the new directory due to ++ changes to :func:`os.mkdir`. This is a mitigation for CVE-2024-4030. ++ (Contributed by Steve Dower in :gh:`118486`.) ++ + + .. _whatsnew311-threading: + +@@ -2727,3 +2754,35 @@ + * Windows builds and macOS installers from python.org now use OpenSSL 3.0. + + .. _libb2: https://www.blake2.net/ ++ ++ ++Notable changes in 3.11.10 ++========================== ++ ++ipaddress ++--------- ++ ++* Fixed ``is_global`` and ``is_private`` behavior in ``IPv4Address``, ++ ``IPv6Address``, ``IPv4Network`` and ``IPv6Network``. ++ ++email ++----- ++ ++* Headers with embedded newlines are now quoted on output. ++ ++ The :mod:`~email.generator` will now refuse to serialize (write) headers ++ that are improperly folded or delimited, such that they would be parsed as ++ multiple headers or joined with adjacent data. ++ If you need to turn this safety feature off, ++ set :attr:`~email.policy.Policy.verify_generated_headers`. ++ (Contributed by Bas Bloemsaat and Petr Viktorin in :gh:`121650`.) ++ ++* :func:`email.utils.getaddresses` and :func:`email.utils.parseaddr` now return ++ ``('', '')`` 2-tuples in more situations where invalid email addresses are ++ encountered, instead of potentially inaccurate values. ++ An optional *strict* parameter was added to these two functions: ++ use ``strict=False`` to get the old behavior, accepting malformed inputs. ++ ``getattr(email.utils, 'supports_strict_parsing', False)`` can be used to ++ check if the *strict* paramater is available. ++ (Contributed by Thomas Dwyer and Victor Stinner for :gh:`102988` to improve ++ the CVE-2023-27043 fix.) +diff --git a/Grammar/python.gram b/Grammar/python.gram +index c7e7233c132..0a54279918e 100644 +--- a/Grammar/python.gram ++++ b/Grammar/python.gram +@@ -955,6 +955,7 @@ + + starred_expression[expr_ty]: + | '*' a=expression { _PyAST_Starred(a, Load, EXTRA) } ++ | '*' { RAISE_SYNTAX_ERROR("Invalid star expression") } + + kwarg_or_starred[KeywordOrStarred*]: + | invalid_kwarg +@@ -1075,8 +1076,8 @@ + + # From here on, there are rules for invalid syntax with specialised error messages + invalid_arguments: +- | ((','.(starred_expression | ( assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' b='*' { +- RAISE_SYNTAX_ERROR_KNOWN_LOCATION(b, "iterable argument unpacking follows keyword argument unpacking") } ++ | ((','.(starred_expression | ( assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) a=',' ','.(starred_expression !'=')+ { ++ RAISE_SYNTAX_ERROR_STARTING_FROM(a, "iterable argument unpacking follows keyword argument unpacking") } + | a=expression b=for_if_clauses ',' [args | expression for_if_clauses] { + RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, _PyPegen_get_last_comprehension_item(PyPegen_last_item(b, comprehension_ty)), "Generator expression must be parenthesized") } + | a=NAME b='=' expression for_if_clauses { +diff --git a/Include/patchlevel.h b/Include/patchlevel.h +index 6dea1dd4486..7540bc8a6c8 100644 +--- a/Include/patchlevel.h ++++ b/Include/patchlevel.h +@@ -18,12 +18,12 @@ + /*--start constants--*/ + #define PY_MAJOR_VERSION 3 + #define PY_MINOR_VERSION 11 +-#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.11.9" ++#define PY_VERSION "3.11.10" + /*--end constants--*/ + + /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. --- /dev/null +++ b/Lib/_ios_support.py @@ -0,0 +1,71 @@ @@ -1418,6 +1830,19 @@ index 986d693d03f..da45aabca28 100644 + model = objc.objc_msgSend(device_model, SEL_UTF8String).decode() + + return system, release, model, is_simulator +diff --git a/Lib/asyncio/__main__.py b/Lib/asyncio/__main__.py +index 18bb87a5bc4..73330f4ac3f 100644 +--- a/Lib/asyncio/__main__.py ++++ b/Lib/asyncio/__main__.py +@@ -90,6 +90,8 @@ + + + if __name__ == '__main__': ++ sys.audit("cpython.run_stdin") ++ + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + diff --git a/Lib/ctypes/__init__.py b/Lib/ctypes/__init__.py index 26135ad9629..315c725e547 100644 --- a/Lib/ctypes/__init__.py @@ -1449,7 +1874,7 @@ index c550883e7c7..12d7428fe9a 100644 @@ -67,7 +67,7 @@ return fname return None - + -elif os.name == "posix" and sys.platform == "darwin": +elif os.name == "posix" and sys.platform in {"darwin", "ios", "tvos", "watchos"}: from ctypes.macholib.dyld import dyld_find as _dyld_find @@ -1462,7 +1887,7 @@ index 633d3041a1b..a91ee9e0f37 100644 @@ -4,6 +4,9 @@ import os from io import BytesIO - + +if sys.platform != 'win32': + raise unittest.SkipTest("Cygwin tests only needed on Windows") + @@ -1481,10 +1906,10 @@ index 363834fe8b3..c67b7a130b5 100644 +from test.support import swap_item, requires_subprocess, is_apple_mobile, is_wasi from test.support.os_helper import TESTFN from test.support.warnings_helper import check_warnings - + @@ -33,6 +33,7 @@ shutil.rmtree(TESTFN) - + @unittest.skipIf(is_wasi, "Incompatible with WASI mapdir and OOT builds") + @unittest.skipIf(is_apple_mobile, "Header files not distributed with Apple mobile") def test_get_config_h_filename(self): @@ -1492,7 +1917,7 @@ index 363834fe8b3..c67b7a130b5 100644 self.assertTrue(os.path.isfile(config_h), config_h) @@ -50,6 +51,7 @@ self.assertTrue(cvars) - + @unittest.skipIf(is_wasi, "Incompatible with WASI mapdir and OOT builds") + @unittest.skipIf(is_apple_mobile, "Header files not distributed with Apple mobile") def test_srcdir(self): @@ -1504,7 +1929,7 @@ index d00c48981eb..5d12b4779db 100644 +++ b/Lib/distutils/unixccompiler.py @@ -270,9 +270,9 @@ static_f = self.library_filename(lib, lib_type='static') - + if sys.platform == 'darwin': - # On OSX users can specify an alternate SDK using - # '-isysroot', calculate the SDK root if it is specified @@ -1527,7 +1952,7 @@ index d00c48981eb..5d12b4779db 100644 + sysroot = m.group(1) else: sysroot = m.group(1) - + - - for dir in dirs: @@ -1564,35 +1989,415 @@ index 2ce5c5b64d6..e927f4af938 100644 + osname, release, machine = _osx_support.get_platform_osx( + config_vars, + osname, release, machine) - + return "%s-%s-%s" % (osname, release, machine) - + @@ -170,7 +185,7 @@ if _environ_checked: return - + - if os.name == 'posix' and 'HOME' not in os.environ: + if os.name == 'posix' and 'HOME' not in os.environ and sys.platform not in {"ios", "tvos", "watchos"}: try: import pwd os.environ['HOME'] = pwd.getpwuid(os.getuid())[5] +diff --git a/Lib/email/_header_value_parser.py b/Lib/email/_header_value_parser.py +index 8cb8852cf0b..992394ea9ff 100644 +--- a/Lib/email/_header_value_parser.py ++++ b/Lib/email/_header_value_parser.py +@@ -92,6 +92,8 @@ + ASPECIALS = TSPECIALS | set("*'%") + ATTRIBUTE_ENDS = ASPECIALS | WSP + EXTENDED_ATTRIBUTE_ENDS = ATTRIBUTE_ENDS - set('%') ++NLSET = {'\n', '\r'} ++SPECIALSNL = SPECIALS | NLSET + + def quote_string(value): + return '"'+str(value).replace('\\', '\\\\').replace('"', r'\"')+'"' +@@ -950,6 +952,7 @@ + DOT = ValueTerminal('.', 'dot') + ListSeparator = ValueTerminal(',', 'list-separator') + ListSeparator.as_ew_allowed = False ++ListSeparator.syntactic_break = False + RouteComponentMarker = ValueTerminal('@', 'route-component-marker') + + # +@@ -2780,9 +2783,13 @@ + wrap_as_ew_blocked -= 1 + continue + tstr = str(part) +- if part.token_type == 'ptext' and set(tstr) & SPECIALS: +- # Encode if tstr contains special characters. +- want_encoding = True ++ if not want_encoding: ++ if part.token_type == 'ptext': ++ # Encode if tstr contains special characters. ++ want_encoding = not SPECIALSNL.isdisjoint(tstr) ++ else: ++ # Encode if tstr contains newlines. ++ want_encoding = not NLSET.isdisjoint(tstr) + try: + tstr.encode(encoding) + charset = encoding +@@ -2821,7 +2828,9 @@ + if not hasattr(part, 'encode'): + # It's not a Terminal, do each piece individually. + parts = list(part) + parts +- else: ++ want_encoding = False ++ continue ++ elif part.as_ew_allowed: + # It's a terminal, wrap it as an encoded word, possibly + # combining it with previously encoded words if allowed. + if (last_ew is not None and +@@ -2832,8 +2841,15 @@ + last_ew = _fold_as_ew(tstr, lines, maxlen, last_ew, + part.ew_combine_allowed, charset) + last_charset = charset +- want_encoding = False +- continue ++ want_encoding = False ++ continue ++ else: ++ # It's a terminal which should be kept non-encoded ++ # (e.g. a ListSeparator). ++ last_ew = None ++ want_encoding = False ++ # fall through ++ + if len(tstr) <= maxlen - len(lines[-1]): + lines[-1] += tstr + continue +diff --git a/Lib/email/_policybase.py b/Lib/email/_policybase.py +index c9cbadd2a80..d1f48211f90 100644 +--- a/Lib/email/_policybase.py ++++ b/Lib/email/_policybase.py +@@ -157,6 +157,13 @@ + message_factory -- the class to use to create new message objects. + If the value is None, the default is Message. + ++ verify_generated_headers ++ -- if true, the generator verifies that each header ++ they are properly folded, so that a parser won't ++ treat it as multiple headers, start-of-body, or ++ part of another header. ++ This is a check against custom Header & fold() ++ implementations. + """ + + raise_on_defect = False +@@ -165,6 +172,7 @@ + max_line_length = 78 + mangle_from_ = False + message_factory = None ++ verify_generated_headers = True + + def handle_defect(self, obj, defect): + """Based on policy, either raise defect or call register_defect. +diff --git a/Lib/email/errors.py b/Lib/email/errors.py +index 3ad00565549..02aa5eced6a 100644 +--- a/Lib/email/errors.py ++++ b/Lib/email/errors.py +@@ -29,6 +29,10 @@ + """An illegal charset was given.""" + + ++class HeaderWriteError(MessageError): ++ """Error while writing headers.""" ++ ++ + # These are parsing defects which the parser was able to work around. + class MessageDefect(ValueError): + """Base class for a message defect.""" +diff --git a/Lib/email/generator.py b/Lib/email/generator.py +index eb597de76d4..563ca170726 100644 +--- a/Lib/email/generator.py ++++ b/Lib/email/generator.py +@@ -14,12 +14,14 @@ + from copy import deepcopy + from io import StringIO, BytesIO + from email.utils import _has_surrogates ++from email.errors import HeaderWriteError + + UNDERSCORE = '_' + NL = '\n' # XXX: no longer used by the code below. + + NLCRE = re.compile(r'\r\n|\r|\n') + fcre = re.compile(r'^From ', re.MULTILINE) ++NEWLINE_WITHOUT_FWSP = re.compile(r'\r\n[^ \t]|\r[^ \n\t]|\n[^ \t]') + + + class Generator: +@@ -222,7 +224,16 @@ + + def _write_headers(self, msg): + for h, v in msg.raw_items(): +- self.write(self.policy.fold(h, v)) ++ folded = self.policy.fold(h, v) ++ if self.policy.verify_generated_headers: ++ linesep = self.policy.linesep ++ if not folded.endswith(self.policy.linesep): ++ raise HeaderWriteError( ++ f'folded header does not end with {linesep!r}: {folded!r}') ++ if NEWLINE_WITHOUT_FWSP.search(folded.removesuffix(linesep)): ++ raise HeaderWriteError( ++ f'folded header contains newline: {folded!r}') ++ self.write(folded) + # A blank line always separates headers from body + self.write(self._NL) + +diff --git a/Lib/email/utils.py b/Lib/email/utils.py +index 8993858ab48..94ead0e91fa 100644 +--- a/Lib/email/utils.py ++++ b/Lib/email/utils.py +@@ -48,6 +48,7 @@ + specialsre = re.compile(r'[][\\()<>@,:;".]') + escapesre = re.compile(r'[\\"]') + ++ + def _has_surrogates(s): + """Return True if s may contain surrogate-escaped binary data.""" + # This check is based on the fact that unless there are surrogates, utf8 +@@ -106,12 +107,127 @@ + return address + + ++def _iter_escaped_chars(addr): ++ pos = 0 ++ escape = False ++ for pos, ch in enumerate(addr): ++ if escape: ++ yield (pos, '\\' + ch) ++ escape = False ++ elif ch == '\\': ++ escape = True ++ else: ++ yield (pos, ch) ++ if escape: ++ yield (pos, '\\') ++ ++ ++def _strip_quoted_realnames(addr): ++ """Strip real names between quotes.""" ++ if '"' not in addr: ++ # Fast path ++ return addr ++ ++ start = 0 ++ open_pos = None ++ result = [] ++ for pos, ch in _iter_escaped_chars(addr): ++ if ch == '"': ++ if open_pos is None: ++ open_pos = pos ++ else: ++ if start != open_pos: ++ result.append(addr[start:open_pos]) ++ start = pos + 1 ++ open_pos = None ++ ++ if start < len(addr): ++ result.append(addr[start:]) ++ ++ return ''.join(result) + +-def getaddresses(fieldvalues): +- """Return a list of (REALNAME, EMAIL) for each fieldvalue.""" +- all = COMMASPACE.join(str(v) for v in fieldvalues) +- a = _AddressList(all) +- return a.addresslist ++ ++supports_strict_parsing = True ++ ++def getaddresses(fieldvalues, *, strict=True): ++ """Return a list of (REALNAME, EMAIL) or ('','') for each fieldvalue. ++ ++ When parsing fails for a fieldvalue, a 2-tuple of ('', '') is returned in ++ its place. ++ ++ If strict is true, use a strict parser which rejects malformed inputs. ++ """ ++ ++ # If strict is true, if the resulting list of parsed addresses is greater ++ # than the number of fieldvalues in the input list, a parsing error has ++ # occurred and consequently a list containing a single empty 2-tuple [('', ++ # '')] is returned in its place. This is done to avoid invalid output. ++ # ++ # Malformed input: getaddresses(['alice@example.com ']) ++ # Invalid output: [('', 'alice@example.com'), ('', 'bob@example.com')] ++ # Safe output: [('', '')] ++ ++ if not strict: ++ all = COMMASPACE.join(str(v) for v in fieldvalues) ++ a = _AddressList(all) ++ return a.addresslist ++ ++ fieldvalues = [str(v) for v in fieldvalues] ++ fieldvalues = _pre_parse_validation(fieldvalues) ++ addr = COMMASPACE.join(fieldvalues) ++ a = _AddressList(addr) ++ result = _post_parse_validation(a.addresslist) ++ ++ # Treat output as invalid if the number of addresses is not equal to the ++ # expected number of addresses. ++ n = 0 ++ for v in fieldvalues: ++ # When a comma is used in the Real Name part it is not a deliminator. ++ # So strip those out before counting the commas. ++ v = _strip_quoted_realnames(v) ++ # Expected number of addresses: 1 + number of commas ++ n += 1 + v.count(',') ++ if len(result) != n: ++ return [('', '')] ++ ++ return result ++ ++ ++def _check_parenthesis(addr): ++ # Ignore parenthesis in quoted real names. ++ addr = _strip_quoted_realnames(addr) ++ ++ opens = 0 ++ for pos, ch in _iter_escaped_chars(addr): ++ if ch == '(': ++ opens += 1 ++ elif ch == ')': ++ opens -= 1 ++ if opens < 0: ++ return False ++ return (opens == 0) ++ ++ ++def _pre_parse_validation(email_header_fields): ++ accepted_values = [] ++ for v in email_header_fields: ++ if not _check_parenthesis(v): ++ v = "('', '')" ++ accepted_values.append(v) ++ ++ return accepted_values ++ ++ ++def _post_parse_validation(parsed_email_header_tuples): ++ accepted_values = [] ++ # The parser would have parsed a correctly formatted domain-literal ++ # The existence of an [ after parsing indicates a parsing failure ++ for v in parsed_email_header_tuples: ++ if '[' in v[1]: ++ v = ('', '') ++ accepted_values.append(v) ++ ++ return accepted_values + + + def _format_timetuple_and_zone(timetuple, zone): +@@ -205,16 +321,33 @@ + tzinfo=datetime.timezone(datetime.timedelta(seconds=tz))) + + +-def parseaddr(addr): ++def parseaddr(addr, *, strict=True): + """ + Parse addr into its constituent realname and email address parts. + + Return a tuple of realname and email address, unless the parse fails, in + which case return a 2-tuple of ('', ''). ++ ++ If strict is True, use a strict parser which rejects malformed inputs. + """ +- addrs = _AddressList(addr).addresslist +- if not addrs: +- return '', '' ++ if not strict: ++ addrs = _AddressList(addr).addresslist ++ if not addrs: ++ return ('', '') ++ return addrs[0] ++ ++ if isinstance(addr, list): ++ addr = addr[0] ++ ++ if not isinstance(addr, str): ++ return ('', '') ++ ++ addr = _pre_parse_validation([addr])[0] ++ addrs = _post_parse_validation(_AddressList(addr).addresslist) ++ ++ if not addrs or len(addrs) > 1: ++ return ('', '') ++ + return addrs[0] + + +diff --git a/Lib/http/cookies.py b/Lib/http/cookies.py +index 35ac2dc6ae2..2c1f021d0ab 100644 +--- a/Lib/http/cookies.py ++++ b/Lib/http/cookies.py +@@ -184,8 +184,13 @@ + return '"' + str.translate(_Translator) + '"' + + +-_OctalPatt = re.compile(r"\\[0-3][0-7][0-7]") +-_QuotePatt = re.compile(r"[\\].") ++_unquote_sub = re.compile(r'\\(?:([0-3][0-7][0-7])|(.))').sub ++ ++def _unquote_replace(m): ++ if m[1]: ++ return chr(int(m[1], 8)) ++ else: ++ return m[2] + + def _unquote(str): + # If there aren't any doublequotes, +@@ -205,30 +210,7 @@ + # \012 --> \n + # \" --> " + # +- i = 0 +- n = len(str) +- res = [] +- while 0 <= i < n: +- o_match = _OctalPatt.search(str, i) +- q_match = _QuotePatt.search(str, i) +- if not o_match and not q_match: # Neither matched +- res.append(str[i:]) +- break +- # else: +- j = k = -1 +- if o_match: +- j = o_match.start(0) +- if q_match: +- k = q_match.start(0) +- if q_match and (not o_match or k < j): # QuotePatt matched +- res.append(str[i:k]) +- res.append(str[k+1]) +- i = k + 2 +- else: # OctalPatt matched +- res.append(str[i:j]) +- res.append(chr(int(str[j+1:j+4], 8))) +- i = j + 4 +- return _nulljoin(res) ++ return _unquote_sub(_unquote_replace, str) + + # The _getdate() routine is used to set the expiration time in the cookie's HTTP + # header. By default, _getdate() returns the current time in the appropriate diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index e53f6acf38f..64aa8444410 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -52,7 +52,7 @@ - + # Bootstrap-related code ###################################################### _CASE_INSENSITIVE_PLATFORMS_STR_KEY = 'win', -_CASE_INSENSITIVE_PLATFORMS_BYTES_KEY = 'cygwin', 'darwin' +_CASE_INSENSITIVE_PLATFORMS_BYTES_KEY = 'cygwin', 'darwin', 'ios', 'tvos', 'watchos' _CASE_INSENSITIVE_PLATFORMS = (_CASE_INSENSITIVE_PLATFORMS_BYTES_KEY + _CASE_INSENSITIVE_PLATFORMS_STR_KEY) - + @@ -1708,6 +1708,46 @@ return 'FileFinder({!r})'.format(self.path) - - + + +class AppleFrameworkLoader(ExtensionFileLoader): + """A loader for modules that have been packaged as frameworks for + compatibility with Apple's iOS App Store policies. @@ -1634,10 +2439,10 @@ index e53f6acf38f..64aa8444410 100644 + return module + # Import setup ############################################################### - + def _fix_up_module(ns, name, pathname, cpathname=None): @@ -1738,10 +1778,17 @@ - + Each item is a tuple (loader, suffixes). """ - extensions = ExtensionFileLoader, _imp.extension_suffixes() @@ -1653,8 +2458,8 @@ index e53f6acf38f..64aa8444410 100644 bytecode = SourcelessFileLoader, BYTECODE_SUFFIXES - return [extensions, source, bytecode] + return extension_loaders + [source, bytecode] - - + + def _set_bootstrap_module(_bootstrap_module): diff --git a/Lib/importlib/abc.py b/Lib/importlib/abc.py index 3fa151f390b..47a6a5ed5a6 100644 @@ -1663,15 +2468,15 @@ index 3fa151f390b..47a6a5ed5a6 100644 @@ -261,7 +261,11 @@ else: return self.source_to_code(source, path) - + -_register(ExecutionLoader, machinery.ExtensionFileLoader) +_register( + ExecutionLoader, + machinery.ExtensionFileLoader, + machinery.AppleFrameworkLoader, +) - - + + class FileLoader(_bootstrap_external.FileLoader, ResourceLoader, ExecutionLoader): diff --git a/Lib/importlib/machinery.py b/Lib/importlib/machinery.py index d9a19a13f7b..fbd30b159fb 100644 @@ -1683,8 +2488,8 @@ index d9a19a13f7b..fbd30b159fb 100644 from ._bootstrap_external import ExtensionFileLoader +from ._bootstrap_external import AppleFrameworkLoader from ._bootstrap_external import NamespaceLoader - - + + diff --git a/Lib/inspect.py b/Lib/inspect.py index 09e6a23652f..0dbe90f470a 100644 --- a/Lib/inspect.py @@ -1704,15 +2509,195 @@ index 09e6a23652f..0dbe90f470a 100644 - if not (file.startswith('<') and file.endswith('>')): + if (not (file.startswith('<') and file.endswith('>'))) or file.endswith('.fwork'): raise OSError('source code not available') - + module = getmodule(object, file) +diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py +index 16ba16cd7de..567beb37e06 100644 +--- a/Lib/ipaddress.py ++++ b/Lib/ipaddress.py +@@ -1086,7 +1086,11 @@ + """ + return any(self.network_address in priv_network and + self.broadcast_address in priv_network +- for priv_network in self._constants._private_networks) ++ for priv_network in self._constants._private_networks) and all( ++ self.network_address not in network and ++ self.broadcast_address not in network ++ for network in self._constants._private_networks_exceptions ++ ) + + @property + def is_global(self): +@@ -1333,18 +1337,41 @@ + @property + @functools.lru_cache() + def is_private(self): +- """Test if this address is allocated for private networks. ++ """``True`` if the address is defined as not globally reachable by ++ iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_ ++ (for IPv6) with the following exceptions: + +- Returns: +- A boolean, True if the address is reserved per +- iana-ipv4-special-registry. ++ * ``is_private`` is ``False`` for ``100.64.0.0/10`` ++ * For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the ++ semantics of the underlying IPv4 addresses and the following condition holds ++ (see :attr:`IPv6Address.ipv4_mapped`):: + ++ address.is_private == address.ipv4_mapped.is_private ++ ++ ``is_private`` has value opposite to :attr:`is_global`, except for the ``100.64.0.0/10`` ++ IPv4 range where they are both ``False``. + """ +- return any(self in net for net in self._constants._private_networks) ++ return ( ++ any(self in net for net in self._constants._private_networks) ++ and all(self not in net for net in self._constants._private_networks_exceptions) ++ ) + + @property + @functools.lru_cache() + def is_global(self): ++ """``True`` if the address is defined as globally reachable by ++ iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_ ++ (for IPv6) with the following exception: ++ ++ For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the ++ semantics of the underlying IPv4 addresses and the following condition holds ++ (see :attr:`IPv6Address.ipv4_mapped`):: ++ ++ address.is_global == address.ipv4_mapped.is_global ++ ++ ``is_global`` has value opposite to :attr:`is_private`, except for the ``100.64.0.0/10`` ++ IPv4 range where they are both ``False``. ++ """ + return self not in self._constants._public_network and not self.is_private + + @property +@@ -1548,13 +1575,15 @@ + + _public_network = IPv4Network('100.64.0.0/10') + ++ # Not globally reachable address blocks listed on ++ # https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml + _private_networks = [ + IPv4Network('0.0.0.0/8'), + IPv4Network('10.0.0.0/8'), + IPv4Network('127.0.0.0/8'), + IPv4Network('169.254.0.0/16'), + IPv4Network('172.16.0.0/12'), +- IPv4Network('192.0.0.0/29'), ++ IPv4Network('192.0.0.0/24'), + IPv4Network('192.0.0.170/31'), + IPv4Network('192.0.2.0/24'), + IPv4Network('192.168.0.0/16'), +@@ -1565,6 +1594,11 @@ + IPv4Network('255.255.255.255/32'), + ] + ++ _private_networks_exceptions = [ ++ IPv4Network('192.0.0.9/32'), ++ IPv4Network('192.0.0.10/32'), ++ ] ++ + _reserved_network = IPv4Network('240.0.0.0/4') + + _unspecified_address = IPv4Address('0.0.0.0') +@@ -2010,27 +2044,42 @@ + @property + @functools.lru_cache() + def is_private(self): +- """Test if this address is allocated for private networks. ++ """``True`` if the address is defined as not globally reachable by ++ iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_ ++ (for IPv6) with the following exceptions: + +- Returns: +- A boolean, True if the address is reserved per +- iana-ipv6-special-registry, or is ipv4_mapped and is +- reserved in the iana-ipv4-special-registry. ++ * ``is_private`` is ``False`` for ``100.64.0.0/10`` ++ * For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the ++ semantics of the underlying IPv4 addresses and the following condition holds ++ (see :attr:`IPv6Address.ipv4_mapped`):: + ++ address.is_private == address.ipv4_mapped.is_private ++ ++ ``is_private`` has value opposite to :attr:`is_global`, except for the ``100.64.0.0/10`` ++ IPv4 range where they are both ``False``. + """ + ipv4_mapped = self.ipv4_mapped + if ipv4_mapped is not None: + return ipv4_mapped.is_private +- return any(self in net for net in self._constants._private_networks) ++ return ( ++ any(self in net for net in self._constants._private_networks) ++ and all(self not in net for net in self._constants._private_networks_exceptions) ++ ) + + @property + def is_global(self): +- """Test if this address is allocated for public networks. ++ """``True`` if the address is defined as globally reachable by ++ iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_ ++ (for IPv6) with the following exception: + +- Returns: +- A boolean, true if the address is not reserved per +- iana-ipv6-special-registry. ++ For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the ++ semantics of the underlying IPv4 addresses and the following condition holds ++ (see :attr:`IPv6Address.ipv4_mapped`):: ++ ++ address.is_global == address.ipv4_mapped.is_global + ++ ``is_global`` has value opposite to :attr:`is_private`, except for the ``100.64.0.0/10`` ++ IPv4 range where they are both ``False``. + """ + return not self.is_private + +@@ -2271,19 +2320,31 @@ + + _multicast_network = IPv6Network('ff00::/8') + ++ # Not globally reachable address blocks listed on ++ # https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml + _private_networks = [ + IPv6Network('::1/128'), + IPv6Network('::/128'), + IPv6Network('::ffff:0:0/96'), ++ IPv6Network('64:ff9b:1::/48'), + IPv6Network('100::/64'), + IPv6Network('2001::/23'), +- IPv6Network('2001:2::/48'), + IPv6Network('2001:db8::/32'), +- IPv6Network('2001:10::/28'), ++ # IANA says N/A, let's consider it not globally reachable to be safe ++ IPv6Network('2002::/16'), + IPv6Network('fc00::/7'), + IPv6Network('fe80::/10'), + ] + ++ _private_networks_exceptions = [ ++ IPv6Network('2001:1::1/128'), ++ IPv6Network('2001:1::2/128'), ++ IPv6Network('2001:3::/32'), ++ IPv6Network('2001:4:112::/48'), ++ IPv6Network('2001:20::/28'), ++ IPv6Network('2001:30::/28'), ++ ] ++ + _reserved_networks = [ + IPv6Network('::/8'), IPv6Network('100::/8'), + IPv6Network('200::/7'), IPv6Network('400::/6'), diff --git a/Lib/lib2to3/tests/test_parser.py b/Lib/lib2to3/tests/test_parser.py index 8e7773bcae1..7df3e354f6d 100644 --- a/Lib/lib2to3/tests/test_parser.py +++ b/Lib/lib2to3/tests/test_parser.py @@ -62,9 +62,7 @@ shutil.rmtree(tmpdir) - + @unittest.skipIf(sys.executable is None, 'sys.executable required') - @unittest.skipIf( - sys.platform in {'emscripten', 'wasi'}, 'requires working subprocess' @@ -1728,7 +2713,7 @@ index a0a020f9eeb..ac478ee7f51 100644 @@ -72,7 +72,12 @@ if isinstance(spec.loader, importlib.machinery.SourceFileLoader): kind = _PY_SOURCE - + - elif isinstance(spec.loader, importlib.machinery.ExtensionFileLoader): + elif isinstance( + spec.loader, ( @@ -1737,7 +2722,7 @@ index a0a020f9eeb..ac478ee7f51 100644 + ) + ): kind = _C_EXTENSION - + elif isinstance(spec.loader, importlib.machinery.SourcelessFileLoader): diff --git a/Lib/platform.py b/Lib/platform.py index 9b9d88bf584..1bb5fcb96d6 100755 @@ -1746,7 +2731,7 @@ index 9b9d88bf584..1bb5fcb96d6 100755 @@ -452,6 +452,78 @@ # If that also doesn't work return the default values return release, versioninfo, machine - + + +# A namedtuple for iOS version information. +IOSVersionInfo = collections.namedtuple( @@ -1820,7 +2805,7 @@ index 9b9d88bf584..1bb5fcb96d6 100755 + + def _java_getprop(name, default): - + from java.lang import System @@ -567,7 +639,7 @@ if cleaned == platform: @@ -1829,21 +2814,21 @@ index 9b9d88bf584..1bb5fcb96d6 100755 - while platform[-1] == '-': + while platform and platform[-1] == '-': platform = platform[:-1] - + return platform @@ -608,7 +680,7 @@ default in case the command should fail. - + """ - if sys.platform in ('dos', 'win32', 'win16'): + if sys.platform in {'dos', 'win32', 'win16', 'ios', 'tvos', 'watchos'}: # XXX Others too ? return default - + @@ -750,6 +822,25 @@ csid, cpu_number = vms_lib.getsyi('SYI$_CPU', 0) return 'Alpha' if cpu_number >= 128 else 'VAX' - + + # On the iOS/tvOS/watchOS simulator, os.uname returns the architecture as + # uname.machine. On device it returns the model name for some reason; but + # there's only one CPU architecture for devices, so we know the right @@ -1869,7 +2854,7 @@ index 9b9d88bf584..1bb5fcb96d6 100755 @@ -904,6 +995,14 @@ system = 'Windows' release = 'Vista' - + + # Normalize responses on Apple mobile platforms + if sys.platform == 'ios': + system, release, _, _ = ios_ver() @@ -1883,7 +2868,7 @@ index 9b9d88bf584..1bb5fcb96d6 100755 _uname_cache = uname_result(*map(_unknown_as_blank, vals)) @@ -1216,11 +1315,18 @@ system, release, version = system_alias(system, release, version) - + if system == 'Darwin': - # macOS (darwin kernel) - macos_release = mac_ver()[0] @@ -1902,9 +2887,35 @@ index 9b9d88bf584..1bb5fcb96d6 100755 + if macos_release: + system = 'macOS' + release = macos_release - + if system == 'Windows': # MS platforms +diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py +index cec9b8b8183..74033ecb600 100644 +--- a/Lib/pydoc_data/topics.py ++++ b/Lib/pydoc_data/topics.py +@@ -1,5 +1,5 @@ + # -*- coding: utf-8 -*- +-# Autogenerated by Sphinx on Tue Apr 2 09:24:48 2024 ++# Autogenerated by Sphinx on Sat Sep 7 02:03:11 2024 + # as part of the release process. + topics = {'assert': 'The "assert" statement\n' + '**********************\n' +@@ -13958,10 +13958,10 @@ + ' The iterator returns "tuple"s containing the "(start_line,\n' + ' end_line, start_column, end_column)". The *i-th* tuple ' + 'corresponds\n' +- ' to the position of the source code that compiled to the *i-th*\n' +- ' instruction. Column information is 0-indexed utf-8 byte offsets ' +- 'on\n' +- ' the given source line.\n' ++ ' to the position of the source code that compiled to the *i-th* ' ++ 'code\n' ++ ' unit. Column information is 0-indexed utf-8 byte offsets on the\n' ++ ' given source line.\n' + '\n' + ' This positional information can be missing. A non-exhaustive ' + 'lists\n' diff --git a/Lib/site.py b/Lib/site.py index 2904e44cffd..371a89ff717 100644 --- a/Lib/site.py @@ -1912,14 +2923,138 @@ index 2904e44cffd..371a89ff717 100644 @@ -276,8 +276,8 @@ if env_base: return env_base - + - # Emscripten, VxWorks, and WASI have no home directories - if sys.platform in {"emscripten", "vxworks", "wasi"}: + # Emscripten, iOS, tvOS, VxWorks, WASI, and watchOS have no home directories + if sys.platform in {"emscripten", "ios", "tvos", "vxworks", "wasi", "watchos"}: return None - + def joinuser(*args): +diff --git a/Lib/socket.py b/Lib/socket.py +index a0567b76bcf..f386241abfb 100644 +--- a/Lib/socket.py ++++ b/Lib/socket.py +@@ -590,16 +590,65 @@ + return socket(0, 0, 0, info) + __all__.append("fromshare") + +-if hasattr(_socket, "socketpair"): ++# Origin: https://gist.github.com/4325783, by Geert Jansen. Public domain. ++# This is used if _socket doesn't natively provide socketpair. It's ++# always defined so that it can be patched in for testing purposes. ++def _fallback_socketpair(family=AF_INET, type=SOCK_STREAM, proto=0): ++ if family == AF_INET: ++ host = _LOCALHOST ++ elif family == AF_INET6: ++ host = _LOCALHOST_V6 ++ else: ++ raise ValueError("Only AF_INET and AF_INET6 socket address families " ++ "are supported") ++ if type != SOCK_STREAM: ++ raise ValueError("Only SOCK_STREAM socket type is supported") ++ if proto != 0: ++ raise ValueError("Only protocol zero is supported") ++ ++ # We create a connected TCP socket. Note the trick with ++ # setblocking(False) that prevents us from having to create a thread. ++ lsock = socket(family, type, proto) ++ try: ++ lsock.bind((host, 0)) ++ lsock.listen() ++ # On IPv6, ignore flow_info and scope_id ++ addr, port = lsock.getsockname()[:2] ++ csock = socket(family, type, proto) ++ try: ++ csock.setblocking(False) ++ try: ++ csock.connect((addr, port)) ++ except (BlockingIOError, InterruptedError): ++ pass ++ csock.setblocking(True) ++ ssock, _ = lsock.accept() ++ except: ++ csock.close() ++ raise ++ finally: ++ lsock.close() + +- def socketpair(family=None, type=SOCK_STREAM, proto=0): +- """socketpair([family[, type[, proto]]]) -> (socket object, socket object) ++ # Authenticating avoids using a connection from something else ++ # able to connect to {host}:{port} instead of us. ++ # We expect only AF_INET and AF_INET6 families. ++ try: ++ if ( ++ ssock.getsockname() != csock.getpeername() ++ or csock.getsockname() != ssock.getpeername() ++ ): ++ raise ConnectionError("Unexpected peer connection") ++ except: ++ # getsockname() and getpeername() can fail ++ # if either socket isn't connected. ++ ssock.close() ++ csock.close() ++ raise + +- Create a pair of socket objects from the sockets returned by the platform +- socketpair() function. +- The arguments are the same as for socket() except the default family is +- AF_UNIX if defined on the platform; otherwise, the default is AF_INET. +- """ ++ return (ssock, csock) ++ ++if hasattr(_socket, "socketpair"): ++ def socketpair(family=None, type=SOCK_STREAM, proto=0): + if family is None: + try: + family = AF_UNIX +@@ -611,44 +660,7 @@ + return a, b + + else: +- +- # Origin: https://gist.github.com/4325783, by Geert Jansen. Public domain. +- def socketpair(family=AF_INET, type=SOCK_STREAM, proto=0): +- if family == AF_INET: +- host = _LOCALHOST +- elif family == AF_INET6: +- host = _LOCALHOST_V6 +- else: +- raise ValueError("Only AF_INET and AF_INET6 socket address families " +- "are supported") +- if type != SOCK_STREAM: +- raise ValueError("Only SOCK_STREAM socket type is supported") +- if proto != 0: +- raise ValueError("Only protocol zero is supported") +- +- # We create a connected TCP socket. Note the trick with +- # setblocking(False) that prevents us from having to create a thread. +- lsock = socket(family, type, proto) +- try: +- lsock.bind((host, 0)) +- lsock.listen() +- # On IPv6, ignore flow_info and scope_id +- addr, port = lsock.getsockname()[:2] +- csock = socket(family, type, proto) +- try: +- csock.setblocking(False) +- try: +- csock.connect((addr, port)) +- except (BlockingIOError, InterruptedError): +- pass +- csock.setblocking(True) +- ssock, _ = lsock.accept() +- except: +- csock.close() +- raise +- finally: +- lsock.close() +- return (ssock, csock) ++ socketpair = _fallback_socketpair + __all__.append("socketpair") + + socketpair.__doc__ = """socketpair([family[, type[, proto]]]) -> (socket object, socket object) diff --git a/Lib/subprocess.py b/Lib/subprocess.py index 1d17ae3608a..34dfa0019a5 100644 --- a/Lib/subprocess.py @@ -1927,12 +3062,12 @@ index 1d17ae3608a..34dfa0019a5 100644 @@ -74,8 +74,8 @@ else: _mswindows = True - + -# wasm32-emscripten and wasm32-wasi do not support processes -_can_fork_exec = sys.platform not in {"emscripten", "wasi"} +# some platforms do not support subprocesses +_can_fork_exec = sys.platform not in {"emscripten", "wasi", "ios", "tvos", "watchos"} - + if _mswindows: import _winapi @@ -103,18 +103,22 @@ @@ -1968,11 +3103,11 @@ index 1d17ae3608a..34dfa0019a5 100644 + import select import selectors - + @@ -1958,20 +1962,16 @@ raise child_exception_type(err_msg) - - + + - def _handle_exitstatus(self, sts, - _waitstatus_to_exitcode=_waitstatus_to_exitcode, - _WIFSTOPPED=_WIFSTOPPED, @@ -1988,13 +3123,13 @@ index 1d17ae3608a..34dfa0019a5 100644 else: - self.returncode = _waitstatus_to_exitcode(sts) + self.returncode = _del_safe.waitstatus_to_exitcode(sts) - + - def _internal_poll(self, _deadstate=None, _waitpid=_waitpid, - _WNOHANG=_WNOHANG, _ECHILD=errno.ECHILD): + def _internal_poll(self, _deadstate=None, _del_safe=_del_safe): """Check if child process has terminated. Returns returncode attribute. - + @@ -1987,13 +1987,13 @@ try: if self.returncode is not None: @@ -2016,13 +3151,13 @@ index ebe37118274..edf12d57068 100644 --- a/Lib/sysconfig.py +++ b/Lib/sysconfig.py @@ -20,6 +20,7 @@ - + # Keys for get_config_var() that are never converted to Python integers. _ALWAYS_STR = { + 'IPHONEOS_DEPLOYMENT_TARGET', 'MACOSX_DEPLOYMENT_TARGET', } - + @@ -56,6 +57,7 @@ 'scripts': '{base}/Scripts', 'data': '{base}', @@ -2034,13 +3169,13 @@ index ebe37118274..edf12d57068 100644 @@ -111,8 +113,8 @@ if env_base: return env_base - + - # Emscripten, VxWorks, and WASI have no home directories - if sys.platform in {"emscripten", "vxworks", "wasi"}: + # Emscripten, iOS, tvOS, VxWorks, WASI, and watchOS have no home directories + if sys.platform in {"emscripten", "ios", "tvos", "vxworks", "wasi", "watchos"}: return None - + def joinuser(*args): @@ -289,6 +291,7 @@ 'home': 'posix_home', @@ -2075,9 +3210,171 @@ index ebe37118274..edf12d57068 100644 + osname, release, machine = _osx_support.get_platform_osx( + get_config_vars(), + osname, release, machine) - + return f"{osname}-{release}-{machine}" - + +diff --git a/Lib/tarfile.py b/Lib/tarfile.py +index 612217b1ad0..0d6b925533b 100755 +--- a/Lib/tarfile.py ++++ b/Lib/tarfile.py +@@ -842,6 +842,9 @@ + # Sentinel for replace() defaults, meaning "don't change the attribute" + _KEEP = object() + ++# Header length is digits followed by a space. ++_header_length_prefix_re = re.compile(br"([0-9]{1,20}) ") ++ + class TarInfo(object): + """Informational class which holds the details about an + archive member given by a tar header block. +@@ -1411,41 +1414,59 @@ + else: + pax_headers = tarfile.pax_headers.copy() + +- # Check if the pax header contains a hdrcharset field. This tells us +- # the encoding of the path, linkpath, uname and gname fields. Normally, +- # these fields are UTF-8 encoded but since POSIX.1-2008 tar +- # implementations are allowed to store them as raw binary strings if +- # the translation to UTF-8 fails. +- match = re.search(br"\d+ hdrcharset=([^\n]+)\n", buf) +- if match is not None: +- pax_headers["hdrcharset"] = match.group(1).decode("utf-8") +- +- # For the time being, we don't care about anything other than "BINARY". +- # The only other value that is currently allowed by the standard is +- # "ISO-IR 10646 2000 UTF-8" in other words UTF-8. +- hdrcharset = pax_headers.get("hdrcharset") +- if hdrcharset == "BINARY": +- encoding = tarfile.encoding +- else: +- encoding = "utf-8" +- + # Parse pax header information. A record looks like that: + # "%d %s=%s\n" % (length, keyword, value). length is the size + # of the complete record including the length field itself and +- # the newline. keyword and value are both UTF-8 encoded strings. +- regex = re.compile(br"(\d+) ([^=]+)=") ++ # the newline. + pos = 0 +- while True: +- match = regex.match(buf, pos) +- if not match: +- break ++ encoding = None ++ raw_headers = [] ++ while len(buf) > pos and buf[pos] != 0x00: ++ if not (match := _header_length_prefix_re.match(buf, pos)): ++ raise InvalidHeaderError("invalid header") ++ try: ++ length = int(match.group(1)) ++ except ValueError: ++ raise InvalidHeaderError("invalid header") ++ # Headers must be at least 5 bytes, shortest being '5 x=\n'. ++ # Value is allowed to be empty. ++ if length < 5: ++ raise InvalidHeaderError("invalid header") ++ if pos + length > len(buf): ++ raise InvalidHeaderError("invalid header") + +- length, keyword = match.groups() +- length = int(length) +- if length == 0: ++ header_value_end_offset = match.start(1) + length - 1 # Last byte of the header ++ keyword_and_value = buf[match.end(1) + 1:header_value_end_offset] ++ raw_keyword, equals, raw_value = keyword_and_value.partition(b"=") ++ ++ # Check the framing of the header. The last character must be '\n' (0x0A) ++ if not raw_keyword or equals != b"=" or buf[header_value_end_offset] != 0x0A: + raise InvalidHeaderError("invalid header") +- value = buf[match.end(2) + 1:match.start(1) + length - 1] ++ raw_headers.append((length, raw_keyword, raw_value)) ++ ++ # Check if the pax header contains a hdrcharset field. This tells us ++ # the encoding of the path, linkpath, uname and gname fields. Normally, ++ # these fields are UTF-8 encoded but since POSIX.1-2008 tar ++ # implementations are allowed to store them as raw binary strings if ++ # the translation to UTF-8 fails. For the time being, we don't care about ++ # anything other than "BINARY". The only other value that is currently ++ # allowed by the standard is "ISO-IR 10646 2000 UTF-8" in other words UTF-8. ++ # Note that we only follow the initial 'hdrcharset' setting to preserve ++ # the initial behavior of the 'tarfile' module. ++ if raw_keyword == b"hdrcharset" and encoding is None: ++ if raw_value == b"BINARY": ++ encoding = tarfile.encoding ++ else: # This branch ensures only the first 'hdrcharset' header is used. ++ encoding = "utf-8" ++ ++ pos += length + ++ # If no explicit hdrcharset is set, we use UTF-8 as a default. ++ if encoding is None: ++ encoding = "utf-8" ++ ++ # After parsing the raw headers we can decode them to text. ++ for length, raw_keyword, raw_value in raw_headers: + # Normally, we could just use "utf-8" as the encoding and "strict" + # as the error handler, but we better not take the risk. For + # example, GNU tar <= 1.23 is known to store filenames it cannot +@@ -1453,17 +1474,16 @@ + # hdrcharset=BINARY header). + # We first try the strict standard encoding, and if that fails we + # fall back on the user's encoding and error handler. +- keyword = self._decode_pax_field(keyword, "utf-8", "utf-8", ++ keyword = self._decode_pax_field(raw_keyword, "utf-8", "utf-8", + tarfile.errors) + if keyword in PAX_NAME_FIELDS: +- value = self._decode_pax_field(value, encoding, tarfile.encoding, ++ value = self._decode_pax_field(raw_value, encoding, tarfile.encoding, + tarfile.errors) + else: +- value = self._decode_pax_field(value, "utf-8", "utf-8", ++ value = self._decode_pax_field(raw_value, "utf-8", "utf-8", + tarfile.errors) + + pax_headers[keyword] = value +- pos += length + + # Fetch the next header. + try: +@@ -1478,7 +1498,7 @@ + + elif "GNU.sparse.size" in pax_headers: + # GNU extended sparse format version 0.0. +- self._proc_gnusparse_00(next, pax_headers, buf) ++ self._proc_gnusparse_00(next, raw_headers) + + elif pax_headers.get("GNU.sparse.major") == "1" and pax_headers.get("GNU.sparse.minor") == "0": + # GNU extended sparse format version 1.0. +@@ -1500,15 +1520,24 @@ + + return next + +- def _proc_gnusparse_00(self, next, pax_headers, buf): ++ def _proc_gnusparse_00(self, next, raw_headers): + """Process a GNU tar extended sparse header, version 0.0. + """ + offsets = [] +- for match in re.finditer(br"\d+ GNU.sparse.offset=(\d+)\n", buf): +- offsets.append(int(match.group(1))) + numbytes = [] +- for match in re.finditer(br"\d+ GNU.sparse.numbytes=(\d+)\n", buf): +- numbytes.append(int(match.group(1))) ++ for _, keyword, value in raw_headers: ++ if keyword == b"GNU.sparse.offset": ++ try: ++ offsets.append(int(value.decode())) ++ except ValueError: ++ raise InvalidHeaderError("invalid header") ++ ++ elif keyword == b"GNU.sparse.numbytes": ++ try: ++ numbytes.append(int(value.decode())) ++ except ValueError: ++ raise InvalidHeaderError("invalid header") ++ + next.sparse = list(zip(offsets, numbytes)) + + def _proc_gnusparse_01(self, next, pax_headers): diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py index 74ebb5e5b8a..d3e5fddf69b 100644 --- a/Lib/test/pythoninfo.py @@ -2104,9 +3401,9 @@ index 059542c2433..532dff848a4 100644 "open_urlresource", # processes @@ -517,7 +517,7 @@ - + is_android = hasattr(sys, 'getandroidapilevel') - + -if sys.platform not in ('win32', 'vxworks'): +if sys.platform not in {"win32", "vxworks", "ios", "tvos", "watchos"}: unix_shell = '/system/bin/sh' if is_android else '/bin/sh' @@ -2115,7 +3412,7 @@ index 059542c2433..532dff848a4 100644 @@ -527,19 +527,35 @@ is_emscripten = sys.platform == "emscripten" is_wasi = sys.platform == "wasi" - + -has_fork_support = hasattr(os, "fork") and not is_emscripten and not is_wasi +# Apple mobile platforms (iOS/tvOS/watchOS) are POSIX-like but do not +# have subprocess or fork support. @@ -2127,28 +3424,28 @@ index 059542c2433..532dff848a4 100644 + or is_wasi + or is_apple_mobile +) - + def requires_fork(): return unittest.skipUnless(has_fork_support, "requires working os.fork()") - + -has_subprocess_support = not is_emscripten and not is_wasi +has_subprocess_support = not ( + is_emscripten + or is_wasi + or is_apple_mobile +) - + def requires_subprocess(): """Used for subprocess, os.spawn calls, fd inheritance""" return unittest.skipUnless(has_subprocess_support, "requires subprocess support") - + # Emscripten's socket emulation and WASI sockets have limitations. -has_socket_support = not is_emscripten and not is_wasi +has_socket_support = not ( + is_emscripten + or is_wasi +) - + def requires_working_socket(*, module=False): """Skip tests or modules that require working sockets diff --git a/Lib/test/support/os_helper.py b/Lib/test/support/os_helper.py @@ -2158,14 +3455,14 @@ index c1b2995ef37..353a3f589ac 100644 @@ -9,6 +9,8 @@ import unittest import warnings - + +from test import support + - + # Filename used for testing if os.name == 'java': @@ -23,8 +25,8 @@ - + # TESTFN_UNICODE is a non-ascii filename TESTFN_UNICODE = TESTFN_ASCII + "-\xe0\xf2\u0258\u0141\u011f" -if sys.platform == 'darwin': @@ -2194,7 +3491,7 @@ index c1b2995ef37..353a3f589ac 100644 + except (OSError, ValueError): + # gh-118201: ValueError is raised intermittently on iOS pass - + old_modes = None diff --git a/Lib/test/support/socket_helper.py b/Lib/test/support/socket_helper.py index ec6d1dee4e9..48900f50508 100644 @@ -2209,11 +3506,11 @@ index ec6d1dee4e9..48900f50508 100644 +import tempfile import sys import unittest - + @@ -273,6 +275,16 @@ socket.setdefaulttimeout(old_timeout) - - + + +def create_unix_domain_name(): + """ + Create a UNIX domain name: socket.bind() argument of a AF_UNIX socket. @@ -2226,7 +3523,7 @@ index ec6d1dee4e9..48900f50508 100644 + # consider that sysctl values should not change while tests are running _sysctl_cache = {} - + diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py index 8e3c68db550..0e4028a31ae 100644 --- a/Lib/test/test_asyncio/test_events.py @@ -2234,23 +3531,23 @@ index 8e3c68db550..0e4028a31ae 100644 @@ -1867,6 +1867,7 @@ else: self.assertEqual(-signal.SIGKILL, returncode) - + + @support.requires_subprocess() def test_subprocess_exec(self): prog = os.path.join(os.path.dirname(__file__), 'echo.py') - + @@ -1888,6 +1889,7 @@ self.check_killed(proto.returncode) self.assertEqual(b'Python The Winner', proto.data[1]) - + + @support.requires_subprocess() def test_subprocess_interactive(self): prog = os.path.join(os.path.dirname(__file__), 'echo.py') - + @@ -1915,6 +1917,7 @@ self.loop.run_until_complete(proto.completed) self.check_killed(proto.returncode) - + + @support.requires_subprocess() def test_subprocess_shell(self): connect = self.loop.subprocess_shell( @@ -2258,7 +3555,7 @@ index 8e3c68db550..0e4028a31ae 100644 @@ -1931,6 +1934,7 @@ self.assertEqual(proto.data[2], b'') transp.close() - + + @support.requires_subprocess() def test_subprocess_exitcode(self): connect = self.loop.subprocess_shell( @@ -2266,7 +3563,7 @@ index 8e3c68db550..0e4028a31ae 100644 @@ -1942,6 +1946,7 @@ self.assertEqual(7, proto.returncode) transp.close() - + + @support.requires_subprocess() def test_subprocess_close_after_finish(self): connect = self.loop.subprocess_shell( @@ -2274,22 +3571,22 @@ index 8e3c68db550..0e4028a31ae 100644 @@ -1956,6 +1961,7 @@ self.assertEqual(7, proto.returncode) self.assertIsNone(transp.close()) - + + @support.requires_subprocess() def test_subprocess_kill(self): prog = os.path.join(os.path.dirname(__file__), 'echo.py') - + @@ -1972,6 +1978,7 @@ self.check_killed(proto.returncode) transp.close() - + + @support.requires_subprocess() def test_subprocess_terminate(self): prog = os.path.join(os.path.dirname(__file__), 'echo.py') - + @@ -1989,6 +1996,7 @@ transp.close() - + @unittest.skipIf(sys.platform == 'win32', "Don't have SIGHUP") + @support.requires_subprocess() def test_subprocess_send_signal(self): @@ -2298,31 +3595,31 @@ index 8e3c68db550..0e4028a31ae 100644 @@ -2013,6 +2021,7 @@ finally: signal.signal(signal.SIGHUP, old_handler) - + + @support.requires_subprocess() def test_subprocess_stderr(self): prog = os.path.join(os.path.dirname(__file__), 'echo2.py') - + @@ -2034,6 +2043,7 @@ self.assertTrue(proto.data[2].startswith(b'ERR:test'), proto.data[2]) self.assertEqual(0, proto.returncode) - + + @support.requires_subprocess() def test_subprocess_stderr_redirect_to_stdout(self): prog = os.path.join(os.path.dirname(__file__), 'echo2.py') - + @@ -2059,6 +2069,7 @@ transp.close() self.assertEqual(0, proto.returncode) - + + @support.requires_subprocess() def test_subprocess_close_client_stream(self): prog = os.path.join(os.path.dirname(__file__), 'echo3.py') - + @@ -2093,6 +2104,7 @@ self.loop.run_until_complete(proto.completed) self.check_killed(proto.returncode) - + + @support.requires_subprocess() def test_subprocess_wait_no_same_group(self): # start the new process in a new session @@ -2330,7 +3627,7 @@ index 8e3c68db550..0e4028a31ae 100644 @@ -2105,6 +2117,7 @@ self.assertEqual(7, proto.returncode) transp.close() - + + @support.requires_subprocess() def test_subprocess_exec_invalid_args(self): async def connect(**kwds): @@ -2338,10 +3635,10 @@ index 8e3c68db550..0e4028a31ae 100644 @@ -2118,6 +2131,7 @@ with self.assertRaises(ValueError): self.loop.run_until_complete(connect(shell=True)) - + + @support.requires_subprocess() def test_subprocess_shell_invalid_args(self): - + async def connect(cmd=None, **kwds): diff --git a/Lib/test/test_asyncio/test_streams.py b/Lib/test/test_asyncio/test_streams.py index 59ff89e7734..320affdfdec 100644 @@ -2358,7 +3655,7 @@ index 59ff89e7734..320affdfdec 100644 except ImportError: @@ -769,6 +769,7 @@ self.assertEqual(msg2, b"hello world 2!\n") - + @unittest.skipIf(sys.platform == 'win32', "Don't have pipes") + @requires_subprocess() def test_read_all_from_pipe_reader(self): @@ -2370,19 +3667,19 @@ index f0d1d95d2c1..b07afb97adb 100644 +++ b/Lib/test/test_asyncio/test_subprocess.py @@ -48,6 +48,7 @@ self._proc.pid = -1 - - + + +@support.requires_subprocess() class SubprocessTransportTests(test_utils.TestCase): def setUp(self): super().setUp() @@ -111,6 +112,7 @@ transport.close() - - + + +@support.requires_subprocess() class SubprocessMixin: - + def test_stdin_stdout(self): diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py index 01c1214c7f7..7e16e2a369d 100644 @@ -2390,7 +3687,7 @@ index 01c1214c7f7..7e16e2a369d 100644 +++ b/Lib/test/test_asyncio/test_unix_events.py @@ -315,11 +315,15 @@ self.loop.run_until_complete(coro) - + def test_create_unix_server_existing_path_nonsock(self): - with tempfile.NamedTemporaryFile() as file: - coro = self.loop.create_unix_server(lambda: None, file.name) @@ -2406,7 +3703,7 @@ index 01c1214c7f7..7e16e2a369d 100644 + with self.assertRaisesRegex(OSError, + 'Address.*is already in use'): + self.loop.run_until_complete(coro) - + def test_create_unix_server_ssl_bool(self): coro = self.loop.create_unix_server(lambda: None, path='spam', diff --git a/Lib/test/test_asyncio/utils.py b/Lib/test/test_asyncio/utils.py @@ -2427,18 +3724,18 @@ index 045e385511b..c39fb20ed7c 100644 from test import support -from test.support import threading_helper +from test.support import threading_helper, socket_helper - - + + # Use the maximum known clock resolution (gh-75191, gh-110088): Windows @@ -256,8 +255,7 @@ - - + + def gen_unix_socket_path(): - with tempfile.NamedTemporaryFile() as file: - return file.name + return socket_helper.create_unix_domain_name() - - + + @contextlib.contextmanager diff --git a/Lib/test/test_asyncore.py b/Lib/test/test_asyncore.py index 98ccd3a9304..d7860853eba 100644 @@ -2446,14 +3743,14 @@ index 98ccd3a9304..d7860853eba 100644 +++ b/Lib/test/test_asyncore.py @@ -9,6 +9,7 @@ import threading - + from test import support +from test.support import is_apple_mobile from test.support import os_helper from test.support import socket_helper from test.support import threading_helper @@ -657,6 +658,7 @@ - + @unittest.skipIf(sys.platform.startswith("sunos"), "OOB support is broken on Solaris") + @unittest.skipIf(is_apple_mobile, "FIXME: edge case in removed test module") @@ -2467,7 +3764,7 @@ index cf28cf35159..54600eafefc 100644 @@ -1099,6 +1099,13 @@ self.addCleanup(os.close, r) self.addCleanup(os.close, w) - + + # Apple extensions must be distributed as frameworks. This requires + # a specialist loader. + if support.is_apple_mobile: @@ -2479,7 +3776,7 @@ index cf28cf35159..54600eafefc 100644 import importlib.machinery import importlib.util @@ -1106,7 +1113,7 @@ - + fullname = '_test_module_state_shared' origin = importlib.util.find_spec('_testmultiphase').origin - loader = importlib.machinery.ExtensionFileLoader(fullname, origin) @@ -2506,7 +3803,7 @@ index 7fcd563be27..2945b3f56b5 100644 --- a/Lib/test/test_cmd_line_script.py +++ b/Lib/test/test_cmd_line_script.py @@ -14,8 +14,7 @@ - + import textwrap from test import support -from test.support import import_helper @@ -2517,7 +3814,7 @@ index 7fcd563be27..2945b3f56b5 100644 assert_python_ok, assert_python_failure, spawn_python, kill_python) @@ -555,12 +554,17 @@ self.assertTrue(text[3].startswith('NameError')) - + def test_non_ascii(self): - # Mac OS X denies the creation of a file with an invalid UTF-8 name. + # Apple platforms deny the creation of a file with an invalid UTF-8 name. @@ -2544,11 +3841,396 @@ index 812f989d8f3..dfcf9e16e40 100644 @@ -49,6 +49,7 @@ self.assertEqual(len(executor._threads), 1) executor.shutdown(wait=True) - + + @support.requires_fork() @unittest.skipUnless(hasattr(os, 'register_at_fork'), 'need os.register_at_fork') @support.requires_resource('cpu') def test_hang_global_shutdown_lock(self): +diff --git a/Lib/test/test_email/test__header_value_parser.py b/Lib/test/test_email/test__header_value_parser.py +index f7e80749c45..0d9343478ce 100644 +--- a/Lib/test/test_email/test__header_value_parser.py ++++ b/Lib/test/test_email/test__header_value_parser.py +@@ -2986,9 +2986,17 @@ + ' =?utf-8?q?bei=C3=9Ft_bei=C3=9Ft?= \n') + + def test_address_list_with_list_separator_after_fold(self): +- to = '0123456789' * 8 + '@foo, ä ' ++ a = 'x' * 66 + '@example.com' ++ to = f'{a}, "Hübsch Kaktus" ' + self._test(parser.get_address_list(to)[0], +- '0123456789' * 8 + '@foo,\n =?utf-8?q?=C3=A4?= \n') ++ f'{a},\n =?utf-8?q?H=C3=BCbsch?= Kaktus \n') ++ ++ a = '.' * 79 ++ to = f'"{a}" , "Hübsch Kaktus" ' ++ self._test(parser.get_address_list(to)[0], ++ f'{a}\n' ++ ' , =?utf-8?q?H=C3=BCbsch?= Kaktus ' ++ '\n') + + # XXX Need tests with comments on various sides of a unicode token, + # and with unicode tokens in the comments. Spaces inside the quotes +diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py +index 785696e5c54..ad60ed3a759 100644 +--- a/Lib/test/test_email/test_email.py ++++ b/Lib/test/test_email/test_email.py +@@ -17,6 +17,7 @@ + + import email + import email.policy ++import email.utils + + from email.charset import Charset + from email.generator import Generator, DecodedGenerator, BytesGenerator +@@ -3336,15 +3337,154 @@ + [('Al Person', 'aperson@dom.ain'), + ('Bud Person', 'bperson@dom.ain')]) + ++ def test_getaddresses_comma_in_name(self): ++ """GH-106669 regression test.""" ++ self.assertEqual( ++ utils.getaddresses( ++ [ ++ '"Bud, Person" ', ++ 'aperson@dom.ain (Al Person)', ++ '"Mariusz Felisiak" ', ++ ] ++ ), ++ [ ++ ('Bud, Person', 'bperson@dom.ain'), ++ ('Al Person', 'aperson@dom.ain'), ++ ('Mariusz Felisiak', 'to@example.com'), ++ ], ++ ) ++ ++ def test_parsing_errors(self): ++ """Test for parsing errors from CVE-2023-27043 and CVE-2019-16056""" ++ alice = 'alice@example.org' ++ bob = 'bob@example.com' ++ empty = ('', '') ++ ++ # Test utils.getaddresses() and utils.parseaddr() on malformed email ++ # addresses: default behavior (strict=True) rejects malformed address, ++ # and strict=False which tolerates malformed address. ++ for invalid_separator, expected_non_strict in ( ++ ('(', [(f'<{bob}>', alice)]), ++ (')', [('', alice), empty, ('', bob)]), ++ ('<', [('', alice), empty, ('', bob), empty]), ++ ('>', [('', alice), empty, ('', bob)]), ++ ('[', [('', f'{alice}[<{bob}>]')]), ++ (']', [('', alice), empty, ('', bob)]), ++ ('@', [empty, empty, ('', bob)]), ++ (';', [('', alice), empty, ('', bob)]), ++ (':', [('', alice), ('', bob)]), ++ ('.', [('', alice + '.'), ('', bob)]), ++ ('"', [('', alice), ('', f'<{bob}>')]), ++ ): ++ address = f'{alice}{invalid_separator}<{bob}>' ++ with self.subTest(address=address): ++ self.assertEqual(utils.getaddresses([address]), ++ [empty]) ++ self.assertEqual(utils.getaddresses([address], strict=False), ++ expected_non_strict) ++ ++ self.assertEqual(utils.parseaddr([address]), ++ empty) ++ self.assertEqual(utils.parseaddr([address], strict=False), ++ ('', address)) ++ ++ # Comma (',') is treated differently depending on strict parameter. ++ # Comma without quotes. ++ address = f'{alice},<{bob}>' ++ self.assertEqual(utils.getaddresses([address]), ++ [('', alice), ('', bob)]) ++ self.assertEqual(utils.getaddresses([address], strict=False), ++ [('', alice), ('', bob)]) ++ self.assertEqual(utils.parseaddr([address]), ++ empty) ++ self.assertEqual(utils.parseaddr([address], strict=False), ++ ('', address)) ++ ++ # Real name between quotes containing comma. ++ address = '"Alice, alice@example.org" ' ++ expected_strict = ('Alice, alice@example.org', 'bob@example.com') ++ self.assertEqual(utils.getaddresses([address]), [expected_strict]) ++ self.assertEqual(utils.getaddresses([address], strict=False), [expected_strict]) ++ self.assertEqual(utils.parseaddr([address]), expected_strict) ++ self.assertEqual(utils.parseaddr([address], strict=False), ++ ('', address)) ++ ++ # Valid parenthesis in comments. ++ address = 'alice@example.org (Alice)' ++ expected_strict = ('Alice', 'alice@example.org') ++ self.assertEqual(utils.getaddresses([address]), [expected_strict]) ++ self.assertEqual(utils.getaddresses([address], strict=False), [expected_strict]) ++ self.assertEqual(utils.parseaddr([address]), expected_strict) ++ self.assertEqual(utils.parseaddr([address], strict=False), ++ ('', address)) ++ ++ # Invalid parenthesis in comments. ++ address = 'alice@example.org )Alice(' ++ self.assertEqual(utils.getaddresses([address]), [empty]) ++ self.assertEqual(utils.getaddresses([address], strict=False), ++ [('', 'alice@example.org'), ('', ''), ('', 'Alice')]) ++ self.assertEqual(utils.parseaddr([address]), empty) ++ self.assertEqual(utils.parseaddr([address], strict=False), ++ ('', address)) ++ ++ # Two addresses with quotes separated by comma. ++ address = '"Jane Doe" , "John Doe" ' ++ self.assertEqual(utils.getaddresses([address]), ++ [('Jane Doe', 'jane@example.net'), ++ ('John Doe', 'john@example.net')]) ++ self.assertEqual(utils.getaddresses([address], strict=False), ++ [('Jane Doe', 'jane@example.net'), ++ ('John Doe', 'john@example.net')]) ++ self.assertEqual(utils.parseaddr([address]), empty) ++ self.assertEqual(utils.parseaddr([address], strict=False), ++ ('', address)) ++ ++ # Test email.utils.supports_strict_parsing attribute ++ self.assertEqual(email.utils.supports_strict_parsing, True) ++ + def test_getaddresses_nasty(self): +- eq = self.assertEqual +- eq(utils.getaddresses(['foo: ;']), [('', '')]) +- eq(utils.getaddresses( +- ['[]*-- =~$']), +- [('', ''), ('', ''), ('', '*--')]) +- eq(utils.getaddresses( +- ['foo: ;', '"Jason R. Mastaler" ']), +- [('', ''), ('Jason R. Mastaler', 'jason@dom.ain')]) ++ for addresses, expected in ( ++ (['"Sürname, Firstname" '], ++ [('Sürname, Firstname', 'to@example.com')]), ++ ++ (['foo: ;'], ++ [('', '')]), ++ ++ (['foo: ;', '"Jason R. Mastaler" '], ++ [('', ''), ('Jason R. Mastaler', 'jason@dom.ain')]), ++ ++ ([r'Pete(A nice \) chap) '], ++ [('Pete (A nice ) chap his account his host)', 'pete@silly.test')]), ++ ++ (['(Empty list)(start)Undisclosed recipients :(nobody(I know))'], ++ [('', '')]), ++ ++ (['Mary <@machine.tld:mary@example.net>, , jdoe@test . example'], ++ [('Mary', 'mary@example.net'), ('', ''), ('', 'jdoe@test.example')]), ++ ++ (['John Doe '], ++ [('John Doe (comment)', 'jdoe@machine.example')]), ++ ++ (['"Mary Smith: Personal Account" '], ++ [('Mary Smith: Personal Account', 'smith@home.example')]), ++ ++ (['Undisclosed recipients:;'], ++ [('', '')]), ++ ++ ([r', "Giant; \"Big\" Box" '], ++ [('', 'boss@nil.test'), ('Giant; "Big" Box', 'bob@example.net')]), ++ ): ++ with self.subTest(addresses=addresses): ++ self.assertEqual(utils.getaddresses(addresses), ++ expected) ++ self.assertEqual(utils.getaddresses(addresses, strict=False), ++ expected) ++ ++ addresses = ['[]*-- =~$'] ++ self.assertEqual(utils.getaddresses(addresses), ++ [('', '')]) ++ self.assertEqual(utils.getaddresses(addresses, strict=False), ++ [('', ''), ('', ''), ('', '*--')]) + + def test_getaddresses_embedded_comment(self): + """Test proper handling of a nested comment""" +@@ -3535,6 +3675,54 @@ + m = cls(*constructor, policy=email.policy.default) + self.assertIs(m.policy, email.policy.default) + ++ def test_iter_escaped_chars(self): ++ self.assertEqual(list(utils._iter_escaped_chars(r'a\\b\"c\\"d')), ++ [(0, 'a'), ++ (2, '\\\\'), ++ (3, 'b'), ++ (5, '\\"'), ++ (6, 'c'), ++ (8, '\\\\'), ++ (9, '"'), ++ (10, 'd')]) ++ self.assertEqual(list(utils._iter_escaped_chars('a\\')), ++ [(0, 'a'), (1, '\\')]) ++ ++ def test_strip_quoted_realnames(self): ++ def check(addr, expected): ++ self.assertEqual(utils._strip_quoted_realnames(addr), expected) ++ ++ check('"Jane Doe" , "John Doe" ', ++ ' , ') ++ check(r'"Jane \"Doe\"." ', ++ ' ') ++ ++ # special cases ++ check(r'before"name"after', 'beforeafter') ++ check(r'before"name"', 'before') ++ check(r'b"name"', 'b') # single char ++ check(r'"name"after', 'after') ++ check(r'"name"a', 'a') # single char ++ check(r'"name"', '') ++ ++ # no change ++ for addr in ( ++ 'Jane Doe , John Doe ', ++ 'lone " quote', ++ ): ++ self.assertEqual(utils._strip_quoted_realnames(addr), addr) ++ ++ ++ def test_check_parenthesis(self): ++ addr = 'alice@example.net' ++ self.assertTrue(utils._check_parenthesis(f'{addr} (Alice)')) ++ self.assertFalse(utils._check_parenthesis(f'{addr} )Alice(')) ++ self.assertFalse(utils._check_parenthesis(f'{addr} (Alice))')) ++ self.assertFalse(utils._check_parenthesis(f'{addr} ((Alice)')) ++ ++ # Ignore real name between quotes ++ self.assertTrue(utils._check_parenthesis(f'")Alice((" {addr}')) ++ + + # Test the iterator/generators + class TestIterators(TestEmailBase): +diff --git a/Lib/test/test_email/test_generator.py b/Lib/test/test_email/test_generator.py +index 89e7edeb63a..d29400f0ed1 100644 +--- a/Lib/test/test_email/test_generator.py ++++ b/Lib/test/test_email/test_generator.py +@@ -6,6 +6,7 @@ + from email.generator import Generator, BytesGenerator + from email.headerregistry import Address + from email import policy ++import email.errors + from test.test_email import TestEmailBase, parameterize + + +@@ -216,6 +217,44 @@ + g.flatten(msg) + self.assertEqual(s.getvalue(), self.typ(expected)) + ++ def test_keep_encoded_newlines(self): ++ msg = self.msgmaker(self.typ(textwrap.dedent("""\ ++ To: nobody ++ Subject: Bad subject=?UTF-8?Q?=0A?=Bcc: injection@example.com ++ ++ None ++ """))) ++ expected = textwrap.dedent("""\ ++ To: nobody ++ Subject: Bad subject=?UTF-8?Q?=0A?=Bcc: injection@example.com ++ ++ None ++ """) ++ s = self.ioclass() ++ g = self.genclass(s, policy=self.policy.clone(max_line_length=80)) ++ g.flatten(msg) ++ self.assertEqual(s.getvalue(), self.typ(expected)) ++ ++ def test_keep_long_encoded_newlines(self): ++ msg = self.msgmaker(self.typ(textwrap.dedent("""\ ++ To: nobody ++ Subject: Bad subject=?UTF-8?Q?=0A?=Bcc: injection@example.com ++ ++ None ++ """))) ++ expected = textwrap.dedent("""\ ++ To: nobody ++ Subject: Bad subject ++ =?utf-8?q?=0A?=Bcc: ++ injection@example.com ++ ++ None ++ """) ++ s = self.ioclass() ++ g = self.genclass(s, policy=self.policy.clone(max_line_length=30)) ++ g.flatten(msg) ++ self.assertEqual(s.getvalue(), self.typ(expected)) ++ + + class TestGenerator(TestGeneratorBase, TestEmailBase): + +@@ -224,6 +263,29 @@ + ioclass = io.StringIO + typ = str + ++ def test_verify_generated_headers(self): ++ """gh-121650: by default the generator prevents header injection""" ++ class LiteralHeader(str): ++ name = 'Header' ++ def fold(self, **kwargs): ++ return self ++ ++ for text in ( ++ 'Value\r\nBad Injection\r\n', ++ 'NoNewLine' ++ ): ++ with self.subTest(text=text): ++ message = message_from_string( ++ "Header: Value\r\n\r\nBody", ++ policy=self.policy, ++ ) ++ ++ del message['Header'] ++ message['Header'] = LiteralHeader(text) ++ ++ with self.assertRaises(email.errors.HeaderWriteError): ++ message.as_string() ++ + + class TestBytesGenerator(TestGeneratorBase, TestEmailBase): + +diff --git a/Lib/test/test_email/test_policy.py b/Lib/test/test_email/test_policy.py +index c6b9c80efe1..baa35fd68e4 100644 +--- a/Lib/test/test_email/test_policy.py ++++ b/Lib/test/test_email/test_policy.py +@@ -26,6 +26,7 @@ + 'raise_on_defect': False, + 'mangle_from_': True, + 'message_factory': None, ++ 'verify_generated_headers': True, + } + # These default values are the ones set on email.policy.default. + # If any of these defaults change, the docs must be updated. +@@ -294,6 +295,31 @@ + with self.assertRaises(email.errors.HeaderParseError): + policy.fold("Subject", subject) + ++ def test_verify_generated_headers(self): ++ """Turning protection off allows header injection""" ++ policy = email.policy.default.clone(verify_generated_headers=False) ++ for text in ( ++ 'Header: Value\r\nBad: Injection\r\n', ++ 'Header: NoNewLine' ++ ): ++ with self.subTest(text=text): ++ message = email.message_from_string( ++ "Header: Value\r\n\r\nBody", ++ policy=policy, ++ ) ++ class LiteralHeader(str): ++ name = 'Header' ++ def fold(self, **kwargs): ++ return self ++ ++ del message['Header'] ++ message['Header'] = LiteralHeader(text) ++ ++ self.assertEqual( ++ message.as_string(), ++ f"{text}\nBody", ++ ) ++ + # XXX: Need subclassing tests. + # For adding subclassed objects, make sure the usual rules apply (subclass + # wins), but that the order still works (right overrides left). diff --git a/Lib/test/test_fcntl.py b/Lib/test/test_fcntl.py index 8e98256a62c..7681e829d8b 100644 --- a/Lib/test/test_fcntl.py @@ -2561,10 +4243,10 @@ index 8e98256a62c..7681e829d8b 100644 +from test.support import cpython_only, is_apple, requires_subprocess, verbose from test.support.import_helper import import_module from test.support.os_helper import TESTFN, unlink - + @@ -25,7 +25,7 @@ start_len = "qq" - + if (sys.platform.startswith(('netbsd', 'freebsd', 'openbsd')) - or sys.platform == 'darwin'): + or is_apple): @@ -2573,7 +4255,7 @@ index 8e98256a62c..7681e829d8b 100644 pid_t = 'i' @@ -156,6 +156,7 @@ self.assertRaises(TypeError, fcntl.flock, 'spam', fcntl.LOCK_SH) - + @unittest.skipIf(platform.system() == "AIX", "AIX returns PermissionError") + @requires_subprocess() def test_lockf_exclusive(self): @@ -2581,7 +4263,7 @@ index 8e98256a62c..7681e829d8b 100644 cmd = fcntl.LOCK_EX | fcntl.LOCK_NB @@ -167,6 +168,7 @@ self.assertEqual(p.exitcode, 0) - + @unittest.skipIf(platform.system() == "AIX", "AIX returns PermissionError") + @requires_subprocess() def test_lockf_share(self): @@ -2592,7 +4274,7 @@ index d813ecdcd6f..38e405933b2 100644 --- a/Lib/test/test_ftplib.py +++ b/Lib/test/test_ftplib.py @@ -18,6 +18,7 @@ - + from unittest import TestCase, skipUnless from test import support +from test.support import requires_subprocess @@ -2600,29 +4282,29 @@ index d813ecdcd6f..38e405933b2 100644 from test.support import socket_helper from test.support import warnings_helper @@ -902,6 +903,7 @@ - - + + @skipUnless(ssl, "SSL not available") +@requires_subprocess() class TestTLS_FTPClassMixin(TestFTPClass): """Repeat TestFTPClass tests starting the TLS layer for both control and data connections first. @@ -918,6 +920,7 @@ - - + + @skipUnless(ssl, "SSL not available") +@requires_subprocess() class TestTLS_FTPClass(TestCase): """Specific TLS_FTP class tests.""" - + diff --git a/Lib/test/test_gc.py b/Lib/test/test_gc.py index 01578539eb3..90669f5ff45 100644 --- a/Lib/test/test_gc.py +++ b/Lib/test/test_gc.py @@ -1188,6 +1188,7 @@ self.assertEqual(len(gc.garbage), 0) - - + + + @requires_subprocess() @unittest.skipIf(BUILD_WITH_NDEBUG, 'built with -NDEBUG') @@ -2643,10 +4325,10 @@ index 4f311c2d498..b77cd4c67d6 100644 +) from test.support.script_helper import assert_python_ok from test.support.os_helper import FakePath - + @@ -483,12 +483,16 @@ self.assertIsInstance(abspath(path), str) - + def test_nonascii_abspath(self): - if (os_helper.TESTFN_UNDECODABLE - # macOS and Emscripten deny the creation of a directory with an @@ -2667,12 +4349,68 @@ index 4f311c2d498..b77cd4c67d6 100644 name = os_helper.TESTFN_UNDECODABLE elif os_helper.TESTFN_NONASCII: name = os_helper.TESTFN_NONASCII +diff --git a/Lib/test/test_http_cookies.py b/Lib/test/test_http_cookies.py +index 925c8697f60..8879902a6e2 100644 +--- a/Lib/test/test_http_cookies.py ++++ b/Lib/test/test_http_cookies.py +@@ -5,6 +5,7 @@ + import doctest + from http import cookies + import pickle ++from test import support + + + class CookieTests(unittest.TestCase): +@@ -58,6 +59,43 @@ + for k, v in sorted(case['dict'].items()): + self.assertEqual(C[k].value, v) + ++ def test_unquote(self): ++ cases = [ ++ (r'a="b=\""', 'b="'), ++ (r'a="b=\\"', 'b=\\'), ++ (r'a="b=\="', 'b=='), ++ (r'a="b=\n"', 'b=n'), ++ (r'a="b=\042"', 'b="'), ++ (r'a="b=\134"', 'b=\\'), ++ (r'a="b=\377"', 'b=\xff'), ++ (r'a="b=\400"', 'b=400'), ++ (r'a="b=\42"', 'b=42'), ++ (r'a="b=\\042"', 'b=\\042'), ++ (r'a="b=\\134"', 'b=\\134'), ++ (r'a="b=\\\""', 'b=\\"'), ++ (r'a="b=\\\042"', 'b=\\"'), ++ (r'a="b=\134\""', 'b=\\"'), ++ (r'a="b=\134\042"', 'b=\\"'), ++ ] ++ for encoded, decoded in cases: ++ with self.subTest(encoded): ++ C = cookies.SimpleCookie() ++ C.load(encoded) ++ self.assertEqual(C['a'].value, decoded) ++ ++ @support.requires_resource('cpu') ++ def test_unquote_large(self): ++ n = 10**6 ++ for encoded in r'\\', r'\134': ++ with self.subTest(encoded): ++ data = 'a="b=' + encoded*n + ';"' ++ C = cookies.SimpleCookie() ++ C.load(data) ++ value = C['a'].value ++ self.assertEqual(value[:3], 'b=\\') ++ self.assertEqual(value[-2:], '\\;') ++ self.assertEqual(len(value), n + 3) ++ + def test_load(self): + C = cookies.SimpleCookie() + C.load('Customer="WILE_E_COYOTE"; Version=1; Path=/acme') diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py index cfd8a101dcc..b8ac2544be5 100644 --- a/Lib/test/test_httpservers.py +++ b/Lib/test/test_httpservers.py @@ -30,8 +30,9 @@ - + import unittest from test import support -from test.support import os_helper @@ -2680,13 +4418,13 @@ index cfd8a101dcc..b8ac2544be5 100644 +from test.support import ( + is_apple, os_helper, requires_subprocess, threading_helper +) - + support.requires_working_socket(module=True) - + @@ -410,8 +411,8 @@ reader.close() return body - + - @unittest.skipIf(sys.platform == 'darwin', - 'undecodable name cannot always be decoded on macOS') + @unittest.skipIf(is_apple, @@ -2711,7 +4449,7 @@ index cfd8a101dcc..b8ac2544be5 100644 break body = self.check_status_and_reason(response, HTTPStatus.OK) @@ -697,6 +698,7 @@ - + @unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0, "This test can't be run reliably as root (issue #13308).") +@requires_subprocess() @@ -2732,7 +4470,7 @@ index aa67cc3514e..7c684c5799f 100644 import warnings @@ -234,6 +235,7 @@ self.assertIsNot(orig_getenv, new_os.getenv) - + @requires_load_dynamic + @unittest.skipIf(is_apple_mobile, "FIXME: edge case of module loader") def test_issue15828_load_extensions(self): @@ -2740,7 +4478,7 @@ index aa67cc3514e..7c684c5799f 100644 # and importlib couldn't handle C extensions @@ -246,6 +248,7 @@ self.assertEqual(mod.__name__, example) - + @requires_load_dynamic + @unittest.skipIf(is_apple_mobile, "FIXME: edge case of module loader") def test_issue16421_multiple_modules_in_one_dll(self): @@ -2748,7 +4486,7 @@ index aa67cc3514e..7c684c5799f 100644 m = '_testimportmultiple' @@ -273,6 +276,7 @@ self.assertEqual(name, err.exception.name) - + @requires_load_dynamic + @unittest.skipIf(is_apple_mobile, "FIXME: edge case of module loader") def test_load_module_extension_file_is_None(self): @@ -2756,7 +4494,7 @@ index aa67cc3514e..7c684c5799f 100644 # on the behalf of imp.load_dynamic(). @@ -286,6 +290,7 @@ imp.load_module(name, None, *found[1:]) - + @requires_load_dynamic + @unittest.skipIf(is_apple_mobile, "FIXME: edge case of module loader") def test_issue24748_load_module_skips_sys_modules_check(self): @@ -2767,7 +4505,7 @@ index f991f323573..b80a29f697c 100644 --- a/Lib/test/test_import/__init__.py +++ b/Lib/test/test_import/__init__.py @@ -20,7 +20,7 @@ - + from test.support import os_helper from test.support import ( - STDLIB_DIR, is_jython, swap_attr, swap_item, cpython_only, is_emscripten, @@ -2791,11 +4529,11 @@ index 3de120958fd..cdc8884d668 100644 @@ -1,3 +1,4 @@ +from test.support import is_apple_mobile from test.test_importlib import abc, util - + machinery = util.import_importlib('importlib.machinery') @@ -19,9 +20,27 @@ ) - + def find_spec(self, fullname): - importer = self.machinery.FileFinder(util.EXTENSIONS.path, - (self.machinery.ExtensionFileLoader, @@ -2821,9 +4559,9 @@ index 3de120958fd..cdc8884d668 100644 + ] + + importer = self.machinery.FileFinder(util.EXTENSIONS.path, *loaders) - + return importer.find_spec(fullname) - + diff --git a/Lib/test/test_importlib/extension/test_loader.py b/Lib/test/test_importlib/extension/test_loader.py index 2519149c071..828b6f0dfd3 100644 --- a/Lib/test/test_importlib/extension/test_loader.py @@ -2832,7 +4570,7 @@ index 2519149c071..828b6f0dfd3 100644 +from test.support import is_apple_mobile from warnings import catch_warnings from test.test_importlib import abc, util - + @@ -25,8 +26,15 @@ raise unittest.SkipTest( f"{util.EXTENSIONS.name} is a builtin module" @@ -2848,24 +4586,24 @@ index 2519149c071..828b6f0dfd3 100644 + self.LoaderClass = self.machinery.ExtensionFileLoader + + self.loader = self.LoaderClass(util.EXTENSIONS.name, util.EXTENSIONS.file_path) - + def load_module(self, fullname): with warnings.catch_warnings(): @@ -43,13 +51,11 @@ self.load_module('XXX') - + def test_equality(self): - other = self.machinery.ExtensionFileLoader(util.EXTENSIONS.name, - util.EXTENSIONS.file_path) + other = self.LoaderClass(util.EXTENSIONS.name, util.EXTENSIONS.file_path) self.assertEqual(self.loader, other) - + def test_inequality(self): - other = self.machinery.ExtensionFileLoader('_' + util.EXTENSIONS.name, - util.EXTENSIONS.file_path) + other = self.LoaderClass('_' + util.EXTENSIONS.name, util.EXTENSIONS.file_path) self.assertNotEqual(self.loader, other) - + def test_module(self): @@ -60,8 +66,7 @@ ('__package__', '')]: @@ -2874,7 +4612,7 @@ index 2519149c071..828b6f0dfd3 100644 - self.assertIsInstance(module.__loader__, - self.machinery.ExtensionFileLoader) + self.assertIsInstance(module.__loader__, self.LoaderClass) - + # No extension module as __init__ available for testing. test_package = None @@ -88,7 +93,7 @@ @@ -2884,7 +4622,7 @@ index 2519149c071..828b6f0dfd3 100644 - loader = self.machinery.ExtensionFileLoader('pkg', path) + loader = self.LoaderClass('pkg', path) self.assertTrue(loader.is_package('pkg')) - + (Frozen_LoaderTests, @@ -101,6 +106,14 @@ def setUp(self): @@ -2908,7 +4646,7 @@ index 2519149c071..828b6f0dfd3 100644 - self.loader = self.machinery.ExtensionFileLoader( - self.name, self.spec.origin) + self.loader = self.LoaderClass(self.name, self.spec.origin) - + def load_module(self): # Load the module from the test extension. @@ -121,7 +133,7 @@ @@ -2927,7 +4665,7 @@ index 2519149c071..828b6f0dfd3 100644 - self.assertIsInstance(module.__loader__, - self.machinery.ExtensionFileLoader) + self.assertIsInstance(module.__loader__, self.LoaderClass) - + def test_functionality(self): # Test basic functionality of stuff defined in an extension module. diff --git a/Lib/test/test_importlib/util.py b/Lib/test/test_importlib/util.py @@ -2961,7 +4699,7 @@ index 5abb66c7ae4..f69f9bd38b8 100644 @@ -25,7 +25,7 @@ except ImportError: ThreadPoolExecutor = None - + -from test.support import cpython_only +from test.support import cpython_only, is_apple_mobile from test.support import MISSING_C_DOCSTRINGS, ALWAYS_EQ @@ -2976,7 +4714,7 @@ index 5abb66c7ae4..f69f9bd38b8 100644 self.assertRaises(OSError, inspect.getsource, unicodedata) self.assertRaises(OSError, inspect.findsource, unicodedata) diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py -index 537c9fa7b98..bc356219f9a 100644 +index 537c9fa7b98..22d17a2a829 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -39,11 +39,9 @@ @@ -2992,11 +4730,11 @@ index 537c9fa7b98..bc356219f9a 100644 + import_helper, is_apple, os_helper, skip_if_sanitizer, threading_helper, warnings_helper +) from test.support.os_helper import FakePath - + import codecs @@ -631,10 +629,10 @@ self.read_ops(f, True) - + def test_large_file_ops(self): - # On Windows and Mac OSX this test consumes large resources; It takes - # a long time to build the >2 GiB file and takes >2 GiB of disk space @@ -3009,6 +4747,89 @@ index 537c9fa7b98..bc356219f9a 100644 support.requires( 'largefile', 'test requires %s bytes and a long time to run' % self.LARGE) +@@ -3960,6 +3958,28 @@ + t.write("x"*chunk_size) + self.assertEqual([b"abcdef", b"ghi", b"x"*chunk_size], buf._write_stack) + ++ def test_issue119506(self): ++ chunk_size = 8192 ++ ++ class MockIO(self.MockRawIO): ++ written = False ++ def write(self, data): ++ if not self.written: ++ self.written = True ++ t.write("middle") ++ return super().write(data) ++ ++ buf = MockIO() ++ t = self.TextIOWrapper(buf) ++ t.write("abc") ++ t.write("def") ++ # writing data which size >= chunk_size cause flushing buffer before write. ++ t.write("g" * chunk_size) ++ t.flush() ++ ++ self.assertEqual([b"abcdef", b"middle", b"g"*chunk_size], ++ buf._write_stack) ++ + + class PyTextIOWrapperTest(TextIOWrapperTest): + io = pyio +diff --git a/Lib/test/test_ipaddress.py b/Lib/test/test_ipaddress.py +index fc27628af17..16c34163a00 100644 +--- a/Lib/test/test_ipaddress.py ++++ b/Lib/test/test_ipaddress.py +@@ -2269,6 +2269,10 @@ + self.assertEqual(True, ipaddress.ip_address( + '172.31.255.255').is_private) + self.assertEqual(False, ipaddress.ip_address('172.32.0.0').is_private) ++ self.assertFalse(ipaddress.ip_address('192.0.0.0').is_global) ++ self.assertTrue(ipaddress.ip_address('192.0.0.9').is_global) ++ self.assertTrue(ipaddress.ip_address('192.0.0.10').is_global) ++ self.assertFalse(ipaddress.ip_address('192.0.0.255').is_global) + + self.assertEqual(True, + ipaddress.ip_address('169.254.100.200').is_link_local) +@@ -2294,6 +2298,7 @@ + self.assertEqual(True, ipaddress.ip_network("169.254.0.0/16").is_private) + self.assertEqual(True, ipaddress.ip_network("172.16.0.0/12").is_private) + self.assertEqual(True, ipaddress.ip_network("192.0.0.0/29").is_private) ++ self.assertEqual(False, ipaddress.ip_network("192.0.0.9/32").is_private) + self.assertEqual(True, ipaddress.ip_network("192.0.0.170/31").is_private) + self.assertEqual(True, ipaddress.ip_network("192.0.2.0/24").is_private) + self.assertEqual(True, ipaddress.ip_network("192.168.0.0/16").is_private) +@@ -2310,8 +2315,8 @@ + self.assertEqual(True, ipaddress.ip_network("::/128").is_private) + self.assertEqual(True, ipaddress.ip_network("::ffff:0:0/96").is_private) + self.assertEqual(True, ipaddress.ip_network("100::/64").is_private) +- self.assertEqual(True, ipaddress.ip_network("2001::/23").is_private) + self.assertEqual(True, ipaddress.ip_network("2001:2::/48").is_private) ++ self.assertEqual(False, ipaddress.ip_network("2001:3::/48").is_private) + self.assertEqual(True, ipaddress.ip_network("2001:db8::/32").is_private) + self.assertEqual(True, ipaddress.ip_network("2001:10::/28").is_private) + self.assertEqual(True, ipaddress.ip_network("fc00::/7").is_private) +@@ -2390,6 +2395,20 @@ + self.assertEqual(True, ipaddress.ip_address('0::0').is_unspecified) + self.assertEqual(False, ipaddress.ip_address('::1').is_unspecified) + ++ self.assertFalse(ipaddress.ip_address('64:ff9b:1::').is_global) ++ self.assertFalse(ipaddress.ip_address('2001::').is_global) ++ self.assertTrue(ipaddress.ip_address('2001:1::1').is_global) ++ self.assertTrue(ipaddress.ip_address('2001:1::2').is_global) ++ self.assertFalse(ipaddress.ip_address('2001:2::').is_global) ++ self.assertTrue(ipaddress.ip_address('2001:3::').is_global) ++ self.assertFalse(ipaddress.ip_address('2001:4::').is_global) ++ self.assertTrue(ipaddress.ip_address('2001:4:112::').is_global) ++ self.assertFalse(ipaddress.ip_address('2001:10::').is_global) ++ self.assertTrue(ipaddress.ip_address('2001:20::').is_global) ++ self.assertTrue(ipaddress.ip_address('2001:30::').is_global) ++ self.assertFalse(ipaddress.ip_address('2001:40::').is_global) ++ self.assertFalse(ipaddress.ip_address('2002::').is_global) ++ + # some generic IETF reserved addresses + self.assertEqual(True, ipaddress.ip_address('100::').is_reserved) + self.assertEqual(True, ipaddress.ip_network('4000::1/128').is_reserved) diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index fbaafde881c..7117b160949 100644 --- a/Lib/test/test_logging.py @@ -3024,7 +4845,7 @@ index fbaafde881c..7117b160949 100644 @@ -2003,6 +2004,7 @@ self.handled.wait(support.LONG_TIMEOUT) self.assertEqual(self.log_output, b'<11>h\xc3\xa4m-sp\xc3\xa4m') - + + @unittest.skipIf(is_apple_mobile, "FIXME: Edge case of logging setup") def test_udp_reconnection(self): logger = logging.getLogger("slh") @@ -3062,7 +4883,7 @@ index 1867e8c957f..f75e40940e4 100644 from test.support.os_helper import TESTFN, unlink @@ -1009,7 +1009,7 @@ unlink(TESTFN) - + def _make_test_file(self, num_zeroes, tail): - if sys.platform[:3] == 'win' or sys.platform == 'darwin': + if sys.platform[:3] == 'win' or is_apple: @@ -3070,10 +4891,29 @@ index 1867e8c957f..f75e40940e4 100644 'test requires %s bytes and a long time to run' % str(0x180000000)) f = open(TESTFN, 'w+b') diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py -index 3dab98d4577..2058c54e156 100644 +index 3dab98d4577..7b6497a2619 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py -@@ -2286,6 +2286,7 @@ +@@ -1743,6 +1743,18 @@ + self.assertRaises(OSError, os.makedirs, path, exist_ok=True) + os.remove(path) + ++ @unittest.skipUnless(os.name == 'nt', "requires Windows") ++ def test_win32_mkdir_700(self): ++ base = os_helper.TESTFN ++ path = os.path.abspath(os.path.join(os_helper.TESTFN, 'dir')) ++ os.mkdir(path, mode=0o700) ++ out = subprocess.check_output(["cacls.exe", path, "/s"], encoding="oem") ++ os.rmdir(path) ++ self.assertEqual( ++ out.strip(), ++ f'{path} "D:P(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;FA;;;OW)"', ++ ) ++ + def tearDown(self): + path = os.path.join(os_helper.TESTFN, 'dir1', 'dir2', 'dir3', + 'dir4', 'dir5', 'dir6') +@@ -2286,6 +2298,7 @@ support.is_emscripten or support.is_wasi, "musl libc issue on Emscripten/WASI, bpo-46390" ) @@ -3081,14 +4921,14 @@ index 3dab98d4577..2058c54e156 100644 def test_fpathconf(self): self.check(os.pathconf, "PC_NAME_MAX") self.check(os.fpathconf, "PC_NAME_MAX") -@@ -3750,6 +3751,7 @@ +@@ -3750,6 +3763,7 @@ self.assertGreaterEqual(size.columns, 0) self.assertGreaterEqual(size.lines, 0) - + + @support.requires_subprocess() def test_stty_match(self): """Check if stty returns the same results - + diff --git a/Lib/test/test_platform.py b/Lib/test/test_platform.py index 4569e30ce86..fceeb4cbfa3 100644 --- a/Lib/test/test_platform.py @@ -3096,7 +4936,7 @@ index 4569e30ce86..fceeb4cbfa3 100644 @@ -10,6 +10,14 @@ from test import support from test.support import os_helper - + +try: + # Some of the iOS tests need ctypes to operate. + # Confirm that the ctypes module is available @@ -3111,7 +4951,7 @@ index 4569e30ce86..fceeb4cbfa3 100644 @@ -229,6 +237,29 @@ self.assertEqual(res[-1], res.processor) self.assertEqual(len(res), 6) - + + if os.name == "posix": + uname = os.uname() + self.assertEqual(res.node, uname.nodename) @@ -3141,7 +4981,7 @@ index 4569e30ce86..fceeb4cbfa3 100644 @@ -400,6 +431,56 @@ # parent support.wait_process(pid, exitcode=0) - + + def test_ios_ver(self): + result = platform.ios_ver() + @@ -3211,7 +5051,7 @@ index 221d25a4d62..a4f473b58ec 100644 +++ b/Lib/test/test_posix.py @@ -1,7 +1,7 @@ "Test posix functions" - + from test import support -from test.support import import_helper +from test.support import is_apple @@ -3219,7 +5059,7 @@ index 221d25a4d62..a4f473b58ec 100644 from test.support import warnings_helper from test.support.script_helper import assert_python_ok @@ -561,6 +561,7 @@ - + @unittest.skipUnless(hasattr(posix, 'confstr'), 'test needs posix.confstr()') + @unittest.skipIf(support.is_apple_mobile, "gh-118201: Test is flaky on iOS") @@ -3250,21 +5090,21 @@ index 221d25a4d62..a4f473b58ec 100644 + if not is_apple: self.assertRaises(OSError, posix.sched_get_priority_min, -23) self.assertRaises(OSError, posix.sched_get_priority_max, -23) - + @@ -2036,11 +2038,13 @@ - - + + @unittest.skipUnless(hasattr(os, 'posix_spawn'), "test needs os.posix_spawn") +@support.requires_subprocess() class TestPosixSpawn(unittest.TestCase, _PosixSpawnMixin): spawn_func = getattr(posix, 'posix_spawn', None) - - + + @unittest.skipUnless(hasattr(os, 'posix_spawnp'), "test needs os.posix_spawnp") +@support.requires_subprocess() class TestPosixSpawnP(unittest.TestCase, _PosixSpawnMixin): spawn_func = getattr(posix, 'posix_spawnp', None) - + diff --git a/Lib/test/test_pty.py b/Lib/test/test_pty.py index 51e3a46d0df..3f2bac0155f 100644 --- a/Lib/test/test_pty.py @@ -3279,7 +5119,7 @@ index 51e3a46d0df..3f2bac0155f 100644 +) from test.support.import_helper import import_module +from test.support.os_helper import TESTFN, unlink - + -# Skip these tests if termios or fcntl are not available +# Skip these tests if termios is not available import_module('termios') @@ -3290,7 +5130,7 @@ index 51e3a46d0df..3f2bac0155f 100644 +# Skip tests on WASM platforms, plus iOS/tvOS/watchOS +if is_apple_mobile or is_emscripten or is_wasi: + raise unittest.SkipTest(f"pty tests not required on {sys.platform}") - + import errno import os @@ -17,7 +22,6 @@ @@ -3299,7 +5139,7 @@ index 51e3a46d0df..3f2bac0155f 100644 import io # readline -import unittest import warnings - + TEST_STRING_1 = b"I wish to buy a fish license.\n" diff --git a/Lib/test/test_selectors.py b/Lib/test/test_selectors.py index 31757205ca3..6b88b121580 100644 @@ -3330,15 +5170,15 @@ index 6728d309589..e85ff0fdcfa 100644 +++ b/Lib/test/test_shutil.py @@ -1906,6 +1906,7 @@ check_chown(dirname, uid, gid) - - + + +@support.requires_subprocess() class TestWhich(BaseTest, unittest.TestCase): - + def setUp(self): @@ -2801,6 +2802,7 @@ self.assertGreaterEqual(size.lines, 0) - + @unittest.skipUnless(os.isatty(sys.__stdout__.fileno()), "not on tty") + @support.requires_subprocess() @unittest.skipUnless(hasattr(os, 'get_terminal_size'), @@ -3363,7 +5203,7 @@ index 3711e7d1c6c..8003f3a226c 100644 except ImportError: @@ -832,7 +833,7 @@ self.assertEqual(self.hndl_called, True) - + # Issue 3864, unknown if this affects earlier versions of freebsd also - @unittest.skipIf(sys.platform in ('netbsd5',), + @unittest.skipIf(sys.platform in ('netbsd5',) or is_apple_mobile, @@ -3373,14 +5213,14 @@ index 3711e7d1c6c..8003f3a226c 100644 @@ -1352,7 +1353,7 @@ # Python handler self.assertEqual(len(sigs), N, "Some signals were lost") - + - @unittest.skipIf(sys.platform == "darwin", "crashes due to system bug (FB13453490)") + @unittest.skipIf(is_apple, "crashes due to system bug (FB13453490)") @unittest.skipUnless(hasattr(signal, "SIGUSR1"), "test needs SIGUSR1") @threading_helper.requires_working_threading() diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py -index 42adc573ecc..96b51d32c25 100644 +index 42adc573ecc..92ffda88617 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -3,6 +3,7 @@ @@ -3388,19 +5228,50 @@ index 42adc573ecc..96b51d32c25 100644 from test.support import socket_helper from test.support import threading_helper +from test.support import is_apple - + import errno import io -@@ -676,7 +677,7 @@ +@@ -542,19 +543,27 @@ + def __init__(self, methodName='runTest'): + unittest.TestCase.__init__(self, methodName=methodName) + ThreadableTest.__init__(self) ++ self.cli = None ++ self.serv = None ++ ++ def socketpair(self): ++ # To be overridden by some child classes. ++ return socket.socketpair() + + def setUp(self): +- self.serv, self.cli = socket.socketpair() ++ self.serv, self.cli = self.socketpair() + + def tearDown(self): +- self.serv.close() ++ if self.serv: ++ self.serv.close() + self.serv = None + + def clientSetUp(self): + pass + + def clientTearDown(self): +- self.cli.close() ++ if self.cli: ++ self.cli.close() + self.cli = None + ThreadableTest.clientTearDown(self) + +@@ -676,7 +685,7 @@ super().setUp() - + def bindSock(self, sock): - path = tempfile.mktemp(dir=self.dir_path) + path = socket_helper.create_unix_domain_name() socket_helper.bind_unix_socket(sock, path) self.addCleanup(os_helper.unlink, path) - -@@ -1153,8 +1154,11 @@ + +@@ -1153,8 +1162,11 @@ # Find one service that exists, then check all the related interfaces. # I've ordered this by protocols that have both a tcp and udp # protocol, at least for modern Linuxes. @@ -3414,9 +5285,9 @@ index 42adc573ecc..96b51d32c25 100644 # avoid the 'echo' service on this platform, as there is an # assumption breaking non-standard port/protocol entry services = ('daytime', 'qotd', 'domain') -@@ -1916,12 +1920,13 @@ +@@ -1916,12 +1928,13 @@ self._test_socket_fileno(s, socket.AF_INET6, socket.SOCK_STREAM) - + if hasattr(socket, "AF_UNIX"): - tmpdir = tempfile.mkdtemp() - self.addCleanup(shutil.rmtree, tmpdir) @@ -3431,51 +5302,164 @@ index 42adc573ecc..96b51d32c25 100644 except PermissionError: pass else: -@@ -3564,7 +3569,7 @@ +@@ -3564,7 +3577,7 @@ def _testFDPassCMSG_LEN(self): self.createAndSendFDs(1) - + - @unittest.skipIf(sys.platform == "darwin", "skipping, see issue #12958") + @unittest.skipIf(is_apple, "skipping, see issue #12958") @unittest.skipIf(AIX, "skipping, see issue #22397") @requireAttrs(socket, "CMSG_SPACE") def testFDPassSeparate(self): -@@ -3575,7 +3580,7 @@ +@@ -3575,7 +3588,7 @@ maxcmsgs=2) - + @testFDPassSeparate.client_skip - @unittest.skipIf(sys.platform == "darwin", "skipping, see issue #12958") + @unittest.skipIf(is_apple, "skipping, see issue #12958") @unittest.skipIf(AIX, "skipping, see issue #22397") def _testFDPassSeparate(self): fd0, fd1 = self.newFDs(2) -@@ -3588,7 +3593,7 @@ +@@ -3588,7 +3601,7 @@ array.array("i", [fd1]))]), len(MSG)) - + - @unittest.skipIf(sys.platform == "darwin", "skipping, see issue #12958") + @unittest.skipIf(is_apple, "skipping, see issue #12958") @unittest.skipIf(AIX, "skipping, see issue #22397") @requireAttrs(socket, "CMSG_SPACE") def testFDPassSeparateMinSpace(self): -@@ -3602,7 +3607,7 @@ +@@ -3602,7 +3615,7 @@ maxcmsgs=2, ignoreflags=socket.MSG_CTRUNC) - + @testFDPassSeparateMinSpace.client_skip - @unittest.skipIf(sys.platform == "darwin", "skipping, see issue #12958") + @unittest.skipIf(is_apple, "skipping, see issue #12958") @unittest.skipIf(AIX, "skipping, see issue #22397") def _testFDPassSeparateMinSpace(self): fd0, fd1 = self.newFDs(2) -@@ -3626,7 +3631,7 @@ +@@ -3626,7 +3639,7 @@ nbytes = self.sendmsgToServer([msg]) self.assertEqual(nbytes, len(msg)) - + - @unittest.skipIf(sys.platform == "darwin", "see issue #24725") + @unittest.skipIf(is_apple, "skipping, see issue #12958") def testFDPassEmpty(self): # Try to pass an empty FD array. Can receive either no array # or an empty array. +@@ -4667,6 +4680,112 @@ + self.assertEqual(msg, MSG) + + ++class PurePythonSocketPairTest(SocketPairTest): ++ # Explicitly use socketpair AF_INET or AF_INET6 to ensure that is the ++ # code path we're using regardless platform is the pure python one where ++ # `_socket.socketpair` does not exist. (AF_INET does not work with ++ # _socket.socketpair on many platforms). ++ def socketpair(self): ++ # called by super().setUp(). ++ try: ++ return socket.socketpair(socket.AF_INET6) ++ except OSError: ++ return socket.socketpair(socket.AF_INET) ++ ++ # Local imports in this class make for easy security fix backporting. ++ ++ def setUp(self): ++ if hasattr(_socket, "socketpair"): ++ self._orig_sp = socket.socketpair ++ # This forces the version using the non-OS provided socketpair ++ # emulation via an AF_INET socket in Lib/socket.py. ++ socket.socketpair = socket._fallback_socketpair ++ else: ++ # This platform already uses the non-OS provided version. ++ self._orig_sp = None ++ super().setUp() ++ ++ def tearDown(self): ++ super().tearDown() ++ if self._orig_sp is not None: ++ # Restore the default socket.socketpair definition. ++ socket.socketpair = self._orig_sp ++ ++ def test_recv(self): ++ msg = self.serv.recv(1024) ++ self.assertEqual(msg, MSG) ++ ++ def _test_recv(self): ++ self.cli.send(MSG) ++ ++ def test_send(self): ++ self.serv.send(MSG) ++ ++ def _test_send(self): ++ msg = self.cli.recv(1024) ++ self.assertEqual(msg, MSG) ++ ++ def test_ipv4(self): ++ cli, srv = socket.socketpair(socket.AF_INET) ++ cli.close() ++ srv.close() ++ ++ def _test_ipv4(self): ++ pass ++ ++ @unittest.skipIf(not hasattr(_socket, 'IPPROTO_IPV6') or ++ not hasattr(_socket, 'IPV6_V6ONLY'), ++ "IPV6_V6ONLY option not supported") ++ @unittest.skipUnless(socket_helper.IPV6_ENABLED, 'IPv6 required for this test') ++ def test_ipv6(self): ++ cli, srv = socket.socketpair(socket.AF_INET6) ++ cli.close() ++ srv.close() ++ ++ def _test_ipv6(self): ++ pass ++ ++ def test_injected_authentication_failure(self): ++ orig_getsockname = socket.socket.getsockname ++ inject_sock = None ++ ++ def inject_getsocketname(self): ++ nonlocal inject_sock ++ sockname = orig_getsockname(self) ++ # Connect to the listening socket ahead of the ++ # client socket. ++ if inject_sock is None: ++ inject_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ++ inject_sock.setblocking(False) ++ try: ++ inject_sock.connect(sockname[:2]) ++ except (BlockingIOError, InterruptedError): ++ pass ++ inject_sock.setblocking(True) ++ return sockname ++ ++ sock1 = sock2 = None ++ try: ++ socket.socket.getsockname = inject_getsocketname ++ with self.assertRaises(OSError): ++ sock1, sock2 = socket.socketpair() ++ finally: ++ socket.socket.getsockname = orig_getsockname ++ if inject_sock: ++ inject_sock.close() ++ if sock1: # This cleanup isn't needed on a successful test. ++ sock1.close() ++ if sock2: ++ sock2.close() ++ ++ def _test_injected_authentication_failure(self): ++ # No-op. Exists for base class threading infrastructure to call. ++ # We could refactor this test into its own lesser class along with the ++ # setUp and tearDown code to construct an ideal; it is simpler to keep ++ # it here and live with extra overhead one this _one_ failure test. ++ pass ++ ++ + class NonBlockingTCPTests(ThreadedTCPSocketTest): + + def __init__(self, methodName='runTest'): diff --git a/Lib/test/test_socketserver.py b/Lib/test/test_socketserver.py index 80e1968c0bf..529b6405f28 100644 --- a/Lib/test/test_socketserver.py @@ -3489,13 +5473,13 @@ index 80e1968c0bf..529b6405f28 100644 + fn = socket_helper.create_unix_domain_name() self.test_files.append(fn) return fn - + diff --git a/Lib/test/test_sqlite3/test_dbapi.py b/Lib/test/test_sqlite3/test_dbapi.py index ff86291bc57..59370264ab3 100644 --- a/Lib/test/test_sqlite3/test_dbapi.py +++ b/Lib/test/test_sqlite3/test_dbapi.py @@ -31,7 +31,7 @@ - + from test.support import ( SHORT_TIMEOUT, bigmemtest, check_disallow_instantiation, requires_subprocess, - is_emscripten, is_wasi @@ -3504,7 +5488,7 @@ index ff86291bc57..59370264ab3 100644 from test.support import threading_helper from _testcapi import INT_MAX, ULLONG_MAX @@ -335,7 +335,7 @@ - + # sqlite3_enable_shared_cache() is deprecated on macOS and calling it may raise # OperationalError on some buildbots. - @unittest.skipIf(sys.platform == "darwin", "shared cache is deprecated on macOS") @@ -3514,7 +5498,7 @@ index ff86291bc57..59370264ab3 100644 with self.assertWarns(DeprecationWarning) as cm: @@ -659,7 +659,7 @@ cx.execute(self._sql) - + @unittest.skipIf(sys.platform == "win32", "skipped on Windows") - @unittest.skipIf(sys.platform == "darwin", "skipped on macOS") + @unittest.skipIf(is_apple, "skipped on Apple platforms") @@ -3523,7 +5507,7 @@ index ff86291bc57..59370264ab3 100644 def test_open_with_undecodable_path(self): @@ -705,7 +705,7 @@ cx.execute(self._sql) - + @unittest.skipIf(sys.platform == "win32", "skipped on Windows") - @unittest.skipIf(sys.platform == "darwin", "skipped on macOS") + @unittest.skipIf(is_apple, "skipped on Apple platforms") @@ -3543,7 +5527,7 @@ index c77fec3d39d..ca55d429aec 100644 +from test.support import is_apple, os_helper, socket_helper from test.support.import_helper import import_fresh_module from test.support.os_helper import TESTFN - + diff --git a/Lib/test/test_sundry.py b/Lib/test/test_sundry.py index de2e7305ccc..3b247e06442 100644 --- a/Lib/test/test_sundry.py @@ -3556,7 +5540,7 @@ index de2e7305ccc..3b247e06442 100644 from test.support import import_helper from test.support import warnings_helper @@ -20,7 +21,8 @@ - + import distutils.bcppcompiler import distutils.ccompiler - import distutils.cygwinccompiler @@ -3565,13 +5549,79 @@ index de2e7305ccc..3b247e06442 100644 import distutils.filelist import distutils.text_file import distutils.unixccompiler +diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py +index 9dd0f745cf2..4ecce225bbd 100644 +--- a/Lib/test/test_syntax.py ++++ b/Lib/test/test_syntax.py +@@ -1725,22 +1725,22 @@ + >>> A[*(1:2)] + Traceback (most recent call last): + ... +- SyntaxError: invalid syntax ++ SyntaxError: Invalid star expression + >>> A[*(1:2)] = 1 + Traceback (most recent call last): + ... +- SyntaxError: invalid syntax ++ SyntaxError: Invalid star expression + >>> del A[*(1:2)] + Traceback (most recent call last): + ... +- SyntaxError: invalid syntax ++ SyntaxError: Invalid star expression + + A[*:] and A[:*] + + >>> A[*:] + Traceback (most recent call last): + ... +- SyntaxError: invalid syntax ++ SyntaxError: Invalid star expression + >>> A[:*] + Traceback (most recent call last): + ... +@@ -1751,7 +1751,7 @@ + >>> A[*] + Traceback (most recent call last): + ... +- SyntaxError: invalid syntax ++ SyntaxError: Invalid star expression + + A[**] + +@@ -1833,11 +1833,23 @@ + + >>> f(**x, *) + Traceback (most recent call last): +- SyntaxError: iterable argument unpacking follows keyword argument unpacking ++ SyntaxError: Invalid star expression + + >>> f(x, *:) + Traceback (most recent call last): +- SyntaxError: invalid syntax ++ SyntaxError: Invalid star expression ++ ++ >>> f(x, *) ++ Traceback (most recent call last): ++ SyntaxError: Invalid star expression ++ ++ >>> f(x = 5, *) ++ Traceback (most recent call last): ++ SyntaxError: Invalid star expression ++ ++ >>> f(x = 5, *:) ++ Traceback (most recent call last): ++ SyntaxError: Invalid star expression + """ + + import re diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index d3bb0d25cac..f487fb5313b 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -6,7 +6,11 @@ from copy import copy - + from test.support import ( - captured_stdout, PythonSymlink, requires_subprocess, is_wasi + captured_stdout, @@ -3584,7 +5634,7 @@ index d3bb0d25cac..f487fb5313b 100644 from test.support.os_helper import (TESTFN, unlink, skip_unless_symlink, @@ -340,6 +344,8 @@ # XXX more platforms to tests here - + @unittest.skipIf(is_wasi, "Incompatible with WASI mapdir and OOT builds") + @unittest.skipIf(is_apple_mobile, + f"{sys.platform} doesn't distribute header files in the runtime environment") @@ -3593,7 +5643,7 @@ index d3bb0d25cac..f487fb5313b 100644 self.assertTrue(os.path.isfile(config_h), config_h) @@ -449,6 +455,8 @@ self.assertEqual(my_platform, test_platform) - + @unittest.skipIf(is_wasi, "Incompatible with WASI mapdir and OOT builds") + @unittest.skipIf(is_apple_mobile, + f"{sys.platform} doesn't include config folder at runtime") @@ -3609,6 +5659,105 @@ index d3bb0d25cac..f487fb5313b 100644 def test_get_makefile_filename(self): makefile = sysconfig.get_makefile_filename() self.assertTrue(os.path.isfile(makefile), makefile) +diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py +index 389da7be3a3..c99c88ce93a 100644 +--- a/Lib/test/test_tarfile.py ++++ b/Lib/test/test_tarfile.py +@@ -1208,6 +1208,48 @@ + finally: + tar.close() + ++ def test_pax_header_bad_formats(self): ++ # The fields from the pax header have priority over the ++ # TarInfo. ++ pax_header_replacements = ( ++ b" foo=bar\n", ++ b"0 \n", ++ b"1 \n", ++ b"2 \n", ++ b"3 =\n", ++ b"4 =a\n", ++ b"1000000 foo=bar\n", ++ b"0 foo=bar\n", ++ b"-12 foo=bar\n", ++ b"000000000000000000000000036 foo=bar\n", ++ ) ++ pax_headers = {"foo": "bar"} ++ ++ for replacement in pax_header_replacements: ++ with self.subTest(header=replacement): ++ tar = tarfile.open(tmpname, "w", format=tarfile.PAX_FORMAT, ++ encoding="iso8859-1") ++ try: ++ t = tarfile.TarInfo() ++ t.name = "pax" # non-ASCII ++ t.uid = 1 ++ t.pax_headers = pax_headers ++ tar.addfile(t) ++ finally: ++ tar.close() ++ ++ with open(tmpname, "rb") as f: ++ data = f.read() ++ self.assertIn(b"11 foo=bar\n", data) ++ data = data.replace(b"11 foo=bar\n", replacement) ++ ++ with open(tmpname, "wb") as f: ++ f.truncate() ++ f.write(data) ++ ++ with self.assertRaisesRegex(tarfile.ReadError, r"method tar: ReadError\('invalid header'\)"): ++ tarfile.open(tmpname, encoding="iso8859-1") ++ + + class WriteTestBase(TarTest): + # Put all write tests in here that are supposed to be tested +diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py +index e735a2520e7..0d6b95441cd 100644 +--- a/Lib/test/test_tempfile.py ++++ b/Lib/test/test_tempfile.py +@@ -11,6 +11,7 @@ + import stat + import types + import weakref ++import subprocess + from unittest import mock + + import unittest +@@ -801,6 +802,33 @@ + finally: + os.rmdir(dir) + ++ @unittest.skipUnless(os.name == "nt", "Only on Windows.") ++ def test_mode_win32(self): ++ # Use icacls.exe to extract the users with some level of access ++ # Main thing we are testing is that the BUILTIN\Users group has ++ # no access. The exact ACL is going to vary based on which user ++ # is running the test. ++ dir = self.do_create() ++ try: ++ out = subprocess.check_output(["icacls.exe", dir], encoding="oem").casefold() ++ finally: ++ os.rmdir(dir) ++ ++ dir = dir.casefold() ++ users = set() ++ found_user = False ++ for line in out.strip().splitlines(): ++ acl = None ++ # First line of result includes our directory ++ if line.startswith(dir): ++ acl = line.removeprefix(dir).strip() ++ elif line and line[:1].isspace(): ++ acl = line.strip() ++ if acl: ++ users.add(acl.partition(":")[0]) ++ ++ self.assertNotIn(r"BUILTIN\Users".casefold(), users) ++ + def test_collision_with_existing_file(self): + # mkdtemp tries another name when a file with + # the chosen name already exists diff --git a/Lib/test/test_unicode_file_functions.py b/Lib/test/test_unicode_file_functions.py index 47619c8807b..25c16e3a0b7 100644 --- a/Lib/test/test_unicode_file_functions.py @@ -3620,12 +5769,12 @@ index 47619c8807b..25c16e3a0b7 100644 -from test.support import os_helper +from test.support import is_apple, os_helper from test import support - - + + @@ -23,13 +23,13 @@ '10_\u1fee\u1ffd', ] - + -# Mac OS X decomposes Unicode names, using Normal Form D. +# Apple platforms decompose Unicode names, using Normal Form D. # http://developer.apple.com/mac/library/qa/qa2001/qa1173.html @@ -3641,7 +5790,7 @@ index 47619c8807b..25c16e3a0b7 100644 @@ -119,11 +119,11 @@ os.stat(name) self._apply_failure(os.listdir, name, self._listdir_failure) - + - # Skip the test on darwin, because darwin does normalize the filename to + # Skip the test on Apple platforms, because they don't normalize the filename to # NFD (a variant of Unicode NFD form). Normalize the filename to NFC, NFKC, @@ -3655,7 +5804,7 @@ index 47619c8807b..25c16e3a0b7 100644 @@ -142,10 +142,10 @@ self._apply_failure(os.remove, name) self._apply_failure(os.listdir, name) - + - # Skip the test on darwin, because darwin uses a normalization different + # Skip the test on Apple platforms, because they use a normalization different # than Python NFD normalization: filenames are different even if we use @@ -3677,17 +5826,129 @@ index 94cbc8a62f9..06a553f093f 100644 +from test.support import requires_subprocess from test.support import warnings_helper from test import test_urllib - + @@ -987,6 +987,7 @@ - + file_obj.close() - + + @requires_subprocess() def test_http_body_pipe(self): # A file reading from a pipe. # A pipe cannot be seek'ed. There is no way to determine the +diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py +index 4fef4303c48..2376dad81b2 100644 +--- a/Lib/test/test_urlparse.py ++++ b/Lib/test/test_urlparse.py +@@ -103,7 +103,9 @@ + + class UrlParseTestCase(unittest.TestCase): + +- def checkRoundtrips(self, url, parsed, split): ++ def checkRoundtrips(self, url, parsed, split, url2=None): ++ if url2 is None: ++ url2 = url + result = urllib.parse.urlparse(url) + self.assertEqual(result, parsed) + t = (result.scheme, result.netloc, result.path, +@@ -111,7 +113,7 @@ + self.assertEqual(t, parsed) + # put it back together and it should be the same + result2 = urllib.parse.urlunparse(result) +- self.assertEqual(result2, url) ++ self.assertEqual(result2, url2) + self.assertEqual(result2, result.geturl()) + + # the result of geturl() is a fixpoint; we can always parse it +@@ -137,7 +139,7 @@ + result.query, result.fragment) + self.assertEqual(t, split) + result2 = urllib.parse.urlunsplit(result) +- self.assertEqual(result2, url) ++ self.assertEqual(result2, url2) + self.assertEqual(result2, result.geturl()) + + # check the fixpoint property of re-parsing the result of geturl() +@@ -175,9 +177,39 @@ + + def test_roundtrips(self): + str_cases = [ ++ ('path/to/file', ++ ('', '', 'path/to/file', '', '', ''), ++ ('', '', 'path/to/file', '', '')), ++ ('/path/to/file', ++ ('', '', '/path/to/file', '', '', ''), ++ ('', '', '/path/to/file', '', '')), ++ ('//path/to/file', ++ ('', 'path', '/to/file', '', '', ''), ++ ('', 'path', '/to/file', '', '')), ++ ('////path/to/file', ++ ('', '', '//path/to/file', '', '', ''), ++ ('', '', '//path/to/file', '', '')), ++ ('scheme:path/to/file', ++ ('scheme', '', 'path/to/file', '', '', ''), ++ ('scheme', '', 'path/to/file', '', '')), ++ ('scheme:/path/to/file', ++ ('scheme', '', '/path/to/file', '', '', ''), ++ ('scheme', '', '/path/to/file', '', '')), ++ ('scheme://path/to/file', ++ ('scheme', 'path', '/to/file', '', '', ''), ++ ('scheme', 'path', '/to/file', '', '')), ++ ('scheme:////path/to/file', ++ ('scheme', '', '//path/to/file', '', '', ''), ++ ('scheme', '', '//path/to/file', '', '')), + ('file:///tmp/junk.txt', + ('file', '', '/tmp/junk.txt', '', '', ''), + ('file', '', '/tmp/junk.txt', '', '')), ++ ('file:////tmp/junk.txt', ++ ('file', '', '//tmp/junk.txt', '', '', ''), ++ ('file', '', '//tmp/junk.txt', '', '')), ++ ('file://///tmp/junk.txt', ++ ('file', '', '///tmp/junk.txt', '', '', ''), ++ ('file', '', '///tmp/junk.txt', '', '')), + ('imap://mail.python.org/mbox1', + ('imap', 'mail.python.org', '/mbox1', '', '', ''), + ('imap', 'mail.python.org', '/mbox1', '', '')), +@@ -208,6 +240,38 @@ + for url, parsed, split in str_cases + bytes_cases: + self.checkRoundtrips(url, parsed, split) + ++ def test_roundtrips_normalization(self): ++ str_cases = [ ++ ('///path/to/file', ++ '/path/to/file', ++ ('', '', '/path/to/file', '', '', ''), ++ ('', '', '/path/to/file', '', '')), ++ ('scheme:///path/to/file', ++ 'scheme:/path/to/file', ++ ('scheme', '', '/path/to/file', '', '', ''), ++ ('scheme', '', '/path/to/file', '', '')), ++ ('file:/tmp/junk.txt', ++ 'file:///tmp/junk.txt', ++ ('file', '', '/tmp/junk.txt', '', '', ''), ++ ('file', '', '/tmp/junk.txt', '', '')), ++ ('http:/tmp/junk.txt', ++ 'http:///tmp/junk.txt', ++ ('http', '', '/tmp/junk.txt', '', '', ''), ++ ('http', '', '/tmp/junk.txt', '', '')), ++ ('https:/tmp/junk.txt', ++ 'https:///tmp/junk.txt', ++ ('https', '', '/tmp/junk.txt', '', '', ''), ++ ('https', '', '/tmp/junk.txt', '', '')), ++ ] ++ def _encode(t): ++ return (t[0].encode('ascii'), ++ t[1].encode('ascii'), ++ tuple(x.encode('ascii') for x in t[2]), ++ tuple(x.encode('ascii') for x in t[3])) ++ bytes_cases = [_encode(x) for x in str_cases] ++ for url, url2, parsed, split in str_cases + bytes_cases: ++ self.checkRoundtrips(url, parsed, split, url2) ++ + def test_http_roundtrips(self): + # urllib.parse.urlsplit treats 'http:' as an optimized special case, + # so we test both 'http:' and 'https:' in all the following. diff --git a/Lib/test/test_venv.py b/Lib/test/test_venv.py -index a60f4cd3111..1ea960e7e33 100644 +index a60f4cd3111..b49c020bc92 100644 --- a/Lib/test/test_venv.py +++ b/Lib/test/test_venv.py @@ -19,8 +19,8 @@ @@ -3704,16 +5965,26 @@ index a60f4cd3111..1ea960e7e33 100644 @@ -39,8 +39,10 @@ or sys._base_executable != sys.executable, 'cannot run venv.create from within a venv on this platform') - + -if is_emscripten or is_wasi: - raise unittest.SkipTest("venv is not available on Emscripten/WASI.") +# Skip tests on WASM platforms, plus iOS/tvOS/watchOS +if is_apple_mobile or is_emscripten or is_wasi: + raise unittest.SkipTest(f"venv tests not required on {sys.platform}") + - + @requires_subprocess() def check_output(cmd, encoding=None): +@@ -253,7 +255,8 @@ + ('base_exec_prefix', sys.base_exec_prefix)): + cmd[2] = 'import sys; print(sys.%s)' % prefix + out, err = check_output(cmd) +- self.assertEqual(out.strip(), expected.encode(), prefix) ++ self.assertEqual(pathlib.Path(out.strip().decode()), ++ pathlib.Path(expected), prefix) + + @requireVenvCreate + def test_sysconfig(self): diff --git a/Lib/test/test_webbrowser.py b/Lib/test/test_webbrowser.py index 9d608d63a01..24b1103f500 100644 --- a/Lib/test/test_webbrowser.py @@ -3727,26 +5998,26 @@ index 9d608d63a01..24b1103f500 100644 from test.support import os_helper +from test.support import requires_subprocess +from test.support import threading_helper - + -if not support.has_subprocess_support: - raise unittest.SkipTest("test webserver requires subprocess") +# The webbrowser module uses threading locks +threading_helper.requires_working_threading(module=True) - + URL = 'http://www.example.com' CMD_NAME = 'test' @@ -24,6 +27,7 @@ return 0 - - + + +@requires_subprocess() class CommandTestMixin: - + def _test(self, meth, *, args=[URL], kw={}, options, arguments): @@ -219,6 +223,73 @@ arguments=['openURL({},new-tab)'.format(URL)]) - - + + +@unittest.skipUnless(sys.platform == "ios", "Test only applicable to iOS") +class IOSBrowserTest(unittest.TestCase): + def _obj_ref(self, *args): @@ -3815,12 +6086,12 @@ index 9d608d63a01..24b1103f500 100644 + + class BrowserRegistrationTest(unittest.TestCase): - + def setUp(self): @@ -302,6 +373,10 @@ webbrowser.register(name, None, webbrowser.GenericBrowser(name)) webbrowser.get(sys.executable) - + + @unittest.skipIf( + is_apple_mobile, + "Apple mobile doesn't allow modifying browser with environment" @@ -3831,7 +6102,7 @@ index 9d608d63a01..24b1103f500 100644 @@ -313,6 +388,10 @@ webbrowser = import_helper.import_fresh_module('webbrowser') webbrowser.get() - + + @unittest.skipIf( + is_apple_mobile, + "Apple mobile doesn't allow modifying browser with environment" @@ -3839,6 +6110,107 @@ index 9d608d63a01..24b1103f500 100644 def test_environment_preferred(self): webbrowser = import_helper.import_fresh_module('webbrowser') try: +diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py +index 4de6f379a47..52831a7bd7c 100644 +--- a/Lib/test/test_zipfile.py ++++ b/Lib/test/test_zipfile.py +@@ -3651,6 +3651,83 @@ + zipfile.Path(zf) + zf.extractall(source_path.parent) + ++ def test_malformed_paths(self): ++ """ ++ Path should handle malformed paths gracefully. ++ ++ Paths with leading slashes are not visible. ++ ++ Paths with dots are treated like regular files. ++ """ ++ data = io.BytesIO() ++ zf = zipfile.ZipFile(data, "w") ++ zf.writestr("/one-slash.txt", b"content") ++ zf.writestr("//two-slash.txt", b"content") ++ zf.writestr("../parent.txt", b"content") ++ zf.filename = '' ++ root = zipfile.Path(zf) ++ assert list(map(str, root.iterdir())) == ['../'] ++ assert root.joinpath('..').joinpath('parent.txt').read_bytes() == b'content' ++ ++ def test_unsupported_names(self): ++ """ ++ Path segments with special characters are readable. ++ ++ On some platforms or file systems, characters like ++ ``:`` and ``?`` are not allowed, but they are valid ++ in the zip file. ++ """ ++ data = io.BytesIO() ++ zf = zipfile.ZipFile(data, "w") ++ zf.writestr("path?", b"content") ++ zf.writestr("V: NMS.flac", b"fLaC...") ++ zf.filename = '' ++ root = zipfile.Path(zf) ++ contents = root.iterdir() ++ assert next(contents).name == 'path?' ++ assert next(contents).name == 'V: NMS.flac' ++ assert root.joinpath('V: NMS.flac').read_bytes() == b"fLaC..." ++ ++ def test_backslash_not_separator(self): ++ """ ++ In a zip file, backslashes are not separators. ++ """ ++ data = io.BytesIO() ++ zf = zipfile.ZipFile(data, "w") ++ zf.writestr(DirtyZipInfo.for_name("foo\\bar", zf), b"content") ++ zf.filename = '' ++ root = zipfile.Path(zf) ++ (first,) = root.iterdir() ++ assert not first.is_dir() ++ assert first.name == 'foo\\bar' ++ ++ ++class DirtyZipInfo(zipfile.ZipInfo): ++ """ ++ Bypass name sanitization. ++ """ ++ ++ def __init__(self, filename, *args, **kwargs): ++ super().__init__(filename, *args, **kwargs) ++ self.filename = filename ++ ++ @classmethod ++ def for_name(cls, name, archive): ++ """ ++ Construct the same way that ZipFile.writestr does. ++ ++ TODO: extract this functionality and re-use ++ """ ++ self = cls(filename=name, date_time=time.localtime(time.time())[:6]) ++ self.compress_type = archive.compression ++ self.compress_level = archive.compresslevel ++ if self.filename.endswith('/'): # pragma: no cover ++ self.external_attr = 0o40775 << 16 # drwxrwxr-x ++ self.external_attr |= 0x10 # MS-DOS directory flag ++ else: ++ self.external_attr = 0o600 << 16 # ?rw------- ++ return self ++ + + class EncodedMetadataTests(unittest.TestCase): + file_names = ['\u4e00', '\u4e8c', '\u4e09'] # Han 'one', 'two', 'three' +diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py +index 10c302d34c1..abf1d1b5466 100644 +--- a/Lib/urllib/parse.py ++++ b/Lib/urllib/parse.py +@@ -525,7 +525,7 @@ + empty query; the RFC states that these are equivalent).""" + scheme, netloc, url, query, fragment, _coerce_result = ( + _coerce_args(*components)) +- if netloc or (scheme and scheme in uses_netloc and url[:2] != '//'): ++ if netloc or (scheme and scheme in uses_netloc) or url[:2] == '//': + if url and url[:1] != '/': url = '/' + url + url = '//' + (netloc or '') + url + if scheme: diff --git a/Lib/webbrowser.py b/Lib/webbrowser.py index 5d72524c087..48976e4e11f 100755 --- a/Lib/webbrowser.py @@ -3846,7 +6218,7 @@ index 5d72524c087..48976e4e11f 100755 @@ -534,6 +534,9 @@ # OS X can use below Unix support (but we prefer using the OS X # specific stuff) - + + if sys.platform == "ios": + register("iosbrowser", None, IOSBrowser(), preferred=True) + @@ -3856,7 +6228,7 @@ index 5d72524c087..48976e4e11f 100755 @@ -707,6 +710,70 @@ rc = osapipe.close() return not rc - + +# +# Platform support for iOS +# @@ -3921,9 +6293,46 @@ index 5d72524c087..48976e4e11f 100755 + + return True + - + def main(): import getopt +diff --git a/Lib/zipfile.py b/Lib/zipfile.py +index 86829abce4e..6a4cf7a972b 100644 +--- a/Lib/zipfile.py ++++ b/Lib/zipfile.py +@@ -9,6 +9,7 @@ + import itertools + import os + import posixpath ++import re + import shutil + import stat + import struct +@@ -2212,7 +2213,7 @@ + def _ancestry(path): + """ + Given a path with elements separated by +- posixpath.sep, generate all elements of that path ++ posixpath.sep, generate all elements of that path. + + >>> list(_ancestry('b/d')) + ['b/d', 'b'] +@@ -2224,9 +2225,14 @@ + ['b'] + >>> list(_ancestry('')) + [] ++ ++ Multiple separators are treated like a single. ++ ++ >>> list(_ancestry('//b//d///f//')) ++ ['//b//d///f', '//b//d', '//b'] + """ + path = path.rstrip(posixpath.sep) +- while path and path != posixpath.sep: ++ while path.rstrip(posixpath.sep): + yield path + path, tail = posixpath.split(path) + --- /dev/null +++ b/Mac/Resources/app-store-compliance.patch @@ -0,0 +1 @@ @@ -3935,7 +6344,7 @@ index 81d4d50f82f..9e7e0cd0ac0 100644 @@ -175,18 +175,29 @@ EXE= @EXEEXT@ BUILDEXE= @BUILDEXEEXT@ - + +# Name of the patch file to apply for app store compliance +APP_STORE_COMPLIANCE_PATCH=@APP_STORE_COMPLIANCE_PATCH@ + @@ -3953,7 +6362,7 @@ index 81d4d50f82f..9e7e0cd0ac0 100644 # deployment target is active during build. MACOSX_DEPLOYMENT_TARGET=@CONFIGURE_MACOSX_DEPLOYMENT_TARGET@ @EXPORT_MACOSX_DEPLOYMENT_TARGET@export MACOSX_DEPLOYMENT_TARGET - + +# iOS Deployment target selected during configure. Unlike macOS, the iOS +# deployment target is controlled using `-mios-version-min` arguments added to +# CFLAGS and LDFLAGS by the configure script. This variable is not used during @@ -3962,29 +6371,29 @@ index 81d4d50f82f..9e7e0cd0ac0 100644 + # Option to install to strip binaries STRIPFLAG=-s - + @@ -344,6 +355,8 @@ ########################################################################## - + LIBFFI_INCLUDEDIR= @LIBFFI_INCLUDEDIR@ +LIBFFI_LIBDIR= @LIBFFI_LIBDIR@ +LIBFFI_LIB= @LIBFFI_LIB@ - + ########################################################################## # Parser @@ -585,7 +598,7 @@ - + # Default target all: @DEF_MAKE_ALL_RULE@ -build_all: check-clean-src $(BUILDPYTHON) platform oldsharedmods sharedmods \ +build_all: check-clean-src check-app-store-compliance $(BUILDPYTHON) platform oldsharedmods sharedmods \ gdbhooks Programs/_testembed python-config build_wasm: check-clean-src $(BUILDPYTHON) platform oldsharedmods python-config - + @@ -604,6 +617,16 @@ exit 1; \ fi - + +# Check that the app store compliance patch can be applied (if configured). +# This is checked as a dry-run against the original library sources; +# the patch will be actually applied during the install phase. @@ -4000,12 +6409,12 @@ index 81d4d50f82f..9e7e0cd0ac0 100644 $(MAKE) clean @@ -765,7 +788,7 @@ $(BLDSHARED) $(NO_AS_NEEDED) -o $@ -Wl,-h$@ $^ - + libpython$(LDVERSION).dylib: $(LIBRARY_OBJS) - $(CC) -dynamiclib -Wl,-single_module $(PY_CORE_LDFLAGS) -undefined dynamic_lookup -Wl,-install_name,$(prefix)/lib/libpython$(LDVERSION).dylib -Wl,-compatibility_version,$(VERSION) -Wl,-current_version,$(VERSION) -o $@ $(LIBRARY_OBJS) $(DTRACE_OBJS) $(SHLIBS) $(LIBC) $(LIBM); \ + $(CC) -dynamiclib $(PY_CORE_LDFLAGS) -undefined dynamic_lookup -Wl,-install_name,$(prefix)/lib/libpython$(LDVERSION).dylib -Wl,-compatibility_version,$(VERSION) -Wl,-current_version,$(VERSION) -o $@ $(LIBRARY_OBJS) $(DTRACE_OBJS) $(SHLIBS) $(LIBC) $(LIBM); \ - - + + libpython$(VERSION).sl: $(LIBRARY_OBJS) @@ -789,14 +812,13 @@ # This rule is here for OPENSTEP/Rhapsody/MacOSX. It builds a temporary @@ -4027,7 +6436,7 @@ index 81d4d50f82f..9e7e0cd0ac0 100644 @@ -808,6 +830,21 @@ $(LN) -fsn Versions/Current/$(PYTHONFRAMEWORK) $(PYTHONFRAMEWORKDIR)/$(PYTHONFRAMEWORK) $(LN) -fsn Versions/Current/Resources $(PYTHONFRAMEWORKDIR)/Resources - + +# This rule is for iOS, which requires an annoyingly just slighly different +# format for frameworks to macOS. It *doesn't* use a versioned framework, and +# the Info.plist must be in the root of the framework. @@ -4049,7 +6458,7 @@ index 81d4d50f82f..9e7e0cd0ac0 100644 @@ -1711,6 +1748,54 @@ $(RUNSHARED) /usr/libexec/oah/translate \ ./$(BUILDPYTHON) -E -m test -j 0 -u all $(TESTOPTS) - + +# Run the test suite on the iOS simulator. Must be run on a macOS machine with +# a full Xcode install that has an iPhone SE (3rd edition) simulator available. +# This must be run *after* a `make install` has completed the build. The @@ -4131,10 +6540,10 @@ index 81d4d50f82f..9e7e0cd0ac0 100644 @@ -2316,9 +2410,11 @@ # automatically set prefix to the location deep down in the framework, so we # only have to cater for the structural bits of the framework. - + -frameworkinstallframework: frameworkinstallstructure install frameworkinstallmaclib +frameworkinstallframework: @FRAMEWORKINSTALLFIRST@ install frameworkinstallmaclib - + -frameworkinstallstructure: $(LDLIBRARY) +# macOS uses a versioned frameworks structure that includes a full install +.PHONY: frameworkinstallversionedstructure @@ -4145,7 +6554,7 @@ index 81d4d50f82f..9e7e0cd0ac0 100644 @@ -2339,6 +2435,27 @@ $(LN) -fsn Versions/Current/Resources $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Resources $(INSTALL_SHARED) $(LDLIBRARY) $(DESTDIR)$(PYTHONFRAMEWORKPREFIX)/$(LDLIBRARY) - + +# iOS/tvOS/watchOS uses a non-versioned framework with Info.plist in the +# framework root, no .lproj data, and only stub compilation assistance binaries +.PHONY: frameworkinstallunversionedstructure @@ -4173,7 +6582,7 @@ index 81d4d50f82f..9e7e0cd0ac0 100644 @@ -2373,6 +2490,19 @@ frameworkinstallextras: cd Mac && $(MAKE) installextras DESTDIR="$(DESTDIR)" - + +# On iOS, bin/lib can't live inside the framework; include needs to be called +# "Headers", but *must* be in the framework, and *not* include the `python3.X` +# subdirectory. The install has put these folders in the same folder as @@ -4187,64 +6596,7214 @@ index 81d4d50f82f..9e7e0cd0ac0 100644 + mv "$(DESTDIR)$(PYTHONFRAMEWORKPREFIX)/include/python$(LDVERSION)" "$(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Headers" + $(LN) -fs "../$(PYTHONFRAMEWORKDIR)/Headers" "$(DESTDIR)$(PYTHONFRAMEWORKPREFIX)/include/python$(LDVERSION)" + - # Build the toplevel Makefile - Makefile.pre: $(srcdir)/Makefile.pre.in config.status - CONFIG_FILES=Makefile.pre CONFIG_HEADERS= $(SHELL) config.status -@@ -2477,6 +2607,10 @@ - -find build -type f -a ! -name '*.gc??' -exec rm -f {} ';' - -rm -f Include/pydtrace_probes.h - -rm -f profile-gen-stamp -+ -rm -rf iOS/testbed/Python.xcframework/ios-*/bin -+ -rm -rf iOS/testbed/Python.xcframework/ios-*/lib -+ -rm -rf iOS/testbed/Python.xcframework/ios-*/include -+ -rm -rf iOS/testbed/Python.xcframework/ios-*/Python.framework - - profile-removal: - find . -name '*.gc??' -exec rm -f {} ';' -@@ -2498,6 +2632,8 @@ - config.cache config.log pyconfig.h Modules/config.c - -rm -rf build platform - -rm -rf $(PYTHONFRAMEWORKDIR) -+ -rm -rf iOS/Frameworks -+ -rm -rf iOSTestbed.* - -rm -f python-config.py python-config - - # Make things extra clean, before making a distribution: -@@ -2578,7 +2714,7 @@ - .PHONY: all build_all build_wasm sharedmods check-clean-src oldsharedmods test quicktest - .PHONY: install altinstall oldsharedinstall bininstall altbininstall - .PHONY: maninstall libinstall inclinstall libainstall sharedinstall --.PHONY: frameworkinstall frameworkinstallframework frameworkinstallstructure -+.PHONY: frameworkinstall frameworkinstallframework - .PHONY: frameworkinstallmaclib frameworkinstallapps frameworkinstallunixtools - .PHONY: frameworkaltinstallunixtools recheck clean clobber distclean - .PHONY: smelly funny patchcheck touch altmaninstall commoninstall -diff --git a/Modules/getpath.c b/Modules/getpath.c -index 61d654065fd..8bd844d6459 100644 ---- a/Modules/getpath.c -+++ b/Modules/getpath.c -@@ -15,6 +15,7 @@ - #endif - - #ifdef __APPLE__ -+# include "TargetConditionals.h" - # include - #endif - -@@ -767,7 +768,7 @@ - if (PyWin_DLLhModule) { - return winmodule_to_dict(dict, key, PyWin_DLLhModule); + # Build the toplevel Makefile + Makefile.pre: $(srcdir)/Makefile.pre.in config.status + CONFIG_FILES=Makefile.pre CONFIG_HEADERS= $(SHELL) config.status +@@ -2477,6 +2607,10 @@ + -find build -type f -a ! -name '*.gc??' -exec rm -f {} ';' + -rm -f Include/pydtrace_probes.h + -rm -f profile-gen-stamp ++ -rm -rf iOS/testbed/Python.xcframework/ios-*/bin ++ -rm -rf iOS/testbed/Python.xcframework/ios-*/lib ++ -rm -rf iOS/testbed/Python.xcframework/ios-*/include ++ -rm -rf iOS/testbed/Python.xcframework/ios-*/Python.framework + + profile-removal: + find . -name '*.gc??' -exec rm -f {} ';' +@@ -2498,6 +2632,8 @@ + config.cache config.log pyconfig.h Modules/config.c + -rm -rf build platform + -rm -rf $(PYTHONFRAMEWORKDIR) ++ -rm -rf iOS/Frameworks ++ -rm -rf iOSTestbed.* + -rm -f python-config.py python-config + + # Make things extra clean, before making a distribution: +@@ -2578,7 +2714,7 @@ + .PHONY: all build_all build_wasm sharedmods check-clean-src oldsharedmods test quicktest + .PHONY: install altinstall oldsharedinstall bininstall altbininstall + .PHONY: maninstall libinstall inclinstall libainstall sharedinstall +-.PHONY: frameworkinstall frameworkinstallframework frameworkinstallstructure ++.PHONY: frameworkinstall frameworkinstallframework + .PHONY: frameworkinstallmaclib frameworkinstallapps frameworkinstallunixtools + .PHONY: frameworkaltinstallunixtools recheck clean clobber distclean + .PHONY: smelly funny patchcheck touch altmaninstall commoninstall +diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c +index 3de4c06704b..ba69e2afd27 100644 +--- a/Modules/_io/textio.c ++++ b/Modules/_io/textio.c +@@ -1701,34 +1701,56 @@ + bytes_len = PyBytes_GET_SIZE(b); + } + +- if (self->pending_bytes == NULL) { +- self->pending_bytes_count = 0; +- self->pending_bytes = b; +- } +- else if (self->pending_bytes_count + bytes_len > self->chunk_size) { +- // Prevent to concatenate more than chunk_size data. +- if (_textiowrapper_writeflush(self) < 0) { +- Py_DECREF(b); +- return NULL; ++ // We should avoid concatinating huge data. ++ // Flush the buffer before adding b to the buffer if b is not small. ++ // https://github.com/python/cpython/issues/87426 ++ if (bytes_len >= self->chunk_size) { ++ // _textiowrapper_writeflush() calls buffer.write(). ++ // self->pending_bytes can be appended during buffer->write() ++ // or other thread. ++ // We need to loop until buffer becomes empty. ++ // https://github.com/python/cpython/issues/118138 ++ // https://github.com/python/cpython/issues/119506 ++ while (self->pending_bytes != NULL) { ++ if (_textiowrapper_writeflush(self) < 0) { ++ Py_DECREF(b); ++ return NULL; ++ } + } +- self->pending_bytes = b; + } +- else if (!PyList_CheckExact(self->pending_bytes)) { +- PyObject *list = PyList_New(2); +- if (list == NULL) { +- Py_DECREF(b); +- return NULL; +- } +- PyList_SET_ITEM(list, 0, self->pending_bytes); +- PyList_SET_ITEM(list, 1, b); +- self->pending_bytes = list; ++ ++ if (self->pending_bytes == NULL) { ++ assert(self->pending_bytes_count == 0); ++ self->pending_bytes = b; + } + else { +- if (PyList_Append(self->pending_bytes, b) < 0) { +- Py_DECREF(b); +- return NULL; ++ if (!PyList_CheckExact(self->pending_bytes)) { ++ PyObject *list = PyList_New(0); ++ if (list == NULL) { ++ Py_DECREF(b); ++ return NULL; ++ } ++ // PyList_New() may trigger GC and other thread may call write(). ++ // So, we need to check the self->pending_bytes is a list again. ++ if (PyList_CheckExact(self->pending_bytes)) { ++ // Releasing empty list won't trigger GC and/or __del__. ++ Py_DECREF(list); ++ } ++ else { ++ if (PyList_Append(list, self->pending_bytes) < 0) { ++ Py_DECREF(list); ++ Py_DECREF(b); ++ return NULL; ++ } ++ Py_SETREF(self->pending_bytes, list); ++ } + } ++ ++ int ret = PyList_Append(self->pending_bytes, b); + Py_DECREF(b); ++ if (ret < 0) { ++ return NULL; ++ } + } + + self->pending_bytes_count += bytes_len; +diff --git a/Modules/_winapi.c b/Modules/_winapi.c +index 54eee9e8c3f..0376cc0a26f 100644 +--- a/Modules/_winapi.c ++++ b/Modules/_winapi.c +@@ -708,7 +708,7 @@ + { + HANDLE handle; + +- if (PySys_Audit("_winapi.CreateNamedPipe", "uII", ++ if (PySys_Audit("_winapi.CreateNamedPipe", "sII", + name, open_mode, pipe_mode) < 0) { + return INVALID_HANDLE_VALUE; + } +diff --git a/Modules/expat/expat.h b/Modules/expat/expat.h +index 95464b0dd17..d0d6015a662 100644 +--- a/Modules/expat/expat.h ++++ b/Modules/expat/expat.h +@@ -18,6 +18,7 @@ + Copyright (c) 2022 Thijs Schreijer + Copyright (c) 2023 Hanno Böck + Copyright (c) 2023 Sony Corporation / Snild Dolkow ++ Copyright (c) 2024 Taichi Haradaguchi <20001722@ymail.ne.jp> + Licensed under the MIT license: + + Permission is hereby granted, free of charge, to any person obtaining +@@ -1042,7 +1043,7 @@ + XMLPARSEAPI(const XML_Feature *) + XML_GetFeatureList(void); + +-#if XML_GE == 1 ++#if defined(XML_DTD) || (defined(XML_GE) && XML_GE == 1) + /* Added in Expat 2.4.0 for XML_DTD defined and + * added in Expat 2.6.0 for XML_GE == 1. */ + XMLPARSEAPI(XML_Bool) +@@ -1065,7 +1066,7 @@ + */ + #define XML_MAJOR_VERSION 2 + #define XML_MINOR_VERSION 6 +-#define XML_MICRO_VERSION 0 ++#define XML_MICRO_VERSION 3 + + #ifdef __cplusplus + } +diff --git a/Modules/expat/internal.h b/Modules/expat/internal.h +index cce71e4c516..167ec36804a 100644 +--- a/Modules/expat/internal.h ++++ b/Modules/expat/internal.h +@@ -28,10 +28,11 @@ + Copyright (c) 2002-2003 Fred L. Drake, Jr. + Copyright (c) 2002-2006 Karl Waclawek + Copyright (c) 2003 Greg Stein +- Copyright (c) 2016-2023 Sebastian Pipping ++ Copyright (c) 2016-2024 Sebastian Pipping + Copyright (c) 2018 Yury Gribov + Copyright (c) 2019 David Loffredo +- Copyright (c) 2023 Sony Corporation / Snild Dolkow ++ Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow ++ Copyright (c) 2024 Taichi Haradaguchi <20001722@ymail.ne.jp> + Licensed under the MIT license: + + Permission is hereby granted, free of charge, to any person obtaining +@@ -155,14 +156,20 @@ + void _INTERNAL_trim_to_complete_utf8_characters(const char *from, + const char **fromLimRef); + +-#if XML_GE == 1 ++#if defined(XML_GE) && XML_GE == 1 + unsigned long long testingAccountingGetCountBytesDirect(XML_Parser parser); + unsigned long long testingAccountingGetCountBytesIndirect(XML_Parser parser); + const char *unsignedCharToPrintable(unsigned char c); + #endif + +-extern XML_Bool g_reparseDeferralEnabledDefault; // written ONLY in runtests.c +-extern unsigned int g_parseAttempts; // used for testing only ++extern ++#if ! defined(XML_TESTING) ++ const ++#endif ++ XML_Bool g_reparseDeferralEnabledDefault; // written ONLY in runtests.c ++#if defined(XML_TESTING) ++extern unsigned int g_bytesScanned; // used for testing only ++#endif + + #ifdef __cplusplus + } +diff --git a/Modules/expat/siphash.h b/Modules/expat/siphash.h +index a1ed99e687b..04f6f74585b 100644 +--- a/Modules/expat/siphash.h ++++ b/Modules/expat/siphash.h +@@ -126,8 +126,7 @@ + | ((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) \ + | ((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56)) + +-#define SIPHASH_INITIALIZER \ +- { 0, 0, 0, 0, {0}, 0, 0 } ++#define SIPHASH_INITIALIZER {0, 0, 0, 0, {0}, 0, 0} + + struct siphash { + uint64_t v0, v1, v2, v3; +diff --git a/Modules/expat/xmlparse.c b/Modules/expat/xmlparse.c +index aaf0fa9c8f9..d9285b213b3 100644 +--- a/Modules/expat/xmlparse.c ++++ b/Modules/expat/xmlparse.c +@@ -1,4 +1,4 @@ +-/* 628e24d4966bedbd4800f6ed128d06d29703765b4bce12d3b7f099f90f842fc9 (2.6.0+) ++/* ba4cdf9bdb534f355a9def4c9e25d20ee8e72f95b0a4d930be52e563f5080196 (2.6.3+) + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| +@@ -38,7 +38,8 @@ + Copyright (c) 2022 Jann Horn + Copyright (c) 2022 Sean McBride + Copyright (c) 2023 Owain Davies +- Copyright (c) 2023 Sony Corporation / Snild Dolkow ++ Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow ++ Copyright (c) 2024 Berkay Eren Ürün + Licensed under the MIT license: + + Permission is hereby granted, free of charge, to any person obtaining +@@ -210,7 +211,7 @@ + #endif + + /* Round up n to be a multiple of sz, where sz is a power of 2. */ +-#define ROUND_UP(n, sz) (((n) + ((sz)-1)) & ~((sz)-1)) ++#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1)) + + /* Do safe (NULL-aware) pointer arithmetic */ + #define EXPAT_SAFE_PTR_DIFF(p, q) (((p) && (q)) ? ((p) - (q)) : 0) +@@ -248,7 +249,7 @@ + it odd, since odd numbers are always relative prime to a power of 2. + */ + #define SECOND_HASH(hash, mask, power) \ +- ((((hash) & ~(mask)) >> ((power)-1)) & ((mask) >> 2)) ++ ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2)) + #define PROBE_STEP(hash, mask, power) \ + ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1)) + +@@ -294,7 +295,7 @@ + The name of the element is stored in both the document and API + encodings. The memory buffer 'buf' is a separately-allocated + memory area which stores the name. During the XML_Parse()/ +- XMLParseBuffer() when the element is open, the memory for the 'raw' ++ XML_ParseBuffer() when the element is open, the memory for the 'raw' + version of the name (in the document encoding) is shared with the + document buffer. If the element is open across calls to + XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to +@@ -629,8 +630,14 @@ + ? 0 \ + : ((*((pool)->ptr)++ = c), 1)) + +-XML_Bool g_reparseDeferralEnabledDefault = XML_TRUE; // write ONLY in runtests.c +-unsigned int g_parseAttempts = 0; // used for testing only ++#if ! defined(XML_TESTING) ++const ++#endif ++ XML_Bool g_reparseDeferralEnabledDefault ++ = XML_TRUE; // write ONLY in runtests.c ++#if defined(XML_TESTING) ++unsigned int g_bytesScanned = 0; // used for testing only ++#endif + + struct XML_ParserStruct { + /* The first member must be m_userData so that the XML_GetUserData +@@ -1017,7 +1024,9 @@ + return XML_ERROR_NONE; + } + } +- g_parseAttempts += 1; ++#if defined(XML_TESTING) ++ g_bytesScanned += (unsigned)have_now; ++#endif + const enum XML_Error ret = parser->m_processor(parser, start, end, endPtr); + if (ret == XML_ERROR_NONE) { + // if we consumed nothing, remember what we had on this parse attempt. +@@ -2030,6 +2039,12 @@ + + if (parser == NULL) + return XML_STATUS_ERROR; ++ ++ if (len < 0) { ++ parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT; ++ return XML_STATUS_ERROR; ++ } ++ + switch (parser->m_parsingStatus.parsing) { + case XML_SUSPENDED: + parser->m_errorCode = XML_ERROR_SUSPENDED; +@@ -5838,18 +5853,17 @@ + /* Set a safe default value in case 'next' does not get set */ + next = textStart; + +-#ifdef XML_DTD + if (entity->is_param) { + int tok + = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next); + result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, + tok, next, &next, XML_FALSE, XML_FALSE, + XML_ACCOUNT_ENTITY_EXPANSION); +- } else +-#endif /* XML_DTD */ ++ } else { + result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding, + textStart, textEnd, &next, XML_FALSE, + XML_ACCOUNT_ENTITY_EXPANSION); ++ } + + if (result == XML_ERROR_NONE) { + if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) { +@@ -5886,18 +5900,17 @@ + /* Set a safe default value in case 'next' does not get set */ + next = textStart; + +-#ifdef XML_DTD + if (entity->is_param) { + int tok + = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next); + result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, + tok, next, &next, XML_FALSE, XML_TRUE, + XML_ACCOUNT_ENTITY_EXPANSION); +- } else +-#endif /* XML_DTD */ ++ } else { + result = doContent(parser, openEntity->startTagLevel, + parser->m_internalEncoding, textStart, textEnd, &next, + XML_FALSE, XML_ACCOUNT_ENTITY_EXPANSION); ++ } + + if (result != XML_ERROR_NONE) + return result; +@@ -5924,7 +5937,6 @@ + return XML_ERROR_NONE; + } + +-#ifdef XML_DTD + if (entity->is_param) { + int tok; + parser->m_processor = prologProcessor; +@@ -5932,9 +5944,7 @@ + return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr, + (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE, + XML_ACCOUNT_DIRECT); +- } else +-#endif /* XML_DTD */ +- { ++ } else { + parser->m_processor = contentProcessor; + /* see externalEntityContentProcessor vs contentProcessor */ + result = doContent(parser, parser->m_parentParser ? 1 : 0, +@@ -6232,7 +6242,7 @@ + dtd->keepProcessing = dtd->standalone; + goto endEntityValue; + } +- if (entity->open) { ++ if (entity->open || (entity == parser->m_declEntity)) { + if (enc == parser->m_encoding) + parser->m_eventPtr = entityTextPtr; + result = XML_ERROR_RECURSIVE_ENTITY_REF; +@@ -7008,6 +7018,16 @@ + if (! newE) + return 0; + if (oldE->nDefaultAtts) { ++ /* Detect and prevent integer overflow. ++ * The preprocessor guard addresses the "always false" warning ++ * from -Wtype-limits on platforms where ++ * sizeof(int) < sizeof(size_t), e.g. on x86_64. */ ++#if UINT_MAX >= SIZE_MAX ++ if ((size_t)oldE->nDefaultAtts ++ > ((size_t)(-1) / sizeof(DEFAULT_ATTRIBUTE))) { ++ return 0; ++ } ++#endif + newE->defaultAtts + = ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); + if (! newE->defaultAtts) { +@@ -7550,6 +7570,15 @@ + int next; + + if (! dtd->scaffIndex) { ++ /* Detect and prevent integer overflow. ++ * The preprocessor guard addresses the "always false" warning ++ * from -Wtype-limits on platforms where ++ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ ++#if UINT_MAX >= SIZE_MAX ++ if (parser->m_groupSize > ((size_t)(-1) / sizeof(int))) { ++ return -1; ++ } ++#endif + dtd->scaffIndex = (int *)MALLOC(parser, parser->m_groupSize * sizeof(int)); + if (! dtd->scaffIndex) + return -1; +@@ -7779,6 +7808,8 @@ + + static float + accountingGetCurrentAmplification(XML_Parser rootParser) { ++ // 1.........1.........12 => 22 ++ const size_t lenOfShortestInclude = sizeof("") - 1; + const XmlBigCount countBytesOutput + = rootParser->m_accounting.countBytesDirect + + rootParser->m_accounting.countBytesIndirect; +@@ -7786,7 +7817,9 @@ + = rootParser->m_accounting.countBytesDirect + ? (countBytesOutput + / (float)(rootParser->m_accounting.countBytesDirect)) +- : 1.0f; ++ : ((lenOfShortestInclude ++ + rootParser->m_accounting.countBytesIndirect) ++ / (float)lenOfShortestInclude); + assert(! rootParser->m_parentParser); + return amplificationFactor; + } +diff --git a/Modules/getpath.c b/Modules/getpath.c +index 61d654065fd..8bd844d6459 100644 +--- a/Modules/getpath.c ++++ b/Modules/getpath.c +@@ -15,6 +15,7 @@ + #endif + + #ifdef __APPLE__ ++# include "TargetConditionals.h" + # include + #endif + +@@ -767,7 +768,7 @@ + if (PyWin_DLLhModule) { + return winmodule_to_dict(dict, key, PyWin_DLLhModule); + } +-#elif defined(WITH_NEXT_FRAMEWORK) ++#elif defined(WITH_NEXT_FRAMEWORK) && !defined(TARGET_OS_IPHONE) + static char modPath[MAXPATHLEN + 1]; + static int modPathInitialized = -1; + if (modPathInitialized < 0) { +@@ -961,4 +962,3 @@ + + return _PyStatus_OK(); + } +- +diff --git a/Modules/main.c b/Modules/main.c +index 6904e3f76e8..f6dade1e409 100644 +--- a/Modules/main.c ++++ b/Modules/main.c +@@ -531,6 +531,10 @@ + return; + } + ++ if (PySys_Audit("cpython.run_stdin", NULL) < 0) { ++ return; ++ } ++ + PyCompilerFlags cf = _PyCompilerFlags_INIT; + int res = PyRun_AnyFileFlags(stdin, "", &cf); + *exitcode = (res != 0); +diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c +index 6114f611682..6fb2fc8ce25 100644 +--- a/Modules/posixmodule.c ++++ b/Modules/posixmodule.c +@@ -34,6 +34,11 @@ + #include "pycore_pystate.h" // _PyInterpreterState_GET() + #include "pycore_signal.h" // Py_NSIG + ++#ifdef MS_WINDOWS ++# include // SetEntriesInAcl ++# include // SDDL_REVISION_1 ++#endif ++ + #include "structmember.h" // PyMemberDef + #ifndef MS_WINDOWS + # include "posixmodule.h" +@@ -598,6 +603,11 @@ + goto fatal_error; + } + ++ status = _PyRuntimeState_ReInitThreads(runtime); ++ if (_PyStatus_EXCEPTION(status)) { ++ goto fatal_error; ++ } ++ + PyThreadState *tstate = _PyThreadState_GET(); + _Py_EnsureTstateNotNULL(tstate); + +@@ -617,11 +627,6 @@ + + _PySignal_AfterFork(); + +- status = _PyRuntimeState_ReInitThreads(runtime); +- if (_PyStatus_EXCEPTION(status)) { +- goto fatal_error; +- } +- + status = _PyInterpreterState_DeleteExceptMain(runtime); + if (_PyStatus_EXCEPTION(status)) { + goto fatal_error; +@@ -4611,6 +4616,12 @@ + /*[clinic end generated code: output=a70446903abe821f input=a61722e1576fab03]*/ + { + int result; ++#ifdef MS_WINDOWS ++ int error = 0; ++ int pathError = 0; ++ SECURITY_ATTRIBUTES secAttr = { sizeof(secAttr) }; ++ SECURITY_ATTRIBUTES *pSecAttr = NULL; ++#endif + #ifdef HAVE_MKDIRAT + int mkdirat_unavailable = 0; + #endif +@@ -4622,11 +4633,38 @@ + + #ifdef MS_WINDOWS + Py_BEGIN_ALLOW_THREADS +- result = CreateDirectoryW(path->wide, NULL); ++ if (mode == 0700 /* 0o700 */) { ++ ULONG sdSize; ++ pSecAttr = &secAttr; ++ // Set a discretionary ACL (D) that is protected (P) and includes ++ // inheritable (OICI) entries that allow (A) full control (FA) to ++ // SYSTEM (SY), Administrators (BA), and the owner (OW). ++ if (!ConvertStringSecurityDescriptorToSecurityDescriptorW( ++ L"D:P(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;FA;;;OW)", ++ SDDL_REVISION_1, ++ &secAttr.lpSecurityDescriptor, ++ &sdSize ++ )) { ++ error = GetLastError(); ++ } ++ } ++ if (!error) { ++ result = CreateDirectoryW(path->wide, pSecAttr); ++ if (secAttr.lpSecurityDescriptor && ++ // uncommonly, LocalFree returns non-zero on error, but still uses ++ // GetLastError() to see what the error code is ++ LocalFree(secAttr.lpSecurityDescriptor)) { ++ error = GetLastError(); ++ } ++ } + Py_END_ALLOW_THREADS + +- if (!result) ++ if (error) { ++ return PyErr_SetFromWindowsErr(error); ++ } ++ if (!result) { + return path_error(path); ++ } + #else + Py_BEGIN_ALLOW_THREADS + #if HAVE_MKDIRAT +diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat +index b4362a5a259..b675a555c6c 100644 +--- a/PCbuild/get_externals.bat ++++ b/PCbuild/get_externals.bat +@@ -53,7 +53,7 @@ + set libraries= + set libraries=%libraries% bzip2-1.0.8 + if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi-3.4.4 +-if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-3.0.13 ++if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-3.0.15 + set libraries=%libraries% sqlite-3.45.1.0 + if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.12.1 + if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.12.1 +@@ -77,7 +77,7 @@ + + set binaries= + if NOT "%IncludeLibffi%"=="false" set binaries=%binaries% libffi-3.4.4 +-if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-3.0.13 ++if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-3.0.15 + if NOT "%IncludeTkinter%"=="false" set binaries=%binaries% tcltk-8.6.12.1 + if NOT "%IncludeSSLSrc%"=="false" set binaries=%binaries% nasm-2.11.06 + +diff --git a/PCbuild/python.props b/PCbuild/python.props +index d85fe4ab2a3..49347c2b78d 100644 +--- a/PCbuild/python.props ++++ b/PCbuild/python.props +@@ -74,8 +74,8 @@ + $(ExternalsDir)libffi-3.4.4\ + $(libffiDir)$(ArchName)\ + $(libffiOutDir)include +- $(ExternalsDir)openssl-3.0.13\ +- $(ExternalsDir)openssl-bin-3.0.13\$(ArchName)\ ++ $(ExternalsDir)openssl-3.0.15\ ++ $(ExternalsDir)openssl-bin-3.0.15\$(ArchName)\ + $(opensslOutDir)include + $(ExternalsDir)\nasm-2.11.06\ + $(ExternalsDir)\zlib-1.3.1\ +diff --git a/Parser/parser.c b/Parser/parser.c +index 2f1427af501..1eae6af1956 100644 +--- a/Parser/parser.c ++++ b/Parser/parser.c +@@ -450,72 +450,72 @@ + #define _gather_141_type 1370 + #define _tmp_143_type 1371 + #define _tmp_144_type 1372 +-#define _tmp_145_type 1373 +-#define _tmp_146_type 1374 ++#define _loop0_146_type 1373 ++#define _gather_145_type 1374 + #define _tmp_147_type 1375 + #define _tmp_148_type 1376 + #define _tmp_149_type 1377 + #define _tmp_150_type 1378 + #define _tmp_151_type 1379 + #define _tmp_152_type 1380 +-#define _loop0_153_type 1381 +-#define _loop0_154_type 1382 ++#define _tmp_153_type 1381 ++#define _tmp_154_type 1382 + #define _loop0_155_type 1383 +-#define _tmp_156_type 1384 +-#define _tmp_157_type 1385 ++#define _loop0_156_type 1384 ++#define _loop0_157_type 1385 + #define _tmp_158_type 1386 + #define _tmp_159_type 1387 +-#define _loop0_160_type 1388 +-#define _loop0_161_type 1389 +-#define _loop1_162_type 1390 +-#define _tmp_163_type 1391 +-#define _loop0_164_type 1392 ++#define _tmp_160_type 1388 ++#define _tmp_161_type 1389 ++#define _loop0_162_type 1390 ++#define _loop0_163_type 1391 ++#define _loop1_164_type 1392 + #define _tmp_165_type 1393 + #define _loop0_166_type 1394 + #define _tmp_167_type 1395 + #define _loop0_168_type 1396 +-#define _loop1_169_type 1397 +-#define _tmp_170_type 1398 +-#define _tmp_171_type 1399 ++#define _tmp_169_type 1397 ++#define _loop0_170_type 1398 ++#define _loop1_171_type 1399 + #define _tmp_172_type 1400 +-#define _loop0_173_type 1401 ++#define _tmp_173_type 1401 + #define _tmp_174_type 1402 +-#define _tmp_175_type 1403 +-#define _loop1_176_type 1404 +-#define _loop0_177_type 1405 +-#define _loop0_178_type 1406 +-#define _loop0_180_type 1407 +-#define _gather_179_type 1408 +-#define _tmp_181_type 1409 +-#define _loop0_182_type 1410 ++#define _loop0_175_type 1403 ++#define _tmp_176_type 1404 ++#define _tmp_177_type 1405 ++#define _loop1_178_type 1406 ++#define _loop0_179_type 1407 ++#define _loop0_180_type 1408 ++#define _loop0_182_type 1409 ++#define _gather_181_type 1410 + #define _tmp_183_type 1411 + #define _loop0_184_type 1412 + #define _tmp_185_type 1413 + #define _loop0_186_type 1414 +-#define _loop1_187_type 1415 +-#define _loop1_188_type 1416 +-#define _tmp_189_type 1417 +-#define _tmp_190_type 1418 +-#define _loop0_191_type 1419 ++#define _tmp_187_type 1415 ++#define _loop0_188_type 1416 ++#define _loop1_189_type 1417 ++#define _loop1_190_type 1418 ++#define _tmp_191_type 1419 + #define _tmp_192_type 1420 +-#define _tmp_193_type 1421 ++#define _loop0_193_type 1421 + #define _tmp_194_type 1422 +-#define _loop0_196_type 1423 +-#define _gather_195_type 1424 ++#define _tmp_195_type 1423 ++#define _tmp_196_type 1424 + #define _loop0_198_type 1425 + #define _gather_197_type 1426 + #define _loop0_200_type 1427 + #define _gather_199_type 1428 + #define _loop0_202_type 1429 + #define _gather_201_type 1430 +-#define _tmp_203_type 1431 +-#define _loop0_204_type 1432 +-#define _loop1_205_type 1433 +-#define _tmp_206_type 1434 +-#define _loop0_207_type 1435 +-#define _loop1_208_type 1436 +-#define _tmp_209_type 1437 +-#define _tmp_210_type 1438 ++#define _loop0_204_type 1431 ++#define _gather_203_type 1432 ++#define _tmp_205_type 1433 ++#define _loop0_206_type 1434 ++#define _loop1_207_type 1435 ++#define _tmp_208_type 1436 ++#define _loop0_209_type 1437 ++#define _loop1_210_type 1438 + #define _tmp_211_type 1439 + #define _tmp_212_type 1440 + #define _tmp_213_type 1441 +@@ -524,10 +524,10 @@ + #define _tmp_216_type 1444 + #define _tmp_217_type 1445 + #define _tmp_218_type 1446 +-#define _loop0_220_type 1447 +-#define _gather_219_type 1448 +-#define _tmp_221_type 1449 +-#define _tmp_222_type 1450 ++#define _tmp_219_type 1447 ++#define _tmp_220_type 1448 ++#define _loop0_222_type 1449 ++#define _gather_221_type 1450 + #define _tmp_223_type 1451 + #define _tmp_224_type 1452 + #define _tmp_225_type 1453 +@@ -553,14 +553,17 @@ + #define _tmp_245_type 1473 + #define _tmp_246_type 1474 + #define _tmp_247_type 1475 +-#define _loop0_249_type 1476 +-#define _gather_248_type 1477 ++#define _tmp_248_type 1476 ++#define _tmp_249_type 1477 + #define _tmp_250_type 1478 +-#define _tmp_251_type 1479 +-#define _tmp_252_type 1480 ++#define _loop0_252_type 1479 ++#define _gather_251_type 1480 + #define _tmp_253_type 1481 + #define _tmp_254_type 1482 + #define _tmp_255_type 1483 ++#define _tmp_256_type 1484 ++#define _tmp_257_type 1485 ++#define _tmp_258_type 1486 + + static mod_ty file_rule(Parser *p); + static mod_ty interactive_rule(Parser *p); +@@ -935,72 +938,72 @@ + static asdl_seq *_gather_141_rule(Parser *p); + static void *_tmp_143_rule(Parser *p); + static void *_tmp_144_rule(Parser *p); +-static void *_tmp_145_rule(Parser *p); +-static void *_tmp_146_rule(Parser *p); ++static asdl_seq *_loop0_146_rule(Parser *p); ++static asdl_seq *_gather_145_rule(Parser *p); + static void *_tmp_147_rule(Parser *p); + static void *_tmp_148_rule(Parser *p); + static void *_tmp_149_rule(Parser *p); + static void *_tmp_150_rule(Parser *p); + static void *_tmp_151_rule(Parser *p); + static void *_tmp_152_rule(Parser *p); +-static asdl_seq *_loop0_153_rule(Parser *p); +-static asdl_seq *_loop0_154_rule(Parser *p); ++static void *_tmp_153_rule(Parser *p); ++static void *_tmp_154_rule(Parser *p); + static asdl_seq *_loop0_155_rule(Parser *p); +-static void *_tmp_156_rule(Parser *p); +-static void *_tmp_157_rule(Parser *p); ++static asdl_seq *_loop0_156_rule(Parser *p); ++static asdl_seq *_loop0_157_rule(Parser *p); + static void *_tmp_158_rule(Parser *p); + static void *_tmp_159_rule(Parser *p); +-static asdl_seq *_loop0_160_rule(Parser *p); +-static asdl_seq *_loop0_161_rule(Parser *p); +-static asdl_seq *_loop1_162_rule(Parser *p); +-static void *_tmp_163_rule(Parser *p); +-static asdl_seq *_loop0_164_rule(Parser *p); ++static void *_tmp_160_rule(Parser *p); ++static void *_tmp_161_rule(Parser *p); ++static asdl_seq *_loop0_162_rule(Parser *p); ++static asdl_seq *_loop0_163_rule(Parser *p); ++static asdl_seq *_loop1_164_rule(Parser *p); + static void *_tmp_165_rule(Parser *p); + static asdl_seq *_loop0_166_rule(Parser *p); + static void *_tmp_167_rule(Parser *p); + static asdl_seq *_loop0_168_rule(Parser *p); +-static asdl_seq *_loop1_169_rule(Parser *p); +-static void *_tmp_170_rule(Parser *p); +-static void *_tmp_171_rule(Parser *p); ++static void *_tmp_169_rule(Parser *p); ++static asdl_seq *_loop0_170_rule(Parser *p); ++static asdl_seq *_loop1_171_rule(Parser *p); + static void *_tmp_172_rule(Parser *p); +-static asdl_seq *_loop0_173_rule(Parser *p); ++static void *_tmp_173_rule(Parser *p); + static void *_tmp_174_rule(Parser *p); +-static void *_tmp_175_rule(Parser *p); +-static asdl_seq *_loop1_176_rule(Parser *p); +-static asdl_seq *_loop0_177_rule(Parser *p); +-static asdl_seq *_loop0_178_rule(Parser *p); ++static asdl_seq *_loop0_175_rule(Parser *p); ++static void *_tmp_176_rule(Parser *p); ++static void *_tmp_177_rule(Parser *p); ++static asdl_seq *_loop1_178_rule(Parser *p); ++static asdl_seq *_loop0_179_rule(Parser *p); + static asdl_seq *_loop0_180_rule(Parser *p); +-static asdl_seq *_gather_179_rule(Parser *p); +-static void *_tmp_181_rule(Parser *p); + static asdl_seq *_loop0_182_rule(Parser *p); ++static asdl_seq *_gather_181_rule(Parser *p); + static void *_tmp_183_rule(Parser *p); + static asdl_seq *_loop0_184_rule(Parser *p); + static void *_tmp_185_rule(Parser *p); + static asdl_seq *_loop0_186_rule(Parser *p); +-static asdl_seq *_loop1_187_rule(Parser *p); +-static asdl_seq *_loop1_188_rule(Parser *p); +-static void *_tmp_189_rule(Parser *p); +-static void *_tmp_190_rule(Parser *p); +-static asdl_seq *_loop0_191_rule(Parser *p); ++static void *_tmp_187_rule(Parser *p); ++static asdl_seq *_loop0_188_rule(Parser *p); ++static asdl_seq *_loop1_189_rule(Parser *p); ++static asdl_seq *_loop1_190_rule(Parser *p); ++static void *_tmp_191_rule(Parser *p); + static void *_tmp_192_rule(Parser *p); +-static void *_tmp_193_rule(Parser *p); ++static asdl_seq *_loop0_193_rule(Parser *p); + static void *_tmp_194_rule(Parser *p); +-static asdl_seq *_loop0_196_rule(Parser *p); +-static asdl_seq *_gather_195_rule(Parser *p); ++static void *_tmp_195_rule(Parser *p); ++static void *_tmp_196_rule(Parser *p); + static asdl_seq *_loop0_198_rule(Parser *p); + static asdl_seq *_gather_197_rule(Parser *p); + static asdl_seq *_loop0_200_rule(Parser *p); + static asdl_seq *_gather_199_rule(Parser *p); + static asdl_seq *_loop0_202_rule(Parser *p); + static asdl_seq *_gather_201_rule(Parser *p); +-static void *_tmp_203_rule(Parser *p); + static asdl_seq *_loop0_204_rule(Parser *p); +-static asdl_seq *_loop1_205_rule(Parser *p); +-static void *_tmp_206_rule(Parser *p); +-static asdl_seq *_loop0_207_rule(Parser *p); +-static asdl_seq *_loop1_208_rule(Parser *p); +-static void *_tmp_209_rule(Parser *p); +-static void *_tmp_210_rule(Parser *p); ++static asdl_seq *_gather_203_rule(Parser *p); ++static void *_tmp_205_rule(Parser *p); ++static asdl_seq *_loop0_206_rule(Parser *p); ++static asdl_seq *_loop1_207_rule(Parser *p); ++static void *_tmp_208_rule(Parser *p); ++static asdl_seq *_loop0_209_rule(Parser *p); ++static asdl_seq *_loop1_210_rule(Parser *p); + static void *_tmp_211_rule(Parser *p); + static void *_tmp_212_rule(Parser *p); + static void *_tmp_213_rule(Parser *p); +@@ -1009,10 +1012,10 @@ + static void *_tmp_216_rule(Parser *p); + static void *_tmp_217_rule(Parser *p); + static void *_tmp_218_rule(Parser *p); +-static asdl_seq *_loop0_220_rule(Parser *p); +-static asdl_seq *_gather_219_rule(Parser *p); +-static void *_tmp_221_rule(Parser *p); +-static void *_tmp_222_rule(Parser *p); ++static void *_tmp_219_rule(Parser *p); ++static void *_tmp_220_rule(Parser *p); ++static asdl_seq *_loop0_222_rule(Parser *p); ++static asdl_seq *_gather_221_rule(Parser *p); + static void *_tmp_223_rule(Parser *p); + static void *_tmp_224_rule(Parser *p); + static void *_tmp_225_rule(Parser *p); +@@ -1038,14 +1041,17 @@ + static void *_tmp_245_rule(Parser *p); + static void *_tmp_246_rule(Parser *p); + static void *_tmp_247_rule(Parser *p); +-static asdl_seq *_loop0_249_rule(Parser *p); +-static asdl_seq *_gather_248_rule(Parser *p); ++static void *_tmp_248_rule(Parser *p); ++static void *_tmp_249_rule(Parser *p); + static void *_tmp_250_rule(Parser *p); +-static void *_tmp_251_rule(Parser *p); +-static void *_tmp_252_rule(Parser *p); ++static asdl_seq *_loop0_252_rule(Parser *p); ++static asdl_seq *_gather_251_rule(Parser *p); + static void *_tmp_253_rule(Parser *p); + static void *_tmp_254_rule(Parser *p); + static void *_tmp_255_rule(Parser *p); ++static void *_tmp_256_rule(Parser *p); ++static void *_tmp_257_rule(Parser *p); ++static void *_tmp_258_rule(Parser *p); + + + // file: statements? $ +@@ -16772,7 +16778,7 @@ + return _res; + } + +-// starred_expression: '*' expression ++// starred_expression: '*' expression | '*' + static expr_ty + starred_expression_rule(Parser *p) + { +@@ -16831,6 +16837,30 @@ + D(fprintf(stderr, "%*c%s starred_expression[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' expression")); + } ++ { // '*' ++ if (p->error_indicator) { ++ p->level--; ++ return NULL; ++ } ++ D(fprintf(stderr, "%*c> starred_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); ++ Token * _literal; ++ if ( ++ (_literal = _PyPegen_expect_token(p, 16)) // token='*' ++ ) ++ { ++ D(fprintf(stderr, "%*c+ starred_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); ++ _res = RAISE_SYNTAX_ERROR ( "Invalid star expression" ); ++ if (_res == NULL && PyErr_Occurred()) { ++ p->error_indicator = 1; ++ p->level--; ++ return NULL; ++ } ++ goto done; ++ } ++ p->mark = _mark; ++ D(fprintf(stderr, "%*c%s starred_expression[%d-%d]: %s failed!\n", p->level, ' ', ++ p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*'")); ++ } + _res = NULL; + done: + p->level--; +@@ -18927,7 +18957,7 @@ + } + + // invalid_arguments: +-// | ((','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' '*' ++// | ((','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' ','.(starred_expression !'=')+ + // | expression for_if_clauses ',' [args | expression for_if_clauses] + // | NAME '=' expression for_if_clauses + // | args for_if_clauses +@@ -18946,25 +18976,25 @@ + } + void * _res = NULL; + int _mark = p->mark; +- { // ((','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' '*' ++ { // ((','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' ','.(starred_expression !'=')+ + if (p->error_indicator) { + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> invalid_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' '*'")); +- Token * _literal; ++ D(fprintf(stderr, "%*c> invalid_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' ','.(starred_expression !'=')+")); ++ asdl_seq * _gather_145_var; + void *_tmp_144_var; +- Token * b; ++ Token * a; + if ( + (_tmp_144_var = _tmp_144_rule(p)) // (','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs + && +- (_literal = _PyPegen_expect_token(p, 12)) // token=',' ++ (a = _PyPegen_expect_token(p, 12)) // token=',' + && +- (b = _PyPegen_expect_token(p, 16)) // token='*' ++ (_gather_145_var = _gather_145_rule(p)) // ','.(starred_expression !'=')+ + ) + { +- D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "((','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' '*'")); +- _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( b , "iterable argument unpacking follows keyword argument unpacking" ); ++ D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "((','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' ','.(starred_expression !'=')+")); ++ _res = RAISE_SYNTAX_ERROR_STARTING_FROM ( a , "iterable argument unpacking follows keyword argument unpacking" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; +@@ -18974,7 +19004,7 @@ + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_arguments[%d-%d]: %s failed!\n", p->level, ' ', +- p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "((','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' '*'")); ++ p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "((','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' ','.(starred_expression !'=')+")); + } + { // expression for_if_clauses ',' [args | expression for_if_clauses] + if (p->error_indicator) { +@@ -18994,7 +19024,7 @@ + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && +- (_opt_var = _tmp_145_rule(p), !p->error_indicator) // [args | expression for_if_clauses] ++ (_opt_var = _tmp_147_rule(p), !p->error_indicator) // [args | expression for_if_clauses] + ) + { + D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses ',' [args | expression for_if_clauses]")); +@@ -19165,7 +19195,7 @@ + Token* a; + Token * b; + if ( +- (a = (Token*)_tmp_146_rule(p)) // 'True' | 'False' | 'None' ++ (a = (Token*)_tmp_148_rule(p)) // 'True' | 'False' | 'None' + && + (b = _PyPegen_expect_token(p, 22)) // token='=' + ) +@@ -19225,7 +19255,7 @@ + expr_ty a; + Token * b; + if ( +- _PyPegen_lookahead(0, _tmp_147_rule, p) ++ _PyPegen_lookahead(0, _tmp_149_rule, p) + && + (a = expression_rule(p)) // expression + && +@@ -19450,7 +19480,7 @@ + expr_ty a; + expr_ty b; + if ( +- _PyPegen_lookahead(0, _tmp_148_rule, p) ++ _PyPegen_lookahead(0, _tmp_150_rule, p) + && + (a = disjunction_rule(p)) // disjunction + && +@@ -19486,7 +19516,7 @@ + && + (b = disjunction_rule(p)) // disjunction + && +- _PyPegen_lookahead(0, _tmp_149_rule, p) ++ _PyPegen_lookahead(0, _tmp_151_rule, p) + ) + { + D(fprintf(stderr, "%*c+ invalid_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "disjunction 'if' disjunction !('else' | ':')")); +@@ -19575,7 +19605,7 @@ + && + (b = bitwise_or_rule(p)) // bitwise_or + && +- _PyPegen_lookahead(0, _tmp_150_rule, p) ++ _PyPegen_lookahead(0, _tmp_152_rule, p) + ) + { + D(fprintf(stderr, "%*c+ invalid_named_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '=' bitwise_or !('=' | ':=')")); +@@ -19601,7 +19631,7 @@ + Token * b; + expr_ty bitwise_or_var; + if ( +- _PyPegen_lookahead(0, _tmp_151_rule, p) ++ _PyPegen_lookahead(0, _tmp_153_rule, p) + && + (a = bitwise_or_rule(p)) // bitwise_or + && +@@ -19609,7 +19639,7 @@ + && + (bitwise_or_var = bitwise_or_rule(p)) // bitwise_or + && +- _PyPegen_lookahead(0, _tmp_152_rule, p) ++ _PyPegen_lookahead(0, _tmp_154_rule, p) + ) + { + D(fprintf(stderr, "%*c+ invalid_named_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!(list | tuple | genexp | 'True' | 'None' | 'False') bitwise_or '=' bitwise_or !('=' | ':=')")); +@@ -19690,7 +19720,7 @@ + D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions* ':' expression")); + Token * _literal; + Token * _literal_1; +- asdl_seq * _loop0_153_var; ++ asdl_seq * _loop0_155_var; + expr_ty a; + expr_ty expression_var; + if ( +@@ -19698,7 +19728,7 @@ + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && +- (_loop0_153_var = _loop0_153_rule(p)) // star_named_expressions* ++ (_loop0_155_var = _loop0_155_rule(p)) // star_named_expressions* + && + (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' + && +@@ -19755,10 +19785,10 @@ + } + D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* star_expressions '='")); + Token * _literal; +- asdl_seq * _loop0_154_var; ++ asdl_seq * _loop0_156_var; + expr_ty a; + if ( +- (_loop0_154_var = _loop0_154_rule(p)) // ((star_targets '='))* ++ (_loop0_156_var = _loop0_156_rule(p)) // ((star_targets '='))* + && + (a = star_expressions_rule(p)) // star_expressions + && +@@ -19785,10 +19815,10 @@ + } + D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* yield_expr '='")); + Token * _literal; +- asdl_seq * _loop0_155_var; ++ asdl_seq * _loop0_157_var; + expr_ty a; + if ( +- (_loop0_155_var = _loop0_155_rule(p)) // ((star_targets '='))* ++ (_loop0_157_var = _loop0_157_rule(p)) // ((star_targets '='))* + && + (a = yield_expr_rule(p)) // yield_expr + && +@@ -19814,7 +19844,7 @@ + return NULL; + } + D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions augassign (yield_expr | star_expressions)")); +- void *_tmp_156_var; ++ void *_tmp_158_var; + expr_ty a; + AugOperator* augassign_var; + if ( +@@ -19822,7 +19852,7 @@ + && + (augassign_var = augassign_rule(p)) // augassign + && +- (_tmp_156_var = _tmp_156_rule(p)) // yield_expr | star_expressions ++ (_tmp_158_var = _tmp_158_rule(p)) // yield_expr | star_expressions + ) + { + D(fprintf(stderr, "%*c+ invalid_assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions augassign (yield_expr | star_expressions)")); +@@ -20048,11 +20078,11 @@ + return NULL; + } + D(fprintf(stderr, "%*c> invalid_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('[' | '(' | '{') starred_expression for_if_clauses")); +- void *_tmp_157_var; ++ void *_tmp_159_var; + expr_ty a; + asdl_comprehension_seq* for_if_clauses_var; + if ( +- (_tmp_157_var = _tmp_157_rule(p)) // '[' | '(' | '{' ++ (_tmp_159_var = _tmp_159_rule(p)) // '[' | '(' | '{' + && + (a = starred_expression_rule(p)) // starred_expression + && +@@ -20079,12 +20109,12 @@ + } + D(fprintf(stderr, "%*c> invalid_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('[' | '{') star_named_expression ',' star_named_expressions for_if_clauses")); + Token * _literal; +- void *_tmp_158_var; ++ void *_tmp_160_var; + expr_ty a; + asdl_expr_seq* b; + asdl_comprehension_seq* for_if_clauses_var; + if ( +- (_tmp_158_var = _tmp_158_rule(p)) // '[' | '{' ++ (_tmp_160_var = _tmp_160_rule(p)) // '[' | '{' + && + (a = star_named_expression_rule(p)) // star_named_expression + && +@@ -20114,12 +20144,12 @@ + return NULL; + } + D(fprintf(stderr, "%*c> invalid_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('[' | '{') star_named_expression ',' for_if_clauses")); +- void *_tmp_159_var; ++ void *_tmp_161_var; + expr_ty a; + Token * b; + asdl_comprehension_seq* for_if_clauses_var; + if ( +- (_tmp_159_var = _tmp_159_rule(p)) // '[' | '{' ++ (_tmp_161_var = _tmp_161_rule(p)) // '[' | '{' + && + (a = star_named_expression_rule(p)) // star_named_expression + && +@@ -20229,11 +20259,11 @@ + return NULL; + } + D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default* invalid_parameters_helper param_no_default")); +- asdl_seq * _loop0_160_var; ++ asdl_seq * _loop0_162_var; + arg_ty a; + void *invalid_parameters_helper_var; + if ( +- (_loop0_160_var = _loop0_160_rule(p)) // param_no_default* ++ (_loop0_162_var = _loop0_162_rule(p)) // param_no_default* + && + (invalid_parameters_helper_var = invalid_parameters_helper_rule(p)) // invalid_parameters_helper + && +@@ -20259,18 +20289,18 @@ + return NULL; + } + D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default* '(' param_no_default+ ','? ')'")); +- asdl_seq * _loop0_161_var; +- asdl_seq * _loop1_162_var; ++ asdl_seq * _loop0_163_var; ++ asdl_seq * _loop1_164_var; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + Token * a; + Token * b; + if ( +- (_loop0_161_var = _loop0_161_rule(p)) // param_no_default* ++ (_loop0_163_var = _loop0_163_rule(p)) // param_no_default* + && + (a = _PyPegen_expect_token(p, 7)) // token='(' + && +- (_loop1_162_var = _loop1_162_rule(p)) // param_no_default+ ++ (_loop1_164_var = _loop1_164_rule(p)) // param_no_default+ + && + (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + && +@@ -20323,13 +20353,13 @@ + return NULL; + } + D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(slash_no_default | slash_with_default) param_maybe_default* '/'")); +- asdl_seq * _loop0_164_var; +- void *_tmp_163_var; ++ asdl_seq * _loop0_166_var; ++ void *_tmp_165_var; + Token * a; + if ( +- (_tmp_163_var = _tmp_163_rule(p)) // slash_no_default | slash_with_default ++ (_tmp_165_var = _tmp_165_rule(p)) // slash_no_default | slash_with_default + && +- (_loop0_164_var = _loop0_164_rule(p)) // param_maybe_default* ++ (_loop0_166_var = _loop0_166_rule(p)) // param_maybe_default* + && + (a = _PyPegen_expect_token(p, 17)) // token='/' + ) +@@ -20354,22 +20384,22 @@ + } + D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "[(slash_no_default | slash_with_default)] param_maybe_default* '*' (',' | param_no_default) param_maybe_default* '/'")); + Token * _literal; +- asdl_seq * _loop0_166_var; + asdl_seq * _loop0_168_var; ++ asdl_seq * _loop0_170_var; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings +- void *_tmp_167_var; ++ void *_tmp_169_var; + Token * a; + if ( +- (_opt_var = _tmp_165_rule(p), !p->error_indicator) // [(slash_no_default | slash_with_default)] ++ (_opt_var = _tmp_167_rule(p), !p->error_indicator) // [(slash_no_default | slash_with_default)] + && +- (_loop0_166_var = _loop0_166_rule(p)) // param_maybe_default* ++ (_loop0_168_var = _loop0_168_rule(p)) // param_maybe_default* + && + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && +- (_tmp_167_var = _tmp_167_rule(p)) // ',' | param_no_default ++ (_tmp_169_var = _tmp_169_rule(p)) // ',' | param_no_default + && +- (_loop0_168_var = _loop0_168_rule(p)) // param_maybe_default* ++ (_loop0_170_var = _loop0_170_rule(p)) // param_maybe_default* + && + (a = _PyPegen_expect_token(p, 17)) // token='/' + ) +@@ -20394,10 +20424,10 @@ + } + D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default+ '/' '*'")); + Token * _literal; +- asdl_seq * _loop1_169_var; ++ asdl_seq * _loop1_171_var; + Token * a; + if ( +- (_loop1_169_var = _loop1_169_rule(p)) // param_maybe_default+ ++ (_loop1_171_var = _loop1_171_rule(p)) // param_maybe_default+ + && + (_literal = _PyPegen_expect_token(p, 17)) // token='/' + && +@@ -20447,7 +20477,7 @@ + if ( + (a = _PyPegen_expect_token(p, 22)) // token='=' + && +- _PyPegen_lookahead(1, _tmp_170_rule, p) ++ _PyPegen_lookahead(1, _tmp_172_rule, p) + ) + { + D(fprintf(stderr, "%*c+ invalid_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'=' &(')' | ',')")); +@@ -20493,12 +20523,12 @@ + return NULL; + } + D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); +- void *_tmp_171_var; ++ void *_tmp_173_var; + Token * a; + if ( + (a = _PyPegen_expect_token(p, 16)) // token='*' + && +- (_tmp_171_var = _tmp_171_rule(p)) // ')' | ',' (')' | '**') ++ (_tmp_173_var = _tmp_173_rule(p)) // ')' | ',' (')' | '**') + ) + { + D(fprintf(stderr, "%*c+ invalid_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); +@@ -20581,20 +20611,20 @@ + } + D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (param_no_default | ',') param_maybe_default* '*' (param_no_default | ',')")); + Token * _literal; +- asdl_seq * _loop0_173_var; +- void *_tmp_172_var; ++ asdl_seq * _loop0_175_var; + void *_tmp_174_var; ++ void *_tmp_176_var; + Token * a; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && +- (_tmp_172_var = _tmp_172_rule(p)) // param_no_default | ',' ++ (_tmp_174_var = _tmp_174_rule(p)) // param_no_default | ',' + && +- (_loop0_173_var = _loop0_173_rule(p)) // param_maybe_default* ++ (_loop0_175_var = _loop0_175_rule(p)) // param_maybe_default* + && + (a = _PyPegen_expect_token(p, 16)) // token='*' + && +- (_tmp_174_var = _tmp_174_rule(p)) // param_no_default | ',' ++ (_tmp_176_var = _tmp_176_rule(p)) // param_no_default | ',' + ) + { + D(fprintf(stderr, "%*c+ invalid_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (param_no_default | ',') param_maybe_default* '*' (param_no_default | ',')")); +@@ -20710,7 +20740,7 @@ + && + (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' + && +- (a = (Token*)_tmp_175_rule(p)) // '*' | '**' | '/' ++ (a = (Token*)_tmp_177_rule(p)) // '*' | '**' | '/' + ) + { + D(fprintf(stderr, "%*c+ invalid_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' param ',' ('*' | '**' | '/')")); +@@ -20776,13 +20806,13 @@ + return NULL; + } + D(fprintf(stderr, "%*c> invalid_parameters_helper[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default+")); +- asdl_seq * _loop1_176_var; ++ asdl_seq * _loop1_178_var; + if ( +- (_loop1_176_var = _loop1_176_rule(p)) // param_with_default+ ++ (_loop1_178_var = _loop1_178_rule(p)) // param_with_default+ + ) + { + D(fprintf(stderr, "%*c+ invalid_parameters_helper[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_with_default+")); +- _res = _loop1_176_var; ++ _res = _loop1_178_var; + goto done; + } + p->mark = _mark; +@@ -20821,11 +20851,11 @@ + return NULL; + } + D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* invalid_lambda_parameters_helper lambda_param_no_default")); +- asdl_seq * _loop0_177_var; ++ asdl_seq * _loop0_179_var; + arg_ty a; + void *invalid_lambda_parameters_helper_var; + if ( +- (_loop0_177_var = _loop0_177_rule(p)) // lambda_param_no_default* ++ (_loop0_179_var = _loop0_179_rule(p)) // lambda_param_no_default* + && + (invalid_lambda_parameters_helper_var = invalid_lambda_parameters_helper_rule(p)) // invalid_lambda_parameters_helper + && +@@ -20851,18 +20881,18 @@ + return NULL; + } + D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* '(' ','.lambda_param+ ','? ')'")); +- asdl_seq * _gather_179_var; +- asdl_seq * _loop0_178_var; ++ asdl_seq * _gather_181_var; ++ asdl_seq * _loop0_180_var; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + Token * a; + Token * b; + if ( +- (_loop0_178_var = _loop0_178_rule(p)) // lambda_param_no_default* ++ (_loop0_180_var = _loop0_180_rule(p)) // lambda_param_no_default* + && + (a = _PyPegen_expect_token(p, 7)) // token='(' + && +- (_gather_179_var = _gather_179_rule(p)) // ','.lambda_param+ ++ (_gather_181_var = _gather_181_rule(p)) // ','.lambda_param+ + && + (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + && +@@ -20915,13 +20945,13 @@ + return NULL; + } + D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(lambda_slash_no_default | lambda_slash_with_default) lambda_param_maybe_default* '/'")); +- asdl_seq * _loop0_182_var; +- void *_tmp_181_var; ++ asdl_seq * _loop0_184_var; ++ void *_tmp_183_var; + Token * a; + if ( +- (_tmp_181_var = _tmp_181_rule(p)) // lambda_slash_no_default | lambda_slash_with_default ++ (_tmp_183_var = _tmp_183_rule(p)) // lambda_slash_no_default | lambda_slash_with_default + && +- (_loop0_182_var = _loop0_182_rule(p)) // lambda_param_maybe_default* ++ (_loop0_184_var = _loop0_184_rule(p)) // lambda_param_maybe_default* + && + (a = _PyPegen_expect_token(p, 17)) // token='/' + ) +@@ -20946,22 +20976,22 @@ + } + D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "[(lambda_slash_no_default | lambda_slash_with_default)] lambda_param_maybe_default* '*' (',' | lambda_param_no_default) lambda_param_maybe_default* '/'")); + Token * _literal; +- asdl_seq * _loop0_184_var; + asdl_seq * _loop0_186_var; ++ asdl_seq * _loop0_188_var; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings +- void *_tmp_185_var; ++ void *_tmp_187_var; + Token * a; + if ( +- (_opt_var = _tmp_183_rule(p), !p->error_indicator) // [(lambda_slash_no_default | lambda_slash_with_default)] ++ (_opt_var = _tmp_185_rule(p), !p->error_indicator) // [(lambda_slash_no_default | lambda_slash_with_default)] + && +- (_loop0_184_var = _loop0_184_rule(p)) // lambda_param_maybe_default* ++ (_loop0_186_var = _loop0_186_rule(p)) // lambda_param_maybe_default* + && + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && +- (_tmp_185_var = _tmp_185_rule(p)) // ',' | lambda_param_no_default ++ (_tmp_187_var = _tmp_187_rule(p)) // ',' | lambda_param_no_default + && +- (_loop0_186_var = _loop0_186_rule(p)) // lambda_param_maybe_default* ++ (_loop0_188_var = _loop0_188_rule(p)) // lambda_param_maybe_default* + && + (a = _PyPegen_expect_token(p, 17)) // token='/' + ) +@@ -20986,10 +21016,10 @@ + } + D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default+ '/' '*'")); + Token * _literal; +- asdl_seq * _loop1_187_var; ++ asdl_seq * _loop1_189_var; + Token * a; + if ( +- (_loop1_187_var = _loop1_187_rule(p)) // lambda_param_maybe_default+ ++ (_loop1_189_var = _loop1_189_rule(p)) // lambda_param_maybe_default+ + && + (_literal = _PyPegen_expect_token(p, 17)) // token='/' + && +@@ -21061,13 +21091,13 @@ + return NULL; + } + D(fprintf(stderr, "%*c> invalid_lambda_parameters_helper[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+")); +- asdl_seq * _loop1_188_var; ++ asdl_seq * _loop1_190_var; + if ( +- (_loop1_188_var = _loop1_188_rule(p)) // lambda_param_with_default+ ++ (_loop1_190_var = _loop1_190_rule(p)) // lambda_param_with_default+ + ) + { + D(fprintf(stderr, "%*c+ invalid_lambda_parameters_helper[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+")); +- _res = _loop1_188_var; ++ _res = _loop1_190_var; + goto done; + } + p->mark = _mark; +@@ -21104,11 +21134,11 @@ + } + D(fprintf(stderr, "%*c> invalid_lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); + Token * _literal; +- void *_tmp_189_var; ++ void *_tmp_191_var; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && +- (_tmp_189_var = _tmp_189_rule(p)) // ':' | ',' (':' | '**') ++ (_tmp_191_var = _tmp_191_rule(p)) // ':' | ',' (':' | '**') + ) + { + D(fprintf(stderr, "%*c+ invalid_lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); +@@ -21161,20 +21191,20 @@ + } + D(fprintf(stderr, "%*c> invalid_lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (lambda_param_no_default | ',') lambda_param_maybe_default* '*' (lambda_param_no_default | ',')")); + Token * _literal; +- asdl_seq * _loop0_191_var; +- void *_tmp_190_var; ++ asdl_seq * _loop0_193_var; + void *_tmp_192_var; ++ void *_tmp_194_var; + Token * a; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && +- (_tmp_190_var = _tmp_190_rule(p)) // lambda_param_no_default | ',' ++ (_tmp_192_var = _tmp_192_rule(p)) // lambda_param_no_default | ',' + && +- (_loop0_191_var = _loop0_191_rule(p)) // lambda_param_maybe_default* ++ (_loop0_193_var = _loop0_193_rule(p)) // lambda_param_maybe_default* + && + (a = _PyPegen_expect_token(p, 16)) // token='*' + && +- (_tmp_192_var = _tmp_192_rule(p)) // lambda_param_no_default | ',' ++ (_tmp_194_var = _tmp_194_rule(p)) // lambda_param_no_default | ',' + ) + { + D(fprintf(stderr, "%*c+ invalid_lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (lambda_param_no_default | ',') lambda_param_maybe_default* '*' (lambda_param_no_default | ',')")); +@@ -21293,7 +21323,7 @@ + && + (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' + && +- (a = (Token*)_tmp_193_rule(p)) // '*' | '**' | '/' ++ (a = (Token*)_tmp_195_rule(p)) // '*' | '**' | '/' + ) + { + D(fprintf(stderr, "%*c+ invalid_lambda_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' lambda_param ',' ('*' | '**' | '/')")); +@@ -21401,7 +21431,7 @@ + && + (a = expression_rule(p)) // expression + && +- _PyPegen_lookahead(1, _tmp_194_rule, p) ++ _PyPegen_lookahead(1, _tmp_196_rule, p) + ) + { + D(fprintf(stderr, "%*c+ invalid_with_item[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression 'as' expression &(',' | ')' | ':')")); +@@ -21629,7 +21659,7 @@ + return NULL; + } + D(fprintf(stderr, "%*c> invalid_with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' ','.(expression ['as' star_target])+ NEWLINE")); +- asdl_seq * _gather_195_var; ++ asdl_seq * _gather_197_var; + Token * _keyword; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings +@@ -21639,7 +21669,7 @@ + && + (_keyword = _PyPegen_expect_token(p, 612)) // token='with' + && +- (_gather_195_var = _gather_195_rule(p)) // ','.(expression ['as' star_target])+ ++ (_gather_197_var = _gather_197_rule(p)) // ','.(expression ['as' star_target])+ + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + ) +@@ -21663,7 +21693,7 @@ + return NULL; + } + D(fprintf(stderr, "%*c> invalid_with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' NEWLINE")); +- asdl_seq * _gather_197_var; ++ asdl_seq * _gather_199_var; + Token * _keyword; + Token * _literal; + Token * _literal_1; +@@ -21679,7 +21709,7 @@ + && + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && +- (_gather_197_var = _gather_197_rule(p)) // ','.(expressions ['as' star_target])+ ++ (_gather_199_var = _gather_199_rule(p)) // ','.(expressions ['as' star_target])+ + && + (_opt_var_1 = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + && +@@ -21729,7 +21759,7 @@ + return NULL; + } + D(fprintf(stderr, "%*c> invalid_with_stmt_indent[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT")); +- asdl_seq * _gather_199_var; ++ asdl_seq * _gather_201_var; + Token * _literal; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings +@@ -21740,7 +21770,7 @@ + && + (a = _PyPegen_expect_token(p, 612)) // token='with' + && +- (_gather_199_var = _gather_199_rule(p)) // ','.(expression ['as' star_target])+ ++ (_gather_201_var = _gather_201_rule(p)) // ','.(expression ['as' star_target])+ + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && +@@ -21768,7 +21798,7 @@ + return NULL; + } + D(fprintf(stderr, "%*c> invalid_with_stmt_indent[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' ':' NEWLINE !INDENT")); +- asdl_seq * _gather_201_var; ++ asdl_seq * _gather_203_var; + Token * _literal; + Token * _literal_1; + Token * _literal_2; +@@ -21785,7 +21815,7 @@ + && + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && +- (_gather_201_var = _gather_201_rule(p)) // ','.(expressions ['as' star_target])+ ++ (_gather_203_var = _gather_203_rule(p)) // ','.(expressions ['as' star_target])+ + && + (_opt_var_1 = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + && +@@ -21883,7 +21913,7 @@ + && + (block_var = block_rule(p)) // block + && +- _PyPegen_lookahead(0, _tmp_203_rule, p) ++ _PyPegen_lookahead(0, _tmp_205_rule, p) + ) + { + D(fprintf(stderr, "%*c+ invalid_try_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'try' ':' block !('except' | 'finally')")); +@@ -21908,8 +21938,8 @@ + Token * _keyword; + Token * _literal; + Token * _literal_1; +- asdl_seq * _loop0_204_var; +- asdl_seq * _loop1_205_var; ++ asdl_seq * _loop0_206_var; ++ asdl_seq * _loop1_207_var; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + Token * a; +@@ -21920,9 +21950,9 @@ + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && +- (_loop0_204_var = _loop0_204_rule(p)) // block* ++ (_loop0_206_var = _loop0_206_rule(p)) // block* + && +- (_loop1_205_var = _loop1_205_rule(p)) // except_block+ ++ (_loop1_207_var = _loop1_207_rule(p)) // except_block+ + && + (a = _PyPegen_expect_token(p, 634)) // token='except' + && +@@ -21930,7 +21960,7 @@ + && + (expression_var = expression_rule(p)) // expression + && +- (_opt_var = _tmp_206_rule(p), !p->error_indicator) // ['as' NAME] ++ (_opt_var = _tmp_208_rule(p), !p->error_indicator) // ['as' NAME] + && + (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' + ) +@@ -21957,8 +21987,8 @@ + Token * _keyword; + Token * _literal; + Token * _literal_1; +- asdl_seq * _loop0_207_var; +- asdl_seq * _loop1_208_var; ++ asdl_seq * _loop0_209_var; ++ asdl_seq * _loop1_210_var; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + Token * a; +@@ -21967,13 +21997,13 @@ + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && +- (_loop0_207_var = _loop0_207_rule(p)) // block* ++ (_loop0_209_var = _loop0_209_rule(p)) // block* + && +- (_loop1_208_var = _loop1_208_rule(p)) // except_star_block+ ++ (_loop1_210_var = _loop1_210_rule(p)) // except_star_block+ + && + (a = _PyPegen_expect_token(p, 634)) // token='except' + && +- (_opt_var = _tmp_209_rule(p), !p->error_indicator) // [expression ['as' NAME]] ++ (_opt_var = _tmp_211_rule(p), !p->error_indicator) // [expression ['as' NAME]] + && + (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' + ) +@@ -22041,7 +22071,7 @@ + && + (expressions_var = expressions_rule(p)) // expressions + && +- (_opt_var_1 = _tmp_210_rule(p), !p->error_indicator) // ['as' NAME] ++ (_opt_var_1 = _tmp_212_rule(p), !p->error_indicator) // ['as' NAME] + && + (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' + ) +@@ -22079,7 +22109,7 @@ + && + (expression_var = expression_rule(p)) // expression + && +- (_opt_var_1 = _tmp_211_rule(p), !p->error_indicator) // ['as' NAME] ++ (_opt_var_1 = _tmp_213_rule(p), !p->error_indicator) // ['as' NAME] + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + ) +@@ -22131,14 +22161,14 @@ + } + D(fprintf(stderr, "%*c> invalid_except_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' '*' (NEWLINE | ':')")); + Token * _literal; +- void *_tmp_212_var; ++ void *_tmp_214_var; + Token * a; + if ( + (a = _PyPegen_expect_token(p, 634)) // token='except' + && + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && +- (_tmp_212_var = _tmp_212_rule(p)) // NEWLINE | ':' ++ (_tmp_214_var = _tmp_214_rule(p)) // NEWLINE | ':' + ) + { + D(fprintf(stderr, "%*c+ invalid_except_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' '*' (NEWLINE | ':')")); +@@ -22245,7 +22275,7 @@ + && + (expression_var = expression_rule(p)) // expression + && +- (_opt_var = _tmp_213_rule(p), !p->error_indicator) // ['as' NAME] ++ (_opt_var = _tmp_215_rule(p), !p->error_indicator) // ['as' NAME] + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && +@@ -22340,7 +22370,7 @@ + && + (expression_var = expression_rule(p)) // expression + && +- (_opt_var = _tmp_214_rule(p), !p->error_indicator) // ['as' NAME] ++ (_opt_var = _tmp_216_rule(p), !p->error_indicator) // ['as' NAME] + && + (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' + && +@@ -22709,7 +22739,7 @@ + asdl_pattern_seq* a; + asdl_seq* keyword_patterns_var; + if ( +- (_opt_var = _tmp_215_rule(p), !p->error_indicator) // [positional_patterns ','] ++ (_opt_var = _tmp_217_rule(p), !p->error_indicator) // [positional_patterns ','] + && + (keyword_patterns_var = keyword_patterns_rule(p)) // keyword_patterns + && +@@ -23203,7 +23233,7 @@ + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + && +- (_opt_var_2 = _tmp_216_rule(p), !p->error_indicator) // ['->' expression] ++ (_opt_var_2 = _tmp_218_rule(p), !p->error_indicator) // ['->' expression] + && + (_literal_2 = _PyPegen_expect_token(p, 11)) // token=':' + && +@@ -23263,7 +23293,7 @@ + && + (name_var = _PyPegen_name_token(p)) // NAME + && +- (_opt_var = _tmp_217_rule(p), !p->error_indicator) // ['(' arguments? ')'] ++ (_opt_var = _tmp_219_rule(p), !p->error_indicator) // ['(' arguments? ')'] + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + ) +@@ -23298,7 +23328,7 @@ + && + (name_var = _PyPegen_name_token(p)) // NAME + && +- (_opt_var = _tmp_218_rule(p), !p->error_indicator) // ['(' arguments? ')'] ++ (_opt_var = _tmp_220_rule(p), !p->error_indicator) // ['(' arguments? ')'] + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && +@@ -23349,11 +23379,11 @@ + return NULL; + } + D(fprintf(stderr, "%*c> invalid_double_starred_kvpairs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.double_starred_kvpair+ ',' invalid_kvpair")); +- asdl_seq * _gather_219_var; ++ asdl_seq * _gather_221_var; + Token * _literal; + void *invalid_kvpair_var; + if ( +- (_gather_219_var = _gather_219_rule(p)) // ','.double_starred_kvpair+ ++ (_gather_221_var = _gather_221_rule(p)) // ','.double_starred_kvpair+ + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && +@@ -23361,7 +23391,7 @@ + ) + { + D(fprintf(stderr, "%*c+ invalid_double_starred_kvpairs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.double_starred_kvpair+ ',' invalid_kvpair")); +- _res = _PyPegen_dummy_name(p, _gather_219_var, _literal, invalid_kvpair_var); ++ _res = _PyPegen_dummy_name(p, _gather_221_var, _literal, invalid_kvpair_var); + goto done; + } + p->mark = _mark; +@@ -23414,7 +23444,7 @@ + && + (a = _PyPegen_expect_token(p, 11)) // token=':' + && +- _PyPegen_lookahead(1, _tmp_221_rule, p) ++ _PyPegen_lookahead(1, _tmp_223_rule, p) + ) + { + D(fprintf(stderr, "%*c+ invalid_double_starred_kvpairs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' &('}' | ',')")); +@@ -23525,7 +23555,7 @@ + && + (a = _PyPegen_expect_token(p, 11)) // token=':' + && +- _PyPegen_lookahead(1, _tmp_222_rule, p) ++ _PyPegen_lookahead(1, _tmp_224_rule, p) + ) + { + D(fprintf(stderr, "%*c+ invalid_kvpair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' &('}' | ',')")); +@@ -24376,12 +24406,12 @@ + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_14[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); +- void *_tmp_223_var; ++ void *_tmp_225_var; + while ( +- (_tmp_223_var = _tmp_223_rule(p)) // star_targets '=' ++ (_tmp_225_var = _tmp_225_rule(p)) // star_targets '=' + ) + { +- _res = _tmp_223_var; ++ _res = _tmp_225_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); +@@ -24955,12 +24985,12 @@ + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_24[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); +- void *_tmp_224_var; ++ void *_tmp_226_var; + while ( +- (_tmp_224_var = _tmp_224_rule(p)) // '.' | '...' ++ (_tmp_226_var = _tmp_226_rule(p)) // '.' | '...' + ) + { +- _res = _tmp_224_var; ++ _res = _tmp_226_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); +@@ -25023,12 +25053,12 @@ + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_25[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); +- void *_tmp_225_var; ++ void *_tmp_227_var; + while ( +- (_tmp_225_var = _tmp_225_rule(p)) // '.' | '...' ++ (_tmp_227_var = _tmp_227_rule(p)) // '.' | '...' + ) + { +- _res = _tmp_225_var; ++ _res = _tmp_227_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); +@@ -25428,12 +25458,12 @@ + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_32[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('@' named_expression NEWLINE)")); +- void *_tmp_226_var; ++ void *_tmp_228_var; + while ( +- (_tmp_226_var = _tmp_226_rule(p)) // '@' named_expression NEWLINE ++ (_tmp_228_var = _tmp_228_rule(p)) // '@' named_expression NEWLINE + ) + { +- _res = _tmp_226_var; ++ _res = _tmp_228_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); +@@ -28489,12 +28519,12 @@ + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_80[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' expression)")); +- void *_tmp_227_var; ++ void *_tmp_229_var; + while ( +- (_tmp_227_var = _tmp_227_rule(p)) // ',' expression ++ (_tmp_229_var = _tmp_229_rule(p)) // ',' expression + ) + { +- _res = _tmp_227_var; ++ _res = _tmp_229_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); +@@ -28562,12 +28592,12 @@ + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_81[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_expression)")); +- void *_tmp_228_var; ++ void *_tmp_230_var; + while ( +- (_tmp_228_var = _tmp_228_rule(p)) // ',' star_expression ++ (_tmp_230_var = _tmp_230_rule(p)) // ',' star_expression + ) + { +- _res = _tmp_228_var; ++ _res = _tmp_230_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); +@@ -28754,12 +28784,12 @@ + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_84[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('or' conjunction)")); +- void *_tmp_229_var; ++ void *_tmp_231_var; + while ( +- (_tmp_229_var = _tmp_229_rule(p)) // 'or' conjunction ++ (_tmp_231_var = _tmp_231_rule(p)) // 'or' conjunction + ) + { +- _res = _tmp_229_var; ++ _res = _tmp_231_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); +@@ -28827,12 +28857,12 @@ + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_85[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('and' inversion)")); +- void *_tmp_230_var; ++ void *_tmp_232_var; + while ( +- (_tmp_230_var = _tmp_230_rule(p)) // 'and' inversion ++ (_tmp_232_var = _tmp_232_rule(p)) // 'and' inversion + ) + { +- _res = _tmp_230_var; ++ _res = _tmp_232_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); +@@ -29022,7 +29052,7 @@ + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && +- (elem = _tmp_231_rule(p)) // slice | starred_expression ++ (elem = _tmp_233_rule(p)) // slice | starred_expression + ) + { + _res = elem; +@@ -29088,7 +29118,7 @@ + void *elem; + asdl_seq * seq; + if ( +- (elem = _tmp_231_rule(p)) // slice | starred_expression ++ (elem = _tmp_233_rule(p)) // slice | starred_expression + && + (seq = _loop0_89_rule(p)) // _loop0_89 + ) +@@ -30774,12 +30804,12 @@ + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_114[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); +- void *_tmp_232_var; ++ void *_tmp_234_var; + while ( +- (_tmp_232_var = _tmp_232_rule(p)) // 'if' disjunction ++ (_tmp_234_var = _tmp_234_rule(p)) // 'if' disjunction + ) + { +- _res = _tmp_232_var; ++ _res = _tmp_234_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); +@@ -30842,12 +30872,12 @@ + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_115[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); +- void *_tmp_233_var; ++ void *_tmp_235_var; + while ( +- (_tmp_233_var = _tmp_233_rule(p)) // 'if' disjunction ++ (_tmp_235_var = _tmp_235_rule(p)) // 'if' disjunction + ) + { +- _res = _tmp_233_var; ++ _res = _tmp_235_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); +@@ -30975,7 +31005,7 @@ + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && +- (elem = _tmp_234_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' ++ (elem = _tmp_236_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' + ) + { + _res = elem; +@@ -31042,7 +31072,7 @@ + void *elem; + asdl_seq * seq; + if ( +- (elem = _tmp_234_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' ++ (elem = _tmp_236_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' + && + (seq = _loop0_118_rule(p)) // _loop0_118 + ) +@@ -31613,12 +31643,12 @@ + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_128[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)")); +- void *_tmp_235_var; ++ void *_tmp_237_var; + while ( +- (_tmp_235_var = _tmp_235_rule(p)) // ',' star_target ++ (_tmp_237_var = _tmp_237_rule(p)) // ',' star_target + ) + { +- _res = _tmp_235_var; ++ _res = _tmp_237_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); +@@ -31800,12 +31830,12 @@ + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_131[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)")); +- void *_tmp_236_var; ++ void *_tmp_238_var; + while ( +- (_tmp_236_var = _tmp_236_rule(p)) // ',' star_target ++ (_tmp_238_var = _tmp_238_rule(p)) // ',' star_target + ) + { +- _res = _tmp_236_var; ++ _res = _tmp_238_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); +@@ -32544,13 +32574,13 @@ + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_144[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs)")); +- void *_tmp_237_var; ++ void *_tmp_239_var; + if ( +- (_tmp_237_var = _tmp_237_rule(p)) // ','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs ++ (_tmp_239_var = _tmp_239_rule(p)) // ','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs + ) + { + D(fprintf(stderr, "%*c+ _tmp_144[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs)")); +- _res = _tmp_237_var; ++ _res = _tmp_239_var; + goto done; + } + p->mark = _mark; +@@ -32582,9 +32612,128 @@ + return _res; + } + +-// _tmp_145: args | expression for_if_clauses ++// _loop0_146: ',' (starred_expression !'=') ++static asdl_seq * ++_loop0_146_rule(Parser *p) ++{ ++ 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; ++ void **_children = PyMem_Malloc(sizeof(void *)); ++ if (!_children) { ++ p->error_indicator = 1; ++ PyErr_NoMemory(); ++ p->level--; ++ return NULL; ++ } ++ Py_ssize_t _children_capacity = 1; ++ Py_ssize_t _n = 0; ++ { // ',' (starred_expression !'=') ++ if (p->error_indicator) { ++ p->level--; ++ return NULL; ++ } ++ D(fprintf(stderr, "%*c> _loop0_146[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (starred_expression !'=')")); ++ Token * _literal; ++ void *elem; ++ while ( ++ (_literal = _PyPegen_expect_token(p, 12)) // token=',' ++ && ++ (elem = _tmp_240_rule(p)) // starred_expression !'=' ++ ) ++ { ++ _res = elem; ++ if (_res == NULL && PyErr_Occurred()) { ++ p->error_indicator = 1; ++ PyMem_Free(_children); ++ p->level--; ++ return NULL; ++ } ++ if (_n == _children_capacity) { ++ _children_capacity *= 2; ++ void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); ++ if (!_new_children) { ++ PyMem_Free(_children); ++ p->error_indicator = 1; ++ PyErr_NoMemory(); ++ p->level--; ++ return NULL; ++ } ++ _children = _new_children; ++ } ++ _children[_n++] = _res; ++ _mark = p->mark; ++ } ++ p->mark = _mark; ++ D(fprintf(stderr, "%*c%s _loop0_146[%d-%d]: %s failed!\n", p->level, ' ', ++ p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (starred_expression !'=')")); ++ } ++ asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); ++ if (!_seq) { ++ PyMem_Free(_children); ++ p->error_indicator = 1; ++ PyErr_NoMemory(); ++ p->level--; ++ return NULL; ++ } ++ for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); ++ PyMem_Free(_children); ++ p->level--; ++ return _seq; ++} ++ ++// _gather_145: (starred_expression !'=') _loop0_146 ++static asdl_seq * ++_gather_145_rule(Parser *p) ++{ ++ if (p->level++ == MAXSTACK) { ++ p->error_indicator = 1; ++ PyErr_NoMemory(); ++ } ++ if (p->error_indicator) { ++ p->level--; ++ return NULL; ++ } ++ asdl_seq * _res = NULL; ++ int _mark = p->mark; ++ { // (starred_expression !'=') _loop0_146 ++ if (p->error_indicator) { ++ p->level--; ++ return NULL; ++ } ++ D(fprintf(stderr, "%*c> _gather_145[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(starred_expression !'=') _loop0_146")); ++ void *elem; ++ asdl_seq * seq; ++ if ( ++ (elem = _tmp_240_rule(p)) // starred_expression !'=' ++ && ++ (seq = _loop0_146_rule(p)) // _loop0_146 ++ ) ++ { ++ D(fprintf(stderr, "%*c+ _gather_145[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(starred_expression !'=') _loop0_146")); ++ _res = _PyPegen_seq_insert_in_front(p, elem, seq); ++ goto done; ++ } ++ p->mark = _mark; ++ D(fprintf(stderr, "%*c%s _gather_145[%d-%d]: %s failed!\n", p->level, ' ', ++ p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(starred_expression !'=') _loop0_146")); ++ } ++ _res = NULL; ++ done: ++ p->level--; ++ return _res; ++} ++ ++// _tmp_147: args | expression for_if_clauses + static void * +-_tmp_145_rule(Parser *p) ++_tmp_147_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -32601,18 +32750,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_145[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args")); ++ D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args")); + expr_ty args_var; + if ( + (args_var = args_rule(p)) // args + ) + { +- D(fprintf(stderr, "%*c+ _tmp_145[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args")); ++ D(fprintf(stderr, "%*c+ _tmp_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args")); + _res = args_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_145[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_147[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "args")); + } + { // expression for_if_clauses +@@ -32620,7 +32769,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_145[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses")); ++ D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses")); + expr_ty expression_var; + asdl_comprehension_seq* for_if_clauses_var; + if ( +@@ -32629,12 +32778,12 @@ + (for_if_clauses_var = for_if_clauses_rule(p)) // for_if_clauses + ) + { +- D(fprintf(stderr, "%*c+ _tmp_145[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses")); ++ D(fprintf(stderr, "%*c+ _tmp_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses")); + _res = _PyPegen_dummy_name(p, expression_var, for_if_clauses_var); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_145[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_147[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression for_if_clauses")); + } + _res = NULL; +@@ -32643,9 +32792,9 @@ + return _res; + } + +-// _tmp_146: 'True' | 'False' | 'None' ++// _tmp_148: 'True' | 'False' | 'None' + static void * +-_tmp_146_rule(Parser *p) ++_tmp_148_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -32662,18 +32811,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_146[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); ++ D(fprintf(stderr, "%*c> _tmp_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 600)) // token='True' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_146[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); ++ D(fprintf(stderr, "%*c+ _tmp_148[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); + _res = _keyword; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_146[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_148[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'True'")); + } + { // 'False' +@@ -32681,18 +32830,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_146[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); ++ D(fprintf(stderr, "%*c> _tmp_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 602)) // token='False' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_146[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); ++ D(fprintf(stderr, "%*c+ _tmp_148[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); + _res = _keyword; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_146[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_148[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'False'")); + } + { // 'None' +@@ -32700,18 +32849,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_146[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); ++ D(fprintf(stderr, "%*c> _tmp_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 601)) // token='None' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_146[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); ++ D(fprintf(stderr, "%*c+ _tmp_148[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); + _res = _keyword; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_146[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_148[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'None'")); + } + _res = NULL; +@@ -32720,9 +32869,9 @@ + return _res; + } + +-// _tmp_147: NAME '=' ++// _tmp_149: NAME '=' + static void * +-_tmp_147_rule(Parser *p) ++_tmp_149_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -32739,7 +32888,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '='")); ++ D(fprintf(stderr, "%*c> _tmp_149[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '='")); + Token * _literal; + expr_ty name_var; + if ( +@@ -32748,12 +32897,12 @@ + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '='")); ++ D(fprintf(stderr, "%*c+ _tmp_149[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '='")); + _res = _PyPegen_dummy_name(p, name_var, _literal); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_147[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_149[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME '='")); + } + _res = NULL; +@@ -32762,9 +32911,9 @@ + return _res; + } + +-// _tmp_148: NAME STRING | SOFT_KEYWORD ++// _tmp_150: NAME STRING | SOFT_KEYWORD + static void * +-_tmp_148_rule(Parser *p) ++_tmp_150_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -32781,7 +32930,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME STRING")); ++ D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME STRING")); + expr_ty name_var; + expr_ty string_var; + if ( +@@ -32790,12 +32939,12 @@ + (string_var = _PyPegen_string_token(p)) // STRING + ) + { +- D(fprintf(stderr, "%*c+ _tmp_148[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME STRING")); ++ D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME STRING")); + _res = _PyPegen_dummy_name(p, name_var, string_var); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_148[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME STRING")); + } + { // SOFT_KEYWORD +@@ -32803,18 +32952,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "SOFT_KEYWORD")); ++ D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "SOFT_KEYWORD")); + expr_ty soft_keyword_var; + if ( + (soft_keyword_var = _PyPegen_soft_keyword_token(p)) // SOFT_KEYWORD + ) + { +- D(fprintf(stderr, "%*c+ _tmp_148[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "SOFT_KEYWORD")); ++ D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "SOFT_KEYWORD")); + _res = soft_keyword_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_148[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "SOFT_KEYWORD")); + } + _res = NULL; +@@ -32823,9 +32972,9 @@ + return _res; + } + +-// _tmp_149: 'else' | ':' ++// _tmp_151: 'else' | ':' + static void * +-_tmp_149_rule(Parser *p) ++_tmp_151_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -32842,18 +32991,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_149[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'else'")); ++ D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'else'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 642)) // token='else' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_149[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'else'")); ++ D(fprintf(stderr, "%*c+ _tmp_151[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'else'")); + _res = _keyword; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_149[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_151[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'else'")); + } + { // ':' +@@ -32861,18 +33010,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_149[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); ++ D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_149[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); ++ D(fprintf(stderr, "%*c+ _tmp_151[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_149[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_151[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); + } + _res = NULL; +@@ -32881,9 +33030,9 @@ + return _res; + } + +-// _tmp_150: '=' | ':=' ++// _tmp_152: '=' | ':=' + static void * +-_tmp_150_rule(Parser *p) ++_tmp_152_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -32900,18 +33049,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); ++ D(fprintf(stderr, "%*c> _tmp_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); ++ D(fprintf(stderr, "%*c+ _tmp_152[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_152[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='")); + } + { // ':=' +@@ -32919,18 +33068,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='")); ++ D(fprintf(stderr, "%*c> _tmp_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 53)) // token=':=' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':='")); ++ D(fprintf(stderr, "%*c+ _tmp_152[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':='")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_152[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':='")); + } + _res = NULL; +@@ -32939,9 +33088,9 @@ + return _res; + } + +-// _tmp_151: list | tuple | genexp | 'True' | 'None' | 'False' ++// _tmp_153: list | tuple | genexp | 'True' | 'None' | 'False' + static void * +-_tmp_151_rule(Parser *p) ++_tmp_153_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -32958,18 +33107,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "list")); ++ D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "list")); + expr_ty list_var; + if ( + (list_var = list_rule(p)) // list + ) + { +- D(fprintf(stderr, "%*c+ _tmp_151[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "list")); ++ D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "list")); + _res = list_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_151[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "list")); + } + { // tuple +@@ -32977,18 +33126,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "tuple")); ++ D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "tuple")); + expr_ty tuple_var; + if ( + (tuple_var = tuple_rule(p)) // tuple + ) + { +- D(fprintf(stderr, "%*c+ _tmp_151[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "tuple")); ++ D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "tuple")); + _res = tuple_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_151[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "tuple")); + } + { // genexp +@@ -32996,18 +33145,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "genexp")); ++ D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "genexp")); + expr_ty genexp_var; + if ( + (genexp_var = genexp_rule(p)) // genexp + ) + { +- D(fprintf(stderr, "%*c+ _tmp_151[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "genexp")); ++ D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "genexp")); + _res = genexp_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_151[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "genexp")); + } + { // 'True' +@@ -33015,18 +33164,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); ++ D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 600)) // token='True' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_151[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); ++ D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); + _res = _keyword; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_151[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'True'")); + } + { // 'None' +@@ -33034,18 +33183,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); ++ D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 601)) // token='None' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_151[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); ++ D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); + _res = _keyword; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_151[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'None'")); + } + { // 'False' +@@ -33053,18 +33202,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); ++ D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 602)) // token='False' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_151[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); ++ D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); + _res = _keyword; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_151[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'False'")); + } + _res = NULL; +@@ -33073,9 +33222,9 @@ + return _res; + } + +-// _tmp_152: '=' | ':=' ++// _tmp_154: '=' | ':=' + static void * +-_tmp_152_rule(Parser *p) ++_tmp_154_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -33092,18 +33241,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); ++ D(fprintf(stderr, "%*c> _tmp_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_152[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); ++ D(fprintf(stderr, "%*c+ _tmp_154[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_152[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_154[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='")); + } + { // ':=' +@@ -33111,18 +33260,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='")); ++ D(fprintf(stderr, "%*c> _tmp_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 53)) // token=':=' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_152[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':='")); ++ D(fprintf(stderr, "%*c+ _tmp_154[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':='")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_152[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_154[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':='")); + } + _res = NULL; +@@ -33131,9 +33280,9 @@ + return _res; + } + +-// _loop0_153: star_named_expressions ++// _loop0_155: star_named_expressions + static asdl_seq * +-_loop0_153_rule(Parser *p) ++_loop0_155_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -33159,7 +33308,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop0_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expressions")); ++ D(fprintf(stderr, "%*c> _loop0_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expressions")); + asdl_expr_seq* star_named_expressions_var; + while ( + (star_named_expressions_var = star_named_expressions_rule(p)) // star_named_expressions +@@ -33182,7 +33331,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop0_153[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop0_155[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expressions")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); +@@ -33199,9 +33348,9 @@ + return _seq; + } + +-// _loop0_154: (star_targets '=') ++// _loop0_156: (star_targets '=') + static asdl_seq * +-_loop0_154_rule(Parser *p) ++_loop0_156_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -33227,13 +33376,13 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop0_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); +- void *_tmp_238_var; ++ D(fprintf(stderr, "%*c> _loop0_156[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); ++ void *_tmp_241_var; + while ( +- (_tmp_238_var = _tmp_238_rule(p)) // star_targets '=' ++ (_tmp_241_var = _tmp_241_rule(p)) // star_targets '=' + ) + { +- _res = _tmp_238_var; ++ _res = _tmp_241_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); +@@ -33250,7 +33399,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop0_154[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop0_156[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(star_targets '=')")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); +@@ -33267,9 +33416,9 @@ + return _seq; + } + +-// _loop0_155: (star_targets '=') ++// _loop0_157: (star_targets '=') + static asdl_seq * +-_loop0_155_rule(Parser *p) ++_loop0_157_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -33295,13 +33444,13 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop0_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); +- void *_tmp_239_var; ++ D(fprintf(stderr, "%*c> _loop0_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); ++ void *_tmp_242_var; + while ( +- (_tmp_239_var = _tmp_239_rule(p)) // star_targets '=' ++ (_tmp_242_var = _tmp_242_rule(p)) // star_targets '=' + ) + { +- _res = _tmp_239_var; ++ _res = _tmp_242_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); +@@ -33318,7 +33467,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop0_155[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop0_157[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(star_targets '=')")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); +@@ -33335,9 +33484,9 @@ + return _seq; + } + +-// _tmp_156: yield_expr | star_expressions ++// _tmp_158: yield_expr | star_expressions + static void * +-_tmp_156_rule(Parser *p) ++_tmp_158_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -33354,18 +33503,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_156[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); ++ D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + expr_ty yield_expr_var; + if ( + (yield_expr_var = yield_expr_rule(p)) // yield_expr + ) + { +- D(fprintf(stderr, "%*c+ _tmp_156[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); ++ D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + _res = yield_expr_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_156[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_158[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); + } + { // star_expressions +@@ -33373,18 +33522,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_156[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); ++ D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + expr_ty star_expressions_var; + if ( + (star_expressions_var = star_expressions_rule(p)) // star_expressions + ) + { +- D(fprintf(stderr, "%*c+ _tmp_156[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); ++ D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + _res = star_expressions_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_156[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_158[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); + } + _res = NULL; +@@ -33393,9 +33542,9 @@ + return _res; + } + +-// _tmp_157: '[' | '(' | '{' ++// _tmp_159: '[' | '(' | '{' + static void * +-_tmp_157_rule(Parser *p) ++_tmp_159_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -33412,18 +33561,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); ++ D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 9)) // token='[' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); ++ D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_159[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['")); + } + { // '(' +@@ -33431,18 +33580,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); ++ D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); ++ D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_159[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'('")); + } + { // '{' +@@ -33450,18 +33599,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); ++ D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 25)) // token='{' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); ++ D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_159[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'")); + } + _res = NULL; +@@ -33470,9 +33619,9 @@ + return _res; + } + +-// _tmp_158: '[' | '{' ++// _tmp_160: '[' | '{' + static void * +-_tmp_158_rule(Parser *p) ++_tmp_160_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -33489,18 +33638,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); ++ D(fprintf(stderr, "%*c> _tmp_160[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 9)) // token='[' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); ++ D(fprintf(stderr, "%*c+ _tmp_160[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_158[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_160[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['")); + } + { // '{' +@@ -33508,18 +33657,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); ++ D(fprintf(stderr, "%*c> _tmp_160[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 25)) // token='{' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); ++ D(fprintf(stderr, "%*c+ _tmp_160[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_158[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_160[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'")); + } + _res = NULL; +@@ -33528,9 +33677,9 @@ + return _res; + } + +-// _tmp_159: '[' | '{' ++// _tmp_161: '[' | '{' + static void * +-_tmp_159_rule(Parser *p) ++_tmp_161_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -33547,18 +33696,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); ++ D(fprintf(stderr, "%*c> _tmp_161[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 9)) // token='[' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); ++ D(fprintf(stderr, "%*c+ _tmp_161[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_159[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_161[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['")); + } + { // '{' +@@ -33566,18 +33715,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); ++ D(fprintf(stderr, "%*c> _tmp_161[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 25)) // token='{' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); ++ D(fprintf(stderr, "%*c+ _tmp_161[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_159[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_161[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'")); + } + _res = NULL; +@@ -33586,9 +33735,9 @@ + return _res; + } + +-// _loop0_160: param_no_default ++// _loop0_162: param_no_default + static asdl_seq * +-_loop0_160_rule(Parser *p) ++_loop0_162_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -33614,7 +33763,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop0_160[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); ++ D(fprintf(stderr, "%*c> _loop0_162[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + arg_ty param_no_default_var; + while ( + (param_no_default_var = param_no_default_rule(p)) // param_no_default +@@ -33637,7 +33786,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop0_160[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop0_162[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); +@@ -33654,9 +33803,9 @@ + return _seq; + } + +-// _loop0_161: param_no_default ++// _loop0_163: param_no_default + static asdl_seq * +-_loop0_161_rule(Parser *p) ++_loop0_163_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -33682,7 +33831,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop0_161[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); ++ D(fprintf(stderr, "%*c> _loop0_163[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + arg_ty param_no_default_var; + while ( + (param_no_default_var = param_no_default_rule(p)) // param_no_default +@@ -33705,7 +33854,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop0_161[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop0_163[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); +@@ -33722,9 +33871,9 @@ + return _seq; + } + +-// _loop1_162: param_no_default ++// _loop1_164: param_no_default + static asdl_seq * +-_loop1_162_rule(Parser *p) ++_loop1_164_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -33750,7 +33899,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop1_162[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); ++ D(fprintf(stderr, "%*c> _loop1_164[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + arg_ty param_no_default_var; + while ( + (param_no_default_var = param_no_default_rule(p)) // param_no_default +@@ -33773,7 +33922,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop1_162[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop1_164[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); + } + if (_n == 0 || p->error_indicator) { +@@ -33795,9 +33944,9 @@ + return _seq; + } + +-// _tmp_163: slash_no_default | slash_with_default ++// _tmp_165: slash_no_default | slash_with_default + static void * +-_tmp_163_rule(Parser *p) ++_tmp_165_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -33814,18 +33963,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_163[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default")); ++ D(fprintf(stderr, "%*c> _tmp_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default")); + asdl_arg_seq* slash_no_default_var; + if ( + (slash_no_default_var = slash_no_default_rule(p)) // slash_no_default + ) + { +- D(fprintf(stderr, "%*c+ _tmp_163[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default")); ++ D(fprintf(stderr, "%*c+ _tmp_165[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default")); + _res = slash_no_default_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_163[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_165[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_no_default")); + } + { // slash_with_default +@@ -33833,18 +33982,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_163[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); ++ D(fprintf(stderr, "%*c> _tmp_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + SlashWithDefault* slash_with_default_var; + if ( + (slash_with_default_var = slash_with_default_rule(p)) // slash_with_default + ) + { +- D(fprintf(stderr, "%*c+ _tmp_163[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); ++ D(fprintf(stderr, "%*c+ _tmp_165[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + _res = slash_with_default_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_163[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_165[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_with_default")); + } + _res = NULL; +@@ -33853,9 +34002,9 @@ + return _res; + } + +-// _loop0_164: param_maybe_default ++// _loop0_166: param_maybe_default + static asdl_seq * +-_loop0_164_rule(Parser *p) ++_loop0_166_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -33881,7 +34030,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop0_164[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); ++ D(fprintf(stderr, "%*c> _loop0_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + NameDefaultPair* param_maybe_default_var; + while ( + (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default +@@ -33904,7 +34053,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop0_164[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop0_166[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); +@@ -33921,9 +34070,9 @@ + return _seq; + } + +-// _tmp_165: slash_no_default | slash_with_default ++// _tmp_167: slash_no_default | slash_with_default + static void * +-_tmp_165_rule(Parser *p) ++_tmp_167_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -33940,18 +34089,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default")); ++ D(fprintf(stderr, "%*c> _tmp_167[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default")); + asdl_arg_seq* slash_no_default_var; + if ( + (slash_no_default_var = slash_no_default_rule(p)) // slash_no_default + ) + { +- D(fprintf(stderr, "%*c+ _tmp_165[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default")); ++ D(fprintf(stderr, "%*c+ _tmp_167[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default")); + _res = slash_no_default_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_165[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_167[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_no_default")); + } + { // slash_with_default +@@ -33959,18 +34108,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); ++ D(fprintf(stderr, "%*c> _tmp_167[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + SlashWithDefault* slash_with_default_var; + if ( + (slash_with_default_var = slash_with_default_rule(p)) // slash_with_default + ) + { +- D(fprintf(stderr, "%*c+ _tmp_165[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); ++ D(fprintf(stderr, "%*c+ _tmp_167[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + _res = slash_with_default_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_165[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_167[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_with_default")); + } + _res = NULL; +@@ -33979,9 +34128,9 @@ + return _res; + } + +-// _loop0_166: param_maybe_default ++// _loop0_168: param_maybe_default + static asdl_seq * +-_loop0_166_rule(Parser *p) ++_loop0_168_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -34007,7 +34156,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop0_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); ++ D(fprintf(stderr, "%*c> _loop0_168[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + NameDefaultPair* param_maybe_default_var; + while ( + (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default +@@ -34030,7 +34179,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop0_166[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop0_168[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); +@@ -34047,9 +34196,9 @@ + return _seq; + } + +-// _tmp_167: ',' | param_no_default ++// _tmp_169: ',' | param_no_default + static void * +-_tmp_167_rule(Parser *p) ++_tmp_169_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -34066,18 +34215,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_167[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); ++ D(fprintf(stderr, "%*c> _tmp_169[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_167[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); ++ D(fprintf(stderr, "%*c+ _tmp_169[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_167[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_169[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + } + { // param_no_default +@@ -34085,18 +34234,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_167[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); ++ D(fprintf(stderr, "%*c> _tmp_169[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + arg_ty param_no_default_var; + if ( + (param_no_default_var = param_no_default_rule(p)) // param_no_default + ) + { +- D(fprintf(stderr, "%*c+ _tmp_167[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); ++ D(fprintf(stderr, "%*c+ _tmp_169[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); + _res = param_no_default_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_167[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_169[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); + } + _res = NULL; +@@ -34105,9 +34254,9 @@ + return _res; + } + +-// _loop0_168: param_maybe_default ++// _loop0_170: param_maybe_default + static asdl_seq * +-_loop0_168_rule(Parser *p) ++_loop0_170_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -34133,7 +34282,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop0_168[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); ++ D(fprintf(stderr, "%*c> _loop0_170[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + NameDefaultPair* param_maybe_default_var; + while ( + (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default +@@ -34156,7 +34305,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop0_168[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop0_170[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); +@@ -34173,9 +34322,9 @@ + return _seq; + } + +-// _loop1_169: param_maybe_default ++// _loop1_171: param_maybe_default + static asdl_seq * +-_loop1_169_rule(Parser *p) ++_loop1_171_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -34201,7 +34350,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop1_169[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); ++ D(fprintf(stderr, "%*c> _loop1_171[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + NameDefaultPair* param_maybe_default_var; + while ( + (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default +@@ -34224,7 +34373,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop1_169[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop1_171[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); + } + if (_n == 0 || p->error_indicator) { +@@ -34246,9 +34395,9 @@ + return _seq; + } + +-// _tmp_170: ')' | ',' ++// _tmp_172: ')' | ',' + static void * +-_tmp_170_rule(Parser *p) ++_tmp_172_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -34265,18 +34414,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_170[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); ++ D(fprintf(stderr, "%*c> _tmp_172[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 8)) // token=')' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_170[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); ++ D(fprintf(stderr, "%*c+ _tmp_172[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_170[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_172[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); + } + { // ',' +@@ -34284,18 +34433,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_170[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); ++ D(fprintf(stderr, "%*c> _tmp_172[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_170[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); ++ D(fprintf(stderr, "%*c+ _tmp_172[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_170[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_172[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + } + _res = NULL; +@@ -34304,9 +34453,9 @@ + return _res; + } + +-// _tmp_171: ')' | ',' (')' | '**') ++// _tmp_173: ')' | ',' (')' | '**') + static void * +-_tmp_171_rule(Parser *p) ++_tmp_173_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -34323,18 +34472,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_171[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); ++ D(fprintf(stderr, "%*c> _tmp_173[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 8)) // token=')' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_171[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); ++ D(fprintf(stderr, "%*c+ _tmp_173[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_171[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_173[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); + } + { // ',' (')' | '**') +@@ -34342,21 +34491,21 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_171[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); ++ D(fprintf(stderr, "%*c> _tmp_173[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); + Token * _literal; +- void *_tmp_240_var; ++ void *_tmp_243_var; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && +- (_tmp_240_var = _tmp_240_rule(p)) // ')' | '**' ++ (_tmp_243_var = _tmp_243_rule(p)) // ')' | '**' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_171[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); +- _res = _PyPegen_dummy_name(p, _literal, _tmp_240_var); ++ D(fprintf(stderr, "%*c+ _tmp_173[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); ++ _res = _PyPegen_dummy_name(p, _literal, _tmp_243_var); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_171[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_173[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (')' | '**')")); + } + _res = NULL; +@@ -34365,9 +34514,9 @@ + return _res; + } + +-// _tmp_172: param_no_default | ',' ++// _tmp_174: param_no_default | ',' + static void * +-_tmp_172_rule(Parser *p) ++_tmp_174_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -34384,18 +34533,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_172[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); ++ D(fprintf(stderr, "%*c> _tmp_174[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + arg_ty param_no_default_var; + if ( + (param_no_default_var = param_no_default_rule(p)) // param_no_default + ) + { +- D(fprintf(stderr, "%*c+ _tmp_172[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); ++ D(fprintf(stderr, "%*c+ _tmp_174[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); + _res = param_no_default_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_172[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_174[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); + } + { // ',' +@@ -34403,18 +34552,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_172[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); ++ D(fprintf(stderr, "%*c> _tmp_174[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_172[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); ++ D(fprintf(stderr, "%*c+ _tmp_174[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_172[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_174[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + } + _res = NULL; +@@ -34423,9 +34572,9 @@ + return _res; + } + +-// _loop0_173: param_maybe_default ++// _loop0_175: param_maybe_default + static asdl_seq * +-_loop0_173_rule(Parser *p) ++_loop0_175_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -34451,7 +34600,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop0_173[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); ++ D(fprintf(stderr, "%*c> _loop0_175[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + NameDefaultPair* param_maybe_default_var; + while ( + (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default +@@ -34474,7 +34623,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop0_173[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop0_175[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); +@@ -34491,9 +34640,9 @@ + return _seq; + } + +-// _tmp_174: param_no_default | ',' ++// _tmp_176: param_no_default | ',' + static void * +-_tmp_174_rule(Parser *p) ++_tmp_176_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -34510,18 +34659,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_174[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); ++ D(fprintf(stderr, "%*c> _tmp_176[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + arg_ty param_no_default_var; + if ( + (param_no_default_var = param_no_default_rule(p)) // param_no_default + ) + { +- D(fprintf(stderr, "%*c+ _tmp_174[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); ++ D(fprintf(stderr, "%*c+ _tmp_176[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); + _res = param_no_default_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_174[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_176[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); + } + { // ',' +@@ -34529,18 +34678,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_174[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); ++ D(fprintf(stderr, "%*c> _tmp_176[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_174[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); ++ D(fprintf(stderr, "%*c+ _tmp_176[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_174[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_176[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + } + _res = NULL; +@@ -34549,9 +34698,9 @@ + return _res; + } + +-// _tmp_175: '*' | '**' | '/' ++// _tmp_177: '*' | '**' | '/' + static void * +-_tmp_175_rule(Parser *p) ++_tmp_177_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -34568,18 +34717,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_175[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); ++ D(fprintf(stderr, "%*c> _tmp_177[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_175[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); ++ D(fprintf(stderr, "%*c+ _tmp_177[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_175[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_177[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*'")); + } + { // '**' +@@ -34587,18 +34736,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_175[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); ++ D(fprintf(stderr, "%*c> _tmp_177[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 35)) // token='**' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_175[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); ++ D(fprintf(stderr, "%*c+ _tmp_177[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_175[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_177[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); + } + { // '/' +@@ -34606,18 +34755,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_175[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'")); ++ D(fprintf(stderr, "%*c> _tmp_177[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 17)) // token='/' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_175[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'")); ++ D(fprintf(stderr, "%*c+ _tmp_177[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_175[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_177[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'/'")); + } + _res = NULL; +@@ -34626,9 +34775,9 @@ + return _res; + } + +-// _loop1_176: param_with_default ++// _loop1_178: param_with_default + static asdl_seq * +-_loop1_176_rule(Parser *p) ++_loop1_178_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -34654,7 +34803,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop1_176[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); ++ D(fprintf(stderr, "%*c> _loop1_178[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); + NameDefaultPair* param_with_default_var; + while ( + (param_with_default_var = param_with_default_rule(p)) // param_with_default +@@ -34677,7 +34826,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop1_176[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop1_178[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); + } + if (_n == 0 || p->error_indicator) { +@@ -34699,9 +34848,9 @@ + return _seq; + } + +-// _loop0_177: lambda_param_no_default ++// _loop0_179: lambda_param_no_default + static asdl_seq * +-_loop0_177_rule(Parser *p) ++_loop0_179_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -34727,7 +34876,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop0_177[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); ++ D(fprintf(stderr, "%*c> _loop0_179[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + arg_ty lambda_param_no_default_var; + while ( + (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default +@@ -34750,7 +34899,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop0_177[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop0_179[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); +@@ -34767,9 +34916,9 @@ + return _seq; + } + +-// _loop0_178: lambda_param_no_default ++// _loop0_180: lambda_param_no_default + static asdl_seq * +-_loop0_178_rule(Parser *p) ++_loop0_180_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -34795,7 +34944,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop0_178[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); ++ D(fprintf(stderr, "%*c> _loop0_180[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + arg_ty lambda_param_no_default_var; + while ( + (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default +@@ -34818,7 +34967,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop0_178[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop0_180[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); +@@ -34835,9 +34984,9 @@ + return _seq; + } + +-// _loop0_180: ',' lambda_param ++// _loop0_182: ',' lambda_param + static asdl_seq * +-_loop0_180_rule(Parser *p) ++_loop0_182_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -34863,7 +35012,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop0_180[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' lambda_param")); ++ D(fprintf(stderr, "%*c> _loop0_182[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' lambda_param")); + Token * _literal; + arg_ty elem; + while ( +@@ -34895,7 +35044,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop0_180[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop0_182[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' lambda_param")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); +@@ -34912,9 +35061,9 @@ + return _seq; + } + +-// _gather_179: lambda_param _loop0_180 ++// _gather_181: lambda_param _loop0_182 + static asdl_seq * +-_gather_179_rule(Parser *p) ++_gather_181_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -34926,27 +35075,27 @@ + } + asdl_seq * _res = NULL; + int _mark = p->mark; +- { // lambda_param _loop0_180 ++ { // lambda_param _loop0_182 + if (p->error_indicator) { + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _gather_179[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_180")); ++ D(fprintf(stderr, "%*c> _gather_181[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_182")); + arg_ty elem; + asdl_seq * seq; + if ( + (elem = lambda_param_rule(p)) // lambda_param + && +- (seq = _loop0_180_rule(p)) // _loop0_180 ++ (seq = _loop0_182_rule(p)) // _loop0_182 + ) + { +- D(fprintf(stderr, "%*c+ _gather_179[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_180")); ++ D(fprintf(stderr, "%*c+ _gather_181[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_182")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _gather_179[%d-%d]: %s failed!\n", p->level, ' ', +- p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param _loop0_180")); ++ D(fprintf(stderr, "%*c%s _gather_181[%d-%d]: %s failed!\n", p->level, ' ', ++ p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param _loop0_182")); + } + _res = NULL; + done: +@@ -34954,9 +35103,9 @@ + return _res; + } + +-// _tmp_181: lambda_slash_no_default | lambda_slash_with_default ++// _tmp_183: lambda_slash_no_default | lambda_slash_with_default + static void * +-_tmp_181_rule(Parser *p) ++_tmp_183_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -34973,18 +35122,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_181[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); ++ D(fprintf(stderr, "%*c> _tmp_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + asdl_arg_seq* lambda_slash_no_default_var; + if ( + (lambda_slash_no_default_var = lambda_slash_no_default_rule(p)) // lambda_slash_no_default + ) + { +- D(fprintf(stderr, "%*c+ _tmp_181[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); ++ D(fprintf(stderr, "%*c+ _tmp_183[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + _res = lambda_slash_no_default_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_181[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_183[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_no_default")); + } + { // lambda_slash_with_default +@@ -34992,18 +35141,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_181[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); ++ D(fprintf(stderr, "%*c> _tmp_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + SlashWithDefault* lambda_slash_with_default_var; + if ( + (lambda_slash_with_default_var = lambda_slash_with_default_rule(p)) // lambda_slash_with_default + ) + { +- D(fprintf(stderr, "%*c+ _tmp_181[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); ++ D(fprintf(stderr, "%*c+ _tmp_183[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + _res = lambda_slash_with_default_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_181[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_183[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_with_default")); + } + _res = NULL; +@@ -35012,9 +35161,9 @@ + return _res; + } + +-// _loop0_182: lambda_param_maybe_default ++// _loop0_184: lambda_param_maybe_default + static asdl_seq * +-_loop0_182_rule(Parser *p) ++_loop0_184_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -35040,7 +35189,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop0_182[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); ++ D(fprintf(stderr, "%*c> _loop0_184[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + NameDefaultPair* lambda_param_maybe_default_var; + while ( + (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default +@@ -35063,7 +35212,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop0_182[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop0_184[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); +@@ -35080,9 +35229,9 @@ + return _seq; + } + +-// _tmp_183: lambda_slash_no_default | lambda_slash_with_default ++// _tmp_185: lambda_slash_no_default | lambda_slash_with_default + static void * +-_tmp_183_rule(Parser *p) ++_tmp_185_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -35099,18 +35248,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); ++ D(fprintf(stderr, "%*c> _tmp_185[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + asdl_arg_seq* lambda_slash_no_default_var; + if ( + (lambda_slash_no_default_var = lambda_slash_no_default_rule(p)) // lambda_slash_no_default + ) + { +- D(fprintf(stderr, "%*c+ _tmp_183[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); ++ D(fprintf(stderr, "%*c+ _tmp_185[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + _res = lambda_slash_no_default_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_183[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_185[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_no_default")); + } + { // lambda_slash_with_default +@@ -35118,18 +35267,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); ++ D(fprintf(stderr, "%*c> _tmp_185[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + SlashWithDefault* lambda_slash_with_default_var; + if ( + (lambda_slash_with_default_var = lambda_slash_with_default_rule(p)) // lambda_slash_with_default + ) + { +- D(fprintf(stderr, "%*c+ _tmp_183[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); ++ D(fprintf(stderr, "%*c+ _tmp_185[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + _res = lambda_slash_with_default_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_183[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_185[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_with_default")); + } + _res = NULL; +@@ -35138,9 +35287,9 @@ + return _res; + } + +-// _loop0_184: lambda_param_maybe_default ++// _loop0_186: lambda_param_maybe_default + static asdl_seq * +-_loop0_184_rule(Parser *p) ++_loop0_186_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -35166,7 +35315,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop0_184[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); ++ D(fprintf(stderr, "%*c> _loop0_186[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + NameDefaultPair* lambda_param_maybe_default_var; + while ( + (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default +@@ -35189,7 +35338,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop0_184[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop0_186[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); +@@ -35206,9 +35355,9 @@ + return _seq; + } + +-// _tmp_185: ',' | lambda_param_no_default ++// _tmp_187: ',' | lambda_param_no_default + static void * +-_tmp_185_rule(Parser *p) ++_tmp_187_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -35225,18 +35374,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_185[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); ++ D(fprintf(stderr, "%*c> _tmp_187[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_185[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); ++ D(fprintf(stderr, "%*c+ _tmp_187[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_185[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_187[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + } + { // lambda_param_no_default +@@ -35244,18 +35393,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_185[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); ++ D(fprintf(stderr, "%*c> _tmp_187[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + arg_ty lambda_param_no_default_var; + if ( + (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default + ) + { +- D(fprintf(stderr, "%*c+ _tmp_185[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); ++ D(fprintf(stderr, "%*c+ _tmp_187[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + _res = lambda_param_no_default_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_185[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_187[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); + } + _res = NULL; +@@ -35264,9 +35413,9 @@ + return _res; + } + +-// _loop0_186: lambda_param_maybe_default ++// _loop0_188: lambda_param_maybe_default + static asdl_seq * +-_loop0_186_rule(Parser *p) ++_loop0_188_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -35292,7 +35441,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop0_186[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); ++ D(fprintf(stderr, "%*c> _loop0_188[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + NameDefaultPair* lambda_param_maybe_default_var; + while ( + (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default +@@ -35315,7 +35464,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop0_186[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop0_188[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); +@@ -35332,9 +35481,9 @@ + return _seq; + } + +-// _loop1_187: lambda_param_maybe_default ++// _loop1_189: lambda_param_maybe_default + static asdl_seq * +-_loop1_187_rule(Parser *p) ++_loop1_189_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -35360,7 +35509,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop1_187[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); ++ D(fprintf(stderr, "%*c> _loop1_189[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + NameDefaultPair* lambda_param_maybe_default_var; + while ( + (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default +@@ -35383,7 +35532,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop1_187[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop1_189[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); + } + if (_n == 0 || p->error_indicator) { +@@ -35405,9 +35554,9 @@ + return _seq; + } + +-// _loop1_188: lambda_param_with_default ++// _loop1_190: lambda_param_with_default + static asdl_seq * +-_loop1_188_rule(Parser *p) ++_loop1_190_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -35433,7 +35582,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop1_188[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); ++ D(fprintf(stderr, "%*c> _loop1_190[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + NameDefaultPair* lambda_param_with_default_var; + while ( + (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default +@@ -35456,7 +35605,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop1_188[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop1_190[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); + } + if (_n == 0 || p->error_indicator) { +@@ -35478,9 +35627,9 @@ + return _seq; + } + +-// _tmp_189: ':' | ',' (':' | '**') ++// _tmp_191: ':' | ',' (':' | '**') + static void * +-_tmp_189_rule(Parser *p) ++_tmp_191_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -35497,18 +35646,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_189[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); ++ D(fprintf(stderr, "%*c> _tmp_191[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_189[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); ++ D(fprintf(stderr, "%*c+ _tmp_191[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_189[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_191[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); + } + { // ',' (':' | '**') +@@ -35516,21 +35665,21 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_189[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); ++ D(fprintf(stderr, "%*c> _tmp_191[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); + Token * _literal; +- void *_tmp_241_var; ++ void *_tmp_244_var; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && +- (_tmp_241_var = _tmp_241_rule(p)) // ':' | '**' ++ (_tmp_244_var = _tmp_244_rule(p)) // ':' | '**' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_189[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); +- _res = _PyPegen_dummy_name(p, _literal, _tmp_241_var); ++ D(fprintf(stderr, "%*c+ _tmp_191[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); ++ _res = _PyPegen_dummy_name(p, _literal, _tmp_244_var); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_189[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_191[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (':' | '**')")); + } + _res = NULL; +@@ -35539,9 +35688,9 @@ + return _res; + } + +-// _tmp_190: lambda_param_no_default | ',' ++// _tmp_192: lambda_param_no_default | ',' + static void * +-_tmp_190_rule(Parser *p) ++_tmp_192_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -35558,18 +35707,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_190[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); ++ D(fprintf(stderr, "%*c> _tmp_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + arg_ty lambda_param_no_default_var; + if ( + (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default + ) + { +- D(fprintf(stderr, "%*c+ _tmp_190[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); ++ D(fprintf(stderr, "%*c+ _tmp_192[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + _res = lambda_param_no_default_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_190[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_192[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); + } + { // ',' +@@ -35577,18 +35726,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_190[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); ++ D(fprintf(stderr, "%*c> _tmp_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_190[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); ++ D(fprintf(stderr, "%*c+ _tmp_192[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_190[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_192[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + } + _res = NULL; +@@ -35597,9 +35746,9 @@ + return _res; + } + +-// _loop0_191: lambda_param_maybe_default ++// _loop0_193: lambda_param_maybe_default + static asdl_seq * +-_loop0_191_rule(Parser *p) ++_loop0_193_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -35625,7 +35774,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop0_191[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); ++ D(fprintf(stderr, "%*c> _loop0_193[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + NameDefaultPair* lambda_param_maybe_default_var; + while ( + (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default +@@ -35648,7 +35797,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop0_191[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop0_193[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); +@@ -35665,9 +35814,9 @@ + return _seq; + } + +-// _tmp_192: lambda_param_no_default | ',' ++// _tmp_194: lambda_param_no_default | ',' + static void * +-_tmp_192_rule(Parser *p) ++_tmp_194_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -35684,18 +35833,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); ++ D(fprintf(stderr, "%*c> _tmp_194[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + arg_ty lambda_param_no_default_var; + if ( + (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default + ) + { +- D(fprintf(stderr, "%*c+ _tmp_192[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); ++ D(fprintf(stderr, "%*c+ _tmp_194[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + _res = lambda_param_no_default_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_192[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_194[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); + } + { // ',' +@@ -35703,18 +35852,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); ++ D(fprintf(stderr, "%*c> _tmp_194[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_192[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); ++ D(fprintf(stderr, "%*c+ _tmp_194[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_192[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_194[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + } + _res = NULL; +@@ -35723,9 +35872,9 @@ + return _res; + } + +-// _tmp_193: '*' | '**' | '/' ++// _tmp_195: '*' | '**' | '/' + static void * +-_tmp_193_rule(Parser *p) ++_tmp_195_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -35742,18 +35891,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_193[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); ++ D(fprintf(stderr, "%*c> _tmp_195[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_193[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); ++ D(fprintf(stderr, "%*c+ _tmp_195[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_193[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_195[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*'")); + } + { // '**' +@@ -35761,18 +35910,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_193[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); ++ D(fprintf(stderr, "%*c> _tmp_195[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 35)) // token='**' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_193[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); ++ D(fprintf(stderr, "%*c+ _tmp_195[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_193[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_195[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); + } + { // '/' +@@ -35780,18 +35929,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_193[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'")); ++ D(fprintf(stderr, "%*c> _tmp_195[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 17)) // token='/' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_193[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'")); ++ D(fprintf(stderr, "%*c+ _tmp_195[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_193[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_195[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'/'")); + } + _res = NULL; +@@ -35800,9 +35949,9 @@ + return _res; + } + +-// _tmp_194: ',' | ')' | ':' ++// _tmp_196: ',' | ')' | ':' + static void * +-_tmp_194_rule(Parser *p) ++_tmp_196_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -35819,18 +35968,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_194[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); ++ D(fprintf(stderr, "%*c> _tmp_196[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_194[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); ++ D(fprintf(stderr, "%*c+ _tmp_196[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_194[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_196[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + } + { // ')' +@@ -35838,18 +35987,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_194[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); ++ D(fprintf(stderr, "%*c> _tmp_196[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 8)) // token=')' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_194[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); ++ D(fprintf(stderr, "%*c+ _tmp_196[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_194[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_196[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); + } + { // ':' +@@ -35857,18 +36006,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_194[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); ++ D(fprintf(stderr, "%*c> _tmp_196[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_194[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); ++ D(fprintf(stderr, "%*c+ _tmp_196[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_194[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_196[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); + } + _res = NULL; +@@ -35877,9 +36026,9 @@ + return _res; + } + +-// _loop0_196: ',' (expression ['as' star_target]) ++// _loop0_198: ',' (expression ['as' star_target]) + static asdl_seq * +-_loop0_196_rule(Parser *p) ++_loop0_198_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -35905,13 +36054,13 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop0_196[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); ++ D(fprintf(stderr, "%*c> _loop0_198[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); + Token * _literal; + void *elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && +- (elem = _tmp_242_rule(p)) // expression ['as' star_target] ++ (elem = _tmp_245_rule(p)) // expression ['as' star_target] + ) + { + _res = elem; +@@ -35937,7 +36086,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop0_196[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop0_198[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expression ['as' star_target])")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); +@@ -35954,9 +36103,9 @@ + return _seq; + } + +-// _gather_195: (expression ['as' star_target]) _loop0_196 ++// _gather_197: (expression ['as' star_target]) _loop0_198 + static asdl_seq * +-_gather_195_rule(Parser *p) ++_gather_197_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -35968,27 +36117,27 @@ + } + asdl_seq * _res = NULL; + int _mark = p->mark; +- { // (expression ['as' star_target]) _loop0_196 ++ { // (expression ['as' star_target]) _loop0_198 + if (p->error_indicator) { + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _gather_195[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_196")); ++ D(fprintf(stderr, "%*c> _gather_197[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_198")); + void *elem; + asdl_seq * seq; + if ( +- (elem = _tmp_242_rule(p)) // expression ['as' star_target] ++ (elem = _tmp_245_rule(p)) // expression ['as' star_target] + && +- (seq = _loop0_196_rule(p)) // _loop0_196 ++ (seq = _loop0_198_rule(p)) // _loop0_198 + ) + { +- D(fprintf(stderr, "%*c+ _gather_195[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_196")); ++ D(fprintf(stderr, "%*c+ _gather_197[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_198")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _gather_195[%d-%d]: %s failed!\n", p->level, ' ', +- p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_196")); ++ D(fprintf(stderr, "%*c%s _gather_197[%d-%d]: %s failed!\n", p->level, ' ', ++ p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_198")); + } + _res = NULL; + done: +@@ -35996,9 +36145,9 @@ + return _res; + } + +-// _loop0_198: ',' (expressions ['as' star_target]) ++// _loop0_200: ',' (expressions ['as' star_target]) + static asdl_seq * +-_loop0_198_rule(Parser *p) ++_loop0_200_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -36024,13 +36173,13 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop0_198[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); ++ D(fprintf(stderr, "%*c> _loop0_200[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); + Token * _literal; + void *elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && +- (elem = _tmp_243_rule(p)) // expressions ['as' star_target] ++ (elem = _tmp_246_rule(p)) // expressions ['as' star_target] + ) + { + _res = elem; +@@ -36056,7 +36205,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop0_198[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop0_200[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expressions ['as' star_target])")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); +@@ -36073,9 +36222,9 @@ + return _seq; + } + +-// _gather_197: (expressions ['as' star_target]) _loop0_198 ++// _gather_199: (expressions ['as' star_target]) _loop0_200 + static asdl_seq * +-_gather_197_rule(Parser *p) ++_gather_199_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -36087,27 +36236,27 @@ + } + asdl_seq * _res = NULL; + int _mark = p->mark; +- { // (expressions ['as' star_target]) _loop0_198 ++ { // (expressions ['as' star_target]) _loop0_200 + if (p->error_indicator) { + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _gather_197[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_198")); ++ D(fprintf(stderr, "%*c> _gather_199[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_200")); + void *elem; + asdl_seq * seq; + if ( +- (elem = _tmp_243_rule(p)) // expressions ['as' star_target] ++ (elem = _tmp_246_rule(p)) // expressions ['as' star_target] + && +- (seq = _loop0_198_rule(p)) // _loop0_198 ++ (seq = _loop0_200_rule(p)) // _loop0_200 + ) + { +- D(fprintf(stderr, "%*c+ _gather_197[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_198")); ++ D(fprintf(stderr, "%*c+ _gather_199[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_200")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _gather_197[%d-%d]: %s failed!\n", p->level, ' ', +- p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_198")); ++ D(fprintf(stderr, "%*c%s _gather_199[%d-%d]: %s failed!\n", p->level, ' ', ++ p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_200")); + } + _res = NULL; + done: +@@ -36115,9 +36264,9 @@ + return _res; + } + +-// _loop0_200: ',' (expression ['as' star_target]) ++// _loop0_202: ',' (expression ['as' star_target]) + static asdl_seq * +-_loop0_200_rule(Parser *p) ++_loop0_202_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -36143,13 +36292,13 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop0_200[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); ++ D(fprintf(stderr, "%*c> _loop0_202[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); + Token * _literal; + void *elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && +- (elem = _tmp_244_rule(p)) // expression ['as' star_target] ++ (elem = _tmp_247_rule(p)) // expression ['as' star_target] + ) + { + _res = elem; +@@ -36175,7 +36324,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop0_200[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop0_202[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expression ['as' star_target])")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); +@@ -36192,9 +36341,9 @@ + return _seq; + } + +-// _gather_199: (expression ['as' star_target]) _loop0_200 ++// _gather_201: (expression ['as' star_target]) _loop0_202 + static asdl_seq * +-_gather_199_rule(Parser *p) ++_gather_201_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -36206,27 +36355,27 @@ + } + asdl_seq * _res = NULL; + int _mark = p->mark; +- { // (expression ['as' star_target]) _loop0_200 ++ { // (expression ['as' star_target]) _loop0_202 + if (p->error_indicator) { + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _gather_199[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_200")); ++ D(fprintf(stderr, "%*c> _gather_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_202")); + void *elem; + asdl_seq * seq; + if ( +- (elem = _tmp_244_rule(p)) // expression ['as' star_target] ++ (elem = _tmp_247_rule(p)) // expression ['as' star_target] + && +- (seq = _loop0_200_rule(p)) // _loop0_200 ++ (seq = _loop0_202_rule(p)) // _loop0_202 + ) + { +- D(fprintf(stderr, "%*c+ _gather_199[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_200")); ++ D(fprintf(stderr, "%*c+ _gather_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_202")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _gather_199[%d-%d]: %s failed!\n", p->level, ' ', +- p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_200")); ++ D(fprintf(stderr, "%*c%s _gather_201[%d-%d]: %s failed!\n", p->level, ' ', ++ p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_202")); + } + _res = NULL; + done: +@@ -36234,9 +36383,9 @@ + return _res; + } + +-// _loop0_202: ',' (expressions ['as' star_target]) ++// _loop0_204: ',' (expressions ['as' star_target]) + static asdl_seq * +-_loop0_202_rule(Parser *p) ++_loop0_204_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -36262,13 +36411,13 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop0_202[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); ++ D(fprintf(stderr, "%*c> _loop0_204[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); + Token * _literal; + void *elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && +- (elem = _tmp_245_rule(p)) // expressions ['as' star_target] ++ (elem = _tmp_248_rule(p)) // expressions ['as' star_target] + ) + { + _res = elem; +@@ -36294,7 +36443,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop0_202[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop0_204[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expressions ['as' star_target])")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); +@@ -36311,9 +36460,9 @@ + return _seq; + } + +-// _gather_201: (expressions ['as' star_target]) _loop0_202 ++// _gather_203: (expressions ['as' star_target]) _loop0_204 + static asdl_seq * +-_gather_201_rule(Parser *p) ++_gather_203_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -36325,27 +36474,27 @@ + } + asdl_seq * _res = NULL; + int _mark = p->mark; +- { // (expressions ['as' star_target]) _loop0_202 ++ { // (expressions ['as' star_target]) _loop0_204 + if (p->error_indicator) { + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _gather_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_202")); ++ D(fprintf(stderr, "%*c> _gather_203[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_204")); + void *elem; + asdl_seq * seq; + if ( +- (elem = _tmp_245_rule(p)) // expressions ['as' star_target] ++ (elem = _tmp_248_rule(p)) // expressions ['as' star_target] + && +- (seq = _loop0_202_rule(p)) // _loop0_202 ++ (seq = _loop0_204_rule(p)) // _loop0_204 + ) + { +- D(fprintf(stderr, "%*c+ _gather_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_202")); ++ D(fprintf(stderr, "%*c+ _gather_203[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_204")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _gather_201[%d-%d]: %s failed!\n", p->level, ' ', +- p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_202")); ++ D(fprintf(stderr, "%*c%s _gather_203[%d-%d]: %s failed!\n", p->level, ' ', ++ p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_204")); + } + _res = NULL; + done: +@@ -36353,9 +36502,9 @@ + return _res; + } + +-// _tmp_203: 'except' | 'finally' ++// _tmp_205: 'except' | 'finally' + static void * +-_tmp_203_rule(Parser *p) ++_tmp_205_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -36372,18 +36521,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_203[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except'")); ++ D(fprintf(stderr, "%*c> _tmp_205[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 634)) // token='except' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_203[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except'")); ++ D(fprintf(stderr, "%*c+ _tmp_205[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except'")); + _res = _keyword; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_203[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_205[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'except'")); + } + { // 'finally' +@@ -36391,18 +36540,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_203[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'finally'")); ++ D(fprintf(stderr, "%*c> _tmp_205[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'finally'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 630)) // token='finally' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_203[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'finally'")); ++ D(fprintf(stderr, "%*c+ _tmp_205[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'finally'")); + _res = _keyword; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_203[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_205[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'finally'")); + } + _res = NULL; +@@ -36411,9 +36560,9 @@ + return _res; + } + +-// _loop0_204: block ++// _loop0_206: block + static asdl_seq * +-_loop0_204_rule(Parser *p) ++_loop0_206_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -36439,7 +36588,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop0_204[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block")); ++ D(fprintf(stderr, "%*c> _loop0_206[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block")); + asdl_stmt_seq* block_var; + while ( + (block_var = block_rule(p)) // block +@@ -36462,7 +36611,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop0_204[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop0_206[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "block")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); +@@ -36479,9 +36628,9 @@ + return _seq; + } + +-// _loop1_205: except_block ++// _loop1_207: except_block + static asdl_seq * +-_loop1_205_rule(Parser *p) ++_loop1_207_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -36507,7 +36656,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop1_205[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_block")); ++ D(fprintf(stderr, "%*c> _loop1_207[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_block")); + excepthandler_ty except_block_var; + while ( + (except_block_var = except_block_rule(p)) // except_block +@@ -36530,7 +36679,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop1_205[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop1_207[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_block")); + } + if (_n == 0 || p->error_indicator) { +@@ -36552,9 +36701,9 @@ + return _seq; + } + +-// _tmp_206: 'as' NAME ++// _tmp_208: 'as' NAME + static void * +-_tmp_206_rule(Parser *p) ++_tmp_208_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -36571,7 +36720,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_206[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); ++ D(fprintf(stderr, "%*c> _tmp_208[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + Token * _keyword; + expr_ty name_var; + if ( +@@ -36580,12 +36729,12 @@ + (name_var = _PyPegen_name_token(p)) // NAME + ) + { +- D(fprintf(stderr, "%*c+ _tmp_206[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); ++ D(fprintf(stderr, "%*c+ _tmp_208[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + _res = _PyPegen_dummy_name(p, _keyword, name_var); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_206[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_208[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); + } + _res = NULL; +@@ -36594,9 +36743,9 @@ + return _res; + } + +-// _loop0_207: block ++// _loop0_209: block + static asdl_seq * +-_loop0_207_rule(Parser *p) ++_loop0_209_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -36622,7 +36771,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop0_207[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block")); ++ D(fprintf(stderr, "%*c> _loop0_209[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block")); + asdl_stmt_seq* block_var; + while ( + (block_var = block_rule(p)) // block +@@ -36645,7 +36794,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop0_207[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop0_209[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "block")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); +@@ -36662,9 +36811,9 @@ + return _seq; + } + +-// _loop1_208: except_star_block ++// _loop1_210: except_star_block + static asdl_seq * +-_loop1_208_rule(Parser *p) ++_loop1_210_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -36690,7 +36839,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop1_208[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_star_block")); ++ D(fprintf(stderr, "%*c> _loop1_210[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_star_block")); + excepthandler_ty except_star_block_var; + while ( + (except_star_block_var = except_star_block_rule(p)) // except_star_block +@@ -36713,7 +36862,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop1_208[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop1_210[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_star_block")); + } + if (_n == 0 || p->error_indicator) { +@@ -36735,9 +36884,9 @@ + return _seq; + } + +-// _tmp_209: expression ['as' NAME] ++// _tmp_211: expression ['as' NAME] + static void * +-_tmp_209_rule(Parser *p) ++_tmp_211_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -36754,22 +36903,22 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_209[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' NAME]")); ++ D(fprintf(stderr, "%*c> _tmp_211[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' NAME]")); + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + expr_ty expression_var; + if ( + (expression_var = expression_rule(p)) // expression + && +- (_opt_var = _tmp_246_rule(p), !p->error_indicator) // ['as' NAME] ++ (_opt_var = _tmp_249_rule(p), !p->error_indicator) // ['as' NAME] + ) + { +- D(fprintf(stderr, "%*c+ _tmp_209[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' NAME]")); ++ D(fprintf(stderr, "%*c+ _tmp_211[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' NAME]")); + _res = _PyPegen_dummy_name(p, expression_var, _opt_var); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_209[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_211[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ['as' NAME]")); + } + _res = NULL; +@@ -36778,9 +36927,9 @@ + return _res; + } + +-// _tmp_210: 'as' NAME ++// _tmp_212: 'as' NAME + static void * +-_tmp_210_rule(Parser *p) ++_tmp_212_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -36797,7 +36946,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_210[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); ++ D(fprintf(stderr, "%*c> _tmp_212[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + Token * _keyword; + expr_ty name_var; + if ( +@@ -36806,12 +36955,12 @@ + (name_var = _PyPegen_name_token(p)) // NAME + ) + { +- D(fprintf(stderr, "%*c+ _tmp_210[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); ++ D(fprintf(stderr, "%*c+ _tmp_212[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + _res = _PyPegen_dummy_name(p, _keyword, name_var); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_210[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_212[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); + } + _res = NULL; +@@ -36820,9 +36969,9 @@ + return _res; + } + +-// _tmp_211: 'as' NAME ++// _tmp_213: 'as' NAME + static void * +-_tmp_211_rule(Parser *p) ++_tmp_213_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -36839,7 +36988,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_211[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); ++ D(fprintf(stderr, "%*c> _tmp_213[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + Token * _keyword; + expr_ty name_var; + if ( +@@ -36848,12 +36997,12 @@ + (name_var = _PyPegen_name_token(p)) // NAME + ) + { +- D(fprintf(stderr, "%*c+ _tmp_211[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); ++ D(fprintf(stderr, "%*c+ _tmp_213[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + _res = _PyPegen_dummy_name(p, _keyword, name_var); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_211[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_213[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); + } + _res = NULL; +@@ -36862,9 +37011,9 @@ + return _res; + } + +-// _tmp_212: NEWLINE | ':' ++// _tmp_214: NEWLINE | ':' + static void * +-_tmp_212_rule(Parser *p) ++_tmp_214_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -36881,18 +37030,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_212[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE")); ++ D(fprintf(stderr, "%*c> _tmp_214[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE")); + Token * newline_var; + if ( + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_212[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE")); ++ D(fprintf(stderr, "%*c+ _tmp_214[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE")); + _res = newline_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_212[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_214[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE")); + } + { // ':' +@@ -36900,18 +37049,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_212[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); ++ D(fprintf(stderr, "%*c> _tmp_214[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_212[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); ++ D(fprintf(stderr, "%*c+ _tmp_214[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_212[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_214[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); + } + _res = NULL; +@@ -36920,9 +37069,9 @@ + return _res; + } + +-// _tmp_213: 'as' NAME ++// _tmp_215: 'as' NAME + static void * +-_tmp_213_rule(Parser *p) ++_tmp_215_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -36939,7 +37088,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_213[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); ++ D(fprintf(stderr, "%*c> _tmp_215[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + Token * _keyword; + expr_ty name_var; + if ( +@@ -36948,12 +37097,12 @@ + (name_var = _PyPegen_name_token(p)) // NAME + ) + { +- D(fprintf(stderr, "%*c+ _tmp_213[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); ++ D(fprintf(stderr, "%*c+ _tmp_215[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + _res = _PyPegen_dummy_name(p, _keyword, name_var); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_213[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_215[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); + } + _res = NULL; +@@ -36962,9 +37111,9 @@ + return _res; + } + +-// _tmp_214: 'as' NAME ++// _tmp_216: 'as' NAME + static void * +-_tmp_214_rule(Parser *p) ++_tmp_216_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -36981,7 +37130,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_214[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); ++ D(fprintf(stderr, "%*c> _tmp_216[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + Token * _keyword; + expr_ty name_var; + if ( +@@ -36990,12 +37139,12 @@ + (name_var = _PyPegen_name_token(p)) // NAME + ) + { +- D(fprintf(stderr, "%*c+ _tmp_214[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); ++ D(fprintf(stderr, "%*c+ _tmp_216[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + _res = _PyPegen_dummy_name(p, _keyword, name_var); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_214[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_216[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); + } + _res = NULL; +@@ -37004,9 +37153,9 @@ + return _res; + } + +-// _tmp_215: positional_patterns ',' ++// _tmp_217: positional_patterns ',' + static void * +-_tmp_215_rule(Parser *p) ++_tmp_217_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -37023,7 +37172,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_215[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); ++ D(fprintf(stderr, "%*c> _tmp_217[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); + Token * _literal; + asdl_pattern_seq* positional_patterns_var; + if ( +@@ -37032,12 +37181,12 @@ + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_215[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); ++ D(fprintf(stderr, "%*c+ _tmp_217[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); + _res = _PyPegen_dummy_name(p, positional_patterns_var, _literal); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_215[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_217[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "positional_patterns ','")); + } + _res = NULL; +@@ -37046,9 +37195,9 @@ + return _res; + } + +-// _tmp_216: '->' expression ++// _tmp_218: '->' expression + static void * +-_tmp_216_rule(Parser *p) ++_tmp_218_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -37065,7 +37214,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_216[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); ++ D(fprintf(stderr, "%*c> _tmp_218[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); + Token * _literal; + expr_ty expression_var; + if ( +@@ -37074,12 +37223,12 @@ + (expression_var = expression_rule(p)) // expression + ) + { +- D(fprintf(stderr, "%*c+ _tmp_216[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'->' expression")); ++ D(fprintf(stderr, "%*c+ _tmp_218[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'->' expression")); + _res = _PyPegen_dummy_name(p, _literal, expression_var); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_216[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_218[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'->' expression")); + } + _res = NULL; +@@ -37088,9 +37237,9 @@ + return _res; + } + +-// _tmp_217: '(' arguments? ')' ++// _tmp_219: '(' arguments? ')' + static void * +-_tmp_217_rule(Parser *p) ++_tmp_219_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -37107,7 +37256,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_217[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); ++ D(fprintf(stderr, "%*c> _tmp_219[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + Token * _literal; + Token * _literal_1; + void *_opt_var; +@@ -37120,12 +37269,12 @@ + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_217[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); ++ D(fprintf(stderr, "%*c+ _tmp_219[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + _res = _PyPegen_dummy_name(p, _literal, _opt_var, _literal_1); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_217[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_219[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' arguments? ')'")); + } + _res = NULL; +@@ -37134,9 +37283,9 @@ + return _res; + } + +-// _tmp_218: '(' arguments? ')' ++// _tmp_220: '(' arguments? ')' + static void * +-_tmp_218_rule(Parser *p) ++_tmp_220_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -37153,7 +37302,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_218[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); ++ D(fprintf(stderr, "%*c> _tmp_220[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + Token * _literal; + Token * _literal_1; + void *_opt_var; +@@ -37166,12 +37315,12 @@ + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_218[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); ++ D(fprintf(stderr, "%*c+ _tmp_220[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + _res = _PyPegen_dummy_name(p, _literal, _opt_var, _literal_1); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_218[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_220[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' arguments? ')'")); + } + _res = NULL; +@@ -37180,9 +37329,9 @@ + return _res; + } + +-// _loop0_220: ',' double_starred_kvpair ++// _loop0_222: ',' double_starred_kvpair + static asdl_seq * +-_loop0_220_rule(Parser *p) ++_loop0_222_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -37208,7 +37357,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop0_220[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' double_starred_kvpair")); ++ D(fprintf(stderr, "%*c> _loop0_222[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' double_starred_kvpair")); + Token * _literal; + KeyValuePair* elem; + while ( +@@ -37240,7 +37389,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop0_220[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop0_222[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' double_starred_kvpair")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); +@@ -37257,9 +37406,9 @@ + return _seq; + } + +-// _gather_219: double_starred_kvpair _loop0_220 ++// _gather_221: double_starred_kvpair _loop0_222 + static asdl_seq * +-_gather_219_rule(Parser *p) ++_gather_221_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -37271,27 +37420,27 @@ + } + asdl_seq * _res = NULL; + int _mark = p->mark; +- { // double_starred_kvpair _loop0_220 ++ { // double_starred_kvpair _loop0_222 + if (p->error_indicator) { + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _gather_219[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_220")); ++ D(fprintf(stderr, "%*c> _gather_221[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_222")); + KeyValuePair* elem; + asdl_seq * seq; + if ( + (elem = double_starred_kvpair_rule(p)) // double_starred_kvpair + && +- (seq = _loop0_220_rule(p)) // _loop0_220 ++ (seq = _loop0_222_rule(p)) // _loop0_222 + ) + { +- D(fprintf(stderr, "%*c+ _gather_219[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_220")); ++ D(fprintf(stderr, "%*c+ _gather_221[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_222")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _gather_219[%d-%d]: %s failed!\n", p->level, ' ', +- p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "double_starred_kvpair _loop0_220")); ++ D(fprintf(stderr, "%*c%s _gather_221[%d-%d]: %s failed!\n", p->level, ' ', ++ p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "double_starred_kvpair _loop0_222")); + } + _res = NULL; + done: +@@ -37299,9 +37448,9 @@ + return _res; + } + +-// _tmp_221: '}' | ',' ++// _tmp_223: '}' | ',' + static void * +-_tmp_221_rule(Parser *p) ++_tmp_223_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -37318,18 +37467,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_221[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); ++ D(fprintf(stderr, "%*c> _tmp_223[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 26)) // token='}' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_221[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); ++ D(fprintf(stderr, "%*c+ _tmp_223[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_221[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_223[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); + } + { // ',' +@@ -37337,18 +37486,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_221[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); ++ D(fprintf(stderr, "%*c> _tmp_223[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_221[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); ++ D(fprintf(stderr, "%*c+ _tmp_223[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_221[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_223[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + } + _res = NULL; +@@ -37357,9 +37506,9 @@ + return _res; + } + +-// _tmp_222: '}' | ',' ++// _tmp_224: '}' | ',' + static void * +-_tmp_222_rule(Parser *p) ++_tmp_224_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -37376,18 +37525,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_222[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); ++ D(fprintf(stderr, "%*c> _tmp_224[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 26)) // token='}' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_222[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); ++ D(fprintf(stderr, "%*c+ _tmp_224[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_222[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_224[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); + } + { // ',' +@@ -37395,18 +37544,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_222[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); ++ D(fprintf(stderr, "%*c> _tmp_224[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_222[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); ++ D(fprintf(stderr, "%*c+ _tmp_224[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_222[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_224[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + } + _res = NULL; +@@ -37415,9 +37564,9 @@ + return _res; + } + +-// _tmp_223: star_targets '=' ++// _tmp_225: star_targets '=' + static void * +-_tmp_223_rule(Parser *p) ++_tmp_225_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -37434,7 +37583,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_223[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); ++ D(fprintf(stderr, "%*c> _tmp_225[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + Token * _literal; + expr_ty z; + if ( +@@ -37443,7 +37592,7 @@ + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_223[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); ++ D(fprintf(stderr, "%*c+ _tmp_225[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + _res = z; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; +@@ -37453,7 +37602,7 @@ + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_223[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_225[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); + } + _res = NULL; +@@ -37462,9 +37611,9 @@ + return _res; + } + +-// _tmp_224: '.' | '...' ++// _tmp_226: '.' | '...' + static void * +-_tmp_224_rule(Parser *p) ++_tmp_226_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -37481,18 +37630,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_224[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); ++ D(fprintf(stderr, "%*c> _tmp_226[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 23)) // token='.' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_224[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); ++ D(fprintf(stderr, "%*c+ _tmp_226[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_224[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_226[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); + } + { // '...' +@@ -37500,18 +37649,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_224[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); ++ D(fprintf(stderr, "%*c> _tmp_226[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 52)) // token='...' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_224[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); ++ D(fprintf(stderr, "%*c+ _tmp_226[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_224[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_226[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'...'")); + } + _res = NULL; +@@ -37520,9 +37669,9 @@ + return _res; + } + +-// _tmp_225: '.' | '...' ++// _tmp_227: '.' | '...' + static void * +-_tmp_225_rule(Parser *p) ++_tmp_227_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -37539,18 +37688,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_225[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); ++ D(fprintf(stderr, "%*c> _tmp_227[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 23)) // token='.' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_225[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); ++ D(fprintf(stderr, "%*c+ _tmp_227[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_225[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_227[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); + } + { // '...' +@@ -37558,18 +37707,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_225[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); ++ D(fprintf(stderr, "%*c> _tmp_227[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 52)) // token='...' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_225[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); ++ D(fprintf(stderr, "%*c+ _tmp_227[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_225[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_227[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'...'")); + } + _res = NULL; +@@ -37578,9 +37727,9 @@ + return _res; + } + +-// _tmp_226: '@' named_expression NEWLINE ++// _tmp_228: '@' named_expression NEWLINE + static void * +-_tmp_226_rule(Parser *p) ++_tmp_228_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -37597,7 +37746,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_226[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); ++ D(fprintf(stderr, "%*c> _tmp_228[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); + Token * _literal; + expr_ty f; + Token * newline_var; +@@ -37609,7 +37758,7 @@ + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_226[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); ++ D(fprintf(stderr, "%*c+ _tmp_228[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); + _res = f; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; +@@ -37619,7 +37768,7 @@ + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_226[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_228[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'@' named_expression NEWLINE")); + } + _res = NULL; +@@ -37628,9 +37777,9 @@ + return _res; + } + +-// _tmp_227: ',' expression ++// _tmp_229: ',' expression + static void * +-_tmp_227_rule(Parser *p) ++_tmp_229_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -37647,7 +37796,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_227[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); ++ D(fprintf(stderr, "%*c> _tmp_229[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); + Token * _literal; + expr_ty c; + if ( +@@ -37656,7 +37805,7 @@ + (c = expression_rule(p)) // expression + ) + { +- D(fprintf(stderr, "%*c+ _tmp_227[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression")); ++ D(fprintf(stderr, "%*c+ _tmp_229[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression")); + _res = c; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; +@@ -37666,7 +37815,7 @@ + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_227[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_229[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); + } + _res = NULL; +@@ -37675,9 +37824,9 @@ + return _res; + } + +-// _tmp_228: ',' star_expression ++// _tmp_230: ',' star_expression + static void * +-_tmp_228_rule(Parser *p) ++_tmp_230_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -37694,7 +37843,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_228[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_expression")); ++ D(fprintf(stderr, "%*c> _tmp_230[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_expression")); + Token * _literal; + expr_ty c; + if ( +@@ -37703,7 +37852,7 @@ + (c = star_expression_rule(p)) // star_expression + ) + { +- D(fprintf(stderr, "%*c+ _tmp_228[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_expression")); ++ D(fprintf(stderr, "%*c+ _tmp_230[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_expression")); + _res = c; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; +@@ -37713,7 +37862,7 @@ + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_228[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_230[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_expression")); + } + _res = NULL; +@@ -37722,9 +37871,9 @@ + return _res; + } + +-// _tmp_229: 'or' conjunction ++// _tmp_231: 'or' conjunction + static void * +-_tmp_229_rule(Parser *p) ++_tmp_231_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -37741,7 +37890,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_229[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); ++ D(fprintf(stderr, "%*c> _tmp_231[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); + Token * _keyword; + expr_ty c; + if ( +@@ -37750,7 +37899,7 @@ + (c = conjunction_rule(p)) // conjunction + ) + { +- D(fprintf(stderr, "%*c+ _tmp_229[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); ++ D(fprintf(stderr, "%*c+ _tmp_231[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); + _res = c; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; +@@ -37760,7 +37909,7 @@ + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_229[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_231[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'or' conjunction")); + } + _res = NULL; +@@ -37769,9 +37918,9 @@ + return _res; + } + +-// _tmp_230: 'and' inversion ++// _tmp_232: 'and' inversion + static void * +-_tmp_230_rule(Parser *p) ++_tmp_232_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -37788,7 +37937,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_230[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'and' inversion")); ++ D(fprintf(stderr, "%*c> _tmp_232[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'and' inversion")); + Token * _keyword; + expr_ty c; + if ( +@@ -37797,7 +37946,7 @@ + (c = inversion_rule(p)) // inversion + ) + { +- D(fprintf(stderr, "%*c+ _tmp_230[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'and' inversion")); ++ D(fprintf(stderr, "%*c+ _tmp_232[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'and' inversion")); + _res = c; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; +@@ -37807,7 +37956,7 @@ + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_230[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_232[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'and' inversion")); + } + _res = NULL; +@@ -37816,9 +37965,9 @@ + return _res; + } + +-// _tmp_231: slice | starred_expression ++// _tmp_233: slice | starred_expression + static void * +-_tmp_231_rule(Parser *p) ++_tmp_233_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -37835,18 +37984,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_231[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slice")); ++ D(fprintf(stderr, "%*c> _tmp_233[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slice")); + expr_ty slice_var; + if ( + (slice_var = slice_rule(p)) // slice + ) + { +- D(fprintf(stderr, "%*c+ _tmp_231[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slice")); ++ D(fprintf(stderr, "%*c+ _tmp_233[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slice")); + _res = slice_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_231[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_233[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slice")); + } + { // starred_expression +@@ -37854,18 +38003,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_231[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); ++ D(fprintf(stderr, "%*c> _tmp_233[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); + expr_ty starred_expression_var; + if ( + (starred_expression_var = starred_expression_rule(p)) // starred_expression + ) + { +- D(fprintf(stderr, "%*c+ _tmp_231[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); ++ D(fprintf(stderr, "%*c+ _tmp_233[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); + _res = starred_expression_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_231[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_233[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "starred_expression")); + } + _res = NULL; +@@ -37874,9 +38023,9 @@ + return _res; + } + +-// _tmp_232: 'if' disjunction ++// _tmp_234: 'if' disjunction + static void * +-_tmp_232_rule(Parser *p) ++_tmp_234_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -37893,7 +38042,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_232[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); ++ D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + Token * _keyword; + expr_ty z; + if ( +@@ -37902,7 +38051,7 @@ + (z = disjunction_rule(p)) // disjunction + ) + { +- D(fprintf(stderr, "%*c+ _tmp_232[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); ++ D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + _res = z; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; +@@ -37912,7 +38061,7 @@ + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_232[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_234[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' disjunction")); + } + _res = NULL; +@@ -37921,9 +38070,9 @@ + return _res; + } + +-// _tmp_233: 'if' disjunction ++// _tmp_235: 'if' disjunction + static void * +-_tmp_233_rule(Parser *p) ++_tmp_235_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -37940,7 +38089,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_233[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); ++ D(fprintf(stderr, "%*c> _tmp_235[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + Token * _keyword; + expr_ty z; + if ( +@@ -37949,7 +38098,7 @@ + (z = disjunction_rule(p)) // disjunction + ) + { +- D(fprintf(stderr, "%*c+ _tmp_233[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); ++ D(fprintf(stderr, "%*c+ _tmp_235[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + _res = z; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; +@@ -37959,7 +38108,7 @@ + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_233[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_235[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' disjunction")); + } + _res = NULL; +@@ -37968,9 +38117,9 @@ + return _res; + } + +-// _tmp_234: starred_expression | (assignment_expression | expression !':=') !'=' ++// _tmp_236: starred_expression | (assignment_expression | expression !':=') !'=' + static void * +-_tmp_234_rule(Parser *p) ++_tmp_236_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -37987,18 +38136,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); ++ D(fprintf(stderr, "%*c> _tmp_236[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); + expr_ty starred_expression_var; + if ( + (starred_expression_var = starred_expression_rule(p)) // starred_expression + ) + { +- D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); ++ D(fprintf(stderr, "%*c+ _tmp_236[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); + _res = starred_expression_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_234[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_236[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "starred_expression")); + } + { // (assignment_expression | expression !':=') !'=' +@@ -38006,20 +38155,20 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); +- void *_tmp_247_var; ++ D(fprintf(stderr, "%*c> _tmp_236[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); ++ void *_tmp_250_var; + if ( +- (_tmp_247_var = _tmp_247_rule(p)) // assignment_expression | expression !':=' ++ (_tmp_250_var = _tmp_250_rule(p)) // assignment_expression | expression !':=' + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 22) // token='=' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); +- _res = _tmp_247_var; ++ D(fprintf(stderr, "%*c+ _tmp_236[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); ++ _res = _tmp_250_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_234[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_236[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(assignment_expression | expression !':=') !'='")); + } + _res = NULL; +@@ -38028,9 +38177,9 @@ + return _res; + } + +-// _tmp_235: ',' star_target ++// _tmp_237: ',' star_target + static void * +-_tmp_235_rule(Parser *p) ++_tmp_237_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -38047,7 +38196,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_235[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); ++ D(fprintf(stderr, "%*c> _tmp_237[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); + Token * _literal; + expr_ty c; + if ( +@@ -38056,7 +38205,7 @@ + (c = star_target_rule(p)) // star_target + ) + { +- D(fprintf(stderr, "%*c+ _tmp_235[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); ++ D(fprintf(stderr, "%*c+ _tmp_237[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); + _res = c; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; +@@ -38066,7 +38215,7 @@ + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_235[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_237[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_target")); + } + _res = NULL; +@@ -38075,9 +38224,9 @@ + return _res; + } + +-// _tmp_236: ',' star_target ++// _tmp_238: ',' star_target + static void * +-_tmp_236_rule(Parser *p) ++_tmp_238_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -38094,7 +38243,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_236[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); ++ D(fprintf(stderr, "%*c> _tmp_238[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); + Token * _literal; + expr_ty c; + if ( +@@ -38103,7 +38252,7 @@ + (c = star_target_rule(p)) // star_target + ) + { +- D(fprintf(stderr, "%*c+ _tmp_236[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); ++ D(fprintf(stderr, "%*c+ _tmp_238[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); + _res = c; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; +@@ -38113,7 +38262,7 @@ + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_236[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_238[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_target")); + } + _res = NULL; +@@ -38122,10 +38271,10 @@ + return _res; + } + +-// _tmp_237: ++// _tmp_239: + // | ','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs + static void * +-_tmp_237_rule(Parser *p) ++_tmp_239_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -38142,24 +38291,24 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_237[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs")); +- asdl_seq * _gather_248_var; ++ D(fprintf(stderr, "%*c> _tmp_239[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs")); ++ asdl_seq * _gather_251_var; + Token * _literal; + asdl_seq* kwargs_var; + if ( +- (_gather_248_var = _gather_248_rule(p)) // ','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ++ (_gather_251_var = _gather_251_rule(p)) // ','.(starred_expression | (assignment_expression | expression !':=') !'=')+ + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (kwargs_var = kwargs_rule(p)) // kwargs + ) + { +- D(fprintf(stderr, "%*c+ _tmp_237[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs")); +- _res = _PyPegen_dummy_name(p, _gather_248_var, _literal, kwargs_var); ++ D(fprintf(stderr, "%*c+ _tmp_239[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs")); ++ _res = _PyPegen_dummy_name(p, _gather_251_var, _literal, kwargs_var); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_237[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_239[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs")); + } + _res = NULL; +@@ -38168,9 +38317,50 @@ + return _res; + } + +-// _tmp_238: star_targets '=' ++// _tmp_240: starred_expression !'=' + static void * +-_tmp_238_rule(Parser *p) ++_tmp_240_rule(Parser *p) ++{ ++ 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; ++ { // starred_expression !'=' ++ if (p->error_indicator) { ++ p->level--; ++ return NULL; ++ } ++ D(fprintf(stderr, "%*c> _tmp_240[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression !'='")); ++ expr_ty starred_expression_var; ++ if ( ++ (starred_expression_var = starred_expression_rule(p)) // starred_expression ++ && ++ _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 22) // token='=' ++ ) ++ { ++ D(fprintf(stderr, "%*c+ _tmp_240[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression !'='")); ++ _res = starred_expression_var; ++ goto done; ++ } ++ p->mark = _mark; ++ D(fprintf(stderr, "%*c%s _tmp_240[%d-%d]: %s failed!\n", p->level, ' ', ++ p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "starred_expression !'='")); ++ } ++ _res = NULL; ++ done: ++ p->level--; ++ return _res; ++} ++ ++// _tmp_241: star_targets '=' ++static void * ++_tmp_241_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -38187,7 +38377,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_238[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); ++ D(fprintf(stderr, "%*c> _tmp_241[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + Token * _literal; + expr_ty star_targets_var; + if ( +@@ -38196,12 +38386,12 @@ + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_238[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); ++ D(fprintf(stderr, "%*c+ _tmp_241[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + _res = _PyPegen_dummy_name(p, star_targets_var, _literal); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_238[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_241[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); } --#elif defined(WITH_NEXT_FRAMEWORK) -+#elif defined(WITH_NEXT_FRAMEWORK) && !defined(TARGET_OS_IPHONE) - static char modPath[MAXPATHLEN + 1]; - static int modPathInitialized = -1; - if (modPathInitialized < 0) { -@@ -961,4 +962,3 @@ - - return _PyStatus_OK(); + _res = NULL; +@@ -38210,9 +38400,9 @@ + return _res; } -- + +-// _tmp_239: star_targets '=' ++// _tmp_242: star_targets '=' + static void * +-_tmp_239_rule(Parser *p) ++_tmp_242_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -38229,7 +38419,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_239[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); ++ D(fprintf(stderr, "%*c> _tmp_242[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + Token * _literal; + expr_ty star_targets_var; + if ( +@@ -38238,12 +38428,12 @@ + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_239[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); ++ D(fprintf(stderr, "%*c+ _tmp_242[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + _res = _PyPegen_dummy_name(p, star_targets_var, _literal); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_239[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_242[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); + } + _res = NULL; +@@ -38252,9 +38442,9 @@ + return _res; + } + +-// _tmp_240: ')' | '**' ++// _tmp_243: ')' | '**' + static void * +-_tmp_240_rule(Parser *p) ++_tmp_243_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -38271,18 +38461,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_240[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); ++ D(fprintf(stderr, "%*c> _tmp_243[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 8)) // token=')' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_240[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); ++ D(fprintf(stderr, "%*c+ _tmp_243[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_240[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_243[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); + } + { // '**' +@@ -38290,18 +38480,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_240[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); ++ D(fprintf(stderr, "%*c> _tmp_243[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 35)) // token='**' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_240[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); ++ D(fprintf(stderr, "%*c+ _tmp_243[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_240[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_243[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); + } + _res = NULL; +@@ -38310,9 +38500,9 @@ + return _res; + } + +-// _tmp_241: ':' | '**' ++// _tmp_244: ':' | '**' + static void * +-_tmp_241_rule(Parser *p) ++_tmp_244_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -38329,18 +38519,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_241[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); ++ D(fprintf(stderr, "%*c> _tmp_244[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_241[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); ++ D(fprintf(stderr, "%*c+ _tmp_244[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_241[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_244[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); + } + { // '**' +@@ -38348,18 +38538,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_241[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); ++ D(fprintf(stderr, "%*c> _tmp_244[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 35)) // token='**' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_241[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); ++ D(fprintf(stderr, "%*c+ _tmp_244[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + _res = _literal; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_241[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_244[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); + } + _res = NULL; +@@ -38368,9 +38558,9 @@ + return _res; + } + +-// _tmp_242: expression ['as' star_target] ++// _tmp_245: expression ['as' star_target] + static void * +-_tmp_242_rule(Parser *p) ++_tmp_245_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -38387,22 +38577,22 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_242[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); ++ D(fprintf(stderr, "%*c> _tmp_245[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + expr_ty expression_var; + if ( + (expression_var = expression_rule(p)) // expression + && +- (_opt_var = _tmp_250_rule(p), !p->error_indicator) // ['as' star_target] ++ (_opt_var = _tmp_253_rule(p), !p->error_indicator) // ['as' star_target] + ) + { +- D(fprintf(stderr, "%*c+ _tmp_242[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); ++ D(fprintf(stderr, "%*c+ _tmp_245[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + _res = _PyPegen_dummy_name(p, expression_var, _opt_var); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_242[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_245[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ['as' star_target]")); + } + _res = NULL; +@@ -38411,9 +38601,9 @@ + return _res; + } + +-// _tmp_243: expressions ['as' star_target] ++// _tmp_246: expressions ['as' star_target] + static void * +-_tmp_243_rule(Parser *p) ++_tmp_246_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -38430,22 +38620,22 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_243[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); ++ D(fprintf(stderr, "%*c> _tmp_246[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + expr_ty expressions_var; + if ( + (expressions_var = expressions_rule(p)) // expressions + && +- (_opt_var = _tmp_251_rule(p), !p->error_indicator) // ['as' star_target] ++ (_opt_var = _tmp_254_rule(p), !p->error_indicator) // ['as' star_target] + ) + { +- D(fprintf(stderr, "%*c+ _tmp_243[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); ++ D(fprintf(stderr, "%*c+ _tmp_246[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + _res = _PyPegen_dummy_name(p, expressions_var, _opt_var); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_243[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_246[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expressions ['as' star_target]")); + } + _res = NULL; +@@ -38454,9 +38644,9 @@ + return _res; + } + +-// _tmp_244: expression ['as' star_target] ++// _tmp_247: expression ['as' star_target] + static void * +-_tmp_244_rule(Parser *p) ++_tmp_247_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -38473,22 +38663,22 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_244[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); ++ D(fprintf(stderr, "%*c> _tmp_247[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + expr_ty expression_var; + if ( + (expression_var = expression_rule(p)) // expression + && +- (_opt_var = _tmp_252_rule(p), !p->error_indicator) // ['as' star_target] ++ (_opt_var = _tmp_255_rule(p), !p->error_indicator) // ['as' star_target] + ) + { +- D(fprintf(stderr, "%*c+ _tmp_244[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); ++ D(fprintf(stderr, "%*c+ _tmp_247[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + _res = _PyPegen_dummy_name(p, expression_var, _opt_var); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_244[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_247[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ['as' star_target]")); + } + _res = NULL; +@@ -38497,9 +38687,9 @@ + return _res; + } + +-// _tmp_245: expressions ['as' star_target] ++// _tmp_248: expressions ['as' star_target] + static void * +-_tmp_245_rule(Parser *p) ++_tmp_248_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -38516,22 +38706,22 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_245[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); ++ D(fprintf(stderr, "%*c> _tmp_248[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + expr_ty expressions_var; + if ( + (expressions_var = expressions_rule(p)) // expressions + && +- (_opt_var = _tmp_253_rule(p), !p->error_indicator) // ['as' star_target] ++ (_opt_var = _tmp_256_rule(p), !p->error_indicator) // ['as' star_target] + ) + { +- D(fprintf(stderr, "%*c+ _tmp_245[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); ++ D(fprintf(stderr, "%*c+ _tmp_248[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + _res = _PyPegen_dummy_name(p, expressions_var, _opt_var); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_245[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_248[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expressions ['as' star_target]")); + } + _res = NULL; +@@ -38540,9 +38730,9 @@ + return _res; + } + +-// _tmp_246: 'as' NAME ++// _tmp_249: 'as' NAME + static void * +-_tmp_246_rule(Parser *p) ++_tmp_249_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -38559,7 +38749,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_246[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); ++ D(fprintf(stderr, "%*c> _tmp_249[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + Token * _keyword; + expr_ty name_var; + if ( +@@ -38568,12 +38758,12 @@ + (name_var = _PyPegen_name_token(p)) // NAME + ) + { +- D(fprintf(stderr, "%*c+ _tmp_246[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); ++ D(fprintf(stderr, "%*c+ _tmp_249[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + _res = _PyPegen_dummy_name(p, _keyword, name_var); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_246[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_249[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); + } + _res = NULL; +@@ -38582,9 +38772,9 @@ + return _res; + } + +-// _tmp_247: assignment_expression | expression !':=' ++// _tmp_250: assignment_expression | expression !':=' + static void * +-_tmp_247_rule(Parser *p) ++_tmp_250_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -38601,18 +38791,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_247[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression")); ++ D(fprintf(stderr, "%*c> _tmp_250[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression")); + expr_ty assignment_expression_var; + if ( + (assignment_expression_var = assignment_expression_rule(p)) // assignment_expression + ) + { +- D(fprintf(stderr, "%*c+ _tmp_247[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment_expression")); ++ D(fprintf(stderr, "%*c+ _tmp_250[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment_expression")); + _res = assignment_expression_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_247[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_250[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "assignment_expression")); + } + { // expression !':=' +@@ -38620,7 +38810,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_247[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); ++ D(fprintf(stderr, "%*c> _tmp_250[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); + expr_ty expression_var; + if ( + (expression_var = expression_rule(p)) // expression +@@ -38628,12 +38818,12 @@ + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 53) // token=':=' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_247[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='")); ++ D(fprintf(stderr, "%*c+ _tmp_250[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='")); + _res = expression_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_247[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_250[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression !':='")); + } + _res = NULL; +@@ -38642,9 +38832,9 @@ + return _res; + } + +-// _loop0_249: ',' (starred_expression | (assignment_expression | expression !':=') !'=') ++// _loop0_252: ',' (starred_expression | (assignment_expression | expression !':=') !'=') + static asdl_seq * +-_loop0_249_rule(Parser *p) ++_loop0_252_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -38670,13 +38860,13 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _loop0_249[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (starred_expression | (assignment_expression | expression !':=') !'=')")); ++ D(fprintf(stderr, "%*c> _loop0_252[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (starred_expression | (assignment_expression | expression !':=') !'=')")); + Token * _literal; + void *elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && +- (elem = _tmp_254_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' ++ (elem = _tmp_257_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' + ) + { + _res = elem; +@@ -38702,7 +38892,7 @@ + _mark = p->mark; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _loop0_249[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _loop0_252[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (starred_expression | (assignment_expression | expression !':=') !'=')")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); +@@ -38719,10 +38909,10 @@ + return _seq; + } + +-// _gather_248: +-// | (starred_expression | (assignment_expression | expression !':=') !'=') _loop0_249 ++// _gather_251: ++// | (starred_expression | (assignment_expression | expression !':=') !'=') _loop0_252 + static asdl_seq * +-_gather_248_rule(Parser *p) ++_gather_251_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -38734,27 +38924,27 @@ + } + asdl_seq * _res = NULL; + int _mark = p->mark; +- { // (starred_expression | (assignment_expression | expression !':=') !'=') _loop0_249 ++ { // (starred_expression | (assignment_expression | expression !':=') !'=') _loop0_252 + if (p->error_indicator) { + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _gather_248[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_249")); ++ D(fprintf(stderr, "%*c> _gather_251[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_252")); + void *elem; + asdl_seq * seq; + if ( +- (elem = _tmp_254_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' ++ (elem = _tmp_257_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' + && +- (seq = _loop0_249_rule(p)) // _loop0_249 ++ (seq = _loop0_252_rule(p)) // _loop0_252 + ) + { +- D(fprintf(stderr, "%*c+ _gather_248[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_249")); ++ D(fprintf(stderr, "%*c+ _gather_251[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_252")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _gather_248[%d-%d]: %s failed!\n", p->level, ' ', +- p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_249")); ++ D(fprintf(stderr, "%*c%s _gather_251[%d-%d]: %s failed!\n", p->level, ' ', ++ p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_252")); + } + _res = NULL; + done: +@@ -38762,9 +38952,9 @@ + return _res; + } + +-// _tmp_250: 'as' star_target ++// _tmp_253: 'as' star_target + static void * +-_tmp_250_rule(Parser *p) ++_tmp_253_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -38781,7 +38971,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_250[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); ++ D(fprintf(stderr, "%*c> _tmp_253[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + Token * _keyword; + expr_ty star_target_var; + if ( +@@ -38790,12 +38980,12 @@ + (star_target_var = star_target_rule(p)) // star_target + ) + { +- D(fprintf(stderr, "%*c+ _tmp_250[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); ++ D(fprintf(stderr, "%*c+ _tmp_253[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + _res = _PyPegen_dummy_name(p, _keyword, star_target_var); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_250[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_253[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); + } + _res = NULL; +@@ -38804,9 +38994,9 @@ + return _res; + } + +-// _tmp_251: 'as' star_target ++// _tmp_254: 'as' star_target + static void * +-_tmp_251_rule(Parser *p) ++_tmp_254_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -38823,7 +39013,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_251[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); ++ D(fprintf(stderr, "%*c> _tmp_254[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + Token * _keyword; + expr_ty star_target_var; + if ( +@@ -38832,12 +39022,12 @@ + (star_target_var = star_target_rule(p)) // star_target + ) + { +- D(fprintf(stderr, "%*c+ _tmp_251[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); ++ D(fprintf(stderr, "%*c+ _tmp_254[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + _res = _PyPegen_dummy_name(p, _keyword, star_target_var); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_251[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_254[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); + } + _res = NULL; +@@ -38846,9 +39036,9 @@ + return _res; + } + +-// _tmp_252: 'as' star_target ++// _tmp_255: 'as' star_target + static void * +-_tmp_252_rule(Parser *p) ++_tmp_255_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -38865,7 +39055,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_252[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); ++ D(fprintf(stderr, "%*c> _tmp_255[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + Token * _keyword; + expr_ty star_target_var; + if ( +@@ -38874,12 +39064,12 @@ + (star_target_var = star_target_rule(p)) // star_target + ) + { +- D(fprintf(stderr, "%*c+ _tmp_252[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); ++ D(fprintf(stderr, "%*c+ _tmp_255[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + _res = _PyPegen_dummy_name(p, _keyword, star_target_var); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_252[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_255[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); + } + _res = NULL; +@@ -38888,9 +39078,9 @@ + return _res; + } + +-// _tmp_253: 'as' star_target ++// _tmp_256: 'as' star_target + static void * +-_tmp_253_rule(Parser *p) ++_tmp_256_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -38907,7 +39097,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_253[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); ++ D(fprintf(stderr, "%*c> _tmp_256[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + Token * _keyword; + expr_ty star_target_var; + if ( +@@ -38916,12 +39106,12 @@ + (star_target_var = star_target_rule(p)) // star_target + ) + { +- D(fprintf(stderr, "%*c+ _tmp_253[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); ++ D(fprintf(stderr, "%*c+ _tmp_256[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + _res = _PyPegen_dummy_name(p, _keyword, star_target_var); + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_253[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_256[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); + } + _res = NULL; +@@ -38930,9 +39120,9 @@ + return _res; + } + +-// _tmp_254: starred_expression | (assignment_expression | expression !':=') !'=' ++// _tmp_257: starred_expression | (assignment_expression | expression !':=') !'=' + static void * +-_tmp_254_rule(Parser *p) ++_tmp_257_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -38949,18 +39139,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_254[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); ++ D(fprintf(stderr, "%*c> _tmp_257[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); + expr_ty starred_expression_var; + if ( + (starred_expression_var = starred_expression_rule(p)) // starred_expression + ) + { +- D(fprintf(stderr, "%*c+ _tmp_254[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); ++ D(fprintf(stderr, "%*c+ _tmp_257[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); + _res = starred_expression_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_254[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_257[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "starred_expression")); + } + { // (assignment_expression | expression !':=') !'=' +@@ -38968,20 +39158,20 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_254[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); +- void *_tmp_255_var; ++ D(fprintf(stderr, "%*c> _tmp_257[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); ++ void *_tmp_258_var; + if ( +- (_tmp_255_var = _tmp_255_rule(p)) // assignment_expression | expression !':=' ++ (_tmp_258_var = _tmp_258_rule(p)) // assignment_expression | expression !':=' + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 22) // token='=' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_254[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); +- _res = _tmp_255_var; ++ D(fprintf(stderr, "%*c+ _tmp_257[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); ++ _res = _tmp_258_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_254[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_257[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(assignment_expression | expression !':=') !'='")); + } + _res = NULL; +@@ -38990,9 +39180,9 @@ + return _res; + } + +-// _tmp_255: assignment_expression | expression !':=' ++// _tmp_258: assignment_expression | expression !':=' + static void * +-_tmp_255_rule(Parser *p) ++_tmp_258_rule(Parser *p) + { + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; +@@ -39009,18 +39199,18 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_255[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression")); ++ D(fprintf(stderr, "%*c> _tmp_258[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression")); + expr_ty assignment_expression_var; + if ( + (assignment_expression_var = assignment_expression_rule(p)) // assignment_expression + ) + { +- D(fprintf(stderr, "%*c+ _tmp_255[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment_expression")); ++ D(fprintf(stderr, "%*c+ _tmp_258[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment_expression")); + _res = assignment_expression_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_255[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_258[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "assignment_expression")); + } + { // expression !':=' +@@ -39028,7 +39218,7 @@ + p->level--; + return NULL; + } +- D(fprintf(stderr, "%*c> _tmp_255[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); ++ D(fprintf(stderr, "%*c> _tmp_258[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); + expr_ty expression_var; + if ( + (expression_var = expression_rule(p)) // expression +@@ -39036,12 +39226,12 @@ + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 53) // token=':=' + ) + { +- D(fprintf(stderr, "%*c+ _tmp_255[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='")); ++ D(fprintf(stderr, "%*c+ _tmp_258[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='")); + _res = expression_var; + goto done; + } + p->mark = _mark; +- D(fprintf(stderr, "%*c%s _tmp_255[%d-%d]: %s failed!\n", p->level, ' ', ++ D(fprintf(stderr, "%*c%s _tmp_258[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression !':='")); + } + _res = NULL; diff --git a/Python/marshal.c b/Python/marshal.c index 29f3bab60a5..7d32bb3661d 100644 --- a/Python/marshal.c @@ -4252,7 +13811,7 @@ index 29f3bab60a5..7d32bb3661d 100644 @@ -14,6 +14,10 @@ #include "pycore_hashtable.h" // _Py_hashtable_t #include "marshal.h" // Py_MARSHAL_VERSION - + +#ifdef __APPLE__ +# include "TargetConditionals.h" +#endif /* __APPLE__ */ @@ -4276,7 +13835,7 @@ index 29f3bab60a5..7d32bb3661d 100644 -#define MAX_MARSHAL_STACK_DEPTH 2000 +# define MAX_MARSHAL_STACK_DEPTH 2000 #endif - + #define TYPE_NULL '0' diff --git a/Python/stdlib_module_names.h b/Python/stdlib_module_names.h index 553585a76a3..2223b9a9a55 100644 @@ -4290,6 +13849,18 @@ index 553585a76a3..2223b9a9a55 100644 "_json", "_locale", "_lsprof", +diff --git a/README.rst b/README.rst +index ffa409a54c5..15ed568e96d 100644 +--- a/README.rst ++++ b/README.rst +@@ -1,5 +1,5 @@ +-This is Python version 3.11.9 +-============================= ++This is Python version 3.11.10 ++============================== + + .. image:: https://github.com/python/cpython/workflows/Tests/badge.svg + :alt: CPython build status on GitHub Actions diff --git a/config.sub b/config.sub index d74fb6deac9..1bb6a05dc11 100755 --- a/config.sub @@ -4299,13 +13870,13 @@ index d74fb6deac9..1bb6a05dc11 100755 # Configuration validation subroutine script. -# Copyright 1992-2021 Free Software Foundation, Inc. +# Copyright 1992-2024 Free Software Foundation, Inc. - + # shellcheck disable=SC2006,SC2268 # see below for rationale - + -timestamp='2021-08-14' +# Patched 2024-02-03 to include support for arm64_32 and iOS/tvOS/watchOS simulators +timestamp='2024-01-01' - + # 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 -# the Free Software Foundation; either version 3 of the License, or @@ -4316,17 +13887,17 @@ index d74fb6deac9..1bb6a05dc11 100755 @@ -76,13 +77,13 @@ version="\ GNU config.sub ($timestamp) - + -Copyright 1992-2021 Free Software Foundation, Inc. +Copyright 1992-2024 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." - + help=" -Try \`$me --help' for more information." +Try '$me --help' for more information." - + # Parse command line while test $# -gt 0 ; do @@ -130,7 +131,7 @@ @@ -4359,7 +13930,7 @@ index d74fb6deac9..1bb6a05dc11 100755 i*86 | x86_64) @@ -1020,6 +1022,11 @@ ;; - + # Here we normalize CPU types with a missing or matching vendor + armh-unknown | armh-alt) + cpu=armv7l @@ -4386,7 +13957,7 @@ index d74fb6deac9..1bb6a05dc11 100755 + arm64-* | aarch64le-* | arm64_32-*) cpu=aarch64 ;; - + @@ -1175,7 +1182,7 @@ case $cpu in 1750a | 580 \ @@ -4462,7 +14033,7 @@ index d74fb6deac9..1bb6a05dc11 100755 | wasm32 | wasm64 \ @@ -1280,7 +1267,7 @@ ;; - + *) - echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2 + echo "Invalid configuration '$1': machine '$cpu-$vendor' not recognized" 1>&2 @@ -4470,13 +14041,13 @@ index d74fb6deac9..1bb6a05dc11 100755 ;; esac @@ -1301,11 +1288,12 @@ - + # Decode manufacturer-specific aliases for certain operating systems. - + -if test x$basic_os != x +if test x"$basic_os" != x then - + -# First recognize some ad-hoc caes, or perhaps split kernel-os, or else just +# First recognize some ad-hoc cases, or perhaps split kernel-os, or else just # set os. @@ -4515,7 +14086,7 @@ index d74fb6deac9..1bb6a05dc11 100755 ;; @@ -1523,12 +1521,15 @@ # system, and we'll never get to this point. - + kernel= +obj= case $cpu-$vendor in @@ -4631,9 +14202,9 @@ index d74fb6deac9..1bb6a05dc11 100755 *-apple) os=macos @@ -1704,10 +1720,11 @@ - + fi - + -# Now, validate our (potentially fixed-up) OS. +# Now, validate our (potentially fixed-up) individual pieces (OS, OBJ). + @@ -4740,7 +14311,7 @@ index d74fb6deac9..1bb6a05dc11 100755 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 @@ -4817,14 +14388,14 @@ index d74fb6deac9..1bb6a05dc11 100755 @@ -1873,7 +1963,7 @@ ;; esac - + -echo "$cpu-$vendor-${kernel:+$kernel-}$os" +echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}" exit - + # Local variables: diff --git a/configure b/configure -index a1ad0ae2510..89b894f6551 100755 +index a1ad0ae2510..66fe8cc92c8 100755 --- a/configure +++ b/configure @@ -838,6 +838,8 @@ @@ -4896,7 +14467,7 @@ index a1ad0ae2510..89b894f6551 100755 @@ -1395,15 +1403,6 @@ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; - + - -runstatedir | --runstatedir | --runstatedi | --runstated \ - | --runstate | --runstat | --runsta | --runst | --runs \ - | --run | --ru | --r) @@ -4940,7 +14511,7 @@ index a1ad0ae2510..89b894f6551 100755 @@ -3566,6 +3568,166 @@ as_fn_error $? "pkg-config is required" "$LINENO" 5] fi - + +# Set name for machine-dependent library files + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking MACHDEP" >&5 @@ -5086,17 +14657,17 @@ index a1ad0ae2510..89b894f6551 100755 +fi +if test -z "$CXX"; then + case "$host" in -+ aarch64-apple-ios*-simulator) CXX=arm64-apple-ios-simulator-clang ;; -+ aarch64-apple-ios*) CXX=arm64-apple-ios-clang ;; -+ x86_64-apple-ios*-simulator) CXX=x86_64-apple-ios-simulator-clang ;; ++ aarch64-apple-ios*-simulator) CXX=arm64-apple-ios-simulator-clang++ ;; ++ aarch64-apple-ios*) CXX=arm64-apple-ios-clang++ ;; ++ x86_64-apple-ios*-simulator) CXX=x86_64-apple-ios-simulator-clang++ ;; + -+ aarch64-apple-tvos*-simulator) CXX=arm64-apple-tvos-simulator-clang ;; -+ aarch64-apple-tvos*) CXX=arm64-apple-tvos-clang ;; -+ x86_64-apple-tvos*-simulator) CXX=x86_64-apple-tvos-simulator-clang ;; ++ aarch64-apple-tvos*-simulator) CXX=arm64-apple-tvos-simulator-clang++ ;; ++ aarch64-apple-tvos*) CXX=arm64-apple-tvos-clang++ ;; ++ x86_64-apple-tvos*-simulator) CXX=x86_64-apple-tvos-simulator-clang++ ;; + -+ aarch64-apple-watchos*-simulator) CXX=arm64-apple-watchos-simulator-clang ;; -+ aarch64-apple-watchos*) CXX=arm64_32-apple-watchos-clang ;; -+ x86_64-apple-watchos*-simulator) CXX=x86_64-apple-watchos-simulator-clang ;; ++ aarch64-apple-watchos*-simulator) CXX=arm64-apple-watchos-simulator-clang++ ;; ++ aarch64-apple-watchos*) CXX=arm64_32-apple-watchos-clang++ ;; ++ x86_64-apple-watchos*-simulator) CXX=x86_64-apple-watchos-simulator-clang++ ;; + *) + esac +fi @@ -5177,7 +14748,7 @@ index a1ad0ae2510..89b894f6551 100755 - else - FRAMEWORKUNIXTOOLSPREFIX="${prefix}" - fi - + - case "${enableval}" in - /System*) - FRAMEWORKINSTALLAPPSPREFIX="/Applications" @@ -5202,7 +14773,7 @@ index a1ad0ae2510..89b894f6551 100755 + else + FRAMEWORKUNIXTOOLSPREFIX="${prefix}" + fi - + - /Library*) - FRAMEWORKINSTALLAPPSPREFIX="/Applications" - ;; @@ -5234,7 +14805,7 @@ index a1ad0ae2510..89b894f6551 100755 + FRAMEWORKUNIXTOOLSPREFIX="${MDIR}" + fi + ;; - + - */Library/Frameworks) - MDIR="`dirname "${enableval}"`" - MDIR="`dirname "${MDIR}"`" @@ -5254,7 +14825,7 @@ index a1ad0ae2510..89b894f6551 100755 + FRAMEWORKINSTALLAPPSPREFIX="/Applications" + ;; + esac - + - *) - FRAMEWORKINSTALLAPPSPREFIX="/Applications" - ;; @@ -5323,7 +14894,7 @@ index a1ad0ae2510..89b894f6551 100755 + ;; + esac esac - + - prefix=$PYTHONFRAMEWORKINSTALLDIR/Versions/$VERSION - - # Add files for Mac specific code to the list of output @@ -5336,7 +14907,7 @@ index a1ad0ae2510..89b894f6551 100755 - - ac_config_files="$ac_config_files Mac/Resources/app/Info.plist" +else - + + case $ac_sys_system in + iOS) as_fn_error $? "iOS builds must use --enable-framework" "$LINENO" 5 ;; + tvOS) as_fn_error $? "tvOS builds must use --enable-framework" "$LINENO" 5 ;; @@ -5361,10 +14932,10 @@ index a1ad0ae2510..89b894f6551 100755 + fi + enable_framework= esac - + -else +fi - + - PYTHONFRAMEWORK= - PYTHONFRAMEWORKDIR=no-framework - PYTHONFRAMEWORKPREFIX= @@ -5380,20 +14951,20 @@ index a1ad0ae2510..89b894f6551 100755 - FRAMEWORKUNIXTOOLSPREFIX="${prefix}" - fi - enable_framework= - - + + -fi - - - + + + @@ -3802,78 +4048,51 @@ _ACEOF - - + + -# Set name for machine-dependent library files +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-app-store-compliance" >&5 +$as_echo_n "checking for --with-app-store-compliance... " >&6; } - + -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking MACHDEP" >&5 -$as_echo_n "checking MACHDEP... " >&6; } -if test -z "$MACHDEP" @@ -5470,13 +15041,13 @@ index a1ad0ae2510..89b894f6551 100755 +$as_echo "applying custom app store compliance patch" >&6; } + ;; esac - + - if test "$ac_sys_system" = "SunOS"; then - # For Solaris, there isn't an OS version specific macro defined - # in most compilers, so we define one here. - SUNOS_VERSION=`echo $ac_sys_release | sed -e 's!\.\(0-9\)$!.0\1!g' | tr -d '.'` +else - + -cat >>confdefs.h <<_ACEOF -#define Py_SUNOS_VERSION $SUNOS_VERSION -_ACEOF @@ -5494,15 +15065,15 @@ index a1ad0ae2510..89b894f6551 100755 +$as_echo "not patching for app store compliance" >&6; } + ;; + esac - + - fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: \"$MACHDEP\"" >&5 -$as_echo "\"$MACHDEP\"" >&6; } + + - - + + if test "$cross_compiling" = yes; then @@ -3881,27 +4100,93 @@ *-*-linux*) @@ -5602,7 +15173,7 @@ index a1ad0ae2510..89b894f6551 100755 - _PYTHON_HOST_PLATFORM="$MACHDEP${_host_cpu:+-$_host_cpu}" + _PYTHON_HOST_PLATFORM="$MACHDEP${_host_ident:+-$_host_ident}" fi - + # Some systems cannot stand _XOPEN_SOURCE being defined at all; they @@ -3968,6 +4253,13 @@ define_xopen_source=no;; @@ -5621,7 +15192,7 @@ index a1ad0ae2510..89b894f6551 100755 @@ -4030,6 +4322,12 @@ CONFIGURE_MACOSX_DEPLOYMENT_TARGET= EXPORT_MACOSX_DEPLOYMENT_TARGET='#' - + +# Record the value of IPHONEOS_DEPLOYMENT_TARGET / TVOS_DEPLOYMENT_TARGET / +# WATCHOS_DEPLOYMENT_TARGET enforced by the selected host triple. + @@ -5629,12 +15200,12 @@ index a1ad0ae2510..89b894f6551 100755 + + # checks for alternative programs - + # compiler flags are generated in two sets, BASECFLAGS and OPT. OPT is just @@ -4062,6 +4360,26 @@ ;; esac - + +case $ac_sys_system in #( + iOS) : + @@ -5717,16 +15288,16 @@ index a1ad0ae2510..89b894f6551 100755 @@ -6222,8 +6581,6 @@ ;; 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 @@ -6233,6 +6590,16 @@ MULTIARCH=$PLATFORM_TRIPLET fi - + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MULTIARCH" >&5 +$as_echo "$MULTIARCH" >&6; } + @@ -5737,7 +15308,7 @@ index a1ad0ae2510..89b894f6551 100755 + SOABI_PLATFORM=$PLATFORM_TRIPLET + ;; +esac - + if test x$MULTIARCH != x; then MULTIARCH_CPPFLAGS="-DMULTIARCH=\\\"$MULTIARCH\\\"" @@ -6276,6 +6643,18 @@ @@ -5762,7 +15333,7 @@ index a1ad0ae2510..89b894f6551 100755 @@ -6718,17 +7097,25 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking LDLIBRARY" >&5 $as_echo_n "checking LDLIBRARY... " >&6; } - + -# MacOSX framework builds need more magic. LDLIBRARY is the dynamic +# Apple framework builds need more magic. LDLIBRARY is the dynamic # library that we build, but we do not want to link against it (we @@ -5790,7 +15361,7 @@ index a1ad0ae2510..89b894f6551 100755 BLDLIBRARY='$(LDLIBRARY)' fi @@ -6741,64 +7128,70 @@ - + case $ac_sys_system in CYGWIN*) - LDLIBRARY='libpython$(LDVERSION).dll.a' @@ -5879,7 +15450,7 @@ index a1ad0ae2510..89b894f6551 100755 + LDLIBRARY='libpython$(LDVERSION).so' + RUNSHARED=LIBPATH=`pwd`${LIBPATH:+:${LIBPATH}} + ;; - + esac else # shared is disabled PY_ENABLE_SHARED=0 @@ -5893,7 +15464,7 @@ index a1ad0ae2510..89b894f6551 100755 + ;; esac fi - + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LDLIBRARY" >&5 +$as_echo "$LDLIBRARY" >&6; } + @@ -5901,12 +15472,12 @@ index a1ad0ae2510..89b894f6551 100755 - RUNSHARED= + RUNSHARED= fi - - + + @@ -6977,9 +7370,6 @@ PYTHON_FOR_BUILD="_PYTHON_HOSTRUNNER='$HOSTRUNNER' $PYTHON_FOR_BUILD" fi - + -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LDLIBRARY" >&5 -$as_echo "$LDLIBRARY" >&6; } - @@ -5915,7 +15486,7 @@ index a1ad0ae2510..89b894f6551 100755 Emscripten/browser*) : @@ -7221,11 +7611,16 @@ fi - + if test "$cross_compiling" = yes; then - case "$READELF" in - readelf|:) @@ -5933,8 +15504,8 @@ index a1ad0ae2510..89b894f6551 100755 + ;; + esac fi - - + + @@ -10951,6 +11346,11 @@ BLDSHARED="$LDSHARED" fi @@ -5954,7 +15525,7 @@ index a1ad0ae2510..89b894f6551 100755 - Darwin/*) + Darwin/*|iOS/*|tvOS/*|watchOS/*) LINKFORSHARED="$extra_undefs -framework CoreFoundation" - + # Issue #18075: the default maximum stack size (8MBytes) is too # small for the default recursion limit. Increase the stack size # to ensure that tests don't crash @@ -5972,13 +15543,13 @@ index a1ad0ae2510..89b894f6551 100755 + # Undefined behavior sanitizer requires an even deeper stack + stack_size="4000000" # 64 MB + fi - - + + cat >>confdefs.h <<_ACEOF @@ -11099,11 +11497,17 @@ _ACEOF - - + + - if test "$enable_framework" - then - LINKFORSHARED="$LINKFORSHARED "'$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' @@ -5999,8 +15570,8 @@ index a1ad0ae2510..89b894f6551 100755 ReliantUNIX*) LINKFORSHARED="-W1 -Blargedynsym";; @@ -12179,7 +12583,7 @@ fi - - + + -if test "$ac_sys_system" = "Darwin" +if test "$ac_sys_system" = "Darwin" -o "$ac_sys_system" = "iOS" -o "$ac_sys_system" = "tvOS" -o "$ac_sys_system" = "watchOS" then @@ -6013,8 +15584,8 @@ index a1ad0ae2510..89b894f6551 100755 - LIBFFI_INCLUDEDIR="" + LIBFFI_INCLUDEDIR="${LIBFFI_INCLUDEDIR}" fi - - + + + + # Check for use of the system libmpdec library @@ -6054,11 +15625,11 @@ index a1ad0ae2510..89b894f6551 100755 + sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile \ tmpnam tmpnam_r truncate ttyname umask uname unlinkat utimensat utimes vfork \ wait wait3 wait4 waitid waitpid wcscoll wcsftime wcsxfrm wmemcmp writev \ - + @@ -15262,8 +15668,46 @@ - + fi - + +# iOS/tvOS/watchOS define some system methods that can be linked (so they are +# found by configure), but either raise a compilation error (because the +# header definition prevents usage - autoconf doesn't use the headers), or @@ -6102,10 +15673,10 @@ index a1ad0ae2510..89b894f6551 100755 + #include " if test "x$ac_cv_have_decl_dirfd" = xyes; then : - + @@ -17817,8 +18261,9 @@ - - + + # check for openpty, login_tty, and forkpty - -for ac_func in openpty @@ -6118,23 +15689,23 @@ index a1ad0ae2510..89b894f6551 100755 @@ -17908,14 +18353,12 @@ LIBS="$LIBS -lbsd" fi - + - fi - + - fi done - + -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing login_tty" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing login_tty" >&5 $as_echo_n "checking for library containing login_tty... " >&6; } if ${ac_cv_search_login_tty+:} false; then : $as_echo_n "(cached) " >&6 @@ -17974,7 +18417,7 @@ - + fi - + -for ac_func in forkpty + for ac_func in forkpty do : @@ -6143,22 +15714,22 @@ index a1ad0ae2510..89b894f6551 100755 @@ -18064,13 +18507,12 @@ LIBS="$LIBS -lbsd" fi - + - fi - + - fi done - + +fi - + # check for long file support functions for ac_func in fseek64 fseeko fstatvfs ftell64 ftello statvfs @@ -18568,7 +19010,12 @@ done - - + + -for ac_func in clock_settime +# On iOS, tvOS and watchOS, clock_settime can be linked (so it is found by +# configure), but when used in an unprivileged process, it crashes rather than @@ -6170,9 +15741,9 @@ index a1ad0ae2510..89b894f6551 100755 ac_fn_c_check_func "$LINENO" "clock_settime" "ac_cv_func_clock_settime" if test "x$ac_cv_func_clock_settime" = xyes; then : @@ -18578,7 +19025,7 @@ - + else - + - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_settime in -lrt" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_settime in -lrt" >&5 $as_echo_n "checking for clock_settime in -lrt... " >&6; } @@ -6181,24 +15752,24 @@ index a1ad0ae2510..89b894f6551 100755 @@ -18616,7 +19063,7 @@ $as_echo "$ac_cv_lib_rt_clock_settime" >&6; } if test "x$ac_cv_lib_rt_clock_settime" = xyes; then : - + - $as_echo "#define HAVE_CLOCK_SETTIME 1" >>confdefs.h + $as_echo "#define HAVE_CLOCK_SETTIME 1" >>confdefs.h - - + + fi @@ -18625,6 +19072,7 @@ fi done - + +fi - + for ac_func in clock_nanosleep do : @@ -18838,7 +19286,9 @@ else if test "$cross_compiling" = yes; then : - + -if test "${enable_ipv6+set}" = set; then +if test "$ac_sys_system" = "Linux-android" -o "$ac_sys_system" = "iOS" -o "$ac_sys_system" = "tvOS" -o "$ac_sys_system" = "watchOS"; then + ac_cv_buggy_getaddrinfo="no" @@ -6214,20 +15785,20 @@ index a1ad0ae2510..89b894f6551 100755 +SOABI='cpython-'`echo $VERSION | tr -d .`${ABIFLAGS}${SOABI_PLATFORM:+-$SOABI_PLATFORM} { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SOABI" >&5 $as_echo "$SOABI" >&6; } - + @@ -20770,7 +21220,7 @@ if test "$Py_DEBUG" = 'true' -a "$with_trace_refs" != "yes"; then # Similar to SOABI but remove "d" flag from ABIFLAGS - + - ALT_SOABI='cpython-'`echo $VERSION | tr -d .``echo $ABIFLAGS | tr -d d`${PLATFORM_TRIPLET:+-$PLATFORM_TRIPLET} + ALT_SOABI='cpython-'`echo $VERSION | tr -d .``echo $ABIFLAGS | tr -d d`${SOABI_PLATFORM:+-$SOABI_PLATFORM} - + cat >>confdefs.h <<_ACEOF #define ALT_SOABI "${ALT_SOABI}" @@ -22152,24 +22602,28 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for device files" >&5 $as_echo "$as_me: checking for device files" >&6;} - + -if test "x$cross_compiling" = xyes; then - if test "${ac_cv_file__dev_ptmx+set}" != set; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for /dev/ptmx" >&5 @@ -6259,21 +15830,21 @@ index a1ad0ae2510..89b894f6551 100755 + fi fi -fi - + -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for /dev/ptmx" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for /dev/ptmx" >&5 $as_echo_n "checking for /dev/ptmx... " >&6; } if ${ac_cv_file__dev_ptmx+:} false; then : $as_echo_n "(cached) " >&6 @@ -22188,12 +22642,12 @@ - + fi - + -if test "x$ac_cv_file__dev_ptmx" = xyes; then + if test "x$ac_cv_file__dev_ptmx" = xyes; then - + $as_echo "#define HAVE_DEV_PTMX 1" >>confdefs.h - + -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for /dev/ptc" >&5 + fi @@ -6282,17 +15853,17 @@ index a1ad0ae2510..89b894f6551 100755 if ${ac_cv_file__dev_ptc+:} false; then : $as_echo_n "(cached) " >&6 @@ -22212,10 +22666,11 @@ - + fi - + -if test "x$ac_cv_file__dev_ptc" = xyes; then + if test "x$ac_cv_file__dev_ptc" = xyes; then - + $as_echo "#define HAVE_DEV_PTC 1" >>confdefs.h - + + fi fi - + if test $ac_sys_system = Darwin @@ -22701,6 +23156,8 @@ with_ensurepip=no ;; #( @@ -6329,8 +15900,8 @@ index a1ad0ae2510..89b894f6551 100755 + + ;; #( CYGWIN*) : - - + + @@ -26886,6 +27364,9 @@ "Mac/PythonLauncher/Makefile") CONFIG_FILES="$CONFIG_FILES Mac/PythonLauncher/Makefile" ;; "Mac/Resources/framework/Info.plist") CONFIG_FILES="$CONFIG_FILES Mac/Resources/framework/Info.plist" ;; @@ -6342,13 +15913,13 @@ index a1ad0ae2510..89b894f6551 100755 "Misc/python.pc") CONFIG_FILES="$CONFIG_FILES Misc/python.pc" ;; "Misc/python-embed.pc") CONFIG_FILES="$CONFIG_FILES Misc/python-embed.pc" ;; diff --git a/configure.ac b/configure.ac -index 7b4000fa9c3..3c6d293a0d3 100644 +index 7b4000fa9c3..08c9405a465 100644 --- a/configure.ac +++ b/configure.ac @@ -303,6 +303,161 @@ AC_MSG_ERROR([pkg-config is required])] fi - + +# Set name for machine-dependent library files +AC_ARG_VAR([MACHDEP], [name for machine-dependent library files]) +AC_MSG_CHECKING([MACHDEP]) @@ -6489,17 +16060,17 @@ index 7b4000fa9c3..3c6d293a0d3 100644 +fi +if test -z "$CXX"; then + case "$host" in -+ aarch64-apple-ios*-simulator) CXX=arm64-apple-ios-simulator-clang ;; -+ aarch64-apple-ios*) CXX=arm64-apple-ios-clang ;; -+ x86_64-apple-ios*-simulator) CXX=x86_64-apple-ios-simulator-clang ;; ++ aarch64-apple-ios*-simulator) CXX=arm64-apple-ios-simulator-clang++ ;; ++ aarch64-apple-ios*) CXX=arm64-apple-ios-clang++ ;; ++ x86_64-apple-ios*-simulator) CXX=x86_64-apple-ios-simulator-clang++ ;; + -+ aarch64-apple-tvos*-simulator) CXX=arm64-apple-tvos-simulator-clang ;; -+ aarch64-apple-tvos*) CXX=arm64-apple-tvos-clang ;; -+ x86_64-apple-tvos*-simulator) CXX=x86_64-apple-tvos-simulator-clang ;; ++ aarch64-apple-tvos*-simulator) CXX=arm64-apple-tvos-simulator-clang++ ;; ++ aarch64-apple-tvos*) CXX=arm64-apple-tvos-clang++ ;; ++ x86_64-apple-tvos*-simulator) CXX=x86_64-apple-tvos-simulator-clang++ ;; + -+ aarch64-apple-watchos*-simulator) CXX=arm64-apple-watchos-simulator-clang ;; -+ aarch64-apple-watchos*) CXX=arm64_32-apple-watchos-clang ;; -+ x86_64-apple-watchos*-simulator) CXX=x86_64-apple-watchos-simulator-clang ;; ++ aarch64-apple-watchos*-simulator) CXX=arm64-apple-watchos-simulator-clang++ ;; ++ aarch64-apple-watchos*) CXX=arm64_32-apple-watchos-clang++ ;; ++ x86_64-apple-watchos*-simulator) CXX=x86_64-apple-watchos-simulator-clang++ ;; + *) + esac +fi @@ -6580,7 +16151,7 @@ index 7b4000fa9c3..3c6d293a0d3 100644 - else - FRAMEWORKUNIXTOOLSPREFIX="${prefix}" - fi - + - case "${enableval}" in - /System*) - FRAMEWORKINSTALLAPPSPREFIX="/Applications" @@ -6605,7 +16176,7 @@ index 7b4000fa9c3..3c6d293a0d3 100644 + else + FRAMEWORKUNIXTOOLSPREFIX="${prefix}" + fi - + - /Library*) - FRAMEWORKINSTALLAPPSPREFIX="/Applications" - ;; @@ -6637,7 +16208,7 @@ index 7b4000fa9c3..3c6d293a0d3 100644 + FRAMEWORKUNIXTOOLSPREFIX="${MDIR}" + fi + ;; - + - */Library/Frameworks) - MDIR="`dirname "${enableval}"`" - MDIR="`dirname "${MDIR}"`" @@ -6657,7 +16228,7 @@ index 7b4000fa9c3..3c6d293a0d3 100644 + FRAMEWORKINSTALLAPPSPREFIX="/Applications" + ;; + esac - + - *) - FRAMEWORKINSTALLAPPSPREFIX="/Applications" - ;; @@ -6799,9 +16370,9 @@ index 7b4000fa9c3..3c6d293a0d3 100644 +AC_SUBST([FRAMEWORKUNIXTOOLSPREFIX]) +AC_SUBST([FRAMEWORKINSTALLAPPSPREFIX]) +AC_SUBST([INSTALLTARGETS]) - + AC_DEFINE_UNQUOTED(_PYTHONFRAMEWORK, "${PYTHONFRAMEWORK}", [framework name]) - + -# Set name for machine-dependent library files -AC_ARG_VAR([MACHDEP], [name for machine-dependent library files]) -AC_MSG_CHECKING(MACHDEP) @@ -6898,7 +16469,7 @@ index 7b4000fa9c3..3c6d293a0d3 100644 + esac +]) +AC_SUBST([APP_STORE_COMPLIANCE_PATCH]) - + - if test "$ac_sys_system" = "SunOS"; then - # For Solaris, there isn't an OS version specific macro defined - # in most compilers, so we define one here. @@ -7004,7 +16575,7 @@ index 7b4000fa9c3..3c6d293a0d3 100644 - _PYTHON_HOST_PLATFORM="$MACHDEP${_host_cpu:+-$_host_cpu}" + _PYTHON_HOST_PLATFORM="$MACHDEP${_host_ident:+-$_host_ident}" fi - + # Some systems cannot stand _XOPEN_SOURCE being defined at all; they @@ -683,6 +952,13 @@ define_xopen_source=no;; @@ -7023,7 +16594,7 @@ index 7b4000fa9c3..3c6d293a0d3 100644 @@ -739,6 +1015,12 @@ CONFIGURE_MACOSX_DEPLOYMENT_TARGET= EXPORT_MACOSX_DEPLOYMENT_TARGET='#' - + +# Record the value of IPHONEOS_DEPLOYMENT_TARGET / TVOS_DEPLOYMENT_TARGET / +# WATCHOS_DEPLOYMENT_TARGET enforced by the selected host triple. +AC_SUBST([IPHONEOS_DEPLOYMENT_TARGET]) @@ -7031,12 +16602,12 @@ index 7b4000fa9c3..3c6d293a0d3 100644 +AC_SUBST([WATCHOS_DEPLOYMENT_TARGET]) + # checks for alternative programs - + # compiler flags are generated in two sets, BASECFLAGS and OPT. OPT is just @@ -771,6 +1053,20 @@ ], ) - + +dnl Add the compiler flag for the iOS/tvOS/watchOS minimum supported OS version. +AS_CASE([$ac_sys_system], + [iOS], [ @@ -7100,7 +16671,7 @@ index 7b4000fa9c3..3c6d293a0d3 100644 @@ -1100,14 +1431,24 @@ fi rm -f conftest.c conftest.out - + +dnl On some platforms, using a true "triplet" for MULTIARCH would be redundant. +dnl For example, `arm64-apple-darwin` is redundant, because there isn't a +dnl non-Apple Darwin. Including the CPU architecture can also be potentially @@ -7120,7 +16691,7 @@ index 7b4000fa9c3..3c6d293a0d3 100644 ) 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 @@ -1116,7 +1457,18 @@ @@ -7140,7 +16711,7 @@ index 7b4000fa9c3..3c6d293a0d3 100644 + [iOS|tvOS|watchOS], [SOABI_PLATFORM=`echo "$PLATFORM_TRIPLET" | cut -d '-' -f2`], + [SOABI_PLATFORM=$PLATFORM_TRIPLET] +) - + if test x$MULTIARCH != x; then MULTIARCH_CPPFLAGS="-DMULTIARCH=\\\"$MULTIARCH\\\"" @@ -1147,6 +1499,12 @@ @@ -7155,11 +16726,11 @@ index 7b4000fa9c3..3c6d293a0d3 100644 + [arm64_32-apple-watchos*/clang], [PY_SUPPORT_TIER=3], dnl watchOS on ARM64 [PY_SUPPORT_TIER=0] ) - + @@ -1459,17 +1817,25 @@ - + AC_MSG_CHECKING(LDLIBRARY) - + -# MacOSX framework builds need more magic. LDLIBRARY is the dynamic +# Apple framework builds need more magic. LDLIBRARY is the dynamic # library that we build, but we do not want to link against it (we @@ -7276,7 +16847,7 @@ index 7b4000fa9c3..3c6d293a0d3 100644 + LDLIBRARY='libpython$(LDVERSION).so' + RUNSHARED=LIBPATH=`pwd`${LIBPATH:+:${LIBPATH}} + ;; - + esac else # shared is disabled PY_ENABLE_SHARED=0 @@ -7290,26 +16861,26 @@ index 7b4000fa9c3..3c6d293a0d3 100644 + ;; esac fi - + +AC_MSG_RESULT($LDLIBRARY) + if test "$cross_compiling" = yes; then - RUNSHARED= + RUNSHARED= fi - + AC_ARG_VAR([HOSTRUNNER], [Program to run CPython for the host platform]) @@ -1593,8 +1964,6 @@ PYTHON_FOR_BUILD="_PYTHON_HOSTRUNNER='$HOSTRUNNER' $PYTHON_FOR_BUILD" fi - + -AC_MSG_RESULT($LDLIBRARY) - # LIBRARY_DEPS, LINK_PYTHON_OBJS and LINK_PYTHON_DEPS variable AS_CASE([$ac_sys_system/$ac_sys_emscripten_target], [Emscripten/browser*], [LIBRARY_DEPS='$(PY3LIBRARY) $(WASM_STDLIB) python.html python.worker.js'], @@ -1635,11 +2004,16 @@ - + AC_CHECK_TOOLS([READELF], [readelf], [:]) if test "$cross_compiling" = yes; then - case "$READELF" in @@ -7329,7 +16900,7 @@ index 7b4000fa9c3..3c6d293a0d3 100644 + esac fi AC_SUBST(READELF) - + @@ -3179,6 +3553,11 @@ BLDSHARED="$LDSHARED" fi @@ -7349,7 +16920,7 @@ index 7b4000fa9c3..3c6d293a0d3 100644 - Darwin/*) + Darwin/*|iOS/*|tvOS/*|watchOS/*) LINKFORSHARED="$extra_undefs -framework CoreFoundation" - + # Issue #18075: the default maximum stack size (8MBytes) is too # small for the default recursion limit. Increase the stack size # to ensure that tests don't crash @@ -7365,18 +16936,18 @@ index 7b4000fa9c3..3c6d293a0d3 100644 + # Undefined behavior sanitizer requires an even deeper stack + stack_size="4000000" # 64 MB + fi - + - LINKFORSHARED="-Wl,-stack_size,$stack_size $LINKFORSHARED" + AC_DEFINE_UNQUOTED([THREAD_STACK_SIZE], + [0x$stack_size], + [Custom thread stack size depending on chosen sanitizer runtimes.]) - + - AC_DEFINE_UNQUOTED(THREAD_STACK_SIZE, - 0x$stack_size, - [Custom thread stack size depending on chosen sanitizer runtimes.]) + if test $ac_sys_system = "Darwin"; then + LINKFORSHARED="-Wl,-stack_size,$stack_size $LINKFORSHARED" - + - if test "$enable_framework" - then - LINKFORSHARED="$LINKFORSHARED "'$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' @@ -7395,7 +16966,7 @@ index 7b4000fa9c3..3c6d293a0d3 100644 @@ -3634,7 +4017,7 @@ AC_ARG_WITH(system_ffi, AS_HELP_STRING([--with-system-ffi], [build _ctypes module using an installed ffi library, see Doc/library/ctypes.rst (default is system-dependent)]),,,) - + -if test "$ac_sys_system" = "Darwin" +if test "$ac_sys_system" = "Darwin" -o "$ac_sys_system" = "iOS" -o "$ac_sys_system" = "tvOS" -o "$ac_sys_system" = "watchOS" then @@ -7411,7 +16982,7 @@ index 7b4000fa9c3..3c6d293a0d3 100644 AC_SUBST(LIBFFI_INCLUDEDIR) +AC_SUBST(LIBFFI_LIBDIR) +AC_SUBST(LIBFFI_LIB) - + # Check for use of the system libmpdec library AC_MSG_CHECKING(for --with-system-libmpdec) @@ -4594,27 +4979,27 @@ @@ -7452,7 +17023,7 @@ index 7b4000fa9c3..3c6d293a0d3 100644 @@ -4626,11 +5011,28 @@ AC_CHECK_FUNCS(lchmod) fi - + -AC_CHECK_DECL(dirfd, - AC_DEFINE(HAVE_DIRFD, 1, - Define if you have the 'dirfd' function or macro.), , @@ -7480,12 +17051,12 @@ index 7b4000fa9c3..3c6d293a0d3 100644 + [], + [@%:@include + @%:@include ]) - + dnl PY_CHECK_FUNC(FUNCTION, [INCLUDES], [AC_DEFINE-VAR]) AC_DEFUN([PY_CHECK_FUNC], @@ -4883,22 +5285,22 @@ ]) - + # check for openpty, login_tty, and forkpty - -AC_CHECK_FUNCS(openpty,, @@ -7519,13 +17090,13 @@ index 7b4000fa9c3..3c6d293a0d3 100644 + [AC_CHECK_LIB([bsd], [forkpty], + [AC_DEFINE([HAVE_FORKPTY]) LIBS="$LIBS -lbsd"])])]) +fi - + # check for long file support functions AC_CHECK_FUNCS(fseek64 fseeko fstatvfs ftell64 ftello statvfs) @@ -4972,11 +5374,17 @@ ]) ]) - + -AC_CHECK_FUNCS(clock_settime, [], [ - AC_CHECK_LIB(rt, clock_settime, [ - AC_DEFINE(HAVE_CLOCK_SETTIME, 1) @@ -7542,7 +17113,7 @@ index 7b4000fa9c3..3c6d293a0d3 100644 + ]) + ]) +fi - + AC_CHECK_FUNCS(clock_nanosleep, [], [ AC_CHECK_LIB(rt, clock_nanosleep, [ @@ -5122,7 +5530,9 @@ @@ -7572,7 +17143,7 @@ index 7b4000fa9c3..3c6d293a0d3 100644 +AC_MSG_CHECKING([SOABI]) +SOABI='cpython-'`echo $VERSION | tr -d .`${ABIFLAGS}${SOABI_PLATFORM:+-$SOABI_PLATFORM} +AC_MSG_RESULT([$SOABI]) - + # Release and debug (Py_DEBUG) ABI are compatible, but not Py_TRACE_REFS ABI if test "$Py_DEBUG" = 'true' -a "$with_trace_refs" != "yes"; then # Similar to SOABI but remove "d" flag from ABIFLAGS @@ -7584,10 +17155,10 @@ index 7b4000fa9c3..3c6d293a0d3 100644 + AC_DEFINE_UNQUOTED([ALT_SOABI], ["${ALT_SOABI}"], [Alternative SOABI used in debug build to load C extensions built in release mode]) fi - + @@ -6193,28 +6603,35 @@ AC_MSG_NOTICE([checking for device files]) - + dnl NOTE: Inform user how to proceed with files when cross compiling. -if test "x$cross_compiling" = xyes; then - if test "${ac_cv_file__dev_ptmx+set}" != set; then @@ -7618,7 +17189,7 @@ index 7b4000fa9c3..3c6d293a0d3 100644 + fi fi -fi - + -AC_CHECK_FILE(/dev/ptmx, [], []) -if test "x$ac_cv_file__dev_ptmx" = xyes; then - AC_DEFINE(HAVE_DEV_PTMX, 1, @@ -7639,7 +17210,7 @@ index 7b4000fa9c3..3c6d293a0d3 100644 + [Define to 1 if you have the /dev/ptc device file.]) + fi fi - + if test $ac_sys_system = Darwin @@ -6523,6 +6940,7 @@ AS_CASE([$ac_sys_system], @@ -8114,6 +17685,11 @@ index 7b4000fa9c3..3c6d293a0d3 100644 +#!/bin/sh +xcrun --sdk iphoneos${IOS_SDK_VERSION} clang -target arm64-apple-ios $@ --- /dev/null ++++ b/iOS/Resources/bin/arm64-apple-ios-clang++ +@@ -0,0 +1,2 @@ ++#!/bin/sh ++xcrun --sdk iphoneos${IOS_SDK_VERSION} clang++ -target arm64-apple-ios $@ +--- /dev/null +++ b/iOS/Resources/bin/arm64-apple-ios-cpp @@ -0,0 +1,2 @@ +#!/bin/sh @@ -8129,6 +17705,11 @@ index 7b4000fa9c3..3c6d293a0d3 100644 +#!/bin/sh +xcrun --sdk iphonesimulator${IOS_SDK_VERSION} clang -target arm64-apple-ios-simulator $@ --- /dev/null ++++ b/iOS/Resources/bin/arm64-apple-ios-simulator-clang++ +@@ -0,0 +1,2 @@ ++#!/bin/sh ++xcrun --sdk iphonesimulator${IOS_SDK_VERSION} clang++ -target arm64-apple-ios-simulator $@ +--- /dev/null +++ b/iOS/Resources/bin/arm64-apple-ios-simulator-cpp @@ -0,0 +1,2 @@ +#!/bin/sh @@ -8144,6 +17725,11 @@ index 7b4000fa9c3..3c6d293a0d3 100644 +#!/bin/sh +xcrun --sdk iphonesimulator${IOS_SDK_VERSION} clang -target x86_64-apple-ios-simulator $@ --- /dev/null ++++ b/iOS/Resources/bin/x86_64-apple-ios-simulator-clang++ +@@ -0,0 +1,2 @@ ++#!/bin/sh ++xcrun --sdk iphonesimulator${IOS_SDK_VERSION} clang++ -target x86_64-apple-ios-simulator $@ +--- /dev/null +++ b/iOS/Resources/bin/x86_64-apple-ios-simulator-cpp @@ -0,0 +1,2 @@ +#!/bin/sh @@ -9170,12 +18756,12 @@ index ad8fb81b218..266035c472c 100644 + dirs.append(path) + break return dirs - - + + @@ -1400,6 +1407,11 @@ extra_compile_args.append('-DMACOSX') include_dirs.append('_ctypes/darwin') - + + elif IOS or TVOS or WATCHOS: + sources.append('_ctypes/malloc_closure.c') + extra_compile_args.append('-DUSING_MALLOC_CLOSURE_DOT_C') @@ -9186,12 +18772,12 @@ index ad8fb81b218..266035c472c 100644 # of the assembler code is non-PIC (i.e. it has relocations @@ -1422,7 +1434,8 @@ self.addext(Extension('_ctypes_test', ['_ctypes/_ctypes_test.c'])) - + ffi_inc = sysconfig.get_config_var("LIBFFI_INCLUDEDIR") - ffi_lib = None + ffi_lib_dir = sysconfig.get_config_var("LIBFFI_LIBDIR") + ffi_lib = sysconfig.get_config_var("LIBFFI_LIB") - + ffi_inc_dirs = self.inc_dirs.copy() if MACOS: @@ -1451,6 +1464,7 @@ @@ -9200,16 +18786,16 @@ index ad8fb81b218..266035c472c 100644 ffi_lib = lib_name + self.use_system_libffi = True break - + if ffi_inc and ffi_lib: @@ -1464,7 +1478,8 @@ - + ext.include_dirs.append(ffi_inc) ext.libraries.append(ffi_lib) - self.use_system_libffi = True + if ffi_lib_dir: + ext.library_dirs.append(ffi_lib_dir) - + if sysconfig.get_config_var('HAVE_LIBDL'): # for dlopen, see bpo-32647 --- /dev/null @@ -9371,6 +18957,11 @@ index ad8fb81b218..266035c472c 100644 +#!/bin/bash +xcrun --sdk appletvos${TVOS_SDK_VERSION} clang -target arm64-apple-tvos $@ --- /dev/null ++++ b/tvOS/Resources/bin/arm64-apple-tvos-clang++ +@@ -0,0 +1,2 @@ ++#!/bin/bash ++xcrun --sdk appletvos${TVOS_SDK_VERSION} clang++ -target arm64-apple-tvos $@ +--- /dev/null +++ b/tvOS/Resources/bin/arm64-apple-tvos-cpp @@ -0,0 +1,2 @@ +#!/bin/bash @@ -9386,6 +18977,11 @@ index ad8fb81b218..266035c472c 100644 +#!/bin/bash +xcrun --sdk appletvsimulator${TVOS_SDK_VERSION} clang -target arm64-apple-tvos-simulator $@ --- /dev/null ++++ b/tvOS/Resources/bin/arm64-apple-tvos-simulator-clang++ +@@ -0,0 +1,2 @@ ++#!/bin/bash ++xcrun --sdk appletvsimulator${TVOS_SDK_VERSION} clang++ -target arm64-apple-tvos-simulator $@ +--- /dev/null +++ b/tvOS/Resources/bin/arm64-apple-tvos-simulator-cpp @@ -0,0 +1,2 @@ +#!/bin/bash @@ -9401,6 +18997,11 @@ index ad8fb81b218..266035c472c 100644 +#!/bin/bash +xcrun --sdk appletvsimulator${TVOS_SDK_VERSION} clang -target x86_64-apple-tvos-simulator $@ --- /dev/null ++++ b/tvOS/Resources/bin/x86_64-apple-tvos-simulator-clang++ +@@ -0,0 +1,2 @@ ++#!/bin/bash ++xcrun --sdk appletvsimulator${TVOS_SDK_VERSION} clang++ -target x86_64-apple-tvos-simulator $@ +--- /dev/null +++ b/tvOS/Resources/bin/x86_64-apple-tvos-simulator-cpp @@ -0,0 +1,2 @@ +#!/bin/bash @@ -9603,6 +19204,11 @@ index ad8fb81b218..266035c472c 100644 +#!/bin/bash +xcrun --sdk watchsimulator${WATCHOS_SDK_VERSION} clang -target arm64-apple-watchos-simulator $@ --- /dev/null ++++ b/watchOS/Resources/bin/arm64-apple-watchos-simulator-clang++ +@@ -0,0 +1,2 @@ ++#!/bin/bash ++xcrun --sdk watchsimulator${WATCHOS_SDK_VERSION} clang++ -target arm64-apple-watchos-simulator $@ +--- /dev/null +++ b/watchOS/Resources/bin/arm64-apple-watchos-simulator-cpp @@ -0,0 +1,2 @@ +#!/bin/bash @@ -9618,6 +19224,11 @@ index ad8fb81b218..266035c472c 100644 +#!/bin/bash +xcrun --sdk watchos${WATCHOS_SDK_VERSION} clang -target arm64_32-apple-watchos $@ --- /dev/null ++++ b/watchOS/Resources/bin/arm64_32-apple-watchos-clang++ +@@ -0,0 +1,2 @@ ++#!/bin/bash ++xcrun --sdk watchos${WATCHOS_SDK_VERSION} clang++ -target arm64_32-apple-watchos $@ +--- /dev/null +++ b/watchOS/Resources/bin/arm64_32-apple-watchos-cpp @@ -0,0 +1,2 @@ +#!/bin/bash @@ -9633,6 +19244,11 @@ index ad8fb81b218..266035c472c 100644 +#!/bin/bash +xcrun --sdk watchsimulator${WATCHOS_SDK_VERSION} clang -target x86_64-apple-watchos-simulator $@ --- /dev/null ++++ b/watchOS/Resources/bin/x86_64-apple-watchos-simulator-clang++ +@@ -0,0 +1,2 @@ ++#!/bin/bash ++xcrun --sdk watchsimulator${WATCHOS_SDK_VERSION} clang++ -target x86_64-apple-watchos-simulator $@ +--- /dev/null +++ b/watchOS/Resources/bin/x86_64-apple-watchos-simulator-cpp @@ -0,0 +1,2 @@ +#!/bin/bash diff --git a/patch/Python/release.macOS.exclude b/patch/Python/release.macOS.exclude index f45bf7f..3bc247c 100644 --- a/patch/Python/release.macOS.exclude +++ b/patch/Python/release.macOS.exclude @@ -2,7 +2,21 @@ # when building macOS Python-Apple-support tarballs from the official Framework # It is used by `tar -X` during the Makefile build. # +._Headers +._Python +._Resources +Resources/._Python.app Resources/Python.app +Versions/._Current +Versions/*/.__CodeSignature +Versions/*/._bin +Versions/*/._etc +Versions/*/._Frameworks +Versions/*/._Headers +Versions/*/._include +Versions/*/._lib +Versions/*/._Resources +Versions/*/._share Versions/*/bin Versions/*/etc Versions/*/Frameworks