diff -Nru python3.12-3.12.0~rc2/debian/changelog python3.12-3.12.0/debian/changelog --- python3.12-3.12.0~rc2/debian/changelog 2023-09-14 12:31:42.000000000 +0000 +++ python3.12-3.12.0/debian/changelog 2023-10-12 08:58:41.000000000 +0000 @@ -1,8 +1,14 @@ -python3.12 (3.12.0~rc2-1~23.04) lunar-proposed; urgency=medium +python3.12 (3.12.0-1~23.04) lunar-proposed; urgency=medium * SRU: LP: #1995503: Backport 3.12 to 23.04. - -- Matthias Klose Thu, 14 Sep 2023 14:31:42 +0200 + -- Matthias Klose Thu, 12 Oct 2023 10:58:41 +0200 + +python3.12 (3.12.0-1) unstable; urgency=medium + + * Python 3.12.0 release. + + -- Matthias Klose Wed, 04 Oct 2023 08:27:34 +0200 python3.12 (3.12.0~rc2-1) unstable; urgency=medium diff -Nru python3.12-3.12.0~rc2/debian/control python3.12-3.12.0/debian/control --- python3.12-3.12.0~rc2/debian/control 2023-09-14 04:34:20.000000000 +0000 +++ python3.12-3.12.0/debian/control 2023-10-12 08:58:41.000000000 +0000 @@ -2,10 +2,11 @@ Section: python Priority: optional Maintainer: Matthias Klose +Uploaders: Stefano Rivera Build-Depends: debhelper (>= 11), dpkg-dev (>= 1.17.11), quilt, autoconf, lsb-release, sharutils, - libreadline-dev | libeditreadline-dev, libncursesw5-dev (>= 5.3), + libreadline-dev | libeditreadline-dev, libncurses-dev, zlib1g-dev, libbz2-dev, liblzma-dev, libgdbm-dev, libdb-dev, tk-dev, blt-dev (>= 2.4z), libssl-dev, @@ -17,7 +18,7 @@ media-types | mime-support, netbase, bzip2, time, python3:any, python3.12:any , net-tools, xvfb , xauth , tzdata , systemtap-sdt-dev, - valgrind-if-available, + valgrind [!riscv64], Build-Depends-Indep: python3-sphinx, python3-docs-theme, texinfo Standards-Version: 4.6.2 Vcs-Browser: https://salsa.debian.org/cpython-team/python3 diff -Nru python3.12-3.12.0~rc2/debian/control.in python3.12-3.12.0/debian/control.in --- python3.12-3.12.0~rc2/debian/control.in 2023-09-14 04:34:20.000000000 +0000 +++ python3.12-3.12.0/debian/control.in 2023-10-12 08:58:41.000000000 +0000 @@ -2,10 +2,11 @@ Section: python Priority: optional Maintainer: Matthias Klose +Uploaders: Stefano Rivera Build-Depends: debhelper (>= 11), @bd_dpkgdev@ quilt, autoconf, lsb-release, sharutils, - libreadline-dev | libeditreadline-dev, libncursesw5-dev (>= 5.3), @bd_gcc@ + libreadline-dev | libeditreadline-dev, libncurses-dev, @bd_gcc@ zlib1g-dev, libbz2-dev, liblzma-dev, libgdbm-dev, @bd_dbm@, tk-dev, blt-dev (>= 2.4z), libssl-dev, @@ -17,7 +18,7 @@ media-types | mime-support, netbase, bzip2, time, python3@bd_qual@, @PVER@@bd_qual@ , net-tools, xvfb , xauth , tzdata , systemtap-sdt-dev, - valgrind-if-available, + valgrind [!riscv64], Build-Depends-Indep: python3-sphinx, python3-docs-theme, texinfo Standards-Version: 4.6.2 Vcs-Browser: https://salsa.debian.org/cpython-team/python3 diff -Nru python3.12-3.12.0~rc2/debian/idle-PVER.overrides.in python3.12-3.12.0/debian/idle-PVER.overrides.in --- python3.12-3.12.0~rc2/debian/idle-PVER.overrides.in 2018-04-28 12:37:08.000000000 +0000 +++ python3.12-3.12.0/debian/idle-PVER.overrides.in 2023-10-06 05:30:19.000000000 +0000 @@ -2,3 +2,6 @@ idle-@PVER@ binary: menu-icon-missing idle-@PVER@ binary: command-with-path-in-maintainer-script + +# no, it's not unusual +idle-@PVER@ binary: unusual-interpreter diff -Nru python3.12-3.12.0~rc2/debian/libPVER-dev.overrides.in python3.12-3.12.0/debian/libPVER-dev.overrides.in --- python3.12-3.12.0~rc2/debian/libPVER-dev.overrides.in 2023-03-01 10:52:56.000000000 +0000 +++ python3.12-3.12.0/debian/libPVER-dev.overrides.in 2023-10-06 05:34:45.000000000 +0000 @@ -4,3 +4,6 @@ # lintian needs an update for 3.8 lib@PVER@-dev binary: package-contains-python-header-in-incorrect-directory + +# no, it's not unusual +lib@PVER@-dev binary: unusual-interpreter diff -Nru python3.12-3.12.0~rc2/debian/libPVER-minimal.overrides.in python3.12-3.12.0/debian/libPVER-minimal.overrides.in --- python3.12-3.12.0~rc2/debian/libPVER-minimal.overrides.in 2023-03-01 10:52:56.000000000 +0000 +++ python3.12-3.12.0/debian/libPVER-minimal.overrides.in 2023-10-06 05:35:45.000000000 +0000 @@ -1,6 +1,9 @@ # intentional lib@PVER@-minimal binary: python3-script-but-no-python3-dep +# no, it's not unusual +lib@PVER@-minimal binary: unusual-interpreter + # lintian omission, multiarch string is encoded in the filename lib@PVER@-minimal binary: arch-dependent-file-not-in-arch-specific-directory diff -Nru python3.12-3.12.0~rc2/debian/libPVER-stdlib.overrides.in python3.12-3.12.0/debian/libPVER-stdlib.overrides.in --- python3.12-3.12.0~rc2/debian/libPVER-stdlib.overrides.in 2023-03-01 10:52:56.000000000 +0000 +++ python3.12-3.12.0/debian/libPVER-stdlib.overrides.in 2023-10-06 05:36:00.000000000 +0000 @@ -11,6 +11,9 @@ # the split is the reason for that lib@PVER@-stdlib binary: python3-script-but-no-python3-dep +# no, it's not unusual +lib@PVER@-stdlib binary: unusual-interpreter + # lintian omission, multiarch string is encoded in the filename lib@PVER@-stdlib binary: arch-dependent-file-not-in-arch-specific-directory diff -Nru python3.12-3.12.0~rc2/debian/libPVER-testsuite.overrides.in python3.12-3.12.0/debian/libPVER-testsuite.overrides.in --- python3.12-3.12.0~rc2/debian/libPVER-testsuite.overrides.in 2023-03-02 10:04:59.000000000 +0000 +++ python3.12-3.12.0/debian/libPVER-testsuite.overrides.in 2023-10-06 05:36:55.000000000 +0000 @@ -4,3 +4,5 @@ lib@PVER@-testsuite binary: command-with-path-in-maintainer-script lib@PVER@-testsuite binary: package-installs-python-egg lib@PVER@-testsuite binary: national-encoding +lib@PVER@-testsuite binary: unusual-interpreter +lib@PVER@-testsuite binary: executable-not-elf-or-script diff -Nru python3.12-3.12.0~rc2/debian/patches/test-no-random-order.diff python3.12-3.12.0/debian/patches/test-no-random-order.diff --- python3.12-3.12.0~rc2/debian/patches/test-no-random-order.diff 2023-02-08 21:58:13.000000000 +0000 +++ python3.12-3.12.0/debian/patches/test-no-random-order.diff 2023-10-06 05:39:39.000000000 +0000 @@ -1,5 +1,6 @@ Description: Don't run the test suite in random order. -Forwarded: not-needed. + Can be dropped in 3.13. +Bug-Upstream: https://github.com/python/cpython/issues/110164 --- a/Tools/scripts/run_tests.py +++ b/Tools/scripts/run_tests.py diff -Nru python3.12-3.12.0~rc2/debian/PVER-dbg.overrides.in python3.12-3.12.0/debian/PVER-dbg.overrides.in --- python3.12-3.12.0~rc2/debian/PVER-dbg.overrides.in 2023-03-02 17:59:35.000000000 +0000 +++ python3.12-3.12.0/debian/PVER-dbg.overrides.in 2023-10-06 05:30:19.000000000 +0000 @@ -8,3 +8,6 @@ # pyexpat.c contains expat error messages that lintian mis-attributes to embedding @PVER@-dbg binary: embedded-library + +# no, it's not unusual +@PVER@-dbg binary: unusual-interpreter diff -Nru python3.12-3.12.0~rc2/debian/PVER-doc.doc-base.PVER-dist.in python3.12-3.12.0/debian/PVER-doc.doc-base.PVER-dist.in --- python3.12-3.12.0~rc2/debian/PVER-doc.doc-base.PVER-dist.in 2013-11-23 12:09:48.000000000 +0000 +++ python3.12-3.12.0/debian/PVER-doc.doc-base.PVER-dist.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -Document: @PVER@-dist -Title: Distributing Python Modules (v@VER@) -Author: Greg Ward -Abstract: This document describes the Python Distribution Utilities - (``Distutils'') from the module developer's point-of-view, describing - how to use the Distutils to make Python modules and extensions easily - available to a wider audience with very little overhead for - build/release/install mechanics. -Section: Programming/Python - -Format: HTML -Index: /usr/share/doc/@PVER@/html/distutils/index.html -Files: /usr/share/doc/@PVER@/html/distutils/*.html diff -Nru python3.12-3.12.0~rc2/debian/PVER-doc.doc-base.PVER-inst.in python3.12-3.12.0/debian/PVER-doc.doc-base.PVER-inst.in --- python3.12-3.12.0~rc2/debian/PVER-doc.doc-base.PVER-inst.in 2013-11-23 12:09:48.000000000 +0000 +++ python3.12-3.12.0/debian/PVER-doc.doc-base.PVER-inst.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ -Document: @PVER@-inst -Title: Installing Python Modules (v@VER@) -Author: Greg Ward -Abstract: This document describes the Python Distribution Utilities - (``Distutils'') from the end-user's point-of-view, describing how to - extend the capabilities of a standard Python installation by building - and installing third-party Python modules and extensions. -Section: Programming/Python - -Format: HTML -Index: /usr/share/doc/@PVER@/html/install/index.html -Files: /usr/share/doc/@PVER@/html/install/*.html diff -Nru python3.12-3.12.0~rc2/debian/PVER-examples.overrides.in python3.12-3.12.0/debian/PVER-examples.overrides.in --- python3.12-3.12.0~rc2/debian/PVER-examples.overrides.in 2020-07-06 13:21:24.000000000 +0000 +++ python3.12-3.12.0/debian/PVER-examples.overrides.in 2023-10-06 06:47:43.000000000 +0000 @@ -1,3 +1,5 @@ # don't care about permissions of the example files @PVER@-examples binary: executable-not-elf-or-script @PVER@-examples binary: package-contains-vcs-control-file +@PVER@-examples binary: privacy-breach-generic +@PVER@-examples binary: unusual-interpreter diff -Nru python3.12-3.12.0~rc2/debian/PVER-minimal.overrides.in python3.12-3.12.0/debian/PVER-minimal.overrides.in --- python3.12-3.12.0~rc2/debian/PVER-minimal.overrides.in 2023-03-02 17:59:46.000000000 +0000 +++ python3.12-3.12.0/debian/PVER-minimal.overrides.in 2023-10-06 06:50:06.000000000 +0000 @@ -1,4 +1,5 @@ @PVER@-minimal binary: command-with-path-in-maintainer-script +@PVER@-minimal binary: unknown-field # pyexpat.c contains expat error messages that lintian mis-attributes to embedding @PVER@-minimal binary: embedded-library diff -Nru python3.12-3.12.0~rc2/debian/PVER-nopie.overrides.in python3.12-3.12.0/debian/PVER-nopie.overrides.in --- python3.12-3.12.0~rc2/debian/PVER-nopie.overrides.in 2023-03-02 17:59:53.000000000 +0000 +++ python3.12-3.12.0/debian/PVER-nopie.overrides.in 2023-10-06 06:50:29.000000000 +0000 @@ -3,3 +3,5 @@ # pyexpat.c contains expat error messages that lintian mis-attributes to embedding @PVER@-nopie binary: embedded-library + +@PVER@-nopie binary: unknown-field diff -Nru python3.12-3.12.0~rc2/debian/PVER.overrides.in python3.12-3.12.0/debian/PVER.overrides.in --- python3.12-3.12.0~rc2/debian/PVER.overrides.in 2023-03-01 10:52:56.000000000 +0000 +++ python3.12-3.12.0/debian/PVER.overrides.in 2023-10-06 06:51:31.000000000 +0000 @@ -3,6 +3,8 @@ @PVER@ binary: desktop-command-not-in-package @PVER@ binary: menu-command-not-in-package +@PVER@ binary: unusual-interpreter +@PVER@ binary: python3-script-but-no-python3-dep # no, not useless @PVER@ binary: manpage-has-useless-whatis-entry diff -Nru python3.12-3.12.0~rc2/debian/rules python3.12-3.12.0/debian/rules --- python3.12-3.12.0~rc2/debian/rules 2023-08-09 14:43:01.000000000 +0000 +++ python3.12-3.12.0/debian/rules 2023-10-06 10:22:59.000000000 +0000 @@ -29,6 +29,8 @@ PLAT = unknown endif +$(warning LIST: $(shell dh_listpackages)) + CHANGELOG_VARS := $(shell dpkg-parsechangelog | \ sed -n 's/ /_/g;/^[^_]/s/^\([^:]*\):_\(.*\)/\1=\2/p') PKGSOURCE := $(call vafilt,$(CHANGELOG_VARS),Source) @@ -100,7 +102,7 @@ endif VER=3.12 -SVER=3.12.0~rc1 +SVER=3.12.0 NVER=3.13 PVER=python$(VER) EXT_VER=$(subst .,,$(VER)) diff -Nru python3.12-3.12.0~rc2/debian/source/lintian-overrides python3.12-3.12.0/debian/source/lintian-overrides --- python3.12-3.12.0~rc2/debian/source/lintian-overrides 2019-02-06 11:29:54.000000000 +0000 +++ python3.12-3.12.0/debian/source/lintian-overrides 2023-10-06 08:04:19.000000000 +0000 @@ -3,3 +3,12 @@ # in the source only, and can be built with mingw64 source-contains-prebuilt-windows-binary + +# expected, diverted +binaries-have-file-conflict + +# these are generated, and one is a test case +# E: python3.12 source: source-is-missing [Lib/idlelib/help.html] +# E: python3.12 source: source-is-missing [Lib/test/test_difflib_expect.html] +# E: python3.12 source: source-is-missing [debian/FAQ.html] +source-is-missing diff -Nru python3.12-3.12.0~rc2/Doc/c-api/intro.rst python3.12-3.12.0/Doc/c-api/intro.rst --- python3.12-3.12.0~rc2/Doc/c-api/intro.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/c-api/intro.rst 2023-10-02 11:48:14.000000000 +0000 @@ -105,6 +105,30 @@ Others of a more general utility are defined here. This is not necessarily a complete listing. +.. c:macro:: PyMODINIT_FUNC + + Declare an extension module ``PyInit`` initialization function. The function + return type is :c:expr:`PyObject*`. The macro declares any special linkage + declarations required by the platform, and for C++ declares the function as + ``extern "C"``. + + The initialization function must be named :samp:`PyInit_{name}`, where + *name* is the name of the module, and should be the only non-\ ``static`` + item defined in the module file. Example:: + + static struct PyModuleDef spam_module = { + PyModuleDef_HEAD_INIT, + .m_name = "spam", + ... + }; + + PyMODINIT_FUNC + PyInit_spam(void) + { + return PyModule_Create(&spam_module); + } + + .. c:macro:: Py_ABS(x) Return the absolute value of ``x``. diff -Nru python3.12-3.12.0~rc2/Doc/conf.py python3.12-3.12.0/Doc/conf.py --- python3.12-3.12.0~rc2/Doc/conf.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/conf.py 2023-10-02 11:48:14.000000000 +0000 @@ -66,7 +66,7 @@ highlight_language = 'python3' # Minimum version of sphinx required -needs_sphinx = '3.2' +needs_sphinx = '4.2' # Ignore any .rst files in the includes/ directory; # they're embedded in pages but not rendered individually. diff -Nru python3.12-3.12.0~rc2/Doc/constraints.txt python3.12-3.12.0/Doc/constraints.txt --- python3.12-3.12.0~rc2/Doc/constraints.txt 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/constraints.txt 2023-10-02 11:48:14.000000000 +0000 @@ -10,8 +10,7 @@ imagesize<1.5 Jinja2<3.2 packaging<24 -# Pygments==2.15.0 breaks CI -Pygments<2.16,!=2.15.0 +Pygments>=2.16.1,<3 requests<3 snowballstemmer<3 sphinxcontrib-applehelp<1.1 diff -Nru python3.12-3.12.0~rc2/Doc/extending/windows.rst python3.12-3.12.0/Doc/extending/windows.rst --- python3.12-3.12.0~rc2/Doc/extending/windows.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/extending/windows.rst 2023-10-02 11:48:14.000000000 +0000 @@ -132,4 +132,4 @@ Developer Studio will throw in a lot of import libraries that you do not really need, adding about 100K to your executable. To get rid of them, use the Project Settings dialog, Link tab, to specify *ignore default libraries*. Add the -correct :file:`msvcrtxx.lib` to the list of libraries. +correct :file:`msvcrt{xx}.lib` to the list of libraries. diff -Nru python3.12-3.12.0~rc2/Doc/howto/logging-cookbook.rst python3.12-3.12.0/Doc/howto/logging-cookbook.rst --- python3.12-3.12.0~rc2/Doc/howto/logging-cookbook.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/howto/logging-cookbook.rst 2023-10-02 11:48:14.000000000 +0000 @@ -1728,7 +1728,7 @@ handler. So the only slightly unusual thing which might trip you up is that the parentheses go around the format string and the arguments, not just the format string. That's because the __ notation is just syntax sugar for a constructor -call to one of the XXXMessage classes. +call to one of the :samp:`{XXX}Message` classes. If you prefer, you can use a :class:`LoggerAdapter` to achieve a similar effect to the above, as in the following example:: @@ -2644,7 +2644,7 @@ handler. So the only slightly unusual thing which might trip you up is that the parentheses go around the format string and the arguments, not just the format string. That’s because the __ notation is just syntax sugar for a constructor -call to one of the ``XXXMessage`` classes shown above. +call to one of the :samp:`{XXX}Message` classes shown above. .. _filters-dictconfig: diff -Nru python3.12-3.12.0~rc2/Doc/howto/logging.rst python3.12-3.12.0/Doc/howto/logging.rst --- python3.12-3.12.0~rc2/Doc/howto/logging.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/howto/logging.rst 2023-10-02 11:48:14.000000000 +0000 @@ -979,7 +979,7 @@ #. :class:`NullHandler` instances do nothing with error messages. They are used by library developers who want to use logging, but want to avoid the 'No - handlers could be found for logger XXX' message which can be displayed if + handlers could be found for logger *XXX*' message which can be displayed if the library user has not configured logging. See :ref:`library-config` for more information. diff -Nru python3.12-3.12.0~rc2/Doc/howto/urllib2.rst python3.12-3.12.0/Doc/howto/urllib2.rst --- python3.12-3.12.0~rc2/Doc/howto/urllib2.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/howto/urllib2.rst 2023-10-02 11:48:14.000000000 +0000 @@ -194,11 +194,11 @@ Handling Exceptions =================== -*urlopen* raises :exc:`URLError` when it cannot handle a response (though as +*urlopen* raises :exc:`~urllib.error.URLError` when it cannot handle a response (though as usual with Python APIs, built-in exceptions such as :exc:`ValueError`, :exc:`TypeError` etc. may also be raised). -:exc:`HTTPError` is the subclass of :exc:`URLError` raised in the specific case of +:exc:`~urllib.error.HTTPError` is the subclass of :exc:`~urllib.error.URLError` raised in the specific case of HTTP URLs. The exception classes are exported from the :mod:`urllib.error` module. @@ -229,12 +229,12 @@ default handlers will handle some of these responses for you (for example, if the response is a "redirection" that requests the client fetch the document from a different URL, urllib will handle that for you). For those it can't handle, -urlopen will raise an :exc:`HTTPError`. Typical errors include '404' (page not +urlopen will raise an :exc:`~urllib.error.HTTPError`. Typical errors include '404' (page not found), '403' (request forbidden), and '401' (authentication required). See section 10 of :rfc:`2616` for a reference on all the HTTP error codes. -The :exc:`HTTPError` instance raised will have an integer 'code' attribute, which +The :exc:`~urllib.error.HTTPError` instance raised will have an integer 'code' attribute, which corresponds to the error sent by the server. Error Codes @@ -317,7 +317,7 @@ } When an error is raised the server responds by returning an HTTP error code -*and* an error page. You can use the :exc:`HTTPError` instance as a response on the +*and* an error page. You can use the :exc:`~urllib.error.HTTPError` instance as a response on the page returned. This means that as well as the code attribute, it also has read, geturl, and info, methods as returned by the ``urllib.response`` module:: @@ -338,7 +338,7 @@ Wrapping it Up -------------- -So if you want to be prepared for :exc:`HTTPError` *or* :exc:`URLError` there are two +So if you want to be prepared for :exc:`~urllib.error.HTTPError` *or* :exc:`~urllib.error.URLError` there are two basic approaches. I prefer the second approach. Number 1 @@ -365,7 +365,7 @@ .. note:: The ``except HTTPError`` *must* come first, otherwise ``except URLError`` - will *also* catch an :exc:`HTTPError`. + will *also* catch an :exc:`~urllib.error.HTTPError`. Number 2 ~~~~~~~~ @@ -391,7 +391,7 @@ info and geturl =============== -The response returned by urlopen (or the :exc:`HTTPError` instance) has two +The response returned by urlopen (or the :exc:`~urllib.error.HTTPError` instance) has two useful methods :meth:`info` and :meth:`geturl` and is defined in the module :mod:`urllib.response`.. diff -Nru python3.12-3.12.0~rc2/Doc/library/ast.rst python3.12-3.12.0/Doc/library/ast.rst --- python3.12-3.12.0~rc2/Doc/library/ast.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/ast.rst 2023-10-02 11:48:14.000000000 +0000 @@ -650,10 +650,10 @@ .. class:: NamedExpr(target, value) - A named expression. This AST node is produced by the assignment expressions - operator (also known as the walrus operator). As opposed to the :class:`Assign` - node in which the first argument can be multiple nodes, in this case both - ``target`` and ``value`` must be single nodes. + A named expression. This AST node is produced by the assignment expressions + operator (also known as the walrus operator). As opposed to the :class:`Assign` + node in which the first argument can be multiple nodes, in this case both + ``target`` and ``value`` must be single nodes. .. doctest:: @@ -663,6 +663,7 @@ target=Name(id='x', ctx=Store()), value=Constant(value=4))) + .. versionadded:: 3.8 Subscripting ~~~~~~~~~~~~ @@ -1036,6 +1037,7 @@ value=Name(id='int', ctx=Load()))], type_ignores=[]) + .. versionadded:: 3.12 Other statements which are only applicable inside functions or loops are described in other sections. @@ -1318,6 +1320,7 @@ finalbody=[])], type_ignores=[]) + .. versionadded:: 3.11 .. class:: ExceptHandler(type, name, body) @@ -1407,6 +1410,8 @@ that is being matched against the cases) and ``cases`` contains an iterable of :class:`match_case` nodes with the different cases. + .. versionadded:: 3.10 + .. class:: match_case(pattern, guard, body) A single case pattern in a ``match`` statement. ``pattern`` contains the @@ -1458,6 +1463,8 @@ value=Constant(value=Ellipsis))])])], type_ignores=[]) + .. versionadded:: 3.10 + .. class:: MatchValue(value) A match literal or value pattern that compares by equality. ``value`` is @@ -1485,6 +1492,8 @@ value=Constant(value=Ellipsis))])])], type_ignores=[]) + .. versionadded:: 3.10 + .. class:: MatchSingleton(value) A match literal pattern that compares by identity. ``value`` is the @@ -1510,6 +1519,8 @@ value=Constant(value=Ellipsis))])])], type_ignores=[]) + .. versionadded:: 3.10 + .. class:: MatchSequence(patterns) A match sequence pattern. ``patterns`` contains the patterns to be matched @@ -1541,6 +1552,8 @@ value=Constant(value=Ellipsis))])])], type_ignores=[]) + .. versionadded:: 3.10 + .. class:: MatchStar(name) Matches the rest of the sequence in a variable length match sequence pattern. @@ -1581,6 +1594,8 @@ value=Constant(value=Ellipsis))])])], type_ignores=[]) + .. versionadded:: 3.10 + .. class:: MatchMapping(keys, patterns, rest) A match mapping pattern. ``keys`` is a sequence of expression nodes. @@ -1627,6 +1642,8 @@ value=Constant(value=Ellipsis))])])], type_ignores=[]) + .. versionadded:: 3.10 + .. class:: MatchClass(cls, patterns, kwd_attrs, kwd_patterns) A match class pattern. ``cls`` is an expression giving the nominal class to @@ -1691,6 +1708,8 @@ value=Constant(value=Ellipsis))])])], type_ignores=[]) + .. versionadded:: 3.10 + .. class:: MatchAs(pattern, name) A match "as-pattern", capture pattern or wildcard pattern. ``pattern`` @@ -1732,6 +1751,8 @@ value=Constant(value=Ellipsis))])])], type_ignores=[]) + .. versionadded:: 3.10 + .. class:: MatchOr(patterns) A match "or-pattern". An or-pattern matches each of its subpatterns in turn @@ -1764,6 +1785,8 @@ value=Constant(value=Ellipsis))])])], type_ignores=[]) + .. versionadded:: 3.10 + .. _ast-type-params: Type parameters @@ -1795,6 +1818,8 @@ ctx=Load()))], type_ignores=[]) + .. versionadded:: 3.12 + .. class:: ParamSpec(name) A :class:`typing.ParamSpec`. ``name`` is the name of the parameter specification. @@ -1818,6 +1843,8 @@ ctx=Load()))], type_ignores=[]) + .. versionadded:: 3.12 + .. class:: TypeVarTuple(name) A :class:`typing.TypeVarTuple`. ``name`` is the name of the type variable tuple. @@ -1842,6 +1869,8 @@ ctx=Load()))], type_ignores=[]) + .. versionadded:: 3.12 + Function and class definitions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1861,6 +1890,9 @@ ``type_comment`` is an optional string with the type annotation as a comment. + .. versionchanged:: 3.12 + Added ``type_params``. + .. class:: Lambda(args, body) @@ -2059,6 +2091,9 @@ type_params=[])], type_ignores=[]) + .. versionchanged:: 3.12 + Added ``type_params``. + Async and await ^^^^^^^^^^^^^^^ @@ -2067,6 +2102,9 @@ An ``async def`` function definition. Has the same fields as :class:`FunctionDef`. + .. versionchanged:: 3.12 + Added ``type_params``. + .. class:: Await(value) diff -Nru python3.12-3.12.0~rc2/Doc/library/calendar.rst python3.12-3.12.0/Doc/library/calendar.rst --- python3.12-3.12.0~rc2/Doc/library/calendar.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/calendar.rst 2023-10-02 11:48:14.000000000 +0000 @@ -489,3 +489,146 @@ Module :mod:`time` Low-level time related functions. + + +.. _calendar-cli: + +Command-Line Usage +------------------ + +.. versionadded:: 2.5 + +The :mod:`calendar` module can be executed as a script from the command line +to interactively print a calendar. + +.. code-block:: shell + + python -m calendar [-h] [-L LOCALE] [-e ENCODING] [-t {text,html}] + [-w WIDTH] [-l LINES] [-s SPACING] [-m MONTHS] [-c CSS] + [year] [month] + + +For example, to print a calendar for the year 2000: + +.. code-block:: console + + $ python -m calendar 2000 + 2000 + + January February March + Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su + 1 2 1 2 3 4 5 6 1 2 3 4 5 + 3 4 5 6 7 8 9 7 8 9 10 11 12 13 6 7 8 9 10 11 12 + 10 11 12 13 14 15 16 14 15 16 17 18 19 20 13 14 15 16 17 18 19 + 17 18 19 20 21 22 23 21 22 23 24 25 26 27 20 21 22 23 24 25 26 + 24 25 26 27 28 29 30 28 29 27 28 29 30 31 + 31 + + April May June + Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su + 1 2 1 2 3 4 5 6 7 1 2 3 4 + 3 4 5 6 7 8 9 8 9 10 11 12 13 14 5 6 7 8 9 10 11 + 10 11 12 13 14 15 16 15 16 17 18 19 20 21 12 13 14 15 16 17 18 + 17 18 19 20 21 22 23 22 23 24 25 26 27 28 19 20 21 22 23 24 25 + 24 25 26 27 28 29 30 29 30 31 26 27 28 29 30 + + July August September + Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su + 1 2 1 2 3 4 5 6 1 2 3 + 3 4 5 6 7 8 9 7 8 9 10 11 12 13 4 5 6 7 8 9 10 + 10 11 12 13 14 15 16 14 15 16 17 18 19 20 11 12 13 14 15 16 17 + 17 18 19 20 21 22 23 21 22 23 24 25 26 27 18 19 20 21 22 23 24 + 24 25 26 27 28 29 30 28 29 30 31 25 26 27 28 29 30 + 31 + + October November December + Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su + 1 1 2 3 4 5 1 2 3 + 2 3 4 5 6 7 8 6 7 8 9 10 11 12 4 5 6 7 8 9 10 + 9 10 11 12 13 14 15 13 14 15 16 17 18 19 11 12 13 14 15 16 17 + 16 17 18 19 20 21 22 20 21 22 23 24 25 26 18 19 20 21 22 23 24 + 23 24 25 26 27 28 29 27 28 29 30 25 26 27 28 29 30 31 + 30 31 + + +The following options are accepted: + +.. program:: calendar + + +.. option:: --help, -h + + Show the help message and exit. + + +.. option:: --locale LOCALE, -L LOCALE + + The locale to use for month and weekday names. + Defaults to English. + + +.. option:: --encoding ENCODING, -e ENCODING + + The encoding to use for output. + :option:`--encoding` is required if :option:`--locale` is set. + + +.. option:: --type {text,html}, -t {text,html} + + Print the calendar to the terminal as text, + or as an HTML document. + + +.. option:: year + + The year to print the calendar for. + Must be a number between 1 and 9999. + Defaults to the current year. + + +.. option:: month + + The month of the specified :option:`year` to print the calendar for. + Must be a number between 1 and 12, + and may only be used in text mode. + Defaults to printing a calendar for the full year. + + +*Text-mode options:* + +.. option:: --width WIDTH, -w WIDTH + + The width of the date column in terminal columns. + The date is printed centred in the column. + Any value lower than 2 is ignored. + Defaults to 2. + + +.. option:: --lines LINES, -l LINES + + The number of lines for each week in terminal rows. + The date is printed top-aligned. + Any value lower than 1 is ignored. + Defaults to 1. + + +.. option:: --spacing SPACING, -s SPACING + + The space between months in columns. + Any value lower than 2 is ignored. + Defaults to 6. + + +.. option:: --months MONTHS, -m MONTHS + + The number of months printed per row. + Defaults to 3. + + +*HTML-mode options:* + +.. option:: --css CSS, -c CSS + + The path of a CSS stylesheet to use for the calendar. + This must either be relative to the generated HTML, + or an absolute HTTP or ``file:///`` URL. diff -Nru python3.12-3.12.0~rc2/Doc/library/codecs.rst python3.12-3.12.0/Doc/library/codecs.rst --- python3.12-3.12.0~rc2/Doc/library/codecs.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/codecs.rst 2023-10-02 11:48:14.000000000 +0000 @@ -345,9 +345,10 @@ +-------------------------+-----------------------------------------------+ | ``'backslashreplace'`` | Replace with backslashed escape sequences. | | | On encoding, use hexadecimal form of Unicode | -| | code point with formats ``\xhh`` ``\uxxxx`` | -| | ``\Uxxxxxxxx``. On decoding, use hexadecimal | -| | form of byte value with format ``\xhh``. | +| | code point with formats :samp:`\\x{hh}` | +| | :samp:`\\u{xxxx}` :samp:`\\U{xxxxxxxx}`. | +| | On decoding, use hexadecimal form of byte | +| | value with format :samp:`\\x{hh}`. | | | Implemented in | | | :func:`backslashreplace_errors`. | +-------------------------+-----------------------------------------------+ @@ -373,8 +374,9 @@ +=========================+===============================================+ | ``'xmlcharrefreplace'`` | Replace with XML/HTML numeric character | | | reference, which is a decimal form of Unicode | -| | code point with format ``&#num;`` Implemented | -| | in :func:`xmlcharrefreplace_errors`. | +| | code point with format :samp:`&#{num};`. | +| | Implemented in | +| | :func:`xmlcharrefreplace_errors`. | +-------------------------+-----------------------------------------------+ | ``'namereplace'`` | Replace with ``\N{...}`` escape sequences, | | | what appears in the braces is the Name | @@ -478,8 +480,9 @@ Malformed data is replaced by a backslashed escape sequence. On encoding, use the hexadecimal form of Unicode code point with formats - ``\xhh`` ``\uxxxx`` ``\Uxxxxxxxx``. On decoding, use the hexadecimal form of - byte value with format ``\xhh``. + :samp:`\\x{hh}` :samp:`\\u{xxxx}` :samp:`\\U{xxxxxxxx}`. + On decoding, use the hexadecimal form of + byte value with format :samp:`\\x{hh}`. .. versionchanged:: 3.5 Works with decoding and translating. @@ -492,7 +495,7 @@ The unencodable character is replaced by an appropriate XML/HTML numeric character reference, which is a decimal form of Unicode code point with - format ``&#num;`` . + format :samp:`&#{num};` . .. function:: namereplace_errors(exception) @@ -1346,9 +1349,10 @@ | | | supported. | +--------------------+---------+---------------------------+ | raw_unicode_escape | | Latin-1 encoding with | -| | | ``\uXXXX`` and | -| | | ``\UXXXXXXXX`` for other | -| | | code points. Existing | +| | | :samp:`\\u{XXXX}` and | +| | | :samp:`\\U{XXXXXXXX}` | +| | | for other code points. | +| | | Existing | | | | backslashes are not | | | | escaped in any way. | | | | It is used in the Python | diff -Nru python3.12-3.12.0~rc2/Doc/library/compileall.rst python3.12-3.12.0/Doc/library/compileall.rst --- python3.12-3.12.0~rc2/Doc/library/compileall.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/compileall.rst 2023-10-02 11:48:14.000000000 +0000 @@ -29,7 +29,7 @@ Positional arguments are files to compile or directories that contain source files, traversed recursively. If no argument is given, behave as if - the command line was ``-l ``. + the command line was :samp:`-l {}`. .. cmdoption:: -l diff -Nru python3.12-3.12.0~rc2/Doc/library/concurrent.futures.rst python3.12-3.12.0/Doc/library/concurrent.futures.rst --- python3.12-3.12.0~rc2/Doc/library/concurrent.futures.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/concurrent.futures.rst 2023-10-02 11:48:14.000000000 +0000 @@ -293,6 +293,14 @@ The *max_tasks_per_child* argument was added to allow users to control the lifetime of workers in the pool. + .. versionchanged:: 3.12 + On POSIX systems, if your application has multiple threads and the + :mod:`multiprocessing` context uses the ``"fork"`` start method: + The :func:`os.fork` function called internally to spawn workers may raise a + :exc:`DeprecationWarning`. Pass a *mp_context* configured to use a + different start method. See the :func:`os.fork` documentation for + further explanation. + .. _processpoolexecutor-example: ProcessPoolExecutor Example diff -Nru python3.12-3.12.0~rc2/Doc/library/configparser.rst python3.12-3.12.0/Doc/library/configparser.rst --- python3.12-3.12.0~rc2/Doc/library/configparser.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/configparser.rst 2023-10-02 11:48:14.000000000 +0000 @@ -935,8 +935,10 @@ When *default_section* is given, it specifies the name for the special section holding default values for other sections and interpolation purposes - (normally named ``"DEFAULT"``). This value can be retrieved and changed on - runtime using the ``default_section`` instance attribute. + (normally named ``"DEFAULT"``). This value can be retrieved and changed at + runtime using the ``default_section`` instance attribute. This won't + re-evaluate an already parsed config file, but will be used when writing + parsed settings to a new config file. Interpolation behaviour may be customized by providing a custom handler through the *interpolation* argument. ``None`` can be used to turn off diff -Nru python3.12-3.12.0~rc2/Doc/library/devmode.rst python3.12-3.12.0/Doc/library/devmode.rst --- python3.12-3.12.0~rc2/Doc/library/devmode.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/devmode.rst 2023-10-02 11:48:14.000000000 +0000 @@ -59,8 +59,9 @@ ``default``. * Call :func:`faulthandler.enable` at Python startup to install handlers for - the :const:`SIGSEGV`, :const:`SIGFPE`, :const:`SIGABRT`, :const:`SIGBUS` and - :const:`SIGILL` signals to dump the Python traceback on a crash. + the :const:`~signal.SIGSEGV`, :const:`~signal.SIGFPE`, + :const:`~signal.SIGABRT`, :const:`~signal.SIGBUS` and + :const:`~signal.SIGILL` signals to dump the Python traceback on a crash. It behaves as if the :option:`-X faulthandler <-X>` command line option is used or if the :envvar:`PYTHONFAULTHANDLER` environment variable is set to diff -Nru python3.12-3.12.0~rc2/Doc/library/difflib.rst python3.12-3.12.0/Doc/library/difflib.rst --- python3.12-3.12.0~rc2/Doc/library/difflib.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/difflib.rst 2023-10-02 11:48:14.000000000 +0000 @@ -570,8 +570,8 @@ The three methods that return the ratio of matching to total characters can give different results due to differing levels of approximation, although -:meth:`quick_ratio` and :meth:`real_quick_ratio` are always at least as large as -:meth:`ratio`: +:meth:`~SequenceMatcher.quick_ratio` and :meth:`~SequenceMatcher.real_quick_ratio` +are always at least as large as :meth:`~SequenceMatcher.ratio`: >>> s = SequenceMatcher(None, "abcd", "bcde") >>> s.ratio() @@ -593,15 +593,15 @@ ... "private Thread currentThread;", ... "private volatile Thread currentThread;") -:meth:`ratio` returns a float in [0, 1], measuring the similarity of the -sequences. As a rule of thumb, a :meth:`ratio` value over 0.6 means the +:meth:`~SequenceMatcher.ratio` returns a float in [0, 1], measuring the similarity of the +sequences. As a rule of thumb, a :meth:`~SequenceMatcher.ratio` value over 0.6 means the sequences are close matches: >>> print(round(s.ratio(), 3)) 0.866 If you're only interested in where the sequences match, -:meth:`get_matching_blocks` is handy: +:meth:`~SequenceMatcher.get_matching_blocks` is handy: >>> for block in s.get_matching_blocks(): ... print("a[%d] and b[%d] match for %d elements" % block) @@ -609,12 +609,12 @@ a[8] and b[17] match for 21 elements a[29] and b[38] match for 0 elements -Note that the last tuple returned by :meth:`get_matching_blocks` is always a -dummy, ``(len(a), len(b), 0)``, and this is the only case in which the last +Note that the last tuple returned by :meth:`~SequenceMatcher.get_matching_blocks` +is always a dummy, ``(len(a), len(b), 0)``, and this is the only case in which the last tuple element (number of elements matched) is ``0``. If you want to know how to change the first sequence into the second, use -:meth:`get_opcodes`: +:meth:`~SequenceMatcher.get_opcodes`: >>> for opcode in s.get_opcodes(): ... print("%6s a[%d:%d] b[%d:%d]" % opcode) @@ -689,7 +689,7 @@ This example compares two texts. First we set up the texts, sequences of individual single-line strings ending with newlines (such sequences can also be -obtained from the :meth:`~io.BaseIO.readlines` method of file-like objects): +obtained from the :meth:`~io.IOBase.readlines` method of file-like objects): >>> text1 = ''' 1. Beautiful is better than ugly. ... 2. Explicit is better than implicit. diff -Nru python3.12-3.12.0~rc2/Doc/library/dis.rst python3.12-3.12.0/Doc/library/dis.rst --- python3.12-3.12.0~rc2/Doc/library/dis.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/dis.rst 2023-10-02 11:48:14.000000000 +0000 @@ -528,7 +528,7 @@ key = STACK.pop() container = STACK.pop() - STACK.append(container[index]) + STACK.append(container[key]) .. opcode:: STORE_SUBSCR diff -Nru python3.12-3.12.0~rc2/Doc/library/ensurepip.rst python3.12-3.12.0/Doc/library/ensurepip.rst --- python3.12-3.12.0~rc2/Doc/library/ensurepip.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/ensurepip.rst 2023-10-02 11:48:14.000000000 +0000 @@ -61,7 +61,7 @@ active virtual environment). The installation location can be controlled through two additional command line options: -* ``--root ``: Installs ``pip`` relative to the given root directory +* :samp:`--root {dir}`: Installs ``pip`` relative to the given root directory rather than the root of the currently active virtual environment (if any) or the default root for the current Python installation. * ``--user``: Installs ``pip`` into the user site packages directory rather diff -Nru python3.12-3.12.0~rc2/Doc/library/exceptions.rst python3.12-3.12.0/Doc/library/exceptions.rst --- python3.12-3.12.0~rc2/Doc/library/exceptions.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/exceptions.rst 2023-10-02 11:48:14.000000000 +0000 @@ -220,10 +220,16 @@ load a module. Also raised when the "from list" in ``from ... import`` has a name that cannot be found. - The :attr:`name` and :attr:`path` attributes can be set using keyword-only - arguments to the constructor. When set they represent the name of the module - that was attempted to be imported and the path to any file which triggered - the exception, respectively. + The optional *name* and *path* keyword-only arguments + set the corresponding attributes: + + .. attribute:: name + + The name of the module that was attempted to be imported. + + .. attribute:: path + + The path to any file which triggered the exception. .. versionchanged:: 3.3 Added the :attr:`name` and :attr:`path` attributes. diff -Nru python3.12-3.12.0~rc2/Doc/library/functions.rst python3.12-3.12.0/Doc/library/functions.rst --- python3.12-3.12.0~rc2/Doc/library/functions.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/functions.rst 2023-10-02 11:48:14.000000000 +0000 @@ -1271,7 +1271,7 @@ * ``'xmlcharrefreplace'`` is only supported when writing to a file. Characters not supported by the encoding are replaced with the - appropriate XML character reference ``&#nnn;``. + appropriate XML character reference :samp:`&#{nnn};`. * ``'backslashreplace'`` replaces malformed data by Python's backslashed escape sequences. @@ -1631,7 +1631,7 @@ .. class:: slice(stop) - slice(start, stop, step=1) + slice(start, stop, step=None) Return a :term:`slice` object representing the set of indices specified by ``range(start, stop, step)``. The *start* and *step* arguments default to diff -Nru python3.12-3.12.0~rc2/Doc/library/gettext.rst python3.12-3.12.0/Doc/library/gettext.rst --- python3.12-3.12.0~rc2/Doc/library/gettext.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/gettext.rst 2023-10-02 11:48:14.000000000 +0000 @@ -58,7 +58,7 @@ Return the localized translation of *message*, based on the current global domain, language, and locale directory. This function is usually aliased as - :func:`_` in the local namespace (see examples below). + :func:`!_` in the local namespace (see examples below). .. function:: dgettext(domain, message) @@ -98,7 +98,7 @@ .. versionadded:: 3.8 -Note that GNU :program:`gettext` also defines a :func:`dcgettext` method, but +Note that GNU :program:`gettext` also defines a :func:`!dcgettext` method, but this was deemed not useful and so it is currently unimplemented. Here's an example of typical usage for this API:: @@ -119,7 +119,7 @@ way of localizing your Python applications and modules. :mod:`!gettext` defines a :class:`GNUTranslations` class which implements the parsing of GNU :file:`.mo` format files, and has methods for returning strings. Instances of this class can also -install themselves in the built-in namespace as the function :func:`_`. +install themselves in the built-in namespace as the function :func:`!_`. .. function:: find(domain, localedir=None, languages=None, all=False) @@ -150,15 +150,12 @@ .. function:: translation(domain, localedir=None, languages=None, class_=None, fallback=False) - Return a :class:`*Translations` instance based on the *domain*, *localedir*, + Return a ``*Translations`` instance based on the *domain*, *localedir*, and *languages*, which are first passed to :func:`find` to get a list of the associated :file:`.mo` file paths. Instances with identical :file:`.mo` file names are cached. The actual class instantiated is *class_* if provided, otherwise :class:`GNUTranslations`. The class's constructor must - take a single :term:`file object` argument. If provided, *codeset* will change - the charset used to encode translated strings in the - :meth:`~NullTranslations.lgettext` and :meth:`~NullTranslations.lngettext` - methods. + take a single :term:`file object` argument. If multiple files are found, later files are used as fallbacks for earlier ones. To allow setting the fallback, :func:`copy.copy` is used to clone each @@ -177,19 +174,19 @@ .. function:: install(domain, localedir=None, *, names=None) - This installs the function :func:`_` in Python's builtins namespace, based on + This installs the function :func:`!_` in Python's builtins namespace, based on *domain* and *localedir* which are passed to the function :func:`translation`. For the *names* parameter, please see the description of the translation object's :meth:`~NullTranslations.install` method. As seen below, you usually mark the strings in your application that are - candidates for translation, by wrapping them in a call to the :func:`_` + candidates for translation, by wrapping them in a call to the :func:`!_` function, like this:: print(_('This string will be translated.')) - For convenience, you want the :func:`_` function to be installed in Python's + For convenience, you want the :func:`!_` function to be installed in Python's builtins namespace, so it is easily accessible in all modules of your application. @@ -276,20 +273,20 @@ If the *names* parameter is given, it must be a sequence containing the names of functions you want to install in the builtins namespace in - addition to :func:`_`. Supported names are ``'gettext'``, ``'ngettext'``, - ``'pgettext'``, ``'npgettext'``, ``'lgettext'``, and ``'lngettext'``. + addition to :func:`!_`. Supported names are ``'gettext'``, ``'ngettext'``, + ``'pgettext'``, and ``'npgettext'``. Note that this is only one way, albeit the most convenient way, to make - the :func:`_` function available to your application. Because it affects + the :func:`!_` function available to your application. Because it affects the entire application globally, and specifically the built-in namespace, - localized modules should never install :func:`_`. Instead, they should use - this code to make :func:`_` available to their module:: + localized modules should never install :func:`!_`. Instead, they should use + this code to make :func:`!_` available to their module:: import gettext t = gettext.translation('mymodule', ...) _ = t.gettext - This puts :func:`_` only in the module's global namespace and so only + This puts :func:`!_` only in the module's global namespace and so only affects calls within this module. .. versionchanged:: 3.8 @@ -314,7 +311,7 @@ ids and message strings read from the catalog are converted to Unicode using this encoding, else ASCII is assumed. -Since message ids are read as Unicode strings too, all :meth:`*gettext` methods +Since message ids are read as Unicode strings too, all ``*gettext()`` methods will assume message ids as Unicode strings, not byte strings. The entire set of key/value pairs are placed into a dictionary and set as the @@ -404,7 +401,7 @@ _ = cat.gettext print(_('hello world')) -For compatibility with this older module, the function :func:`Catalog` is an +For compatibility with this older module, the function :func:`!Catalog` is an alias for the :func:`translation` function described above. One difference between this module and Henstridge's: his catalog objects @@ -432,7 +429,7 @@ In order to prepare your code for I18N, you need to look at all the strings in your files. Any string that needs to be translated should be marked by wrapping -it in ``_('...')`` --- that is, a call to the function :func:`_`. For example:: +it in ``_('...')`` --- that is, a call to the function :func:`_ `. For example:: filename = 'mylog.txt' message = _('writing a log message') @@ -504,7 +501,7 @@ Localizing your application ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -If you are localizing your application, you can install the :func:`_` function +If you are localizing your application, you can install the :func:`!_` function globally into the built-in namespace, usually in the main driver file of your application. This will let all your application-specific files just use ``_('...')`` without having to explicitly install it in each file. @@ -581,13 +578,13 @@ for a in animals: print(_(a)) -This works because the dummy definition of :func:`_` simply returns the string +This works because the dummy definition of :func:`!_` simply returns the string unchanged. And this dummy definition will temporarily override any definition -of :func:`_` in the built-in namespace (until the :keyword:`del` command). Take -care, though if you have a previous definition of :func:`_` in the local +of :func:`!_` in the built-in namespace (until the :keyword:`del` command). Take +care, though if you have a previous definition of :func:`!_` in the local namespace. -Note that the second use of :func:`_` will not identify "a" as being +Note that the second use of :func:`!_` will not identify "a" as being translatable to the :program:`gettext` program, because the parameter is not a string literal. @@ -606,13 +603,13 @@ print(_(a)) In this case, you are marking translatable strings with the function -:func:`N_`, which won't conflict with any definition of :func:`_`. +:func:`!N_`, which won't conflict with any definition of :func:`!_`. However, you will need to teach your message extraction program to -look for translatable strings marked with :func:`N_`. :program:`xgettext`, +look for translatable strings marked with :func:`!N_`. :program:`xgettext`, :program:`pygettext`, ``pybabel extract``, and :program:`xpot` all support this through the use of the :option:`!-k` command-line switch. -The choice of :func:`N_` here is totally arbitrary; it could have just -as easily been :func:`MarkThisStringForTranslation`. +The choice of :func:`!N_` here is totally arbitrary; it could have just +as easily been :func:`!MarkThisStringForTranslation`. Acknowledgements diff -Nru python3.12-3.12.0~rc2/Doc/library/hashlib.rst python3.12-3.12.0/Doc/library/hashlib.rst --- python3.12-3.12.0~rc2/Doc/library/hashlib.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/hashlib.rst 2023-10-02 11:48:14.000000000 +0000 @@ -136,16 +136,16 @@ '031edd7d41651593c5fe5c006fa5752b37fddff7bc4e843aa6af0c950f4b9406' -.. function:: md5([, data], \*, usedforsecurity=True) -.. function:: sha1([, data], \*, usedforsecurity=True) -.. function:: sha224([, data], \*, usedforsecurity=True) -.. function:: sha256([, data], \*, usedforsecurity=True) -.. function:: sha384([, data], \*, usedforsecurity=True) -.. function:: sha512([, data], \*, usedforsecurity=True) -.. function:: sha3_224([, data], \*, usedforsecurity=True) -.. function:: sha3_256([, data], \*, usedforsecurity=True) -.. function:: sha3_384([, data], \*, usedforsecurity=True) -.. function:: sha3_512([, data], \*, usedforsecurity=True) +.. function:: md5([, data], *, usedforsecurity=True) +.. function:: sha1([, data], *, usedforsecurity=True) +.. function:: sha224([, data], *, usedforsecurity=True) +.. function:: sha256([, data], *, usedforsecurity=True) +.. function:: sha384([, data], *, usedforsecurity=True) +.. function:: sha512([, data], *, usedforsecurity=True) +.. function:: sha3_224([, data], *, usedforsecurity=True) +.. function:: sha3_256([, data], *, usedforsecurity=True) +.. function:: sha3_384([, data], *, usedforsecurity=True) +.. function:: sha3_512([, data], *, usedforsecurity=True) Named constructors such as these are faster than passing an algorithm name to :func:`new`. @@ -234,8 +234,8 @@ SHAKE variable length digests ----------------------------- -.. function:: shake_128([, data], \*, usedforsecurity=True) -.. function:: shake_256([, data], \*, usedforsecurity=True) +.. function:: shake_128([, data], *, usedforsecurity=True) +.. function:: shake_256([, data], *, usedforsecurity=True) The :func:`shake_128` and :func:`shake_256` algorithms provide variable length digests with length_in_bits//2 up to 128 or 256 bits of security. diff -Nru python3.12-3.12.0~rc2/Doc/library/html.parser.rst python3.12-3.12.0/Doc/library/html.parser.rst --- python3.12-3.12.0~rc2/Doc/library/html.parser.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/html.parser.rst 2023-10-02 11:48:14.000000000 +0000 @@ -173,7 +173,7 @@ .. method:: HTMLParser.handle_charref(name) This method is called to process decimal and hexadecimal numeric character - references of the form ``&#NNN;`` and ``&#xNNN;``. For example, the decimal + references of the form :samp:`&#{NNN};` and :samp:`&#x{NNN};`. For example, the decimal equivalent for ``>`` is ``>``, whereas the hexadecimal is ``>``; in this case the method will receive ``'62'`` or ``'x3E'``. This method is never called if *convert_charrefs* is ``True``. diff -Nru python3.12-3.12.0~rc2/Doc/library/http.server.rst python3.12-3.12.0/Doc/library/http.server.rst --- python3.12-3.12.0~rc2/Doc/library/http.server.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/http.server.rst 2023-10-02 11:48:14.000000000 +0000 @@ -217,7 +217,7 @@ attribute holds the default values for *message* and *explain* that will be used if no value is provided; for unknown codes the default value for both is the string ``???``. The body will be empty if the method is - HEAD or the response code is one of the following: ``1xx``, + HEAD or the response code is one of the following: :samp:`1{xx}`, ``204 No Content``, ``205 Reset Content``, ``304 Not Modified``. .. versionchanged:: 3.4 diff -Nru python3.12-3.12.0~rc2/Doc/library/importlib.resources.abc.rst python3.12-3.12.0/Doc/library/importlib.resources.abc.rst --- python3.12-3.12.0~rc2/Doc/library/importlib.resources.abc.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/importlib.resources.abc.rst 2023-10-02 11:48:14.000000000 +0000 @@ -43,8 +43,6 @@ :const:`None`. An object compatible with this ABC should only be returned when the specified module is a package. - .. versionadded:: 3.7 - .. deprecated-removed:: 3.12 3.14 Use :class:`importlib.resources.abc.TraversableResources` instead. @@ -95,11 +93,6 @@ For a representation of the object on the file-system, use :meth:`importlib.resources.as_file`. - .. versionadded:: 3.9 - - .. deprecated-removed:: 3.12 3.14 - Use :class:`importlib.resources.abc.Traversable` instead. - .. attribute:: name Abstract. The base name of this object without any parent references. @@ -153,11 +146,6 @@ Loaders that wish to support resource reading are expected to implement this interface. - .. versionadded:: 3.9 - - .. deprecated-removed:: 3.12 3.14 - Use :class:`importlib.resources.abc.TraversableResources` instead. - .. abstractmethod:: files() Returns a :class:`importlib.resources.abc.Traversable` object for the loaded diff -Nru python3.12-3.12.0~rc2/Doc/library/importlib.resources.rst python3.12-3.12.0/Doc/library/importlib.resources.rst --- python3.12-3.12.0~rc2/Doc/library/importlib.resources.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/importlib.resources.rst 2023-10-02 11:48:14.000000000 +0000 @@ -82,19 +82,22 @@ .. function:: as_file(traversable) Given a :class:`~importlib.resources.abc.Traversable` object representing - a file, typically from :func:`importlib.resources.files`, return - a context manager for use in a :keyword:`with` statement. + a file or directory, typically from :func:`importlib.resources.files`, + return a context manager for use in a :keyword:`with` statement. The context manager provides a :class:`pathlib.Path` object. - Exiting the context manager cleans up any temporary file created when the - resource was extracted from e.g. a zip file. + Exiting the context manager cleans up any temporary file or directory + created when the resource was extracted from e.g. a zip file. Use ``as_file`` when the Traversable methods - (``read_text``, etc) are insufficient and an actual file on + (``read_text``, etc) are insufficient and an actual file or directory on the file system is required. .. versionadded:: 3.9 + .. versionchanged:: 3.12 + Added support for ``traversable`` representing a directory. + Deprecated functions ^^^^^^^^^^^^^^^^^^^^ diff -Nru python3.12-3.12.0~rc2/Doc/library/importlib.rst python3.12-3.12.0/Doc/library/importlib.rst --- python3.12-3.12.0~rc2/Doc/library/importlib.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/importlib.rst 2023-10-02 11:48:14.000000000 +0000 @@ -645,6 +645,160 @@ itself does not end in ``__init__``. +.. class:: ResourceReader + + *Superseded by TraversableResources* + + An :term:`abstract base class` to provide the ability to read + *resources*. + + From the perspective of this ABC, a *resource* is a binary + artifact that is shipped within a package. Typically this is + something like a data file that lives next to the ``__init__.py`` + file of the package. The purpose of this class is to help abstract + out the accessing of such data files so that it does not matter if + the package and its data file(s) are stored in a e.g. zip file + versus on the file system. + + For any of methods of this class, a *resource* argument is + expected to be a :term:`path-like object` which represents + conceptually just a file name. This means that no subdirectory + paths should be included in the *resource* argument. This is + because the location of the package the reader is for, acts as the + "directory". Hence the metaphor for directories and file + names is packages and resources, respectively. This is also why + instances of this class are expected to directly correlate to + a specific package (instead of potentially representing multiple + packages or a module). + + Loaders that wish to support resource reading are expected to + provide a method called ``get_resource_reader(fullname)`` which + returns an object implementing this ABC's interface. If the module + specified by fullname is not a package, this method should return + :const:`None`. An object compatible with this ABC should only be + returned when the specified module is a package. + + .. versionadded:: 3.7 + + .. deprecated-removed:: 3.12 3.14 + Use :class:`importlib.resources.abc.TraversableResources` instead. + + .. abstractmethod:: open_resource(resource) + + Returns an opened, :term:`file-like object` for binary reading + of the *resource*. + + If the resource cannot be found, :exc:`FileNotFoundError` is + raised. + + .. abstractmethod:: resource_path(resource) + + Returns the file system path to the *resource*. + + If the resource does not concretely exist on the file system, + raise :exc:`FileNotFoundError`. + + .. abstractmethod:: is_resource(name) + + Returns ``True`` if the named *name* is considered a resource. + :exc:`FileNotFoundError` is raised if *name* does not exist. + + .. abstractmethod:: contents() + + Returns an :term:`iterable` of strings over the contents of + the package. Do note that it is not required that all names + returned by the iterator be actual resources, e.g. it is + acceptable to return names for which :meth:`is_resource` would + be false. + + Allowing non-resource names to be returned is to allow for + situations where how a package and its resources are stored + are known a priori and the non-resource names would be useful. + For instance, returning subdirectory names is allowed so that + when it is known that the package and resources are stored on + the file system then those subdirectory names can be used + directly. + + The abstract method returns an iterable of no items. + + +.. class:: Traversable + + An object with a subset of :class:`pathlib.Path` methods suitable for + traversing directories and opening files. + + For a representation of the object on the file-system, use + :meth:`importlib.resources.as_file`. + + .. versionadded:: 3.9 + + .. deprecated-removed:: 3.12 3.14 + Use :class:`importlib.resources.abc.Traversable` instead. + + .. attribute:: name + + Abstract. The base name of this object without any parent references. + + .. abstractmethod:: iterdir() + + Yield ``Traversable`` objects in ``self``. + + .. abstractmethod:: is_dir() + + Return ``True`` if ``self`` is a directory. + + .. abstractmethod:: is_file() + + Return ``True`` if ``self`` is a file. + + .. abstractmethod:: joinpath(child) + + Return Traversable child in ``self``. + + .. abstractmethod:: __truediv__(child) + + Return ``Traversable`` child in ``self``. + + .. abstractmethod:: open(mode='r', *args, **kwargs) + + *mode* may be 'r' or 'rb' to open as text or binary. Return a handle + suitable for reading (same as :attr:`pathlib.Path.open`). + + When opening as text, accepts encoding parameters such as those + accepted by :attr:`io.TextIOWrapper`. + + .. method:: read_bytes() + + Read contents of ``self`` as bytes. + + .. method:: read_text(encoding=None) + + Read contents of ``self`` as text. + + +.. class:: TraversableResources + + An abstract base class for resource readers capable of serving + the :meth:`importlib.resources.files` interface. Subclasses + :class:`importlib.resources.abc.ResourceReader` and provides + concrete implementations of the :class:`importlib.resources.abc.ResourceReader`'s + abstract methods. Therefore, any loader supplying + :class:`importlib.abc.TraversableResources` also supplies ResourceReader. + + Loaders that wish to support resource reading are expected to + implement this interface. + + .. versionadded:: 3.9 + + .. deprecated-removed:: 3.12 3.14 + Use :class:`importlib.resources.abc.TraversableResources` instead. + + .. abstractmethod:: files() + + Returns a :class:`importlib.resources.abc.Traversable` object for the loaded + package. + + :mod:`importlib.machinery` -- Importers and path hooks ------------------------------------------------------ diff -Nru python3.12-3.12.0~rc2/Doc/library/inspect.rst python3.12-3.12.0/Doc/library/inspect.rst --- python3.12-3.12.0~rc2/Doc/library/inspect.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/inspect.rst 2023-10-02 11:48:14.000000000 +0000 @@ -730,7 +730,7 @@ .. method:: Signature.replace(*[, parameters][, return_annotation]) - Create a new Signature instance based on the instance replace was invoked + Create a new Signature instance based on the instance :meth:`replace` was invoked on. It is possible to pass different ``parameters`` and/or ``return_annotation`` to override the corresponding properties of the base signature. To remove return_annotation from the copied Signature, pass in diff -Nru python3.12-3.12.0~rc2/Doc/library/itertools.rst python3.12-3.12.0/Doc/library/itertools.rst --- python3.12-3.12.0~rc2/Doc/library/itertools.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/itertools.rst 2023-10-02 11:48:14.000000000 +0000 @@ -844,7 +844,7 @@ return next(islice(iterable, n, None), default) def quantify(iterable, pred=bool): - "Count how many times the predicate is True" + "Given a predicate that returns True or False, count the True results." return sum(map(pred, iterable)) def all_equal(iterable): @@ -877,6 +877,7 @@ yield i else: # Fast path for sequences + stop = len(iterable) if stop is None else stop i = start - 1 try: while True: @@ -1027,33 +1028,6 @@ s = list(iterable) return chain.from_iterable(combinations(s, r) for r in range(len(s)+1)) - def sieve(n): - "Primes less than n." - # sieve(30) --> 2 3 5 7 11 13 17 19 23 29 - data = bytearray((0, 1)) * (n // 2) - data[:3] = 0, 0, 0 - limit = math.isqrt(n) + 1 - for p in compress(range(limit), data): - data[p*p : n : p+p] = bytes(len(range(p*p, n, p+p))) - data[2] = 1 - return iter_index(data, 1) if n > 2 else iter([]) - - def factor(n): - "Prime factors of n." - # factor(99) --> 3 3 11 - # factor(1_000_000_000_000_007) --> 47 59 360620266859 - # factor(1_000_000_000_000_403) --> 1000000000000403 - for prime in sieve(math.isqrt(n) + 1): - while True: - if n % prime: - break - yield prime - n //= prime - if n == 1: - return - if n > 1: - yield n - def sum_of_squares(it): "Add up the squares of the input values." # sum_of_squares([10, 20, 30]) -> 1400 @@ -1071,14 +1045,21 @@ return batched(starmap(math.sumprod, product(m1, transpose(m2))), n) def convolve(signal, kernel): - """Linear convolution of two iterables. + """Discrete linear convolution of two iterables. + + The kernel is fully consumed before the calculations begin. + The signal is consumed lazily and can be infinite. + + Convolutions are mathematically commutative. + If the signal and kernel are swapped, + the output will be the same. Article: https://betterexplained.com/articles/intuitive-convolution/ Video: https://www.youtube.com/watch?v=KuXjwB4LzSA """ # convolve(data, [0.25, 0.25, 0.25, 0.25]) --> Moving average (blur) - # convolve(data, [1, -1]) --> 1st finite difference (1st derivative) - # convolve(data, [1, -2, 1]) --> 2nd finite difference (2nd derivative) + # convolve(data, [1/2, 0, -1/2]) --> 1st derivative estimate + # convolve(data, [1, -2, 1]) --> 2nd derivative estimate kernel = tuple(kernel)[::-1] n = len(kernel) padded_signal = chain(repeat(0, n-1), signal, repeat(0, n-1)) @@ -1102,8 +1083,8 @@ # Evaluate x³ -4x² -17x + 60 at x = 2.5 # polynomial_eval([1, -4, -17, 60], x=2.5) --> 8.125 n = len(coefficients) - if n == 0: - return x * 0 # coerce zero to the type of x + if not n: + return type(x)(0) powers = map(pow, repeat(x), reversed(range(n))) return math.sumprod(coefficients, powers) @@ -1118,6 +1099,36 @@ powers = reversed(range(1, n)) return list(map(operator.mul, coefficients, powers)) + def sieve(n): + "Primes less than n." + # sieve(30) --> 2 3 5 7 11 13 17 19 23 29 + if n > 2: + yield 2 + start = 3 + data = bytearray((0, 1)) * (n // 2) + limit = math.isqrt(n) + 1 + for p in iter_index(data, 1, start, limit): + yield from iter_index(data, 1, start, p*p) + data[p*p : n : p+p] = bytes(len(range(p*p, n, p+p))) + start = p*p + yield from iter_index(data, 1, start) + + def factor(n): + "Prime factors of n." + # factor(99) --> 3 3 11 + # factor(1_000_000_000_000_007) --> 47 59 360620266859 + # factor(1_000_000_000_000_403) --> 1000000000000403 + for prime in sieve(math.isqrt(n) + 1): + while True: + if n % prime: + break + yield prime + n //= prime + if n == 1: + return + if n > 1: + yield n + def nth_combination(iterable, r, index): "Equivalent to list(combinations(iterable, r))[index]" pool = tuple(iterable) @@ -1293,7 +1304,7 @@ >>> polynomial_eval([], Fraction(2, 3)) Fraction(0, 1) >>> polynomial_eval([], Decimal('1.75')) - Decimal('0.00') + Decimal('0') >>> polynomial_eval([11], 7) == 11 True >>> polynomial_eval([11, 2], 7) == 11 * 7 + 2 @@ -1344,6 +1355,16 @@ Traceback (most recent call last): ... ValueError + >>> # Verify that both paths can find identical NaN values + >>> x = float('NaN') + >>> y = float('NaN') + >>> list(iter_index([0, x, x, y, 0], x)) + [1, 2] + >>> list(iter_index(iter([0, x, x, y, 0]), x)) + [1, 2] + >>> # Test list input. Lists do not support None for the stop argument + >>> list(iter_index(list('AABCADEAF'), 'A')) + [0, 1, 4, 7] >>> list(sieve(30)) [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] diff -Nru python3.12-3.12.0~rc2/Doc/library/logging.rst python3.12-3.12.0/Doc/library/logging.rst --- python3.12-3.12.0~rc2/Doc/library/logging.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/logging.rst 2023-10-02 11:48:14.000000000 +0000 @@ -907,7 +907,7 @@ In the case of {}-formatting, you can specify formatting flags by placing them after the attribute name, separated from it with a colon. For example: a -placeholder of ``{msecs:03d}`` would format a millisecond value of ``4`` as +placeholder of ``{msecs:03.0f}`` would format a millisecond value of ``4`` as ``004``. Refer to the :meth:`str.format` documentation for full details on the options available to you. diff -Nru python3.12-3.12.0~rc2/Doc/library/__main__.rst python3.12-3.12.0/Doc/library/__main__.rst --- python3.12-3.12.0~rc2/Doc/library/__main__.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/__main__.rst 2023-10-02 11:48:14.000000000 +0000 @@ -238,9 +238,9 @@ Idiomatic Usage ^^^^^^^^^^^^^^^ -The contents of ``__main__.py`` typically isn't fenced with -``if __name__ == '__main__'`` blocks. Instead, those files are kept short, -functions to execute from other modules. Those other modules can then be +The content of ``__main__.py`` typically isn't fenced with an +``if __name__ == '__main__'`` block. Instead, those files are kept +short and import functions to execute from other modules. Those other modules can then be easily unit-tested and are properly reusable. If used, an ``if __name__ == '__main__'`` block will still work as expected diff -Nru python3.12-3.12.0~rc2/Doc/library/multiprocessing.rst python3.12-3.12.0/Doc/library/multiprocessing.rst --- python3.12-3.12.0~rc2/Doc/library/multiprocessing.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/multiprocessing.rst 2023-10-02 11:48:14.000000000 +0000 @@ -131,6 +131,12 @@ Code that requires *fork* should explicitly specify that via :func:`get_context` or :func:`set_start_method`. + .. versionchanged:: 3.12 + If Python is able to detect that your process has multiple threads, the + :func:`os.fork` function that this start method calls internally will + raise a :exc:`DeprecationWarning`. Use a different start method. + See the :func:`os.fork` documentation for further explanation. + *forkserver* When the program starts and selects the *forkserver* start method, a server process is spawned. From then on, whenever a new process diff -Nru python3.12-3.12.0~rc2/Doc/library/os.rst python3.12-3.12.0/Doc/library/os.rst --- python3.12-3.12.0~rc2/Doc/library/os.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/os.rst 2023-10-02 11:48:14.000000000 +0000 @@ -88,8 +88,8 @@ On some systems, conversion using the file system encoding may fail. In this case, Python uses the :ref:`surrogateescape encoding error handler `, which means that undecodable bytes are replaced by a - Unicode character U+DCxx on decoding, and these are again translated to the - original byte on encoding. + Unicode character U+DC\ *xx* on decoding, and these are again + translated to the original byte on encoding. The :term:`file system encoding ` must @@ -1618,25 +1618,6 @@ Parameters *out* and *in* was renamed to *out_fd* and *in_fd*. -.. function:: set_blocking(fd, blocking, /) - - Set the blocking mode of the specified file descriptor. Set the - :data:`O_NONBLOCK` flag if blocking is ``False``, clear the flag otherwise. - - See also :func:`get_blocking` and :meth:`socket.socket.setblocking`. - - .. availability:: Unix, Windows. - - The function is limited on Emscripten and WASI, see - :ref:`wasm-availability` for more information. - - On Windows, this function is limited to pipes. - - .. versionadded:: 3.5 - - .. versionchanged:: 3.12 - Added support for pipes on Windows. - .. data:: SF_NODISKIO SF_MNOWAIT SF_SYNC @@ -1658,6 +1639,26 @@ .. versionadded:: 3.11 +.. function:: set_blocking(fd, blocking, /) + + Set the blocking mode of the specified file descriptor. Set the + :data:`O_NONBLOCK` flag if blocking is ``False``, clear the flag otherwise. + + See also :func:`get_blocking` and :meth:`socket.socket.setblocking`. + + .. availability:: Unix, Windows. + + The function is limited on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + + On Windows, this function is limited to pipes. + + .. versionadded:: 3.5 + + .. versionchanged:: 3.12 + Added support for pipes on Windows. + + .. function:: splice(src, dst, count, offset_src=None, offset_dst=None) Transfer *count* bytes from file descriptor *src*, starting from offset @@ -4156,15 +4157,38 @@ .. audit-event:: os.fork "" os.fork + .. warning:: + + If you use TLS sockets in an application calling ``fork()``, see + the warning in the :mod:`ssl` documentation. + .. versionchanged:: 3.8 Calling ``fork()`` in a subinterpreter is no longer supported (:exc:`RuntimeError` is raised). - .. warning:: + .. versionchanged:: 3.12 + If Python is able to detect that your process has multiple + threads, :func:`os.fork` now raises a :exc:`DeprecationWarning`. - See :mod:`ssl` for applications that use the SSL module with fork(). + We chose to surface this as a warning, when detectable, to better + inform developers of a design problem that the POSIX platform + specifically notes as not supported. Even in code that + *appears* to work, it has never been safe to mix threading with + :func:`os.fork` on POSIX platforms. The CPython runtime itself has + always made API calls that are not safe for use in the child + process when threads existed in the parent (such as ``malloc`` and + ``free``). + + Users of macOS or users of libc or malloc implementations other + than those typically found in glibc to date are among those + already more likely to experience deadlocks running such code. + + See `this discussion on fork being incompatible with threads + `_ + for technical details of why we're surfacing this longstanding + platform compatibility problem to developers. - .. availability:: Unix, not Emscripten, not WASI. + .. availability:: POSIX, not Emscripten, not WASI. .. function:: forkpty() @@ -4177,6 +4201,11 @@ .. audit-event:: os.forkpty "" os.forkpty + .. versionchanged:: 3.12 + If Python is able to detect that your process has multiple + threads, this now raises a :exc:`DeprecationWarning`. See the + longer explanation on :func:`os.fork`. + .. versionchanged:: 3.8 Calling ``forkpty()`` in a subinterpreter is no longer supported (:exc:`RuntimeError` is raised). diff -Nru python3.12-3.12.0~rc2/Doc/library/re.rst python3.12-3.12.0/Doc/library/re.rst --- python3.12-3.12.0~rc2/Doc/library/re.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/re.rst 2023-10-02 11:48:14.000000000 +0000 @@ -660,7 +660,7 @@ Unknown escapes consisting of ``'\'`` and an ASCII letter now are errors. .. versionchanged:: 3.8 - The ``'\N{name}'`` escape sequence has been added. As in string literals, + The :samp:`'\\N\\{{name}\\}'` escape sequence has been added. As in string literals, it expands to the named Unicode character (e.g. ``'\N{EM DASH}'``). diff -Nru python3.12-3.12.0~rc2/Doc/library/site.rst python3.12-3.12.0/Doc/library/site.rst --- python3.12-3.12.0~rc2/Doc/library/site.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/site.rst 2023-10-02 11:48:14.000000000 +0000 @@ -19,7 +19,7 @@ and add a few builtins, unless :option:`-S` was used. In that case, this module can be safely imported with no automatic modifications to the module search path or additions to the builtins. To explicitly trigger the usual site-specific -additions, call the :func:`site.main` function. +additions, call the :func:`main` function. .. versionchanged:: 3.3 Importing the module used to trigger paths manipulation even when using @@ -109,32 +109,40 @@ alphabetically before :file:`foo.pth`; and :file:`spam` is omitted because it is not mentioned in either path configuration file. -.. index:: pair: module; sitecustomize +:mod:`sitecustomize` +-------------------- + +.. module:: sitecustomize After these path manipulations, an attempt is made to import a module named :mod:`sitecustomize`, which can perform arbitrary site-specific customizations. It is typically created by a system administrator in the site-packages directory. If this import fails with an :exc:`ImportError` or its subclass -exception, and the exception's :attr:`name` attribute equals to ``'sitecustomize'``, +exception, and the exception's :attr:`~ImportError.name` +attribute equals to ``'sitecustomize'``, it is silently ignored. If Python is started without output streams available, as with :file:`pythonw.exe` on Windows (which is used by default to start IDLE), attempted output from :mod:`sitecustomize` is ignored. Any other exception causes a silent and perhaps mysterious failure of the process. -.. index:: pair: module; usercustomize +:mod:`usercustomize` +-------------------- + +.. module:: usercustomize After this, an attempt is made to import a module named :mod:`usercustomize`, which can perform arbitrary user-specific customizations, if -:data:`ENABLE_USER_SITE` is true. This file is intended to be created in the +:data:`~site.ENABLE_USER_SITE` is true. This file is intended to be created in the user site-packages directory (see below), which is part of ``sys.path`` unless disabled by :option:`-s`. If this import fails with an :exc:`ImportError` or -its subclass exception, and the exception's :attr:`name` attribute equals to -``'usercustomize'``, it is silently ignored. +its subclass exception, and the exception's :attr:`~ImportError.name` +attribute equals to ``'usercustomize'``, it is silently ignored. Note that for some non-Unix systems, ``sys.prefix`` and ``sys.exec_prefix`` are empty, and the path manipulations are skipped; however the import of :mod:`sitecustomize` and :mod:`usercustomize` is still attempted. +.. currentmodule:: site .. _rlcompleter-config: @@ -191,7 +199,7 @@ :file:`~/Library/Python/{X.Y}` for macOS framework builds, and :file:`{%APPDATA%}\\Python` for Windows. This value is used to compute the installation directories for scripts, data files, Python modules, - etc. for the user installation scheme. + etc. for the :ref:`user installation scheme `. See also :envvar:`PYTHONUSERBASE`. diff -Nru python3.12-3.12.0~rc2/Doc/library/socket.rst python3.12-3.12.0/Doc/library/socket.rst --- python3.12-3.12.0~rc2/Doc/library/socket.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/socket.rst 2023-10-02 11:48:14.000000000 +0000 @@ -979,7 +979,7 @@ .. function:: gethostbyname_ex(hostname) Translate a host name to IPv4 address format, extended interface. Return a - triple ``(hostname, aliaslist, ipaddrlist)`` where *hostname* is the host's + 3-tuple ``(hostname, aliaslist, ipaddrlist)`` where *hostname* is the host's primary host name, *aliaslist* is a (possibly empty) list of alternative host names for the same address, and *ipaddrlist* is a list of IPv4 addresses for the same interface on the same host (often but not @@ -1007,7 +1007,7 @@ .. function:: gethostbyaddr(ip_address) - Return a triple ``(hostname, aliaslist, ipaddrlist)`` where *hostname* is the + Return a 3-tuple ``(hostname, aliaslist, ipaddrlist)`` where *hostname* is the primary host name responding to the given *ip_address*, *aliaslist* is a (possibly empty) list of alternative host names for the same address, and *ipaddrlist* is a list of IPv4/v6 addresses for the same interface on the same diff -Nru python3.12-3.12.0~rc2/Doc/library/stdtypes.rst python3.12-3.12.0/Doc/library/stdtypes.rst --- python3.12-3.12.0~rc2/Doc/library/stdtypes.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/stdtypes.rst 2023-10-02 11:48:14.000000000 +0000 @@ -282,7 +282,7 @@ +---------------------+---------------------------------+---------+--------------------+ | ``x / y`` | quotient of *x* and *y* | | | +---------------------+---------------------------------+---------+--------------------+ -| ``x // y`` | floored quotient of *x* and | \(1) | | +| ``x // y`` | floored quotient of *x* and | \(1)\(2)| | | | *y* | | | +---------------------+---------------------------------+---------+--------------------+ | ``x % y`` | remainder of ``x / y`` | \(2) | | @@ -319,8 +319,10 @@ Notes: (1) - Also referred to as integer division. The resultant value is a whole - integer, though the result's type is not necessarily int. The result is + Also referred to as integer division. For operands of type :class:`int`, + the result has type :class:`int`. For operands of type :class:`float`, + the result has type :class:`float`. In general, the result is a whole + integer, though the result's type is not necessarily :class:`int`. The result is always rounded towards minus infinity: ``1//2`` is ``0``, ``(-1)//2`` is ``-1``, ``1//(-2)`` is ``-1``, and ``(-1)//(-2)`` is ``0``. diff -Nru python3.12-3.12.0~rc2/Doc/library/superseded.rst python3.12-3.12.0/Doc/library/superseded.rst --- python3.12-3.12.0~rc2/Doc/library/superseded.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/superseded.rst 2023-10-02 11:48:14.000000000 +0000 @@ -9,6 +9,7 @@ .. toctree:: + :maxdepth: 1 aifc.rst audioop.rst diff -Nru python3.12-3.12.0~rc2/Doc/library/symtable.rst python3.12-3.12.0/Doc/library/symtable.rst --- python3.12-3.12.0~rc2/Doc/library/symtable.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/symtable.rst 2023-10-02 11:48:14.000000000 +0000 @@ -38,7 +38,13 @@ .. method:: get_type() Return the type of the symbol table. Possible values are ``'class'``, - ``'module'``, and ``'function'``. + ``'module'``, ``'function'``, ``'annotation'``, ``'TypeVar bound'``, + ``'type alias'``, and ``'type parameter'``. The latter four refer to + different flavors of :ref:`annotation scopes `. + + .. versionchanged:: 3.12 + Added ``'annotation'``, ``'TypeVar bound'``, ``'type alias'``, + and ``'type parameter'`` as possible return values. .. method:: get_id() @@ -49,6 +55,10 @@ Return the table's name. This is the name of the class if the table is for a class, the name of the function if the table is for a function, or ``'top'`` if the table is global (:meth:`get_type` returns ``'module'``). + For type parameter scopes (which are used for generic classes, functions, + and type aliases), it is the name of the underlying class, function, or + type alias. For type alias scopes, it is the name of the type alias. + For :class:`~typing.TypeVar` bound scopes, it is the name of the ``TypeVar``. .. method:: get_lineno() diff -Nru python3.12-3.12.0~rc2/Doc/library/sysconfig.rst python3.12-3.12.0/Doc/library/sysconfig.rst --- python3.12-3.12.0~rc2/Doc/library/sysconfig.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/sysconfig.rst 2023-10-02 11:48:14.000000000 +0000 @@ -20,6 +20,7 @@ information like the list of installation paths and the configuration variables relevant for the current platform. + Configuration variables ----------------------- @@ -60,6 +61,7 @@ >>> sysconfig.get_config_vars('AR', 'CXX') ['ar', 'g++'] + .. _installation_paths: Installation paths @@ -68,27 +70,24 @@ Python uses an installation scheme that differs depending on the platform and on the installation options. These schemes are stored in :mod:`sysconfig` under unique identifiers based on the value returned by :const:`os.name`. - -Every new component that is installed using :mod:`!distutils` or a -Distutils-based system will follow the same scheme to copy its file in the right -places. +The schemes are used by package installers to determine where to copy files to. Python currently supports nine schemes: - *posix_prefix*: scheme for POSIX platforms like Linux or macOS. This is the default scheme used when Python or a component is installed. -- *posix_home*: scheme for POSIX platforms used when a *home* option is used - upon installation. This scheme is used when a component is installed through - Distutils with a specific home prefix. -- *posix_user*: scheme for POSIX platforms used when a component is installed - through Distutils and the *user* option is used. This scheme defines paths - located under the user home directory. +- *posix_home*: scheme for POSIX platforms, when the *home* option is used. + This scheme defines paths located under a specific home prefix. +- *posix_user*: scheme for POSIX platforms, when the *user* option is used. + This scheme defines paths located under the user's home directory + (:const:`site.USER_BASE`). - *posix_venv*: scheme for :mod:`Python virtual environments ` on POSIX platforms; by default it is the same as *posix_prefix*. -- *nt*: scheme for NT platforms like Windows. -- *nt_user*: scheme for NT platforms, when the *user* option is used. -- *nt_venv*: scheme for :mod:`Python virtual environments ` on NT - platforms; by default it is the same as *nt*. +- *nt*: scheme for Windows. + This is the default scheme used when Python or a component is installed. +- *nt_user*: scheme for Windows, when the *user* option is used. +- *nt_venv*: scheme for :mod:`Python virtual environments ` on Windows; + by default it is the same as *nt*. - *venv*: a scheme with values from either *posix_venv* or *nt_venv* depending on the platform Python runs on. - *osx_framework_user*: scheme for macOS, when the *user* option is used. @@ -101,7 +100,7 @@ - *platstdlib*: directory containing the standard Python library files that are platform-specific. - *platlib*: directory for site-specific, platform-specific files. -- *purelib*: directory for site-specific, non-platform-specific files. +- *purelib*: directory for site-specific, non-platform-specific files ('pure' Python). - *include*: directory for non-platform-specific header files for the Python C-API. - *platinclude*: directory for platform-specific header files for @@ -109,7 +108,157 @@ - *scripts*: directory for script files. - *data*: directory for data files. -:mod:`sysconfig` provides some functions to determine these paths. + +.. _sysconfig-user-scheme: + +User scheme +--------------- + +This scheme is designed to be the most convenient solution for users that don't +have write permission to the global site-packages directory or don't want to +install into it. + +Files will be installed into subdirectories of :const:`site.USER_BASE` (written +as :file:`{userbase}` hereafter). This scheme installs pure Python modules and +extension modules in the same location (also known as :const:`site.USER_SITE`). + +``posix_user`` +^^^^^^^^^^^^^^ + +============== =========================================================== +Path Installation directory +============== =========================================================== +*stdlib* :file:`{userbase}/lib/python{X.Y}` +*platstdlib* :file:`{userbase}/lib/python{X.Y}` +*platlib* :file:`{userbase}/lib/python{X.Y}/site-packages` +*purelib* :file:`{userbase}/lib/python{X.Y}/site-packages` +*include* :file:`{userbase}/include/python{X.Y}` +*scripts* :file:`{userbase}/bin` +*data* :file:`{userbase}` +============== =========================================================== + +``nt_user`` +^^^^^^^^^^^ + +============== =========================================================== +Path Installation directory +============== =========================================================== +*stdlib* :file:`{userbase}\\Python{XY}` +*platstdlib* :file:`{userbase}\\Python{XY}` +*platlib* :file:`{userbase}\\Python{XY}\\site-packages` +*purelib* :file:`{userbase}\\Python{XY}\\site-packages` +*include* :file:`{userbase}\\Python{XY}\\Include` +*scripts* :file:`{userbase}\\Python{XY}\\Scripts` +*data* :file:`{userbase}` +============== =========================================================== + +``osx_framework_user`` +^^^^^^^^^^^^^^^^^^^^^^ + +============== =========================================================== +Path Installation directory +============== =========================================================== +*stdlib* :file:`{userbase}/lib/python` +*platstdlib* :file:`{userbase}/lib/python` +*platlib* :file:`{userbase}/lib/python/site-packages` +*purelib* :file:`{userbase}/lib/python/site-packages` +*include* :file:`{userbase}/include/python{X.Y}` +*scripts* :file:`{userbase}/bin` +*data* :file:`{userbase}` +============== =========================================================== + + +.. _sysconfig-home-scheme: + +Home scheme +----------- + +The idea behind the "home scheme" is that you build and maintain a personal +stash of Python modules. This scheme's name is derived from the idea of a +"home" directory on Unix, since it's not unusual for a Unix user to make their +home directory have a layout similar to :file:`/usr/` or :file:`/usr/local/`. +This scheme can be used by anyone, regardless of the operating system they +are installing for. + +``posix_home`` +^^^^^^^^^^^^^^ + +============== =========================================================== +Path Installation directory +============== =========================================================== +*stdlib* :file:`{home}/lib/python` +*platstdlib* :file:`{home}/lib/python` +*platlib* :file:`{home}/lib/python` +*purelib* :file:`{home}/lib/python` +*include* :file:`{home}/include/python` +*platinclude* :file:`{home}/include/python` +*scripts* :file:`{home}/bin` +*data* :file:`{home}` +============== =========================================================== + + +.. _sysconfig-prefix-scheme: + +Prefix scheme +------------- + +The "prefix scheme" is useful when you wish to use one Python installation to +perform the build/install (i.e., to run the setup script), but install modules +into the third-party module directory of a different Python installation (or +something that looks like a different Python installation). If this sounds a +trifle unusual, it is---that's why the user and home schemes come before. However, +there are at least two known cases where the prefix scheme will be useful. + +First, consider that many Linux distributions put Python in :file:`/usr`, rather +than the more traditional :file:`/usr/local`. This is entirely appropriate, +since in those cases Python is part of "the system" rather than a local add-on. +However, if you are installing Python modules from source, you probably want +them to go in :file:`/usr/local/lib/python2.{X}` rather than +:file:`/usr/lib/python2.{X}`. + +Another possibility is a network filesystem where the name used to write to a +remote directory is different from the name used to read it: for example, the +Python interpreter accessed as :file:`/usr/local/bin/python` might search for +modules in :file:`/usr/local/lib/python2.{X}`, but those modules would have to +be installed to, say, :file:`/mnt/{@server}/export/lib/python2.{X}`. + +``posix_prefix`` +^^^^^^^^^^^^^^^^ + +============== ========================================================== +Path Installation directory +============== ========================================================== +*stdlib* :file:`{prefix}/lib/python{X.Y}` +*platstdlib* :file:`{prefix}/lib/python{X.Y}` +*platlib* :file:`{prefix}/lib/python{X.Y}/site-packages` +*purelib* :file:`{prefix}/lib/python{X.Y}/site-packages` +*include* :file:`{prefix}/include/python{X.Y}` +*platinclude* :file:`{prefix}/include/python{X.Y}` +*scripts* :file:`{prefix}/bin` +*data* :file:`{prefix}` +============== ========================================================== + +``nt`` +^^^^^^ + +============== ========================================================== +Path Installation directory +============== ========================================================== +*stdlib* :file:`{prefix}\\Lib` +*platstdlib* :file:`{prefix}\\Lib` +*platlib* :file:`{prefix}\\Lib\\site-packages` +*purelib* :file:`{prefix}\\Lib\\site-packages` +*include* :file:`{prefix}\\Include` +*platinclude* :file:`{prefix}\\Include` +*scripts* :file:`{prefix}\\Scripts` +*data* :file:`{prefix}` +============== ========================================================== + + +Installation path functions +--------------------------- + +:mod:`sysconfig` provides some functions to determine these installation paths. .. function:: get_scheme_names() diff -Nru python3.12-3.12.0~rc2/Doc/library/sys.rst python3.12-3.12.0/Doc/library/sys.rst --- python3.12-3.12.0~rc2/Doc/library/sys.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/sys.rst 2023-10-02 11:48:14.000000000 +0000 @@ -378,7 +378,7 @@ This function prints out a given traceback and exception to ``sys.stderr``. - When an exception is raised and uncaught, the interpreter calls + When an exception other than :exc:`SystemExit` is raised and uncaught, the interpreter calls ``sys.excepthook`` with three arguments, the exception class, exception instance, and a traceback object. In an interactive session this happens just before control is returned to the prompt; in a Python program this happens just @@ -753,7 +753,7 @@ Return the current value of the flags that are used for :c:func:`dlopen` calls. Symbolic names for the flag values can be - found in the :mod:`os` module (``RTLD_xxx`` constants, e.g. + found in the :mod:`os` module (:samp:`RTLD_{xxx}` constants, e.g. :const:`os.RTLD_LAZY`). .. availability:: Unix. @@ -1441,7 +1441,7 @@ lazy resolving of symbols when importing a module, if called as ``sys.setdlopenflags(0)``. To share symbols across extension modules, call as ``sys.setdlopenflags(os.RTLD_GLOBAL)``. Symbolic names for the flag values - can be found in the :mod:`os` module (``RTLD_xxx`` constants, e.g. + can be found in the :mod:`os` module (:samp:`RTLD_{xxx}` constants, e.g. :const:`os.RTLD_LAZY`). .. availability:: Unix. diff -Nru python3.12-3.12.0~rc2/Doc/library/traceback.rst python3.12-3.12.0/Doc/library/traceback.rst --- python3.12-3.12.0~rc2/Doc/library/traceback.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/traceback.rst 2023-10-02 11:48:14.000000000 +0000 @@ -139,11 +139,11 @@ Format the exception part of a traceback using an exception value such as given by ``sys.last_value``. The return value is a list of strings, each - ending in a newline. Normally, the list contains a single string; however, - for :exc:`SyntaxError` exceptions, it contains several lines that (when - printed) display detailed information about where the syntax error occurred. - The message indicating which exception occurred is the always last string in - the list. + ending in a newline. The list contains the exception's message, which is + normally a single string; however, for :exc:`SyntaxError` exceptions, it + contains several lines that (when printed) display detailed information + about where the syntax error occurred. Following the message, the list + contains the exception's :attr:`notes `. Since Python 3.10, instead of passing *value*, an exception object can be passed as the first argument. If *value* is provided, the first @@ -153,6 +153,9 @@ The *etype* parameter has been renamed to *exc* and is now positional-only. + .. versionchanged:: 3.11 + The returned list now includes any notes attached to the exception. + .. function:: format_exception(exc, /[, value, tb], limit=None, chain=True) @@ -235,6 +238,12 @@ group's exceptions array. The formatted output is truncated when either limit is exceeded. + .. versionchanged:: 3.10 + Added the *compact* parameter. + + .. versionchanged:: 3.11 + Added the *max_group_width* and *max_group_depth* parameters. + .. attribute:: __cause__ A :class:`TracebackException` of the original ``__cause__``. @@ -330,28 +339,21 @@ some containing internal newlines. :func:`~traceback.print_exception` is a wrapper around this method which just prints the lines to a file. - The message indicating which exception occurred is always the last - string in the output. - .. method:: format_exception_only() Format the exception part of the traceback. The return value is a generator of strings, each ending in a newline. - Normally, the generator emits a single string; however, for - :exc:`SyntaxError` exceptions, it emits several lines that (when - printed) display detailed information about where the syntax - error occurred. + The generator emits the exception's message followed by its notes + (if it has any). The exception message is normally a single string; + however, for :exc:`SyntaxError` exceptions, it consists of several + lines that (when printed) display detailed information about where + the syntax error occurred. - The message indicating which exception occurred is always the last - string in the output. + .. versionchanged:: 3.11 + The exception's notes are now included in the output. - .. versionchanged:: 3.10 - Added the *compact* parameter. - - .. versionchanged:: 3.11 - Added the *max_group_width* and *max_group_depth* parameters. :class:`StackSummary` Objects diff -Nru python3.12-3.12.0~rc2/Doc/library/turtle.rst python3.12-3.12.0/Doc/library/turtle.rst --- python3.12-3.12.0~rc2/Doc/library/turtle.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/turtle.rst 2023-10-02 11:48:14.000000000 +0000 @@ -2329,7 +2329,7 @@ .. class:: RawTurtle(canvas) RawPen(canvas) - :param canvas: a :class:`tkinter.Canvas`, a :class:`ScrolledCanvas` or a + :param canvas: a :class:`!tkinter.Canvas`, a :class:`ScrolledCanvas` or a :class:`TurtleScreen` Create a turtle. The turtle has all methods described above as "methods of @@ -2344,7 +2344,7 @@ .. class:: TurtleScreen(cv) - :param cv: a :class:`tkinter.Canvas` + :param cv: a :class:`!tkinter.Canvas` Provides screen oriented methods like :func:`bgcolor` etc. that are described above. @@ -2428,7 +2428,7 @@ ``Turtle`` is a subclass of :class:`RawTurtle`, which *doesn't* automatically create a drawing surface - a *canvas* will need to be provided or created for -it. The *canvas* can be a :class:`tkinter.Canvas`, :class:`ScrolledCanvas` +it. The *canvas* can be a :class:`!tkinter.Canvas`, :class:`ScrolledCanvas` or :class:`TurtleScreen`. @@ -2436,7 +2436,7 @@ turtle. :class:`Screen` is a subclass of ``TurtleScreen``, and includes :ref:`some additional methods ` for managing its appearance (including size and title) and behaviour. ``TurtleScreen``'s -constructor needs a :class:`tkinter.Canvas` or a +constructor needs a :class:`!tkinter.Canvas` or a :class:`ScrolledCanvas` as an argument. The functional interface for turtle graphics uses the various methods of diff -Nru python3.12-3.12.0~rc2/Doc/library/unittest.mock-examples.rst python3.12-3.12.0/Doc/library/unittest.mock-examples.rst --- python3.12-3.12.0~rc2/Doc/library/unittest.mock-examples.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/unittest.mock-examples.rst 2023-10-02 11:48:14.000000000 +0000 @@ -360,6 +360,30 @@ *spec_set* instead of *spec*. +Using side_effect to return per file content +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:func:`mock_open` is used to patch :func:`open` method. :attr:`~Mock.side_effect` +can be used to return a new Mock object per call. This can be used to return different +contents per file stored in a dictionary:: + + DEFAULT = "default" + data_dict = {"file1": "data1", + "file2": "data2"} + + def open_side_effect(name): + return mock_open(read_data=data_dict.get(name, DEFAULT))() + + with patch("builtins.open", side_effect=open_side_effect): + with open("file1") as file1: + assert file1.read() == "data1" + + with open("file2") as file2: + assert file2.read() == "data2" + + with open("file3") as file2: + assert file2.read() == "default" + Patch Decorators ---------------- diff -Nru python3.12-3.12.0~rc2/Doc/library/urllib.parse.rst python3.12-3.12.0/Doc/library/urllib.parse.rst --- python3.12-3.12.0~rc2/Doc/library/urllib.parse.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/urllib.parse.rst 2023-10-02 11:48:14.000000000 +0000 @@ -598,7 +598,7 @@ .. function:: quote(string, safe='/', encoding=None, errors=None) - Replace special characters in *string* using the ``%xx`` escape. Letters, + Replace special characters in *string* using the :samp:`%{xx}` escape. Letters, digits, and the characters ``'_.-~'`` are never quoted. By default, this function is intended for quoting the path section of a URL. The optional *safe* parameter specifies additional ASCII characters that should not be @@ -645,7 +645,7 @@ .. function:: unquote(string, encoding='utf-8', errors='replace') - Replace ``%xx`` escapes with their single-character equivalent. + Replace :samp:`%{xx}` escapes with their single-character equivalent. The optional *encoding* and *errors* parameters specify how to decode percent-encoded sequences into Unicode characters, as accepted by the :meth:`bytes.decode` method. @@ -676,7 +676,7 @@ .. function:: unquote_to_bytes(string) - Replace ``%xx`` escapes with their single-octet equivalent, and return a + Replace :samp:`%{xx}` escapes with their single-octet equivalent, and return a :class:`bytes` object. *string* may be either a :class:`str` or a :class:`bytes` object. diff -Nru python3.12-3.12.0~rc2/Doc/library/venv.rst python3.12-3.12.0/Doc/library/venv.rst --- python3.12-3.12.0~rc2/Doc/library/venv.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/venv.rst 2023-10-02 11:48:14.000000000 +0000 @@ -30,6 +30,25 @@ `pip`_ will install Python packages into a virtual environment without needing to be told to do so explicitly. +A virtual environment is (amongst other things): + +* Used to contain a specific Python interpreter and software libraries and + binaries which are needed to support a project (library or application). These + are by default isolated from software in other virtual environments and Python + interpreters and libraries installed in the operating system. + +* Contained in a directory, conventionally either named ``venv`` or ``.venv`` in + the project directory, or under a container directory for lots of virtual + environments, such as ``~/.virtualenvs``. + +* Not checked into source control systems such as Git. + +* Considered as disposable -- it should be simple to delete and recreate it from + scratch. You don't place any project code in the environment + +* Not considered as movable or copyable -- you just recreate the same + environment in the target location. + See :pep:`405` for more background on Python virtual environments. .. seealso:: diff -Nru python3.12-3.12.0~rc2/Doc/library/weakref.rst python3.12-3.12.0/Doc/library/weakref.rst --- python3.12-3.12.0~rc2/Doc/library/weakref.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/weakref.rst 2023-10-02 11:48:14.000000000 +0000 @@ -111,7 +111,7 @@ Exceptions raised by the callback will be noted on the standard error output, but cannot be propagated; they are handled in exactly the same way as exceptions - raised from an object's :meth:`__del__` method. + raised from an object's :meth:`~object.__del__` method. Weak references are :term:`hashable` if the *object* is hashable. They will maintain their hash value even after the *object* was deleted. If @@ -221,8 +221,7 @@ Added support for ``|`` and ``|=`` operators, as specified in :pep:`584`. :class:`WeakValueDictionary` objects have an additional method that has the -same issues as the :meth:`keyrefs` method of :class:`WeakKeyDictionary` -objects. +same issues as the :meth:`WeakKeyDictionary.keyrefs` method. .. method:: WeakValueDictionary.valuerefs() @@ -281,7 +280,7 @@ Exceptions raised by finalizer callbacks during garbage collection will be shown on the standard error output, but cannot be propagated. They are handled in the same way as exceptions raised - from an object's :meth:`__del__` method or a weak reference's + from an object's :meth:`~object.__del__` method or a weak reference's callback. When the program exits, each remaining live finalizer is called @@ -523,18 +522,18 @@ obj dead or exiting -Comparing finalizers with :meth:`__del__` methods -------------------------------------------------- +Comparing finalizers with :meth:`~object.__del__` methods +--------------------------------------------------------- Suppose we want to create a class whose instances represent temporary directories. The directories should be deleted with their contents when the first of the following events occurs: * the object is garbage collected, -* the object's :meth:`remove` method is called, or +* the object's :meth:`!remove` method is called, or * the program exits. -We might try to implement the class using a :meth:`__del__` method as +We might try to implement the class using a :meth:`~object.__del__` method as follows:: class TempDir: @@ -553,12 +552,12 @@ def __del__(self): self.remove() -Starting with Python 3.4, :meth:`__del__` methods no longer prevent +Starting with Python 3.4, :meth:`~object.__del__` methods no longer prevent reference cycles from being garbage collected, and module globals are no longer forced to :const:`None` during :term:`interpreter shutdown`. So this code should work without any issues on CPython. -However, handling of :meth:`__del__` methods is notoriously implementation +However, handling of :meth:`~object.__del__` methods is notoriously implementation specific, since it depends on internal details of the interpreter's garbage collector implementation. diff -Nru python3.12-3.12.0~rc2/Doc/library/xml.etree.elementtree.rst python3.12-3.12.0/Doc/library/xml.etree.elementtree.rst --- python3.12-3.12.0~rc2/Doc/library/xml.etree.elementtree.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/xml.etree.elementtree.rst 2023-10-02 11:48:14.000000000 +0000 @@ -17,7 +17,7 @@ This module will use a fast implementation whenever available. .. deprecated:: 3.3 - The :mod:`xml.etree.cElementTree` module is deprecated. + The :mod:`!xml.etree.cElementTree` module is deprecated. .. warning:: @@ -825,6 +825,8 @@ Functions ^^^^^^^^^ +.. module:: xml.etree.ElementInclude + .. function:: xml.etree.ElementInclude.default_loader( href, parse, encoding=None) :module: @@ -862,6 +864,9 @@ Element Objects ^^^^^^^^^^^^^^^ +.. module:: xml.etree.ElementTree + :noindex: + .. class:: Element(tag, attrib={}, **extra) Element class. This class defines the Element interface, and provides a diff -Nru python3.12-3.12.0~rc2/Doc/library/zipapp.rst python3.12-3.12.0/Doc/library/zipapp.rst --- python3.12-3.12.0~rc2/Doc/library/zipapp.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/library/zipapp.rst 2023-10-02 11:48:14.000000000 +0000 @@ -281,12 +281,7 @@ file - if not, you can just list the dependencies manually on the pip command line). -3. Optionally, delete the ``.dist-info`` directories created by pip in the - ``myapp`` directory. These hold metadata for pip to manage the packages, and - as you won't be making any further use of pip they aren't required - - although it won't do any harm if you leave them. - -4. Package the application using: +3. Package the application using: .. code-block:: shell-session diff -Nru python3.12-3.12.0~rc2/Doc/reference/lexical_analysis.rst python3.12-3.12.0/Doc/reference/lexical_analysis.rst --- python3.12-3.12.0~rc2/Doc/reference/lexical_analysis.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/reference/lexical_analysis.rst 2023-10-02 11:48:14.000000000 +0000 @@ -557,51 +557,51 @@ bytes literals are interpreted according to rules similar to those used by Standard C. The recognized escape sequences are: -+-----------------+---------------------------------+-------+ -| Escape Sequence | Meaning | Notes | -+=================+=================================+=======+ -| ``\``\ | Backslash and newline ignored | \(1) | -+-----------------+---------------------------------+-------+ -| ``\\`` | Backslash (``\``) | | -+-----------------+---------------------------------+-------+ -| ``\'`` | Single quote (``'``) | | -+-----------------+---------------------------------+-------+ -| ``\"`` | Double quote (``"``) | | -+-----------------+---------------------------------+-------+ -| ``\a`` | ASCII Bell (BEL) | | -+-----------------+---------------------------------+-------+ -| ``\b`` | ASCII Backspace (BS) | | -+-----------------+---------------------------------+-------+ -| ``\f`` | ASCII Formfeed (FF) | | -+-----------------+---------------------------------+-------+ -| ``\n`` | ASCII Linefeed (LF) | | -+-----------------+---------------------------------+-------+ -| ``\r`` | ASCII Carriage Return (CR) | | -+-----------------+---------------------------------+-------+ -| ``\t`` | ASCII Horizontal Tab (TAB) | | -+-----------------+---------------------------------+-------+ -| ``\v`` | ASCII Vertical Tab (VT) | | -+-----------------+---------------------------------+-------+ -| ``\ooo`` | Character with octal value | (2,4) | -| | *ooo* | | -+-----------------+---------------------------------+-------+ -| ``\xhh`` | Character with hex value *hh* | (3,4) | -+-----------------+---------------------------------+-------+ ++-------------------------+---------------------------------+-------+ +| Escape Sequence | Meaning | Notes | ++=========================+=================================+=======+ +| ``\``\ | Backslash and newline ignored | \(1) | ++-------------------------+---------------------------------+-------+ +| ``\\`` | Backslash (``\``) | | ++-------------------------+---------------------------------+-------+ +| ``\'`` | Single quote (``'``) | | ++-------------------------+---------------------------------+-------+ +| ``\"`` | Double quote (``"``) | | ++-------------------------+---------------------------------+-------+ +| ``\a`` | ASCII Bell (BEL) | | ++-------------------------+---------------------------------+-------+ +| ``\b`` | ASCII Backspace (BS) | | ++-------------------------+---------------------------------+-------+ +| ``\f`` | ASCII Formfeed (FF) | | ++-------------------------+---------------------------------+-------+ +| ``\n`` | ASCII Linefeed (LF) | | ++-------------------------+---------------------------------+-------+ +| ``\r`` | ASCII Carriage Return (CR) | | ++-------------------------+---------------------------------+-------+ +| ``\t`` | ASCII Horizontal Tab (TAB) | | ++-------------------------+---------------------------------+-------+ +| ``\v`` | ASCII Vertical Tab (VT) | | ++-------------------------+---------------------------------+-------+ +| :samp:`\\\\{ooo}` | Character with octal value | (2,4) | +| | *ooo* | | ++-------------------------+---------------------------------+-------+ +| :samp:`\\x{hh}` | Character with hex value *hh* | (3,4) | ++-------------------------+---------------------------------+-------+ Escape sequences only recognized in string literals are: -+-----------------+---------------------------------+-------+ -| Escape Sequence | Meaning | Notes | -+=================+=================================+=======+ -| ``\N{name}`` | Character named *name* in the | \(5) | -| | Unicode database | | -+-----------------+---------------------------------+-------+ -| ``\uxxxx`` | Character with 16-bit hex value | \(6) | -| | *xxxx* | | -+-----------------+---------------------------------+-------+ -| ``\Uxxxxxxxx`` | Character with 32-bit hex value | \(7) | -| | *xxxxxxxx* | | -+-----------------+---------------------------------+-------+ ++-------------------------+---------------------------------+-------+ +| Escape Sequence | Meaning | Notes | ++=========================+=================================+=======+ +| :samp:`\\N\\{{name}\\}` | Character named *name* in the | \(5) | +| | Unicode database | | ++-------------------------+---------------------------------+-------+ +| :samp:`\\u{xxxx}` | Character with 16-bit hex value | \(6) | +| | *xxxx* | | ++-------------------------+---------------------------------+-------+ +| :samp:`\\U{xxxxxxxx}` | Character with 32-bit hex value | \(7) | +| | *xxxxxxxx* | | ++-------------------------+---------------------------------+-------+ Notes: diff -Nru python3.12-3.12.0~rc2/Doc/requirements-oldest-sphinx.txt python3.12-3.12.0/Doc/requirements-oldest-sphinx.txt --- python3.12-3.12.0~rc2/Doc/requirements-oldest-sphinx.txt 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/requirements-oldest-sphinx.txt 2023-10-02 11:48:14.000000000 +0000 @@ -7,12 +7,10 @@ python-docs-theme>=2022.1 # Generated from: -# pip install "Sphinx~=3.2.0" "docutils<0.17" "Jinja2<3" "MarkupSafe<2" +# pip install "Sphinx~=4.2.0" # pip freeze # -# Sphinx 3.2 comes from ``needs_sphinx = '3.2'`` in ``Doc/conf.py``. -# Docutils<0.17, Jinja2<3, and MarkupSafe<2 are additionally specified as -# Sphinx 3.2 is incompatible with newer releases of these packages. +# Sphinx 4.2 comes from ``needs_sphinx = '4.2'`` in ``Doc/conf.py``. alabaster==0.7.13 Babel==2.12.1 @@ -25,10 +23,10 @@ Jinja2==2.11.3 MarkupSafe==1.1.1 packaging==23.1 -Pygments==2.15.1 +Pygments==2.16.1 requests==2.31.0 snowballstemmer==2.2.0 -Sphinx==3.2.1 +Sphinx==4.2.0 sphinxcontrib-applehelp==1.0.4 sphinxcontrib-devhelp==1.0.2 sphinxcontrib-htmlhelp==2.0.1 diff -Nru python3.12-3.12.0~rc2/Doc/tools/.nitignore python3.12-3.12.0/Doc/tools/.nitignore --- python3.12-3.12.0~rc2/Doc/tools/.nitignore 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/tools/.nitignore 2023-10-02 11:48:14.000000000 +0000 @@ -60,8 +60,6 @@ Doc/library/datetime.rst Doc/library/dbm.rst Doc/library/decimal.rst -Doc/library/devmode.rst -Doc/library/difflib.rst Doc/library/doctest.rst Doc/library/email.charset.rst Doc/library/email.compat32-message.rst @@ -120,7 +118,6 @@ Doc/library/selectors.rst Doc/library/shelve.rst Doc/library/signal.rst -Doc/library/site.rst Doc/library/smtplib.rst Doc/library/socket.rst Doc/library/socketserver.rst @@ -129,7 +126,6 @@ Doc/library/string.rst Doc/library/subprocess.rst Doc/library/sunau.rst -Doc/library/sys_path_init.rst Doc/library/syslog.rst Doc/library/tarfile.rst Doc/library/telnetlib.rst @@ -143,19 +139,16 @@ Doc/library/tkinter.ttk.rst Doc/library/traceback.rst Doc/library/tty.rst -Doc/library/turtle.rst Doc/library/unittest.mock.rst Doc/library/unittest.rst Doc/library/urllib.parse.rst Doc/library/urllib.request.rst -Doc/library/weakref.rst Doc/library/webbrowser.rst Doc/library/wsgiref.rst Doc/library/xdrlib.rst Doc/library/xml.dom.minidom.rst Doc/library/xml.dom.pulldom.rst Doc/library/xml.dom.rst -Doc/library/xml.etree.elementtree.rst Doc/library/xml.rst Doc/library/xml.sax.handler.rst Doc/library/xml.sax.reader.rst @@ -168,11 +161,9 @@ Doc/reference/expressions.rst Doc/reference/import.rst Doc/reference/simple_stmts.rst -Doc/tutorial/controlflow.rst Doc/tutorial/datastructures.rst Doc/tutorial/introduction.rst Doc/using/cmdline.rst -Doc/using/configure.rst Doc/using/windows.rst Doc/whatsnew/2.0.rst Doc/whatsnew/2.1.rst diff -Nru python3.12-3.12.0~rc2/Doc/tools/templates/indexcontent.html python3.12-3.12.0/Doc/tools/templates/indexcontent.html --- python3.12-3.12.0~rc2/Doc/tools/templates/indexcontent.html 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/tools/templates/indexcontent.html 2023-10-02 11:48:14.000000000 +0000 @@ -62,6 +62,7 @@ + {% endblock %} diff -Nru python3.12-3.12.0~rc2/Doc/tutorial/controlflow.rst python3.12-3.12.0/Doc/tutorial/controlflow.rst --- python3.12-3.12.0~rc2/Doc/tutorial/controlflow.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/tutorial/controlflow.rst 2023-10-02 11:48:14.000000000 +0000 @@ -534,7 +534,7 @@ Different types define different methods. Methods of different types may have the same name without causing ambiguity. (It is possible to define your own object types and methods, using *classes*, see :ref:`tut-classes`) - The method :meth:`~list.append` shown in the example is defined for list objects; it + The method :meth:`!append` shown in the example is defined for list objects; it adds a new element at the end of the list. In this example it is equivalent to ``result = result + [a]``, but more efficient. @@ -1046,7 +1046,7 @@ information about the types used by user-defined functions (see :pep:`3107` and :pep:`484` for more information). -:term:`Annotations ` are stored in the :attr:`__annotations__` +:term:`Annotations ` are stored in the :attr:`!__annotations__` attribute of the function as a dictionary and have no effect on any other part of the function. Parameter annotations are defined by a colon after the parameter name, followed by an expression evaluating to the value of the annotation. Return annotations are diff -Nru python3.12-3.12.0~rc2/Doc/using/cmdline.rst python3.12-3.12.0/Doc/using/cmdline.rst --- python3.12-3.12.0~rc2/Doc/using/cmdline.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/using/cmdline.rst 2023-10-02 11:48:14.000000000 +0000 @@ -811,7 +811,7 @@ Defines the :data:`user base directory `, which is used to compute the path of the :data:`user site-packages directory ` - and installation paths for + and :ref:`installation paths ` for ``python -m pip install --user``. .. seealso:: diff -Nru python3.12-3.12.0~rc2/Doc/using/configure.rst python3.12-3.12.0/Doc/using/configure.rst --- python3.12-3.12.0~rc2/Doc/using/configure.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/using/configure.rst 2023-10-02 11:48:14.000000000 +0000 @@ -43,6 +43,29 @@ support". +Generated files +=============== + +To reduce build dependencies, Python source code contains multiple generated +files. Commands to regenerate all generated files:: + + make regen-all + make regen-stdlib-module-names + make regen-limited-abi + make regen-configure + +The ``Makefile.pre.in`` file documents generated files, their inputs, and tools used +to regenerate them. Search for ``regen-*`` make targets. + +The ``make regen-configure`` command runs `tiran/cpython_autoconf +`_ container for reproducible build; +see container ``entry.sh`` script. The container is optional, the following +command can be run locally, the generated files depend on autoconf and aclocal +versions:: + + autoreconf -ivf -Werror + + .. _configure-options: Configure Options @@ -59,8 +82,8 @@ .. cmdoption:: --enable-loadable-sqlite-extensions - Support loadable extensions in the :mod:`_sqlite` extension module (default - is no). + Support loadable extensions in the :mod:`!_sqlite` extension module (default + is no) of the :mod:`sqlite3` module. See the :meth:`sqlite3.Connection.enable_load_extension` method of the :mod:`sqlite3` module. @@ -158,7 +181,7 @@ Some Linux distribution packaging policies recommend against bundling dependencies. For example, Fedora installs wheel packages in the ``/usr/share/python-wheels/`` directory and don't install the - :mod:`ensurepip._bundled` package. + :mod:`!ensurepip._bundled` package. .. versionadded:: 3.10 @@ -235,7 +258,7 @@ .. cmdoption:: --disable-test-modules Don't build nor install test modules, like the :mod:`test` package or the - :mod:`_testcapi` extension module (built and installed by default). + :mod:`!_testcapi` extension module (built and installed by default). .. versionadded:: 3.10 @@ -368,7 +391,7 @@ * Display all warnings by default: the list of default warning filters is empty in the :mod:`warnings` module. * Add ``d`` to :data:`sys.abiflags`. -* Add :func:`sys.gettotalrefcount` function. +* Add :func:`!sys.gettotalrefcount` function. * Add :option:`-X showrefcount <-X>` command line option. * Add :option:`-d` command line option and :envvar:`PYTHONDEBUG` environment variable to debug the parser. @@ -390,7 +413,7 @@ * Check that deallocator functions don't change the current exception. * The garbage collector (:func:`gc.collect` function) runs some basic checks on objects consistency. - * The :c:macro:`Py_SAFE_DOWNCAST()` macro checks for integer underflow and + * The :c:macro:`!Py_SAFE_DOWNCAST()` macro checks for integer underflow and overflow when downcasting from wide types to narrow types. See also the :ref:`Python Development Mode ` and the @@ -418,7 +441,7 @@ Effects: * Define the ``Py_TRACE_REFS`` macro. - * Add :func:`sys.getobjects` function. + * Add :func:`!sys.getobjects` function. * Add :envvar:`PYTHONDUMPREFS` environment variable. This build is not ABI compatible with release build (default build) or debug @@ -496,7 +519,7 @@ .. cmdoption:: --with-system-expat - Build the :mod:`pyexpat` module using an installed ``expat`` library + Build the :mod:`!pyexpat` module using an installed ``expat`` library (default is no). .. cmdoption:: --with-system-libmpdec @@ -746,15 +769,15 @@ At the beginning of the files, C extensions are built as built-in modules. Extensions defined after the ``*shared*`` marker are built as dynamic libraries. -The :c:macro:`PyAPI_FUNC()`, :c:macro:`PyAPI_DATA()` and -:c:macro:`PyMODINIT_FUNC` macros of :file:`Include/pyport.h` are defined +The :c:macro:`!PyAPI_FUNC()`, :c:macro:`!PyAPI_DATA()` and +:c:macro:`PyMODINIT_FUNC` macros of :file:`Include/exports.h` are defined differently depending if the ``Py_BUILD_CORE_MODULE`` macro is defined: * Use ``Py_EXPORTED_SYMBOL`` if the ``Py_BUILD_CORE_MODULE`` is defined * Use ``Py_IMPORTED_SYMBOL`` otherwise. If the ``Py_BUILD_CORE_BUILTIN`` macro is used by mistake on a C extension -built as a shared library, its ``PyInit_xxx()`` function is not exported, +built as a shared library, its :samp:`PyInit_{xxx}()` function is not exported, causing an :exc:`ImportError` on import. @@ -775,8 +798,8 @@ .. envvar:: CPPFLAGS - (Objective) C/C++ preprocessor flags, e.g. ``-I`` if you have - headers in a nonstandard directory ````. + (Objective) C/C++ preprocessor flags, e.g. :samp:`-I{include_dir}` if you have + headers in a nonstandard directory *include_dir*. Both :envvar:`CPPFLAGS` and :envvar:`LDFLAGS` need to contain the shell's value to be able to build extension modules using the @@ -965,8 +988,8 @@ .. envvar:: LDFLAGS - Linker flags, e.g. ``-L`` if you have libraries in a nonstandard - directory ````. + Linker flags, e.g. :samp:`-L{lib_dir}` if you have libraries in a nonstandard + directory *lib_dir*. Both :envvar:`CPPFLAGS` and :envvar:`LDFLAGS` need to contain the shell's value to be able to build extension modules using the diff -Nru python3.12-3.12.0~rc2/Doc/using/unix.rst python3.12-3.12.0/Doc/using/unix.rst --- python3.12-3.12.0~rc2/Doc/using/unix.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/using/unix.rst 2023-10-02 11:48:14.000000000 +0000 @@ -30,9 +30,9 @@ for Debian users https://en.opensuse.org/Portal:Packaging for OpenSuse users - https://docs-old.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch-creating-rpms.html + https://docs.fedoraproject.org/en-US/package-maintainers/Packaging_Tutorial_GNU_Hello/ for Fedora users - http://www.slackbook.org/html/package-management-making-packages.html + https://slackbook.org/html/package-management-making-packages.html for Slackware users diff -Nru python3.12-3.12.0~rc2/Doc/using/windows.rst python3.12-3.12.0/Doc/using/windows.rst --- python3.12-3.12.0~rc2/Doc/using/windows.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/using/windows.rst 2023-10-02 11:48:14.000000000 +0000 @@ -889,7 +889,7 @@ The "-64" suffix is deprecated, and now implies "any architecture that is not provably i386/32-bit". To request a specific environment, use the new - ``-V:`` argument with the complete tag. + :samp:`-V:{TAG}` argument with the complete tag. The ``/usr/bin/env`` form of shebang line has one further special property. Before looking for installed Python interpreters, this form will search the @@ -1192,7 +1192,7 @@ * Adds ``._pth`` file support and removes ``applocal`` option from ``pyvenv.cfg``. - * Adds ``pythonXX.zip`` as a potential landmark when directly adjacent + * Adds :file:`python{XX}.zip` as a potential landmark when directly adjacent to the executable. .. deprecated:: diff -Nru python3.12-3.12.0~rc2/Doc/whatsnew/2.0.rst python3.12-3.12.0/Doc/whatsnew/2.0.rst --- python3.12-3.12.0~rc2/Doc/whatsnew/2.0.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/whatsnew/2.0.rst 2023-10-02 11:48:14.000000000 +0000 @@ -153,9 +153,9 @@ significant points about the Unicode interfaces. In Python source code, Unicode strings are written as ``u"string"``. Arbitrary -Unicode characters can be written using a new escape sequence, ``\uHHHH``, where +Unicode characters can be written using a new escape sequence, :samp:`\\u{HHHH}`, where *HHHH* is a 4-digit hexadecimal number from 0000 to FFFF. The existing -``\xHHHH`` escape sequence can also be used, and octal escapes can be used for +:samp:`\\x{HH}` escape sequence can also be used, and octal escapes can be used for characters up to U+01FF, which is represented by ``\777``. Unicode strings, just like regular strings, are an immutable sequence type. diff -Nru python3.12-3.12.0~rc2/Doc/whatsnew/2.3.rst python3.12-3.12.0/Doc/whatsnew/2.3.rst --- python3.12-3.12.0~rc2/Doc/whatsnew/2.3.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/whatsnew/2.3.rst 2023-10-02 11:48:14.000000000 +0000 @@ -1889,7 +1889,7 @@ * The :c:macro:`!DL_EXPORT` and :c:macro:`!DL_IMPORT` macros are now deprecated. Initialization functions for Python extension modules should now be declared using the new macro :c:macro:`PyMODINIT_FUNC`, while the Python core will - generally use the :c:macro:`PyAPI_FUNC` and :c:macro:`PyAPI_DATA` macros. + generally use the :c:macro:`!PyAPI_FUNC` and :c:macro:`!PyAPI_DATA` macros. * The interpreter can be compiled without any docstrings for the built-in functions and modules by supplying :option:`!--without-doc-strings` to the diff -Nru python3.12-3.12.0~rc2/Doc/whatsnew/2.6.rst python3.12-3.12.0/Doc/whatsnew/2.6.rst --- python3.12-3.12.0~rc2/Doc/whatsnew/2.6.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/whatsnew/2.6.rst 2023-10-02 11:48:14.000000000 +0000 @@ -125,7 +125,7 @@ .. seealso:: - The 3xxx series of PEPs, which contains proposals for Python 3.0. + The 3\ *xxx* series of PEPs, which contains proposals for Python 3.0. :pep:`3000` describes the development process for Python 3.0. Start with :pep:`3100` that describes the general goals for Python 3.0, and then explore the higher-numbered PEPS that propose @@ -1850,8 +1850,8 @@ special values and floating-point exceptions in a manner consistent with Annex 'G' of the C99 standard. -* A new data type in the :mod:`collections` module: :class:`namedtuple(typename, - fieldnames)` is a factory function that creates subclasses of the standard tuple +* A new data type in the :mod:`collections` module: ``namedtuple(typename, fieldnames)`` + is a factory function that creates subclasses of the standard tuple whose fields are accessible by name as well as index. For example:: >>> var_type = collections.namedtuple('variable', @@ -1873,7 +1873,7 @@ variable(id=1, name='amplitude', type='int', size=4) Several places in the standard library that returned tuples have - been modified to return :class:`namedtuple` instances. For example, + been modified to return :func:`namedtuple` instances. For example, the :meth:`Decimal.as_tuple` method now returns a named tuple with :attr:`sign`, :attr:`digits`, and :attr:`exponent` fields. diff -Nru python3.12-3.12.0~rc2/Doc/whatsnew/3.10.rst python3.12-3.12.0/Doc/whatsnew/3.10.rst --- python3.12-3.12.0~rc2/Doc/whatsnew/3.10.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/whatsnew/3.10.rst 2023-10-02 11:48:14.000000000 +0000 @@ -878,7 +878,7 @@ (Contributed by Raymond Hettinger in :issue:`43475`.) * A :exc:`SyntaxError` (instead of a :exc:`NameError`) will be raised when deleting - the :const:`__debug__` constant. (Contributed by Dong-hee Na in :issue:`45000`.) + the :const:`__debug__` constant. (Contributed by Donghee Na in :issue:`45000`.) * :exc:`SyntaxError` exceptions now have ``end_lineno`` and ``end_offset`` attributes. They will be ``None`` if not determined. @@ -1255,7 +1255,7 @@ Add :const:`~os.O_EVTONLY`, :const:`~os.O_FSYNC`, :const:`~os.O_SYMLINK` and :const:`~os.O_NOFOLLOW_ANY` for macOS. -(Contributed by Dong-hee Na in :issue:`43106`.) +(Contributed by Donghee Na in :issue:`43106`.) os.path ------- @@ -1582,7 +1582,7 @@ * The following built-in functions now support the faster :pep:`590` vectorcall calling convention: :func:`map`, :func:`filter`, :func:`reversed`, :func:`bool` and :func:`float`. - (Contributed by Dong-hee Na and Jeroen Demeyer in :issue:`43575`, :issue:`43287`, :issue:`41922`, :issue:`41873` and :issue:`41870`.) + (Contributed by Donghee Na and Jeroen Demeyer in :issue:`43575`, :issue:`43287`, :issue:`41922`, :issue:`41873` and :issue:`41870`.) * :class:`BZ2File` performance is improved by removing internal ``RLock``. This makes :class:`BZ2File` thread unsafe in the face of multiple simultaneous @@ -1817,7 +1817,7 @@ scheduled to be removed in Python 3.6, but such removals were delayed until after Python 2.7 EOL. Existing users should copy whatever classes they use into their code. - (Contributed by Dong-hee Na and Terry J. Reedy in :issue:`42299`.) + (Contributed by Donghee Na and Terry J. Reedy in :issue:`42299`.) * Removed the :c:func:`!PyModule_GetWarningsModule` function that was useless now due to the :mod:`!_warnings` module was converted to a builtin module in 2.6. diff -Nru python3.12-3.12.0~rc2/Doc/whatsnew/3.11.rst python3.12-3.12.0/Doc/whatsnew/3.11.rst --- python3.12-3.12.0~rc2/Doc/whatsnew/3.11.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/whatsnew/3.11.rst 2023-10-02 11:48:14.000000000 +0000 @@ -45,7 +45,7 @@ when researching a change. This article explains the new features in Python 3.11, compared to 3.10. - +Python 3.11 was released on October 24, 2022. For full details, see the :ref:`changelog `. @@ -218,7 +218,7 @@ The copy of the :ref:`launcher` included with Python 3.11 has been significantly updated. It now supports company/tag syntax as defined in :pep:`514` using the -``-V:/`` argument instead of the limited ``-.``. +:samp:`-V:{}/{}` argument instead of the limited :samp:`-{}.{}`. This allows launching distributions other than ``PythonCore``, the one hosted on `python.org `_. @@ -227,8 +227,8 @@ "best" tag registered for ``OtherPython``, while ``-V:3.11`` or ``-V:/3.11`` will select the "best" distribution with tag ``3.11``. -When using the legacy ``-``, ``-.``, -``--`` or ``-.-`` arguments, +When using the legacy :samp:`-{}`, :samp:`-{}.{}`, +:samp:`-{}-{}` or :samp:`-{}.{}-{}` arguments, all existing behaviour should be preserved from past versions, and only releases from ``PythonCore`` will be selected. However, the ``-64`` suffix now implies "not 32-bit" (not necessarily x86-64), @@ -499,7 +499,7 @@ * The special methods :meth:`~object.__complex__` for :class:`complex` and :meth:`~object.__bytes__` for :class:`bytes` are implemented to support the :class:`typing.SupportsComplex` and :class:`typing.SupportsBytes` protocols. - (Contributed by Mark Dickinson and Dong-hee Na in :issue:`24234`.) + (Contributed by Mark Dickinson and Donghee Na in :issue:`24234`.) * ``siphash13`` is added as a new internal hashing algorithm. It has similar security properties as ``siphash24``, @@ -897,7 +897,7 @@ * On Windows, :func:`os.urandom` now uses ``BCryptGenRandom()``, instead of ``CryptGenRandom()`` which is deprecated. - (Contributed by Dong-hee Na in :issue:`44611`.) + (Contributed by Donghee Na in :issue:`44611`.) .. _whatsnew311-pathlib: @@ -1089,7 +1089,7 @@ `_ which has a resolution of 100 nanoseconds (10\ :sup:`-7` seconds). Previously, it had a resolution of 1 millisecond (10\ :sup:`-3` seconds). - (Contributed by Benjamin SzÅ‘ke, Dong-hee Na, Eryk Sun and Victor Stinner in :issue:`21302` and :issue:`45429`.) + (Contributed by Benjamin SzÅ‘ke, Donghee Na, Eryk Sun and Victor Stinner in :issue:`21302` and :issue:`45429`.) .. _whatsnew311-tkinter: @@ -1305,7 +1305,7 @@ * :func:`unicodedata.normalize` now normalizes pure-ASCII strings in constant time. - (Contributed by Dong-hee Na in :issue:`44987`.) + (Contributed by Donghee Na in :issue:`44987`.) .. _whatsnew311-faster-cpython: @@ -1452,7 +1452,7 @@ | | | | (up to) | | +===============+====================+=======================================================+===================+===================+ | Binary | ``x + x`` | Binary add, multiply and subtract for common types | 10% | Mark Shannon, | -| operations | | such as :class:`int`, :class:`float` and :class:`str` | | Dong-hee Na, | +| operations | | such as :class:`int`, :class:`float` and :class:`str` | | Donghee Na, | | | ``x - x`` | take custom fast paths for their underlying types. | | Brandt Bucher, | | | | | | Dennis Sweeney | | | ``x * x`` | | | | @@ -1839,7 +1839,7 @@ * :class:`!webbrowser.MacOSX` is deprecated and will be removed in Python 3.13. It is untested, undocumented, and not used by :mod:`webbrowser` itself. - (Contributed by Dong-hee Na in :issue:`42255`.) + (Contributed by Donghee Na in :issue:`42255`.) * The behavior of returning a value from a :class:`~unittest.TestCase` and :class:`~unittest.IsolatedAsyncioTestCase` test methods (other than the @@ -1984,7 +1984,7 @@ :meth:`!NullTranslations.set_output_charset` methods, and the *codeset* parameter of :func:`!translation` and :func:`!install`, since they are only used for the :func:`!l*gettext` functions. - (Contributed by Dong-hee Na and Serhiy Storchaka in :issue:`44235`.) + (Contributed by Donghee Na and Serhiy Storchaka in :issue:`44235`.) * Removed from the :mod:`inspect` module: @@ -2009,7 +2009,7 @@ * Removed the :class:`!MailmanProxy` class in the :mod:`smtpd` module, as it is unusable without the external :mod:`!mailman` package. - (Contributed by Dong-hee Na in :issue:`35800`.) + (Contributed by Donghee Na in :issue:`35800`.) * Removed the deprecated :meth:`!split` method of :class:`!_tkinter.TkappType`. (Contributed by Erlend E. Aasland in :issue:`38371`.) @@ -2151,7 +2151,7 @@ * CPython can now be built with the `ThinLTO `_ option via passing ``thin`` to :option:`--with-lto`, i.e. ``--with-lto=thin``. - (Contributed by Dong-hee Na and Brett Holman in :issue:`44340`.) + (Contributed by Donghee Na and Brett Holman in :issue:`44340`.) * Freelists for object structs can now be disabled. A new :program:`configure` option :option:`--without-freelists` can be used to disable all freelists diff -Nru python3.12-3.12.0~rc2/Doc/whatsnew/3.12.rst python3.12-3.12.0/Doc/whatsnew/3.12.rst --- python3.12-3.12.0~rc2/Doc/whatsnew/3.12.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/whatsnew/3.12.rst 2023-10-02 11:48:14.000000000 +0000 @@ -3,8 +3,7 @@ What's New In Python 3.12 **************************** -:Release: |release| -:Date: |today| +:Editor: Adam Turner .. Rules for maintenance: @@ -47,15 +46,12 @@ researching a change. This article explains the new features in Python 3.12, compared to 3.11. - +Python 3.12 was released on October 2, 2023. For full details, see the :ref:`changelog `. -.. note:: - - Prerelease users should be aware that this document is currently in draft - form. It will be updated substantially as Python 3.12 moves towards release, - so it's worth checking back even after reading earlier versions. +.. seealso:: + :pep:`693` -- Python 3.12 Release Schedule Summary -- Release highlights ============================= @@ -63,104 +59,198 @@ .. This section singles out the most important changes in Python 3.12. Brevity is key. +Python 3.12 is the latest stable release of the Python programming language, +with a mix of changes to the language and the standard library. +The library changes focus on cleaning up deprecated APIs, usability, and correctness. +Of note, the :mod:`!distutils` package has been removed from the standard library. +Filesystem support in :mod:`os` and :mod:`pathlib` has seen a number of improvements, +and several modules have better performance. + +The language changes focus on usability, +as :term:`f-strings ` have had many limitations removed +and 'Did you mean ...' suggestions continue to improve. +The new :ref:`type parameter syntax ` +and :keyword:`type` statement improve ergonomics for using :term:`generic types +` and :term:`type aliases ` with static type checkers. + +This article doesn't attempt to provide a complete specification of all new features, +but instead gives a convenient overview. +For full details, you should refer to the documentation, +such as the :ref:`Library Reference ` +and :ref:`Language Reference `. +If you want to understand the complete implementation and design rationale for a change, +refer to the PEP for a particular new feature; +but note that PEPs usually are not kept up-to-date +once a feature has been fully implemented. + +-------------- .. PEP-sized items next. +New syntax features: + +* :ref:`PEP 695 `, type parameter syntax and the :keyword:`type` statement + New grammar features: -* :ref:`whatsnew312-pep701` +* :ref:`PEP 701 `, :term:`f-strings ` in the grammar Interpreter improvements: -* :ref:`whatsnew312-pep684` - -* :ref:`whatsnew312-pep669` +* :ref:`PEP 684 `, a unique per-interpreter :term:`GIL + ` +* :ref:`PEP 669 `, low impact monitoring +* `Improved 'Did you mean ...' suggestions `_ + for :exc:`NameError`, :exc:`ImportError`, and :exc:`SyntaxError` exceptions + +Python data model improvements: + +* :ref:`PEP 688 `, using the :ref:`buffer protocol + ` from Python + +Significant improvements in the standard library: + +* The :class:`pathlib.Path` class now supports subclassing +* The :mod:`os` module received several improvements for Windows support +* A :ref:`command-line interface ` has been added to the + :mod:`sqlite3` module +* :func:`isinstance` checks against :func:`runtime-checkable protocols + ` enjoy a speed up of between two and 20 times +* The :mod:`asyncio` package has had a number of performance improvements, + with some benchmarks showing a 75% speed up. +* A :ref:`command-line interface ` has been added to the + :mod:`uuid` module +* Due to the changes in :ref:`PEP 701 `, + producing tokens via the :mod:`tokenize` module is up to up to 64% faster. + +Security improvements: + +* Replace the builtin :mod:`hashlib` implementations of + SHA1, SHA3, SHA2-384, SHA2-512, and MD5 with formally verified code from the + `HACL* `__ project. + These builtin implementations remain as fallbacks that are only used when + OpenSSL does not provide them. + +C API improvements: + +* :ref:`PEP 697 `, unstable C API tier +* :ref:`PEP 683 `, immortal objects + +CPython implementation improvements: + +* :ref:`PEP 709 `, comprehension inlining +* :ref:`CPython support ` for the Linux ``perf`` profiler +* Implement stack overflow protection on supported platforms New typing features: -* :ref:`whatsnew312-pep688` +* :ref:`PEP 692 `, using :class:`~typing.TypedDict` to + annotate :term:`**kwargs ` +* :ref:`PEP 698 `, :func:`typing.override` decorator -* :ref:`whatsnew312-pep692` +Important deprecations, removals or restrictions: -* :ref:`whatsnew312-pep695` +* :pep:`623`: Remove ``wstr`` from Unicode objects in Python's C API, + reducing the size of every :class:`str` object by at least 8 bytes. -* :ref:`whatsnew312-pep698` +* :pep:`632`: Remove the :mod:`!distutils` package. + See `the migration guide `_ + for advice replacing the APIs it provided. + The third-party `Setuptools `__ + package continues to provide :mod:`!distutils`, + if you still require it in Python 3.12 and beyond. + +* :gh:`95299`: Do not pre-install ``setuptools`` in virtual environments + created with :mod:`venv`. + This means that ``distutils``, ``setuptools``, ``pkg_resources``, + and ``easy_install`` will no longer available by default; to access these + run ``pip install setuptools`` in the :ref:`activated ` + virtual environment. + +* The :mod:`!asynchat`, :mod:`!asyncore`, and :mod:`!imp` modules have been + removed, along with several :class:`unittest.TestCase` + `method aliases `_. -Important deprecations, removals or restrictions: -* :pep:`623`: Remove wstr from Unicode +New Features +============ -* :pep:`632`: Remove the ``distutils`` package. See - `the migration guide `_ - for advice on its replacement. +.. _whatsnew312-pep695: -Improved Error Messages -======================= +PEP 695: Type Parameter Syntax +------------------------------ -* Modules from the standard library are now potentially suggested as part of - the error messages displayed by the interpreter when a :exc:`NameError` is - raised to the top level. Contributed by Pablo Galindo in :gh:`98254`. +Generic classes and functions under :pep:`484` were declared using a verbose syntax +that left the scope of type parameters unclear and required explicit declarations of +variance. - >>> sys.version_info - Traceback (most recent call last): - File "", line 1, in - NameError: name 'sys' is not defined. Did you forget to import 'sys'? +:pep:`695` introduces a new, more compact and explicit way to create +:ref:`generic classes ` and :ref:`functions `:: -* Improve the error suggestion for :exc:`NameError` exceptions for instances. - Now if a :exc:`NameError` is raised in a method and the instance has an - attribute that's exactly equal to the name in the exception, the suggestion - will include ``self.`` instead of the closest match in the method - scope. Contributed by Pablo Galindo in :gh:`99139`. + def max[T](args: Iterable[T]) -> T: + ... - >>> class A: - ... def __init__(self): - ... self.blech = 1 - ... - ... def foo(self): - ... somethin = blech + class list[T]: + def __getitem__(self, index: int, /) -> T: + ... - >>> A().foo() - Traceback (most recent call last): - File "", line 1 - somethin = blech - ^^^^^ - NameError: name 'blech' is not defined. Did you mean: 'self.blech'? + def append(self, element: T) -> None: + ... +In addition, the PEP introduces a new way to declare :ref:`type aliases ` +using the :keyword:`type` statement, which creates an instance of +:class:`~typing.TypeAliasType`:: -* Improve the :exc:`SyntaxError` error message when the user types ``import x - from y`` instead of ``from y import x``. Contributed by Pablo Galindo in :gh:`98931`. + type Point = tuple[float, float] - >>> import a.y.z from b.y.z - Traceback (most recent call last): - File "", line 1 - import a.y.z from b.y.z - ^^^^^^^^^^^^^^^^^^^^^^^ - SyntaxError: Did you mean to use 'from ... import ...' instead? +Type aliases can also be :ref:`generic `:: -* :exc:`ImportError` exceptions raised from failed ``from import - `` statements now include suggestions for the value of ```` based on the - available names in ````. Contributed by Pablo Galindo in :gh:`91058`. + type Point[T] = tuple[T, T] - >>> from collections import chainmap - Traceback (most recent call last): - File "", line 1, in - ImportError: cannot import name 'chainmap' from 'collections'. Did you mean: 'ChainMap'? +The new syntax allows declaring :class:`~typing.TypeVarTuple` +and :class:`~typing.ParamSpec` parameters, as well as :class:`~typing.TypeVar` +parameters with bounds or constraints:: + type IntFunc[**P] = Callable[P, int] # ParamSpec + type LabeledTuple[*Ts] = tuple[str, *Ts] # TypeVarTuple + type HashableSequence[T: Hashable] = Sequence[T] # TypeVar with bound + type IntOrStrSequence[T: (int, str)] = Sequence[T] # TypeVar with constraints -New Features -============ +The value of type aliases and the bound and constraints of type variables +created through this syntax are evaluated only on demand (see +:ref:`lazy evaluation `). This means type aliases are able to +refer to other types defined later in the file. + +Type parameters declared through a type parameter list are visible within the +scope of the declaration and any nested scopes, but not in the outer scope. For +example, they can be used in the type annotations for the methods of a generic +class or in the class body. However, they cannot be used in the module scope after +the class is defined. See :ref:`type-params` for a detailed description of the +runtime semantics of type parameters. + +In order to support these scoping semantics, a new kind of scope is introduced, +the :ref:`annotation scope `. Annotation scopes behave for the +most part like function scopes, but interact differently with enclosing class scopes. +In Python 3.13, :term:`annotations ` will also be evaluated in +annotation scopes. + +See :pep:`695` for more details. + +(PEP written by Eric Traut. Implementation by Jelle Zijlstra, Eric Traut, +and others in :gh:`103764`.) .. _whatsnew312-pep701: PEP 701: Syntactic formalization of f-strings --------------------------------------------- -:pep:`701` lifts some restrictions on the usage of f-strings. Expression components -inside f-strings can now be any valid Python expression including backslashes, -unicode escaped sequences, multi-line expressions, comments and strings reusing the -same quote as the containing f-string. Let's cover these in detail: +:pep:`701` lifts some restrictions on the usage of :term:`f-strings `. +Expression components inside f-strings can now be any valid Python expression, +including strings reusing the same quote as the containing f-string, +multi-line expressions, comments, backslashes, and unicode escape sequences. +Let's cover these in detail: -* Quote reuse: in Python 3.11, reusing the same quotes as the containing f-string +* Quote reuse: in Python 3.11, reusing the same quotes as the enclosing f-string raises a :exc:`SyntaxError`, forcing the user to either use other available quotes (like using double quotes or triple quotes if the f-string uses single quotes). In Python 3.12, you can now do things like this: @@ -183,11 +273,12 @@ >>> f"{f"{f"{f"{f"{f"{1+1}"}"}"}"}"}" '2' -* Multi-line expressions and comments: In Python 3.11, f-strings expressions - must be defined in a single line even if outside f-strings expressions could - span multiple lines (like literal lists being defined over multiple lines), - making them harder to read. In Python 3.12 you can now define expressions - spanning multiple lines and include comments on them: +* Multi-line expressions and comments: In Python 3.11, f-string expressions + must be defined in a single line, even if the expression within the f-string + could normally span multiple lines + (like literal lists being defined over multiple lines), + making them harder to read. In Python 3.12 you can now define f-strings + spanning multiple lines, and add inline comments: >>> f"This is the playlist: {", ".join([ ... 'Take me back to Eden', # My, my, those eyes like fire @@ -197,10 +288,10 @@ 'This is the playlist: Take me back to Eden, Alkaline, Ascensionism' * Backslashes and unicode characters: before Python 3.12 f-string expressions - couldn't contain any ``\`` character. This also affected unicode escaped - sequences (such as ``\N{snowman}``) as these contain the ``\N`` part that - previously could not be part of expression components of f-strings. Now, you - can define expressions like this: + couldn't contain any ``\`` character. This also affected unicode :ref:`escape + sequences ` (such as ``\N{snowman}``) as these contain + the ``\N`` part that previously could not be part of expression components of + f-strings. Now, you can define expressions like this: >>> print(f"This is the playlist: {"\n".join(songs)}") This is the playlist: Take me back to Eden @@ -212,7 +303,7 @@ See :pep:`701` for more details. As a positive side-effect of how this feature has been implemented (by parsing f-strings -with the PEG parser (see :pep:`617`), now error messages for f-strings are more precise +with :pep:`the PEG parser <617>`, now error messages for f-strings are more precise and include the exact location of the error. For example, in Python 3.11, the following f-string raises a :exc:`SyntaxError`: @@ -240,59 +331,16 @@ Maureira-Fredes and Marta GĂ³mez in :gh:`102856`. PEP written by Pablo Galindo, Batuhan Taskaya, Lysandros Nikolaou and Marta GĂ³mez). -.. _whatsnew312-pep709: - -PEP 709: Comprehension inlining -------------------------------- - -Dictionary, list, and set comprehensions are now inlined, rather than creating a -new single-use function object for each execution of the comprehension. This -speeds up execution of a comprehension by up to 2x. - -Comprehension iteration variables remain isolated; they don't overwrite a -variable of the same name in the outer scope, nor are they visible after the -comprehension. This isolation is now maintained via stack/locals manipulation, -not via separate function scope. - -Inlining does result in a few visible behavior changes: - -* There is no longer a separate frame for the comprehension in tracebacks, - and tracing/profiling no longer shows the comprehension as a function call. -* Calling :func:`locals` inside a comprehension now includes variables - from outside the comprehension, and no longer includes the synthetic ``.0`` - variable for the comprehension "argument". -* A comprehension iterating directly over ``locals()`` (e.g. ``[k for k in - locals()]``) may see "RuntimeError: dictionary changed size during iteration" - when run under tracing (e.g. code coverage measurement). This is the same - behavior already seen in e.g. ``for k in locals():``. To avoid the error, first - create a list of keys to iterate over: ``keys = list(locals()); [k for k in - keys]``. - -Contributed by Carl Meyer and Vladimir Matveev in :pep:`709`. - -.. _whatsnew312-pep688: - -PEP 688: Making the buffer protocol accessible in Python --------------------------------------------------------- - -:pep:`688` introduces a way to use the :ref:`buffer protocol ` -from Python code. Classes that implement the :meth:`~object.__buffer__` method -are now usable as buffer types. - -The new :class:`collections.abc.Buffer` ABC provides a standard -way to represent buffer objects, for example in type annotations. -The new :class:`inspect.BufferFlags` enum represents the flags that -can be used to customize buffer creation. -(Contributed by Jelle Zijlstra in :gh:`102500`.) - .. _whatsnew312-pep684: PEP 684: A Per-Interpreter GIL ------------------------------ -Sub-interpreters may now be created with a unique GIL per interpreter. +:pep:`684` introduces a per-interpreter :term:`GIL `, +so that sub-interpreters may now be created with a unique GIL per interpreter. This allows Python programs to take full advantage of multiple CPU -cores. +cores. This is currently only available through the C-API, +though a Python API is :pep:`anticipated for 3.13 <554>`. Use the new :c:func:`Py_NewInterpreterFromConfig` function to create an interpreter with its own GIL:: @@ -311,8 +359,6 @@ For further examples how to use the C-API for sub-interpreters with a per-interpreter GIL, see :source:`Modules/_xxsubinterpretersmodule.c`. -A Python API is anticipated for 3.13. (See :pep:`554`.) - (Contributed by Eric Snow in :gh:`104210`, etc.) .. _whatsnew312-pep669: @@ -320,18 +366,118 @@ PEP 669: Low impact monitoring for CPython ------------------------------------------ -CPython 3.12 now supports the ability to monitor calls, -returns, lines, exceptions and other events using instrumentation. +:pep:`669` defines a new :mod:`API ` for profilers, +debuggers, and other tools to monitor events in CPython. +It covers a wide range of events, including calls, +returns, lines, exceptions, jumps, and more. This means that you only pay for what you use, providing support for near-zero overhead debuggers and coverage tools. - See :mod:`sys.monitoring` for details. +(Contributed by Mark Shannon in :gh:`103082`.) + +.. _whatsnew312-pep688: + +PEP 688: Making the buffer protocol accessible in Python +-------------------------------------------------------- + +:pep:`688` introduces a way to use the :ref:`buffer protocol ` +from Python code. Classes that implement the :meth:`~object.__buffer__` method +are now usable as buffer types. + +The new :class:`collections.abc.Buffer` ABC provides a standard +way to represent buffer objects, for example in type annotations. +The new :class:`inspect.BufferFlags` enum represents the flags that +can be used to customize buffer creation. +(Contributed by Jelle Zijlstra in :gh:`102500`.) + +.. _whatsnew312-pep709: + +PEP 709: Comprehension inlining +------------------------------- + +Dictionary, list, and set comprehensions are now inlined, rather than creating a +new single-use function object for each execution of the comprehension. This +speeds up execution of a comprehension by up to two times. +See :pep:`709` for further details. + +Comprehension iteration variables remain isolated and don't overwrite a +variable of the same name in the outer scope, nor are they visible after the +comprehension. Inlining does result in a few visible behavior changes: + +* There is no longer a separate frame for the comprehension in tracebacks, + and tracing/profiling no longer shows the comprehension as a function call. +* The :mod:`symtable` module will no longer produce child symbol tables for each + comprehension; instead, the comprehension's locals will be included in the + parent function's symbol table. +* Calling :func:`locals` inside a comprehension now includes variables + from outside the comprehension, and no longer includes the synthetic ``.0`` + variable for the comprehension "argument". +* A comprehension iterating directly over ``locals()`` (e.g. ``[k for k in + locals()]``) may see "RuntimeError: dictionary changed size during iteration" + when run under tracing (e.g. code coverage measurement). This is the same + behavior already seen in e.g. ``for k in locals():``. To avoid the error, first + create a list of keys to iterate over: ``keys = list(locals()); [k for k in + keys]``. + +(Contributed by Carl Meyer and Vladimir Matveev in :pep:`709`.) + +Improved Error Messages +----------------------- + +* Modules from the standard library are now potentially suggested as part of + the error messages displayed by the interpreter when a :exc:`NameError` is + raised to the top level. (Contributed by Pablo Galindo in :gh:`98254`.) + + >>> sys.version_info + Traceback (most recent call last): + File "", line 1, in + NameError: name 'sys' is not defined. Did you forget to import 'sys'? + +* Improve the error suggestion for :exc:`NameError` exceptions for instances. + Now if a :exc:`NameError` is raised in a method and the instance has an + attribute that's exactly equal to the name in the exception, the suggestion + will include ``self.`` instead of the closest match in the method + scope. (Contributed by Pablo Galindo in :gh:`99139`.) + + >>> class A: + ... def __init__(self): + ... self.blech = 1 + ... + ... def foo(self): + ... somethin = blech + ... + >>> A().foo() + Traceback (most recent call last): + File "", line 1 + somethin = blech + ^^^^^ + NameError: name 'blech' is not defined. Did you mean: 'self.blech'? + +* Improve the :exc:`SyntaxError` error message when the user types ``import x + from y`` instead of ``from y import x``. (Contributed by Pablo Galindo in :gh:`98931`.) + + >>> import a.y.z from b.y.z + Traceback (most recent call last): + File "", line 1 + import a.y.z from b.y.z + ^^^^^^^^^^^^^^^^^^^^^^^ + SyntaxError: Did you mean to use 'from ... import ...' instead? + +* :exc:`ImportError` exceptions raised from failed ``from import + `` statements now include suggestions for the value of ```` based on the + available names in ````. (Contributed by Pablo Galindo in :gh:`91058`.) + + >>> from collections import chainmap + Traceback (most recent call last): + File "", line 1, in + ImportError: cannot import name 'chainmap' from 'collections'. Did you mean: 'ChainMap'? + New Features Related to Type Hints ================================== -This section covers major changes affecting :pep:`484` type hints and +This section covers major changes affecting :pep:`type hints <484>` and the :mod:`typing` module. .. _whatsnew312-pep692: @@ -343,7 +489,7 @@ for valid annotations only in cases where all of the ``**kwargs`` were of the same type. -This PEP specifies a more precise way of typing ``**kwargs`` by relying on +:pep:`692` specifies a more precise way of typing ``**kwargs`` by relying on typed dictionaries:: from typing import TypedDict, Unpack @@ -387,106 +533,46 @@ def get_colour(self) -> str: return "red" -(Contributed by Steven Troxler in :gh:`101561`.) - -.. _whatsnew312-pep695: - -PEP 695: Type Parameter Syntax ------------------------------- +See :pep:`698` for more details. -Generic classes and functions under :pep:`484` were declared using a verbose syntax -that left the scope of type parameters unclear and required explicit declarations of -variance. - -:pep:`695` introduces a new, more compact and explicit way to create -:ref:`generic classes ` and :ref:`functions `:: - - def max[T](args: Iterable[T]) -> T: - ... - - class list[T]: - def __getitem__(self, index: int, /) -> T: - ... - - def append(self, element: T) -> None: - ... - -In addition, the PEP introduces a new way to declare :ref:`type aliases ` -using the :keyword:`type` statement, which creates an instance of -:class:`~typing.TypeAliasType`:: - - type Point = tuple[float, float] - -Type aliases can also be :ref:`generic `:: - - type Point[T] = tuple[T, T] - -The new syntax allows declaring :class:`~typing.TypeVarTuple` -and :class:`~typing.ParamSpec` parameters, as well as :class:`~typing.TypeVar` -parameters with bounds or constraints:: - - type IntFunc[**P] = Callable[P, int] # ParamSpec - type LabeledTuple[*Ts] = tuple[str, *Ts] # TypeVarTuple - type HashableSequence[T: Hashable] = Sequence[T] # TypeVar with bound - type IntOrStrSequence[T: (int, str)] = Sequence[T] # TypeVar with constraints - -The value of type aliases and the bound and constraints of type variables -created through this syntax are evaluated only on demand (see -:ref:`lazy-evaluation`). This means type aliases are able to refer to other -types defined later in the file. - -Type parameters declared through a type parameter list are visible within the -scope of the declaration and any nested scopes, but not in the outer scope. For -example, they can be used in the type annotations for the methods of a generic -class or in the class body. However, they cannot be used in the module scope after -the class is defined. See :ref:`type-params` for a detailed description of the -runtime semantics of type parameters. - -In order to support these scoping semantics, a new kind of scope is introduced, -the :ref:`annotation scope `. Annotation scopes behave for the -most part like function scopes, but interact differently with enclosing class scopes. -In Python 3.13, :term:`annotations ` will also be evaluated in -annotation scopes. - -See :pep:`695` for more details. - -(PEP written by Eric Traut. Implementation by Jelle Zijlstra, Eric Traut, -and others in :gh:`103764`.) +(Contributed by Steven Troxler in :gh:`101561`.) Other Language Changes ====================== -* Add :ref:`perf_profiling` through the new - environment variable :envvar:`PYTHONPERFSUPPORT`, - the new command-line option :option:`-X perf <-X>`, - as well as the new :func:`sys.activate_stack_trampoline`, - :func:`sys.deactivate_stack_trampoline`, - and :func:`sys.is_stack_trampoline_active` APIs. - (Design by Pablo Galindo. Contributed by Pablo Galindo and Christian Heimes - with contributions from Gregory P. Smith [Google] and Mark Shannon - in :gh:`96123`.) +* The parser now raises :exc:`SyntaxError` when parsing source code containing + null bytes. (Contributed by Pablo Galindo in :gh:`96670`.) -* The extraction methods in :mod:`tarfile`, and :func:`shutil.unpack_archive`, - have a new a *filter* argument that allows limiting tar features than may be - surprising or dangerous, such as creating files outside the destination - directory. - See :ref:`tarfile-extraction-filter` for details. - In Python 3.14, the default will switch to ``'data'``. - (Contributed by Petr Viktorin in :pep:`706`.) +* A backslash-character pair that is not a valid escape sequence now generates + a :exc:`SyntaxWarning`, instead of :exc:`DeprecationWarning`. + For example, ``re.compile("\d+\.\d+")`` now emits a :exc:`SyntaxWarning` + (``"\d"`` is an invalid escape sequence, use raw strings for regular + expression: ``re.compile(r"\d+\.\d+")``). + In a future Python version, :exc:`SyntaxError` will eventually be raised, + instead of :exc:`SyntaxWarning`. + (Contributed by Victor Stinner in :gh:`98401`.) -* :class:`types.MappingProxyType` instances are now hashable if the underlying - mapping is hashable. - (Contributed by Serhiy Storchaka in :gh:`87995`.) +* Octal escapes with value larger than ``0o377`` (ex: ``"\477"``), deprecated + in Python 3.11, now produce a :exc:`SyntaxWarning`, instead of + :exc:`DeprecationWarning`. + In a future Python version they will be eventually a :exc:`SyntaxError`. + (Contributed by Victor Stinner in :gh:`98401`.) -* :class:`memoryview` now supports the half-float type (the "e" format code). - (Contributed by Dong-hee Na and Antoine Pitrou in :gh:`90751`.) +* Variables used in the target part of comprehensions that are not stored to + can now be used in assignment expressions (``:=``). + For example, in ``[(b := 1) for a, b.prop in some_iter]``, the assignment to + ``b`` is now allowed. Note that assigning to variables stored to in the target + part of comprehensions (like ``a``) is still disallowed, as per :pep:`572`. + (Contributed by Nikita Sobolev in :gh:`100581`.) -* The parser now raises :exc:`SyntaxError` when parsing source code containing - null bytes. (Contributed by Pablo Galindo in :gh:`96670`.) +* Exceptions raised in a class or type's ``__set_name__`` method are no longer + wrapped by a :exc:`RuntimeError`. Context information is added to the + exception as a :pep:`678` note. (Contributed by Irit Katriel in :gh:`77757`.) -* :func:`ast.parse` now raises :exc:`SyntaxError` instead of :exc:`ValueError` - when parsing source code containing null bytes. (Contributed by Pablo Galindo - in :gh:`96670`.) +* When a ``try-except*`` construct handles the entire :exc:`ExceptionGroup` + and raises one other exception, that exception is no longer wrapped in an + :exc:`ExceptionGroup`. Also changed in version 3.11.4. (Contributed by Irit + Katriel in :gh:`103590`.) * The Garbage Collector now runs only on the eval breaker mechanism of the Python bytecode evaluation loop instead of object allocations. The GC can @@ -495,47 +581,45 @@ chance to execute the GC periodically. (Contributed by Pablo Galindo in :gh:`97922`.) -* A backslash-character pair that is not a valid escape sequence now generates - a :exc:`SyntaxWarning`, instead of :exc:`DeprecationWarning`. - For example, ``re.compile("\d+\.\d+")`` now emits a :exc:`SyntaxWarning` - (``"\d"`` is an invalid escape sequence), use raw strings for regular - expression: ``re.compile(r"\d+\.\d+")``. - In a future Python version, :exc:`SyntaxError` will eventually be raised, - instead of :exc:`SyntaxWarning`. - (Contributed by Victor Stinner in :gh:`98401`.) - -* Octal escapes with value larger than ``0o377`` (ex: ``"\477"``), deprecated - in Python 3.11, now produce a :exc:`SyntaxWarning`, instead of - :exc:`DeprecationWarning`. - In a future Python version they will be eventually a :exc:`SyntaxError`. - (Contributed by Victor Stinner in :gh:`98401`.) - * All builtin and extension callables expecting boolean parameters now accept arguments of any type instead of just :class:`bool` and :class:`int`. (Contributed by Serhiy Storchaka in :gh:`60203`.) -* Variables used in the target part of comprehensions that are not stored to - can now be used in assignment expressions (``:=``). - For example, in ``[(b := 1) for a, b.prop in some_iter]``, the assignment to - ``b`` is now allowed. Note that assigning to variables stored to in the target - part of comprehensions (like ``a``) is still disallowed, as per :pep:`572`. - (Contributed by Nikita Sobolev in :gh:`100581`.) +* :class:`memoryview` now supports the half-float type (the "e" format code). + (Contributed by Donghee Na and Antoine Pitrou in :gh:`90751`.) * :class:`slice` objects are now hashable, allowing them to be used as dict keys and set items. (Contributed by Will Bradshaw, Furkan Onder, and Raymond Hettinger in :gh:`101264`.) -* :func:`sum` now uses Neumaier summation to improve accuracy when summing - floats or mixed ints and floats. +* :func:`sum` now uses Neumaier summation to improve accuracy and commutativity + when summing floats or mixed ints and floats. (Contributed by Raymond Hettinger in :gh:`100425`.) -* Exceptions raised in a typeobject's ``__set_name__`` method are no longer - wrapped by a :exc:`RuntimeError`. Context information is added to the - exception as a :pep:`678` note. (Contributed by Irit Katriel in :gh:`77757`.) +* :func:`ast.parse` now raises :exc:`SyntaxError` instead of :exc:`ValueError` + when parsing source code containing null bytes. (Contributed by Pablo Galindo + in :gh:`96670`.) -* When a ``try-except*`` construct handles the entire :exc:`ExceptionGroup` - and raises one other exception, that exception is no longer wrapped in an - :exc:`ExceptionGroup`. Also changed in version 3.11.4. (Contributed by Irit - Katriel in :gh:`103590`.) +* The extraction methods in :mod:`tarfile`, and :func:`shutil.unpack_archive`, + have a new a *filter* argument that allows limiting tar features than may be + surprising or dangerous, such as creating files outside the destination + directory. + See :ref:`tarfile extraction filters ` for details. + In Python 3.14, the default will switch to ``'data'``. + (Contributed by Petr Viktorin in :pep:`706`.) + +* :class:`types.MappingProxyType` instances are now hashable if the underlying + mapping is hashable. + (Contributed by Serhiy Storchaka in :gh:`87995`.) + +* Add :ref:`support for the perf profiler ` through the new + environment variable :envvar:`PYTHONPERFSUPPORT` + and command-line option :option:`-X perf <-X>`, + as well as the new :func:`sys.activate_stack_trampoline`, + :func:`sys.deactivate_stack_trampoline`, + and :func:`sys.is_stack_trampoline_active` functions. + (Design by Pablo Galindo. Contributed by Pablo Galindo and Christian Heimes + with contributions from Gregory P. Smith [Google] and Mark Shannon + in :gh:`96123`.) New Modules @@ -561,29 +645,20 @@ writing to sockets and uses :meth:`~socket.socket.sendmsg` if the platform supports it. (Contributed by Kumar Aditya in :gh:`91166`.) -* Added :func:`asyncio.eager_task_factory` and :func:`asyncio.create_eager_task_factory` +* Add :func:`asyncio.eager_task_factory` and :func:`asyncio.create_eager_task_factory` functions to allow opting an event loop in to eager task execution, making some use-cases 2x to 5x faster. - (Contributed by Jacob Bower & Itamar O in :gh:`102853`, :gh:`104140`, and :gh:`104138`) + (Contributed by Jacob Bower & Itamar Oren in :gh:`102853`, :gh:`104140`, and :gh:`104138`) -* On Linux, :mod:`asyncio` uses :class:`~asyncio.PidfdChildWatcher` by default +* On Linux, :mod:`asyncio` uses :class:`asyncio.PidfdChildWatcher` by default if :func:`os.pidfd_open` is available and functional instead of - :class:`~asyncio.ThreadedChildWatcher`. + :class:`asyncio.ThreadedChildWatcher`. (Contributed by Kumar Aditya in :gh:`98024`.) -* The child watcher classes :class:`~asyncio.MultiLoopChildWatcher`, - :class:`~asyncio.FastChildWatcher`, :class:`~asyncio.AbstractChildWatcher` - and :class:`~asyncio.SafeChildWatcher` are deprecated and - will be removed in Python 3.14. It is recommended to not manually - configure a child watcher as the event loop now uses the best available - child watcher for each platform (:class:`~asyncio.PidfdChildWatcher` - if supported and :class:`~asyncio.ThreadedChildWatcher` otherwise). - (Contributed by Kumar Aditya in :gh:`94597`.) - -* :func:`asyncio.set_child_watcher`, :func:`asyncio.get_child_watcher`, - :meth:`asyncio.AbstractEventLoopPolicy.set_child_watcher` and - :meth:`asyncio.AbstractEventLoopPolicy.get_child_watcher` are deprecated - and will be removed in Python 3.14. +* The event loop now uses the best available child watcher for each platform + (:class:`asyncio.PidfdChildWatcher` if supported and + :class:`asyncio.ThreadedChildWatcher` otherwise), so manually + configuring a child watcher is not recommended. (Contributed by Kumar Aditya in :gh:`94597`.) * Add *loop_factory* parameter to :func:`asyncio.run` to allow specifying @@ -591,7 +666,7 @@ (Contributed by Kumar Aditya in :gh:`99388`.) * Add C implementation of :func:`asyncio.current_task` for 4x-6x speedup. - (Contributed by Itamar Ostricher and Pranav Thulasiram Bhat in :gh:`100344`.) + (Contributed by Itamar Oren and Pranav Thulasiram Bhat in :gh:`100344`.) * :func:`asyncio.iscoroutine` now returns ``False`` for generators as :mod:`asyncio` does not support legacy generator-based coroutines. @@ -604,15 +679,16 @@ calendar -------- -* Add enums :data:`~calendar.Month` and :data:`~calendar.Day`. +* Add enums :data:`calendar.Month` and :data:`calendar.Day` + defining months of the year and days of the week. (Contributed by Prince Roshan in :gh:`103636`.) csv --- -* Add :const:`~csv.QUOTE_NOTNULL` and :const:`~csv.QUOTE_STRINGS` flags to +* Add :const:`csv.QUOTE_NOTNULL` and :const:`csv.QUOTE_STRINGS` flags to provide finer grained control of ``None`` and empty strings by - :class:`~csv.writer` objects. + :class:`csv.writer` objects. dis --- @@ -622,15 +698,24 @@ :mod:`dis` module. :opcode:`HAVE_ARGUMENT` is still relevant to real opcodes, but it is not useful for pseudo instructions. Use the new - :data:`~dis.hasarg` collection instead. + :data:`dis.hasarg` collection instead. (Contributed by Irit Katriel in :gh:`94216`.) +* Add the :data:`dis.hasexc` collection to signify instructions that set + an exception handler. (Contributed by Irit Katriel in :gh:`94216`.) + fractions --------- * Objects of type :class:`fractions.Fraction` now support float-style formatting. (Contributed by Mark Dickinson in :gh:`100161`.) +importlib.resources +------------------- + +* :func:`importlib.resources.as_file` now supports resource directories. + (Contributed by Jason R. Coombs in :gh:`97930`.) + inspect ------- @@ -640,7 +725,7 @@ * Add :func:`inspect.getasyncgenstate` and :func:`inspect.getasyncgenlocals` for determining the current state of asynchronous generators. - (Contributed by Thomas Krennwallner in :issue:`35759`.) + (Contributed by Thomas Krennwallner in :gh:`79940`.) * The performance of :func:`inspect.getattr_static` has been considerably improved. Most calls to the function should be at least 2x faster than they @@ -650,17 +735,17 @@ itertools --------- -* Added :class:`itertools.batched()` for collecting into even-sized +* Add :class:`itertools.batched()` for collecting into even-sized tuples where the last batch may be shorter than the rest. (Contributed by Raymond Hettinger in :gh:`98363`.) math ---- -* Added :func:`math.sumprod` for computing a sum of products. +* Add :func:`math.sumprod` for computing a sum of products. (Contributed by Raymond Hettinger in :gh:`100485`.) -* Extended :func:`math.nextafter` to include a *steps* argument +* Extend :func:`math.nextafter` to include a *steps* argument for moving up or down multiple steps at a time. (By Matthias Goergens, Mark Dickinson, and Raymond Hettinger in :gh:`94906`.) @@ -702,18 +787,18 @@ ------- * Add support for subclassing :class:`pathlib.PurePath` and - :class:`~pathlib.Path`, plus their Posix- and Windows-specific variants. - Subclasses may override the :meth:`~pathlib.PurePath.with_segments` method + :class:`pathlib.Path`, plus their Posix- and Windows-specific variants. + Subclasses may override the :meth:`pathlib.PurePath.with_segments` method to pass information between path instances. -* Add :meth:`~pathlib.Path.walk` for walking the directory trees and generating +* Add :meth:`pathlib.Path.walk` for walking the directory trees and generating all file or directory names within them, similar to :func:`os.walk`. (Contributed by Stanislav Zmiev in :gh:`90385`.) * Add *walk_up* optional parameter to :meth:`pathlib.PurePath.relative_to` to allow the insertion of ``..`` entries in the result; this behavior is more consistent with :func:`os.path.relpath`. - (Contributed by Domenico Ragusa in :issue:`40358`.) + (Contributed by Domenico Ragusa in :gh:`84538`.) * Add :meth:`pathlib.Path.is_junction` as a proxy to :func:`os.path.isjunction`. (Contributed by Charles Machalow in :gh:`99547`.) @@ -733,10 +818,10 @@ random ------ -* Added :func:`random.binomialvariate`. +* Add :func:`random.binomialvariate`. (Contributed by Raymond Hettinger in :gh:`81620`.) -* Added a default of ``lamb=1.0`` to :func:`random.expovariate`. +* Add a default of ``lambd=1.0`` to :func:`random.expovariate`. (Contributed by Raymond Hettinger in :gh:`100234`.) shutil @@ -775,33 +860,37 @@ * Add a :ref:`command-line interface `. (Contributed by Erlend E. Aasland in :gh:`77617`.) -* Add the :attr:`~sqlite3.Connection.autocommit` attribute - to :class:`~sqlite3.Connection` - and the *autocommit* parameter to :func:`~sqlite3.connect` +* Add the :attr:`sqlite3.Connection.autocommit` attribute + to :class:`sqlite3.Connection` + and the *autocommit* parameter to :func:`sqlite3.connect` to control :pep:`249`-compliant :ref:`transaction handling `. (Contributed by Erlend E. Aasland in :gh:`83638`.) * Add *entrypoint* keyword-only parameter to - :meth:`~sqlite3.Connection.load_extension`, + :meth:`sqlite3.Connection.load_extension`, for overriding the SQLite extension entry point. (Contributed by Erlend E. Aasland in :gh:`103015`.) -* Add :meth:`~sqlite3.Connection.getconfig` and - :meth:`~sqlite3.Connection.setconfig` to :class:`~sqlite3.Connection` +* Add :meth:`sqlite3.Connection.getconfig` and + :meth:`sqlite3.Connection.setconfig` to :class:`sqlite3.Connection` to make configuration changes to a database connection. (Contributed by Erlend E. Aasland in :gh:`103489`.) statistics ---------- -* Extended :func:`statistics.correlation` to include as a ``ranked`` method +* Extend :func:`statistics.correlation` to include as a ``ranked`` method for computing the Spearman correlation of ranked data. (Contributed by Raymond Hettinger in :gh:`95861`.) sys --- +* Add the :mod:`sys.monitoring` namespace to expose the new :ref:`PEP 669 + ` monitoring API. + (Contributed by Mark Shannon in :gh:`103082`.) + * Add :func:`sys.activate_stack_trampoline` and :func:`sys.deactivate_stack_trampoline` for activating and deactivating stack profiler trampolines, @@ -858,8 +947,8 @@ tokenize -------- -* The :mod:`tokenize` module includes the changes introduced in :pep:`701`. ( - Contributed by Marta GĂ³mez MacĂ­as and Pablo Galindo in :gh:`102856`.) +* The :mod:`tokenize` module includes the changes introduced in :pep:`701`. + (Contributed by Marta GĂ³mez MacĂ­as and Pablo Galindo in :gh:`102856`.) See :ref:`whatsnew312-porting-to-python312` for more information on the changes to the :mod:`tokenize` module. @@ -933,7 +1022,7 @@ unittest -------- -Added ``--durations`` command line option, showing the N slowest test cases:: +Add a ``--durations`` command line option, showing the N slowest test cases:: python3 -m unittest --durations=3 lib.tests.test_threading ..... @@ -949,7 +1038,7 @@ OK (skipped=3) -(Contributed by Giampaolo Rodola in :issue:`4080`) +(Contributed by Giampaolo Rodola in :gh:`48330`) uuid ---- @@ -961,13 +1050,13 @@ Optimizations ============= -* Removed ``wstr`` and ``wstr_length`` members from Unicode objects. +* Remove ``wstr`` and ``wstr_length`` members from Unicode objects. It reduces object size by 8 or 16 bytes on 64bit platform. (:pep:`623`) (Contributed by Inada Naoki in :gh:`92536`.) -* Added experimental support for using the BOLT binary optimizer in the build +* Add experimental support for using the BOLT binary optimizer in the build process, which improves performance by 1-5%. - (Contributed by Kevin Modzelewski in :gh:`90536` and tuned by Dong-hee Na in :gh:`101525`) + (Contributed by Kevin Modzelewski in :gh:`90536` and tuned by Donghee Na in :gh:`101525`) * Speed up the regular expression substitution (functions :func:`re.sub` and :func:`re.subn` and corresponding :class:`!re.Pattern` methods) for @@ -975,7 +1064,7 @@ (Contributed by Serhiy Storchaka in :gh:`91524`.) * Speed up :class:`asyncio.Task` creation by deferring expensive string formatting. - (Contributed by Itamar O in :gh:`103793`.) + (Contributed by Itamar Oren in :gh:`103793`.) * The :func:`tokenize.tokenize` and :func:`tokenize.generate_tokens` functions are up to 64% faster as a side effect of the changes required to cover :pep:`701` in @@ -990,17 +1079,38 @@ CPython bytecode changes ======================== -* Remove the :opcode:`LOAD_METHOD` instruction. It has been merged into +* Remove the :opcode:`!LOAD_METHOD` instruction. It has been merged into :opcode:`LOAD_ATTR`. :opcode:`LOAD_ATTR` will now behave like the old - :opcode:`LOAD_METHOD` instruction if the low bit of its oparg is set. + :opcode:`!LOAD_METHOD` instruction if the low bit of its oparg is set. (Contributed by Ken Jin in :gh:`93429`.) * Remove the :opcode:`!JUMP_IF_FALSE_OR_POP` and :opcode:`!JUMP_IF_TRUE_OR_POP` instructions. (Contributed by Irit Katriel in :gh:`102859`.) +* Remove the :opcode:`!PRECALL` instruction. (Contributed by Mark Shannon in + :gh:`92925`.) + +* Add the :opcode:`BINARY_SLICE` and :opcode:`STORE_SLICE` instructions. + (Contributed by Mark Shannon in :gh:`94163`.) + +* Add the :opcode:`CALL_INTRINSIC_1` instructions. + (Contributed by Mark Shannon in :gh:`99005`.) + +* Add the :opcode:`CALL_INTRINSIC_2` instruction. + (Contributed by Irit Katriel in :gh:`101799`.) + +* Add the :opcode:`CLEANUP_THROW` instruction. + (Contributed by Brandt Bucher in :gh:`90997`.) + +* Add the :opcode:`!END_SEND` instruction. + (Contributed by Mark Shannon in :gh:`103082`.) + * Add the :opcode:`LOAD_FAST_AND_CLEAR` instruction as part of the implementation of :pep:`709`. (Contributed by Carl Meyer in :gh:`101441`.) +* Add the :opcode:`LOAD_FAST_CHECK` instruction. + (Contributed by Dennis Sweeney in :gh:`93143`.) + * Add the :opcode:`LOAD_FROM_DICT_OR_DEREF`, :opcode:`LOAD_FROM_DICT_OR_GLOBALS`, and :opcode:`LOAD_LOCALS` opcodes as part of the implementation of :pep:`695`. Remove the :opcode:`!LOAD_CLASSDEREF` opcode, which can be replaced with @@ -1010,6 +1120,8 @@ * Add the :opcode:`LOAD_SUPER_ATTR` instruction. (Contributed by Carl Meyer and Vladimir Matveev in :gh:`103497`.) +* Add the :opcode:`RETURN_CONST` instruction. (Contributed by Wenyang Wang in :gh:`101632`.) + Demos and Tools =============== @@ -1027,15 +1139,52 @@ Deprecated ========== -* :mod:`asyncio`: The :meth:`~asyncio.get_event_loop` method of the - default event loop policy now emits a :exc:`DeprecationWarning` if there - is no current event loop set and it decides to create one. - (Contributed by Serhiy Storchaka and Guido van Rossum in :gh:`100160`.) +* :mod:`argparse`: The *type*, *choices*, and *metavar* parameters + of :class:`!argparse.BooleanOptionalAction` are deprecated + and will be removed in 3.14. + (Contributed by Nikita Sobolev in :gh:`92248`.) + +* :mod:`ast`: The following :mod:`ast` features have been deprecated in documentation since + Python 3.8, now cause a :exc:`DeprecationWarning` to be emitted at runtime + when they are accessed or used, and will be removed in Python 3.14: + + * :class:`!ast.Num` + * :class:`!ast.Str` + * :class:`!ast.Bytes` + * :class:`!ast.NameConstant` + * :class:`!ast.Ellipsis` + + Use :class:`ast.Constant` instead. + (Contributed by Serhiy Storchaka in :gh:`90953`.) + +* :mod:`asyncio`: + + * The child watcher classes :class:`asyncio.MultiLoopChildWatcher`, + :class:`asyncio.FastChildWatcher`, :class:`asyncio.AbstractChildWatcher` + and :class:`asyncio.SafeChildWatcher` are deprecated and + will be removed in Python 3.14. + (Contributed by Kumar Aditya in :gh:`94597`.) + + * :func:`asyncio.set_child_watcher`, :func:`asyncio.get_child_watcher`, + :meth:`asyncio.AbstractEventLoopPolicy.set_child_watcher` and + :meth:`asyncio.AbstractEventLoopPolicy.get_child_watcher` are deprecated + and will be removed in Python 3.14. + (Contributed by Kumar Aditya in :gh:`94597`.) + + * The :meth:`~asyncio.get_event_loop` method of the + default event loop policy now emits a :exc:`DeprecationWarning` if there + is no current event loop set and it decides to create one. + (Contributed by Serhiy Storchaka and Guido van Rossum in :gh:`100160`.) * :mod:`calendar`: ``calendar.January`` and ``calendar.February`` constants are deprecated and replaced by :data:`calendar.JANUARY` and :data:`calendar.FEBRUARY`. (Contributed by Prince Roshan in :gh:`103636`.) +* :mod:`collections.abc`: Deprecated :class:`collections.abc.ByteString`. + Prefer :class:`Sequence` or :class:`collections.abc.Buffer`. + For use in typing, prefer a union, like ``bytes | bytearray``, or :class:`collections.abc.Buffer`. + (Contributed by Shantanu Jain in :gh:`91896`.) + * :mod:`datetime`: :class:`datetime.datetime`'s :meth:`~datetime.datetime.utcnow` and :meth:`~datetime.datetime.utcfromtimestamp` are deprecated and will be removed in a future version. Instead, use timezone-aware objects to represent @@ -1044,28 +1193,88 @@ :const:`datetime.UTC`. (Contributed by Paul Ganssle in :gh:`103857`.) -* :mod:`os`: The ``st_ctime`` fields return by :func:`os.stat` and :func:`os.lstat` on - Windows are deprecated. In a future release, they will contain the last - metadata change time, consistent with other platforms. For now, they still - contain the creation time, which is also available in the new ``st_birthtime`` - field. (Contributed by Steve Dower in :gh:`99726`.) +* :mod:`email`: Deprecate the *isdst* parameter in :func:`email.utils.localtime`. + (Contributed by Alan Williams in :gh:`72346`.) + +* :mod:`importlib.abc`: Deprecated the following classes, scheduled for removal in + Python 3.14: + + * :class:`!importlib.abc.ResourceReader` + * :class:`!importlib.abc.Traversable` + * :class:`!importlib.abc.TraversableResources` + + Use :mod:`importlib.resources.abc` classes instead: + + * :class:`importlib.resources.abc.Traversable` + * :class:`importlib.resources.abc.TraversableResources` + + (Contributed by Jason R. Coombs and Hugo van Kemenade in :gh:`93963`.) + +* :mod:`itertools`: Deprecate the support for copy, deepcopy, and pickle operations, + which is undocumented, inefficient, historically buggy, and inconsistent. + This will be removed in 3.14 for a significant reduction in code + volume and maintenance burden. + (Contributed by Raymond Hettinger in :gh:`101588`.) + +* :mod:`multiprocessing`: In Python 3.14, the default :mod:`multiprocessing` + start method will change to a safer one on Linux, BSDs, + and other non-macOS POSIX platforms where ``'fork'`` is currently + the default (:gh:`84559`). Adding a runtime warning about this was deemed too + disruptive as the majority of code is not expected to care. Use the + :func:`~multiprocessing.get_context` or + :func:`~multiprocessing.set_start_method` APIs to explicitly specify when + your code *requires* ``'fork'``. See :ref:`contexts and start methods + `. + +* :mod:`pkgutil`: :func:`pkgutil.find_loader` and :func:`pkgutil.get_loader` + are deprecated and will be removed in Python 3.14; + use :func:`importlib.util.find_spec` instead. + (Contributed by Nikita Sobolev in :gh:`97850`.) + +* :mod:`pty`: The module has two undocumented ``master_open()`` and ``slave_open()`` + functions that have been deprecated since Python 2 but only gained a + proper :exc:`DeprecationWarning` in 3.12. Remove them in 3.14. + (Contributed by Soumendra Ganguly and Gregory P. Smith in :gh:`85984`.) + +* :mod:`os`: + + * The ``st_ctime`` fields return by :func:`os.stat` and :func:`os.lstat` on + Windows are deprecated. In a future release, they will contain the last + metadata change time, consistent with other platforms. For now, they still + contain the creation time, which is also available in the new ``st_birthtime`` + field. (Contributed by Steve Dower in :gh:`99726`.) + + * On POSIX platforms, :func:`os.fork` can now raise a + :exc:`DeprecationWarning` when it can detect being called from a + multithreaded process. There has always been a fundamental incompatibility + with the POSIX platform when doing so. Even if such code *appeared* to work. + We added the warning to to raise awareness as issues encounted by code doing + this are becoming more frequent. See the :func:`os.fork` documentation for + more details along with `this discussion on fork being incompatible with threads + `_ for *why* we're now surfacing this + longstanding platform compatibility problem to developers. + + When this warning appears due to usage of :mod:`multiprocessing` or + :mod:`concurrent.futures` the fix is to use a different + :mod:`multiprocessing` start method such as ``"spawn"`` or ``"forkserver"``. -* :mod:`shutil`: The *onerror* argument of :func:`shutil.rmtree` is deprecated as will be removed +* :mod:`shutil`: The *onerror* argument of :func:`shutil.rmtree` is deprecated and will be removed in Python 3.14. Use *onexc* instead. (Contributed by Irit Katriel in :gh:`102828`.) * :mod:`sqlite3`: - * :ref:`default adapters and converters - ` are now deprecated. - Instead, use the :ref:`sqlite3-adapter-converter-recipes` - and tailor them to your needs. - (Contributed by Erlend E. Aasland in :gh:`90016`.) - - * In :meth:`~sqlite3.Cursor.execute`, :exc:`DeprecationWarning` is now emitted - when :ref:`named placeholders ` are used together with - parameters supplied as a :term:`sequence` instead of as a :class:`dict`. - Starting from Python 3.14, using named placeholders with parameters supplied - as a sequence will raise a :exc:`~sqlite3.ProgrammingError`. - (Contributed by Erlend E. Aasland in :gh:`101698`.) + + * :ref:`default adapters and converters + ` are now deprecated. + Instead, use the :ref:`sqlite3-adapter-converter-recipes` + and tailor them to your needs. + (Contributed by Erlend E. Aasland in :gh:`90016`.) + + * In :meth:`~sqlite3.Cursor.execute`, :exc:`DeprecationWarning` is now emitted + when :ref:`named placeholders ` are used together with + parameters supplied as a :term:`sequence` instead of as a :class:`dict`. + Starting from Python 3.14, using named placeholders with parameters supplied + as a sequence will raise a :exc:`~sqlite3.ProgrammingError`. + (Contributed by Erlend E. Aasland in :gh:`101698`.) * :mod:`sys`: The :data:`sys.last_type`, :data:`sys.last_value` and :data:`sys.last_traceback` fields are deprecated. Use :data:`sys.last_exc` instead. @@ -1075,16 +1284,24 @@ Python 3.14, when ``'data'`` filter will become the default. See :ref:`tarfile-extraction-filter` for details. -* :mod:`typing`: :class:`typing.Hashable` and :class:`typing.Sized` aliases for :class:`collections.abc.Hashable` - and :class:`collections.abc.Sized`. (:gh:`94309`.) +* :mod:`typing`: + + * :class:`typing.Hashable` and :class:`typing.Sized` aliases for :class:`collections.abc.Hashable` + and :class:`collections.abc.Sized`. (:gh:`94309`.) + + * :class:`typing.ByteString`, deprecated since Python 3.9, now causes a + :exc:`DeprecationWarning` to be emitted when it is used. + (Contributed by Alex Waygood in :gh:`91896`.) * :mod:`xml.etree.ElementTree`: The module now emits :exc:`DeprecationWarning` when testing the truth value of an :class:`xml.etree.ElementTree.Element`. Before, the Python implementation emitted :exc:`FutureWarning`, and the C implementation emitted nothing. + (Contributed by Jacob Walls in :gh:`83122`.) -* The 3-arg signatures (type, value, traceback) of :meth:`~coroutine.throw`, - :meth:`~generator.throw` and :meth:`~agen.athrow` are deprecated and +* The 3-arg signatures (type, value, traceback) of :meth:`coroutine throw() + `, :meth:`generator throw() ` and + :meth:`async generator throw() ` are deprecated and may be removed in a future version of Python. Use the single-arg versions of these functions instead. (Contributed by Ofey Chan in :gh:`89874`.) @@ -1093,17 +1310,21 @@ :exc:`ImportWarning`). (Contributed by Brett Cannon in :gh:`65961`.) -* In accordance with :pep:`699`, the ``ma_version_tag`` field in :c:type:`PyDictObject` - is deprecated for extension modules. Accessing this field will generate a compiler - warning at compile time. This field will be removed in Python 3.14. - (Contributed by Ramvikrams and Kumar Aditya in :gh:`101193`. PEP by Ken Jin.) +* Setting ``__package__`` or ``__cached__`` on a module is deprecated, + and will cease to be set or taken into consideration by the import system in Python 3.14. + (Contributed by Brett Cannon in :gh:`65961`.) * The bitwise inversion operator (``~``) on bool is deprecated. It will throw an error in Python 3.14. Use ``not`` for logical negation of bools instead. In the rare case that you really need the bitwise inversion of the underlying - ``int``, convert to int explicitly with ``~int(x)``. (Contributed by Tim Hoffmann + ``int``, convert to int explicitly: ``~int(x)``. (Contributed by Tim Hoffmann in :gh:`103487`.) +* Accessing ``co_lnotab`` on code objects was deprecated in Python 3.10 via :pep:`626`, + but it only got a proper :exc:`DeprecationWarning` in 3.12, + therefore it will be removed in 3.14. + (Contributed by Nikita Sobolev in :gh:`101866`.) + Pending Removal in Python 3.13 ------------------------------ @@ -1151,14 +1372,13 @@ Pending Removal in Python 3.14 ------------------------------ +The following APIs have been deprecated +and will be removed in Python 3.14. + * :mod:`argparse`: The *type*, *choices*, and *metavar* parameters - of :class:`!argparse.BooleanOptionalAction` are deprecated - and will be removed in 3.14. - (Contributed by Nikita Sobolev in :gh:`92248`.) + of :class:`!argparse.BooleanOptionalAction` -* :mod:`ast`: The following :mod:`ast` features have been deprecated in documentation since - Python 3.8, now cause a :exc:`DeprecationWarning` to be emitted at runtime - when they are accessed or used, and will be removed in Python 3.14: +* :mod:`ast`: * :class:`!ast.Num` * :class:`!ast.Str` @@ -1166,81 +1386,48 @@ * :class:`!ast.NameConstant` * :class:`!ast.Ellipsis` - Use :class:`ast.Constant` instead. - (Contributed by Serhiy Storchaka in :gh:`90953`.) +* :mod:`asyncio`: -* :mod:`asyncio`: the *msg* parameter of both - :meth:`asyncio.Future.cancel` and - :meth:`asyncio.Task.cancel` (:gh:`90985`) + * :class:`!asyncio.MultiLoopChildWatcher` + * :class:`!asyncio.FastChildWatcher` + * :class:`!asyncio.AbstractChildWatcher` + * :class:`!asyncio.SafeChildWatcher` + * :func:`!asyncio.set_child_watcher` + * :func:`!asyncio.get_child_watcher`, + * :meth:`!asyncio.AbstractEventLoopPolicy.set_child_watcher` + * :meth:`!asyncio.AbstractEventLoopPolicy.get_child_watcher` -* :mod:`collections.abc`: Deprecated :class:`collections.abc.ByteString`. - Prefer :class:`Sequence` or :class:`collections.abc.Buffer`. - For use in typing, prefer a union, like ``bytes | bytearray``, or :class:`collections.abc.Buffer`. - (Contributed by Shantanu Jain in :gh:`91896`.) +* :mod:`collections.abc`: :class:`!collections.abc.ByteString`. -* :mod:`email`: Deprecated the *isdst* parameter in :func:`email.utils.localtime`. - (Contributed by Alan Williams in :gh:`72346`.) +* :mod:`email`: the *isdst* parameter in :func:`email.utils.localtime`. -* :mod:`importlib.abc`: Deprecated the following classes, scheduled for removal in - Python 3.14: +* :mod:`importlib.abc`: * :class:`!importlib.abc.ResourceReader` * :class:`!importlib.abc.Traversable` * :class:`!importlib.abc.TraversableResources` - Use :mod:`importlib.resources.abc` classes instead: - - * :class:`importlib.resources.abc.Traversable` - * :class:`importlib.resources.abc.TraversableResources` - - (Contributed by Jason R. Coombs and Hugo van Kemenade in :gh:`93963`.) - -* :mod:`itertools`: The module had undocumented, inefficient, historically buggy, - and inconsistent support for copy, deepcopy, and pickle operations. - This will be removed in 3.14 for a significant reduction in code - volume and maintenance burden. - (Contributed by Raymond Hettinger in :gh:`101588`.) +* :mod:`itertools`: Support for copy, deepcopy, and pickle operations. -* :mod:`multiprocessing`: The default :mod:`multiprocessing` start method will change to a safer one on - Linux, BSDs, and other non-macOS POSIX platforms where ``'fork'`` is currently - the default (:gh:`84559`). Adding a runtime warning about this was deemed too - disruptive as the majority of code is not expected to care. Use the - :func:`~multiprocessing.get_context` or - :func:`~multiprocessing.set_start_method` APIs to explicitly specify when - your code *requires* ``'fork'``. See :ref:`multiprocessing-start-methods`. +* :mod:`pkgutil`: -* :mod:`pkgutil`: :func:`pkgutil.find_loader` and :func:`pkgutil.get_loader` - now raise :exc:`DeprecationWarning`; - use :func:`importlib.util.find_spec` instead. - (Contributed by Nikita Sobolev in :gh:`97850`.) + * :func:`!pkgutil.find_loader` + * :func:`!pkgutil.get_loader`. -* :mod:`pty`: The module has two undocumented ``master_open()`` and ``slave_open()`` - functions that have been deprecated since Python 2 but only gained a - proper :exc:`DeprecationWarning` in 3.12. Remove them in 3.14. +* :mod:`pty`: -* :mod:`shutil`: The *onerror* argument of :func:`shutil.rmtree` is deprecated in 3.12, - and will be removed in 3.14. + * :func:`!pty.master_open` + * :func:`!pty.slave_open` -* :mod:`typing`: :class:`typing.ByteString`, deprecated since Python 3.9, now causes a - :exc:`DeprecationWarning` to be emitted when it is used. +* :mod:`shutil`: The *onerror* argument of :func:`shutil.rmtree` -* :mod:`xml.etree.ElementTree`: Testing the truth value of an :class:`xml.etree.ElementTree.Element` - is deprecated and will raise an exception in Python 3.14. +* :mod:`typing`: :class:`!typing.ByteString` -* Creating immutable types (:c:macro:`Py_TPFLAGS_IMMUTABLETYPE`) with mutable - bases using the C API (:gh:`95388`). +* :mod:`xml.etree.ElementTree`: Testing the truth value of an :class:`xml.etree.ElementTree.Element`. -* ``__package__`` and ``__cached__`` will cease to be set or taken - into consideration by the import system (:gh:`97879`). - -* Accessing ``co_lnotab`` was deprecated in :pep:`626` since 3.10 - and was planned to be removed in 3.12 - but it only got a proper :exc:`DeprecationWarning` in 3.12. - May be removed in 3.14. - (Contributed by Nikita Sobolev in :gh:`101866`.) +* The ``__package__`` and ``__cached__`` attributes on module objects. -* Creating :c:data:`immutable types ` with mutable - bases using the C API (:gh:`95388`) +* The ``co_lnotab`` attribute of code objects. Pending Removal in Future Versions ---------------------------------- @@ -1265,13 +1452,19 @@ Removed ======= -* ``asynchat`` and ``asyncore``: These two modules have been removed +asynchat and asyncore +--------------------- + +* These two modules have been removed according to the schedule in :pep:`594`, having been deprecated in Python 3.6. Use :mod:`asyncio` instead. (Contributed by Nikita Sobolev in :gh:`96580`.) -* :mod:`configparser`: Several names deprecated in the :mod:`configparser` way back in 3.2 have +configparser +------------ + +* Several names deprecated in the :mod:`configparser` way back in 3.2 have been removed per :gh:`89336`: * :class:`configparser.ParsingError` no longer has a ``filename`` attribute @@ -1281,13 +1474,19 @@ * :class:`configparser.ConfigParser` no longer has a ``readfp`` method. Use :meth:`~configparser.ConfigParser.read_file` instead. -* ``distutils``: Remove the ``distutils`` package. It was deprecated in Python 3.10 by +distutils +--------- + +* Remove the :py:mod:`!distutils` package. It was deprecated in Python 3.10 by :pep:`632` "Deprecate distutils module". For projects still using ``distutils`` and cannot be updated to something else, the ``setuptools`` project can be installed: it still provides ``distutils``. (Contributed by Victor Stinner in :gh:`92584`.) -* :mod:`ensurepip`: Remove the bundled setuptools wheel from :mod:`ensurepip`, +ensurepip +--------- + +* Remove the bundled setuptools wheel from :mod:`ensurepip`, and stop installing setuptools in environments created by :mod:`venv`. ``pip (>= 22.1)`` does not require setuptools to be installed in the @@ -1305,27 +1504,42 @@ (Contributed by Pradyun Gedam in :gh:`95299`.) -* :mod:`enum`: Remove ``EnumMeta.__getattr__``, which is no longer needed for +enum +---- + +* Remove :mod:`enum`'s ``EnumMeta.__getattr__``, which is no longer needed for enum attribute access. (Contributed by Ethan Furman in :gh:`95083`.) -* :mod:`ftplib`: Remove the ``FTP_TLS.ssl_version`` class attribute: use the +ftplib +------ + +* Remove :mod:`ftplib`'s ``FTP_TLS.ssl_version`` class attribute: use the *context* parameter instead. (Contributed by Victor Stinner in :gh:`94172`.) -* :mod:`gzip`: Remove the ``filename`` attribute of :class:`gzip.GzipFile`, +gzip +---- + +* Remove the ``filename`` attribute of :mod:`gzip`'s :class:`gzip.GzipFile`, deprecated since Python 2.6, use the :attr:`~gzip.GzipFile.name` attribute instead. In write mode, the ``filename`` attribute added ``'.gz'`` file extension if it was not present. (Contributed by Victor Stinner in :gh:`94196`.) -* :mod:`hashlib`: Remove the pure Python implementation of +hashlib +------- + +* Remove the pure Python implementation of :mod:`hashlib`'s :func:`hashlib.pbkdf2_hmac()`, deprecated in Python 3.10. Python 3.10 and newer requires OpenSSL 1.1.1 (:pep:`644`): this OpenSSL version provides a C implementation of :func:`~hashlib.pbkdf2_hmac()` which is faster. (Contributed by Victor Stinner in :gh:`94199`.) -* :mod:`importlib`: Many previously deprecated cleanups in :mod:`importlib` have now been +importlib +--------- + +* Many previously deprecated cleanups in :mod:`importlib` have now been completed: * References to, and support for :meth:`!module_repr()` has been removed. @@ -1341,10 +1555,13 @@ * ``importlib.abc.Finder``, ``pkgutil.ImpImporter``, and ``pkgutil.ImpLoader`` have been removed. (Contributed by Barry Warsaw in :gh:`98040`.) - * The :mod:`!imp` module has been removed. (Contributed by Barry Warsaw in - :gh:`98040`.) +imp +--- + +* The :mod:`!imp` module has been removed. (Contributed by Barry Warsaw in + :gh:`98040`.) - * Replace removed :mod:`!imp` functions with :mod:`importlib` functions: + To migrate, consult the following correspondence table: ================================= ======================================= imp importlib @@ -1359,9 +1576,10 @@ ``imp.new_module(name)`` ``types.ModuleType(name)`` ``imp.reload()`` :func:`importlib.reload` ``imp.source_from_cache()`` :func:`importlib.util.source_from_cache` + ``imp.load_source()`` *See below* ================================= ======================================= - * Replace ``imp.load_source()`` with:: + Replace ``imp.load_source()`` with:: import importlib.util import importlib.machinery @@ -1376,28 +1594,34 @@ loader.exec_module(module) return module - * Removed :mod:`!imp` functions and attributes with no replacements: +* Remove :mod:`!imp` functions and attributes with no replacements: - * undocumented functions: + * Undocumented functions: - * ``imp.init_builtin()`` - * ``imp.load_compiled()`` - * ``imp.load_dynamic()`` - * ``imp.load_package()`` - - * ``imp.lock_held()``, ``imp.acquire_lock()``, ``imp.release_lock()``: - the locking scheme has changed in Python 3.3 to per-module locks. - * ``imp.find_module()`` constants: ``SEARCH_ERROR``, ``PY_SOURCE``, - ``PY_COMPILED``, ``C_EXTENSION``, ``PY_RESOURCE``, ``PKG_DIRECTORY``, - ``C_BUILTIN``, ``PY_FROZEN``, ``PY_CODERESOURCE``, ``IMP_HOOK``. + * ``imp.init_builtin()`` + * ``imp.load_compiled()`` + * ``imp.load_dynamic()`` + * ``imp.load_package()`` + + * ``imp.lock_held()``, ``imp.acquire_lock()``, ``imp.release_lock()``: + the locking scheme has changed in Python 3.3 to per-module locks. + * ``imp.find_module()`` constants: ``SEARCH_ERROR``, ``PY_SOURCE``, + ``PY_COMPILED``, ``C_EXTENSION``, ``PY_RESOURCE``, ``PKG_DIRECTORY``, + ``C_BUILTIN``, ``PY_FROZEN``, ``PY_CODERESOURCE``, ``IMP_HOOK``. + +io +-- -* :mod:`io`: Remove ``io.OpenWrapper`` and ``_pyio.OpenWrapper``, deprecated in Python +* Remove :mod:`io`'s ``io.OpenWrapper`` and ``_pyio.OpenWrapper``, deprecated in Python 3.10: just use :func:`open` instead. The :func:`open` (:func:`io.open`) function is a built-in function. Since Python 3.10, :func:`!_pyio.open` is also a static method. (Contributed by Victor Stinner in :gh:`94169`.) -* :mod:`locale`: Remove the :func:`!locale.format` function, deprecated in Python 3.7: +locale +------ + +* Remove :mod:`locale`'s :func:`!locale.format` function, deprecated in Python 3.7: use :func:`locale.format_string` instead. (Contributed by Victor Stinner in :gh:`94226`.) @@ -1409,7 +1633,10 @@ .. _aiosmtpd: https://pypi.org/project/aiosmtpd/ -* :mod:`sqlite3`: The following undocumented :mod:`sqlite3` features, deprecated in Python +sqlite3 +------- + +* The following undocumented :mod:`sqlite3` features, deprecated in Python 3.10, are now removed: * ``sqlite3.enable_shared_cache()`` @@ -1425,30 +1652,36 @@ (Contributed by Erlend E. Aasland in :gh:`92548`.) -* :mod:`ssl`: +ssl +--- + +* Remove :mod:`ssl`'s :func:`!ssl.RAND_pseudo_bytes` function, deprecated in Python 3.6: + use :func:`os.urandom` or :func:`ssl.RAND_bytes` instead. + (Contributed by Victor Stinner in :gh:`94199`.) + +* Remove the :func:`!ssl.match_hostname` function. + It was deprecated in Python 3.7. OpenSSL performs + hostname matching since Python 3.7, Python no longer uses the + :func:`!ssl.match_hostname` function. + (Contributed by Victor Stinner in :gh:`94199`.) + +* Remove the :func:`!ssl.wrap_socket` function, deprecated in Python 3.7: + instead, create a :class:`ssl.SSLContext` object and call its + :class:`ssl.SSLContext.wrap_socket` method. Any package that still uses + :func:`!ssl.wrap_socket` is broken and insecure. The function neither sends a + SNI TLS extension nor validates server hostname. Code is subject to `CWE-295 + `_: Improper Certificate + Validation. + (Contributed by Victor Stinner in :gh:`94199`.) + +unittest +-------- - * Remove the :func:`!ssl.RAND_pseudo_bytes` function, deprecated in Python 3.6: - use :func:`os.urandom` or :func:`ssl.RAND_bytes` instead. - (Contributed by Victor Stinner in :gh:`94199`.) - - * Remove the :func:`!ssl.match_hostname` function. - It was deprecated in Python 3.7. OpenSSL performs - hostname matching since Python 3.7, Python no longer uses the - :func:`!ssl.match_hostname` function. - (Contributed by Victor Stinner in :gh:`94199`.) - - * Remove the :func:`!ssl.wrap_socket` function, deprecated in Python 3.7: - instead, create a :class:`ssl.SSLContext` object and call its - :class:`ssl.SSLContext.wrap_socket` method. Any package that still uses - :func:`!ssl.wrap_socket` is broken and insecure. The function neither sends a - SNI TLS extension nor validates server hostname. Code is subject to `CWE-295 - `_: Improper Certificate - Validation. - (Contributed by Victor Stinner in :gh:`94199`.) +* Remove many long-deprecated :mod:`unittest` features: -* :mod:`unittest`: Removed many old deprecated :mod:`unittest` features: + .. _unittest-TestCase-removed-aliases: - - A number of :class:`~unittest.TestCase` method aliases: + * A number of :class:`~unittest.TestCase` method aliases: ============================ =============================== =============== Deprecated alias Method Name Deprecated in @@ -1473,35 +1706,47 @@ You can use https://github.com/isidentical/teyit to automatically modernise your unit tests. - - Undocumented and broken :class:`~unittest.TestCase` method + * Undocumented and broken :class:`~unittest.TestCase` method ``assertDictContainsSubset`` (deprecated in Python 3.2). - - Undocumented :meth:`TestLoader.loadTestsFromModule + * Undocumented :meth:`TestLoader.loadTestsFromModule ` parameter *use_load_tests* (deprecated and ignored since Python 3.2). - - An alias of the :class:`~unittest.TextTestResult` class: + * An alias of the :class:`~unittest.TextTestResult` class: ``_TextTestResult`` (deprecated in Python 3.2). - (Contributed by Serhiy Storchaka in :issue:`45162`.) + (Contributed by Serhiy Storchaka in :gh:`89325`.) + +webbrowser +---------- -* :mod:`webbrowser`: Remove support for obsolete browsers from :mod:`webbrowser`. - Removed browsers include: Grail, Mosaic, Netscape, Galeon, Skipstone, +* Remove support for obsolete browsers from :mod:`webbrowser`. + The removed browsers include: Grail, Mosaic, Netscape, Galeon, Skipstone, Iceape, Firebird, and Firefox versions 35 and below (:gh:`102871`). -* :mod:`xml.etree.ElementTree`: Remove the ``ElementTree.Element.copy()`` method of the +xml.etree.ElementTree +--------------------- + +* Remove the ``ElementTree.Element.copy()`` method of the pure Python implementation, deprecated in Python 3.10, use the :func:`copy.copy` function instead. The C implementation of :mod:`xml.etree.ElementTree` has no ``copy()`` method, only a ``__copy__()`` method. (Contributed by Victor Stinner in :gh:`94383`.) -* :mod:`zipimport`: Remove ``find_loader()`` and ``find_module()`` methods, +zipimport +--------- + +* Remove :mod:`zipimport`'s ``find_loader()`` and ``find_module()`` methods, deprecated in Python 3.10: use the ``find_spec()`` method instead. See :pep:`451` for the rationale. (Contributed by Victor Stinner in :gh:`94379`.) -* Removed the ``suspicious`` rule from the documentation Makefile, and - removed ``Doc/tools/rstlint.py``, both in favor of `sphinx-lint +Others +------ + +* Remove the ``suspicious`` rule from the documentation :file:`Makefile` and + :file:`Doc/tools/rstlint.py`, both in favor of `sphinx-lint `_. (Contributed by Julien Palard in :gh:`98179`.) @@ -1531,7 +1776,7 @@ contain ASCII letters and digits and underscore. (Contributed by Serhiy Storchaka in :gh:`91760`.) -* Removed ``randrange()`` functionality deprecated since Python 3.10. Formerly, +* Remove ``randrange()`` functionality deprecated since Python 3.10. Formerly, ``randrange(10.0)`` losslessly converted to ``randrange(10)``. Now, it raises a :exc:`TypeError`. Also, the exception raised for non-integer values such as ``randrange(10.5)`` or ``randrange('10')`` has been changed from :exc:`ValueError` to @@ -1545,7 +1790,7 @@ to :term:`filesystem encoding and error handler`. Argument files should be encoded in UTF-8 instead of ANSI Codepage on Windows. -* Removed the ``asyncore``-based ``smtpd`` module deprecated in Python 3.4.7 +* Remove the ``asyncore``-based ``smtpd`` module deprecated in Python 3.4.7 and 3.5.4. A recommended replacement is the :mod:`asyncio`-based aiosmtpd_ PyPI module. @@ -1566,7 +1811,7 @@ so only a very small set of users might be affected. This change helps with interpreter isolation. Furthermore, :mod:`syslog` is a wrapper around process-global resources, which are best managed from the main interpreter. - (Contributed by Dong-hee Na in :gh:`99127`.) + (Contributed by Donghee Na in :gh:`99127`.) * The undocumented locking behavior of :func:`~functools.cached_property` is removed, because it locked across all instances of the class, leading to high @@ -1590,7 +1835,7 @@ functions is now changed due to the changes introduced in :pep:`701`. This means that ``STRING`` tokens are not emitted any more for f-strings and the tokens described in :pep:`701` are now produced instead: ``FSTRING_START``, - ``FSRING_MIDDLE`` and ``FSTRING_END`` are now emitted for f-string "string" + ``FSTRING_MIDDLE`` and ``FSTRING_END`` are now emitted for f-string "string" parts in addition to the appropriate tokens for the tokenization in the expression components. For example for the f-string ``f"start {1+1} end"`` the old version of the tokenizer emitted:: @@ -1627,9 +1872,9 @@ Build Changes ============= -* Python no longer uses ``setup.py`` to build shared C extension modules. +* Python no longer uses :file:`setup.py` to build shared C extension modules. Build parameters like headers and libraries are detected in ``configure`` - script. Extensions are built by ``Makefile``. Most extensions use + script. Extensions are built by :file:`Makefile`. Most extensions use ``pkg-config`` and fall back to manual detection. (Contributed by Christian Heimes in :gh:`93939`.) @@ -1640,9 +1885,9 @@ * CPython now uses the ThinLTO option as the default link time optimization policy if the Clang compiler accepts the flag. - (Contributed by Dong-hee Na in :gh:`89536`.) + (Contributed by Donghee Na in :gh:`89536`.) -* Add ``COMPILEALL_OPTS`` variable in Makefile to override :mod:`compileall` +* Add ``COMPILEALL_OPTS`` variable in :file:`Makefile` to override :mod:`compileall` options (default: ``-j0``) in ``make install``. Also merged the 3 ``compileall`` commands into a single command to build .pyc files for all optimization levels (0, 1, 2) at once. @@ -1671,8 +1916,9 @@ New Features ------------ +.. _whatsnew312-pep697: -* :pep:`697`: Introduced the :ref:`Unstable C API tier `, +* :pep:`697`: Introduce the :ref:`Unstable C API tier `, intended for low-level tools like debuggers and JIT compilers. This API may change in each minor release of CPython without deprecation warnings. @@ -1694,7 +1940,7 @@ (Contributed by Petr Viktorin in :gh:`101101`.) -* :pep:`697`: Added API for extending types whose instance memory layout is +* :pep:`697`: Add an API for extending types whose instance memory layout is opaque: - :c:member:`PyType_Spec.basicsize` can be zero or negative to specify @@ -1709,7 +1955,7 @@ (Contributed by Petr Viktorin in :gh:`103509`.) -* Added the new :ref:`limited C API ` function :c:func:`PyType_FromMetaclass`, +* Add the new :ref:`limited C API ` function :c:func:`PyType_FromMetaclass`, which generalizes the existing :c:func:`PyType_FromModuleAndSpec` using an additional metaclass argument. (Contributed by Wenzel Jakob in :gh:`93012`.) @@ -1748,13 +1994,13 @@ protocol are now available in the :ref:`Limited API `. (Contributed by Wenzel Jakob in :gh:`98586`.) -* Added two new public functions, +* Add two new public functions, :c:func:`PyEval_SetProfileAllThreads` and :c:func:`PyEval_SetTraceAllThreads`, that allow to set tracing and profiling functions in all running threads in addition to the calling one. (Contributed by Pablo Galindo in :gh:`93503`.) -* Added new function :c:func:`PyFunction_SetVectorcall` to the C API +* Add new function :c:func:`PyFunction_SetVectorcall` to the C API which sets the vectorcall field of a given :c:type:`PyFunctionObject`. (Contributed by Andrew Frost in :gh:`92257`.) @@ -1764,14 +2010,14 @@ compilers, or debuggers. (Contributed by Carl Meyer in :gh:`91052`.) -* Added :c:func:`PyType_AddWatcher` and :c:func:`PyType_Watch` API to register +* Add :c:func:`PyType_AddWatcher` and :c:func:`PyType_Watch` API to register callbacks to receive notification on changes to a type. (Contributed by Carl Meyer in :gh:`91051`.) -* Added :c:func:`PyCode_AddWatcher` and :c:func:`PyCode_ClearWatcher` +* Add :c:func:`PyCode_AddWatcher` and :c:func:`PyCode_ClearWatcher` APIs to register callbacks to receive notification on creation and destruction of code objects. - (Contributed by Itamar Ostricher in :gh:`91054`.) + (Contributed by Itamar Oren in :gh:`91054`.) * Add :c:func:`PyFrame_GetVar` and :c:func:`PyFrame_GetVarString` functions to get a frame variable by its name. @@ -1798,8 +2044,10 @@ to replace the legacy-api :c:func:`!PyErr_Display`. (Contributed by Irit Katriel in :gh:`102755`). -* :pep:`683`: Introduced Immortal Objects to Python which allows objects - to bypass reference counts and introduced changes to the C-API: +.. _whatsnew312-pep683: + +* :pep:`683`: Introduce *Immortal Objects*, which allows objects + to bypass reference counts, and related changes to the C-API: - ``_Py_IMMORTAL_REFCNT``: The reference count that defines an object as immortal. @@ -1811,12 +2059,12 @@ - ``SSTATE_INTERNED_IMMORTAL_STATIC`` An identifier for interned unicode objects that are immortal and static - ``sys.getunicodeinternedsize`` This returns the total number of unicode - objects that have been interned. This is now needed for refleak.py to + objects that have been interned. This is now needed for :file:`refleak.py` to correctly track reference counts and allocated blocks (Contributed by Eddie Elizondo in :gh:`84436`.) -* :pep:`684`: Added the new :c:func:`Py_NewInterpreterFromConfig` +* :pep:`684`: Add the new :c:func:`Py_NewInterpreterFromConfig` function and :c:type:`PyInterpreterConfig`, which may be used to create sub-interpreters with their own GILs. (See :ref:`whatsnew312-pep684` for more info.) @@ -1865,7 +2113,7 @@ copied as-is to the result string, and any extra arguments discarded. (Contributed by Serhiy Storchaka in :gh:`95781`.) -* Fixed wrong sign placement in :c:func:`PyUnicode_FromFormat` and +* Fix wrong sign placement in :c:func:`PyUnicode_FromFormat` and :c:func:`PyUnicode_FromFormatV`. (Contributed by Philip Georgi in :gh:`95504`.) @@ -1970,6 +2218,11 @@ Deprecated ---------- +* In accordance with :pep:`699`, the ``ma_version_tag`` field in :c:type:`PyDictObject` + is deprecated for extension modules. Accessing this field will generate a compiler + warning at compile time. This field will be removed in Python 3.14. + (Contributed by Ramvikrams and Kumar Aditya in :gh:`101193`. PEP by Ken Jin.) + * Deprecate global configuration variable: * :c:var:`Py_DebugFlag`: use :c:member:`PyConfig.parser_debug` @@ -1999,13 +2252,13 @@ :c:type:`PyConfig` instead. (Contributed by Victor Stinner in :gh:`77782`.) -* Creating immutable types (:c:macro:`Py_TPFLAGS_IMMUTABLETYPE`) with mutable - bases is deprecated and will be disabled in Python 3.14. +* Creating :c:data:`immutable types ` with mutable + bases is deprecated and will be disabled in Python 3.14. (:gh:`95388`) -* The ``structmember.h`` header is deprecated, though it continues to be +* The :file:`structmember.h` header is deprecated, though it continues to be available and there are no plans to remove it. - Its contents are now available just by including ``Python.h``, + Its contents are now available just by including :file:`Python.h`, with a ``Py`` prefix added if it was missing: - :c:struct:`PyMemberDef`, :c:func:`PyMember_GetOne` and @@ -2015,14 +2268,14 @@ - The flags :c:macro:`Py_READONLY` (previously ``READONLY``) and :c:macro:`Py_AUDIT_READ` (previously all uppercase) - Several items are not exposed from ``Python.h``: + Several items are not exposed from :file:`Python.h`: - :c:macro:`T_OBJECT` (use :c:macro:`Py_T_OBJECT_EX`) - :c:macro:`T_NONE` (previously undocumented, and pretty quirky) - The macro ``WRITE_RESTRICTED`` which does nothing. - The macros ``RESTRICTED`` and ``READ_RESTRICTED``, equivalents of :c:macro:`Py_AUDIT_READ`. - - In some configurations, ```` is not included from ``Python.h``. + - In some configurations, ```` is not included from :file:`Python.h`. It should be included manually when using ``offsetof()``. The deprecated header continues to provide its original @@ -2049,11 +2302,98 @@ overrides :c:member:`~PyTypeObject.tp_new` is deprecated. Call the metaclass instead. +Pending Removal in Python 3.14 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* The ``ma_version_tag`` field in :c:type:`PyDictObject` for extension modules + (:pep:`699`; :gh:`101193`). + +* Global configuration variables: + + * :c:var:`Py_DebugFlag`: use :c:member:`PyConfig.parser_debug` + * :c:var:`Py_VerboseFlag`: use :c:member:`PyConfig.verbose` + * :c:var:`Py_QuietFlag`: use :c:member:`PyConfig.quiet` + * :c:var:`Py_InteractiveFlag`: use :c:member:`PyConfig.interactive` + * :c:var:`Py_InspectFlag`: use :c:member:`PyConfig.inspect` + * :c:var:`Py_OptimizeFlag`: use :c:member:`PyConfig.optimization_level` + * :c:var:`Py_NoSiteFlag`: use :c:member:`PyConfig.site_import` + * :c:var:`Py_BytesWarningFlag`: use :c:member:`PyConfig.bytes_warning` + * :c:var:`Py_FrozenFlag`: use :c:member:`PyConfig.pathconfig_warnings` + * :c:var:`Py_IgnoreEnvironmentFlag`: use :c:member:`PyConfig.use_environment` + * :c:var:`Py_DontWriteBytecodeFlag`: use :c:member:`PyConfig.write_bytecode` + * :c:var:`Py_NoUserSiteDirectory`: use :c:member:`PyConfig.user_site_directory` + * :c:var:`Py_UnbufferedStdioFlag`: use :c:member:`PyConfig.buffered_stdio` + * :c:var:`Py_HashRandomizationFlag`: use :c:member:`PyConfig.use_hash_seed` + and :c:member:`PyConfig.hash_seed` + * :c:var:`Py_IsolatedFlag`: use :c:member:`PyConfig.isolated` + * :c:var:`Py_LegacyWindowsFSEncodingFlag`: use :c:member:`PyPreConfig.legacy_windows_fs_encoding` + * :c:var:`Py_LegacyWindowsStdioFlag`: use :c:member:`PyConfig.legacy_windows_stdio` + * :c:var:`!Py_FileSystemDefaultEncoding`: use :c:member:`PyConfig.filesystem_encoding` + * :c:var:`!Py_HasFileSystemDefaultEncoding`: use :c:member:`PyConfig.filesystem_encoding` + * :c:var:`!Py_FileSystemDefaultEncodeErrors`: use :c:member:`PyConfig.filesystem_errors` + * :c:var:`!Py_UTF8Mode`: use :c:member:`PyPreConfig.utf8_mode` (see :c:func:`Py_PreInitialize`) + + The :c:func:`Py_InitializeFromConfig` API should be used with + :c:type:`PyConfig` instead. + +* Creating :c:data:`immutable types ` with mutable + bases (:gh:`95388`). + +Pending Removal in Python 3.15 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* :c:func:`PyImport_ImportModuleNoBlock`: use :c:func:`PyImport_ImportModule` +* :c:type:`!Py_UNICODE_WIDE` type: use :c:type:`wchar_t` +* :c:type:`Py_UNICODE` type: use :c:type:`wchar_t` +* Python initialization functions: + + * :c:func:`PySys_ResetWarnOptions`: clear :data:`sys.warnoptions` and + :data:`!warnings.filters` + * :c:func:`Py_GetExecPrefix`: get :data:`sys.exec_prefix` + * :c:func:`Py_GetPath`: get :data:`sys.path` + * :c:func:`Py_GetPrefix`: get :data:`sys.prefix` + * :c:func:`Py_GetProgramFullPath`: get :data:`sys.executable` + * :c:func:`Py_GetProgramName`: get :data:`sys.executable` + * :c:func:`Py_GetPythonHome`: get :c:member:`PyConfig.home` or + the :envvar:`PYTHONHOME` environment variable + +Pending Removal in Future Versions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The following APIs are deprecated and will be removed, +although there is currently no date scheduled for their removal. + +* :c:macro:`Py_TPFLAGS_HAVE_FINALIZE`: unneeded since Python 3.8 +* :c:func:`PyErr_Fetch`: use :c:func:`PyErr_GetRaisedException` +* :c:func:`PyErr_NormalizeException`: use :c:func:`PyErr_GetRaisedException` +* :c:func:`PyErr_Restore`: use :c:func:`PyErr_SetRaisedException` +* :c:func:`PyModule_GetFilename`: use :c:func:`PyModule_GetFilenameObject` +* :c:func:`PyOS_AfterFork`: use :c:func:`PyOS_AfterFork_Child` +* :c:func:`PySlice_GetIndicesEx`: use :c:func:`PySlice_Unpack` and :c:func:`PySlice_AdjustIndices` +* :c:func:`!PyUnicode_AsDecodedObject`: use :c:func:`PyCodec_Decode` +* :c:func:`!PyUnicode_AsDecodedUnicode`: use :c:func:`PyCodec_Decode` +* :c:func:`!PyUnicode_AsEncodedObject`: use :c:func:`PyCodec_Encode` +* :c:func:`!PyUnicode_AsEncodedUnicode`: use :c:func:`PyCodec_Encode` +* :c:func:`PyUnicode_READY`: unneeded since Python 3.12 +* :c:func:`!PyErr_Display`: use :c:func:`PyErr_DisplayException` +* :c:func:`!_PyErr_ChainExceptions`: use ``_PyErr_ChainExceptions1`` +* :c:member:`!PyBytesObject.ob_shash` member: + call :c:func:`PyObject_Hash` instead +* :c:member:`!PyDictObject.ma_version_tag` member +* Thread Local Storage (TLS) API: + + * :c:func:`PyThread_create_key`: use :c:func:`PyThread_tss_alloc` + * :c:func:`PyThread_delete_key`: use :c:func:`PyThread_tss_free` + * :c:func:`PyThread_set_key_value`: use :c:func:`PyThread_tss_set` + * :c:func:`PyThread_get_key_value`: use :c:func:`PyThread_tss_get` + * :c:func:`PyThread_delete_key_value`: use :c:func:`PyThread_tss_delete` + * :c:func:`PyThread_ReInitTLS`: unneeded since Python 3.7 + Removed ------- -* Remove the ``token.h`` header file. There was never any public tokenizer C - API. The ``token.h`` header file was only designed to be used by Python +* Remove the :file:`token.h` header file. There was never any public tokenizer C + API. The :file:`token.h` header file was only designed to be used by Python internals. (Contributed by Victor Stinner in :gh:`92651`.) diff -Nru python3.12-3.12.0~rc2/Doc/whatsnew/3.3.rst python3.12-3.12.0/Doc/whatsnew/3.3.rst --- python3.12-3.12.0~rc2/Doc/whatsnew/3.3.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/whatsnew/3.3.rst 2023-10-02 11:48:14.000000000 +0000 @@ -2067,7 +2067,7 @@ Other new functions: * :func:`~time.clock_getres`, :func:`~time.clock_gettime` and - :func:`~time.clock_settime` functions with ``CLOCK_xxx`` constants. + :func:`~time.clock_settime` functions with :samp:`CLOCK_{xxx}` constants. (Contributed by Victor Stinner in :issue:`10278`.) To improve cross platform consistency, :func:`~time.sleep` now raises a diff -Nru python3.12-3.12.0~rc2/Doc/whatsnew/3.4.rst python3.12-3.12.0/Doc/whatsnew/3.4.rst --- python3.12-3.12.0~rc2/Doc/whatsnew/3.4.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/whatsnew/3.4.rst 2023-10-02 11:48:14.000000000 +0000 @@ -2085,7 +2085,7 @@ :meth:`importlib.abc.MetaPathFinder.find_spec`; :meth:`!importlib.abc.PathEntryFinder.find_loader` and :meth:`!find_module` are replaced by - :meth:`importlib.abc.PathEntryFinder.find_spec`; all of the ``xxxLoader`` ABC + :meth:`importlib.abc.PathEntryFinder.find_spec`; all of the :samp:`{xxx}Loader` ABC ``load_module`` methods (:meth:`!importlib.abc.Loader.load_module`, :meth:`!importlib.abc.InspectLoader.load_module`, :meth:`!importlib.abc.FileLoader.load_module`, diff -Nru python3.12-3.12.0~rc2/Doc/whatsnew/3.8.rst python3.12-3.12.0/Doc/whatsnew/3.8.rst --- python3.12-3.12.0~rc2/Doc/whatsnew/3.8.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/whatsnew/3.8.rst 2023-10-02 11:48:14.000000000 +0000 @@ -404,7 +404,7 @@ or :meth:`~object.__complex__` is not available. (Contributed by Serhiy Storchaka in :issue:`20092`.) -* Added support of ``\N{name}`` escapes in :mod:`regular expressions `:: +* Added support of :samp:`\\N\\{{name}\\}` escapes in :mod:`regular expressions `:: >>> notice = 'Copyright © 2019' >>> copyright_year_pattern = re.compile(r'\N{copyright sign}\s*(\d{4})') @@ -947,7 +947,7 @@ logging configuration options using the interactive prompt or a Jupyter notebook. -(Suggested by Raymond Hettinger, implemented by Dong-hee Na, and +(Suggested by Raymond Hettinger, implemented by Donghee Na, and reviewed by Vinay Sajip in :issue:`33897`.) @@ -1714,7 +1714,7 @@ * The :meth:`~threading.Thread.isAlive()` method of :class:`threading.Thread` has been deprecated. - (Contributed by Dong-hee Na in :issue:`35283`.) + (Contributed by Donghee Na in :issue:`35283`.) * Many builtin and extension functions that take integer arguments will now emit a deprecation warning for :class:`~decimal.Decimal`\ s, diff -Nru python3.12-3.12.0~rc2/Doc/whatsnew/3.9.rst python3.12-3.12.0/Doc/whatsnew/3.9.rst --- python3.12-3.12.0~rc2/Doc/whatsnew/3.9.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Doc/whatsnew/3.9.rst 2023-10-02 11:48:14.000000000 +0000 @@ -44,7 +44,6 @@ This article explains the new features in Python 3.9, compared to 3.8. Python 3.9 was released on October 5, 2020. - For full details, see the :ref:`changelog `. .. seealso:: @@ -415,7 +414,7 @@ The :meth:`~datetime.date.isocalendar()` of :class:`datetime.date` and :meth:`~datetime.datetime.isocalendar()` of :class:`datetime.datetime` methods now returns a :func:`~collections.namedtuple` instead of a :class:`tuple`. -(Contributed by Dong-hee Na in :issue:`24416`.) +(Contributed by Donghee Na in :issue:`24416`.) distutils --------- @@ -429,14 +428,14 @@ Added constants :const:`~fcntl.F_OFD_GETLK`, :const:`~fcntl.F_OFD_SETLK` and :const:`~fcntl.F_OFD_SETLKW`. -(Contributed by Dong-hee Na in :issue:`38602`.) +(Contributed by Donghee Na in :issue:`38602`.) ftplib ------- :class:`~ftplib.FTP` and :class:`~ftplib.FTP_TLS` now raise a :class:`ValueError` if the given timeout for their constructor is zero to prevent the creation of -a non-blocking socket. (Contributed by Dong-hee Na in :issue:`39259`.) +a non-blocking socket. (Contributed by Donghee Na in :issue:`39259`.) gc -- @@ -468,7 +467,7 @@ ---- HTTP status codes ``103 EARLY_HINTS``, ``418 IM_A_TEAPOT`` and ``425 TOO_EARLY`` are added to -:class:`http.HTTPStatus`. (Contributed by Dong-hee Na in :issue:`39509` and Ross Rhodes in :issue:`39507`.) +:class:`http.HTTPStatus`. (Contributed by Donghee Na in :issue:`39509` and Ross Rhodes in :issue:`39507`.) IDLE and idlelib ---------------- @@ -509,14 +508,14 @@ Also, the :meth:`~imaplib.IMAP4.open` method now has an optional *timeout* parameter with this change. The overridden methods of :class:`~imaplib.IMAP4_SSL` and :class:`~imaplib.IMAP4_stream` were applied to this change. -(Contributed by Dong-hee Na in :issue:`38615`.) +(Contributed by Donghee Na in :issue:`38615`.) :meth:`imaplib.IMAP4.unselect` is added. :meth:`imaplib.IMAP4.unselect` frees server's resources associated with the selected mailbox and returns the server to the authenticated state. This command performs the same actions as :meth:`imaplib.IMAP4.close`, except that no messages are permanently removed from the currently -selected mailbox. (Contributed by Dong-hee Na in :issue:`40375`.) +selected mailbox. (Contributed by Donghee Na in :issue:`40375`.) importlib --------- @@ -588,13 +587,13 @@ :class:`~nntplib.NNTP` and :class:`~nntplib.NNTP_SSL` now raise a :class:`ValueError` if the given timeout for their constructor is zero to prevent the creation of -a non-blocking socket. (Contributed by Dong-hee Na in :issue:`39259`.) +a non-blocking socket. (Contributed by Donghee Na in :issue:`39259`.) os -- Added :const:`~os.CLD_KILLED` and :const:`~os.CLD_STOPPED` for :attr:`si_code`. -(Contributed by Dong-hee Na in :issue:`38493`.) +(Contributed by Donghee Na in :issue:`38493`.) Exposed the Linux-specific :func:`os.pidfd_open` (:issue:`38692`) and :const:`os.P_PIDFD` (:issue:`38713`) for process management with file @@ -629,7 +628,7 @@ :class:`~poplib.POP3` and :class:`~poplib.POP3_SSL` now raise a :class:`ValueError` if the given timeout for their constructor is zero to prevent the creation of -a non-blocking socket. (Contributed by Dong-hee Na in :issue:`39259`.) +a non-blocking socket. (Contributed by Donghee Na in :issue:`39259`.) pprint ------ @@ -661,10 +660,10 @@ :class:`~smtplib.SMTP` and :class:`~smtplib.SMTP_SSL` now raise a :class:`ValueError` if the given timeout for their constructor is zero to prevent the creation of -a non-blocking socket. (Contributed by Dong-hee Na in :issue:`39259`.) +a non-blocking socket. (Contributed by Donghee Na in :issue:`39259`.) :class:`~smtplib.LMTP` constructor now has an optional *timeout* parameter. -(Contributed by Dong-hee Na in :issue:`39329`.) +(Contributed by Donghee Na in :issue:`39329`.) socket ------ @@ -777,7 +776,7 @@ * A number of Python builtins (:class:`range`, :class:`tuple`, :class:`set`, :class:`frozenset`, :class:`list`, :class:`dict`) are now sped up by using :pep:`590` vectorcall protocol. - (Contributed by Dong-hee Na, Mark Shannon, Jeroen Demeyer and Petr Viktorin in :issue:`37207`.) + (Contributed by Donghee Na, Mark Shannon, Jeroen Demeyer and Petr Viktorin in :issue:`37207`.) * Optimized :func:`~set.difference_update` for the case when the other set is much larger than the base set. @@ -791,7 +790,7 @@ * :term:`floor division` of float operation now has a better performance. Also the message of :exc:`ZeroDivisionError` for this operation is updated. - (Contributed by Dong-hee Na in :issue:`39434`.) + (Contributed by Donghee Na in :issue:`39434`.) * Decoding short ASCII strings with UTF-8 and ascii codecs is now about 15% faster. (Contributed by Inada Naoki in :issue:`37348`.) @@ -961,7 +960,7 @@ are not supported or not enabled by NNTP server administrators. For ``xgtitle()``, please use :meth:`nntplib.NNTP.descriptions` or :meth:`nntplib.NNTP.description` instead. - (Contributed by Dong-hee Na in :issue:`39366`.) + (Contributed by Donghee Na in :issue:`39366`.) * :class:`array.array`: ``tostring()`` and ``fromstring()`` methods have been removed. They were aliases to ``tobytes()`` and ``frombytes()``, deprecated @@ -994,7 +993,7 @@ * The :meth:`~threading.Thread.isAlive()` method of :class:`threading.Thread` has been removed. It was deprecated since Python 3.8. Use :meth:`~threading.Thread.is_alive()` instead. - (Contributed by Dong-hee Na in :issue:`37804`.) + (Contributed by Donghee Na in :issue:`37804`.) * Methods ``getchildren()`` and ``getiterator()`` of classes :class:`~xml.etree.ElementTree.ElementTree` and @@ -1315,7 +1314,7 @@ * The :c:func:`PyModule_AddType` function is added to help adding a type to a module. - (Contributed by Dong-hee Na in :issue:`40024`.) + (Contributed by Donghee Na in :issue:`40024`.) * Added the functions :c:func:`PyObject_GC_IsTracked` and :c:func:`PyObject_GC_IsFinalized` to the public API to allow to query if diff -Nru python3.12-3.12.0~rc2/Grammar/python.gram python3.12-3.12.0/Grammar/python.gram --- python3.12-3.12.0~rc2/Grammar/python.gram 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Grammar/python.gram 2023-10-02 11:48:14.000000000 +0000 @@ -1170,7 +1170,7 @@ _PyPegen_check_legacy_stmt(p, a) ? NULL : p->tokens[p->mark-1]->level == 0 ? NULL : RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "invalid syntax. Perhaps you forgot a comma?") } | a=disjunction 'if' b=disjunction !('else'|':') { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "expected 'else' after 'if' expression") } - | a='lambda' [lambda_params] b=':' &(FSTRING_MIDDLE | fstring_replacement_field) { + | a='lambda' [lambda_params] b=':' &FSTRING_MIDDLE { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "f-string: lambda expressions are not allowed without parentheses") } invalid_named_expression(memo): diff -Nru python3.12-3.12.0~rc2/Include/object.h python3.12-3.12.0/Include/object.h --- python3.12-3.12.0~rc2/Include/object.h 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Include/object.h 2023-10-02 11:48:14.000000000 +0000 @@ -679,17 +679,15 @@ #elif defined(Py_REF_DEBUG) static inline void Py_DECREF(const char *filename, int lineno, PyObject *op) { + if (op->ob_refcnt <= 0) { + _Py_NegativeRefcount(filename, lineno, op); + } if (_Py_IsImmortal(op)) { return; } _Py_DECREF_STAT_INC(); _Py_DECREF_DecRefTotal(); - if (--op->ob_refcnt != 0) { - if (op->ob_refcnt < 0) { - _Py_NegativeRefcount(filename, lineno, op); - } - } - else { + if (--op->ob_refcnt == 0) { _Py_Dealloc(op); } } diff -Nru python3.12-3.12.0~rc2/Include/patchlevel.h python3.12-3.12.0/Include/patchlevel.h --- python3.12-3.12.0~rc2/Include/patchlevel.h 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Include/patchlevel.h 2023-10-02 11:48:14.000000000 +0000 @@ -19,11 +19,11 @@ #define PY_MAJOR_VERSION 3 #define PY_MINOR_VERSION 12 #define PY_MICRO_VERSION 0 -#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_GAMMA -#define PY_RELEASE_SERIAL 2 +#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL +#define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "3.12.0rc2" +#define PY_VERSION "3.12.0" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff -Nru python3.12-3.12.0~rc2/Lib/ast.py python3.12-3.12.0/Lib/ast.py --- python3.12-3.12.0~rc2/Lib/ast.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/ast.py 2023-10-02 11:48:14.000000000 +0000 @@ -1234,17 +1234,36 @@ new_fstring_parts = [] quote_types = list(_ALL_QUOTES) + fallback_to_repr = False for value, is_constant in fstring_parts: if is_constant: - value, quote_types = self._str_literal_helper( + value, new_quote_types = self._str_literal_helper( value, quote_types=quote_types, escape_special_whitespace=True, ) + if set(new_quote_types).isdisjoint(quote_types): + fallback_to_repr = True + break + quote_types = new_quote_types elif "\n" in value: quote_types = [q for q in quote_types if q in _MULTI_QUOTES] + assert quote_types new_fstring_parts.append(value) + if fallback_to_repr: + # If we weren't able to find a quote type that works for all parts + # of the JoinedStr, fallback to using repr and triple single quotes. + quote_types = ["'''"] + new_fstring_parts.clear() + for value, is_constant in fstring_parts: + if is_constant: + value = repr('"' + value) # force repr to use single quotes + expected_prefix = "'\"" + assert value.startswith(expected_prefix), repr(value) + value = value[len(expected_prefix):-1] + new_fstring_parts.append(value) + value = "".join(new_fstring_parts) quote_type = quote_types[0] self.write(f"{quote_type}{value}{quote_type}") diff -Nru python3.12-3.12.0~rc2/Lib/calendar.py python3.12-3.12.0/Lib/calendar.py --- python3.12-3.12.0~rc2/Lib/calendar.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/calendar.py 2023-10-02 11:48:14.000000000 +0000 @@ -723,7 +723,7 @@ parser.add_argument( "-L", "--locale", default=None, - help="locale to be used from month and weekday names" + help="locale to use for month and weekday names" ) parser.add_argument( "-e", "--encoding", diff -Nru python3.12-3.12.0~rc2/Lib/enum.py python3.12-3.12.0/Lib/enum.py --- python3.12-3.12.0~rc2/Lib/enum.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/enum.py 2023-10-02 11:48:14.000000000 +0000 @@ -739,6 +739,11 @@ value = (value, names) + values return cls.__new__(cls, value) # otherwise, functional API: we're creating a new Enum type + if names is None and type is None: + # no body? no data-type? possibly wrong usage + raise TypeError( + f"{cls} has no members; specify `names=()` if you meant to create a new, empty, enum" + ) return cls._create_( class_name=value, names=names, diff -Nru python3.12-3.12.0~rc2/Lib/_pydatetime.py python3.12-3.12.0/Lib/_pydatetime.py --- python3.12-3.12.0~rc2/Lib/_pydatetime.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/_pydatetime.py 2023-10-02 11:48:14.000000000 +0000 @@ -1236,7 +1236,7 @@ class tzinfo: """Abstract base class for time zone info classes. - Subclasses must override the name(), utcoffset() and dst() methods. + Subclasses must override the tzname(), utcoffset() and dst() methods. """ __slots__ = () diff -Nru python3.12-3.12.0~rc2/Lib/pydoc_data/topics.py python3.12-3.12.0/Lib/pydoc_data/topics.py --- python3.12-3.12.0~rc2/Lib/pydoc_data/topics.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/pydoc_data/topics.py 2023-10-02 11:48:14.000000000 +0000 @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Tue Sep 5 23:56:33 2023 +# Autogenerated by Sphinx on Mon Oct 2 13:45:14 2023 # as part of the release process. topics = {'assert': 'The "assert" statement\n' '**********************\n' @@ -13016,71 +13016,71 @@ 'those\n' 'used by Standard C. The recognized escape sequences are:\n' '\n' - '+-------------------+-----------------------------------+---------+\n' - '| Escape Sequence | Meaning | Notes ' - '|\n' - '|===================|===================================|=========|\n' - '| "\\" | Backslash and newline ignored | ' - '(1) |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\\\" | Backslash ("\\") ' + '+---------------------------+-----------------------------------+---------+\n' + '| Escape Sequence | Meaning | ' + 'Notes |\n' + '|===========================|===================================|=========|\n' + '| "\\" | Backslash and newline ignored ' + '| (1) |\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\\\" | Backslash ' + '("\\") | |\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\\'" | Single quote ' + '("\'") | |\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\"" | Double quote (""") ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\\'" | Single quote ("\'") ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\a" | ASCII Bell (BEL) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\"" | Double quote (""") ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\b" | ASCII Backspace (BS) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\a" | ASCII Bell (BEL) ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\f" | ASCII Formfeed (FF) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\b" | ASCII Backspace (BS) ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\n" | ASCII Linefeed (LF) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\f" | ASCII Formfeed (FF) ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\r" | ASCII Carriage Return (CR) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\n" | ASCII Linefeed (LF) ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\t" | ASCII Horizontal Tab (TAB) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\r" | ASCII Carriage Return (CR) ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\v" | ASCII Vertical Tab (VT) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\t" | ASCII Horizontal Tab (TAB) ' - '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\v" | ASCII Vertical Tab (VT) ' - '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\ooo" | Character with octal value *ooo* | ' - '(2,4) |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\xhh" | Character with hex value *hh* | ' - '(3,4) |\n' - '+-------------------+-----------------------------------+---------+\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\*ooo*" | Character with octal value *ooo* ' + '| (2,4) |\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\x*hh*" | Character with hex value *hh* ' + '| (3,4) |\n' + '+---------------------------+-----------------------------------+---------+\n' '\n' 'Escape sequences only recognized in string literals are:\n' '\n' - '+-------------------+-----------------------------------+---------+\n' - '| Escape Sequence | Meaning | Notes ' - '|\n' - '|===================|===================================|=========|\n' - '| "\\N{name}" | Character named *name* in the | ' - '(5) |\n' - '| | Unicode database | ' - '|\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\uxxxx" | Character with 16-bit hex value | ' - '(6) |\n' - '| | *xxxx* | ' - '|\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\Uxxxxxxxx" | Character with 32-bit hex value | ' - '(7) |\n' - '| | *xxxxxxxx* | ' - '|\n' - '+-------------------+-----------------------------------+---------+\n' + '+---------------------------+-----------------------------------+---------+\n' + '| Escape Sequence | Meaning | ' + 'Notes |\n' + '|===========================|===================================|=========|\n' + '| "\\N{*name*}" | Character named *name* in the ' + '| (5) |\n' + '| | Unicode database ' + '| |\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\u*xxxx*" | Character with 16-bit hex value ' + '| (6) |\n' + '| | *xxxx* ' + '| |\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\U*xxxxxxxx*" | Character with 32-bit hex value ' + '| (7) |\n' + '| | *xxxxxxxx* ' + '| |\n' + '+---------------------------+-----------------------------------+---------+\n' '\n' 'Notes:\n' '\n' diff -Nru python3.12-3.12.0~rc2/Lib/random.py python3.12-3.12.0/Lib/random.py --- python3.12-3.12.0~rc2/Lib/random.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/random.py 2023-10-02 11:48:14.000000000 +0000 @@ -827,7 +827,7 @@ return k # Acceptance-rejection test. - # Note, the original paper errorneously omits the call to log(v) + # Note, the original paper erroneously omits the call to log(v) # when comparing to the log of the rescaled binomial distribution. if not setup_complete: alpha = (2.83 + 5.1 / b) * spq diff -Nru python3.12-3.12.0~rc2/Lib/symtable.py python3.12-3.12.0/Lib/symtable.py --- python3.12-3.12.0~rc2/Lib/symtable.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/symtable.py 2023-10-02 11:48:14.000000000 +0000 @@ -62,8 +62,8 @@ def get_type(self): """Return the type of the symbol table. - The values returned are 'class', 'module' and - 'function'. + The values returned are 'class', 'module', 'function', + 'annotation', 'TypeVar bound', 'type alias', and 'type parameter'. """ if self._table.type == _symtable.TYPE_MODULE: return "module" @@ -71,8 +71,15 @@ return "function" if self._table.type == _symtable.TYPE_CLASS: return "class" - assert self._table.type in (1, 2, 3), \ - "unexpected type: {0}".format(self._table.type) + if self._table.type == _symtable.TYPE_ANNOTATION: + return "annotation" + if self._table.type == _symtable.TYPE_TYPE_VAR_BOUND: + return "TypeVar bound" + if self._table.type == _symtable.TYPE_TYPE_ALIAS: + return "type alias" + if self._table.type == _symtable.TYPE_TYPE_PARAM: + return "type parameter" + assert False, f"unexpected type: {self._table.type}" def get_id(self): """Return an identifier for the table. diff -Nru python3.12-3.12.0~rc2/Lib/test/bisect_cmd.py python3.12-3.12.0/Lib/test/bisect_cmd.py --- python3.12-3.12.0~rc2/Lib/test/bisect_cmd.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/bisect_cmd.py 2023-10-02 11:48:14.000000000 +0000 @@ -109,9 +109,10 @@ def main(): args = parse_args() - if '-w' in args.test_args or '--verbose2' in args.test_args: - print("WARNING: -w/--verbose2 option should not be used to bisect!") - print() + for opt in ('-w', '--rerun', '--verbose2'): + if opt in args.test_args: + print(f"WARNING: {opt} option should not be used to bisect!") + print() if args.input: with open(args.input) as fp: diff -Nru python3.12-3.12.0~rc2/Lib/test/libregrtest/cmdline.py python3.12-3.12.0/Lib/test/libregrtest/cmdline.py --- python3.12-3.12.0~rc2/Lib/test/libregrtest/cmdline.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/libregrtest/cmdline.py 2023-10-02 11:48:14.000000000 +0000 @@ -107,6 +107,8 @@ cpu - Used for certain CPU-heavy tests. + walltime - Long running but not CPU-bound tests. + subprocess Run all tests for the subprocess module. urlfetch - It is okay to download files required on testing. @@ -129,7 +131,7 @@ ALL_RESOURCES = ('audio', 'curses', 'largefile', 'network', - 'decimal', 'cpu', 'subprocess', 'urlfetch', 'gui') + 'decimal', 'cpu', 'subprocess', 'urlfetch', 'gui', 'walltime') # Other resources excluded from --use=all: # @@ -156,7 +158,7 @@ self.coverdir = 'coverage' self.runleaks = False self.huntrleaks = False - self.verbose2 = False + self.rerun = False self.verbose3 = False self.print_slow = False self.random_seed = None @@ -213,8 +215,10 @@ group = parser.add_argument_group('Verbosity') group.add_argument('-v', '--verbose', action='count', help='run tests in verbose mode with output to stdout') - group.add_argument('-w', '--verbose2', action='store_true', + group.add_argument('-w', '--rerun', action='store_true', help='re-run failed tests in verbose mode') + group.add_argument('--verbose2', action='store_true', dest='rerun', + help='deprecated alias to --rerun') group.add_argument('-W', '--verbose3', action='store_true', help='display test output on failure') group.add_argument('-q', '--quiet', action='store_true', @@ -309,6 +313,9 @@ group.add_argument('--fail-env-changed', action='store_true', help='if a test file alters the environment, mark ' 'the test as failed') + group.add_argument('--fail-rerun', action='store_true', + help='if a test failed and then passed when re-run, ' + 'mark the tests as failed') group.add_argument('--junit-xml', dest='xmlpath', metavar='FILENAME', help='writes JUnit-style XML results to the specified ' @@ -380,7 +387,7 @@ ns.python = shlex.split(ns.python) if ns.failfast and not (ns.verbose or ns.verbose3): parser.error("-G/--failfast needs either -v or -W") - if ns.pgo and (ns.verbose or ns.verbose2 or ns.verbose3): + if ns.pgo and (ns.verbose or ns.rerun or ns.verbose3): parser.error("--pgo/-v don't go together!") if ns.pgo_extended: ns.pgo = True # pgo_extended implies pgo diff -Nru python3.12-3.12.0~rc2/Lib/test/libregrtest/main.py python3.12-3.12.0/Lib/test/libregrtest/main.py --- python3.12-3.12.0~rc2/Lib/test/libregrtest/main.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/libregrtest/main.py 2023-10-02 11:48:14.000000000 +0000 @@ -11,11 +11,11 @@ import unittest from test.libregrtest.cmdline import _parse_args from test.libregrtest.runtest import ( - findtests, split_test_packages, runtest, get_abs_module, - PROGRESS_MIN_TIME, State) + findtests, split_test_packages, runtest, abs_module_name, + PROGRESS_MIN_TIME, State, MatchTestsDict, RunTests) from test.libregrtest.setup import setup_tests from test.libregrtest.pgo import setup_pgo_tests -from test.libregrtest.utils import (removepy, count, format_duration, +from test.libregrtest.utils import (strip_py_suffix, count, format_duration, printlist, get_build_info) from test import support from test.support import TestStats @@ -28,18 +28,11 @@ # Must be smaller than buildbot "1200 seconds without output" limit. EXIT_TIMEOUT = 120.0 -# gh-90681: When rerunning tests, we might need to rerun the whole -# class or module suite if some its life-cycle hooks fail. -# Test level hooks are not affected. -_TEST_LIFECYCLE_HOOKS = frozenset(( - 'setUpClass', 'tearDownClass', - 'setUpModule', 'tearDownModule', -)) - EXITCODE_BAD_TEST = 2 -EXITCODE_INTERRUPTED = 130 EXITCODE_ENV_CHANGED = 3 EXITCODE_NO_TESTS_RAN = 4 +EXITCODE_RERUN_FAIL = 5 +EXITCODE_INTERRUPTED = 130 class Regrtest: @@ -72,19 +65,22 @@ # tests self.tests = [] self.selected = [] + self.all_runtests: list[RunTests] = [] # test results - self.good = [] - self.bad = [] - self.skipped = [] - self.resource_denied = [] - self.environment_changed = [] - self.run_no_tests = [] - self.need_rerun = [] - self.rerun = [] - self.first_result = None + self.good: list[str] = [] + self.bad: list[str] = [] + self.rerun_bad: list[str] = [] + self.skipped: list[str] = [] + self.resource_denied: list[str] = [] + self.environment_changed: list[str] = [] + self.run_no_tests: list[str] = [] + self.rerun: list[str] = [] + + self.need_rerun: list[TestResult] = [] + self.first_state: str | None = None self.interrupted = False - self.stats_dict: dict[str, TestStats] = {} + self.total_stats = TestStats() # used by --slow self.test_times = [] @@ -94,7 +90,7 @@ # used to display the progress bar "[ 3/100]" self.start_time = time.perf_counter() - self.test_count = '' + self.test_count_text = '' self.test_count_width = 1 # used by --single @@ -107,7 +103,6 @@ # misc self.win_load_tracker = None self.tmp_dir = None - self.worker_test_name = None def get_executed(self): return (set(self.good) | set(self.bad) | set(self.skipped) @@ -115,11 +110,9 @@ | set(self.run_no_tests)) def accumulate_result(self, result, rerun=False): + fail_env_changed = self.ns.fail_env_changed test_name = result.test_name - if result.has_meaningful_duration() and not rerun: - self.test_times.append((result.duration, test_name)) - match result.state: case State.PASSED: self.good.append(test_name) @@ -128,25 +121,24 @@ case State.SKIPPED: self.skipped.append(test_name) case State.RESOURCE_DENIED: - self.skipped.append(test_name) self.resource_denied.append(test_name) case State.INTERRUPTED: self.interrupted = True case State.DID_NOT_RUN: self.run_no_tests.append(test_name) case _: - if result.is_failed(self.ns.fail_env_changed): - if not rerun: - self.bad.append(test_name) - self.need_rerun.append(result) + if result.is_failed(fail_env_changed): + self.bad.append(test_name) + self.need_rerun.append(result) else: - raise ValueError(f"invalid test state: {state!r}") + raise ValueError(f"invalid test state: {result.state!r}") + if result.has_meaningful_duration() and not rerun: + self.test_times.append((result.duration, test_name)) if result.stats is not None: - self.stats_dict[result.test_name] = result.stats - - if rerun and not(result.is_failed(False) or result.state == State.INTERRUPTED): - self.bad.remove(test_name) + self.total_stats.accumulate(result.stats) + if rerun: + self.rerun.append(test_name) xml_data = result.xml_data if xml_data: @@ -180,13 +172,15 @@ print(line, flush=True) def display_progress(self, test_index, text): - if self.ns.quiet: + quiet = self.ns.quiet + pgo = self.ns.pgo + if quiet: return # "[ 51/405/1] test_tcl passed" - line = f"{test_index:{self.test_count_width}}{self.test_count}" + line = f"{test_index:{self.test_count_width}}{self.test_count_text}" fails = len(self.bad) + len(self.environment_changed) - if fails and not self.ns.pgo: + if fails and not pgo: line = f"{line}/{fails}" self.log(f"[{line}] {text}") @@ -196,15 +190,7 @@ if ns.xmlpath: support.junit_xml_list = self.testsuite_xml = [] - worker_args = ns.worker_args - if worker_args is not None: - from test.libregrtest.runtest_mp import parse_worker_args - ns, test_name = parse_worker_args(ns.worker_args) - ns.worker_args = worker_args - self.worker_test_name = test_name - - # Strip .py extensions. - removepy(ns.args) + strip_py_suffix(ns.args) if ns.huntrleaks: warmup, repetitions, _ = ns.huntrleaks @@ -221,9 +207,18 @@ self.ns = ns def find_tests(self, tests): + ns = self.ns + single = ns.single + fromfile = ns.fromfile + pgo = ns.pgo + exclude = ns.exclude + test_dir = ns.testdir + starting_test = ns.start + randomize = ns.randomize + self.tests = tests - if self.ns.single: + if single: self.next_single_filename = os.path.join(self.tmp_dir, 'pynexttest') try: with open(self.next_single_filename, 'r') as fp: @@ -232,12 +227,12 @@ except OSError: pass - if self.ns.fromfile: + if fromfile: self.tests = [] # regex to match 'test_builtin' in line: # '0:00:00 [ 4/400] test_builtin -- test_dict took 1 sec' regex = re.compile(r'\btest_[a-zA-Z0-9_]+\b') - with open(os.path.join(os_helper.SAVEDCWD, self.ns.fromfile)) as fp: + with open(os.path.join(os_helper.SAVEDCWD, fromfile)) as fp: for line in fp: line = line.split('#', 1)[0] line = line.strip() @@ -245,22 +240,22 @@ if match is not None: self.tests.append(match.group()) - removepy(self.tests) + strip_py_suffix(self.tests) - if self.ns.pgo: + if pgo: # add default PGO tests if no tests are specified - setup_pgo_tests(self.ns) + setup_pgo_tests(ns) - exclude = set() - if self.ns.exclude: - for arg in self.ns.args: - exclude.add(arg) - self.ns.args = [] + exclude_tests = set() + if exclude: + for arg in ns.args: + exclude_tests.add(arg) + ns.args = [] - alltests = findtests(testdir=self.ns.testdir, exclude=exclude) + alltests = findtests(testdir=test_dir, exclude=exclude_tests) - if not self.ns.fromfile: - self.selected = self.tests or self.ns.args + if not fromfile: + self.selected = self.tests or ns.args if self.selected: self.selected = split_test_packages(self.selected) else: @@ -268,7 +263,7 @@ else: self.selected = self.tests - if self.ns.single: + if single: self.selected = self.selected[:1] try: pos = alltests.index(self.selected[0]) @@ -277,17 +272,17 @@ pass # Remove all the selected tests that precede start if it's set. - if self.ns.start: + if starting_test: try: - del self.selected[:self.selected.index(self.ns.start)] + del self.selected[:self.selected.index(starting_test)] except ValueError: - print("Couldn't find starting test (%s), using all tests" - % self.ns.start, file=sys.stderr) + print(f"Cannot find starting test: {starting_test}") + sys.exit(1) - if self.ns.randomize: - if self.ns.random_seed is None: - self.ns.random_seed = random.randrange(10000000) - random.seed(self.ns.random_seed) + if randomize: + if ns.random_seed is None: + ns.random_seed = random.randrange(10000000) + random.seed(ns.random_seed) random.shuffle(self.selected) def list_tests(self): @@ -305,25 +300,63 @@ print(test.id()) def list_cases(self): + ns = self.ns + test_dir = ns.testdir support.verbose = False - support.set_match_tests(self.ns.match_tests, self.ns.ignore_tests) + support.set_match_tests(ns.match_tests, ns.ignore_tests) + skipped = [] for test_name in self.selected: - abstest = get_abs_module(self.ns, test_name) + module_name = abs_module_name(test_name, test_dir) try: - suite = unittest.defaultTestLoader.loadTestsFromName(abstest) + suite = unittest.defaultTestLoader.loadTestsFromName(module_name) self._list_cases(suite) except unittest.SkipTest: - self.skipped.append(test_name) + skipped.append(test_name) + + if skipped: + sys.stdout.flush() + stderr = sys.stderr + print(file=stderr) + print(count(len(skipped), "test"), "skipped:", file=stderr) + printlist(skipped, file=stderr) - if self.skipped: - print(file=sys.stderr) - print(count(len(self.skipped), "test"), "skipped:", file=sys.stderr) - printlist(self.skipped, file=sys.stderr) + def get_rerun_match(self, rerun_list) -> MatchTestsDict: + rerun_match_tests = {} + for result in rerun_list: + match_tests = result.get_rerun_match_tests() + # ignore empty match list + if match_tests: + rerun_match_tests[result.test_name] = match_tests + return rerun_match_tests + + def _rerun_failed_tests(self, need_rerun): + # Configure the runner to re-run tests + ns = self.ns + ns.verbose = True + ns.failfast = False + ns.verbose3 = False + ns.forever = False + if ns.use_mp is None: + ns.use_mp = 1 + + # Get tests to re-run + tests = [result.test_name for result in need_rerun] + match_tests = self.get_rerun_match(need_rerun) + self.set_tests(tests) + + # Clear previously failed tests + self.rerun_bad.extend(self.bad) + self.bad.clear() + self.need_rerun.clear() - def rerun_failed_tests(self): - self.log() + # Re-run failed tests + self.log(f"Re-running {len(tests)} failed tests in verbose mode in subprocesses") + runtests = RunTests(tests, match_tests=match_tests, rerun=True) + self.all_runtests.append(runtests) + self._run_tests_mp(runtests) + def rerun_failed_tests(self, need_rerun): if self.ns.python: # Temp patch for https://github.com/python/cpython/issues/94052 self.log( @@ -332,45 +365,10 @@ ) return - self.ns.verbose = True - self.ns.failfast = False - self.ns.verbose3 = False - - self.first_result = self.get_tests_result() - - self.log("Re-running failed tests in verbose mode") - rerun_list = list(self.need_rerun) - self.need_rerun.clear() - for result in rerun_list: - test_name = result.test_name - self.rerun.append(test_name) - - errors = result.errors or [] - failures = result.failures or [] - error_names = [ - self.normalize_test_name(test_full_name, is_error=True) - for (test_full_name, *_) in errors] - failure_names = [ - self.normalize_test_name(test_full_name) - for (test_full_name, *_) in failures] - self.ns.verbose = True - orig_match_tests = self.ns.match_tests - if errors or failures: - if self.ns.match_tests is None: - self.ns.match_tests = [] - self.ns.match_tests.extend(error_names) - self.ns.match_tests.extend(failure_names) - matching = "matching: " + ", ".join(self.ns.match_tests) - self.log(f"Re-running {test_name} in verbose mode ({matching})") - else: - self.log(f"Re-running {test_name} in verbose mode") - result = runtest(self.ns, test_name) - self.ns.match_tests = orig_match_tests - - self.accumulate_result(result, rerun=True) + self.first_state = self.get_tests_state() - if result.state == State.INTERRUPTED: - break + print() + self._rerun_failed_tests(need_rerun) if self.bad: print(count(len(self.bad), 'test'), "failed again:") @@ -378,28 +376,17 @@ self.display_result() - def normalize_test_name(self, test_full_name, *, is_error=False): - short_name = test_full_name.split(" ")[0] - if is_error and short_name in _TEST_LIFECYCLE_HOOKS: - # This means that we have a failure in a life-cycle hook, - # we need to rerun the whole module or class suite. - # Basically the error looks like this: - # ERROR: setUpClass (test.test_reg_ex.RegTest) - # or - # ERROR: setUpModule (test.test_reg_ex) - # So, we need to parse the class / module name. - lpar = test_full_name.index('(') - rpar = test_full_name.index(')') - return test_full_name[lpar + 1: rpar].split('.')[-1] - return short_name - def display_result(self): + pgo = self.ns.pgo + quiet = self.ns.quiet + print_slow = self.ns.print_slow + # If running the test suite for PGO then no one cares about results. - if self.ns.pgo: + if pgo: return print() - print("== Tests result: %s ==" % self.get_tests_result()) + print("== Tests result: %s ==" % self.get_tests_state()) if self.interrupted: print("Test suite interrupted by signal SIGINT.") @@ -410,7 +397,7 @@ print(count(len(omitted), "test"), "omitted:") printlist(omitted) - if self.good and not self.ns.quiet: + if self.good and not quiet: print() if (not self.bad and not self.skipped @@ -419,7 +406,7 @@ print("All", end=' ') print(count(len(self.good), "test"), "OK.") - if self.ns.print_slow: + if print_slow: self.test_times.sort(reverse=True) print() print("10 slowest tests:") @@ -437,11 +424,16 @@ count(len(self.environment_changed), "test"))) printlist(self.environment_changed) - if self.skipped and not self.ns.quiet: + if self.skipped and not quiet: print() print(count(len(self.skipped), "test"), "skipped:") printlist(self.skipped) + if self.resource_denied and not quiet: + print() + print(count(len(self.resource_denied), "test"), "skipped (resource denied):") + printlist(self.resource_denied) + if self.rerun: print() print("%s:" % count(len(self.rerun), "re-run test")) @@ -452,40 +444,58 @@ print(count(len(self.run_no_tests), "test"), "run no tests:") printlist(self.run_no_tests) - def run_tests_sequential(self): - if self.ns.trace: + def run_test(self, test_index, test_name, previous_test, save_modules): + text = test_name + if previous_test: + text = '%s -- %s' % (text, previous_test) + self.display_progress(test_index, text) + + if self.tracer: + # If we're tracing code coverage, then we don't exit with status + # if on a false return value from main. + cmd = ('result = runtest(self.ns, test_name); ' + 'self.accumulate_result(result)') + ns = dict(locals()) + self.tracer.runctx(cmd, globals=globals(), locals=ns) + result = ns['result'] + else: + result = runtest(self.ns, test_name) + self.accumulate_result(result) + + # Unload the newly imported modules (best effort finalization) + for module in sys.modules.keys(): + if module not in save_modules and module.startswith("test."): + support.unload(module) + + return result + + def run_tests_sequentially(self, runtests): + ns = self.ns + coverage = ns.trace + fail_fast = ns.failfast + fail_env_changed = ns.fail_env_changed + timeout = ns.timeout + + if coverage: import trace self.tracer = trace.Trace(trace=False, count=True) save_modules = sys.modules.keys() msg = "Run tests sequentially" - if self.ns.timeout: - msg += " (timeout: %s)" % format_duration(self.ns.timeout) + if timeout: + msg += " (timeout: %s)" % format_duration(timeout) self.log(msg) previous_test = None - for test_index, test_name in enumerate(self.tests, 1): + tests_iter = runtests.iter_tests() + for test_index, test_name in enumerate(tests_iter, 1): start_time = time.perf_counter() - text = test_name - if previous_test: - text = '%s -- %s' % (text, previous_test) - self.display_progress(test_index, text) - - if self.tracer: - # If we're tracing code coverage, then we don't exit with status - # if on a false return value from main. - cmd = ('result = runtest(self.ns, test_name); ' - 'self.accumulate_result(result)') - ns = dict(locals()) - self.tracer.runctx(cmd, globals=globals(), locals=ns) - result = ns['result'] - else: - result = runtest(self.ns, test_name) - self.accumulate_result(result) + result = self.run_test(test_index, test_name, + previous_test, save_modules) - if result.state == State.INTERRUPTED: + if result.must_stop(fail_fast, fail_env_changed): break previous_test = str(result) @@ -496,26 +506,9 @@ # be quiet: say nothing if the test passed shortly previous_test = None - # Unload the newly imported modules (best effort finalization) - for module in sys.modules.keys(): - if module not in save_modules and module.startswith("test."): - support.unload(module) - - if self.ns.failfast and result.is_failed(self.ns.fail_env_changed): - break - if previous_test: print(previous_test) - def _test_forever(self, tests): - while True: - for test_name in tests: - yield test_name - if self.bad: - return - if self.ns.fail_env_changed and self.environment_changed: - return - def display_header(self): # Print basic platform information print("==", platform.python_implementation(), *sys.version.split()) @@ -528,36 +521,45 @@ print("== CPU count:", cpu_count) print("== encodings: locale=%s, FS=%s" % (locale.getencoding(), sys.getfilesystemencoding())) + self.display_sanitizers() + + def display_sanitizers(self): + # This makes it easier to remember what to set in your local + # environment when trying to reproduce a sanitizer failure. asan = support.check_sanitizer(address=True) msan = support.check_sanitizer(memory=True) ubsan = support.check_sanitizer(ub=True) - # This makes it easier to remember what to set in your local - # environment when trying to reproduce a sanitizer failure. - if asan or msan or ubsan: - names = [n for n in (asan and "address", - msan and "memory", - ubsan and "undefined behavior") - if n] - print(f"== sanitizers: {', '.join(names)}") - a_opts = os.environ.get("ASAN_OPTIONS") - if asan and a_opts is not None: - print(f"== ASAN_OPTIONS={a_opts}") - m_opts = os.environ.get("ASAN_OPTIONS") - if msan and m_opts is not None: - print(f"== MSAN_OPTIONS={m_opts}") - ub_opts = os.environ.get("UBSAN_OPTIONS") - if ubsan and ub_opts is not None: - print(f"== UBSAN_OPTIONS={ub_opts}") + sanitizers = [] + if asan: + sanitizers.append("address") + if msan: + sanitizers.append("memory") + if ubsan: + sanitizers.append("undefined behavior") + if not sanitizers: + return + + print(f"== sanitizers: {', '.join(sanitizers)}") + for sanitizer, env_var in ( + (asan, "ASAN_OPTIONS"), + (msan, "MSAN_OPTIONS"), + (ubsan, "UBSAN_OPTIONS"), + ): + options= os.environ.get(env_var) + if sanitizer and options is not None: + print(f"== {env_var}={options!r}") def no_tests_run(self): return not any((self.good, self.bad, self.skipped, self.interrupted, self.environment_changed)) - def get_tests_result(self): + def get_tests_state(self): + fail_env_changed = self.ns.fail_env_changed + result = [] if self.bad: result.append("FAILURE") - elif self.ns.fail_env_changed and self.environment_changed: + elif fail_env_changed and self.environment_changed: result.append("ENV CHANGED") elif self.no_tests_run(): result.append("NO TESTS RAN") @@ -569,10 +571,40 @@ result.append("SUCCESS") result = ', '.join(result) - if self.first_result: - result = '%s then %s' % (self.first_result, result) + if self.first_state: + result = '%s then %s' % (self.first_state, result) return result + def _run_tests_mp(self, runtests: RunTests) -> None: + from test.libregrtest.runtest_mp import run_tests_multiprocess + # If we're on windows and this is the parent runner (not a worker), + # track the load average. + if sys.platform == 'win32': + from test.libregrtest.win_utils import WindowsLoadTracker + + try: + self.win_load_tracker = WindowsLoadTracker() + except PermissionError as error: + # Standard accounts may not have access to the performance + # counters. + print(f'Failed to create WindowsLoadTracker: {error}') + + try: + run_tests_multiprocess(self, runtests) + finally: + if self.win_load_tracker is not None: + self.win_load_tracker.close() + self.win_load_tracker = None + + def set_tests(self, tests): + self.tests = tests + if self.ns.forever: + self.test_count_text = '' + self.test_count_width = 3 + else: + self.test_count_text = '/{}'.format(len(self.tests)) + self.test_count_width = len(self.test_count_text) - 1 + def run_tests(self): # For a partial run, we do not need to clutter the output. if (self.ns.header @@ -590,37 +622,14 @@ if self.ns.randomize: print("Using random seed", self.ns.random_seed) - if self.ns.forever: - self.tests = self._test_forever(list(self.selected)) - self.test_count = '' - self.test_count_width = 3 - else: - self.tests = iter(self.selected) - self.test_count = '/{}'.format(len(self.selected)) - self.test_count_width = len(self.test_count) - 1 - + tests = self.selected + self.set_tests(tests) + runtests = RunTests(tests, forever=self.ns.forever) + self.all_runtests.append(runtests) if self.ns.use_mp: - from test.libregrtest.runtest_mp import run_tests_multiprocess - # If we're on windows and this is the parent runner (not a worker), - # track the load average. - if sys.platform == 'win32' and self.worker_test_name is None: - from test.libregrtest.win_utils import WindowsLoadTracker - - try: - self.win_load_tracker = WindowsLoadTracker() - except PermissionError as error: - # Standard accounts may not have access to the performance - # counters. - print(f'Failed to create WindowsLoadTracker: {error}') - - try: - run_tests_multiprocess(self) - finally: - if self.win_load_tracker is not None: - self.win_load_tracker.close() - self.win_load_tracker = None + self._run_tests_mp(runtests) else: - self.run_tests_sequential() + self.run_tests_sequentially(runtests) def finalize(self): if self.next_single_filename: @@ -635,23 +644,29 @@ r.write_results(show_missing=True, summary=True, coverdir=self.ns.coverdir) - print() - self.display_summary() - if self.ns.runleaks: os.system("leaks %d" % os.getpid()) + self.save_xml_result() + def display_summary(self): duration = time.perf_counter() - self.start_time + first_runtests = self.all_runtests[0] + # the second runtests (re-run failed tests) disables forever, + # use the first runtests + forever = first_runtests.forever + filtered = bool(self.ns.match_tests) or bool(self.ns.ignore_tests) # Total duration + print() print("Total duration: %s" % format_duration(duration)) # Total tests - total = TestStats() - for stats in self.stats_dict.values(): - total.accumulate(stats) - stats = [f'run={total.tests_run:,}'] + total = self.total_stats + text = f'run={total.tests_run:,}' + if filtered: + text = f"{text} (filtered)" + stats = [text] if total.failures: stats.append(f'failures={total.failures:,}') if total.skipped: @@ -659,23 +674,31 @@ print(f"Total tests: {' '.join(stats)}") # Total test files - report = [f'success={len(self.good)}'] - if self.bad: - report.append(f'failed={len(self.bad)}') - if self.environment_changed: - report.append(f'env_changed={len(self.environment_changed)}') - if self.skipped: - report.append(f'skipped={len(self.skipped)}') - if self.resource_denied: - report.append(f'resource_denied={len(self.resource_denied)}') - if self.rerun: - report.append(f'rerun={len(self.rerun)}') - if self.run_no_tests: - report.append(f'run_no_tests={len(self.run_no_tests)}') + all_tests = [self.good, self.bad, self.rerun, + self.skipped, + self.environment_changed, self.run_no_tests] + run = sum(map(len, all_tests)) + text = f'run={run}' + if not forever: + ntest = len(first_runtests.tests) + text = f"{text}/{ntest}" + if filtered: + text = f"{text} (filtered)" + report = [text] + for name, tests in ( + ('failed', self.bad), + ('env_changed', self.environment_changed), + ('skipped', self.skipped), + ('resource_denied', self.resource_denied), + ('rerun', self.rerun), + ('run_no_tests', self.run_no_tests), + ): + if tests: + report.append(f'{name}={len(tests)}') print(f"Total test files: {' '.join(report)}") # Result - result = self.get_tests_result() + result = self.get_tests_state() print(f"Result: {result}") def save_xml_result(self): @@ -735,6 +758,9 @@ self.tmp_dir = os.path.abspath(self.tmp_dir) + def is_worker(self): + return (self.ns.worker_args is not None) + def create_temp_dir(self): os.makedirs(self.tmp_dir, exist_ok=True) @@ -747,7 +773,8 @@ nounce = random.randint(0, 1_000_000) else: nounce = os.getpid() - if self.worker_test_name is not None: + + if self.is_worker(): test_cwd = 'test_python_worker_{}'.format(nounce) else: test_cwd = 'test_python_{}'.format(nounce) @@ -810,48 +837,53 @@ return None + def get_exitcode(self): + exitcode = 0 + if self.bad: + exitcode = EXITCODE_BAD_TEST + elif self.interrupted: + exitcode = EXITCODE_INTERRUPTED + elif self.ns.fail_env_changed and self.environment_changed: + exitcode = EXITCODE_ENV_CHANGED + elif self.no_tests_run(): + exitcode = EXITCODE_NO_TESTS_RAN + elif self.rerun and self.ns.fail_rerun: + exitcode = EXITCODE_RERUN_FAIL + return exitcode + + def action_run_tests(self): + self.run_tests() + self.display_result() + + need_rerun = self.need_rerun + if self.ns.rerun and need_rerun: + self.rerun_failed_tests(need_rerun) + + self.display_summary() + self.finalize() + def _main(self, tests, kwargs): - if self.worker_test_name is not None: + if self.is_worker(): from test.libregrtest.runtest_mp import run_tests_worker - run_tests_worker(self.ns, self.worker_test_name) + run_tests_worker(self.ns.worker_args) + return if self.ns.wait: input("Press any key to continue...") - support.PGO = self.ns.pgo - support.PGO_EXTENDED = self.ns.pgo_extended - setup_tests(self.ns) - self.find_tests(tests) + exitcode = 0 if self.ns.list_tests: self.list_tests() - sys.exit(0) - - if self.ns.list_cases: + elif self.ns.list_cases: self.list_cases() - sys.exit(0) - - self.run_tests() - self.display_result() - - if self.ns.verbose2 and self.bad: - self.rerun_failed_tests() - - self.finalize() - - self.save_xml_result() + else: + self.action_run_tests() + exitcode = self.get_exitcode() - if self.bad: - sys.exit(EXITCODE_BAD_TEST) - if self.interrupted: - sys.exit(EXITCODE_INTERRUPTED) - if self.ns.fail_env_changed and self.environment_changed: - sys.exit(EXITCODE_ENV_CHANGED) - if self.no_tests_run(): - sys.exit(EXITCODE_NO_TESTS_RAN) - sys.exit(0) + sys.exit(exitcode) def main(tests=None, **kwargs): diff -Nru python3.12-3.12.0~rc2/Lib/test/libregrtest/runtest_mp.py python3.12-3.12.0/Lib/test/libregrtest/runtest_mp.py --- python3.12-3.12.0~rc2/Lib/test/libregrtest/runtest_mp.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/libregrtest/runtest_mp.py 2023-10-02 11:48:14.000000000 +0000 @@ -19,8 +19,8 @@ from test.libregrtest.cmdline import Namespace from test.libregrtest.main import Regrtest from test.libregrtest.runtest import ( - runtest, TestResult, State, - PROGRESS_MIN_TIME) + runtest, TestResult, State, PROGRESS_MIN_TIME, + MatchTests, RunTests) from test.libregrtest.setup import setup_tests from test.libregrtest.utils import format_duration, print_warning @@ -44,26 +44,54 @@ USE_PROCESS_GROUP = (hasattr(os, "setsid") and hasattr(os, "killpg")) -def must_stop(result: TestResult, ns: Namespace) -> bool: - if result.state == State.INTERRUPTED: - return True - if ns.failfast and result.is_failed(ns.fail_env_changed): - return True - return False - - -def parse_worker_args(worker_args) -> tuple[Namespace, str]: - ns_dict, test_name = json.loads(worker_args) - ns = Namespace(**ns_dict) - return (ns, test_name) - - -def run_test_in_subprocess(testname: str, ns: Namespace, tmp_dir: str, stdout_fh: TextIO) -> subprocess.Popen: - ns_dict = vars(ns) - worker_args = (ns_dict, testname) - worker_args = json.dumps(worker_args) - if ns.python is not None: - executable = ns.python +@dataclasses.dataclass(slots=True) +class WorkerJob: + test_name: str + namespace: Namespace + rerun: bool = False + match_tests: MatchTests | None = None + + +class _EncodeWorkerJob(json.JSONEncoder): + def default(self, o: Any) -> dict[str, Any]: + match o: + case WorkerJob(): + result = dataclasses.asdict(o) + result["__worker_job__"] = True + return result + case Namespace(): + result = vars(o) + result["__namespace__"] = True + return result + case _: + return super().default(o) + + +def _decode_worker_job(d: dict[str, Any]) -> WorkerJob | dict[str, Any]: + if "__worker_job__" in d: + d.pop('__worker_job__') + return WorkerJob(**d) + if "__namespace__" in d: + d.pop('__namespace__') + return Namespace(**d) + else: + return d + + +def _parse_worker_args(worker_json: str) -> tuple[Namespace, str]: + return json.loads(worker_json, + object_hook=_decode_worker_job) + + +def run_test_in_subprocess(worker_job: WorkerJob, + output_file: TextIO, + tmp_dir: str | None = None) -> subprocess.Popen: + ns = worker_job.namespace + python = ns.python + worker_args = json.dumps(worker_job, cls=_EncodeWorkerJob) + + if python is not None: + executable = python else: executable = [sys.executable] cmd = [*executable, *support.args_from_interpreter_flags(), @@ -82,9 +110,9 @@ # sysconfig.is_python_build() is true. See issue 15300. kw = dict( env=env, - stdout=stdout_fh, + stdout=output_file, # bpo-45410: Write stderr into stdout to keep messages order - stderr=stdout_fh, + stderr=output_file, text=True, close_fds=(os.name != 'nt'), cwd=os_helper.SAVEDCWD, @@ -94,11 +122,27 @@ return subprocess.Popen(cmd, **kw) -def run_tests_worker(ns: Namespace, test_name: str) -> NoReturn: +def run_tests_worker(worker_json: str) -> NoReturn: + worker_job = _parse_worker_args(worker_json) + ns = worker_job.namespace + test_name = worker_job.test_name + rerun = worker_job.rerun + match_tests = worker_job.match_tests + setup_tests(ns) - result = runtest(ns, test_name) + if rerun: + if match_tests: + matching = "matching: " + ", ".join(match_tests) + print(f"Re-running {test_name} in verbose mode ({matching})", flush=True) + else: + print(f"Re-running {test_name} in verbose mode", flush=True) + ns.verbose = True + + if match_tests is not None: + ns.match_tests = match_tests + result = runtest(ns, test_name) print() # Force a newline (just in case) # Serialize TestResult as dict in JSON @@ -148,11 +192,13 @@ def __init__(self, worker_id: int, runner: "MultiprocessTestRunner") -> None: super().__init__() self.worker_id = worker_id + self.runtests = runner.runtests self.pending = runner.pending self.output = runner.output self.ns = runner.ns self.timeout = runner.worker_timeout self.regrtest = runner.regrtest + self.rerun = runner.rerun self.current_test_name = None self.start_time = None self._popen = None @@ -216,10 +262,11 @@ ) -> MultiprocessResult: return MultiprocessResult(test_result, stdout, err_msg) - def _run_process(self, test_name: str, tmp_dir: str, stdout_fh: TextIO) -> int: - self.current_test_name = test_name + def _run_process(self, worker_job, output_file: TextIO, + tmp_dir: str | None = None) -> int: + self.current_test_name = worker_job.test_name try: - popen = run_test_in_subprocess(test_name, self.ns, tmp_dir, stdout_fh) + popen = run_test_in_subprocess(worker_job, output_file, tmp_dir) self._killed = False self._popen = popen @@ -277,9 +324,15 @@ else: encoding = sys.stdout.encoding + match_tests = self.runtests.get_match_tests(test_name) + # gh-94026: Write stdout+stderr to a tempfile as workaround for # non-blocking pipes on Emscripten with NodeJS. - with tempfile.TemporaryFile('w+', encoding=encoding) as stdout_fh: + with tempfile.TemporaryFile('w+', encoding=encoding) as stdout_file: + worker_job = WorkerJob(test_name, + namespace=self.ns, + rerun=self.rerun, + match_tests=match_tests) # gh-93353: Check for leaked temporary files in the parent process, # since the deletion of temporary files can happen late during # Python finalization: too late for libregrtest. @@ -290,17 +343,17 @@ tmp_dir = tempfile.mkdtemp(prefix="test_python_") tmp_dir = os.path.abspath(tmp_dir) try: - retcode = self._run_process(test_name, tmp_dir, stdout_fh) + retcode = self._run_process(worker_job, stdout_file, tmp_dir) finally: tmp_files = os.listdir(tmp_dir) os_helper.rmtree(tmp_dir) else: - retcode = self._run_process(test_name, None, stdout_fh) + retcode = self._run_process(worker_job, stdout_file) tmp_files = () - stdout_fh.seek(0) + stdout_file.seek(0) try: - stdout = stdout_fh.read().strip() + stdout = stdout_file.read().strip() except Exception as exc: # gh-101634: Catch UnicodeDecodeError if stdout cannot be # decoded from encoding @@ -342,6 +395,8 @@ return MultiprocessResult(result, stdout) def run(self) -> None: + fail_fast = self.ns.failfast + fail_env_changed = self.ns.fail_env_changed while not self._stopped: try: try: @@ -354,7 +409,7 @@ mp_result.result.duration = time.monotonic() - self.start_time self.output.put((False, mp_result)) - if must_stop(mp_result.result, self.ns): + if mp_result.result.must_stop(fail_fast, fail_env_changed): break except ExitThread: break @@ -410,29 +465,36 @@ class MultiprocessTestRunner: - def __init__(self, regrtest: Regrtest) -> None: + def __init__(self, regrtest: Regrtest, runtests: RunTests) -> None: + ns = regrtest.ns + timeout = ns.timeout + self.regrtest = regrtest + self.runtests = runtests + self.rerun = runtests.rerun self.log = self.regrtest.log - self.ns = regrtest.ns + self.ns = ns self.output: queue.Queue[QueueOutput] = queue.Queue() - self.pending = MultiprocessIterator(self.regrtest.tests) - if self.ns.timeout is not None: + tests_iter = runtests.iter_tests() + self.pending = MultiprocessIterator(tests_iter) + if timeout is not None: # Rely on faulthandler to kill a worker process. This timouet is # when faulthandler fails to kill a worker process. Give a maximum # of 5 minutes to faulthandler to kill the worker. - self.worker_timeout = min(self.ns.timeout * 1.5, - self.ns.timeout + 5 * 60) + self.worker_timeout = min(timeout * 1.5, timeout + 5 * 60) else: self.worker_timeout = None self.workers = None def start_workers(self) -> None: + use_mp = self.ns.use_mp + timeout = self.ns.timeout self.workers = [TestWorkerProcess(index, self) - for index in range(1, self.ns.use_mp + 1)] + for index in range(1, use_mp + 1)] msg = f"Run tests in parallel using {len(self.workers)} child processes" - if self.ns.timeout: + if timeout: msg += (" (timeout: %s, worker timeout: %s)" - % (format_duration(self.ns.timeout), + % (format_duration(timeout), format_duration(self.worker_timeout))) self.log(msg) for worker in self.workers: @@ -446,6 +508,7 @@ worker.wait_stopped(start_time) def _get_result(self) -> QueueOutput | None: + pgo = self.ns.pgo use_faulthandler = (self.ns.timeout is not None) timeout = PROGRESS_UPDATE @@ -464,7 +527,7 @@ # display progress running = get_running(self.workers) - if running and not self.ns.pgo: + if running and not pgo: self.log('running: %s' % ', '.join(running)) # all worker threads are done: consume pending results @@ -475,42 +538,46 @@ def display_result(self, mp_result: MultiprocessResult) -> None: result = mp_result.result + pgo = self.ns.pgo text = str(result) if mp_result.err_msg: # MULTIPROCESSING_ERROR text += ' (%s)' % mp_result.err_msg - elif (result.duration >= PROGRESS_MIN_TIME and not self.ns.pgo): + elif (result.duration >= PROGRESS_MIN_TIME and not pgo): text += ' (%s)' % format_duration(result.duration) running = get_running(self.workers) - if running and not self.ns.pgo: + if running and not pgo: text += ' -- running: %s' % ', '.join(running) self.regrtest.display_progress(self.test_index, text) def _process_result(self, item: QueueOutput) -> bool: """Returns True if test runner must stop.""" + rerun = self.runtests.rerun if item[0]: # Thread got an exception format_exc = item[1] print_warning(f"regrtest worker thread failed: {format_exc}") result = TestResult("", state=State.MULTIPROCESSING_ERROR) - self.regrtest.accumulate_result(result) - return True + self.regrtest.accumulate_result(result, rerun=rerun) + return result self.test_index += 1 mp_result = item[1] - self.regrtest.accumulate_result(mp_result.result) + result = mp_result.result + self.regrtest.accumulate_result(result, rerun=rerun) self.display_result(mp_result) if mp_result.worker_stdout: print(mp_result.worker_stdout, flush=True) - if must_stop(mp_result.result, self.ns): - return True - - return False + return result def run_tests(self) -> None: + fail_fast = self.ns.failfast + fail_env_changed = self.ns.fail_env_changed + timeout = self.ns.timeout + self.start_workers() self.test_index = 0 @@ -520,14 +587,14 @@ if item is None: break - stop = self._process_result(item) - if stop: + result = self._process_result(item) + if result.must_stop(fail_fast, fail_env_changed): break except KeyboardInterrupt: print() self.regrtest.interrupted = True finally: - if self.ns.timeout is not None: + if timeout is not None: faulthandler.cancel_dump_traceback_later() # Always ensure that all worker processes are no longer @@ -536,8 +603,8 @@ self.stop_workers() -def run_tests_multiprocess(regrtest: Regrtest) -> None: - MultiprocessTestRunner(regrtest).run_tests() +def run_tests_multiprocess(regrtest: Regrtest, runtests: RunTests) -> None: + MultiprocessTestRunner(regrtest, runtests).run_tests() class EncodeTestResult(json.JSONEncoder): @@ -552,7 +619,7 @@ return super().default(o) -def decode_test_result(d: dict[str, Any]) -> TestResult | TestStats | dict[str, Any]: +def decode_test_result(d: dict[str, Any]) -> TestResult | dict[str, Any]: """Decode a TestResult (sub)class object from a JSON dict.""" if "__test_result__" not in d: diff -Nru python3.12-3.12.0~rc2/Lib/test/libregrtest/runtest.py python3.12-3.12.0/Lib/test/libregrtest/runtest.py --- python3.12-3.12.0~rc2/Lib/test/libregrtest/runtest.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/libregrtest/runtest.py 2023-10-02 11:48:14.000000000 +0000 @@ -1,7 +1,6 @@ import dataclasses import doctest import faulthandler -import functools import gc import importlib import io @@ -20,6 +19,10 @@ from test.libregrtest.utils import clear_caches, format_duration, print_warning +MatchTests = list[str] +MatchTestsDict = dict[str, MatchTests] + + # Avoid enum.Enum to reduce the number of imports when tests are run class State: PASSED = "PASSED" @@ -56,6 +59,41 @@ State.MULTIPROCESSING_ERROR, State.DID_NOT_RUN} + @staticmethod + def must_stop(state): + return state in { + State.INTERRUPTED, + State.MULTIPROCESSING_ERROR} + + +# gh-90681: When rerunning tests, we might need to rerun the whole +# class or module suite if some its life-cycle hooks fail. +# Test level hooks are not affected. +_TEST_LIFECYCLE_HOOKS = frozenset(( + 'setUpClass', 'tearDownClass', + 'setUpModule', 'tearDownModule', +)) + +def normalize_test_name(test_full_name, *, is_error=False): + short_name = test_full_name.split(" ")[0] + if is_error and short_name in _TEST_LIFECYCLE_HOOKS: + if test_full_name.startswith(('setUpModule (', 'tearDownModule (')): + # if setUpModule() or tearDownModule() failed, don't filter + # tests with the test file name, don't use use filters. + return None + + # This means that we have a failure in a life-cycle hook, + # we need to rerun the whole module or class suite. + # Basically the error looks like this: + # ERROR: setUpClass (test.test_reg_ex.RegTest) + # or + # ERROR: setUpModule (test.test_reg_ex) + # So, we need to parse the class / module name. + lpar = test_full_name.index('(') + rpar = test_full_name.index(')') + return test_full_name[lpar + 1: rpar].split('.')[-1] + return short_name + @dataclasses.dataclass(slots=True) class TestResult: @@ -129,6 +167,58 @@ if self.state is None or self.state == State.PASSED: self.state = State.ENV_CHANGED + def must_stop(self, fail_fast: bool, fail_env_changed: bool) -> bool: + if State.must_stop(self.state): + return True + if fail_fast and self.is_failed(fail_env_changed): + return True + return False + + def get_rerun_match_tests(self): + match_tests = [] + + errors = self.errors or [] + failures = self.failures or [] + for error_list, is_error in ( + (errors, True), + (failures, False), + ): + for full_name, *_ in error_list: + match_name = normalize_test_name(full_name, is_error=is_error) + if match_name is None: + # 'setUpModule (test.test_sys)': don't filter tests + return None + if not match_name: + error_type = "ERROR" if is_error else "FAIL" + print_warning(f"rerun failed to parse {error_type} test name: " + f"{full_name!r}: don't filter tests") + return None + match_tests.append(match_name) + + return match_tests + + +@dataclasses.dataclass(slots=True, frozen=True) +class RunTests: + tests: list[str] + match_tests: MatchTestsDict | None = None + rerun: bool = False + forever: bool = False + + def get_match_tests(self, test_name) -> MatchTests | None: + if self.match_tests is not None: + return self.match_tests.get(test_name, None) + else: + return None + + def iter_tests(self): + tests = tuple(self.tests) + if self.forever: + while True: + yield from tests + else: + yield from tests + # Minimum duration of a test to display its duration or to mention that # the test is running in background @@ -147,9 +237,6 @@ "test_multiprocessing_spawn", } -# Storage of uncollectable objects -FOUND_GARBAGE = [] - def findtestdir(path=None): return path or os.path.dirname(os.path.dirname(__file__)) or os.curdir @@ -189,31 +276,41 @@ return splitted -def get_abs_module(ns: Namespace, test_name: str) -> str: - if test_name.startswith('test.') or ns.testdir: +def abs_module_name(test_name: str, test_dir: str | None) -> str: + if test_name.startswith('test.') or test_dir: return test_name else: # Import it from the test package return 'test.' + test_name -def _runtest_capture_output_timeout_junit(result: TestResult, ns: Namespace) -> None: +def setup_support(ns: Namespace): + support.PGO = ns.pgo + support.PGO_EXTENDED = ns.pgo_extended + support.set_match_tests(ns.match_tests, ns.ignore_tests) + support.failfast = ns.failfast + support.verbose = ns.verbose + if ns.xmlpath: + support.junit_xml_list = [] + else: + support.junit_xml_list = None + + +def _runtest(result: TestResult, ns: Namespace) -> None: # Capture stdout and stderr, set faulthandler timeout, # and create JUnit XML report. - + verbose = ns.verbose output_on_failure = ns.verbose3 + timeout = ns.timeout use_timeout = ( - ns.timeout is not None and threading_helper.can_start_thread + timeout is not None and threading_helper.can_start_thread ) if use_timeout: - faulthandler.dump_traceback_later(ns.timeout, exit=True) + faulthandler.dump_traceback_later(timeout, exit=True) try: - support.set_match_tests(ns.match_tests, ns.ignore_tests) - support.junit_xml_list = xml_list = [] if ns.xmlpath else None - if ns.failfast: - support.failfast = True + setup_support(ns) if output_on_failure: support.verbose = True @@ -247,11 +344,10 @@ sys.stderr.flush() else: # Tell tests to be moderately quiet - support.verbose = ns.verbose - - _runtest_env_changed_exc(result, ns, - display_failure=not ns.verbose) + support.verbose = verbose + _runtest_env_changed_exc(result, ns, display_failure=not verbose) + xml_list = support.junit_xml_list if xml_list: import xml.etree.ElementTree as ET result.xml_data = [ET.tostring(x).decode('us-ascii') @@ -276,7 +372,7 @@ start_time = time.perf_counter() result = TestResult(test_name) try: - _runtest_capture_output_timeout_junit(result, ns) + _runtest(result, ns) except: if not ns.pgo: msg = traceback.format_exc() @@ -287,9 +383,9 @@ return result -def _test_module(the_module): +def run_unittest(test_mod): loader = unittest.TestLoader() - tests = loader.loadTestsFromModule(the_module) + tests = loader.loadTestsFromModule(test_mod) for error in loader.errors: print(error, file=sys.stderr) if loader.errors: @@ -304,7 +400,6 @@ def regrtest_runner(result, test_func, ns) -> None: # Run test_func(), collect statistics, and detect reference and memory # leaks. - if ns.huntrleaks: from test.libregrtest.refleak import dash_R refleak, test_result = dash_R(ns, result.test_name, test_func) @@ -332,23 +427,24 @@ result.stats = stats +# Storage of uncollectable objects +FOUND_GARBAGE = [] + + def _load_run_test(result: TestResult, ns: Namespace) -> None: # Load the test function, run the test function. + module_name = abs_module_name(result.test_name, ns.testdir) - abstest = get_abs_module(ns, result.test_name) + # Remove the module from sys.module to reload it if it was already imported + sys.modules.pop(module_name, None) - # remove the module from sys.module to reload it if it was already imported - try: - del sys.modules[abstest] - except KeyError: - pass + test_mod = importlib.import_module(module_name) - the_module = importlib.import_module(abstest) - - if hasattr(the_module, "test_main"): + if hasattr(test_mod, "test_main"): # https://github.com/python/cpython/issues/89392 raise Exception(f"Module {result.test_name} defines test_main() which is no longer supported by regrtest") - test_func = functools.partial(_test_module, the_module) + def test_func(): + return run_unittest(test_mod) try: with save_env(ns, result.test_name): @@ -360,12 +456,12 @@ # failures. support.gc_collect() - cleanup_test_droppings(result.test_name, ns.verbose) + remove_testfn(result.test_name, ns.verbose) if gc.garbage: support.environment_altered = True print_warning(f"{result.test_name} created {len(gc.garbage)} " - f"uncollectable object(s).") + f"uncollectable object(s)") # move the uncollectable objects somewhere, # so we don't see them again @@ -443,35 +539,37 @@ result.state = State.PASSED -def cleanup_test_droppings(test_name: str, verbose: int) -> None: - # Try to clean up junk commonly left behind. While tests shouldn't leave - # any files or directories behind, when a test fails that can be tedious - # for it to arrange. The consequences can be especially nasty on Windows, - # since if a test leaves a file open, it cannot be deleted by name (while - # there's nothing we can do about that here either, we can display the - # name of the offending test, which is a real help). - for name in (os_helper.TESTFN,): - if not os.path.exists(name): - continue +def remove_testfn(test_name: str, verbose: int) -> None: + # Try to clean up os_helper.TESTFN if left behind. + # + # While tests shouldn't leave any files or directories behind, when a test + # fails that can be tedious for it to arrange. The consequences can be + # especially nasty on Windows, since if a test leaves a file open, it + # cannot be deleted by name (while there's nothing we can do about that + # here either, we can display the name of the offending test, which is a + # real help). + name = os_helper.TESTFN + if not os.path.exists(name): + return - if os.path.isdir(name): - import shutil - kind, nuker = "directory", shutil.rmtree - elif os.path.isfile(name): - kind, nuker = "file", os.unlink - else: - raise RuntimeError(f"os.path says {name!r} exists but is neither " - f"directory nor file") + if os.path.isdir(name): + import shutil + kind, nuker = "directory", shutil.rmtree + elif os.path.isfile(name): + kind, nuker = "file", os.unlink + else: + raise RuntimeError(f"os.path says {name!r} exists but is neither " + f"directory nor file") + + if verbose: + print_warning(f"{test_name} left behind {kind} {name!r}") + support.environment_altered = True - if verbose: - print_warning(f"{test_name} left behind {kind} {name!r}") - support.environment_altered = True - - try: - import stat - # fix possible permissions problems that might prevent cleanup - os.chmod(name, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) - nuker(name) - except Exception as exc: - print_warning(f"{test_name} left behind {kind} {name!r} " - f"and it couldn't be removed: {exc}") + try: + import stat + # fix possible permissions problems that might prevent cleanup + os.chmod(name, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) + nuker(name) + except Exception as exc: + print_warning(f"{test_name} left behind {kind} {name!r} " + f"and it couldn't be removed: {exc}") diff -Nru python3.12-3.12.0~rc2/Lib/test/libregrtest/utils.py python3.12-3.12.0/Lib/test/libregrtest/utils.py --- python3.12-3.12.0~rc2/Lib/test/libregrtest/utils.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/libregrtest/utils.py 2023-10-02 11:48:14.000000000 +0000 @@ -31,7 +31,7 @@ return ' '.join(parts) -def removepy(names): +def strip_py_suffix(names: list[str]): if not names: return for idx, name in enumerate(names): diff -Nru python3.12-3.12.0~rc2/Lib/test/pythoninfo.py python3.12-3.12.0/Lib/test/pythoninfo.py --- python3.12-3.12.0~rc2/Lib/test/pythoninfo.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/pythoninfo.py 2023-10-02 11:48:14.000000000 +0000 @@ -112,6 +112,7 @@ call_func(info_add, 'sys.androidapilevel', sys, 'getandroidapilevel') call_func(info_add, 'sys.windowsversion', sys, 'getwindowsversion') + call_func(info_add, 'sys.getrecursionlimit', sys, 'getrecursionlimit') encoding = sys.getfilesystemencoding() if hasattr(sys, 'getfilesystemencodeerrors'): @@ -163,6 +164,26 @@ if libc_ver: info_add('platform.libc_ver', libc_ver) + try: + os_release = platform.freedesktop_os_release() + except OSError: + pass + else: + for key in ( + 'ID', + 'NAME', + 'PRETTY_NAME' + 'VARIANT', + 'VARIANT_ID', + 'VERSION', + 'VERSION_CODENAME', + 'VERSION_ID', + ): + if key not in os_release: + continue + info_add(f'platform.freedesktop_os_release[{key}]', + os_release[key]) + def collect_locale(info_add): import locale @@ -912,7 +933,6 @@ for key, value in infos: value = value.replace("\n", " ") print("%s: %s" % (key, value)) - print() def main(): @@ -921,6 +941,7 @@ dump_info(info) if error: + print() print("Collection failed: exit with error", file=sys.stderr) sys.exit(1) diff -Nru python3.12-3.12.0~rc2/Lib/test/.ruff.toml python3.12-3.12.0/Lib/test/.ruff.toml --- python3.12-3.12.0~rc2/Lib/test/.ruff.toml 1970-01-01 00:00:00.000000000 +0000 +++ python3.12-3.12.0/Lib/test/.ruff.toml 2023-10-02 11:48:14.000000000 +0000 @@ -0,0 +1,42 @@ +fix = true +select = [ + "F811", # Redefinition of unused variable (useful for finding test methods with the same name) +] +extend-exclude = [ + # Failed to lint + "badsyntax_pep3120.py", + "encoded_modules/module_iso_8859_1.py", + "encoded_modules/module_koi8_r.py", + # Failed to parse + "badsyntax_3131.py", + "support/socket_helper.py", + "test_fstring.py", + "test_lib2to3/data/bom.py", + "test_lib2to3/data/crlf.py", + "test_lib2to3/data/different_encoding.py", + "test_lib2to3/data/false_encoding.py", + "test_lib2to3/data/py2_test_grammar.py", + # TODO Fix: F811 Redefinition of unused name + "test_buffer.py", + "test_capi/test_misc.py", + "test_capi/test_unicode.py", + "test_ctypes/test_arrays.py", + "test_ctypes/test_functions.py", + "test_dataclasses.py", + "test_descr.py", + "test_enum.py", + "test_functools.py", + "test_genericclass.py", + "test_grammar.py", + "test_import/__init__.py", + "test_keywordonlyarg.py", + "test_lib2to3/data/py3_test_grammar.py", + "test_pkg.py", + "test_subclassinit.py", + "test_tokenize.py", + "test_typing.py", + "test_yield_from.py", + "time_hashlib.py", + # Pending https://github.com/python/cpython/pull/109139 + "test_monitoring.py", +] diff -Nru python3.12-3.12.0~rc2/Lib/test/support/__init__.py python3.12-3.12.0/Lib/test/support/__init__.py --- python3.12-3.12.0~rc2/Lib/test/support/__init__.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/support/__init__.py 2023-10-02 11:48:14.000000000 +0000 @@ -1191,7 +1191,6 @@ def set_match_tests(accept_patterns=None, ignore_patterns=None): global _match_test_func, _accept_test_patterns, _ignore_test_patterns - if accept_patterns is None: accept_patterns = () if ignore_patterns is None: @@ -2244,6 +2243,39 @@ msg = f"cannot create '{re.escape(qualname)}' instances" testcase.assertRaisesRegex(TypeError, msg, tp, *args, **kwds) +def get_recursion_depth(): + """Get the recursion depth of the caller function. + + In the __main__ module, at the module level, it should be 1. + """ + try: + import _testinternalcapi + depth = _testinternalcapi.get_recursion_depth() + except (ImportError, RecursionError) as exc: + # sys._getframe() + frame.f_back implementation. + try: + depth = 0 + frame = sys._getframe() + while frame is not None: + depth += 1 + frame = frame.f_back + finally: + # Break any reference cycles. + frame = None + + # Ignore get_recursion_depth() frame. + return max(depth - 1, 1) + +def get_recursion_available(): + """Get the number of available frames before RecursionError. + + It depends on the current recursion depth of the caller function and + sys.getrecursionlimit(). + """ + limit = sys.getrecursionlimit() + depth = get_recursion_depth() + return limit - depth + @contextlib.contextmanager def set_recursion_limit(limit): """Temporarily change the recursion limit.""" @@ -2254,14 +2286,18 @@ finally: sys.setrecursionlimit(original_limit) -def infinite_recursion(max_depth=75): +def infinite_recursion(max_depth=100): """Set a lower limit for tests that interact with infinite recursions (e.g test_ast.ASTHelpers_Test.test_recursion_direct) since on some debug windows builds, due to not enough functions being inlined the stack size might not handle the default recursion limit (1000). See bpo-11105 for details.""" - return set_recursion_limit(max_depth) - + if max_depth < 3: + raise ValueError("max_depth must be at least 3, got {max_depth}") + depth = get_recursion_depth() + depth = max(depth - 1, 1) # Ignore infinite_recursion() frame. + limit = depth + max_depth + return set_recursion_limit(limit) def ignore_deprecations_from(module: str, *, like: str) -> object: token = object() diff -Nru python3.12-3.12.0~rc2/Lib/test/support/socket_helper.py python3.12-3.12.0/Lib/test/support/socket_helper.py --- python3.12-3.12.0~rc2/Lib/test/support/socket_helper.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/support/socket_helper.py 2023-10-02 11:48:14.000000000 +0000 @@ -3,6 +3,7 @@ import os.path import socket import sys +import subprocess import tempfile import unittest @@ -283,3 +284,62 @@ """ return tempfile.mktemp(prefix="test_python_", suffix='.sock', dir=os.path.curdir) + + +# consider that sysctl values should not change while tests are running +_sysctl_cache = {} + +def _get_sysctl(name): + """Get a sysctl value as an integer.""" + try: + return _sysctl_cache[name] + except KeyError: + pass + + # At least Linux and FreeBSD support the "-n" option + cmd = ['sysctl', '-n', name] + proc = subprocess.run(cmd, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True) + if proc.returncode: + support.print_warning(f'{' '.join(cmd)!r} command failed with ' + f'exit code {proc.returncode}') + # cache the error to only log the warning once + _sysctl_cache[name] = None + return None + output = proc.stdout + + # Parse '0\n' to get '0' + try: + value = int(output.strip()) + except Exception as exc: + support.print_warning(f'Failed to parse {' '.join(cmd)!r} ' + f'command output {output!r}: {exc!r}') + # cache the error to only log the warning once + _sysctl_cache[name] = None + return None + + _sysctl_cache[name] = value + return value + + +def tcp_blackhole(): + if not sys.platform.startswith('freebsd'): + return False + + # gh-109015: test if FreeBSD TCP blackhole is enabled + value = _get_sysctl('net.inet.tcp.blackhole') + if value is None: + # don't skip if we fail to get the sysctl value + return False + return (value != 0) + + +def skip_if_tcp_blackhole(test): + """Decorator skipping test if TCP blackhole is enabled.""" + skip_if = unittest.skipIf( + tcp_blackhole(), + "TCP blackhole is enabled (sysctl net.inet.tcp.blackhole)" + ) + return skip_if(test) diff -Nru python3.12-3.12.0~rc2/Lib/test/support/testresult.py python3.12-3.12.0/Lib/test/support/testresult.py --- python3.12-3.12.0~rc2/Lib/test/support/testresult.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/support/testresult.py 2023-10-02 11:48:14.000000000 +0000 @@ -8,6 +8,7 @@ import time import traceback import unittest +from test import support class RegressionTestResult(unittest.TextTestResult): USE_XML = False @@ -112,6 +113,8 @@ def addFailure(self, test, err): self._add_result(test, True, failure=self.__makeErrorDict(*err)) super().addFailure(test, err) + if support.failfast: + self.stop() def addSkip(self, test, reason): self._add_result(test, skipped=reason) diff -Nru python3.12-3.12.0~rc2/Lib/test/test_asyncgen.py python3.12-3.12.0/Lib/test/test_asyncgen.py --- python3.12-3.12.0~rc2/Lib/test/test_asyncgen.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_asyncgen.py 2023-10-02 11:48:14.000000000 +0000 @@ -1057,8 +1057,7 @@ while True: yield 1 finally: - await asyncio.sleep(0.01) - await asyncio.sleep(0.01) + await asyncio.sleep(0) DONE = 1 async def run(): @@ -1068,7 +1067,10 @@ del g gc_collect() # For PyPy or other GCs. - await asyncio.sleep(0.1) + # Starts running the aclose task + await asyncio.sleep(0) + # For asyncio.sleep(0) in finally block + await asyncio.sleep(0) self.loop.run_until_complete(run()) self.assertEqual(DONE, 1) diff -Nru python3.12-3.12.0~rc2/Lib/test/test_asyncio/test_events.py python3.12-3.12.0/Lib/test/test_asyncio/test_events.py --- python3.12-3.12.0~rc2/Lib/test/test_asyncio/test_events.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_asyncio/test_events.py 2023-10-02 11:48:14.000000000 +0000 @@ -31,6 +31,7 @@ from asyncio import coroutines from asyncio import events from asyncio import selector_events +from multiprocessing.util import _cleanup_tests as multiprocessing_cleanup_tests from test.test_asyncio import utils as test_utils from test import support from test.support import socket_helper @@ -671,6 +672,7 @@ self.assertEqual(port, expected) tr.close() + @socket_helper.skip_if_tcp_blackhole def test_create_connection_local_addr_skip_different_family(self): # See https://github.com/python/cpython/issues/86508 port1 = socket_helper.find_unused_port() @@ -692,6 +694,7 @@ with self.assertRaises(OSError): self.loop.run_until_complete(f) + @socket_helper.skip_if_tcp_blackhole def test_create_connection_local_addr_nomatch_family(self): # See https://github.com/python/cpython/issues/86508 port1 = socket_helper.find_unused_port() @@ -1271,6 +1274,7 @@ server.close() + @socket_helper.skip_if_tcp_blackhole def test_server_close(self): f = self.loop.create_server(MyProto, '0.0.0.0', 0) server = self.loop.run_until_complete(f) @@ -2762,6 +2766,8 @@ # multiprocessing.synchronize module cannot be imported. support.skip_if_broken_multiprocessing_synchronize() + self.addCleanup(multiprocessing_cleanup_tests) + async def main(): if multiprocessing.get_start_method() == 'fork': # Avoid 'fork' DeprecationWarning. diff -Nru python3.12-3.12.0~rc2/Lib/test/test_asyncio/test_sock_lowlevel.py python3.12-3.12.0/Lib/test/test_asyncio/test_sock_lowlevel.py --- python3.12-3.12.0~rc2/Lib/test/test_asyncio/test_sock_lowlevel.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_asyncio/test_sock_lowlevel.py 2023-10-02 11:48:14.000000000 +0000 @@ -10,6 +10,10 @@ from test import support from test.support import socket_helper +if socket_helper.tcp_blackhole(): + raise unittest.SkipTest('Not relevant to ProactorEventLoop') + + def tearDownModule(): asyncio.set_event_loop_policy(None) diff -Nru python3.12-3.12.0~rc2/Lib/test/test_asyncio/test_sslproto.py python3.12-3.12.0/Lib/test/test_asyncio/test_sslproto.py --- python3.12-3.12.0~rc2/Lib/test/test_asyncio/test_sslproto.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_asyncio/test_sslproto.py 2023-10-02 11:48:14.000000000 +0000 @@ -5,6 +5,7 @@ import unittest import weakref from test import support +from test.support import socket_helper from unittest import mock try: import ssl @@ -350,6 +351,7 @@ support.gc_collect() self.assertIsNone(client_context()) + @socket_helper.skip_if_tcp_blackhole def test_start_tls_client_buf_proto_1(self): HELLO_MSG = b'1' * self.PAYLOAD_SIZE @@ -502,6 +504,7 @@ asyncio.wait_for(client(srv.addr), timeout=support.SHORT_TIMEOUT)) + @socket_helper.skip_if_tcp_blackhole def test_start_tls_server_1(self): HELLO_MSG = b'1' * self.PAYLOAD_SIZE ANSWER = b'answer' diff -Nru python3.12-3.12.0~rc2/Lib/test/test_capi/test_misc.py python3.12-3.12.0/Lib/test/test_capi/test_misc.py --- python3.12-3.12.0~rc2/Lib/test/test_capi/test_misc.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_capi/test_misc.py 2023-10-02 11:48:14.000000000 +0000 @@ -301,24 +301,40 @@ def test_buildvalue_N(self): _testcapi.test_buildvalue_N() - @unittest.skipUnless(hasattr(_testcapi, 'negative_refcount'), - 'need _testcapi.negative_refcount') - def test_negative_refcount(self): + def check_negative_refcount(self, code): # bpo-35059: Check that Py_DECREF() reports the correct filename # when calling _Py_NegativeRefcount() to abort Python. - code = textwrap.dedent(""" - import _testcapi - from test import support - - with support.SuppressCrashReport(): - _testcapi.negative_refcount() - """) + code = textwrap.dedent(code) rc, out, err = assert_python_failure('-c', code) self.assertRegex(err, br'_testcapimodule\.c:[0-9]+: ' br'_Py_NegativeRefcount: Assertion failed: ' br'object has negative ref count') + @unittest.skipUnless(hasattr(_testcapi, 'negative_refcount'), + 'need _testcapi.negative_refcount()') + def test_negative_refcount(self): + code = """ + import _testcapi + from test import support + + with support.SuppressCrashReport(): + _testcapi.negative_refcount() + """ + self.check_negative_refcount(code) + + @unittest.skipUnless(hasattr(_testcapi, 'decref_freed_object'), + 'need _testcapi.decref_freed_object()') + def test_decref_freed_object(self): + code = """ + import _testcapi + from test import support + + with support.SuppressCrashReport(): + _testcapi.decref_freed_object() + """ + self.check_negative_refcount(code) + def test_trashcan_subclass(self): # bpo-35983: Check that the trashcan mechanism for "list" is NOT # activated when its tp_dealloc is being called by a subclass diff -Nru python3.12-3.12.0~rc2/Lib/test/test_compileall.py python3.12-3.12.0/Lib/test/test_compileall.py --- python3.12-3.12.0~rc2/Lib/test/test_compileall.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_compileall.py 2023-10-02 11:48:14.000000000 +0000 @@ -18,6 +18,7 @@ try: # compileall relies on ProcessPoolExecutor if ProcessPoolExecutor exists # and it can function. + from multiprocessing.util import _cleanup_tests as multiprocessing_cleanup_tests from concurrent.futures import ProcessPoolExecutor from concurrent.futures.process import _check_system_limits _check_system_limits() @@ -54,6 +55,8 @@ def setUp(self): self.directory = tempfile.mkdtemp() + self.addCleanup(shutil.rmtree, self.directory) + self.source_path = os.path.join(self.directory, '_test.py') self.bc_path = importlib.util.cache_from_source(self.source_path) with open(self.source_path, 'w', encoding="utf-8") as file: @@ -66,9 +69,6 @@ self.source_path3 = os.path.join(self.subdirectory, '_test3.py') shutil.copyfile(self.source_path, self.source_path3) - def tearDown(self): - shutil.rmtree(self.directory) - def add_bad_source_file(self): self.bad_source_path = os.path.join(self.directory, '_test_bad.py') with open(self.bad_source_path, 'w', encoding="utf-8") as file: @@ -307,9 +307,13 @@ script_helper.make_script(path, "__init__", "") mods.append(script_helper.make_script(path, "mod", "def fn(): 1/0\nfn()\n")) + + if parallel: + self.addCleanup(multiprocessing_cleanup_tests) compileall.compile_dir( self.directory, quiet=True, ddir=ddir, workers=2 if parallel else 1) + self.assertTrue(mods) for mod in mods: self.assertTrue(mod.startswith(self.directory), mod) diff -Nru python3.12-3.12.0~rc2/Lib/test/test_compile.py python3.12-3.12.0/Lib/test/test_compile.py --- python3.12-3.12.0~rc2/Lib/test/test_compile.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_compile.py 2023-10-02 11:48:14.000000000 +0000 @@ -478,6 +478,26 @@ ast.body = [_ast.BoolOp()] self.assertRaises(TypeError, compile, ast, '', 'exec') + def test_compile_invalid_typealias(self): + # gh-109341 + m = ast.Module( + body=[ + ast.TypeAlias( + name=ast.Subscript( + value=ast.Name(id="foo", ctx=ast.Load()), + slice=ast.Constant(value="x"), + ctx=ast.Store(), + ), + type_params=[], + value=ast.Name(id="Callable", ctx=ast.Load()), + ) + ], + type_ignores=[], + ) + + with self.assertRaisesRegex(TypeError, "TypeAlias with non-Name name"): + compile(ast.fix_missing_locations(m), "", "exec") + def test_dict_evaluation_order(self): i = 0 @@ -1196,6 +1216,31 @@ return a self.assertEqual(f("x", "y", "z"), "y") + def test_duplicated_small_exit_block(self): + # See gh-109627 + def f(): + while element and something: + try: + return something + except: + pass + + def test_cold_block_moved_to_end(self): + # See gh-109719 + def f(): + while name: + try: + break + except: + pass + else: + 1 if 1 else 1 + + def test_remove_empty_basic_block_with_jump_target_label(self): + # See gh-109823 + def f(x): + while x: + 0 if 1 else 0 @requires_debug_ranges() class TestSourcePositions(unittest.TestCase): @@ -1742,6 +1787,13 @@ list(code.co_consts[1].co_positions()), ) + def test_load_super_attr(self): + source = "class C:\n def __init__(self):\n super().__init__()" + code = compile(source, "", "exec").co_consts[0].co_consts[1] + self.assertOpcodeSourcePositionIs( + code, "LOAD_GLOBAL", line=3, end_line=3, column=4, end_column=9 + ) + class TestExpressionStackSize(unittest.TestCase): # These tests check that the computed stack size for a code object diff -Nru python3.12-3.12.0~rc2/Lib/test/test_concurrent_futures/executor.py python3.12-3.12.0/Lib/test/test_concurrent_futures/executor.py --- python3.12-3.12.0~rc2/Lib/test/test_concurrent_futures/executor.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_concurrent_futures/executor.py 2023-10-02 11:48:14.000000000 +0000 @@ -53,6 +53,7 @@ self.assertEqual(i.__next__(), (0, 1)) self.assertRaises(ZeroDivisionError, i.__next__) + @support.requires_resource('walltime') def test_map_timeout(self): results = [] try: diff -Nru python3.12-3.12.0~rc2/Lib/test/test_concurrent_futures/test_wait.py python3.12-3.12.0/Lib/test/test_concurrent_futures/test_wait.py --- python3.12-3.12.0~rc2/Lib/test/test_concurrent_futures/test_wait.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_concurrent_futures/test_wait.py 2023-10-02 11:48:14.000000000 +0000 @@ -3,6 +3,7 @@ import time import unittest from concurrent import futures +from test import support from .util import ( CANCELLED_FUTURE, CANCELLED_AND_NOTIFIED_FUTURE, EXCEPTION_FUTURE, @@ -53,6 +54,7 @@ finished) self.assertEqual(set([future1]), pending) + @support.requires_resource('walltime') def test_first_exception(self): future1 = self.executor.submit(mul, 2, 21) future2 = self.executor.submit(sleep_and_raise, 1.5) @@ -110,6 +112,7 @@ future2]), finished) self.assertEqual(set(), pending) + @support.requires_resource('walltime') def test_timeout(self): future1 = self.executor.submit(mul, 6, 7) future2 = self.executor.submit(time.sleep, 6) diff -Nru python3.12-3.12.0~rc2/Lib/test/test_doctest.py python3.12-3.12.0/Lib/test/test_doctest.py --- python3.12-3.12.0~rc2/Lib/test/test_doctest.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_doctest.py 2023-10-02 11:48:14.000000000 +0000 @@ -740,15 +740,13 @@ def test_issue35753(self): # This import of `call` should trigger issue35753 when - # `support.run_doctest` is called due to unwrap failing, + # DocTestFinder.find() is called due to inspect.unwrap() failing, # however with a patched doctest this should succeed. from unittest.mock import call dummy_module = types.ModuleType("dummy") dummy_module.__dict__['inject_call'] = call - try: - support.run_doctest(dummy_module, verbosity=True) - except ValueError as e: - raise support.TestFailed("Doctest unwrap failed") from e + finder = doctest.DocTestFinder() + self.assertEqual(finder.find(dummy_module), []) def test_empty_namespace_package(self): pkg_name = 'doctest_empty_pkg' diff -Nru python3.12-3.12.0~rc2/Lib/test/test_eintr.py python3.12-3.12.0/Lib/test/test_eintr.py --- python3.12-3.12.0~rc2/Lib/test/test_eintr.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_eintr.py 2023-10-02 11:48:14.000000000 +0000 @@ -9,6 +9,7 @@ class EINTRTests(unittest.TestCase): @unittest.skipUnless(hasattr(signal, "setitimer"), "requires setitimer()") + @support.requires_resource('walltime') def test_all(self): # Run the tester in a sub-process, to make sure there is only one # thread (for reliable signal delivery). diff -Nru python3.12-3.12.0~rc2/Lib/test/test_enum.py python3.12-3.12.0/Lib/test/test_enum.py --- python3.12-3.12.0~rc2/Lib/test/test_enum.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_enum.py 2023-10-02 11:48:14.000000000 +0000 @@ -276,6 +276,7 @@ return self.name.title() def __format__(self, spec): return ''.join(reversed(self.name)) + self.NewBaseEnum = NewBaseEnum class NewSubEnum(NewBaseEnum): first = auto() self.NewSubEnum = NewSubEnum @@ -342,10 +343,8 @@ return self.name.title() def __format__(self, spec): return ''.join(reversed(self.name)) - NewBaseEnum = self.enum_type('NewBaseEnum', dict(__format__=__format__, __str__=__str__)) - class NewSubEnum(NewBaseEnum): - first = auto() - self.NewSubEnum = NewBaseEnum('NewSubEnum', 'first') + self.NewBaseEnum = self.enum_type('NewBaseEnum', dict(__format__=__format__, __str__=__str__)) + self.NewSubEnum = self.NewBaseEnum('NewSubEnum', 'first') # def _generate_next_value_(name, start, last, values): pass @@ -561,6 +560,10 @@ self.assertTrue('description' not in dir(SubEnum)) self.assertTrue('description' in dir(SubEnum.sample), dir(SubEnum.sample)) + def test_empty_enum_has_no_values(self): + with self.assertRaisesRegex(TypeError, "<.... 'NewBaseEnum'> has no members"): + self.NewBaseEnum(7) + def test_enum_in_enum_out(self): Main = self.MainEnum self.assertIs(Main(Main.first), Main.first) diff -Nru python3.12-3.12.0~rc2/Lib/test/test_faulthandler.py python3.12-3.12.0/Lib/test/test_faulthandler.py --- python3.12-3.12.0~rc2/Lib/test/test_faulthandler.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_faulthandler.py 2023-10-02 11:48:14.000000000 +0000 @@ -676,6 +676,7 @@ with tempfile.TemporaryFile('wb+') as fp: self.check_dump_traceback_later(fd=fp.fileno()) + @support.requires_resource('walltime') def test_dump_traceback_later_twice(self): self.check_dump_traceback_later(loops=2) diff -Nru python3.12-3.12.0~rc2/Lib/test/test_fstring.py python3.12-3.12.0/Lib/test/test_fstring.py --- python3.12-3.12.0~rc2/Lib/test/test_fstring.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_fstring.py 2023-10-02 11:48:14.000000000 +0000 @@ -1027,6 +1027,10 @@ "f'{lambda x:}'", "f'{lambda :}'", ]) + # Ensure the detection of invalid lambdas doesn't trigger detection + # for valid lambdas in the second error pass + with self.assertRaisesRegex(SyntaxError, "invalid syntax"): + compile("lambda name_3=f'{name_4}': {name_3}\n1 $ 1", "", "exec") # but don't emit the paren warning in general cases with self.assertRaisesRegex(SyntaxError, "f-string: expecting a valid expression after '{'"): diff -Nru python3.12-3.12.0~rc2/Lib/test/test_functools.py python3.12-3.12.0/Lib/test/test_functools.py --- python3.12-3.12.0~rc2/Lib/test/test_functools.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_functools.py 2023-10-02 11:48:14.000000000 +0000 @@ -26,10 +26,16 @@ py_functools = import_helper.import_fresh_module('functools', blocked=['_functools']) -c_functools = import_helper.import_fresh_module('functools') +c_functools = import_helper.import_fresh_module('functools', + fresh=['_functools']) decimal = import_helper.import_fresh_module('decimal', fresh=['_decimal']) +_partial_types = [py_functools.partial] +if c_functools: + _partial_types.append(c_functools.partial) + + @contextlib.contextmanager def replaced_module(name, replacement): original_module = sys.modules[name] @@ -201,7 +207,7 @@ kwargs = {'a': object(), 'b': object()} kwargs_reprs = ['a={a!r}, b={b!r}'.format_map(kwargs), 'b={b!r}, a={a!r}'.format_map(kwargs)] - if self.partial in (c_functools.partial, py_functools.partial): + if self.partial in _partial_types: name = 'functools.partial' else: name = self.partial.__name__ @@ -223,7 +229,7 @@ for kwargs_repr in kwargs_reprs]) def test_recursive_repr(self): - if self.partial in (c_functools.partial, py_functools.partial): + if self.partial in _partial_types: name = 'functools.partial' else: name = self.partial.__name__ @@ -250,7 +256,7 @@ f.__setstate__((capture, (), {}, {})) def test_pickle(self): - with self.AllowPickle(): + with replaced_module('functools', self.module): f = self.partial(signature, ['asdf'], bar=[True]) f.attr = [] for proto in range(pickle.HIGHEST_PROTOCOL + 1): @@ -333,7 +339,7 @@ self.assertIs(type(r[0]), tuple) def test_recursive_pickle(self): - with self.AllowPickle(): + with replaced_module('functools', self.module): f = self.partial(capture) f.__setstate__((f, (), {}, {})) try: @@ -387,14 +393,9 @@ @unittest.skipUnless(c_functools, 'requires the C _functools module') class TestPartialC(TestPartial, unittest.TestCase): if c_functools: + module = c_functools partial = c_functools.partial - class AllowPickle: - def __enter__(self): - return self - def __exit__(self, type, value, tb): - return False - def test_attributes_unwritable(self): # attributes should not be writable p = self.partial(capture, 1, 2, a=10, b=20) @@ -437,15 +438,9 @@ class TestPartialPy(TestPartial, unittest.TestCase): + module = py_functools partial = py_functools.partial - class AllowPickle: - def __init__(self): - self._cm = replaced_module("functools", py_functools) - def __enter__(self): - return self._cm.__enter__() - def __exit__(self, type, value, tb): - return self._cm.__exit__(type, value, tb) if c_functools: class CPartialSubclass(c_functools.partial): @@ -1872,9 +1867,10 @@ def py_cached_func(x, y): return 3 * x + y -@c_functools.lru_cache() -def c_cached_func(x, y): - return 3 * x + y +if c_functools: + @c_functools.lru_cache() + def c_cached_func(x, y): + return 3 * x + y class TestLRUPy(TestLRU, unittest.TestCase): @@ -1891,18 +1887,20 @@ return 3 * x + y +@unittest.skipUnless(c_functools, 'requires the C _functools module') class TestLRUC(TestLRU, unittest.TestCase): - module = c_functools - cached_func = c_cached_func, + if c_functools: + module = c_functools + cached_func = c_cached_func, - @module.lru_cache() - def cached_meth(self, x, y): - return 3 * x + y + @module.lru_cache() + def cached_meth(self, x, y): + return 3 * x + y - @staticmethod - @module.lru_cache() - def cached_staticmeth(x, y): - return 3 * x + y + @staticmethod + @module.lru_cache() + def cached_staticmeth(x, y): + return 3 * x + y class TestSingleDispatch(unittest.TestCase): diff -Nru python3.12-3.12.0~rc2/Lib/test/test_gdb.py python3.12-3.12.0/Lib/test/test_gdb.py --- python3.12-3.12.0~rc2/Lib/test/test_gdb.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_gdb.py 2023-10-02 11:48:14.000000000 +0000 @@ -55,10 +55,6 @@ if not sysconfig.is_python_build(): raise unittest.SkipTest("test_gdb only works on source builds at the moment.") -if 'Clang' in platform.python_compiler() and sys.platform == 'darwin': - raise unittest.SkipTest("test_gdb doesn't work correctly when python is" - " built with LLVM clang") - if ((sysconfig.get_config_var('PGO_PROF_USE_FLAG') or 'xxx') in (sysconfig.get_config_var('PY_CORE_CFLAGS') or '')): raise unittest.SkipTest("test_gdb is not reliable on PGO builds") @@ -247,6 +243,17 @@ for pattern in ( '(frame information optimized out)', 'Unable to read information on python frame', + # gh-91960: On Python built with "clang -Og", gdb gets + # "frame=" for _PyEval_EvalFrameDefault() parameter + '(unable to read python frame information)', + # gh-104736: On Python built with "clang -Og" on ppc64le, + # "py-bt" displays a truncated or not traceback, but "where" + # logs this error message: + 'Backtrace stopped: frame did not save the PC', + # gh-104736: When "bt" command displays something like: + # "#1 0x0000000000000000 in ?? ()", the traceback is likely + # truncated or wrong. + ' ?? ()', ): if pattern in out: raise unittest.SkipTest(f"{pattern!r} found in gdb output") diff -Nru python3.12-3.12.0~rc2/Lib/test/test_getopt.py python3.12-3.12.0/Lib/test/test_getopt.py --- python3.12-3.12.0~rc2/Lib/test/test_getopt.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_getopt.py 2023-10-02 11:48:14.000000000 +0000 @@ -1,8 +1,8 @@ # test_getopt.py # David Goodger 2000-08-19 -from test.support import verbose, run_doctest from test.support.os_helper import EnvironmentVarGuard +import doctest import unittest import getopt @@ -134,42 +134,6 @@ self.assertEqual(opts, [('-a', '')]) self.assertEqual(args, ['arg1', '-b', '1', '--alpha', '--beta=2']) - def test_libref_examples(self): - s = """ - Examples from the Library Reference: Doc/lib/libgetopt.tex - - An example using only Unix style options: - - - >>> import getopt - >>> args = '-a -b -cfoo -d bar a1 a2'.split() - >>> args - ['-a', '-b', '-cfoo', '-d', 'bar', 'a1', 'a2'] - >>> optlist, args = getopt.getopt(args, 'abc:d:') - >>> optlist - [('-a', ''), ('-b', ''), ('-c', 'foo'), ('-d', 'bar')] - >>> args - ['a1', 'a2'] - - Using long option names is equally easy: - - - >>> s = '--condition=foo --testing --output-file abc.def -x a1 a2' - >>> args = s.split() - >>> args - ['--condition=foo', '--testing', '--output-file', 'abc.def', '-x', 'a1', 'a2'] - >>> optlist, args = getopt.getopt(args, 'x', [ - ... 'condition=', 'output-file=', 'testing']) - >>> optlist - [('--condition', 'foo'), ('--testing', ''), ('--output-file', 'abc.def'), ('-x', '')] - >>> args - ['a1', 'a2'] - """ - - import types - m = types.ModuleType("libreftest", s) - run_doctest(m, verbose) - def test_issue4629(self): longopts, shortopts = getopt.getopt(['--help='], '', ['help=']) self.assertEqual(longopts, [('--help', '')]) @@ -177,5 +141,42 @@ self.assertEqual(longopts, [('--help', 'x')]) self.assertRaises(getopt.GetoptError, getopt.getopt, ['--help='], '', ['help']) +def test_libref_examples(): + """ + Examples from the Library Reference: Doc/lib/libgetopt.tex + + An example using only Unix style options: + + + >>> import getopt + >>> args = '-a -b -cfoo -d bar a1 a2'.split() + >>> args + ['-a', '-b', '-cfoo', '-d', 'bar', 'a1', 'a2'] + >>> optlist, args = getopt.getopt(args, 'abc:d:') + >>> optlist + [('-a', ''), ('-b', ''), ('-c', 'foo'), ('-d', 'bar')] + >>> args + ['a1', 'a2'] + + Using long option names is equally easy: + + + >>> s = '--condition=foo --testing --output-file abc.def -x a1 a2' + >>> args = s.split() + >>> args + ['--condition=foo', '--testing', '--output-file', 'abc.def', '-x', 'a1', 'a2'] + >>> optlist, args = getopt.getopt(args, 'x', [ + ... 'condition=', 'output-file=', 'testing']) + >>> optlist + [('--condition', 'foo'), ('--testing', ''), ('--output-file', 'abc.def'), ('-x', '')] + >>> args + ['a1', 'a2'] + """ + +def load_tests(loader, tests, pattern): + tests.addTest(doctest.DocTestSuite()) + return tests + + if __name__ == "__main__": unittest.main() diff -Nru python3.12-3.12.0~rc2/Lib/test/test_grammar.py python3.12-3.12.0/Lib/test/test_grammar.py --- python3.12-3.12.0~rc2/Lib/test/test_grammar.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_grammar.py 2023-10-02 11:48:14.000000000 +0000 @@ -350,6 +350,11 @@ check_syntax_error(self, "x: int: str") check_syntax_error(self, "def f():\n" " nonlocal x: int\n") + check_syntax_error(self, "def f():\n" + " global x: int\n") + check_syntax_error(self, "x: int = y = 1") + check_syntax_error(self, "z = w: int = 1") + check_syntax_error(self, "x: int = y: int = 1") # AST pass check_syntax_error(self, "[x, 0]: int\n") check_syntax_error(self, "f(): int\n") @@ -363,6 +368,12 @@ check_syntax_error(self, "def f():\n" " global x\n" " x: int\n") + check_syntax_error(self, "def f():\n" + " x: int\n" + " nonlocal x\n") + check_syntax_error(self, "def f():\n" + " nonlocal x\n" + " x: int\n") def test_var_annot_basic_semantics(self): # execution order diff -Nru python3.12-3.12.0~rc2/Lib/test/test_httplib.py python3.12-3.12.0/Lib/test/test_httplib.py --- python3.12-3.12.0~rc2/Lib/test/test_httplib.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_httplib.py 2023-10-02 11:48:14.000000000 +0000 @@ -1954,6 +1954,7 @@ h.close() self.assertIn('nginx', server_string) + @support.requires_resource('walltime') def test_networked_bad_cert(self): # We feed a "CA" cert that is unrelated to the server's cert import ssl diff -Nru python3.12-3.12.0~rc2/Lib/test/test_httpservers.py python3.12-3.12.0/Lib/test/test_httpservers.py --- python3.12-3.12.0~rc2/Lib/test/test_httpservers.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_httpservers.py 2023-10-02 11:48:14.000000000 +0000 @@ -26,6 +26,7 @@ import datetime import threading from unittest import mock +import warnings from io import BytesIO, StringIO import unittest @@ -699,7 +700,11 @@ "This test can't be run reliably as root (issue #13308).") class CGIHTTPServerTestCase(BaseTestCase): class request_handler(NoLogRequestHandler, CGIHTTPRequestHandler): - pass + def run_cgi(self): + # Silence the threading + fork DeprecationWarning this causes. + # gh-109096: This is deprecated in 3.13 to go away in 3.15. + with warnings.catch_warnings(action='ignore', category=DeprecationWarning): + return super().run_cgi() linesep = os.linesep.encode('ascii') diff -Nru python3.12-3.12.0~rc2/Lib/test/test_imaplib.py python3.12-3.12.0/Lib/test/test_imaplib.py --- python3.12-3.12.0~rc2/Lib/test/test_imaplib.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_imaplib.py 2023-10-02 11:48:14.000000000 +0000 @@ -10,7 +10,7 @@ import threading import socket -from test.support import verbose, run_with_tz, run_with_locale, cpython_only +from test.support import verbose, run_with_tz, run_with_locale, cpython_only, requires_resource from test.support import hashlib_helper from test.support import threading_helper import unittest @@ -74,6 +74,7 @@ for t in self.timevalues(): imaplib.Time2Internaldate(t) + @socket_helper.skip_if_tcp_blackhole def test_imap4_host_default_value(self): # Check whether the IMAP4_PORT is truly unavailable. with socket.socket() as s: @@ -456,6 +457,7 @@ with self.imap_class(*server.server_address): pass + @requires_resource('walltime') def test_imaplib_timeout_test(self): _, server = self._setup(SimpleIMAPHandler) addr = server.server_address[1] @@ -549,6 +551,7 @@ imap_class = IMAP4_SSL server_class = SecureTCPServer + @requires_resource('walltime') def test_ssl_raises(self): ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) self.assertEqual(ssl_context.verify_mode, ssl.CERT_REQUIRED) @@ -563,6 +566,7 @@ ssl_context=ssl_context) client.shutdown() + @requires_resource('walltime') def test_ssl_verified(self): ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) ssl_context.load_verify_locations(CAFILE) diff -Nru python3.12-3.12.0~rc2/Lib/test/test_import/__init__.py python3.12-3.12.0/Lib/test/test_import/__init__.py --- python3.12-3.12.0~rc2/Lib/test/test_import/__init__.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_import/__init__.py 2023-10-02 11:48:14.000000000 +0000 @@ -106,6 +106,25 @@ rmtree('__pycache__') +def no_rerun(reason): + """Skip rerunning for a particular test. + + WARNING: Use this decorator with care; skipping rerunning makes it + impossible to find reference leaks. Provide a clear reason for skipping the + test using the 'reason' parameter. + """ + def deco(func): + _has_run = False + def wrapper(self): + nonlocal _has_run + if _has_run: + self.skipTest(reason) + func(self) + _has_run = True + return wrapper + return deco + + @contextlib.contextmanager def _ready_to_import(name=None, source=""): # sets up a temporary directory and removes it @@ -2018,10 +2037,6 @@ @classmethod def setUpClass(cls): - if '-R' in sys.argv or '--huntrleaks' in sys.argv: - # https://github.com/python/cpython/issues/102251 - raise unittest.SkipTest('unresolved refleaks (see gh-102251)') - spec = importlib.util.find_spec(cls.NAME) from importlib.machinery import ExtensionFileLoader cls.FILE = spec.origin @@ -2535,6 +2550,7 @@ # * m_copy was copied from interp2 (was from interp1) # * module's global state was updated, not reset + @no_rerun(reason="rerun not possible; module state is never cleared (see gh-102251)") @requires_subinterpreters def test_basic_multiple_interpreters_deleted_no_reset(self): # without resetting; already loaded in a deleted interpreter diff -Nru python3.12-3.12.0~rc2/Lib/test/test_io.py python3.12-3.12.0/Lib/test/test_io.py --- python3.12-3.12.0~rc2/Lib/test/test_io.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_io.py 2023-10-02 11:48:14.000000000 +0000 @@ -4478,10 +4478,12 @@ self.assertFalse(err.strip('.!')) @threading_helper.requires_working_threading() + @support.requires_resource('walltime') def test_daemon_threads_shutdown_stdout_deadlock(self): self.check_daemon_threads_shutdown_deadlock('stdout') @threading_helper.requires_working_threading() + @support.requires_resource('walltime') def test_daemon_threads_shutdown_stderr_deadlock(self): self.check_daemon_threads_shutdown_deadlock('stderr') @@ -4655,11 +4657,13 @@ os.close(r) @requires_alarm + @support.requires_resource('walltime') def test_interrupted_read_retry_buffered(self): self.check_interrupted_read_retry(lambda x: x.decode('latin1'), mode="rb") @requires_alarm + @support.requires_resource('walltime') def test_interrupted_read_retry_text(self): self.check_interrupted_read_retry(lambda x: x, mode="r", encoding="latin1") @@ -4733,10 +4737,12 @@ raise @requires_alarm + @support.requires_resource('walltime') def test_interrupted_write_retry_buffered(self): self.check_interrupted_write_retry(b"x", mode="wb") @requires_alarm + @support.requires_resource('walltime') def test_interrupted_write_retry_text(self): self.check_interrupted_write_retry("x", mode="w", encoding="latin1") diff -Nru python3.12-3.12.0~rc2/Lib/test/test_listcomps.py python3.12-3.12.0/Lib/test/test_listcomps.py --- python3.12-3.12.0~rc2/Lib/test/test_listcomps.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_listcomps.py 2023-10-02 11:48:14.000000000 +0000 @@ -125,7 +125,7 @@ self.assertIs(type(e), raises) else: for k, v in (outputs or {}).items(): - self.assertEqual(get_output(newns, k), v) + self.assertEqual(get_output(newns, k), v, k) def test_lambdas_with_iteration_var_as_default(self): code = """ @@ -563,28 +563,38 @@ def test_comp_in_try_except(self): template = """ - value = ["a"] + value = ["ab"] + result = snapshot = None try: - [{func}(value) for value in value] + result = [{func}(value) for value in value] except: - pass + snapshot = value + raise """ - for func in ["str", "int"]: - code = template.format(func=func) - raises = func != "str" - with self.subTest(raises=raises): - self._check_in_scopes(code, {"value": ["a"]}) + # No exception. + code = template.format(func='len') + self._check_in_scopes(code, {"value": ["ab"], "result": [2], "snapshot": None}) + # Handles exception. + code = template.format(func='int') + self._check_in_scopes(code, {"value": ["ab"], "result": None, "snapshot": ["ab"]}, + raises=ValueError) def test_comp_in_try_finally(self): - code = """ - def f(value): - try: - [{func}(value) for value in value] - finally: - return value - ret = f(["a"]) - """ - self._check_in_scopes(code, {"ret": ["a"]}) + template = """ + value = ["ab"] + result = snapshot = None + try: + result = [{func}(value) for value in value] + finally: + snapshot = value + """ + # No exception. + code = template.format(func='len') + self._check_in_scopes(code, {"value": ["ab"], "result": [2], "snapshot": ["ab"]}) + # Handles exception. + code = template.format(func='int') + self._check_in_scopes(code, {"value": ["ab"], "result": None, "snapshot": ["ab"]}, + raises=ValueError) def test_exception_in_post_comp_call(self): code = """ @@ -596,6 +606,13 @@ """ self._check_in_scopes(code, {"value": [1, None]}) + def test_frame_locals(self): + code = """ + val = [sys._getframe().f_locals for a in [0]][0]["a"] + """ + import sys + self._check_in_scopes(code, {"val": 0}, ns={"sys": sys}) + __test__ = {'doctests' : doctests} diff -Nru python3.12-3.12.0~rc2/Lib/test/test_logging.py python3.12-3.12.0/Lib/test/test_logging.py --- python3.12-3.12.0~rc2/Lib/test/test_logging.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_logging.py 2023-10-02 11:48:14.000000000 +0000 @@ -680,6 +680,7 @@ support.is_emscripten, "Emscripten cannot fstat unlinked files." ) @threading_helper.requires_working_threading() + @support.requires_resource('walltime') def test_race(self): # Issue #14632 refers. def remove_loop(fname, tries): diff -Nru python3.12-3.12.0~rc2/Lib/test/test_mmap.py python3.12-3.12.0/Lib/test/test_mmap.py --- python3.12-3.12.0~rc2/Lib/test/test_mmap.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_mmap.py 2023-10-02 11:48:14.000000000 +0000 @@ -255,10 +255,15 @@ # Try writing with PROT_EXEC and without PROT_WRITE prot = mmap.PROT_READ | getattr(mmap, 'PROT_EXEC', 0) with open(TESTFN, "r+b") as f: - m = mmap.mmap(f.fileno(), mapsize, prot=prot) - self.assertRaises(TypeError, m.write, b"abcdef") - self.assertRaises(TypeError, m.write_byte, 0) - m.close() + try: + m = mmap.mmap(f.fileno(), mapsize, prot=prot) + except PermissionError: + # on macOS 14, PROT_READ | PROT_EXEC is not allowed + pass + else: + self.assertRaises(TypeError, m.write, b"abcdef") + self.assertRaises(TypeError, m.write_byte, 0) + m.close() def test_bad_file_desc(self): # Try opening a bad file descriptor... diff -Nru python3.12-3.12.0~rc2/Lib/test/test_monitoring.py python3.12-3.12.0/Lib/test/test_monitoring.py --- python3.12-3.12.0~rc2/Lib/test/test_monitoring.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_monitoring.py 2023-10-02 11:48:14.000000000 +0000 @@ -501,6 +501,22 @@ self.assertEqual(sys.monitoring._all_events(), {}) sys.monitoring.restart_events() + def test_with_instruction_event(self): + """Test that the second tool can set events with instruction events set by the first tool.""" + def f(): + pass + code = f.__code__ + + try: + self.assertEqual(sys.monitoring._all_events(), {}) + sys.monitoring.set_local_events(TEST_TOOL, code, E.INSTRUCTION | E.LINE) + sys.monitoring.set_local_events(TEST_TOOL2, code, E.LINE) + finally: + sys.monitoring.set_events(TEST_TOOL, 0) + sys.monitoring.set_events(TEST_TOOL2, 0) + self.assertEqual(sys.monitoring._all_events(), {}) + + class LineMonitoringTest(MonitoringTestBase, unittest.TestCase): def test_lines_single(self): @@ -1718,3 +1734,12 @@ make_foo_optimized_then_set_event() finally: sys.monitoring.set_events(TEST_TOOL, 0) + + def test_gh108976(self): + sys.monitoring.use_tool_id(0, "test") + self.addCleanup(sys.monitoring.free_tool_id, 0) + sys.monitoring.set_events(0, 0) + sys.monitoring.register_callback(0, E.LINE, lambda *args: sys.monitoring.set_events(0, 0)) + sys.monitoring.register_callback(0, E.INSTRUCTION, lambda *args: 0) + sys.monitoring.set_events(0, E.LINE | E.INSTRUCTION) + sys.monitoring.set_events(0, 0) diff -Nru python3.12-3.12.0~rc2/Lib/test/_test_multiprocessing.py python3.12-3.12.0/Lib/test/_test_multiprocessing.py --- python3.12-3.12.0~rc2/Lib/test/_test_multiprocessing.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/_test_multiprocessing.py 2023-10-02 11:48:14.000000000 +0000 @@ -675,6 +675,7 @@ close_queue(q) + @support.requires_resource('walltime') def test_many_processes(self): if self.TYPE == 'threads': self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -4953,6 +4954,7 @@ def test_wait_socket_slow(self): self.test_wait_socket(True) + @support.requires_resource('walltime') def test_wait_timeout(self): from multiprocessing.connection import wait @@ -4981,6 +4983,7 @@ sem.release() time.sleep(period) + @support.requires_resource('walltime') def test_wait_integer(self): from multiprocessing.connection import wait diff -Nru python3.12-3.12.0~rc2/Lib/test/test_os.py python3.12-3.12.0/Lib/test/test_os.py --- python3.12-3.12.0~rc2/Lib/test/test_os.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_os.py 2023-10-02 11:48:14.000000000 +0000 @@ -737,7 +737,7 @@ # denied. See issue 28075. # os.environ['TEMP'] should be located on a volume that # supports file ACLs. - fname = os.path.join(os.environ['TEMP'], self.fname) + fname = os.path.join(os.environ['TEMP'], self.fname + "_access") self.addCleanup(os_helper.unlink, fname) create_file(fname, b'ABC') # Deny the right to [S]YNCHRONIZE on the file to diff -Nru python3.12-3.12.0~rc2/Lib/test/test_pdb.py python3.12-3.12.0/Lib/test/test_pdb.py --- python3.12-3.12.0~rc2/Lib/test/test_pdb.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_pdb.py 2023-10-02 11:48:14.000000000 +0000 @@ -1799,6 +1799,24 @@ (Pdb) continue """ +def test_pdb_issue_gh_108976(): + """See GH-108976 + Make sure setting f_trace_opcodes = True won't crash pdb + >>> def test_function(): + ... import sys + ... sys._getframe().f_trace_opcodes = True + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + ... a = 1 + >>> with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE + ... 'continue' + ... ]): + ... test_function() + bdb.Bdb.dispatch: unknown debugging event: 'opcode' + > (5)test_function() + -> a = 1 + (Pdb) continue + """ + def test_pdb_ambiguous_statements(): """See GH-104301 diff -Nru python3.12-3.12.0~rc2/Lib/test/test_poll.py python3.12-3.12.0/Lib/test/test_poll.py --- python3.12-3.12.0~rc2/Lib/test/test_poll.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_poll.py 2023-10-02 11:48:14.000000000 +0000 @@ -8,7 +8,7 @@ import time import unittest from test.support import ( - cpython_only, requires_subprocess, requires_working_socket + cpython_only, requires_subprocess, requires_working_socket, requires_resource ) from test.support import threading_helper from test.support.os_helper import TESTFN @@ -124,6 +124,7 @@ # select(), modified to use poll() instead. @requires_subprocess() + @requires_resource('walltime') def test_poll2(self): cmd = 'for i in 0 1 2 3 4 5 6 7 8 9; do echo testing...; sleep 1; done' proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, diff -Nru python3.12-3.12.0~rc2/Lib/test/test_pyexpat.py python3.12-3.12.0/Lib/test/test_pyexpat.py --- python3.12-3.12.0~rc2/Lib/test/test_pyexpat.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_pyexpat.py 2023-10-02 11:48:14.000000000 +0000 @@ -1,13 +1,15 @@ # XXX TypeErrors on calling handlers, or on bad return values from a # handler, are obscure and unhelpful. -from io import BytesIO import os import platform import sys import sysconfig import unittest import traceback +from io import BytesIO +from test import support +from test.support import os_helper from xml.parsers import expat from xml.parsers.expat import errors @@ -441,37 +443,59 @@ # Test handling of exception from callback: class HandlerExceptionTest(unittest.TestCase): def StartElementHandler(self, name, attrs): - raise RuntimeError(name) + raise RuntimeError(f'StartElementHandler: <{name}>') def check_traceback_entry(self, entry, filename, funcname): - self.assertEqual(os.path.basename(entry[0]), filename) - self.assertEqual(entry[2], funcname) + self.assertEqual(os.path.basename(entry.filename), filename) + self.assertEqual(entry.name, funcname) + @support.cpython_only def test_exception(self): + # gh-66652: test _PyTraceback_Add() used by pyexpat.c to inject frames + + # Change the current directory to the Python source code directory + # if it is available. + src_dir = sysconfig.get_config_var('abs_builddir') + if src_dir: + have_source = os.path.isdir(src_dir) + else: + have_source = False + if have_source: + with os_helper.change_cwd(src_dir): + self._test_exception(have_source) + else: + self._test_exception(have_source) + + def _test_exception(self, have_source): + # Use path relative to the current directory which should be the Python + # source code directory (if it is available). + PYEXPAT_C = os.path.join('Modules', 'pyexpat.c') + parser = expat.ParserCreate() parser.StartElementHandler = self.StartElementHandler try: parser.Parse(b"", True) - self.fail() - except RuntimeError as e: - self.assertEqual(e.args[0], 'a', - "Expected RuntimeError for element 'a', but" + \ - " found %r" % e.args[0]) - # Check that the traceback contains the relevant line in pyexpat.c - entries = traceback.extract_tb(e.__traceback__) - self.assertEqual(len(entries), 3) - self.check_traceback_entry(entries[0], - "test_pyexpat.py", "test_exception") - self.check_traceback_entry(entries[1], - "pyexpat.c", "StartElement") - self.check_traceback_entry(entries[2], - "test_pyexpat.py", "StartElementHandler") - if (sysconfig.is_python_build() - and not (sys.platform == 'win32' and platform.machine() == 'ARM') - and not is_emscripten - and not is_wasi - ): - self.assertIn('call_with_frame("StartElement"', entries[1][3]) + + self.fail("the parser did not raise RuntimeError") + except RuntimeError as exc: + self.assertEqual(exc.args[0], 'StartElementHandler: ', exc) + entries = traceback.extract_tb(exc.__traceback__) + + self.assertEqual(len(entries), 3, entries) + self.check_traceback_entry(entries[0], + "test_pyexpat.py", "_test_exception") + self.check_traceback_entry(entries[1], + os.path.basename(PYEXPAT_C), + "StartElement") + self.check_traceback_entry(entries[2], + "test_pyexpat.py", "StartElementHandler") + + # Check that the traceback contains the relevant line in + # Modules/pyexpat.c. Skip the test if Modules/pyexpat.c is not + # available. + if have_source and os.path.exists(PYEXPAT_C): + self.assertIn('call_with_frame("StartElement"', + entries[1].line) # Test Current* members: diff -Nru python3.12-3.12.0~rc2/Lib/test/test_regrtest.py python3.12-3.12.0/Lib/test/test_regrtest.py --- python3.12-3.12.0~rc2/Lib/test/test_regrtest.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_regrtest.py 2023-10-02 11:48:14.000000000 +0000 @@ -5,6 +5,7 @@ """ import contextlib +import dataclasses import glob import io import locale @@ -21,6 +22,7 @@ from test import support from test.support import os_helper, TestStats from test.libregrtest import utils, setup +from test.libregrtest.runtest import normalize_test_name if not support.has_subprocess_support: raise unittest.SkipTest("test module requires subprocess") @@ -32,6 +34,7 @@ EXITCODE_BAD_TEST = 2 EXITCODE_ENV_CHANGED = 3 EXITCODE_NO_TESTS_RAN = 4 +EXITCODE_RERUN_FAIL = 5 EXITCODE_INTERRUPTED = 130 TEST_INTERRUPTED = textwrap.dedent(""" @@ -96,11 +99,11 @@ ns = libregrtest._parse_args([]) self.assertEqual(ns.verbose, 0) - def test_verbose2(self): - for opt in '-w', '--verbose2': + def test_rerun(self): + for opt in '-w', '--rerun', '--verbose2': with self.subTest(opt=opt): ns = libregrtest._parse_args([opt]) - self.assertTrue(ns.verbose2) + self.assertTrue(ns.rerun) def test_verbose3(self): for opt in '-W', '--verbose3': @@ -362,6 +365,13 @@ 'unrecognized arguments: --unknown-option') +@dataclasses.dataclass(slots=True) +class Rerun: + name: str + match: str | None + success: bool + + class BaseTestCase(unittest.TestCase): TEST_UNIQUE_ID = 1 TESTNAME_PREFIX = 'test_regrtest_' @@ -423,11 +433,11 @@ def check_executed_tests(self, output, tests, skipped=(), failed=(), env_changed=(), omitted=(), - rerun={}, run_no_tests=(), + rerun=None, run_no_tests=(), resource_denied=(), randomize=False, interrupted=False, fail_env_changed=False, - *, stats): + *, stats, forever=False, filtered=False): if isinstance(tests, str): tests = [tests] if isinstance(skipped, str): @@ -445,11 +455,20 @@ if isinstance(stats, int): stats = TestStats(stats) + rerun_failed = [] + if rerun is not None: + failed = [rerun.name] + if not rerun.success: + rerun_failed.append(rerun.name) + executed = self.parse_executed_tests(output) + total_tests = list(tests) + if rerun is not None: + total_tests.append(rerun.name) if randomize: - self.assertEqual(set(executed), set(tests), output) + self.assertEqual(set(executed), set(total_tests), output) else: - self.assertEqual(executed, tests, output) + self.assertEqual(executed, total_tests, output) def plural(count): return 's' if count != 1 else '' @@ -465,6 +484,10 @@ regex = list_regex('%s test%s skipped', skipped) self.check_line(output, regex) + if resource_denied: + regex = list_regex(r'%s test%s skipped \(resource denied\)', resource_denied) + self.check_line(output, regex) + if failed: regex = list_regex('%s test%s failed', failed) self.check_line(output, regex) @@ -478,32 +501,36 @@ regex = list_regex('%s test%s omitted', omitted) self.check_line(output, regex) - if rerun: - regex = list_regex('%s re-run test%s', rerun.keys()) + if rerun is not None: + regex = list_regex('%s re-run test%s', [rerun.name]) self.check_line(output, regex) - regex = LOG_PREFIX + r"Re-running failed tests in verbose mode" + regex = LOG_PREFIX + fr"Re-running 1 failed tests in verbose mode" + self.check_line(output, regex) + regex = fr"Re-running {rerun.name} in verbose mode" + if rerun.match: + regex = fr"{regex} \(matching: {rerun.match}\)" self.check_line(output, regex) - for name, match in rerun.items(): - regex = LOG_PREFIX + f"Re-running {name} in verbose mode \\(matching: {match}\\)" - self.check_line(output, regex) if run_no_tests: regex = list_regex('%s test%s run no tests', run_no_tests) self.check_line(output, regex) - good = (len(tests) - len(skipped) - len(failed) + good = (len(tests) - len(skipped) - len(resource_denied) - len(failed) - len(omitted) - len(env_changed) - len(run_no_tests)) if good: - regex = r'%s test%s OK\.$' % (good, plural(good)) - if not skipped and not failed and good > 1: + regex = r'%s test%s OK\.' % (good, plural(good)) + if not skipped and not failed and (rerun is None or rerun.success) and good > 1: regex = 'All %s' % regex - self.check_line(output, regex) + self.check_line(output, regex, full=True) if interrupted: self.check_line(output, 'Test suite interrupted by signal SIGINT.') # Total tests - parts = [f'run={stats.tests_run:,}'] + text = f'run={stats.tests_run:,}' + if filtered: + text = fr'{text} \(filtered\)' + parts = [text] if stats.failures: parts.append(f'failures={stats.failures:,}') if stats.skipped: @@ -512,39 +539,52 @@ self.check_line(output, line, full=True) # Total test files - report = [f'success={good}'] - if failed: - report.append(f'failed={len(failed)}') - if env_changed: - report.append(f'env_changed={len(env_changed)}') - if skipped: - report.append(f'skipped={len(skipped)}') - if resource_denied: - report.append(f'resource_denied={len(resource_denied)}') - if rerun: - report.append(f'rerun={len(rerun)}') - if run_no_tests: - report.append(f'run_no_tests={len(run_no_tests)}') + run = len(total_tests) - len(resource_denied) + if rerun is not None: + total_failed = len(rerun_failed) + total_rerun = 1 + else: + total_failed = len(failed) + total_rerun = 0 + if interrupted: + run = 0 + text = f'run={run}' + if not forever: + text = f'{text}/{len(tests)}' + if filtered: + text = fr'{text} \(filtered\)' + report = [text] + for name, ntest in ( + ('failed', total_failed), + ('env_changed', len(env_changed)), + ('skipped', len(skipped)), + ('resource_denied', len(resource_denied)), + ('rerun', total_rerun), + ('run_no_tests', len(run_no_tests)), + ): + if ntest: + report.append(f'{name}={ntest}') line = fr'Total test files: {" ".join(report)}' self.check_line(output, line, full=True) # Result - result = [] + state = [] if failed: - result.append('FAILURE') + state.append('FAILURE') elif fail_env_changed and env_changed: - result.append('ENV CHANGED') + state.append('ENV CHANGED') if interrupted: - result.append('INTERRUPTED') - if not any((good, result, failed, interrupted, skipped, + state.append('INTERRUPTED') + if not any((good, failed, interrupted, skipped, env_changed, fail_env_changed)): - result.append("NO TESTS RAN") - elif not result: - result.append('SUCCESS') - result = ', '.join(result) - if rerun: - result = 'FAILURE then %s' % result - self.check_line(output, f'Result: {result}', full=True) + state.append("NO TESTS RAN") + elif not state: + state.append('SUCCESS') + state = ', '.join(state) + if rerun is not None: + new_state = 'SUCCESS' if rerun.success else 'FAILURE' + state = 'FAILURE then ' + new_state + self.check_line(output, f'Result: {state}', full=True) def parse_random_seed(self, output): match = self.regex_search(r'Using random seed ([0-9]+)', output) @@ -563,13 +603,13 @@ stdout=subprocess.PIPE, **kw) if proc.returncode != exitcode: - msg = ("Command %s failed with exit code %s\n" + msg = ("Command %s failed with exit code %s, but exit code %s expected!\n" "\n" "stdout:\n" "---\n" "%s\n" "---\n" - % (str(args), proc.returncode, proc.stdout)) + % (str(args), proc.returncode, exitcode, proc.stdout)) if proc.stderr: msg += ("\n" "stderr:\n" @@ -734,6 +774,40 @@ cmdargs = ['-m', 'test', '--testdir=%s' % self.tmptestdir, *testargs] return self.run_python(cmdargs, **kw) + def test_success(self): + code = textwrap.dedent(""" + import unittest + + class PassingTests(unittest.TestCase): + def test_test1(self): + pass + + def test_test2(self): + pass + + def test_test3(self): + pass + """) + tests = [self.create_test(f'ok{i}', code=code) for i in range(1, 6)] + + output = self.run_tests(*tests) + self.check_executed_tests(output, tests, + stats=3 * len(tests)) + + def test_skip(self): + code = textwrap.dedent(""" + import unittest + raise unittest.SkipTest("nope") + """) + test_ok = self.create_test('ok') + test_skip = self.create_test('skip', code=code) + tests = [test_ok, test_skip] + + output = self.run_tests(*tests) + self.check_executed_tests(output, tests, + skipped=[test_skip], + stats=1) + def test_failing_test(self): # test a failing test code = textwrap.dedent(""" @@ -773,14 +847,12 @@ # -u audio: 1 resource enabled output = self.run_tests('-uaudio', *test_names) self.check_executed_tests(output, test_names, - skipped=tests['network'], resource_denied=tests['network'], stats=1) # no option: 0 resources enabled - output = self.run_tests(*test_names) + output = self.run_tests(*test_names, exitcode=EXITCODE_NO_TESTS_RAN) self.check_executed_tests(output, test_names, - skipped=test_names, resource_denied=test_names, stats=0) @@ -926,9 +998,21 @@ builtins.__dict__['RUN'] = 1 """) test = self.create_test('forever', code=code) + + # --forever output = self.run_tests('--forever', test, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, [test]*3, failed=test, - stats=TestStats(1, 1)) + stats=TestStats(3, 1), + forever=True) + + # --forever --rerun + output = self.run_tests('--forever', '--rerun', test, exitcode=0) + self.check_executed_tests(output, [test]*3, + rerun=Rerun(test, + match='test_run', + success=True), + stats=TestStats(4, 1), + forever=True) def check_leak(self, code, what): test = self.create_test('huntrleaks', code=code) @@ -1139,33 +1223,55 @@ """) testname = self.create_test(code=code) - output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) + output = self.run_tests("--rerun", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, [testname], - failed=testname, - rerun={testname: "test_fail_always"}, - stats=TestStats(1, 1)) + rerun=Rerun(testname, + "test_fail_always", + success=False), + stats=TestStats(3, 2)) def test_rerun_success(self): # FAILURE then SUCCESS - code = textwrap.dedent(""" - import builtins + marker_filename = os.path.abspath("regrtest_marker_filename") + self.addCleanup(os_helper.unlink, marker_filename) + self.assertFalse(os.path.exists(marker_filename)) + + code = textwrap.dedent(f""" + import os.path import unittest + marker_filename = {marker_filename!r} + class Tests(unittest.TestCase): def test_succeed(self): return def test_fail_once(self): - if not hasattr(builtins, '_test_failed'): - builtins._test_failed = True + if not os.path.exists(marker_filename): + open(marker_filename, "w").close() self.fail("bug") """) testname = self.create_test(code=code) - output = self.run_tests("-w", testname, exitcode=0) + # FAILURE then SUCCESS => exit code 0 + output = self.run_tests("--rerun", testname, exitcode=0) self.check_executed_tests(output, [testname], - rerun={testname: "test_fail_once"}, - stats=1) + rerun=Rerun(testname, + match="test_fail_once", + success=True), + stats=TestStats(3, 1)) + os_helper.unlink(marker_filename) + + # with --fail-rerun, exit code EXITCODE_RERUN_FAIL + # on "FAILURE then SUCCESS" state. + output = self.run_tests("--rerun", "--fail-rerun", testname, + exitcode=EXITCODE_RERUN_FAIL) + self.check_executed_tests(output, [testname], + rerun=Rerun(testname, + match="test_fail_once", + success=True), + stats=TestStats(3, 1)) + os_helper.unlink(marker_filename) def test_rerun_setup_class_hook_failure(self): # FAILURE then FAILURE @@ -1182,10 +1288,12 @@ """) testname = self.create_test(code=code) - output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) + output = self.run_tests("--rerun", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, testname, failed=[testname], - rerun={testname: "ExampleTests"}, + rerun=Rerun(testname, + match="ExampleTests", + success=False), stats=0) def test_rerun_teardown_class_hook_failure(self): @@ -1203,11 +1311,13 @@ """) testname = self.create_test(code=code) - output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) + output = self.run_tests("--rerun", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, testname, failed=[testname], - rerun={testname: "ExampleTests"}, - stats=1) + rerun=Rerun(testname, + match="ExampleTests", + success=False), + stats=2) def test_rerun_setup_module_hook_failure(self): # FAILURE then FAILURE @@ -1223,10 +1333,12 @@ """) testname = self.create_test(code=code) - output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) + output = self.run_tests("--rerun", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, testname, failed=[testname], - rerun={testname: testname}, + rerun=Rerun(testname, + match=None, + success=False), stats=0) def test_rerun_teardown_module_hook_failure(self): @@ -1243,11 +1355,13 @@ """) testname = self.create_test(code=code) - output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) - self.check_executed_tests(output, testname, + output = self.run_tests("--rerun", testname, exitcode=EXITCODE_BAD_TEST) + self.check_executed_tests(output, [testname], failed=[testname], - rerun={testname: testname}, - stats=1) + rerun=Rerun(testname, + match=None, + success=False), + stats=2) def test_rerun_setup_hook_failure(self): # FAILURE then FAILURE @@ -1263,11 +1377,13 @@ """) testname = self.create_test(code=code) - output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) + output = self.run_tests("--rerun", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, testname, failed=[testname], - rerun={testname: "test_success"}, - stats=1) + rerun=Rerun(testname, + match="test_success", + success=False), + stats=2) def test_rerun_teardown_hook_failure(self): # FAILURE then FAILURE @@ -1283,11 +1399,13 @@ """) testname = self.create_test(code=code) - output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) + output = self.run_tests("--rerun", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, testname, failed=[testname], - rerun={testname: "test_success"}, - stats=1) + rerun=Rerun(testname, + match="test_success", + success=False), + stats=2) def test_rerun_async_setup_hook_failure(self): # FAILURE then FAILURE @@ -1303,11 +1421,12 @@ """) testname = self.create_test(code=code) - output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) + output = self.run_tests("--rerun", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, testname, - failed=[testname], - rerun={testname: "test_success"}, - stats=1) + rerun=Rerun(testname, + match="test_success", + success=False), + stats=2) def test_rerun_async_teardown_hook_failure(self): # FAILURE then FAILURE @@ -1323,11 +1442,13 @@ """) testname = self.create_test(code=code) - output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) + output = self.run_tests("--rerun", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, testname, failed=[testname], - rerun={testname: "test_success"}, - stats=1) + rerun=Rerun(testname, + match="test_success", + success=False), + stats=2) def test_no_tests_ran(self): code = textwrap.dedent(""" @@ -1343,7 +1464,7 @@ exitcode=EXITCODE_NO_TESTS_RAN) self.check_executed_tests(output, [testname], run_no_tests=testname, - stats=0) + stats=0, filtered=True) def test_no_tests_ran_skip(self): code = textwrap.dedent(""" @@ -1374,7 +1495,7 @@ exitcode=EXITCODE_NO_TESTS_RAN) self.check_executed_tests(output, [testname, testname2], run_no_tests=[testname, testname2], - stats=0) + stats=0, filtered=True) def test_no_test_ran_some_test_exist_some_not(self): code = textwrap.dedent(""" @@ -1398,7 +1519,7 @@ "-m", "test_other_bug", exitcode=0) self.check_executed_tests(output, [testname, testname2], run_no_tests=[testname], - stats=1) + stats=1, filtered=True) @support.cpython_only def test_uncollectable(self): @@ -1715,6 +1836,17 @@ self.assertEqual(utils.format_duration(3 * 3600 + 1), '3 hour 1 sec') + def test_normalize_test_name(self): + normalize = normalize_test_name + self.assertEqual(normalize('test_access (test.test_os.FileTests.test_access)'), + 'test_access') + self.assertEqual(normalize('setUpClass (test.test_os.ChownFileTests)', is_error=True), + 'ChownFileTests') + self.assertEqual(normalize('test_success (test.test_bug.ExampleTests.test_success)', is_error=True), + 'test_success') + self.assertIsNone(normalize('setUpModule (test.test_x)', is_error=True)) + self.assertIsNone(normalize('tearDownModule (test.test_module)', is_error=True)) + if __name__ == '__main__': unittest.main() diff -Nru python3.12-3.12.0~rc2/Lib/test/test_signal.py python3.12-3.12.0/Lib/test/test_signal.py --- python3.12-3.12.0~rc2/Lib/test/test_signal.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_signal.py 2023-10-02 11:48:14.000000000 +0000 @@ -745,6 +745,7 @@ interrupted = self.readpipe_interrupted(True) self.assertTrue(interrupted) + @support.requires_resource('walltime') def test_siginterrupt_off(self): # If a signal handler is installed and siginterrupt is called with # a false value for the second argument, when that signal arrives, it diff -Nru python3.12-3.12.0~rc2/Lib/test/test_site.py python3.12-3.12.0/Lib/test/test_site.py --- python3.12-3.12.0~rc2/Lib/test/test_site.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_site.py 2023-10-02 11:48:14.000000000 +0000 @@ -576,7 +576,7 @@ _pth_file = os.path.splitext(exe_file)[0] + '._pth' else: _pth_file = os.path.splitext(dll_file)[0] + '._pth' - with open(_pth_file, 'w') as f: + with open(_pth_file, 'w', encoding='utf8') as f: for line in lines: print(line, file=f) return exe_file @@ -613,7 +613,7 @@ os.path.dirname(exe_file), pth_lines) - output = subprocess.check_output([exe_file, '-c', + output = subprocess.check_output([exe_file, '-X', 'utf8', '-c', 'import sys; print("\\n".join(sys.path) if sys.flags.no_site else "")' ], encoding='utf-8', errors='surrogateescape') actual_sys_path = output.rstrip().split('\n') diff -Nru python3.12-3.12.0~rc2/Lib/test/test_smtpnet.py python3.12-3.12.0/Lib/test/test_smtpnet.py --- python3.12-3.12.0~rc2/Lib/test/test_smtpnet.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_smtpnet.py 2023-10-02 11:48:14.000000000 +0000 @@ -61,6 +61,7 @@ server.ehlo() server.quit() + @support.requires_resource('walltime') def test_connect_using_sslcontext(self): context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) context.check_hostname = False diff -Nru python3.12-3.12.0~rc2/Lib/test/test_socket.py python3.12-3.12.0/Lib/test/test_socket.py --- python3.12-3.12.0~rc2/Lib/test/test_socket.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_socket.py 2023-10-02 11:48:14.000000000 +0000 @@ -5288,6 +5288,7 @@ finally: socket.socket = old_socket + @socket_helper.skip_if_tcp_blackhole def test_connect(self): port = socket_helper.find_unused_port() cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -5296,6 +5297,7 @@ cli.connect((HOST, port)) self.assertEqual(cm.exception.errno, errno.ECONNREFUSED) + @socket_helper.skip_if_tcp_blackhole def test_create_connection(self): # Issue #9792: errors raised by create_connection() should have # a proper errno attribute. @@ -6472,12 +6474,16 @@ self.assertEqual(op.recv(512), expected) def test_hmac_sha1(self): - expected = bytes.fromhex("effcdf6ae5eb2fa2d27416d5f184df9c259a7c79") + # gh-109396: In FIPS mode, Linux 6.5 requires a key + # of at least 112 bits. Use a key of 152 bits. + key = b"Python loves AF_ALG" + data = b"what do ya want for nothing?" + expected = bytes.fromhex("193dbb43c6297b47ea6277ec0ce67119a3f3aa66") with self.create_alg('hash', 'hmac(sha1)') as algo: - algo.setsockopt(socket.SOL_ALG, socket.ALG_SET_KEY, b"Jefe") + algo.setsockopt(socket.SOL_ALG, socket.ALG_SET_KEY, key) op, _ = algo.accept() with op: - op.sendall(b"what do ya want for nothing?") + op.sendall(data) self.assertEqual(op.recv(512), expected) # Although it should work with 3.19 and newer the test blocks on diff -Nru python3.12-3.12.0~rc2/Lib/test/test_ssl.py python3.12-3.12.0/Lib/test/test_ssl.py --- python3.12-3.12.0~rc2/Lib/test/test_ssl.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_ssl.py 2023-10-02 11:48:14.000000000 +0000 @@ -2182,6 +2182,7 @@ self.assertIn(rc, (errno.EAGAIN, errno.EWOULDBLOCK)) @unittest.skipUnless(socket_helper.IPV6_ENABLED, 'Needs IPv6') + @support.requires_resource('walltime') def test_get_server_certificate_ipv6(self): with socket_helper.transient_internet('ipv6.google.com'): _test_get_server_certificate(self, 'ipv6.google.com', 443) @@ -2740,6 +2741,7 @@ class ThreadedTests(unittest.TestCase): + @support.requires_resource('walltime') def test_echo(self): """Basic test of an SSL client connecting to a server""" if support.verbose: diff -Nru python3.12-3.12.0~rc2/Lib/test/test_subprocess.py python3.12-3.12.0/Lib/test/test_subprocess.py --- python3.12-3.12.0~rc2/Lib/test/test_subprocess.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_subprocess.py 2023-10-02 11:48:14.000000000 +0000 @@ -269,6 +269,7 @@ self.assertIn('stdin', c.exception.args[0]) self.assertIn('input', c.exception.args[0]) + @support.requires_resource('walltime') def test_check_output_timeout(self): # check_output() function with timeout arg with self.assertRaises(subprocess.TimeoutExpired) as c: @@ -1643,6 +1644,7 @@ self.assertIn('stdin', c.exception.args[0]) self.assertIn('input', c.exception.args[0]) + @support.requires_resource('walltime') def test_check_output_timeout(self): with self.assertRaises(subprocess.TimeoutExpired) as c: cp = self.run_python(( diff -Nru python3.12-3.12.0~rc2/Lib/test/test_support.py python3.12-3.12.0/Lib/test/test_support.py --- python3.12-3.12.0~rc2/Lib/test/test_support.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_support.py 2023-10-02 11:48:14.000000000 +0000 @@ -688,6 +688,83 @@ else: self.assertTrue(support.has_strftime_extensions) + def test_get_recursion_depth(self): + # test support.get_recursion_depth() + code = textwrap.dedent(""" + from test import support + import sys + + def check(cond): + if not cond: + raise AssertionError("test failed") + + # depth 1 + check(support.get_recursion_depth() == 1) + + # depth 2 + def test_func(): + check(support.get_recursion_depth() == 2) + test_func() + + def test_recursive(depth, limit): + if depth >= limit: + # cannot call get_recursion_depth() at this depth, + # it can raise RecursionError + return + get_depth = support.get_recursion_depth() + print(f"test_recursive: {depth}/{limit}: " + f"get_recursion_depth() says {get_depth}") + check(get_depth == depth) + test_recursive(depth + 1, limit) + + # depth up to 25 + with support.infinite_recursion(max_depth=25): + limit = sys.getrecursionlimit() + print(f"test with sys.getrecursionlimit()={limit}") + test_recursive(2, limit) + + # depth up to 500 + with support.infinite_recursion(max_depth=500): + limit = sys.getrecursionlimit() + print(f"test with sys.getrecursionlimit()={limit}") + test_recursive(2, limit) + """) + script_helper.assert_python_ok("-c", code) + + def test_recursion(self): + # Test infinite_recursion() and get_recursion_available() functions. + def recursive_function(depth): + if depth: + recursive_function(depth - 1) + + for max_depth in (5, 25, 250): + with support.infinite_recursion(max_depth): + available = support.get_recursion_available() + + # Recursion up to 'available' additional frames should be OK. + recursive_function(available) + + # Recursion up to 'available+1' additional frames must raise + # RecursionError. Avoid self.assertRaises(RecursionError) which + # can consume more than 3 frames and so raises RecursionError. + try: + recursive_function(available + 1) + except RecursionError: + pass + else: + self.fail("RecursionError was not raised") + + # Test the bare minimumum: max_depth=3 + with support.infinite_recursion(3): + try: + recursive_function(3) + except RecursionError: + pass + else: + self.fail("RecursionError was not raised") + + #self.assertEqual(available, 2) + # XXX -follows a list of untested API # make_legacy_pyc # is_resource_enabled diff -Nru python3.12-3.12.0~rc2/Lib/test/test_symtable.py python3.12-3.12.0/Lib/test/test_symtable.py --- python3.12-3.12.0~rc2/Lib/test/test_symtable.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_symtable.py 2023-10-02 11:48:14.000000000 +0000 @@ -40,6 +40,15 @@ def namespace_test(): pass def namespace_test(): pass + +type Alias = int +type GenericAlias[T] = list[T] + +def generic_spam[T](a): + pass + +class GenericMine[T: int]: + pass """ @@ -59,6 +68,14 @@ internal = find_block(spam, "internal") other_internal = find_block(spam, "other_internal") foo = find_block(top, "foo") + Alias = find_block(top, "Alias") + GenericAlias = find_block(top, "GenericAlias") + GenericAlias_inner = find_block(GenericAlias, "GenericAlias") + generic_spam = find_block(top, "generic_spam") + generic_spam_inner = find_block(generic_spam, "generic_spam") + GenericMine = find_block(top, "GenericMine") + GenericMine_inner = find_block(GenericMine, "GenericMine") + T = find_block(GenericMine, "T") def test_type(self): self.assertEqual(self.top.get_type(), "module") @@ -66,6 +83,15 @@ self.assertEqual(self.a_method.get_type(), "function") self.assertEqual(self.spam.get_type(), "function") self.assertEqual(self.internal.get_type(), "function") + self.assertEqual(self.foo.get_type(), "function") + self.assertEqual(self.Alias.get_type(), "type alias") + self.assertEqual(self.GenericAlias.get_type(), "type parameter") + self.assertEqual(self.GenericAlias_inner.get_type(), "type alias") + self.assertEqual(self.generic_spam.get_type(), "type parameter") + self.assertEqual(self.generic_spam_inner.get_type(), "function") + self.assertEqual(self.GenericMine.get_type(), "type parameter") + self.assertEqual(self.GenericMine_inner.get_type(), "class") + self.assertEqual(self.T.get_type(), "TypeVar bound") def test_id(self): self.assertGreater(self.top.get_id(), 0) @@ -73,6 +99,11 @@ self.assertGreater(self.a_method.get_id(), 0) self.assertGreater(self.spam.get_id(), 0) self.assertGreater(self.internal.get_id(), 0) + self.assertGreater(self.foo.get_id(), 0) + self.assertGreater(self.Alias.get_id(), 0) + self.assertGreater(self.GenericAlias.get_id(), 0) + self.assertGreater(self.generic_spam.get_id(), 0) + self.assertGreater(self.GenericMine.get_id(), 0) def test_optimized(self): self.assertFalse(self.top.is_optimized()) diff -Nru python3.12-3.12.0~rc2/Lib/test/test_sys.py python3.12-3.12.0/Lib/test/test_sys.py --- python3.12-3.12.0~rc2/Lib/test/test_sys.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_sys.py 2023-10-02 11:48:14.000000000 +0000 @@ -269,20 +269,29 @@ finally: sys.setswitchinterval(orig) - def test_recursionlimit(self): + def test_getrecursionlimit(self): + limit = sys.getrecursionlimit() + self.assertIsInstance(limit, int) + self.assertGreater(limit, 1) + self.assertRaises(TypeError, sys.getrecursionlimit, 42) - oldlimit = sys.getrecursionlimit() - self.assertRaises(TypeError, sys.setrecursionlimit) - self.assertRaises(ValueError, sys.setrecursionlimit, -42) - sys.setrecursionlimit(10000) - self.assertEqual(sys.getrecursionlimit(), 10000) - sys.setrecursionlimit(oldlimit) + + def test_setrecursionlimit(self): + old_limit = sys.getrecursionlimit() + try: + sys.setrecursionlimit(10_005) + self.assertEqual(sys.getrecursionlimit(), 10_005) + + self.assertRaises(TypeError, sys.setrecursionlimit) + self.assertRaises(ValueError, sys.setrecursionlimit, -42) + finally: + sys.setrecursionlimit(old_limit) def test_recursionlimit_recovery(self): if hasattr(sys, 'gettrace') and sys.gettrace(): self.skipTest('fatal error if run with a trace function') - oldlimit = sys.getrecursionlimit() + old_limit = sys.getrecursionlimit() def f(): f() try: @@ -301,35 +310,31 @@ with self.assertRaises(RecursionError): f() finally: - sys.setrecursionlimit(oldlimit) + sys.setrecursionlimit(old_limit) @test.support.cpython_only - def test_setrecursionlimit_recursion_depth(self): + def test_setrecursionlimit_to_depth(self): # Issue #25274: Setting a low recursion limit must be blocked if the # current recursion depth is already higher than limit. - from _testinternalcapi import get_recursion_depth - - def set_recursion_limit_at_depth(depth, limit): - recursion_depth = get_recursion_depth() - if recursion_depth >= depth: - with self.assertRaises(RecursionError) as cm: - sys.setrecursionlimit(limit) - self.assertRegex(str(cm.exception), - "cannot set the recursion limit to [0-9]+ " - "at the recursion depth [0-9]+: " - "the limit is too low") - else: - set_recursion_limit_at_depth(depth, limit) - - oldlimit = sys.getrecursionlimit() + old_limit = sys.getrecursionlimit() try: - sys.setrecursionlimit(1000) - - for limit in (10, 25, 50, 75, 100, 150, 200): - set_recursion_limit_at_depth(limit, limit) + depth = support.get_recursion_depth() + with self.subTest(limit=sys.getrecursionlimit(), depth=depth): + # depth + 1 is OK + sys.setrecursionlimit(depth + 1) + + # reset the limit to be able to call self.assertRaises() + # context manager + sys.setrecursionlimit(old_limit) + with self.assertRaises(RecursionError) as cm: + sys.setrecursionlimit(depth) + self.assertRegex(str(cm.exception), + "cannot set the recursion limit to [0-9]+ " + "at the recursion depth [0-9]+: " + "the limit is too low") finally: - sys.setrecursionlimit(oldlimit) + sys.setrecursionlimit(old_limit) def test_getwindowsversion(self): # Raise SkipTest if sys doesn't have getwindowsversion attribute diff -Nru python3.12-3.12.0~rc2/Lib/test/test_sys_setprofile.py python3.12-3.12.0/Lib/test/test_sys_setprofile.py --- python3.12-3.12.0~rc2/Lib/test/test_sys_setprofile.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_sys_setprofile.py 2023-10-02 11:48:14.000000000 +0000 @@ -439,7 +439,6 @@ sys.setprofile(foo) self.assertEqual(sys.getprofile(), bar) - def test_same_object(self): def foo(*args): ... @@ -448,6 +447,18 @@ del foo sys.setprofile(sys.getprofile()) + def test_profile_after_trace_opcodes(self): + def f(): + ... + + sys._getframe().f_trace_opcodes = True + prev_trace = sys.gettrace() + sys.settrace(lambda *args: None) + f() + sys.settrace(prev_trace) + sys.setprofile(lambda *args: None) + f() + if __name__ == "__main__": unittest.main() diff -Nru python3.12-3.12.0~rc2/Lib/test/test_sys_settrace.py python3.12-3.12.0/Lib/test/test_sys_settrace.py --- python3.12-3.12.0~rc2/Lib/test/test_sys_settrace.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_sys_settrace.py 2023-10-02 11:48:14.000000000 +0000 @@ -8,6 +8,7 @@ from functools import wraps import asyncio from test.support import import_helper +import contextlib support.requires_working_socket(module=True) @@ -40,6 +41,20 @@ for x in iterable: yield x +def clean_asynciter(test): + @wraps(test) + async def wrapper(*args, **kwargs): + cleanups = [] + def wrapped_asynciter(iterable): + it = asynciter(iterable) + cleanups.append(it.aclose) + return it + try: + return await test(*args, **kwargs, asynciter=wrapped_asynciter) + finally: + while cleanups: + await cleanups.pop()() + return wrapper # A very basic example. If this fails, we're in deep trouble. def basic(): @@ -906,6 +921,35 @@ (6, 'line'), (6, 'return')]) + def test_finally_with_conditional(self): + + # See gh-105658 + condition = True + def func(): + try: + try: + raise Exception + finally: + if condition: + result = 1 + result = 2 + except: + result = 3 + return result + + self.run_and_compare(func, + [(0, 'call'), + (1, 'line'), + (2, 'line'), + (3, 'line'), + (3, 'exception'), + (5, 'line'), + (6, 'line'), + (8, 'line'), + (9, 'line'), + (10, 'line'), + (10, 'return')]) + def test_break_to_continue1(self): def func(): @@ -1631,7 +1675,6 @@ except Exception as ex: count = 0 tb = ex.__traceback__ - print(tb) while tb: if tb.tb_frame.f_code.co_name == "test_settrace_error": count += 1 @@ -1900,6 +1943,8 @@ class JumpTestCase(unittest.TestCase): + unbound_locals = r"assigning None to [0-9]+ unbound local" + def setUp(self): self.addCleanup(sys.settrace, sys.gettrace()) sys.settrace(None) @@ -1911,33 +1956,47 @@ "Received: " + repr(received)) def run_test(self, func, jumpFrom, jumpTo, expected, error=None, - event='line', decorated=False): - tracer = JumpTracer(func, jumpFrom, jumpTo, event, decorated) + event='line', decorated=False, warning=None): + wrapped = func + while hasattr(wrapped, '__wrapped__'): + wrapped = wrapped.__wrapped__ + + tracer = JumpTracer(wrapped, jumpFrom, jumpTo, event, decorated) sys.settrace(tracer.trace) output = [] - if error is None: + + with contextlib.ExitStack() as stack: + if error is not None: + stack.enter_context(self.assertRaisesRegex(*error)) + if warning is not None: + stack.enter_context(self.assertWarnsRegex(*warning)) func(output) - else: - with self.assertRaisesRegex(*error): - func(output) + sys.settrace(None) self.compare_jump_output(expected, output) def run_async_test(self, func, jumpFrom, jumpTo, expected, error=None, - event='line', decorated=False): - tracer = JumpTracer(func, jumpFrom, jumpTo, event, decorated) + event='line', decorated=False, warning=None): + wrapped = func + while hasattr(wrapped, '__wrapped__'): + wrapped = wrapped.__wrapped__ + + tracer = JumpTracer(wrapped, jumpFrom, jumpTo, event, decorated) sys.settrace(tracer.trace) output = [] - if error is None: + + with contextlib.ExitStack() as stack: + if error is not None: + stack.enter_context(self.assertRaisesRegex(*error)) + if warning is not None: + stack.enter_context(self.assertWarnsRegex(*warning)) asyncio.run(func(output)) - else: - with self.assertRaisesRegex(*error): - asyncio.run(func(output)) + sys.settrace(None) asyncio.set_event_loop_policy(None) self.compare_jump_output(expected, output) - def jump_test(jumpFrom, jumpTo, expected, error=None, event='line'): + def jump_test(jumpFrom, jumpTo, expected, error=None, event='line', warning=None): """Decorator that creates a test that makes a jump from one place to another in the following code. """ @@ -1945,11 +2004,11 @@ @wraps(func) def test(self): self.run_test(func, jumpFrom, jumpTo, expected, - error=error, event=event, decorated=True) + error=error, event=event, decorated=True, warning=warning) return test return decorator - def async_jump_test(jumpFrom, jumpTo, expected, error=None, event='line'): + def async_jump_test(jumpFrom, jumpTo, expected, error=None, event='line', warning=None): """Decorator that creates a test that makes a jump from one place to another in the following asynchronous code. """ @@ -1957,7 +2016,7 @@ @wraps(func) def test(self): self.run_async_test(func, jumpFrom, jumpTo, expected, - error=error, event=event, decorated=True) + error=error, event=event, decorated=True, warning=warning) return test return decorator @@ -1974,7 +2033,7 @@ output.append(1) output.append(2) - @jump_test(3, 5, [2, 5]) + @jump_test(3, 5, [2, 5], warning=(RuntimeWarning, unbound_locals)) def test_jump_out_of_block_forwards(output): for i in 1, 2: output.append(2) @@ -1993,7 +2052,8 @@ output.append(7) @async_jump_test(4, 5, [3, 5]) - async def test_jump_out_of_async_for_block_forwards(output): + @clean_asynciter + async def test_jump_out_of_async_for_block_forwards(output, asynciter): for i in [1]: async for i in asynciter([1, 2]): output.append(3) @@ -2001,7 +2061,8 @@ output.append(5) @async_jump_test(5, 2, [2, 4, 2, 4, 5, 6]) - async def test_jump_out_of_async_for_block_backwards(output): + @clean_asynciter + async def test_jump_out_of_async_for_block_backwards(output, asynciter): for i in [1]: output.append(2) async for i in asynciter([1]): @@ -2060,7 +2121,7 @@ output.append(11) output.append(12) - @jump_test(5, 11, [2, 4], (ValueError, 'exception')) + @jump_test(5, 11, [2, 4], (ValueError, 'comes after the current code block')) def test_no_jump_over_return_try_finally_in_finally_block(output): try: output.append(2) @@ -2188,7 +2249,7 @@ output.append(6) output.append(7) - @jump_test(6, 1, [1, 5, 1, 5]) + @jump_test(6, 1, [1, 5, 1, 5], warning=(RuntimeWarning, unbound_locals)) def test_jump_over_try_except(output): output.append(1) try: @@ -2284,7 +2345,7 @@ output.append(11) output.append(12) - @jump_test(3, 5, [1, 2, 5]) + @jump_test(3, 5, [1, 2, 5], warning=(RuntimeWarning, unbound_locals)) def test_jump_out_of_with_assignment(output): output.append(1) with tracecontext(output, 2) \ @@ -2292,7 +2353,7 @@ output.append(4) output.append(5) - @async_jump_test(3, 5, [1, 2, 5]) + @async_jump_test(3, 5, [1, 2, 5], warning=(RuntimeWarning, unbound_locals)) async def test_jump_out_of_async_with_assignment(output): output.append(1) async with asynctracecontext(output, 2) \ @@ -2328,7 +2389,7 @@ break output.append(13) - @jump_test(1, 7, [7, 8]) + @jump_test(1, 7, [7, 8], warning=(RuntimeWarning, unbound_locals)) def test_jump_over_for_block_before_else(output): output.append(1) if not output: # always false @@ -2339,7 +2400,7 @@ output.append(7) output.append(8) - @async_jump_test(1, 7, [7, 8]) + @async_jump_test(1, 7, [7, 8], warning=(RuntimeWarning, unbound_locals)) async def test_jump_over_async_for_block_before_else(output): output.append(1) if not output: # always false @@ -2414,6 +2475,7 @@ output.append(2) output.append(3) + @async_jump_test(3, 2, [2, 2], (ValueError, "can't jump into the body of a for loop")) async def test_no_jump_backwards_into_async_for_block(output): async for i in asynciter([1, 2]): @@ -2479,7 +2541,7 @@ output.append(6) # 'except' with a variable creates an implicit finally block - @jump_test(5, 7, [4, 7, 8]) + @jump_test(5, 7, [4, 7, 8], warning=(RuntimeWarning, unbound_locals)) def test_jump_between_except_blocks_2(output): try: 1/0 @@ -2642,7 +2704,7 @@ output.append(x) # line 1007 return""" % ('\n' * 1000,), d) f = d['f'] - self.run_test(f, 2, 1007, [0]) + self.run_test(f, 2, 1007, [0], warning=(RuntimeWarning, self.unbound_locals)) def test_jump_to_firstlineno(self): # This tests that PDB can jump back to the first line in a @@ -2692,7 +2754,7 @@ next(gen()) output.append(5) - @jump_test(2, 3, [1, 3]) + @jump_test(2, 3, [1, 3], warning=(RuntimeWarning, unbound_locals)) def test_jump_forward_over_listcomp(output): output.append(1) x = [i for i in range(10)] @@ -2700,13 +2762,13 @@ # checking for segfaults. # See https://github.com/python/cpython/issues/92311 - @jump_test(3, 1, []) + @jump_test(3, 1, [], warning=(RuntimeWarning, unbound_locals)) def test_jump_backward_over_listcomp(output): a = 1 x = [i for i in range(10)] c = 3 - @jump_test(8, 2, [2, 7, 2]) + @jump_test(8, 2, [2, 7, 2], warning=(RuntimeWarning, unbound_locals)) def test_jump_backward_over_listcomp_v2(output): flag = False output.append(2) @@ -2717,19 +2779,19 @@ output.append(7) output.append(8) - @async_jump_test(2, 3, [1, 3]) + @async_jump_test(2, 3, [1, 3], warning=(RuntimeWarning, unbound_locals)) async def test_jump_forward_over_async_listcomp(output): output.append(1) x = [i async for i in asynciter(range(10))] output.append(3) - @async_jump_test(3, 1, []) + @async_jump_test(3, 1, [], warning=(RuntimeWarning, unbound_locals)) async def test_jump_backward_over_async_listcomp(output): a = 1 x = [i async for i in asynciter(range(10))] c = 3 - @async_jump_test(8, 2, [2, 7, 2]) + @async_jump_test(8, 2, [2, 7, 2], warning=(RuntimeWarning, unbound_locals)) async def test_jump_backward_over_async_listcomp_v2(output): flag = False output.append(2) @@ -2798,13 +2860,13 @@ ) output.append(15) - @jump_test(2, 3, [1, 3]) + @jump_test(2, 3, [1, 3], warning=(RuntimeWarning, unbound_locals)) def test_jump_extended_args_unpack_ex_simple(output): output.append(1) _, *_, _ = output.append(2) or "Spam" output.append(3) - @jump_test(3, 4, [1, 4, 4, 5]) + @jump_test(3, 4, [1, 4, 4, 5], warning=(RuntimeWarning, unbound_locals)) def test_jump_extended_args_unpack_ex_tricky(output): output.append(1) ( @@ -2826,9 +2888,9 @@ namespace = {} exec("\n".join(source), namespace) f = namespace["f"] - self.run_test(f, 2, 100_000, [1, 100_000]) + self.run_test(f, 2, 100_000, [1, 100_000], warning=(RuntimeWarning, self.unbound_locals)) - @jump_test(2, 3, [1, 3]) + @jump_test(2, 3, [1, 3], warning=(RuntimeWarning, unbound_locals)) def test_jump_or_pop(output): output.append(1) _ = output.append(2) and "Spam" diff -Nru python3.12-3.12.0~rc2/Lib/test/test_tempfile.py python3.12-3.12.0/Lib/test/test_tempfile.py --- python3.12-3.12.0~rc2/Lib/test/test_tempfile.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_tempfile.py 2023-10-02 11:48:14.000000000 +0000 @@ -1834,9 +1834,25 @@ d.cleanup() self.assertFalse(os.path.exists(d.name)) - @unittest.skipUnless(hasattr(os, 'chflags'), 'requires os.lchflags') + @unittest.skipUnless(hasattr(os, 'chflags'), 'requires os.chflags') def test_flags(self): flags = stat.UF_IMMUTABLE | stat.UF_NOUNLINK + + # skip the test if these flags are not supported (ex: FreeBSD 13) + filename = os_helper.TESTFN + try: + open(filename, "w").close() + try: + os.chflags(filename, flags) + except OSError as exc: + # "OSError: [Errno 45] Operation not supported" + self.skipTest(f"chflags() doesn't support " + f"UF_IMMUTABLE|UF_NOUNLINK: {exc}") + else: + os.chflags(filename, 0) + finally: + os_helper.unlink(filename) + d = self.do_create(recurse=3, dirs=2, files=2) with d: # Change files and directories flags recursively. diff -Nru python3.12-3.12.0~rc2/Lib/test/test_timeout.py python3.12-3.12.0/Lib/test/test_timeout.py --- python3.12-3.12.0~rc2/Lib/test/test_timeout.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_timeout.py 2023-10-02 11:48:14.000000000 +0000 @@ -148,13 +148,12 @@ def tearDown(self): self.sock.close() - @unittest.skipIf(True, 'need to replace these hosts; see bpo-35518') def testConnectTimeout(self): # Testing connect timeout is tricky: we need to have IP connectivity # to a host that silently drops our packets. We can't simulate this # from Python because it's a function of the underlying TCP/IP stack. - # So, the following Snakebite host has been defined: - blackhole = resolve_address('blackhole.snakebite.net', 56666) + # So, the following port on the pythontest.net host has been defined: + blackhole = resolve_address('pythontest.net', 56666) # Blackhole has been configured to silently drop any incoming packets. # No RSTs (for TCP) or ICMP UNREACH (for UDP/ICMP) will be sent back @@ -166,7 +165,7 @@ # to firewalling or general network configuration. In order to improve # our confidence in testing the blackhole, a corresponding 'whitehole' # has also been set up using one port higher: - whitehole = resolve_address('whitehole.snakebite.net', 56667) + whitehole = resolve_address('pythontest.net', 56667) # This address has been configured to immediately drop any incoming # packets as well, but it does it respectfully with regards to the @@ -180,20 +179,15 @@ # timeframe). # For the records, the whitehole/blackhole configuration has been set - # up using the 'pf' firewall (available on BSDs), using the following: + # up using the 'iptables' firewall, using the following rules: # - # ext_if="bge0" - # - # blackhole_ip="35.8.247.6" - # whitehole_ip="35.8.247.6" - # blackhole_port="56666" - # whitehole_port="56667" - # - # block return in log quick on $ext_if proto { tcp udp } \ - # from any to $whitehole_ip port $whitehole_port - # block drop in log quick on $ext_if proto { tcp udp } \ - # from any to $blackhole_ip port $blackhole_port + # -A INPUT -p tcp --destination-port 56666 -j DROP + # -A INPUT -p udp --destination-port 56666 -j DROP + # -A INPUT -p tcp --destination-port 56667 -j REJECT + # -A INPUT -p udp --destination-port 56667 -j REJECT # + # See https://github.com/python/psf-salt/blob/main/pillar/base/firewall/snakebite.sls + # for the current configuration. skip = True sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) diff -Nru python3.12-3.12.0~rc2/Lib/test/test_tomllib/test_misc.py python3.12-3.12.0/Lib/test/test_tomllib/test_misc.py --- python3.12-3.12.0~rc2/Lib/test/test_tomllib/test_misc.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_tomllib/test_misc.py 2023-10-02 11:48:14.000000000 +0000 @@ -9,6 +9,7 @@ import sys import tempfile import unittest +from test import support from . import tomllib @@ -92,13 +93,23 @@ self.assertEqual(obj_copy, expected_obj) def test_inline_array_recursion_limit(self): - # 465 with default recursion limit - nest_count = int(sys.getrecursionlimit() * 0.465) - recursive_array_toml = "arr = " + nest_count * "[" + nest_count * "]" - tomllib.loads(recursive_array_toml) + with support.infinite_recursion(max_depth=100): + available = support.get_recursion_available() + nest_count = (available // 2) - 2 + # Add details if the test fails + with self.subTest(limit=sys.getrecursionlimit(), + available=available, + nest_count=nest_count): + recursive_array_toml = "arr = " + nest_count * "[" + nest_count * "]" + tomllib.loads(recursive_array_toml) def test_inline_table_recursion_limit(self): - # 310 with default recursion limit - nest_count = int(sys.getrecursionlimit() * 0.31) - recursive_table_toml = nest_count * "key = {" + nest_count * "}" - tomllib.loads(recursive_table_toml) + with support.infinite_recursion(max_depth=100): + available = support.get_recursion_available() + nest_count = (available // 3) - 1 + # Add details if the test fails + with self.subTest(limit=sys.getrecursionlimit(), + available=available, + nest_count=nest_count): + recursive_table_toml = nest_count * "key = {" + nest_count * "}" + tomllib.loads(recursive_table_toml) diff -Nru python3.12-3.12.0~rc2/Lib/test/test_traceback.py python3.12-3.12.0/Lib/test/test_traceback.py --- python3.12-3.12.0~rc2/Lib/test/test_traceback.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_traceback.py 2023-10-02 11:48:14.000000000 +0000 @@ -596,6 +596,24 @@ result_lines = self.get_exception(f_with_binary_operator) self.assertEqual(result_lines, expected_error.splitlines()) + def test_caret_for_binary_operators_with_spaces_and_parenthesis(self): + def f_with_binary_operator(): + a = 1 + b = "" + return ( a ) + b + + lineno_f = f_with_binary_operator.__code__.co_firstlineno + expected_error = ( + 'Traceback (most recent call last):\n' + f' File "{__file__}", line {self.callable_line}, in get_exception\n' + ' callable()\n' + f' File "{__file__}", line {lineno_f+3}, in f_with_binary_operator\n' + ' return ( a ) + b\n' + ' ~~~~~~~~~~^~~\n' + ) + result_lines = self.get_exception(f_with_binary_operator) + self.assertEqual(result_lines, expected_error.splitlines()) + def test_caret_for_subscript(self): def f_with_subscript(): some_dict = {'x': {'y': None}} @@ -630,6 +648,24 @@ result_lines = self.get_exception(f_with_subscript) self.assertEqual(result_lines, expected_error.splitlines()) + def test_caret_for_subscript_with_spaces_and_parenthesis(self): + def f_with_binary_operator(): + a = [] + b = c = 1 + return b [ a ] + c + + lineno_f = f_with_binary_operator.__code__.co_firstlineno + expected_error = ( + 'Traceback (most recent call last):\n' + f' File "{__file__}", line {self.callable_line}, in get_exception\n' + ' callable()\n' + f' File "{__file__}", line {lineno_f+3}, in f_with_binary_operator\n' + ' return b [ a ] + c\n' + ' ~~~~~~^^^^^^^^^\n' + ) + result_lines = self.get_exception(f_with_binary_operator) + self.assertEqual(result_lines, expected_error.splitlines()) + def test_traceback_specialization_with_syntax_error(self): bytecode = compile("1 / 0 / 1 / 2\n", TESTFN, "exec") diff -Nru python3.12-3.12.0~rc2/Lib/test/test_trace.py python3.12-3.12.0/Lib/test/test_trace.py --- python3.12-3.12.0~rc2/Lib/test/test_trace.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_trace.py 2023-10-02 11:48:14.000000000 +0000 @@ -360,9 +360,14 @@ rmtree(TESTFN) unlink(TESTFN) - def _coverage(self, tracer, - cmd='import test.support, test.test_pprint;' - 'test.support.run_unittest(test.test_pprint.QueryTestCase)'): + DEFAULT_SCRIPT = '''if True: + import unittest + from test.test_pprint import QueryTestCase + loader = unittest.TestLoader() + tests = loader.loadTestsFromTestCase(QueryTestCase) + tests(unittest.TestResult()) + ''' + def _coverage(self, tracer, cmd=DEFAULT_SCRIPT): tracer.run(cmd) r = tracer.results() r.write_results(show_missing=True, summary=True, coverdir=TESTFN) diff -Nru python3.12-3.12.0~rc2/Lib/test/test_type_cache.py python3.12-3.12.0/Lib/test/test_type_cache.py --- python3.12-3.12.0~rc2/Lib/test/test_type_cache.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_type_cache.py 2023-10-02 11:48:14.000000000 +0000 @@ -58,4 +58,4 @@ if __name__ == "__main__": - support.run_unittest(TypeCacheTests) + unittest.main() diff -Nru python3.12-3.12.0~rc2/Lib/test/test_type_params.py python3.12-3.12.0/Lib/test/test_type_params.py --- python3.12-3.12.0~rc2/Lib/test/test_type_params.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_type_params.py 2023-10-02 11:48:14.000000000 +0000 @@ -412,6 +412,99 @@ func, = T.__bound__ self.assertEqual(func(), 1) + def test_gen_exp_in_nested_class(self): + code = """ + from test.test_type_params import make_base + + class C[T]: + T = "class" + class Inner(make_base(T for _ in (1,)), make_base(T)): + pass + """ + C = run_code(code)["C"] + T, = C.__type_params__ + base1, base2 = C.Inner.__bases__ + self.assertEqual(list(base1.__arg__), [T]) + self.assertEqual(base2.__arg__, "class") + + def test_gen_exp_in_nested_generic_class(self): + code = """ + from test.test_type_params import make_base + + class C[T]: + T = "class" + class Inner[U](make_base(T for _ in (1,)), make_base(T)): + pass + """ + with self.assertRaisesRegex(SyntaxError, + "Cannot use comprehension in annotation scope within class scope"): + run_code(code) + + def test_listcomp_in_nested_class(self): + code = """ + from test.test_type_params import make_base + + class C[T]: + T = "class" + class Inner(make_base([T for _ in (1,)]), make_base(T)): + pass + """ + C = run_code(code)["C"] + T, = C.__type_params__ + base1, base2 = C.Inner.__bases__ + self.assertEqual(base1.__arg__, [T]) + self.assertEqual(base2.__arg__, "class") + + def test_listcomp_in_nested_generic_class(self): + code = """ + from test.test_type_params import make_base + + class C[T]: + T = "class" + class Inner[U](make_base([T for _ in (1,)]), make_base(T)): + pass + """ + with self.assertRaisesRegex(SyntaxError, + "Cannot use comprehension in annotation scope within class scope"): + run_code(code) + + def test_gen_exp_in_generic_method(self): + code = """ + class C[T]: + T = "class" + def meth[U](x: (T for _ in (1,)), y: T): + pass + """ + with self.assertRaisesRegex(SyntaxError, + "Cannot use comprehension in annotation scope within class scope"): + run_code(code) + + def test_nested_scope_in_generic_alias(self): + code = """ + class C[T]: + T = "class" + {} + """ + error_cases = [ + "type Alias1[T] = lambda: T", + "type Alias2 = lambda: T", + "type Alias3[T] = (T for _ in (1,))", + "type Alias4 = (T for _ in (1,))", + "type Alias5[T] = [T for _ in (1,)]", + "type Alias6 = [T for _ in (1,)]", + ] + for case in error_cases: + with self.subTest(case=case): + with self.assertRaisesRegex(SyntaxError, + r"Cannot use [a-z]+ in annotation scope within class scope"): + run_code(code.format(case)) + + +def make_base(arg): + class Base: + __arg__ = arg + return Base + def global_generic_func[T](): pass @@ -601,6 +694,19 @@ cls = ns["outer"]() self.assertEqual(cls.Alias.__value__, "class") + def test_nested_free(self): + ns = run_code(""" + def f(): + T = str + class C: + T = int + class D[U](T): + x = T + return C + """) + C = ns["f"]() + self.assertIn(int, C.D.__bases__) + self.assertIs(C.D.x, str) class TypeParamsManglingTest(unittest.TestCase): def test_mangling(self): @@ -956,3 +1062,43 @@ for case in cases: with self.subTest(case=case): weakref.ref(case) + + +class TypeParamsRuntimeTest(unittest.TestCase): + def test_name_error(self): + # gh-109118: This crashed the interpreter due to a refcounting bug + code = """ + class name_2[name_5]: + class name_4[name_5](name_0): + pass + """ + with self.assertRaises(NameError): + run_code(code) + + # Crashed with a slightly different stack trace + code = """ + class name_2[name_5]: + class name_4[name_5: name_5](name_0): + pass + """ + with self.assertRaises(NameError): + run_code(code) + + def test_broken_class_namespace(self): + code = """ + class WeirdMapping(dict): + def __missing__(self, key): + if key == "T": + raise RuntimeError + raise KeyError(key) + + class Meta(type): + def __prepare__(name, bases): + return WeirdMapping() + + class MyClass[V](metaclass=Meta): + class Inner[U](T): + pass + """ + with self.assertRaises(RuntimeError): + run_code(code) diff -Nru python3.12-3.12.0~rc2/Lib/test/test_unparse.py python3.12-3.12.0/Lib/test/test_unparse.py --- python3.12-3.12.0~rc2/Lib/test/test_unparse.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_unparse.py 2023-10-02 11:48:14.000000000 +0000 @@ -635,6 +635,20 @@ self.check_src_roundtrip("[a, b] = [c, d] = [e, f] = g") self.check_src_roundtrip("a, b = [c, d] = e, f = g") + def test_multiquote_joined_string(self): + self.check_ast_roundtrip("f\"'''{1}\\\"\\\"\\\"\" ") + self.check_ast_roundtrip("""f"'''{1}""\\"" """) + self.check_ast_roundtrip("""f'""\"{1}''' """) + self.check_ast_roundtrip("""f'""\"{1}""\\"' """) + + self.check_ast_roundtrip("""f"'''{"\\n"}""\\"" """) + self.check_ast_roundtrip("""f'""\"{"\\n"}''' """) + self.check_ast_roundtrip("""f'""\"{"\\n"}""\\"' """) + + self.check_ast_roundtrip("""f'''""\"''\\'{"\\n"}''' """) + self.check_ast_roundtrip("""f'''""\"''\\'{"\\n\\"'"}''' """) + self.check_ast_roundtrip("""f'''""\"''\\'{""\"\\n\\"'''""\" '''\\n'''}''' """) + class ManualASTCreationTestCase(unittest.TestCase): """Test that AST nodes created without a type_params field unparse correctly.""" diff -Nru python3.12-3.12.0~rc2/Lib/test/test_urllib2net.py python3.12-3.12.0/Lib/test/test_urllib2net.py --- python3.12-3.12.0~rc2/Lib/test/test_urllib2net.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_urllib2net.py 2023-10-02 11:48:14.000000000 +0000 @@ -133,6 +133,7 @@ # XXX The rest of these tests aren't very good -- they don't check much. # They do sometimes catch some major disasters, though. + @support.requires_resource('walltime') def test_ftp(self): # Testing the same URL twice exercises the caching in CacheFTPHandler urls = [ @@ -196,6 +197,7 @@ self.assertEqual(res.geturl(), "http://www.pythontest.net/index.html#frag") + @support.requires_resource('walltime') def test_redirect_url_withfrag(self): redirect_url_with_frag = "http://www.pythontest.net/redir/with_frag/" with socket_helper.transient_internet(redirect_url_with_frag): @@ -334,6 +336,7 @@ FTP_HOST = 'ftp://www.pythontest.net/' + @support.requires_resource('walltime') def test_ftp_basic(self): self.assertIsNone(socket.getdefaulttimeout()) with socket_helper.transient_internet(self.FTP_HOST, timeout=None): @@ -352,6 +355,7 @@ socket.setdefaulttimeout(None) self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 60) + @support.requires_resource('walltime') def test_ftp_no_timeout(self): self.assertIsNone(socket.getdefaulttimeout()) with socket_helper.transient_internet(self.FTP_HOST): @@ -363,6 +367,7 @@ socket.setdefaulttimeout(None) self.assertIsNone(u.fp.fp.raw._sock.gettimeout()) + @support.requires_resource('walltime') def test_ftp_timeout(self): with socket_helper.transient_internet(self.FTP_HOST): u = _urlopen_with_retry(self.FTP_HOST, timeout=60) diff -Nru python3.12-3.12.0~rc2/Lib/test/test_urllibnet.py python3.12-3.12.0/Lib/test/test_urllibnet.py --- python3.12-3.12.0~rc2/Lib/test/test_urllibnet.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_urllibnet.py 2023-10-02 11:48:14.000000000 +0000 @@ -109,6 +109,7 @@ open_url.close() self.assertEqual(code, 404) + @support.requires_resource('walltime') def test_bad_address(self): # Make sure proper exception is raised when connecting to a bogus # address. @@ -191,6 +192,7 @@ logo = "http://www.pythontest.net/" + @support.requires_resource('walltime') def test_data_header(self): with self.urlretrieve(self.logo) as (file_location, fileheaders): datevalue = fileheaders.get('Date') diff -Nru python3.12-3.12.0~rc2/Lib/test/test_xmlrpc.py python3.12-3.12.0/Lib/test/test_xmlrpc.py --- python3.12-3.12.0~rc2/Lib/test/test_xmlrpc.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/test/test_xmlrpc.py 2023-10-02 11:48:14.000000000 +0000 @@ -1031,38 +1031,47 @@ self.assertEqual(p.add(6,8), 6+8) self.assertRaises(xmlrpclib.Fault, p.pow, 6, 8) + @support.requires_resource('walltime') def test_path3(self): p = xmlrpclib.ServerProxy(URL+"/is/broken") self.assertRaises(xmlrpclib.Fault, p.add, 6, 8) + @support.requires_resource('walltime') def test_invalid_path(self): p = xmlrpclib.ServerProxy(URL+"/invalid") self.assertRaises(xmlrpclib.Fault, p.add, 6, 8) + @support.requires_resource('walltime') def test_path_query_fragment(self): p = xmlrpclib.ServerProxy(URL+"/foo?k=v#frag") self.assertEqual(p.test(), "/foo?k=v#frag") + @support.requires_resource('walltime') def test_path_fragment(self): p = xmlrpclib.ServerProxy(URL+"/foo#frag") self.assertEqual(p.test(), "/foo#frag") + @support.requires_resource('walltime') def test_path_query(self): p = xmlrpclib.ServerProxy(URL+"/foo?k=v") self.assertEqual(p.test(), "/foo?k=v") + @support.requires_resource('walltime') def test_empty_path(self): p = xmlrpclib.ServerProxy(URL) self.assertEqual(p.test(), "/RPC2") + @support.requires_resource('walltime') def test_root_path(self): p = xmlrpclib.ServerProxy(URL + "/") self.assertEqual(p.test(), "/") + @support.requires_resource('walltime') def test_empty_path_query(self): p = xmlrpclib.ServerProxy(URL + "?k=v") self.assertEqual(p.test(), "?k=v") + @support.requires_resource('walltime') def test_empty_path_fragment(self): p = xmlrpclib.ServerProxy(URL + "#frag") self.assertEqual(p.test(), "#frag") diff -Nru python3.12-3.12.0~rc2/Lib/traceback.py python3.12-3.12.0/Lib/traceback.py --- python3.12-3.12.0~rc2/Lib/traceback.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Lib/traceback.py 2023-10-02 11:48:14.000000000 +0000 @@ -608,11 +608,21 @@ and not operator_str[operator_offset + 1].isspace() ): right_anchor += 1 + + while left_anchor < len(segment) and ((ch := segment[left_anchor]).isspace() or ch in ")#"): + left_anchor += 1 + right_anchor += 1 return _Anchors(normalize(left_anchor), normalize(right_anchor)) case ast.Subscript(): - subscript_start = normalize(expr.value.end_col_offset) - subscript_end = normalize(expr.slice.end_col_offset + 1) - return _Anchors(subscript_start, subscript_end) + left_anchor = normalize(expr.value.end_col_offset) + right_anchor = normalize(expr.slice.end_col_offset + 1) + while left_anchor < len(segment) and ((ch := segment[left_anchor]).isspace() or ch != "["): + left_anchor += 1 + while right_anchor < len(segment) and ((ch := segment[right_anchor]).isspace() or ch != "]"): + right_anchor += 1 + if right_anchor < len(segment): + right_anchor += 1 + return _Anchors(left_anchor, right_anchor) return None diff -Nru python3.12-3.12.0~rc2/Mac/BuildScript/build-installer.py python3.12-3.12.0/Mac/BuildScript/build-installer.py --- python3.12-3.12.0~rc2/Mac/BuildScript/build-installer.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Mac/BuildScript/build-installer.py 2023-10-02 11:48:14.000000000 +0000 @@ -246,9 +246,9 @@ result.extend([ dict( - name="OpenSSL 3.0.10", - url="https://www.openssl.org/source/openssl-3.0.10.tar.gz", - checksum='1761d4f5b13a1028b9b6f3d4b8e17feb0cedc9370f6afe61d7193d2cdce83323', + name="OpenSSL 3.0.11", + url="https://www.openssl.org/source/openssl-3.0.11.tar.gz", + checksum='b3425d3bb4a2218d0697eb41f7fc0cdede016ed19ca49d168b78e8d947887f55', buildrecipe=build_universal_openssl, configure=None, install=None, diff -Nru python3.12-3.12.0~rc2/Makefile.pre.in python3.12-3.12.0/Makefile.pre.in --- python3.12-3.12.0~rc2/Makefile.pre.in 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Makefile.pre.in 2023-10-02 11:48:14.000000000 +0000 @@ -487,6 +487,7 @@ Objects/weakrefobject.o \ @PERF_TRAMPOLINE_OBJ@ +DEEPFREEZE_C = Python/deepfreeze/deepfreeze.c DEEPFREEZE_OBJS = Python/deepfreeze/deepfreeze.o ########################################################################## @@ -774,7 +775,6 @@ .PHONY: clinic clinic: check-clean-src $(srcdir)/Modules/_blake2/blake2s_impl.c $(PYTHON_FOR_REGEN) $(srcdir)/Tools/clinic/clinic.py --make --srcdir $(srcdir) - $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_global_objects.py # Build the interpreter $(BUILDPYTHON): Programs/python.o $(LINK_PYTHON_DEPS) @@ -1245,12 +1245,12 @@ # Deepfreeze targets .PHONY: regen-deepfreeze -regen-deepfreeze: $(DEEPFREEZE_OBJS) +regen-deepfreeze: $(DEEPFREEZE_C) DEEPFREEZE_DEPS=$(srcdir)/Tools/build/deepfreeze.py $(FREEZE_MODULE_DEPS) $(FROZEN_FILES_OUT) # BEGIN: deepfreeze modules -Python/deepfreeze/deepfreeze.c: $(DEEPFREEZE_DEPS) +$(DEEPFREEZE_C): $(DEEPFREEZE_DEPS) $(PYTHON_FOR_FREEZE) $(srcdir)/Tools/build/deepfreeze.py \ Python/frozen_modules/importlib._bootstrap.h:importlib._bootstrap \ Python/frozen_modules/importlib._bootstrap_external.h:importlib._bootstrap_external \ @@ -1277,8 +1277,6 @@ Python/frozen_modules/frozen_only.h:frozen_only \ -o Python/deepfreeze/deepfreeze.c # END: deepfreeze modules - @echo "Note: Deepfreeze may have added some global objects," - @echo " so run 'make regen-global-objects' if necessary." # We keep this renamed target around for folks with muscle memory. .PHONY: regen-importlib @@ -1287,11 +1285,12 @@ ############################################################################ # Global objects +# Dependencies which can add and/or remove _Py_ID() identifiers: +# - deepfreeze.c +# - "make clinic" .PHONY: regen-global-objects -regen-global-objects: $(srcdir)/Tools/build/generate_global_objects.py +regen-global-objects: $(srcdir)/Tools/build/generate_global_objects.py $(DEEPFREEZE_C) clinic $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_global_objects.py - @echo "Note: Global objects can be added or removed by other tools (e.g. deepfreeze), " - @echo " so be sure to re-run regen-global-objects after those tools." ############################################################################ # ABI @@ -1313,9 +1312,10 @@ ############################################################################ # Regenerate all generated files +# "clinic" is regenerated implicitly via "regen-global-objects". .PHONY: regen-all regen-all: regen-cases regen-opcode regen-opcode-targets regen-typeslots \ - regen-token regen-ast regen-keyword regen-sre regen-frozen clinic \ + regen-token regen-ast regen-keyword regen-sre regen-frozen \ regen-pegen-metaparser regen-pegen regen-test-frozenmain \ regen-test-levenshtein regen-global-objects @echo @@ -2586,6 +2586,7 @@ autoconf: (cd $(srcdir); autoreconf -ivf -Werror) +# See https://github.com/tiran/cpython_autoconf container .PHONY: regen-configure regen-configure: @if command -v podman >/dev/null; then RUNTIME="podman"; else RUNTIME="docker"; fi; \ diff -Nru python3.12-3.12.0~rc2/Misc/ACKS python3.12-3.12.0/Misc/ACKS --- python3.12-3.12.0~rc2/Misc/ACKS 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Misc/ACKS 2023-10-02 11:48:14.000000000 +0000 @@ -502,6 +502,7 @@ Phil Elson David Ely Victor van den Elzen +Vlad Emelianov Jeff Epler Tom Epperly Gökcen Eraslan @@ -1267,7 +1268,7 @@ Matti Mäki Jörg MĂ¼ller Kaushik N -Dong-hee Na +Donghee Na Dale Nagata John Nagle Takahiro Nakayama @@ -1329,6 +1330,7 @@ Ken Jin Ooi Piet van Oostrum Tomas Oppelstrup +Itamar Oren Jason Orendorff Yan "yyyyyyyan" Orestes Bastien Orivel @@ -1339,7 +1341,6 @@ TomĂ¡Å¡ Orsava Oleg Oshmyan Denis Osipov -Itamar Ostricher Denis S. Otkidach Peter Otten Michael Otteneder @@ -1865,6 +1866,7 @@ Brent Tubbs Anthony Tuininga Erno Tukia +Adam Turner David Turner Stephen Turner Itamar Turner-Trauring @@ -2072,7 +2074,5 @@ Gennadiy Zlobin Doug Zongker Peter Ă…strand -Vlad Emelianov -Andrey Doroschenko (Entries should be added in rough alphabetical order by last names) diff -Nru python3.12-3.12.0~rc2/Misc/NEWS python3.12-3.12.0/Misc/NEWS --- python3.12-3.12.0~rc2/Misc/NEWS 2023-09-05 22:12:01.000000000 +0000 +++ python3.12-3.12.0/Misc/NEWS 2023-10-02 12:03:24.000000000 +0000 @@ -2,6 +2,206 @@ Python News +++++++++++ +What's New in Python 3.12.0 final? +================================== + +*Release date: 2023-10-02* + +Core and Builtins +----------------- + +- gh-issue-109823: Fix bug where compiler does not adjust labels when + removing an empty basic block which is a jump target. + +- gh-issue-109719: Fix missing jump target labels when compiler reorders + cold/warm blocks. + +- gh-issue-109627: Fix bug where the compiler does not assign a new jump + target label to a duplicated small exit block. + +Library +------- + +- gh-issue-110045: Update the :mod:`symtable` module to support the new + scopes introduced by :pep:`695`. + +Documentation +------------- + +- gh-issue-109209: The minimum Sphinx version required for the documentation + is now 4.2. + +Windows +------- + +- gh-issue-109991: Update Windows build to use OpenSSL 3.0.11. + +macOS +----- + +- gh-issue-109991: Update macOS installer to use OpenSSL 3.0.11. + +Tools/Demos +----------- + +- gh-issue-109991: Update GitHub CI workflows to use OpenSSL 3.0.11 and + multissltests to use 1.1.1w, 3.0.11, and 3.1.3. + + +What's New in Python 3.12.0 release candidate 3? +================================================ + +*Release date: 2023-09-18* + +Core and Builtins +----------------- + +- gh-issue-109496: On a Python built in debug mode, :c:func:`Py_DECREF()` + now calls ``_Py_NegativeRefcount()`` if the object is a dangling pointer + to deallocated memory: memory filled with ``0xDD`` "dead byte" by the + debug hook on memory allocators. The fix is to check the reference count + *before* checking for ``_Py_IsImmortal()``. Patch by Victor Stinner. + +- gh-issue-109371: Deopted instructions correctly for tool initialization + and modified the incorrect assertion in instrumentation, when a previous + tool already sets INSTRUCTION events + +- gh-issue-105658: Fix bug where the line trace of an except block ending + with a conditional includes an excess event with the line of the + conditional expression. + +- gh-issue-109219: Fix compiling type param scopes that use a name which is + also free in an inner scope. + +- gh-issue-109341: Fix crash when compiling an invalid AST involving a + :class:`ast.TypeAlias`. + +- gh-issue-109195: Fix source location for the ``LOAD_*`` instruction + preceding a ``LOAD_SUPER_ATTR`` to load the ``super`` global (or shadowing + variable) so that it encompasses only the name ``super`` and not the + following parentheses. + +- gh-issue-109118: Disallow nested scopes (lambdas, generator expressions, + and comprehensions) within PEP 695 annotation scopes that are nested + within classes. + +- gh-issue-109114: Relax the detection of the error message for invalid + lambdas inside f-strings to not search for arbitrary replacement fields to + avoid false positives. Patch by Pablo Galindo + +- gh-issue-109118: Fix interpreter crash when a NameError is raised inside + the type parameters of a generic class. + +- gh-issue-108976: Fix crash that occurs after de-instrumenting a code + object in a monitoring callback. + +- gh-issue-108732: Make iteration variables of module- and class-scoped + comprehensions visible to pdb and other tools that use ``frame.f_locals`` + again. + +- gh-issue-108959: Fix caret placement for error locations for subscript and + binary operations that involve non-semantic parentheses and spaces. Patch + by Pablo Galindo + +Library +------- + +- gh-issue-108682: Enum: require ``names=()`` or ``type=...`` to create an + empty enum using the functional syntax. + +- gh-issue-108843: Fix an issue in :func:`ast.unparse` when unparsing + f-strings containing many quote types. + +Documentation +------------- + +- gh-issue-102823: Document the return type of ``x // y`` when ``x`` and + ``y`` have type :class:`float`. + +Tests +----- + +- gh-issue-109396: Fix ``test_socket.test_hmac_sha1()`` in FIPS mode. Use a + longer key: FIPS mode requires at least of at least 112 bits. The previous + key was only 32 bits. Patch by Victor Stinner. + +- gh-issue-104736: Fix test_gdb on Python built with LLVM clang 16 on Linux + ppc64le (ex: Fedora 38). Search patterns in gdb "bt" command output to + detect when gdb fails to retrieve the traceback. For example, skip a test + if ``Backtrace stopped: frame did not save the PC`` is found. Patch by + Victor Stinner. + +- gh-issue-109237: Fix ``test_site.test_underpth_basic()`` when the working + directory contains at least one non-ASCII character: encode the ``._pth`` + file to UTF-8 and enable the UTF-8 Mode to use UTF-8 for the child process + stdout. Patch by Victor Stinner. + +- gh-issue-109230: Fix ``test_pyexpat.test_exception()``: it can now be run + from a directory different than Python source code directory. Before, the + test failed in this case. Skip the test if Modules/pyexpat.c source is + not available. Skip also the test on Python implementations other than + CPython. Patch by Victor Stinner. + +- gh-issue-109015: Fix test_asyncio, test_imaplib and test_socket tests on + FreeBSD if the TCP blackhole is enabled (``sysctl + net.inet.tcp.blackhole``). Skip the few tests which failed with + ``ETIMEDOUT`` which such non standard configuration. Currently, the + `FreeBSD GCP image enables TCP and UDP blackhole + `_ (``sysctl + net.inet.tcp.blackhole=2`` and ``sysctl net.inet.udp.blackhole=1``). + Patch by Victor Stinner. + +- gh-issue-91960: Skip ``test_gdb`` if gdb is unable to retrieve Python + frame objects: if a frame is ````. When Python is built + with "clang -Og", gdb can fail to retrive the *frame* parameter of + ``_PyEval_EvalFrameDefault()``. In this case, tests like ``py_bt()`` are + likely to fail. Without getting access to Python frames, ``python-gdb.py`` + is mostly clueless on retrieving the Python traceback. Moreover, + ``test_gdb`` is no longer skipped on macOS if Python is built with Clang. + Patch by Victor Stinner. + +- gh-issue-108962: Skip ``test_tempfile.test_flags()`` if ``chflags()`` + fails with "OSError: [Errno 45] Operation not supported" (ex: on FreeBSD + 13). Patch by Victor Stinner. + +- gh-issue-108851: Fix ``test_tomllib`` recursion tests for WASI buildbots: + reduce the recursion limit and compute the maximum nested array/dict + depending on the current available recursion limit. Patch by Victor + Stinner. + +- gh-issue-108851: Add ``get_recursion_available()`` and + ``get_recursion_depth()`` functions to the :mod:`test.support` module. + Patch by Victor Stinner. + +- gh-issue-108834: Add ``--fail-rerun option`` option to regrtest: if a test + failed when then passed when rerun in verbose mode, exit the process with + exit code 2 (error), instead of exit code 0 (success). Patch by Victor + Stinner. + +- gh-issue-108834: Rename regrtest ``--verbose2`` option (``-w``) to + ``--rerun``. Keep ``--verbose2`` as a deprecated alias. Patch by Victor + Stinner. + +- gh-issue-108834: When regrtest reruns failed tests in verbose mode + (``./python -m test --rerun``), tests are now rerun in fresh worker + processes rather than being executed in the main process. If a test does + crash or is killed by a timeout, the main process can detect and handle + the killed worker process. Tests are rerun in parallel if the ``-jN`` + option is used to run tests in parallel. Patch by Victor Stinner. + +- gh-issue-103186: Suppress and assert expected RuntimeWarnings in + test_sys_settrace.py + +Build +----- + +- gh-issue-108740: Fix a race condition in ``make regen-all``. The + ``deepfreeze.c`` source and files generated by Argument Clinic are now + generated or updated before generating "global objects". Previously, some + identifiers may miss depending on the order in which these files were + generated. Patch by Victor Stinner. + + What's New in Python 3.12.0 release candidate 2? ================================================ @@ -102,7 +302,7 @@ Patch by Erlend E. Aasland. - gh-issue-107963: Fix :func:`multiprocessing.set_forkserver_preload` to - check the given list of modules names. Patch by Dong-hee Na. + check the given list of modules names. Patch by Donghee Na. - gh-issue-106242: Fixes :func:`os.path.normpath` to handle embedded null characters without truncating the path. @@ -1077,7 +1277,7 @@ objects with a missing attribute. - gh-issue-104028: Reduce object creation while calling callback function - from gc. Patch by Dong-hee Na. + from gc. Patch by Donghee Na. - gh-issue-104018: Disallow the "z" format specifier in %-format of bytes objects. @@ -1182,7 +1382,7 @@ when pickled and unpickled. - gh-issue-103242: Migrate :meth:`~ssl.SSLContext.set_ecdh_curve` method not - to use deprecated OpenSSL APIs. Patch by Dong-hee Na. + to use deprecated OpenSSL APIs. Patch by Donghee Na. - gh-issue-103323: We've replaced our use of ``_PyRuntime.tstate_current`` with a thread-local variable. This is a fairly low-level implementation @@ -1761,7 +1961,7 @@ properly. - gh-issue-104106: Add gcc fallback of mkfifoat/mknodat for macOS. Patch by - Dong-hee Na. + Donghee Na. - gh-issue-103532: The ``TKINTER_PROTECT_LOADTK`` macro is no longer defined or used in the ``_tkinter`` module. It was previously only defined when @@ -1884,7 +2084,7 @@ to a PyTypeObject: ``PyUnstable_Type_AssignVersionTag()``. - gh-issue-101408: :c:func:`PyObject_GC_Resize` should calculate preheader - size if needed. Patch by Dong-hee Na. + size if needed. Patch by Donghee Na. - gh-issue-98836: Add support of more formatting options (left aligning, octals, uppercase hexadecimals, :c:type:`intmax_t`, :c:type:`ptrdiff_t`, @@ -2283,7 +2483,7 @@ the iter object. - gh-issue-101430: Update :mod:`tracemalloc` to handle presize of object - properly. Patch by Dong-hee Na. + properly. Patch by Donghee Na. - gh-issue-101696: Invalidate type version tag in ``_PyStaticType_Dealloc`` for static types, avoiding bug where a false cache hit could crash the @@ -2547,10 +2747,10 @@ - gh-issue-101400: Fix wrong lineno in exception message on :keyword:`continue` or :keyword:`break` which are not in a loop. Patch by - Dong-hee Na. + Donghee Na. - gh-issue-101372: Fix :func:`~unicodedata.is_normalized` to properly handle - the UCD 3.2.0 cases. Patch by Dong-hee Na. + the UCD 3.2.0 cases. Patch by Donghee Na. - gh-issue-101266: Fix :func:`sys.getsizeof` reporting for :class:`int` subclasses. @@ -2723,7 +2923,7 @@ ----- - gh-issue-101282: Update BOLT configration not to use depreacted usage of - ``--split functions``. Patch by Dong-hee Na. + ``--split functions``. Patch by Donghee Na. - gh-issue-101522: Allow overriding Windows dependencies versions and paths using MSBuild properties. @@ -2795,10 +2995,10 @@ - gh-issue-99005: Remove :opcode:`UNARY_POSITIVE`, :opcode:`ASYNC_GEN_WRAP` and :opcode:`LIST_TO_TUPLE`, replacing them with intrinsics. -- gh-issue-99005: Add new :opcode:`CALL_INSTRINSIC_1` instruction. Remove +- gh-issue-99005: Add new :opcode:`CALL_INTRINSIC_1` instruction. Remove :opcode:`IMPORT_STAR`, :opcode:`PRINT_EXPR` and :opcode:`STOPITERATION_ERROR`, replacing them with the - :opcode:`CALL_INSTRINSIC_1` instruction. + :opcode:`CALL_INTRINSIC_1` instruction. - gh-issue-100288: Remove the LOAD_ATTR_METHOD_WITH_DICT specialized instruction. Stats show it is not useful. @@ -3025,7 +3225,7 @@ Waygood. - gh-issue-98778: Update :exc:`~urllib.error.HTTPError` to be initialized - properly, even if the ``fp`` is ``None``. Patch by Dong-hee Na. + properly, even if the ``fp`` is ``None``. Patch by Donghee Na. - gh-issue-99925: Unify error messages in JSON serialization between ``json.dumps(float('nan'), allow_nan=False)`` and @@ -3232,7 +3432,7 @@ This is done by changing the :mod:`http.server` :class:`BaseHTTPRequestHandler` ``.log_message`` method to replace control - characters with a ``\xHH`` hex escape before printing. + characters with a :samp:`\\x{HH}` hex escape before printing. - gh-issue-87604: Avoid publishing list of active per-interpreter audit hooks via the :mod:`gc` module @@ -3283,7 +3483,7 @@ haven't had :c:func:`PyType_Ready` called on them yet. - gh-issue-99127: Allow some features of :mod:`syslog` to the main - interpreter only. Patch by Dong-hee Na. + interpreter only. Patch by Donghee Na. - gh-issue-91053: Optimizing interpreters and JIT compilers may need to invalidate internal metadata when functions are modified. This change adds @@ -3570,8 +3770,8 @@ longer involves a quadratic algorithm. This prevents a potential CPU denial of service if an out-of-spec excessive length hostname involving bidirectional characters were decoded. Some protocols such as - :mod:`urllib` http ``3xx`` redirects potentially allow for an attacker to - supply such a name. + :mod:`urllib` http :samp:`3{xx}` redirects potentially allow for an + attacker to supply such a name. Individual labels within an IDNA encoded DNS name will now raise an error early during IDNA decoding if they are longer than 1024 unicode characters @@ -3615,7 +3815,7 @@ "python."). - gh-issue-96055: Update :mod:`faulthandler` to emit an error message with - the proper unexpected signal number. Patch by Dong-hee Na. + the proper unexpected signal number. Patch by Donghee Na. - gh-issue-99153: Fix location of :exc:`SyntaxError` for a :keyword:`try` block with both :keyword:`except` and :keyword:`except* `. @@ -4051,7 +4251,7 @@ ----------------- - gh-issue-98374: Suppress ImportError for invalid query for help() command. - Patch by Dong-hee Na. + Patch by Donghee Na. - gh-issue-98461: Fix source location in bytecode for list, set and dict comprehensions as well as generator expressions. @@ -4076,7 +4276,7 @@ parser does not have to calculate those doing pointer arithmetic. - gh-issue-96078: :func:`os.sched_yield` now release the GIL while calling - sched_yield(2). Patch by Dong-hee Na. + sched_yield(2). Patch by Donghee Na. - gh-issue-97955: Migrate :mod:`zoneinfo` to Argument Clinic. @@ -4184,7 +4384,7 @@ - gh-issue-96751: Remove dead code from ``CALL_FUNCTION_EX`` opcode. - gh-issue-90751: :class:`memoryview` now supports half-floats. Patch by - Dong-hee Na and Antoine Pitrou. + Donghee Na and Antoine Pitrou. - gh-issue-96678: Fix case of undefined behavior in ceval.c @@ -4333,7 +4533,7 @@ non-identical code objects could be "deduplicated" during compilation. - gh-issue-91146: Reduce allocation size of :class:`list` from - :meth:`str.split` and :meth:`str.rsplit`. Patch by Dong-hee Na and Inada + :meth:`str.split` and :meth:`str.rsplit`. Patch by Donghee Na and Inada Naoki. - gh-issue-87092: Create a 'jump target label' abstraction in the compiler @@ -5369,7 +5569,7 @@ - gh-issue-92932: Now :func:`~dis.dis` and :func:`~dis.get_instructions` handle operand values for instructions prefixed by ``EXTENDED_ARG_QUICK``. - Patch by Sam Gross and Dong-hee Na. + Patch by Sam Gross and Donghee Na. - gh-issue-92675: Fix :func:`venv.ensure_directories` to accept :class:`pathlib.Path` arguments in addition to :class:`str` paths. Patch @@ -5825,13 +6025,13 @@ - gh-issue-96761: Fix the build process of clang compiler for :program:`_bootstrap_python` if LTO optimization is applied. Patch by - Matthias Görgens and Dong-hee Na. + Matthias Görgens and Donghee Na. - gh-issue-96883: ``wasm32-emscripten`` builds for browsers now include :mod:`concurrent.futures` for :mod:`asyncio` and :mod:`unittest.mock`. - gh-issue-85936: CPython now uses the ThinLTO option as the default policy - if the Clang compiler accepts the flag. Patch by Dong-hee Na. + if the Clang compiler accepts the flag. Patch by Donghee Na. - gh-issue-96729: Ensure that Windows releases built with ``Tools\msi\buildrelease.bat`` are upgradable to and from official Python @@ -5949,9 +6149,9 @@ also use :mod:`multiprocessing` to spawn more children will recognize that they are in a virtual environment. -- gh-issue-98414: Fix :file:`py.exe` launcher handling of ``-V:/`` - option when default preferences have been set in environment variables or - configuration files. +- gh-issue-98414: Fix :file:`py.exe` launcher handling of + :samp:`-V:{}/` option when default preferences have been set in + environment variables or configuration files. - gh-issue-97728: Fix possible crashes caused by the use of uninitialized variables when pass invalid arguments in :func:`os.system` on Windows and @@ -6354,7 +6554,7 @@ Victor Stinner. - gh-issue-91632: Fix a minor memory leak at exit: release the memory of the - :class:`generic_alias_iterator` type. Patch by Dong-hee Na. + :class:`generic_alias_iterator` type. Patch by Donghee Na. - gh-issue-81548: Octal escapes with value larger than ``0o377`` now produce a :exc:`DeprecationWarning`. In a future Python version they will be a @@ -7084,7 +7284,7 @@ - bpo-46775: Some Windows system error codes(>= 10000) are now mapped into the correct errno and may now raise a subclass of :exc:`OSError`. Patch by - Dong-hee Na. + Donghee Na. - bpo-47129: Improve error messages in f-string syntax errors concerning empty expressions. @@ -7634,7 +7834,7 @@ :func:`sys.set_asyncgen_hooks` functions instead. Patch by Victor Stinner. - bpo-46987: Remove private functions ``_PySys_GetObjectId()`` and - ``_PySys_SetObjectId()``. Patch by Dong-hee Na. + ``_PySys_SetObjectId()``. Patch by Donghee Na. - bpo-46906: Add new functions to pack and unpack C double (serialize and deserialize): :c:func:`PyFloat_Pack2`, :c:func:`PyFloat_Pack4`, @@ -7772,7 +7972,7 @@ - bpo-46323: :mod:`ctypes` now allocates memory on the stack instead of on the heap to pass arguments while calling a Python callback function. Patch - by Dong-hee Na. + by Donghee Na. - bpo-45923: Add a quickened form of :opcode:`RESUME` that skips quickening checks. @@ -7791,7 +7991,7 @@ ``Modules/_hashopenssl.c``. - bpo-46323: Use :c:func:`PyObject_Vectorcall` while calling ctypes callback - function. Patch by Dong-hee Na. + function. Patch by Donghee Na. - bpo-46615: When iterating over sets internally in ``setobject.c``, acquire strong references to the resulting items from the set. This prevents @@ -7819,7 +8019,7 @@ :meth:`~mmap.find` and :meth:`~mmap.rfind`. - bpo-46736: :class:`~http.server.SimpleHTTPRequestHandler` now uses HTML5 - grammar. Patch by Dong-hee Na. + grammar. Patch by Donghee Na. - bpo-44886: Inherit asyncio proactor datagram transport from :class:`asyncio.DatagramTransport`. @@ -8142,7 +8342,7 @@ by Kumar Aditya. - bpo-46481: Speed up calls to :meth:`weakref.ref.__call__` by using the - :pep:`590` ``vectorcall`` calling convention. Patch by Dong-hee Na. + :pep:`590` ``vectorcall`` calling convention. Patch by Donghee Na. - bpo-46417: Fix a race condition on setting a type ``__bases__`` attribute: the internal function ``add_subclass()`` now gets the @@ -9133,7 +9333,7 @@ gvfs-open - bpo-45429: On Windows, :func:`time.sleep` now uses a waitable timer which - supports high-resolution timers. Patch by Dong-hee Na and Eryk Sun. + supports high-resolution timers. Patch by Donghee Na and Eryk Sun. - bpo-37295: Optimize :func:`math.comb` and :func:`math.perm`. @@ -9440,7 +9640,7 @@ - bpo-29410: Add SipHash13 for string hash algorithm and use it by default. -- bpo-45385: Fix reference leak from descr_check. Patch by Dong-hee Na. +- bpo-45385: Fix reference leak from descr_check. Patch by Donghee Na. - bpo-45367: Specialized the ``BINARY_MULTIPLY`` opcode to ``BINARY_MULTIPLY_INT`` and ``BINARY_MULTIPLY_FLOAT`` using the PEP 659 @@ -9494,7 +9694,7 @@ - bpo-44511: Improve the generated bytecode for class and mapping patterns. - bpo-43706: Speed up calls to ``enumerate()`` by using the :pep:`590` - ``vectorcall`` calling convention. Patch by Dong-hee Na. + ``vectorcall`` calling convention. Patch by Donghee Na. Library ------- @@ -9542,7 +9742,7 @@ them. Patch by Inada Naoki. - bpo-45489: Update :class:`~typing.ForwardRef` to support ``|`` operator. - Patch by Dong-hee Na. + Patch by Donghee Na. - bpo-42222: Removed deprecated support for float arguments in *randrange()*. @@ -9574,7 +9774,7 @@ explicit loop arguments. Patch by Joongi Kim. - bpo-20028: Empty escapechar/quotechar is not allowed when initializing - :class:`csv.Dialect`. Patch by Vajrasky Kok and Dong-hee Na. + :class:`csv.Dialect`. Patch by Vajrasky Kok and Donghee Na. - bpo-44904: Fix bug in the :mod:`doctest` module that caused it to fail if a docstring included an example with a ``classmethod`` ``property``. Patch @@ -9602,7 +9802,7 @@ testing for year formatting options. - bpo-20028: Improve error message of :class:`csv.Dialect` when - initializing. Patch by Vajrasky Kok and Dong-hee Na. + initializing. Patch by Vajrasky Kok and Donghee Na. - bpo-45343: Update bundled pip to 21.2.4 and setuptools to 58.1.0 @@ -10034,7 +10234,7 @@ ``2**32`` times. - bpo-45000: A :exc:`SyntaxError` is now raised when trying to delete - :const:`__debug__`. Patch by Dong-hee Na. + :const:`__debug__`. Patch by Donghee Na. - bpo-44963: Implement ``send()`` and ``throw()`` methods for ``anext_awaitable`` objects. Patch by Pablo Galindo. @@ -10081,7 +10281,7 @@ - bpo-44895: A debug variable :envvar:`PYTHONDUMPREFSFILE` is added for creating a dump file which is generated by :option:`--with-trace-refs`. - Patch by Dong-hee Na. + Patch by Donghee Na. - bpo-44900: Add five superinstructions for PEP 659 quickening: @@ -10170,7 +10370,7 @@ raises ``TypeError`` instead of returning ``NotImplemented``. - bpo-44661: Update ``property_descr_set`` to use vectorcall if possible. - Patch by Dong-hee Na. + Patch by Donghee Na. - bpo-44662: Add ``__module__`` to ``types.Union``. This also fixes ``types.Union`` issues with ``typing.Annotated``. Patch provided by Yurii @@ -10192,7 +10392,7 @@ - bpo-44611: On Windows, :func:`os.urandom`: uses BCryptGenRandom API instead of CryptGenRandom API which is deprecated from Microsoft Windows - API. Patch by Dong-hee Na. + API. Patch by Donghee Na. - bpo-44635: Convert ``None`` to ``type(None)`` in the union type constructor. @@ -10546,7 +10746,7 @@ Patch by Hugo van Kemenade. - bpo-44987: Pure ASCII strings are now normalized in constant time by - :func:`unicodedata.normalize`. Patch by Dong-hee Na. + :func:`unicodedata.normalize`. Patch by Donghee Na. - bpo-35474: Calling :func:`mimetypes.guess_all_extensions` with ``strict=False`` no longer affects the result of the following call with @@ -10674,7 +10874,7 @@ - bpo-42255: :class:`webbrowser.MacOSX` is deprecated and will be removed in Python 3.13. It is untested and undocumented and also not used by - webbrowser itself. Patch by Dong-hee Na. + webbrowser itself. Patch by Donghee Na. - bpo-44955: Method :meth:`~unittest.TestResult.stopTestRun` is now always called in pair with method :meth:`~unittest.TestResult.startTestRun` for @@ -10854,7 +11054,7 @@ @contextlib.contextmanager generator - bpo-44558: Make the implementation consistency of - :func:`~operator.indexOf` between C and Python versions. Patch by Dong-hee + :func:`~operator.indexOf` between C and Python versions. Patch by Donghee Na. - bpo-41249: Fixes ``TypedDict`` to work with ``typing.get_type_hints()`` @@ -10952,7 +11152,7 @@ or colons. - bpo-44395: Fix :meth:`~email.message.MIMEPart.as_string` to pass unixfrom - properly. Patch by Dong-hee Na. + properly. Patch by Donghee Na. - bpo-34266: Handle exceptions from parsing the arg of :mod:`pdb`'s run/restart command. @@ -10970,7 +11170,7 @@ :mod:`sysconfig`. - bpo-35800: :class:`smtpd.MailmanProxy` is now removed as it is unusable - without an external module, ``mailman``. Patch by Dong-hee Na. + without an external module, ``mailman``. Patch by Donghee Na. - bpo-44357: Added a function that returns cube root of the given number :func:`math.cbrt` @@ -11009,7 +11209,7 @@ - bpo-44258: Support PEP 515 for Fraction's initialization from string. - bpo-44235: Remove deprecated functions in the :mod:`gettext`. Patch by - Dong-hee Na. + Donghee Na. - bpo-38693: Prefer f-strings to ``.format`` in importlib.resources. @@ -11561,7 +11761,7 @@ easier to add to and modify the frozen modules. - bpo-44340: Add support for building with clang thin lto via - --with-lto=thin/full. Patch by Dong-hee Na and Brett Holman. + --with-lto=thin/full. Patch by Donghee Na and Brett Holman. - bpo-44535: Enable building using a Visual Studio 2022 install on Windows. @@ -11676,7 +11876,7 @@ - bpo-43425: Removed the 'test2to3' demo project that demonstrated using lib2to3 to support Python 2.x and Python 3.x from a single source in a - distutils package. Patch by Dong-hee Na + distutils package. Patch by Donghee Na - bpo-44074: Make patchcheck automatically detect the correct base branch name (previously it was hardcoded to 'master') @@ -12016,7 +12216,7 @@ locale encoding. - bpo-43979: Removed an unnecessary list comprehension before looping from - :func:`urllib.parse.parse_qsl`. Patch by Christoph Zwerschke and Dong-hee + :func:`urllib.parse.parse_qsl`. Patch by Christoph Zwerschke and Donghee Na. - bpo-43993: Update bundled pip to 21.1.1. @@ -12567,7 +12767,7 @@ elements ('**') in f-strings. Patch by Pablo Galindo. - bpo-43575: Speed up calls to ``map()`` by using the :pep:`590` - ``vectorcall`` calling convention. Patch by Dong-hee Na. + ``vectorcall`` calling convention. Patch by Donghee Na. - bpo-42137: The import system now prefers using ``__spec__`` for ``ModuleType.__repr__`` over ``module_repr()``. @@ -12611,7 +12811,7 @@ the vast majority of processes that don't use sigaltstack. - bpo-43287: Speed up calls to ``filter()`` by using the :pep:`590` - ``vectorcall`` calling convention. Patch by Dong-hee Na. + ``vectorcall`` calling convention. Patch by Donghee Na. - bpo-37448: Add a radix tree based memory map to track in-use obmalloc arenas. Use to replace the old implementation of address_in_range(). The @@ -13068,7 +13268,7 @@ - bpo-43106: Added :const:`~os.O_EVTONLY`, :const:`~os.O_FSYNC`, :const:`~os.O_SYMLINK` and :const:`~os.O_NOFOLLOW_ANY` for macOS. Patch by - Dong-hee Na. + Donghee Na. - bpo-42960: Adds :const:`resource.RLIMIT_KQUEUES` constant from FreeBSD to the :mod:`resource` module. @@ -13478,8 +13678,8 @@ unreachable bytecode blocks - bpo-42639: Make the :mod:`atexit` module state per-interpreter. It is now - safe have more than one :mod:`atexit` module instance. Patch by Dong-hee - Na and Victor Stinner. + safe have more than one :mod:`atexit` module instance. Patch by Donghee Na + and Victor Stinner. - bpo-32381: Fix encoding name when running a ``.pyc`` file on Windows: :c:func:`PyRun_SimpleFileExFlags()` now uses the correct encoding to @@ -13717,7 +13917,7 @@ ----- - bpo-42794: Update test_nntplib to use official group name of news.aioe.org - for testing. Patch by Dong-hee Na. + for testing. Patch by Donghee Na. - bpo-31904: Skip some asyncio tests on VxWorks. @@ -13963,7 +14163,7 @@ Python 3.4. It is somewhat obsolete, little used, and not tested. It was originally scheduled to be removed in Python 3.6, but such removals were delayed until after Python 2.7 EOL. Existing users should copy whatever - classes they use into their code. Patch by Dong-hee Na and and Terry J. + classes they use into their code. Patch by Donghee Na and and Terry J. Reedy. - bpo-26131: Deprecate zipimport.zipimporter.load_module() in favour of @@ -14451,14 +14651,14 @@ - bpo-41902: Micro optimization when compute :c:member:`~PySequenceMethods.sq_item` and :c:member:`~PyMappingMethods.mp_subscript` of :class:`range`. Patch by - Dong-hee Na. + Donghee Na. - bpo-41894: When loading a native module and a load failure occurs, prevent a possible UnicodeDecodeError when not running in a UTF-8 locale by decoding the load error message using the current locale's encoding. - bpo-41902: Micro optimization for range.index if step is 1. Patch by - Dong-hee Na. + Donghee Na. - bpo-41435: Add `sys._current_exceptions()` function to retrieve a dictionary mapping each thread's identifier to the topmost exception @@ -14756,13 +14956,13 @@ infinite recursion. - bpo-41922: Speed up calls to ``reversed()`` by using the :pep:`590` - ``vectorcall`` calling convention. Patch by Dong-hee Na. + ``vectorcall`` calling convention. Patch by Donghee Na. - bpo-41873: Calls to ``float()`` are now faster due to the ``vectorcall`` calling convention. Patch by Dennis Sweeney. - bpo-41870: Speed up calls to ``bool()`` by using the :pep:`590` - ``vectorcall`` calling convention. Patch by Dong-hee Na. + ``vectorcall`` calling convention. Patch by Donghee Na. - bpo-1635741: Port the :mod:`_bisect` module to the multi-phase initialization API (:pep:`489`). @@ -14958,7 +15158,7 @@ - bpo-40957: Fix refleak in _Py_fopen_obj() when PySys_Audit() fails - bpo-40950: Add a state to the :mod:`nis` module (:pep:`3121`) and apply - the multiphase initialization. Patch by Dong-hee Na. + the multiphase initialization. Patch by Donghee Na. - bpo-40947: The Python :ref:`Path Configuration ` now takes :c:member:`PyConfig.platlibdir` in account. @@ -15037,7 +15237,7 @@ Galindo. - bpo-39573: :c:func:`Py_TYPE()` is changed to the inline static function. - Patch by Dong-hee Na. + Patch by Donghee Na. - bpo-40696: Fix a hang that can arise after :meth:`generator.throw` due to a cycle in the exception context chain. @@ -15583,7 +15783,7 @@ do you remove multiple items from a list". - bpo-35293: Fix RemovedInSphinx40Warning when building the documentation. - Patch by Dong-hee Na. + Patch by Donghee Na. - bpo-37149: Change Shipman tkinter doc link from archive.org to TkDocs. (The doc has been removed from the NMT server.) The new link responds @@ -15670,7 +15870,7 @@ ----- - bpo-38249: Update :c:macro:`Py_UNREACHABLE` to use __builtin_unreachable() - if only the compiler is able to use it. Patch by Dong-hee Na. + if only the compiler is able to use it. Patch by Donghee Na. - bpo-41617: Fix ``pycore_bitutils.h`` header file to support old clang versions: ``__builtin_bswap16()`` is not available in LLVM clang 3.0. @@ -16058,10 +16258,10 @@ positional-only. - bpo-39305: Update :mod:`nntplib` to merge :class:`nntplib.NNTP` and - :class:`nntplib._NNTPBase`. Patch by Dong-hee Na. + :class:`nntplib._NNTPBase`. Patch by Donghee Na. - bpo-32494: Update :mod:`dbm.gnu` to use gdbm_count if possible when - calling :func:`len`. Patch by Dong-hee Na. + calling :func:`len`. Patch by Donghee Na. - bpo-40453: Add ``isolated=True`` keyword-only parameter to ``_xxsubinterpreters.create()``. An isolated subinterpreter cannot spawn @@ -16091,7 +16291,7 @@ for subdirectories in package data, matching backport in importlib_resources 1.5. -- bpo-40375: :meth:`imaplib.IMAP4.unselect` is added. Patch by Dong-hee Na. +- bpo-40375: :meth:`imaplib.IMAP4.unselect` is added. Patch by Donghee Na. - bpo-40389: ``repr()`` now returns ``typing.Optional[T]`` when called for ``typing.Union`` of two types, one of which is ``NoneType``. @@ -16745,7 +16945,7 @@ (:pep:`489`). - bpo-37207: Speed up calls to ``frozenset()`` by using the :pep:`590` - ``vectorcall`` calling convention. Patch by Dong-hee Na. + ``vectorcall`` calling convention. Patch by Donghee Na. - bpo-39984: subinterpreters: Move ``_PyRuntimeState.ceval.tracing_possible`` to @@ -16753,7 +16953,7 @@ its own variable. - bpo-37207: Speed up calls to ``set()`` by using the :pep:`590` - ``vectorcall`` calling convention. Patch by Dong-hee Na. + ``vectorcall`` calling convention. Patch by Donghee Na. - bpo-1635741: Port _statistics module to multiphase initialization (:pep:`489`). @@ -16770,7 +16970,7 @@ Taskaya. - bpo-37207: Speed up calls to ``tuple()`` by using the :pep:`590` - ``vectorcall`` calling convention. Patch by Dong-hee Na. + ``vectorcall`` calling convention. Patch by Donghee Na. - bpo-38373: Changed list overallocation strategy. It no longer overallocates if the new size is closer to overallocated size than to the @@ -16918,7 +17118,7 @@ a tuple (e.g. ``a[i, j]``). - bpo-39828: Fix :mod:`json.tool` to catch :exc:`BrokenPipeError`. Patch by - Dong-hee Na. + Donghee Na. - bpo-13487: Avoid a possible *"RuntimeError: dictionary changed size during iteration"* from :func:`inspect.getmodule` when it tried to loop through @@ -16989,7 +17189,7 @@ ``qop`` parameter is not present. - bpo-39509: HTTP status codes ``103 EARLY_HINTS`` and ``425 TOO_EARLY`` are - added to :class:`http.HTTPStatus`. Patch by Dong-hee Na. + added to :class:`http.HTTPStatus`. Patch by Donghee Na. - bpo-39507: Adding HTTP status 418 "I'm a Teapot" to HTTPStatus in http library. Patch by Ross Rhodes. @@ -17132,7 +17332,7 @@ ----- - bpo-40024: Add :c:func:`PyModule_AddType` helper function: add a type to a - module. Patch by Dong-hee Na. + module. Patch by Donghee Na. - bpo-39946: Remove ``_PyRuntime.getframe`` hook and remove ``_PyThreadState_GetFrame`` macro which was an alias to @@ -17142,7 +17342,7 @@ - bpo-39947: Add :c:func:`PyThreadState_GetFrame` function: get the current frame of a Python thread state. -- bpo-37207: Add _PyArg_NoKwnames helper function. Patch by Dong-hee Na. +- bpo-37207: Add _PyArg_NoKwnames helper function. Patch by Donghee Na. - bpo-39947: Add :c:func:`PyThreadState_GetInterpreter`: get the interpreter of a Python thread state. @@ -17225,7 +17425,7 @@ reference, and so does its first item. Patch by Yonatan Goldschmidt. - bpo-39573: Update clinic tool to use :c:func:`Py_IS_TYPE`. Patch by - Dong-hee Na. + Donghee Na. - bpo-39619: Enable use of :func:`os.chroot` on HP-UX systems. @@ -17255,11 +17455,11 @@ garbage collection of deleted, pickled objects. - bpo-39453: Fixed a possible crash in :meth:`list.__contains__` when a list - is changed during comparing items. Patch by Dong-hee Na. + is changed during comparing items. Patch by Donghee Na. - bpo-39434: :term:`floor division` of float operation now has a better performance. Also the message of :exc:`ZeroDivisionError` for this - operation is updated. Patch by Dong-hee Na. + operation is updated. Patch by Donghee Na. - bpo-1635741: Port _codecs extension module to multiphase initialization (:pep:`489`). @@ -17618,7 +17818,7 @@ positional-only argument - by Anthony Sottile. - bpo-39200: Correct the error message when calling the :func:`min` or - :func:`max` with no arguments. Patch by Dong-hee Na. + :func:`max` with no arguments. Patch by Donghee Na. - bpo-39200: Correct the error message when trying to construct :class:`range` objects with no arguments. Patch by Pablo Galindo. @@ -17710,7 +17910,7 @@ 3.5 (:issue:`22486`): use :func:`math.gcd` instead. - bpo-39329: :class:`~smtplib.LMTP` constructor now has an optional - *timeout* parameter. Patch by Dong-hee Na. + *timeout* parameter. Patch by Donghee Na. - bpo-39313: Add a new ``exec_function`` option (*--exec-function* in the CLI) to ``RefactoringTool`` for making ``exec`` a function. Patch by @@ -17718,11 +17918,11 @@ - bpo-39259: :class:`~ftplib.FTP_TLS` and :class:`~ftplib.FTP_TLS` now raise a :class:`ValueError` if the given timeout for their constructor is zero - to prevent the creation of a non-blocking socket. Patch by Dong-hee Na. + to prevent the creation of a non-blocking socket. Patch by Donghee Na. - bpo-39259: :class:`~smtplib.SMTP` and :class:`~smtplib.SMTP_SSL` now raise a :class:`ValueError` if the given timeout for their constructor is zero - to prevent the creation of a non-blocking socket. Patch by Dong-hee Na. + to prevent the creation of a non-blocking socket. Patch by Donghee Na. - bpo-39310: Add :func:`math.ulp`: return the value of the least significant bit of a float. @@ -17733,7 +17933,7 @@ - bpo-39259: :class:`~nntplib.NNTP` and :class:`~nntplib.NNTP_SSL` now raise a :class:`ValueError` if the given timeout for their constructor is zero - to prevent the creation of a non-blocking socket. Patch by Dong-hee Na. + to prevent the creation of a non-blocking socket. Patch by Donghee Na. - bpo-38901: When you specify prompt='.' or equivalently python -m venv --prompt . ... the basename of the current directory is used to set the @@ -17744,7 +17944,7 @@ - bpo-39259: :class:`~poplib.POP3` and :class:`~poplib.POP3_SSL` now raise a :class:`ValueError` if the given timeout for their constructor is zero to - prevent the creation of a non-blocking socket. Patch by Dong-hee Na. + prevent the creation of a non-blocking socket. Patch by Donghee Na. - bpo-39242: Updated the Gmane domain from news.gmane.org to news.gmane.io which is used for examples of :class:`~nntplib.NNTP` news reader server @@ -17772,7 +17972,7 @@ new task spawning before exception raising. - bpo-38871: Correctly parenthesize filter-based statements that contain - lambda expressions in mod:`lib2to3`. Patch by Dong-hee Na. + lambda expressions in mod:`lib2to3`. Patch by Donghee Na. - bpo-39142: A change was made to logging.config.dictConfig to avoid converting instances of named tuples to ConvertingTuple. It's assumed that @@ -17816,7 +18016,7 @@ :meth:`~imaplib.IMAP4.open` method now has an optional *timeout* parameter with this change. The overridden methods of :class:`~imaplib.IMAP4_SSL` and :class:`~imaplib.IMAP4_stream` were applied to this change. Patch by - Dong-hee Na. + Donghee Na. - bpo-35182: Fixed :func:`Popen.communicate` subsequent call crash when the child process has already closed any piped standard stream, but still @@ -18306,7 +18506,7 @@ - bpo-38243: Escape the server title of :class:`xmlrpc.server.DocXMLRPCServer` when rendering the document page as - HTML. (Contributed by Dong-hee Na in :issue:`38243`.) + HTML. (Contributed by Donghee Na in :issue:`38243`.) - bpo-38174: Update vendorized expat library version to 2.2.8, which resolves CVE-2019-15903. @@ -18367,7 +18567,7 @@ without arguments in decorators. - bpo-38525: Fix a segmentation fault when using reverse iterators of empty - ``dict`` objects. Patch by Dong-hee Na and Inada Naoki. + ``dict`` objects. Patch by Donghee Na and Inada Naoki. - bpo-38465: :class:`bytearray`, :class:`~array.array` and :class:`~mmap.mmap` objects allow now to export more than ``2**31`` @@ -18398,7 +18598,7 @@ test that objects visited by ``tp_traverse()`` are valid. - bpo-38210: Remove unnecessary intersection and update set operation in - dictview with empty set. (Contributed by Dong-hee Na in :issue:`38210`.) + dictview with empty set. (Contributed by Donghee Na in :issue:`38210`.) - bpo-38402: Check the error from the system's underlying ``crypt`` or ``crypt_r``. @@ -18701,7 +18901,7 @@ - bpo-38602: Added constants :const:`~fcntl.F_OFD_GETLK`, :const:`~fcntl.F_OFD_SETLK` and :const:`~fcntl.F_OFD_SETLKW` to the - :mod:`fcntl` module. Patch by Dong-hee Na. + :mod:`fcntl` module. Patch by Donghee Na. - bpo-38334: Fixed seeking backward on an encrypted :class:`zipfile.ZipExtFile`. @@ -18728,7 +18928,7 @@ - bpo-38521: Fixed erroneous equality comparison in statistics.NormalDist(). - bpo-38493: Added :const:`~os.CLD_KILLED` and :const:`~os.CLD_STOPPED` for - :attr:`si_code`. Patch by Dong-hee Na. + :attr:`si_code`. Patch by Donghee Na. - bpo-38478: Fixed a bug in :meth:`inspect.signature.bind` that was causing it to fail when handling a keyword argument with same name as @@ -18927,7 +19127,7 @@ it should avoid dynamic lookup. - bpo-35923: Update :class:`importlib.machinery.BuiltinImporter` to use - ``loader._ORIGIN`` instead of a hardcoded value. Patch by Dong-hee Na. + ``loader._ORIGIN`` instead of a hardcoded value. Patch by Donghee Na. - bpo-38010: In ``importlib.metadata`` sync with ``importlib_metadata`` 0.20, clarifying behavior of ``files()`` and fixing issue where only one @@ -18996,7 +19196,7 @@ etc. - bpo-37798: Update test_statistics.py to verify that the statistics module - works well for both C and Python implementations. Patch by Dong-hee Na + works well for both C and Python implementations. Patch by Donghee Na - bpo-26589: Added a new status code to the http module: 451 UNAVAILABLE_FOR_LEGAL_REASONS @@ -19037,10 +19237,10 @@ platforms. - bpo-37798: Add C fastpath for statistics.NormalDist.inv_cdf() Patch by - Dong-hee Na + Donghee Na - bpo-37804: Remove the deprecated method `threading.Thread.isAlive()`. - Patch by Dong-hee Na. + Patch by Donghee Na. - bpo-37819: Add Fraction.as_integer_ratio() to match the corresponding methods in bool, int, float, and decimal. @@ -19674,7 +19874,7 @@ - bpo-38018: Increase code coverage for multiprocessing.shared_memory. -- bpo-37805: Add tests for json.dump(..., skipkeys=True). Patch by Dong-hee +- bpo-37805: Add tests for json.dump(..., skipkeys=True). Patch by Donghee Na. - bpo-37531: Enhance regrtest multiprocess timeout: write a message when @@ -19683,8 +19883,8 @@ - bpo-37876: Add tests for ROT-13 codec. -- bpo-36833: Added tests for PyDateTime_xxx_GET_xxx() macros of the C API of - the :mod:`datetime` module. Patch by Joannah Nanjekye. +- bpo-36833: Added tests for :samp:`PyDateTime_{xxx}_GET_{xxx}()` macros of + the C API of the :mod:`datetime` module. Patch by Joannah Nanjekye. - bpo-37558: Fix test_shared_memory_cleaned_after_process_termination name handling @@ -19841,9 +20041,9 @@ - bpo-37468: ``make install`` no longer installs ``wininst-*.exe`` files used by distutils bdist_wininst: bdist_wininst only works on Windows. -- bpo-37189: Many ``PyRun_XXX()`` functions like :c:func:`PyRun_String` were - no longer exported in ``libpython38.dll`` by mistake. Export them again to - fix the ABI compatibility. +- bpo-37189: Many :samp:`PyRun_{XXX}()` functions like + :c:func:`PyRun_String` were no longer exported in ``libpython38.dll`` by + mistake. Export them again to fix the ABI compatibility. - bpo-25361: Enables use of SSE2 instructions in Windows 32-bit build. @@ -21395,7 +21595,7 @@ ``PyMODINIT_FUNC`` macros of ``pyport.h`` when ``Py_BUILD_CORE_MODULE`` is defined. The ``Py_BUILD_CORE_MODULE`` define must be now be used to build a C extension as a dynamic library accessing Python internals: export the - PyInit_xxx() function in DLL exports on Windows. + :samp:`PyInit_{xxx}()` function in DLL exports on Windows. - bpo-31904: Don't build the ``_crypt`` extension on VxWorks. @@ -22211,7 +22411,7 @@ - bpo-35224: Implement :pep:`572` (assignment expressions). Patch by Emily Morehouse. -- bpo-32492: Speed up :class:`namedtuple` attribute access by 1.6x using a C +- bpo-32492: Speed up :func:`namedtuple` attribute access by 1.6x using a C fast-path for the name descriptors. Patch by Pablo Galindo. - bpo-35214: Fixed an out of bounds memory access when parsing a truncated @@ -22749,7 +22949,7 @@ set the result of an internal future if it's already done. - bpo-35283: Add a deprecated warning for the - :meth:`threading.Thread.isAlive` method. Patch by Dong-hee Na. + :meth:`threading.Thread.isAlive` method. Patch by Donghee Na. - bpo-35664: Improve operator.itemgetter() performance by 33% with optimized argument handling and with adding a fast path for the common case of a @@ -23776,7 +23976,7 @@ classes and Enum members. - bpo-33197: Update error message when constructing invalid - inspect.Parameters Patch by Dong-hee Na. + inspect.Parameters Patch by Donghee Na. - bpo-33383: Fixed crash in the get() method of the :mod:`dbm.ndbm` database object when it is called with a single argument. @@ -24834,7 +25034,8 @@ - bpo-35099: Improve the doc about IDLE running user code. The section is renamed from "IDLE -- console differences" is renamed "Running user code". - It mostly covers the implications of using custom sys.stdxxx objects. + It mostly covers the implications of using custom :samp:`sys.std{xxx}` + objects. - bpo-35097: Add IDLE doc subsection explaining editor windows. Topics include opening, title and status bar, .py* extension, and running. @@ -25353,7 +25554,7 @@ marked for removal in Python 3.8 - bpo-33197: Update error message when constructing invalid - inspect.Parameters Patch by Dong-hee Na. + inspect.Parameters Patch by Donghee Na. - bpo-33263: Fix FD leak in `_SelectorSocketTransport` Patch by Vlad Starostin. @@ -26906,10 +27107,10 @@ arg should be optional - bpo-32046: Updates 2to3 to convert from operator.isCallable(obj) to - callable(obj). Patch by Dong-hee Na. + callable(obj). Patch by Donghee Na. - bpo-32018: inspect.signature should follow :pep:`8`, if the parameter has - an annotation and a default value. Patch by Dong-hee Na. + an annotation and a default value. Patch by Donghee Na. - bpo-32025: Add time.thread_time() and time.thread_time_ns() @@ -27732,7 +27933,7 @@ - bpo-12414: sys.getsizeof() on a code object now returns the sizes which includes the code struct and sizes of objects which it references. Patch - by Dong-hee Na. + by Donghee Na. - bpo-29839: len() now raises ValueError rather than OverflowError if __len__() returned a large negative integer. @@ -28292,7 +28493,7 @@ - bpo-29169: Update zlib to 1.2.11. - bpo-30119: ftplib.FTP.putline() now throws ValueError on commands that - contains CR or LF. Patch by Dong-hee Na. + contains CR or LF. Patch by Donghee Na. - bpo-30879: os.listdir() and os.scandir() now emit bytes names when called with bytes-like argument. @@ -28315,7 +28516,7 @@ They now always return bytes. - bpo-30616: Functional API of enum allows to create empty enums. Patched by - Dong-hee Na + Donghee Na - bpo-30038: Fix race condition between signal delivery and wakeup file descriptor. Patch by Nathaniel Smith. @@ -28404,7 +28605,7 @@ Ma Lin. - bpo-30149: inspect.signature() now supports callables with - variable-argument parameters wrapped with partialmethod. Patch by Dong-hee + variable-argument parameters wrapped with partialmethod. Patch by Donghee Na. - bpo-30436: importlib.find_spec() raises ModuleNotFoundError instead of @@ -29767,7 +29968,7 @@ byte/string literals on pydoc. Patch by AndrĂ©s Delfino. - bpo-33197: Update error message when constructing invalid - inspect.Parameters Patch by Dong-hee Na. + inspect.Parameters Patch by Donghee Na. - bpo-33383: Fixed crash in the get() method of the :mod:`dbm.ndbm` database object when it is called with a single argument. @@ -30937,7 +31138,7 @@ Heimes. - bpo-30119: ftplib.FTP.putline() now throws ValueError on commands that - contains CR or LF. Patch by Dong-hee Na. + contains CR or LF. Patch by Donghee Na. - bpo-30595: multiprocessing.Queue.get() with a timeout now polls its reader in non-blocking mode if it succeeded to acquire the lock but the acquire @@ -31287,7 +31488,7 @@ - bpo-12414: sys.getsizeof() on a code object now returns the sizes which includes the code struct and sizes of objects which it references. Patch - by Dong-hee Na. + by Donghee Na. - bpo-29949: Fix memory usage regression of set and frozenset object. @@ -31315,7 +31516,7 @@ ------- - bpo-30616: Functional API of enum allows to create empty enums. Patched by - Dong-hee Na + Donghee Na - bpo-30038: Fix race condition between signal delivery and wakeup file descriptor. Patch by Nathaniel Smith. @@ -31326,7 +31527,7 @@ reference cycle to not keep objects alive longer than expected. - bpo-30149: inspect.signature() now supports callables with - variable-argument parameters wrapped with partialmethod. Patch by Dong-hee + variable-argument parameters wrapped with partialmethod. Patch by Donghee Na. - bpo-30645: Fix path calculation in imp.load_package(), fixing it for cases @@ -35150,7 +35351,7 @@ ------- - bpo-30119: ftplib.FTP.putline() now throws ValueError on commands that - contains CR or LF. Patch by Dong-hee Na. + contains CR or LF. Patch by Donghee Na. What's New in Python 3.5.4 release candidate 1? @@ -35280,7 +35481,7 @@ reference cycle to not keep objects alive longer than expected. - bpo-30149: inspect.signature() now supports callables with - variable-argument parameters wrapped with partialmethod. Patch by Dong-hee + variable-argument parameters wrapped with partialmethod. Patch by Donghee Na. - bpo-29931: Fixed comparison check for ipaddress.ip_interface objects. @@ -37089,8 +37290,8 @@ - bpo-25131: Make the line number and column offset of set/dict literals and comprehensions correspond to the opening brace. -- bpo-25150: Hide the private _Py_atomic_xxx symbols from the public - Python.h header to fix a compilation error with OpenMP. +- bpo-25150: Hide the private :samp:`_Py_atomic_{xxx}` symbols from the + public Python.h header to fix a compilation error with OpenMP. PyThreadState_GET() becomes an alias to PyThreadState_Get() to avoid ABI incompatibilities. @@ -37668,8 +37869,8 @@ - bpo-24745: Idle editor default font. Switch from Courier to platform-sensitive TkFixedFont. This should not affect current customized font selections. If there is a problem, edit - $HOME/.idlerc/config-main.cfg and remove 'fontxxx' entries from [Editor - Window]. Patch by Mark Roseman. + $HOME/.idlerc/config-main.cfg and remove ':samp:`font{xxx}`' entries from + [Editor Window]. Patch by Mark Roseman. - bpo-21192: Idle editor. When a file is run, put its name in the restart bar. Do not print false prompts. Original patch by Adnan Umer. diff -Nru python3.12-3.12.0~rc2/Modules/symtablemodule.c python3.12-3.12.0/Modules/symtablemodule.c --- python3.12-3.12.0~rc2/Modules/symtablemodule.c 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Modules/symtablemodule.c 2023-10-02 11:48:14.000000000 +0000 @@ -85,6 +85,14 @@ if (PyModule_AddIntConstant(m, "TYPE_CLASS", ClassBlock) < 0) return -1; if (PyModule_AddIntConstant(m, "TYPE_MODULE", ModuleBlock) < 0) return -1; + if (PyModule_AddIntConstant(m, "TYPE_ANNOTATION", AnnotationBlock) < 0) + return -1; + if (PyModule_AddIntConstant(m, "TYPE_TYPE_VAR_BOUND", TypeVarBoundBlock) < 0) + return -1; + if (PyModule_AddIntConstant(m, "TYPE_TYPE_ALIAS", TypeAliasBlock) < 0) + return -1; + if (PyModule_AddIntConstant(m, "TYPE_TYPE_PARAM", TypeParamBlock) < 0) + return -1; if (PyModule_AddIntMacro(m, LOCAL) < 0) return -1; if (PyModule_AddIntMacro(m, GLOBAL_EXPLICIT) < 0) return -1; diff -Nru python3.12-3.12.0~rc2/Modules/_testcapi/code.c python3.12-3.12.0/Modules/_testcapi/code.c --- python3.12-3.12.0~rc2/Modules/_testcapi/code.c 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Modules/_testcapi/code.c 2023-10-02 11:48:14.000000000 +0000 @@ -1,4 +1,5 @@ #include "parts.h" +#include "util.h" static Py_ssize_t get_code_extra_index(PyInterpreterState* interp) { @@ -74,7 +75,7 @@ } // Check the value is initially NULL - void *extra; + void *extra = UNINITIALIZED_PTR; int res = PyUnstable_Code_GetExtra(test_func_code, code_extra_index, &extra); if (res < 0) { goto finally; @@ -87,6 +88,7 @@ goto finally; } // Assert it was set correctly + extra = UNINITIALIZED_PTR; res = PyUnstable_Code_GetExtra(test_func_code, code_extra_index, &extra); if (res < 0) { goto finally; diff -Nru python3.12-3.12.0~rc2/Modules/_testcapi/dict.c python3.12-3.12.0/Modules/_testcapi/dict.c --- python3.12-3.12.0~rc2/Modules/_testcapi/dict.c 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Modules/_testcapi/dict.c 2023-10-02 11:48:14.000000000 +0000 @@ -212,7 +212,7 @@ static PyObject * dict_next(PyObject *self, PyObject *args) { - PyObject *mapping, *key, *value; + PyObject *mapping, *key = UNINITIALIZED_PTR, *value = UNINITIALIZED_PTR; Py_ssize_t pos; if (!PyArg_ParseTuple(args, "On", &mapping, &pos)) { return NULL; @@ -222,6 +222,8 @@ if (rc != 0) { return Py_BuildValue("inOO", rc, pos, key, value); } + assert(key == UNINITIALIZED_PTR); + assert(value == UNINITIALIZED_PTR); if (PyErr_Occurred()) { return NULL; } diff -Nru python3.12-3.12.0~rc2/Modules/_testcapi/exceptions.c python3.12-3.12.0/Modules/_testcapi/exceptions.c --- python3.12-3.12.0~rc2/Modules/_testcapi/exceptions.c 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Modules/_testcapi/exceptions.c 2023-10-02 11:48:14.000000000 +0000 @@ -121,12 +121,15 @@ PyObject *obj) /*[clinic end generated code: output=7a5ff5f6d3cf687f input=77ec686f1f95fa38]*/ { - PyObject *type; - PyObject *value; - PyObject *tb; + PyObject *type = UNINITIALIZED_PTR; + PyObject *value = UNINITIALIZED_PTR; + PyObject *tb = UNINITIALIZED_PTR; PyErr_SetObject(exc, obj); PyErr_Fetch(&type, &value, &tb); + assert(type != UNINITIALIZED_PTR); + assert(value != UNINITIALIZED_PTR); + assert(tb != UNINITIALIZED_PTR); Py_XDECREF(type); Py_XDECREF(tb); return value; @@ -245,7 +248,7 @@ PyObject *new_value, PyObject *new_tb) /*[clinic end generated code: output=b55fa35dec31300e input=ea9f19e0f55fe5b3]*/ { - PyObject *type, *value, *tb; + PyObject *type = UNINITIALIZED_PTR, *value = UNINITIALIZED_PTR, *tb = UNINITIALIZED_PTR; PyErr_GetExcInfo(&type, &value, &tb); Py_INCREF(new_type); diff -Nru python3.12-3.12.0~rc2/Modules/_testcapi/unicode.c python3.12-3.12.0/Modules/_testcapi/unicode.c --- python3.12-3.12.0~rc2/Modules/_testcapi/unicode.c 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Modules/_testcapi/unicode.c 2023-10-02 11:48:14.000000000 +0000 @@ -491,7 +491,7 @@ unicode_aswidecharstring(PyObject *self, PyObject *args) { PyObject *unicode, *result; - Py_ssize_t size = 100; + Py_ssize_t size = UNINITIALIZED_SIZE; wchar_t *buffer; if (!PyArg_ParseTuple(args, "O", &unicode)) @@ -499,8 +499,10 @@ NULLABLE(unicode); buffer = PyUnicode_AsWideCharString(unicode, &size); - if (buffer == NULL) + if (buffer == NULL) { + assert(size == UNINITIALIZED_SIZE); return NULL; + } result = PyUnicode_FromWideChar(buffer, size + 1); PyMem_Free(buffer); @@ -625,15 +627,17 @@ PyObject *unicode; Py_ssize_t buflen; const char *s; - Py_ssize_t size = -100; + Py_ssize_t size = UNINITIALIZED_SIZE; if (!PyArg_ParseTuple(args, "On", &unicode, &buflen)) return NULL; NULLABLE(unicode); s = PyUnicode_AsUTF8AndSize(unicode, &size); - if (s == NULL) + if (s == NULL) { + assert(size == UNINITIALIZED_SIZE); return NULL; + } return Py_BuildValue("(y#n)", s, buflen, size); } @@ -735,7 +739,7 @@ const char *data; Py_ssize_t size; const char *errors = NULL; - Py_ssize_t consumed; + Py_ssize_t consumed = UNINITIALIZED_SIZE; PyObject *result; if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors)) @@ -743,6 +747,7 @@ result = PyUnicode_DecodeUTF7Stateful(data, size, errors, &consumed); if (!result) { + assert(consumed == UNINITIALIZED_SIZE); return NULL; } return Py_BuildValue("(Nn)", result, consumed); @@ -769,7 +774,7 @@ const char *data; Py_ssize_t size; const char *errors = NULL; - Py_ssize_t consumed = 123456789; + Py_ssize_t consumed = UNINITIALIZED_SIZE; PyObject *result; if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors)) @@ -777,6 +782,7 @@ result = PyUnicode_DecodeUTF8Stateful(data, size, errors, &consumed); if (!result) { + assert(consumed == UNINITIALIZED_SIZE); return NULL; } return Py_BuildValue("(Nn)", result, consumed); @@ -797,7 +803,7 @@ const char *data; Py_ssize_t size; const char *errors = NULL; - int byteorder; + int byteorder = UNINITIALIZED_INT; PyObject *result; if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors)) @@ -817,8 +823,8 @@ const char *data; Py_ssize_t size; const char *errors = NULL; - int byteorder; - Py_ssize_t consumed; + int byteorder = UNINITIALIZED_INT; + Py_ssize_t consumed = UNINITIALIZED_SIZE; PyObject *result; if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors)) @@ -826,6 +832,7 @@ result = PyUnicode_DecodeUTF32Stateful(data, size, errors, &byteorder, &consumed); if (!result) { + assert(consumed == UNINITIALIZED_SIZE); return NULL; } return Py_BuildValue("(iNn)", byteorder, result, consumed); @@ -846,7 +853,7 @@ const char *data; Py_ssize_t size; const char *errors = NULL; - int byteorder = 0; + int byteorder = UNINITIALIZED_INT; PyObject *result; if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors)) @@ -866,8 +873,8 @@ const char *data; Py_ssize_t size; const char *errors = NULL; - int byteorder; - Py_ssize_t consumed; + int byteorder = UNINITIALIZED_INT; + Py_ssize_t consumed = UNINITIALIZED_SIZE; PyObject *result; if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors)) @@ -875,6 +882,7 @@ result = PyUnicode_DecodeUTF16Stateful(data, size, errors, &byteorder, &consumed); if (!result) { + assert(consumed == UNINITIALIZED_SIZE); return NULL; } return Py_BuildValue("(iNn)", byteorder, result, consumed); @@ -1028,7 +1036,7 @@ const char *data; Py_ssize_t size; const char *errors = NULL; - Py_ssize_t consumed; + Py_ssize_t consumed = UNINITIALIZED_SIZE; PyObject *result; if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors)) @@ -1036,6 +1044,7 @@ result = PyUnicode_DecodeMBCSStateful(data, size, errors, &consumed); if (!result) { + assert(consumed == UNINITIALIZED_SIZE); return NULL; } return Py_BuildValue("(Nn)", result, consumed); @@ -1049,7 +1058,7 @@ const char *data; Py_ssize_t size; const char *errors = NULL; - Py_ssize_t consumed; + Py_ssize_t consumed = UNINITIALIZED_SIZE; PyObject *result; if (!PyArg_ParseTuple(args, "iy#|z", &code_page, &data, &size, &errors)) @@ -1057,6 +1066,7 @@ result = PyUnicode_DecodeCodePageStateful(code_page, data, size, errors, &consumed); if (!result) { + assert(consumed == UNINITIALIZED_SIZE); return NULL; } return Py_BuildValue("(Nn)", result, consumed); diff -Nru python3.12-3.12.0~rc2/Modules/_testcapi/util.h python3.12-3.12.0/Modules/_testcapi/util.h --- python3.12-3.12.0~rc2/Modules/_testcapi/util.h 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Modules/_testcapi/util.h 2023-10-02 11:48:14.000000000 +0000 @@ -23,3 +23,10 @@ assert(!PyErr_Occurred()); \ return PyLong_FromSsize_t(_ret); \ } while (0) + +/* Marker to check that pointer value was set. */ +#define UNINITIALIZED_PTR ((void *)"uninitialized") +/* Marker to check that Py_ssize_t value was set. */ +#define UNINITIALIZED_SIZE ((Py_ssize_t)236892191) +/* Marker to check that integer value was set. */ +#define UNINITIALIZED_INT (63256717) diff -Nru python3.12-3.12.0~rc2/Modules/_testcapimodule.c python3.12-3.12.0/Modules/_testcapimodule.c --- python3.12-3.12.0~rc2/Modules/_testcapimodule.c 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Modules/_testcapimodule.c 2023-10-02 11:48:14.000000000 +0000 @@ -221,10 +221,13 @@ Py_DECREF(v); } + k = v = UNINITIALIZED_PTR; while (PyDict_Next(dict, &pos, &k, &v)) { PyObject *o; iterations++; + assert(k != UNINITIALIZED_PTR); + assert(v != UNINITIALIZED_PTR); i = PyLong_AS_LONG(v) + 1; o = PyLong_FromLong(i); if (o == NULL) @@ -234,7 +237,10 @@ return -1; } Py_DECREF(o); + k = v = UNINITIALIZED_PTR; } + assert(k == UNINITIALIZED_PTR); + assert(v == UNINITIALIZED_PTR); Py_DECREF(dict); @@ -2151,6 +2157,26 @@ Py_RETURN_NONE; } + +static PyObject * +decref_freed_object(PyObject *self, PyObject *Py_UNUSED(args)) +{ + PyObject *obj = PyUnicode_FromString("decref_freed_object"); + if (obj == NULL) { + return NULL; + } + assert(Py_REFCNT(obj) == 1); + + // Deallocate the memory + Py_DECREF(obj); + // obj is a now a dangling pointer + + // gh-109496: If Python is built in debug mode, Py_DECREF() must call + // _Py_NegativeRefcount() and abort Python. + Py_DECREF(obj); + + Py_RETURN_NONE; +} #endif @@ -3300,6 +3326,7 @@ {"bad_get", _PyCFunction_CAST(bad_get), METH_FASTCALL}, #ifdef Py_REF_DEBUG {"negative_refcount", negative_refcount, METH_NOARGS}, + {"decref_freed_object", decref_freed_object, METH_NOARGS}, #endif {"meth_varargs", meth_varargs, METH_VARARGS}, {"meth_varargs_keywords", _PyCFunction_CAST(meth_varargs_keywords), METH_VARARGS|METH_KEYWORDS}, diff -Nru python3.12-3.12.0~rc2/Objects/clinic/unicodeobject.c.h python3.12-3.12.0/Objects/clinic/unicodeobject.c.h --- python3.12-3.12.0~rc2/Objects/clinic/unicodeobject.c.h 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Objects/clinic/unicodeobject.c.h 2023-10-02 11:48:14.000000000 +0000 @@ -934,7 +934,7 @@ " The separator used to split the string.\n" "\n" " When set to None (the default value), will split on any whitespace\n" -" character (including \\\\n \\\\r \\\\t \\\\f and spaces) and will discard\n" +" character (including \\n \\r \\t \\f and spaces) and will discard\n" " empty strings from the result.\n" " maxsplit\n" " Maximum number of splits (starting from the left).\n" @@ -1058,7 +1058,7 @@ " The separator used to split the string.\n" "\n" " When set to None (the default value), will split on any whitespace\n" -" character (including \\\\n \\\\r \\\\t \\\\f and spaces) and will discard\n" +" character (including \\n \\r \\t \\f and spaces) and will discard\n" " empty strings from the result.\n" " maxsplit\n" " Maximum number of splits (starting from the left).\n" @@ -1497,4 +1497,4 @@ exit: return return_value; } -/*[clinic end generated code: output=05d942840635dadf input=a9049054013a1b77]*/ +/*[clinic end generated code: output=32edbbf75dc8a03b input=a9049054013a1b77]*/ diff -Nru python3.12-3.12.0~rc2/Objects/frameobject.c python3.12-3.12.0/Objects/frameobject.c --- python3.12-3.12.0~rc2/Objects/frameobject.c 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Objects/frameobject.c 2023-10-02 11:48:14.000000000 +0000 @@ -24,10 +24,16 @@ static PyObject * frame_getlocals(PyFrameObject *f, void *closure) { - if (PyFrame_FastToLocalsWithError(f) < 0) + if (f == NULL) { + PyErr_BadInternalCall(); return NULL; - PyObject *locals = f->f_frame->f_locals; - return Py_NewRef(locals); + } + assert(!_PyFrame_IsIncomplete(f->f_frame)); + PyObject *locals = _PyFrame_GetLocals(f->f_frame, 1); + if (locals) { + f->f_fast_as_locals = 1; + } + return locals; } int @@ -1351,11 +1357,11 @@ int PyFrame_FastToLocalsWithError(PyFrameObject *f) { - assert(!_PyFrame_IsIncomplete(f->f_frame)); if (f == NULL) { PyErr_BadInternalCall(); return -1; } + assert(!_PyFrame_IsIncomplete(f->f_frame)); int err = _PyFrame_FastToLocalsWithError(f->f_frame); if (err == 0) { f->f_fast_as_locals = 1; diff -Nru python3.12-3.12.0~rc2/Objects/unicodeobject.c python3.12-3.12.0/Objects/unicodeobject.c --- python3.12-3.12.0~rc2/Objects/unicodeobject.c 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Objects/unicodeobject.c 2023-10-02 11:48:14.000000000 +0000 @@ -12361,7 +12361,7 @@ The separator used to split the string. When set to None (the default value), will split on any whitespace - character (including \\n \\r \\t \\f and spaces) and will discard + character (including \n \r \t \f and spaces) and will discard empty strings from the result. maxsplit: Py_ssize_t = -1 Maximum number of splits (starting from the left). @@ -12377,7 +12377,7 @@ static PyObject * unicode_split_impl(PyObject *self, PyObject *sep, Py_ssize_t maxsplit) -/*[clinic end generated code: output=3a65b1db356948dc input=906d953b44efc43b]*/ +/*[clinic end generated code: output=3a65b1db356948dc input=07b9040d98c5fe8d]*/ { if (sep == Py_None) return split(self, NULL, maxsplit); diff -Nru python3.12-3.12.0~rc2/Parser/parser.c python3.12-3.12.0/Parser/parser.c --- python3.12-3.12.0~rc2/Parser/parser.c 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Parser/parser.c 2023-10-02 11:48:14.000000000 +0000 @@ -481,65 +481,65 @@ #define _tmp_157_type 1400 #define _tmp_158_type 1401 #define _tmp_159_type 1402 -#define _tmp_160_type 1403 +#define _loop0_160_type 1403 #define _loop0_161_type 1404 #define _loop0_162_type 1405 -#define _loop0_163_type 1406 +#define _tmp_163_type 1406 #define _tmp_164_type 1407 #define _tmp_165_type 1408 #define _tmp_166_type 1409 #define _tmp_167_type 1410 -#define _tmp_168_type 1411 +#define _loop0_168_type 1411 #define _loop0_169_type 1412 #define _loop0_170_type 1413 -#define _loop0_171_type 1414 -#define _loop1_172_type 1415 -#define _tmp_173_type 1416 -#define _loop0_174_type 1417 -#define _tmp_175_type 1418 -#define _loop0_176_type 1419 -#define _loop1_177_type 1420 +#define _loop1_171_type 1414 +#define _tmp_172_type 1415 +#define _loop0_173_type 1416 +#define _tmp_174_type 1417 +#define _loop0_175_type 1418 +#define _loop1_176_type 1419 +#define _tmp_177_type 1420 #define _tmp_178_type 1421 #define _tmp_179_type 1422 -#define _tmp_180_type 1423 -#define _loop0_181_type 1424 +#define _loop0_180_type 1423 +#define _tmp_181_type 1424 #define _tmp_182_type 1425 -#define _tmp_183_type 1426 -#define _loop1_184_type 1427 -#define _tmp_185_type 1428 +#define _loop1_183_type 1426 +#define _tmp_184_type 1427 +#define _loop0_185_type 1428 #define _loop0_186_type 1429 #define _loop0_187_type 1430 -#define _loop0_188_type 1431 -#define _loop0_190_type 1432 -#define _gather_189_type 1433 -#define _tmp_191_type 1434 -#define _loop0_192_type 1435 -#define _tmp_193_type 1436 -#define _loop0_194_type 1437 +#define _loop0_189_type 1431 +#define _gather_188_type 1432 +#define _tmp_190_type 1433 +#define _loop0_191_type 1434 +#define _tmp_192_type 1435 +#define _loop0_193_type 1436 +#define _loop1_194_type 1437 #define _loop1_195_type 1438 -#define _loop1_196_type 1439 +#define _tmp_196_type 1439 #define _tmp_197_type 1440 -#define _tmp_198_type 1441 -#define _loop0_199_type 1442 +#define _loop0_198_type 1441 +#define _tmp_199_type 1442 #define _tmp_200_type 1443 #define _tmp_201_type 1444 -#define _tmp_202_type 1445 -#define _loop0_204_type 1446 -#define _gather_203_type 1447 -#define _loop0_206_type 1448 -#define _gather_205_type 1449 -#define _loop0_208_type 1450 -#define _gather_207_type 1451 -#define _loop0_210_type 1452 -#define _gather_209_type 1453 -#define _loop0_212_type 1454 -#define _gather_211_type 1455 -#define _tmp_213_type 1456 -#define _loop0_214_type 1457 -#define _loop1_215_type 1458 -#define _tmp_216_type 1459 -#define _loop0_217_type 1460 -#define _loop1_218_type 1461 +#define _loop0_203_type 1445 +#define _gather_202_type 1446 +#define _loop0_205_type 1447 +#define _gather_204_type 1448 +#define _loop0_207_type 1449 +#define _gather_206_type 1450 +#define _loop0_209_type 1451 +#define _gather_208_type 1452 +#define _loop0_211_type 1453 +#define _gather_210_type 1454 +#define _tmp_212_type 1455 +#define _loop0_213_type 1456 +#define _loop1_214_type 1457 +#define _tmp_215_type 1458 +#define _loop0_216_type 1459 +#define _loop1_217_type 1460 +#define _tmp_218_type 1461 #define _tmp_219_type 1462 #define _tmp_220_type 1463 #define _tmp_221_type 1464 @@ -549,9 +549,9 @@ #define _tmp_225_type 1468 #define _tmp_226_type 1469 #define _tmp_227_type 1470 -#define _tmp_228_type 1471 -#define _loop0_230_type 1472 -#define _gather_229_type 1473 +#define _loop0_229_type 1471 +#define _gather_228_type 1472 +#define _tmp_230_type 1473 #define _tmp_231_type 1474 #define _tmp_232_type 1475 #define _tmp_233_type 1476 @@ -564,8 +564,8 @@ #define _tmp_240_type 1483 #define _tmp_241_type 1484 #define _tmp_242_type 1485 -#define _tmp_243_type 1486 -#define _loop0_244_type 1487 +#define _loop0_243_type 1486 +#define _tmp_244_type 1487 #define _tmp_245_type 1488 #define _tmp_246_type 1489 #define _tmp_247_type 1490 @@ -597,7 +597,6 @@ #define _tmp_273_type 1516 #define _tmp_274_type 1517 #define _tmp_275_type 1518 -#define _tmp_276_type 1519 static mod_ty file_rule(Parser *p); static mod_ty interactive_rule(Parser *p); @@ -1002,65 +1001,65 @@ static void *_tmp_157_rule(Parser *p); static void *_tmp_158_rule(Parser *p); static void *_tmp_159_rule(Parser *p); -static void *_tmp_160_rule(Parser *p); +static asdl_seq *_loop0_160_rule(Parser *p); static asdl_seq *_loop0_161_rule(Parser *p); static asdl_seq *_loop0_162_rule(Parser *p); -static asdl_seq *_loop0_163_rule(Parser *p); +static void *_tmp_163_rule(Parser *p); static void *_tmp_164_rule(Parser *p); static void *_tmp_165_rule(Parser *p); static void *_tmp_166_rule(Parser *p); static void *_tmp_167_rule(Parser *p); -static void *_tmp_168_rule(Parser *p); +static asdl_seq *_loop0_168_rule(Parser *p); static asdl_seq *_loop0_169_rule(Parser *p); static asdl_seq *_loop0_170_rule(Parser *p); -static asdl_seq *_loop0_171_rule(Parser *p); -static asdl_seq *_loop1_172_rule(Parser *p); -static void *_tmp_173_rule(Parser *p); -static asdl_seq *_loop0_174_rule(Parser *p); -static void *_tmp_175_rule(Parser *p); -static asdl_seq *_loop0_176_rule(Parser *p); -static asdl_seq *_loop1_177_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_174_rule(Parser *p); +static asdl_seq *_loop0_175_rule(Parser *p); +static asdl_seq *_loop1_176_rule(Parser *p); +static void *_tmp_177_rule(Parser *p); static void *_tmp_178_rule(Parser *p); static void *_tmp_179_rule(Parser *p); -static void *_tmp_180_rule(Parser *p); -static asdl_seq *_loop0_181_rule(Parser *p); +static asdl_seq *_loop0_180_rule(Parser *p); +static void *_tmp_181_rule(Parser *p); static void *_tmp_182_rule(Parser *p); -static void *_tmp_183_rule(Parser *p); -static asdl_seq *_loop1_184_rule(Parser *p); -static void *_tmp_185_rule(Parser *p); +static asdl_seq *_loop1_183_rule(Parser *p); +static void *_tmp_184_rule(Parser *p); +static asdl_seq *_loop0_185_rule(Parser *p); static asdl_seq *_loop0_186_rule(Parser *p); static asdl_seq *_loop0_187_rule(Parser *p); -static asdl_seq *_loop0_188_rule(Parser *p); -static asdl_seq *_loop0_190_rule(Parser *p); -static asdl_seq *_gather_189_rule(Parser *p); -static void *_tmp_191_rule(Parser *p); -static asdl_seq *_loop0_192_rule(Parser *p); -static void *_tmp_193_rule(Parser *p); -static asdl_seq *_loop0_194_rule(Parser *p); +static asdl_seq *_loop0_189_rule(Parser *p); +static asdl_seq *_gather_188_rule(Parser *p); +static void *_tmp_190_rule(Parser *p); +static asdl_seq *_loop0_191_rule(Parser *p); +static void *_tmp_192_rule(Parser *p); +static asdl_seq *_loop0_193_rule(Parser *p); +static asdl_seq *_loop1_194_rule(Parser *p); static asdl_seq *_loop1_195_rule(Parser *p); -static asdl_seq *_loop1_196_rule(Parser *p); +static void *_tmp_196_rule(Parser *p); static void *_tmp_197_rule(Parser *p); -static void *_tmp_198_rule(Parser *p); -static asdl_seq *_loop0_199_rule(Parser *p); +static asdl_seq *_loop0_198_rule(Parser *p); +static void *_tmp_199_rule(Parser *p); static void *_tmp_200_rule(Parser *p); static void *_tmp_201_rule(Parser *p); -static void *_tmp_202_rule(Parser *p); -static asdl_seq *_loop0_204_rule(Parser *p); -static asdl_seq *_gather_203_rule(Parser *p); -static asdl_seq *_loop0_206_rule(Parser *p); -static asdl_seq *_gather_205_rule(Parser *p); -static asdl_seq *_loop0_208_rule(Parser *p); -static asdl_seq *_gather_207_rule(Parser *p); -static asdl_seq *_loop0_210_rule(Parser *p); -static asdl_seq *_gather_209_rule(Parser *p); -static asdl_seq *_loop0_212_rule(Parser *p); -static asdl_seq *_gather_211_rule(Parser *p); -static void *_tmp_213_rule(Parser *p); -static asdl_seq *_loop0_214_rule(Parser *p); -static asdl_seq *_loop1_215_rule(Parser *p); -static void *_tmp_216_rule(Parser *p); -static asdl_seq *_loop0_217_rule(Parser *p); -static asdl_seq *_loop1_218_rule(Parser *p); +static asdl_seq *_loop0_203_rule(Parser *p); +static asdl_seq *_gather_202_rule(Parser *p); +static asdl_seq *_loop0_205_rule(Parser *p); +static asdl_seq *_gather_204_rule(Parser *p); +static asdl_seq *_loop0_207_rule(Parser *p); +static asdl_seq *_gather_206_rule(Parser *p); +static asdl_seq *_loop0_209_rule(Parser *p); +static asdl_seq *_gather_208_rule(Parser *p); +static asdl_seq *_loop0_211_rule(Parser *p); +static asdl_seq *_gather_210_rule(Parser *p); +static void *_tmp_212_rule(Parser *p); +static asdl_seq *_loop0_213_rule(Parser *p); +static asdl_seq *_loop1_214_rule(Parser *p); +static void *_tmp_215_rule(Parser *p); +static asdl_seq *_loop0_216_rule(Parser *p); +static asdl_seq *_loop1_217_rule(Parser *p); +static void *_tmp_218_rule(Parser *p); static void *_tmp_219_rule(Parser *p); static void *_tmp_220_rule(Parser *p); static void *_tmp_221_rule(Parser *p); @@ -1070,9 +1069,9 @@ static void *_tmp_225_rule(Parser *p); static void *_tmp_226_rule(Parser *p); static void *_tmp_227_rule(Parser *p); -static void *_tmp_228_rule(Parser *p); -static asdl_seq *_loop0_230_rule(Parser *p); -static asdl_seq *_gather_229_rule(Parser *p); +static asdl_seq *_loop0_229_rule(Parser *p); +static asdl_seq *_gather_228_rule(Parser *p); +static void *_tmp_230_rule(Parser *p); static void *_tmp_231_rule(Parser *p); static void *_tmp_232_rule(Parser *p); static void *_tmp_233_rule(Parser *p); @@ -1085,8 +1084,8 @@ static void *_tmp_240_rule(Parser *p); static void *_tmp_241_rule(Parser *p); static void *_tmp_242_rule(Parser *p); -static void *_tmp_243_rule(Parser *p); -static asdl_seq *_loop0_244_rule(Parser *p); +static asdl_seq *_loop0_243_rule(Parser *p); +static void *_tmp_244_rule(Parser *p); static void *_tmp_245_rule(Parser *p); static void *_tmp_246_rule(Parser *p); static void *_tmp_247_rule(Parser *p); @@ -1118,7 +1117,6 @@ static void *_tmp_273_rule(Parser *p); static void *_tmp_274_rule(Parser *p); static void *_tmp_275_rule(Parser *p); -static void *_tmp_276_rule(Parser *p); // file: statements? $ @@ -20274,7 +20272,7 @@ // invalid_expression: // | !(NAME STRING | SOFT_KEYWORD) disjunction expression_without_invalid // | disjunction 'if' disjunction !('else' | ':') -// | 'lambda' lambda_params? ':' &(FSTRING_MIDDLE | fstring_replacement_field) +// | 'lambda' lambda_params? ':' &FSTRING_MIDDLE static void * invalid_expression_rule(Parser *p) { @@ -20348,12 +20346,12 @@ D(fprintf(stderr, "%*c%s invalid_expression[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "disjunction 'if' disjunction !('else' | ':')")); } - { // 'lambda' lambda_params? ':' &(FSTRING_MIDDLE | fstring_replacement_field) + { // 'lambda' lambda_params? ':' &FSTRING_MIDDLE if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'lambda' lambda_params? ':' &(FSTRING_MIDDLE | fstring_replacement_field)")); + D(fprintf(stderr, "%*c> invalid_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'lambda' lambda_params? ':' &FSTRING_MIDDLE")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings Token * a; @@ -20365,10 +20363,10 @@ && (b = _PyPegen_expect_token(p, 11)) // token=':' && - _PyPegen_lookahead(1, _tmp_157_rule, p) + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, FSTRING_MIDDLE) // token=FSTRING_MIDDLE ) { - D(fprintf(stderr, "%*c+ invalid_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'lambda' lambda_params? ':' &(FSTRING_MIDDLE | fstring_replacement_field)")); + D(fprintf(stderr, "%*c+ invalid_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'lambda' lambda_params? ':' &FSTRING_MIDDLE")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "f-string: lambda expressions are not allowed without parentheses" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -20379,7 +20377,7 @@ } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_expression[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'lambda' lambda_params? ':' &(FSTRING_MIDDLE | fstring_replacement_field)")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'lambda' lambda_params? ':' &FSTRING_MIDDLE")); } _res = NULL; done: @@ -20453,7 +20451,7 @@ && (b = bitwise_or_rule(p)) // bitwise_or && - _PyPegen_lookahead(0, _tmp_158_rule, p) + _PyPegen_lookahead(0, _tmp_157_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_named_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '=' bitwise_or !('=' | ':=')")); @@ -20479,7 +20477,7 @@ Token * b; expr_ty bitwise_or_var; if ( - _PyPegen_lookahead(0, _tmp_159_rule, p) + _PyPegen_lookahead(0, _tmp_158_rule, p) && (a = bitwise_or_rule(p)) // bitwise_or && @@ -20487,7 +20485,7 @@ && (bitwise_or_var = bitwise_or_rule(p)) // bitwise_or && - _PyPegen_lookahead(0, _tmp_160_rule, p) + _PyPegen_lookahead(0, _tmp_159_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 !('=' | ':=')")); @@ -20567,7 +20565,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_161_var; + asdl_seq * _loop0_160_var; expr_ty a; expr_ty expression_var; if ( @@ -20575,7 +20573,7 @@ && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_loop0_161_var = _loop0_161_rule(p)) // star_named_expressions* + (_loop0_160_var = _loop0_160_rule(p)) // star_named_expressions* && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' && @@ -20632,10 +20630,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_162_var; + asdl_seq * _loop0_161_var; expr_ty a; if ( - (_loop0_162_var = _loop0_162_rule(p)) // ((star_targets '='))* + (_loop0_161_var = _loop0_161_rule(p)) // ((star_targets '='))* && (a = star_expressions_rule(p)) // star_expressions && @@ -20662,10 +20660,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_163_var; + asdl_seq * _loop0_162_var; expr_ty a; if ( - (_loop0_163_var = _loop0_163_rule(p)) // ((star_targets '='))* + (_loop0_162_var = _loop0_162_rule(p)) // ((star_targets '='))* && (a = yield_expr_rule(p)) // yield_expr && @@ -20691,7 +20689,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_164_var; + void *_tmp_163_var; expr_ty a; AugOperator* augassign_var; if ( @@ -20699,7 +20697,7 @@ && (augassign_var = augassign_rule(p)) // augassign && - (_tmp_164_var = _tmp_164_rule(p)) // yield_expr | star_expressions + (_tmp_163_var = _tmp_163_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)")); @@ -20921,11 +20919,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_165_var; + void *_tmp_164_var; expr_ty a; asdl_comprehension_seq* for_if_clauses_var; if ( - (_tmp_165_var = _tmp_165_rule(p)) // '[' | '(' | '{' + (_tmp_164_var = _tmp_164_rule(p)) // '[' | '(' | '{' && (a = starred_expression_rule(p)) // starred_expression && @@ -20952,12 +20950,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_166_var; + void *_tmp_165_var; expr_ty a; asdl_expr_seq* b; asdl_comprehension_seq* for_if_clauses_var; if ( - (_tmp_166_var = _tmp_166_rule(p)) // '[' | '{' + (_tmp_165_var = _tmp_165_rule(p)) // '[' | '{' && (a = star_named_expression_rule(p)) // star_named_expression && @@ -20987,12 +20985,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_167_var; + void *_tmp_166_var; expr_ty a; Token * b; asdl_comprehension_seq* for_if_clauses_var; if ( - (_tmp_167_var = _tmp_167_rule(p)) // '[' | '{' + (_tmp_166_var = _tmp_166_rule(p)) // '[' | '{' && (a = star_named_expression_rule(p)) // star_named_expression && @@ -21127,13 +21125,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_169_var; - void *_tmp_168_var; + asdl_seq * _loop0_168_var; + void *_tmp_167_var; Token * a; if ( - (_tmp_168_var = _tmp_168_rule(p)) // slash_no_default | slash_with_default + (_tmp_167_var = _tmp_167_rule(p)) // slash_no_default | slash_with_default && - (_loop0_169_var = _loop0_169_rule(p)) // param_maybe_default* + (_loop0_168_var = _loop0_168_rule(p)) // param_maybe_default* && (a = _PyPegen_expect_token(p, 17)) // token='/' ) @@ -21157,7 +21155,7 @@ return NULL; } D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default? param_no_default* invalid_parameters_helper param_no_default")); - asdl_seq * _loop0_170_var; + asdl_seq * _loop0_169_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings arg_ty a; @@ -21165,7 +21163,7 @@ if ( (_opt_var = slash_no_default_rule(p), !p->error_indicator) // slash_no_default? && - (_loop0_170_var = _loop0_170_rule(p)) // param_no_default* + (_loop0_169_var = _loop0_169_rule(p)) // param_no_default* && (invalid_parameters_helper_var = invalid_parameters_helper_rule(p)) // invalid_parameters_helper && @@ -21191,18 +21189,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_171_var; - asdl_seq * _loop1_172_var; + asdl_seq * _loop0_170_var; + asdl_seq * _loop1_171_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings Token * a; Token * b; if ( - (_loop0_171_var = _loop0_171_rule(p)) // param_no_default* + (_loop0_170_var = _loop0_170_rule(p)) // param_no_default* && (a = _PyPegen_expect_token(p, 7)) // token='(' && - (_loop1_172_var = _loop1_172_rule(p)) // param_no_default+ + (_loop1_171_var = _loop1_171_rule(p)) // param_no_default+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -21229,22 +21227,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_174_var; - asdl_seq * _loop0_176_var; + asdl_seq * _loop0_173_var; + asdl_seq * _loop0_175_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings - void *_tmp_175_var; + void *_tmp_174_var; Token * a; if ( - (_opt_var = _tmp_173_rule(p), !p->error_indicator) // [(slash_no_default | slash_with_default)] + (_opt_var = _tmp_172_rule(p), !p->error_indicator) // [(slash_no_default | slash_with_default)] && - (_loop0_174_var = _loop0_174_rule(p)) // param_maybe_default* + (_loop0_173_var = _loop0_173_rule(p)) // param_maybe_default* && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_175_var = _tmp_175_rule(p)) // ',' | param_no_default + (_tmp_174_var = _tmp_174_rule(p)) // ',' | param_no_default && - (_loop0_176_var = _loop0_176_rule(p)) // param_maybe_default* + (_loop0_175_var = _loop0_175_rule(p)) // param_maybe_default* && (a = _PyPegen_expect_token(p, 17)) // token='/' ) @@ -21269,10 +21267,10 @@ } D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default+ '/' '*'")); Token * _literal; - asdl_seq * _loop1_177_var; + asdl_seq * _loop1_176_var; Token * a; if ( - (_loop1_177_var = _loop1_177_rule(p)) // param_maybe_default+ + (_loop1_176_var = _loop1_176_rule(p)) // param_maybe_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -21321,7 +21319,7 @@ if ( (a = _PyPegen_expect_token(p, 22)) // token='=' && - _PyPegen_lookahead(1, _tmp_178_rule, p) + _PyPegen_lookahead(1, _tmp_177_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'=' &(')' | ',')")); @@ -21366,12 +21364,12 @@ return NULL; } D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); - void *_tmp_179_var; + void *_tmp_178_var; Token * a; if ( (a = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_179_var = _tmp_179_rule(p)) // ')' | ',' (')' | '**') + (_tmp_178_var = _tmp_178_rule(p)) // ')' | ',' (')' | '**') ) { D(fprintf(stderr, "%*c+ invalid_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); @@ -21454,20 +21452,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_181_var; - void *_tmp_180_var; - void *_tmp_182_var; + asdl_seq * _loop0_180_var; + void *_tmp_179_var; + void *_tmp_181_var; Token * a; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_180_var = _tmp_180_rule(p)) // param_no_default | ',' + (_tmp_179_var = _tmp_179_rule(p)) // param_no_default | ',' && - (_loop0_181_var = _loop0_181_rule(p)) // param_maybe_default* + (_loop0_180_var = _loop0_180_rule(p)) // param_maybe_default* && (a = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_182_var = _tmp_182_rule(p)) // param_no_default | ',' + (_tmp_181_var = _tmp_181_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 | ',')")); @@ -21582,7 +21580,7 @@ && (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' && - (a = (Token*)_tmp_183_rule(p)) // '*' | '**' | '/' + (a = (Token*)_tmp_182_rule(p)) // '*' | '**' | '/' ) { D(fprintf(stderr, "%*c+ invalid_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' param ',' ('*' | '**' | '/')")); @@ -21647,13 +21645,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_184_var; + asdl_seq * _loop1_183_var; if ( - (_loop1_184_var = _loop1_184_rule(p)) // param_with_default+ + (_loop1_183_var = _loop1_183_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_184_var; + _res = _loop1_183_var; goto done; } p->mark = _mark; @@ -21718,13 +21716,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_186_var; - void *_tmp_185_var; + asdl_seq * _loop0_185_var; + void *_tmp_184_var; Token * a; if ( - (_tmp_185_var = _tmp_185_rule(p)) // lambda_slash_no_default | lambda_slash_with_default + (_tmp_184_var = _tmp_184_rule(p)) // lambda_slash_no_default | lambda_slash_with_default && - (_loop0_186_var = _loop0_186_rule(p)) // lambda_param_maybe_default* + (_loop0_185_var = _loop0_185_rule(p)) // lambda_param_maybe_default* && (a = _PyPegen_expect_token(p, 17)) // token='/' ) @@ -21748,7 +21746,7 @@ return NULL; } D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default? lambda_param_no_default* invalid_lambda_parameters_helper lambda_param_no_default")); - asdl_seq * _loop0_187_var; + asdl_seq * _loop0_186_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings arg_ty a; @@ -21756,7 +21754,7 @@ if ( (_opt_var = lambda_slash_no_default_rule(p), !p->error_indicator) // lambda_slash_no_default? && - (_loop0_187_var = _loop0_187_rule(p)) // lambda_param_no_default* + (_loop0_186_var = _loop0_186_rule(p)) // lambda_param_no_default* && (invalid_lambda_parameters_helper_var = invalid_lambda_parameters_helper_rule(p)) // invalid_lambda_parameters_helper && @@ -21782,18 +21780,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_189_var; - asdl_seq * _loop0_188_var; + asdl_seq * _gather_188_var; + asdl_seq * _loop0_187_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings Token * a; Token * b; if ( - (_loop0_188_var = _loop0_188_rule(p)) // lambda_param_no_default* + (_loop0_187_var = _loop0_187_rule(p)) // lambda_param_no_default* && (a = _PyPegen_expect_token(p, 7)) // token='(' && - (_gather_189_var = _gather_189_rule(p)) // ','.lambda_param+ + (_gather_188_var = _gather_188_rule(p)) // ','.lambda_param+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -21820,22 +21818,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_192_var; - asdl_seq * _loop0_194_var; + asdl_seq * _loop0_191_var; + asdl_seq * _loop0_193_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings - void *_tmp_193_var; + void *_tmp_192_var; Token * a; if ( - (_opt_var = _tmp_191_rule(p), !p->error_indicator) // [(lambda_slash_no_default | lambda_slash_with_default)] + (_opt_var = _tmp_190_rule(p), !p->error_indicator) // [(lambda_slash_no_default | lambda_slash_with_default)] && - (_loop0_192_var = _loop0_192_rule(p)) // lambda_param_maybe_default* + (_loop0_191_var = _loop0_191_rule(p)) // lambda_param_maybe_default* && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_193_var = _tmp_193_rule(p)) // ',' | lambda_param_no_default + (_tmp_192_var = _tmp_192_rule(p)) // ',' | lambda_param_no_default && - (_loop0_194_var = _loop0_194_rule(p)) // lambda_param_maybe_default* + (_loop0_193_var = _loop0_193_rule(p)) // lambda_param_maybe_default* && (a = _PyPegen_expect_token(p, 17)) // token='/' ) @@ -21860,10 +21858,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_195_var; + asdl_seq * _loop1_194_var; Token * a; if ( - (_loop1_195_var = _loop1_195_rule(p)) // lambda_param_maybe_default+ + (_loop1_194_var = _loop1_194_rule(p)) // lambda_param_maybe_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -21934,13 +21932,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_196_var; + asdl_seq * _loop1_195_var; if ( - (_loop1_196_var = _loop1_196_rule(p)) // lambda_param_with_default+ + (_loop1_195_var = _loop1_195_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_196_var; + _res = _loop1_195_var; goto done; } p->mark = _mark; @@ -21976,11 +21974,11 @@ } D(fprintf(stderr, "%*c> invalid_lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); Token * _literal; - void *_tmp_197_var; + void *_tmp_196_var; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_197_var = _tmp_197_rule(p)) // ':' | ',' (':' | '**') + (_tmp_196_var = _tmp_196_rule(p)) // ':' | ',' (':' | '**') ) { D(fprintf(stderr, "%*c+ invalid_lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); @@ -22033,20 +22031,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_199_var; - void *_tmp_198_var; - void *_tmp_200_var; + asdl_seq * _loop0_198_var; + void *_tmp_197_var; + void *_tmp_199_var; Token * a; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_198_var = _tmp_198_rule(p)) // lambda_param_no_default | ',' + (_tmp_197_var = _tmp_197_rule(p)) // lambda_param_no_default | ',' && - (_loop0_199_var = _loop0_199_rule(p)) // lambda_param_maybe_default* + (_loop0_198_var = _loop0_198_rule(p)) // lambda_param_maybe_default* && (a = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_200_var = _tmp_200_rule(p)) // lambda_param_no_default | ',' + (_tmp_199_var = _tmp_199_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 | ',')")); @@ -22164,7 +22162,7 @@ && (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' && - (a = (Token*)_tmp_201_rule(p)) // '*' | '**' | '/' + (a = (Token*)_tmp_200_rule(p)) // '*' | '**' | '/' ) { D(fprintf(stderr, "%*c+ invalid_lambda_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' lambda_param ',' ('*' | '**' | '/')")); @@ -22270,7 +22268,7 @@ && (a = expression_rule(p)) // expression && - _PyPegen_lookahead(1, _tmp_202_rule, p) + _PyPegen_lookahead(1, _tmp_201_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_with_item[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression 'as' expression &(',' | ')' | ':')")); @@ -22443,14 +22441,14 @@ return NULL; } D(fprintf(stderr, "%*c> invalid_import[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'import' ','.dotted_name+ 'from' dotted_name")); - asdl_seq * _gather_203_var; + asdl_seq * _gather_202_var; Token * _keyword; Token * a; expr_ty dotted_name_var; if ( (a = _PyPegen_expect_token(p, 607)) // token='import' && - (_gather_203_var = _gather_203_rule(p)) // ','.dotted_name+ + (_gather_202_var = _gather_202_rule(p)) // ','.dotted_name+ && (_keyword = _PyPegen_expect_token(p, 608)) // token='from' && @@ -22546,7 +22544,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_205_var; + asdl_seq * _gather_204_var; Token * _keyword; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings @@ -22556,7 +22554,7 @@ && (_keyword = _PyPegen_expect_token(p, 615)) // token='with' && - (_gather_205_var = _gather_205_rule(p)) // ','.(expression ['as' star_target])+ + (_gather_204_var = _gather_204_rule(p)) // ','.(expression ['as' star_target])+ && (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) @@ -22580,7 +22578,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_207_var; + asdl_seq * _gather_206_var; Token * _keyword; Token * _literal; Token * _literal_1; @@ -22596,7 +22594,7 @@ && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (_gather_207_var = _gather_207_rule(p)) // ','.(expressions ['as' star_target])+ + (_gather_206_var = _gather_206_rule(p)) // ','.(expressions ['as' star_target])+ && (_opt_var_1 = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -22645,7 +22643,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_209_var; + asdl_seq * _gather_208_var; Token * _literal; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings @@ -22656,7 +22654,7 @@ && (a = _PyPegen_expect_token(p, 615)) // token='with' && - (_gather_209_var = _gather_209_rule(p)) // ','.(expression ['as' star_target])+ + (_gather_208_var = _gather_208_rule(p)) // ','.(expression ['as' star_target])+ && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -22684,7 +22682,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_211_var; + asdl_seq * _gather_210_var; Token * _literal; Token * _literal_1; Token * _literal_2; @@ -22701,7 +22699,7 @@ && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (_gather_211_var = _gather_211_rule(p)) // ','.(expressions ['as' star_target])+ + (_gather_210_var = _gather_210_rule(p)) // ','.(expressions ['as' star_target])+ && (_opt_var_1 = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -22798,7 +22796,7 @@ && (block_var = block_rule(p)) // block && - _PyPegen_lookahead(0, _tmp_213_rule, p) + _PyPegen_lookahead(0, _tmp_212_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_try_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'try' ':' block !('except' | 'finally')")); @@ -22823,8 +22821,8 @@ Token * _keyword; Token * _literal; Token * _literal_1; - asdl_seq * _loop0_214_var; - asdl_seq * _loop1_215_var; + asdl_seq * _loop0_213_var; + asdl_seq * _loop1_214_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings Token * a; @@ -22835,9 +22833,9 @@ && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && - (_loop0_214_var = _loop0_214_rule(p)) // block* + (_loop0_213_var = _loop0_213_rule(p)) // block* && - (_loop1_215_var = _loop1_215_rule(p)) // except_block+ + (_loop1_214_var = _loop1_214_rule(p)) // except_block+ && (a = _PyPegen_expect_token(p, 637)) // token='except' && @@ -22845,7 +22843,7 @@ && (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_216_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var = _tmp_215_rule(p), !p->error_indicator) // ['as' NAME] && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' ) @@ -22872,8 +22870,8 @@ Token * _keyword; Token * _literal; Token * _literal_1; - asdl_seq * _loop0_217_var; - asdl_seq * _loop1_218_var; + asdl_seq * _loop0_216_var; + asdl_seq * _loop1_217_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings Token * a; @@ -22882,13 +22880,13 @@ && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && - (_loop0_217_var = _loop0_217_rule(p)) // block* + (_loop0_216_var = _loop0_216_rule(p)) // block* && - (_loop1_218_var = _loop1_218_rule(p)) // except_star_block+ + (_loop1_217_var = _loop1_217_rule(p)) // except_star_block+ && (a = _PyPegen_expect_token(p, 637)) // token='except' && - (_opt_var = _tmp_219_rule(p), !p->error_indicator) // [expression ['as' NAME]] + (_opt_var = _tmp_218_rule(p), !p->error_indicator) // [expression ['as' NAME]] && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' ) @@ -22955,7 +22953,7 @@ && (expressions_var = expressions_rule(p)) // expressions && - (_opt_var_1 = _tmp_220_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var_1 = _tmp_219_rule(p), !p->error_indicator) // ['as' NAME] && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' ) @@ -22993,7 +22991,7 @@ && (expression_var = expression_rule(p)) // expression && - (_opt_var_1 = _tmp_221_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var_1 = _tmp_220_rule(p), !p->error_indicator) // ['as' NAME] && (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) @@ -23045,14 +23043,14 @@ } D(fprintf(stderr, "%*c> invalid_except_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' '*' (NEWLINE | ':')")); Token * _literal; - void *_tmp_222_var; + void *_tmp_221_var; Token * a; if ( (a = _PyPegen_expect_token(p, 637)) // token='except' && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_222_var = _tmp_222_rule(p)) // NEWLINE | ':' + (_tmp_221_var = _tmp_221_rule(p)) // NEWLINE | ':' ) { D(fprintf(stderr, "%*c+ invalid_except_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' '*' (NEWLINE | ':')")); @@ -23157,7 +23155,7 @@ && (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_223_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var = _tmp_222_rule(p), !p->error_indicator) // ['as' NAME] && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -23251,7 +23249,7 @@ && (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_224_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var = _tmp_223_rule(p), !p->error_indicator) // ['as' NAME] && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' && @@ -23615,7 +23613,7 @@ asdl_pattern_seq* a; asdl_seq* keyword_patterns_var; if ( - (_opt_var = _tmp_225_rule(p), !p->error_indicator) // [positional_patterns ','] + (_opt_var = _tmp_224_rule(p), !p->error_indicator) // [positional_patterns ','] && (keyword_patterns_var = keyword_patterns_rule(p)) // keyword_patterns && @@ -24103,7 +24101,7 @@ && (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' && - (_opt_var_2 = _tmp_226_rule(p), !p->error_indicator) // ['->' expression] + (_opt_var_2 = _tmp_225_rule(p), !p->error_indicator) // ['->' expression] && (_literal_2 = _PyPegen_expect_token(p, 11)) // token=':' && @@ -24162,7 +24160,7 @@ && (name_var = _PyPegen_name_token(p)) // NAME && - (_opt_var = _tmp_227_rule(p), !p->error_indicator) // ['(' arguments? ')'] + (_opt_var = _tmp_226_rule(p), !p->error_indicator) // ['(' arguments? ')'] && (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) @@ -24197,7 +24195,7 @@ && (name_var = _PyPegen_name_token(p)) // NAME && - (_opt_var = _tmp_228_rule(p), !p->error_indicator) // ['(' arguments? ')'] + (_opt_var = _tmp_227_rule(p), !p->error_indicator) // ['(' arguments? ')'] && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -24247,11 +24245,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_229_var; + asdl_seq * _gather_228_var; Token * _literal; void *invalid_kvpair_var; if ( - (_gather_229_var = _gather_229_rule(p)) // ','.double_starred_kvpair+ + (_gather_228_var = _gather_228_rule(p)) // ','.double_starred_kvpair+ && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && @@ -24259,7 +24257,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_229_var, _literal, invalid_kvpair_var); + _res = _PyPegen_dummy_name(p, _gather_228_var, _literal, invalid_kvpair_var); goto done; } p->mark = _mark; @@ -24312,7 +24310,7 @@ && (a = _PyPegen_expect_token(p, 11)) // token=':' && - _PyPegen_lookahead(1, _tmp_231_rule, p) + _PyPegen_lookahead(1, _tmp_230_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_double_starred_kvpairs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' &('}' | ',')")); @@ -24422,7 +24420,7 @@ && (a = _PyPegen_expect_token(p, 11)) // token=':' && - _PyPegen_lookahead(1, _tmp_232_rule, p) + _PyPegen_lookahead(1, _tmp_231_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_kvpair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' &('}' | ',')")); @@ -24638,7 +24636,7 @@ if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' && - _PyPegen_lookahead(0, _tmp_233_rule, p) + _PyPegen_lookahead(0, _tmp_232_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' !(yield_expr | star_expressions)")); @@ -24661,13 +24659,13 @@ } D(fprintf(stderr, "%*c> invalid_replacement_field[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) !('=' | '!' | ':' | '}')")); Token * _literal; - void *_tmp_234_var; + void *_tmp_233_var; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' && - (_tmp_234_var = _tmp_234_rule(p)) // yield_expr | star_expressions + (_tmp_233_var = _tmp_233_rule(p)) // yield_expr | star_expressions && - _PyPegen_lookahead(0, _tmp_235_rule, p) + _PyPegen_lookahead(0, _tmp_234_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) !('=' | '!' | ':' | '}')")); @@ -24691,15 +24689,15 @@ D(fprintf(stderr, "%*c> invalid_replacement_field[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '=' !('!' | ':' | '}')")); Token * _literal; Token * _literal_1; - void *_tmp_236_var; + void *_tmp_235_var; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' && - (_tmp_236_var = _tmp_236_rule(p)) // yield_expr | star_expressions + (_tmp_235_var = _tmp_235_rule(p)) // yield_expr | star_expressions && (_literal_1 = _PyPegen_expect_token(p, 22)) // token='=' && - _PyPegen_lookahead(0, _tmp_237_rule, p) + _PyPegen_lookahead(0, _tmp_236_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '=' !('!' | ':' | '}')")); @@ -24724,12 +24722,12 @@ Token * _literal; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings - void *_tmp_238_var; + void *_tmp_237_var; void *invalid_conversion_character_var; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' && - (_tmp_238_var = _tmp_238_rule(p)) // yield_expr | star_expressions + (_tmp_237_var = _tmp_237_rule(p)) // yield_expr | star_expressions && (_opt_var = _PyPegen_expect_token(p, 22), !p->error_indicator) // '='? && @@ -24737,7 +24735,7 @@ ) { D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '='? invalid_conversion_character")); - _res = _PyPegen_dummy_name(p, _literal, _tmp_238_var, _opt_var, invalid_conversion_character_var); + _res = _PyPegen_dummy_name(p, _literal, _tmp_237_var, _opt_var, invalid_conversion_character_var); goto done; } p->mark = _mark; @@ -24755,17 +24753,17 @@ UNUSED(_opt_var); // Silence compiler warnings void *_opt_var_1; UNUSED(_opt_var_1); // Silence compiler warnings - void *_tmp_239_var; + void *_tmp_238_var; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' && - (_tmp_239_var = _tmp_239_rule(p)) // yield_expr | star_expressions + (_tmp_238_var = _tmp_238_rule(p)) // yield_expr | star_expressions && (_opt_var = _PyPegen_expect_token(p, 22), !p->error_indicator) // '='? && - (_opt_var_1 = _tmp_240_rule(p), !p->error_indicator) // ['!' NAME] + (_opt_var_1 = _tmp_239_rule(p), !p->error_indicator) // ['!' NAME] && - _PyPegen_lookahead(0, _tmp_241_rule, p) + _PyPegen_lookahead(0, _tmp_240_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '='? ['!' NAME] !(':' | '}')")); @@ -24789,24 +24787,24 @@ D(fprintf(stderr, "%*c> invalid_replacement_field[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '='? ['!' NAME] ':' fstring_format_spec* !'}'")); Token * _literal; Token * _literal_1; - asdl_seq * _loop0_244_var; + asdl_seq * _loop0_243_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings void *_opt_var_1; UNUSED(_opt_var_1); // Silence compiler warnings - void *_tmp_242_var; + void *_tmp_241_var; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' && - (_tmp_242_var = _tmp_242_rule(p)) // yield_expr | star_expressions + (_tmp_241_var = _tmp_241_rule(p)) // yield_expr | star_expressions && (_opt_var = _PyPegen_expect_token(p, 22), !p->error_indicator) // '='? && - (_opt_var_1 = _tmp_243_rule(p), !p->error_indicator) // ['!' NAME] + (_opt_var_1 = _tmp_242_rule(p), !p->error_indicator) // ['!' NAME] && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' && - (_loop0_244_var = _loop0_244_rule(p)) // fstring_format_spec* + (_loop0_243_var = _loop0_243_rule(p)) // fstring_format_spec* && _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 26) // token='}' ) @@ -24835,15 +24833,15 @@ UNUSED(_opt_var); // Silence compiler warnings void *_opt_var_1; UNUSED(_opt_var_1); // Silence compiler warnings - void *_tmp_245_var; + void *_tmp_244_var; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' && - (_tmp_245_var = _tmp_245_rule(p)) // yield_expr | star_expressions + (_tmp_244_var = _tmp_244_rule(p)) // yield_expr | star_expressions && (_opt_var = _PyPegen_expect_token(p, 22), !p->error_indicator) // '='? && - (_opt_var_1 = _tmp_246_rule(p), !p->error_indicator) // ['!' NAME] + (_opt_var_1 = _tmp_245_rule(p), !p->error_indicator) // ['!' NAME] && _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 26) // token='}' ) @@ -24890,7 +24888,7 @@ if ( (_literal = _PyPegen_expect_token(p, 54)) // token='!' && - _PyPegen_lookahead(1, _tmp_247_rule, p) + _PyPegen_lookahead(1, _tmp_246_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_conversion_character[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' &(':' | '}')")); @@ -25820,12 +25818,12 @@ return NULL; } D(fprintf(stderr, "%*c> _loop1_15[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_248_var; + void *_tmp_247_var; while ( - (_tmp_248_var = _tmp_248_rule(p)) // star_targets '=' + (_tmp_247_var = _tmp_247_rule(p)) // star_targets '=' ) { - _res = _tmp_248_var; + _res = _tmp_247_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -26389,12 +26387,12 @@ return NULL; } D(fprintf(stderr, "%*c> _loop0_25[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); - void *_tmp_249_var; + void *_tmp_248_var; while ( - (_tmp_249_var = _tmp_249_rule(p)) // '.' | '...' + (_tmp_248_var = _tmp_248_rule(p)) // '.' | '...' ) { - _res = _tmp_249_var; + _res = _tmp_248_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -26456,12 +26454,12 @@ return NULL; } D(fprintf(stderr, "%*c> _loop1_26[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); - void *_tmp_250_var; + void *_tmp_249_var; while ( - (_tmp_250_var = _tmp_250_rule(p)) // '.' | '...' + (_tmp_249_var = _tmp_249_rule(p)) // '.' | '...' ) { - _res = _tmp_250_var; + _res = _tmp_249_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -26854,12 +26852,12 @@ return NULL; } D(fprintf(stderr, "%*c> _loop1_33[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('@' named_expression NEWLINE)")); - void *_tmp_251_var; + void *_tmp_250_var; while ( - (_tmp_251_var = _tmp_251_rule(p)) // '@' named_expression NEWLINE + (_tmp_250_var = _tmp_250_rule(p)) // '@' named_expression NEWLINE ) { - _res = _tmp_251_var; + _res = _tmp_250_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -29984,12 +29982,12 @@ return NULL; } D(fprintf(stderr, "%*c> _loop1_83[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' expression)")); - void *_tmp_252_var; + void *_tmp_251_var; while ( - (_tmp_252_var = _tmp_252_rule(p)) // ',' expression + (_tmp_251_var = _tmp_251_rule(p)) // ',' expression ) { - _res = _tmp_252_var; + _res = _tmp_251_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -30056,12 +30054,12 @@ return NULL; } D(fprintf(stderr, "%*c> _loop1_84[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_expression)")); - void *_tmp_253_var; + void *_tmp_252_var; while ( - (_tmp_253_var = _tmp_253_rule(p)) // ',' star_expression + (_tmp_252_var = _tmp_252_rule(p)) // ',' star_expression ) { - _res = _tmp_253_var; + _res = _tmp_252_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -30245,12 +30243,12 @@ return NULL; } D(fprintf(stderr, "%*c> _loop1_87[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('or' conjunction)")); - void *_tmp_254_var; + void *_tmp_253_var; while ( - (_tmp_254_var = _tmp_254_rule(p)) // 'or' conjunction + (_tmp_253_var = _tmp_253_rule(p)) // 'or' conjunction ) { - _res = _tmp_254_var; + _res = _tmp_253_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -30317,12 +30315,12 @@ return NULL; } D(fprintf(stderr, "%*c> _loop1_88[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('and' inversion)")); - void *_tmp_255_var; + void *_tmp_254_var; while ( - (_tmp_255_var = _tmp_255_rule(p)) // 'and' inversion + (_tmp_254_var = _tmp_254_rule(p)) // 'and' inversion ) { - _res = _tmp_255_var; + _res = _tmp_254_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -30509,7 +30507,7 @@ while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_256_rule(p)) // slice | starred_expression + (elem = _tmp_255_rule(p)) // slice | starred_expression ) { _res = elem; @@ -30574,7 +30572,7 @@ void *elem; asdl_seq * seq; if ( - (elem = _tmp_256_rule(p)) // slice | starred_expression + (elem = _tmp_255_rule(p)) // slice | starred_expression && (seq = _loop0_92_rule(p)) // _loop0_92 ) @@ -32106,12 +32104,12 @@ return NULL; } D(fprintf(stderr, "%*c> _loop1_115[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(fstring | string)")); - void *_tmp_257_var; + void *_tmp_256_var; while ( - (_tmp_257_var = _tmp_257_rule(p)) // fstring | string + (_tmp_256_var = _tmp_256_rule(p)) // fstring | string ) { - _res = _tmp_257_var; + _res = _tmp_256_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -32416,12 +32414,12 @@ return NULL; } D(fprintf(stderr, "%*c> _loop0_120[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); - void *_tmp_258_var; + void *_tmp_257_var; while ( - (_tmp_258_var = _tmp_258_rule(p)) // 'if' disjunction + (_tmp_257_var = _tmp_257_rule(p)) // 'if' disjunction ) { - _res = _tmp_258_var; + _res = _tmp_257_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -32483,12 +32481,12 @@ return NULL; } D(fprintf(stderr, "%*c> _loop0_121[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); - void *_tmp_259_var; + void *_tmp_258_var; while ( - (_tmp_259_var = _tmp_259_rule(p)) // 'if' disjunction + (_tmp_258_var = _tmp_258_rule(p)) // 'if' disjunction ) { - _res = _tmp_259_var; + _res = _tmp_258_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -32614,7 +32612,7 @@ while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_260_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' + (elem = _tmp_259_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' ) { _res = elem; @@ -32680,7 +32678,7 @@ void *elem; asdl_seq * seq; if ( - (elem = _tmp_260_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' + (elem = _tmp_259_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' && (seq = _loop0_124_rule(p)) // _loop0_124 ) @@ -33241,12 +33239,12 @@ return NULL; } D(fprintf(stderr, "%*c> _loop0_134[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)")); - void *_tmp_261_var; + void *_tmp_260_var; while ( - (_tmp_261_var = _tmp_261_rule(p)) // ',' star_target + (_tmp_260_var = _tmp_260_rule(p)) // ',' star_target ) { - _res = _tmp_261_var; + _res = _tmp_260_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -33425,12 +33423,12 @@ return NULL; } D(fprintf(stderr, "%*c> _loop1_137[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)")); - void *_tmp_262_var; + void *_tmp_261_var; while ( - (_tmp_262_var = _tmp_262_rule(p)) // ',' star_target + (_tmp_261_var = _tmp_261_rule(p)) // ',' star_target ) { - _res = _tmp_262_var; + _res = _tmp_261_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -34527,7 +34525,7 @@ return _res; } -// _tmp_157: FSTRING_MIDDLE | fstring_replacement_field +// _tmp_157: '=' | ':=' static void * _tmp_157_rule(Parser *p) { @@ -34540,80 +34538,23 @@ } void * _res = NULL; int _mark = p->mark; - { // FSTRING_MIDDLE - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "FSTRING_MIDDLE")); - Token * fstring_middle_var; - if ( - (fstring_middle_var = _PyPegen_expect_token(p, FSTRING_MIDDLE)) // token='FSTRING_MIDDLE' - ) - { - D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "FSTRING_MIDDLE")); - _res = fstring_middle_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "FSTRING_MIDDLE")); - } - { // fstring_replacement_field - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring_replacement_field")); - expr_ty fstring_replacement_field_var; - if ( - (fstring_replacement_field_var = fstring_replacement_field_rule(p)) // fstring_replacement_field - ) - { - D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "fstring_replacement_field")); - _res = fstring_replacement_field_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "fstring_replacement_field")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_158: '=' | ':=' -static void * -_tmp_158_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - _Pypegen_stack_overflow(p); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - void * _res = NULL; - int _mark = p->mark; { // '=' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c+ _tmp_157[%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_157[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='")); } { // ':=' @@ -34621,18 +34562,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_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 53)) // token=':=' ) { - D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':='")); + D(fprintf(stderr, "%*c+ _tmp_157[%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_157[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':='")); } _res = NULL; @@ -34641,9 +34582,9 @@ return _res; } -// _tmp_159: list | tuple | genexp | 'True' | 'None' | 'False' +// _tmp_158: list | tuple | genexp | 'True' | 'None' | 'False' static void * -_tmp_159_rule(Parser *p) +_tmp_158_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -34659,18 +34600,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "list")); + D(fprintf(stderr, "%*c> _tmp_158[%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_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "list")); + D(fprintf(stderr, "%*c+ _tmp_158[%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_159[%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, "list")); } { // tuple @@ -34678,18 +34619,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "tuple")); + D(fprintf(stderr, "%*c> _tmp_158[%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_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "tuple")); + D(fprintf(stderr, "%*c+ _tmp_158[%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_159[%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, "tuple")); } { // genexp @@ -34697,18 +34638,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "genexp")); + D(fprintf(stderr, "%*c> _tmp_158[%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_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "genexp")); + D(fprintf(stderr, "%*c+ _tmp_158[%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_159[%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, "genexp")); } { // 'True' @@ -34716,18 +34657,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); + D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); Token * _keyword; if ( (_keyword = _PyPegen_expect_token(p, 601)) // token='True' ) { - D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); + D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); _res = _keyword; 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_158[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'True'")); } { // 'None' @@ -34735,18 +34676,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); + D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); Token * _keyword; if ( (_keyword = _PyPegen_expect_token(p, 602)) // token='None' ) { - D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); + D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); _res = _keyword; 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_158[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'None'")); } { // 'False' @@ -34754,18 +34695,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); + D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); Token * _keyword; if ( (_keyword = _PyPegen_expect_token(p, 603)) // token='False' ) { - D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); + D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); _res = _keyword; 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_158[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'False'")); } _res = NULL; @@ -34774,9 +34715,9 @@ return _res; } -// _tmp_160: '=' | ':=' +// _tmp_159: '=' | ':=' static void * -_tmp_160_rule(Parser *p) +_tmp_159_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -34792,18 +34733,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_160[%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, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_160[%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_160[%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, "'='")); } { // ':=' @@ -34811,18 +34752,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_160[%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, 53)) // token=':=' ) { - D(fprintf(stderr, "%*c+ _tmp_160[%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_160[%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; @@ -34831,9 +34772,9 @@ return _res; } -// _loop0_161: star_named_expressions +// _loop0_160: star_named_expressions static asdl_seq * -_loop0_161_rule(Parser *p) +_loop0_160_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -34858,7 +34799,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_161[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expressions")); + D(fprintf(stderr, "%*c> _loop0_160[%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 @@ -34881,7 +34822,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_160[%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); @@ -34898,9 +34839,9 @@ return _seq; } -// _loop0_162: (star_targets '=') +// _loop0_161: (star_targets '=') static asdl_seq * -_loop0_162_rule(Parser *p) +_loop0_161_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -34925,13 +34866,13 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_162[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_263_var; + D(fprintf(stderr, "%*c> _loop0_161[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); + void *_tmp_262_var; while ( - (_tmp_263_var = _tmp_263_rule(p)) // star_targets '=' + (_tmp_262_var = _tmp_262_rule(p)) // star_targets '=' ) { - _res = _tmp_263_var; + _res = _tmp_262_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -34948,7 +34889,7 @@ _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_162[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_161[%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); @@ -34965,9 +34906,9 @@ return _seq; } -// _loop0_163: (star_targets '=') +// _loop0_162: (star_targets '=') static asdl_seq * -_loop0_163_rule(Parser *p) +_loop0_162_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -34992,13 +34933,13 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_163[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_264_var; + D(fprintf(stderr, "%*c> _loop0_162[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); + void *_tmp_263_var; while ( - (_tmp_264_var = _tmp_264_rule(p)) // star_targets '=' + (_tmp_263_var = _tmp_263_rule(p)) // star_targets '=' ) { - _res = _tmp_264_var; + _res = _tmp_263_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -35015,7 +34956,7 @@ _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_163[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_162[%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); @@ -35032,9 +34973,9 @@ return _seq; } -// _tmp_164: yield_expr | star_expressions +// _tmp_163: yield_expr | star_expressions static void * -_tmp_164_rule(Parser *p) +_tmp_163_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35050,18 +34991,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_164[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_163[%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_164[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_163[%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_164[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_163[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } { // star_expressions @@ -35069,18 +35010,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_164[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c> _tmp_163[%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_164[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c+ _tmp_163[%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_164[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_163[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; @@ -35089,9 +35030,9 @@ return _res; } -// _tmp_165: '[' | '(' | '{' +// _tmp_164: '[' | '(' | '{' static void * -_tmp_165_rule(Parser *p) +_tmp_164_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35107,18 +35048,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c> _tmp_164[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 9)) // token='[' ) { - D(fprintf(stderr, "%*c+ _tmp_165[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c+ _tmp_164[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); _res = _literal; 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_164[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['")); } { // '(' @@ -35126,18 +35067,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); + D(fprintf(stderr, "%*c> _tmp_164[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 7)) // token='(' ) { - D(fprintf(stderr, "%*c+ _tmp_165[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); + D(fprintf(stderr, "%*c+ _tmp_164[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); _res = _literal; 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_164[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'('")); } { // '{' @@ -35145,18 +35086,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c> _tmp_164[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' ) { - D(fprintf(stderr, "%*c+ _tmp_165[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c+ _tmp_164[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); _res = _literal; 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_164[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'")); } _res = NULL; @@ -35165,9 +35106,9 @@ return _res; } -// _tmp_166: '[' | '{' +// _tmp_165: '[' | '{' static void * -_tmp_166_rule(Parser *p) +_tmp_165_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35183,18 +35124,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c> _tmp_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 9)) // token='[' ) { - D(fprintf(stderr, "%*c+ _tmp_166[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c+ _tmp_165[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_166[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_165[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['")); } { // '{' @@ -35202,18 +35143,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c> _tmp_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' ) { - D(fprintf(stderr, "%*c+ _tmp_166[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c+ _tmp_165[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_166[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_165[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'")); } _res = NULL; @@ -35222,9 +35163,9 @@ return _res; } -// _tmp_167: '[' | '{' +// _tmp_166: '[' | '{' static void * -_tmp_167_rule(Parser *p) +_tmp_166_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35240,18 +35181,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_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 9)) // token='[' ) { - D(fprintf(stderr, "%*c+ _tmp_167[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c+ _tmp_166[%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_166[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['")); } { // '{' @@ -35259,18 +35200,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_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' ) { - D(fprintf(stderr, "%*c+ _tmp_167[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c+ _tmp_166[%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_166[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'")); } _res = NULL; @@ -35279,9 +35220,9 @@ return _res; } -// _tmp_168: slash_no_default | slash_with_default +// _tmp_167: slash_no_default | slash_with_default static void * -_tmp_168_rule(Parser *p) +_tmp_167_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35297,18 +35238,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_168[%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_168[%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_168[%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 @@ -35316,18 +35257,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_168[%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_168[%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_168[%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; @@ -35336,9 +35277,9 @@ return _res; } -// _loop0_169: param_maybe_default +// _loop0_168: param_maybe_default static asdl_seq * -_loop0_169_rule(Parser *p) +_loop0_168_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35363,7 +35304,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_169[%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 @@ -35386,7 +35327,7 @@ _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_169[%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); @@ -35403,9 +35344,9 @@ return _seq; } -// _loop0_170: param_no_default +// _loop0_169: param_no_default static asdl_seq * -_loop0_170_rule(Parser *p) +_loop0_169_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35430,7 +35371,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_170[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _loop0_169[%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 @@ -35453,7 +35394,7 @@ _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_170[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_169[%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); @@ -35470,9 +35411,9 @@ return _seq; } -// _loop0_171: param_no_default +// _loop0_170: param_no_default static asdl_seq * -_loop0_171_rule(Parser *p) +_loop0_170_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35497,7 +35438,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_171[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _loop0_170[%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 @@ -35520,7 +35461,7 @@ _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_171[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_170[%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); @@ -35537,9 +35478,9 @@ return _seq; } -// _loop1_172: param_no_default +// _loop1_171: param_no_default static asdl_seq * -_loop1_172_rule(Parser *p) +_loop1_171_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35564,7 +35505,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_172[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _loop1_171[%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 @@ -35587,7 +35528,7 @@ _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_172[%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_no_default")); } if (_n == 0 || p->error_indicator) { @@ -35609,9 +35550,9 @@ return _seq; } -// _tmp_173: slash_no_default | slash_with_default +// _tmp_172: slash_no_default | slash_with_default static void * -_tmp_173_rule(Parser *p) +_tmp_172_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35627,18 +35568,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_173[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default")); + D(fprintf(stderr, "%*c> _tmp_172[%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_173[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default")); + D(fprintf(stderr, "%*c+ _tmp_172[%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_173[%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, "slash_no_default")); } { // slash_with_default @@ -35646,18 +35587,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_173[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + D(fprintf(stderr, "%*c> _tmp_172[%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_173[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + D(fprintf(stderr, "%*c+ _tmp_172[%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_173[%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, "slash_with_default")); } _res = NULL; @@ -35666,9 +35607,9 @@ return _res; } -// _loop0_174: param_maybe_default +// _loop0_173: param_maybe_default static asdl_seq * -_loop0_174_rule(Parser *p) +_loop0_173_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35693,7 +35634,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_174[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_173[%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 @@ -35716,7 +35657,7 @@ _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_174[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_173[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -35733,9 +35674,9 @@ return _seq; } -// _tmp_175: ',' | param_no_default +// _tmp_174: ',' | param_no_default static void * -_tmp_175_rule(Parser *p) +_tmp_174_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35751,18 +35692,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_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_175[%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_175[%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 @@ -35770,18 +35711,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_175[%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_175[%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_175[%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")); } _res = NULL; @@ -35790,9 +35731,9 @@ return _res; } -// _loop0_176: param_maybe_default +// _loop0_175: param_maybe_default static asdl_seq * -_loop0_176_rule(Parser *p) +_loop0_175_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35817,7 +35758,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_176[%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 @@ -35840,7 +35781,7 @@ _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_176[%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); @@ -35857,9 +35798,9 @@ return _seq; } -// _loop1_177: param_maybe_default +// _loop1_176: param_maybe_default static asdl_seq * -_loop1_177_rule(Parser *p) +_loop1_176_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35884,7 +35825,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_177[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c> _loop1_176[%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 @@ -35907,7 +35848,7 @@ _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_177[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_176[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); } if (_n == 0 || p->error_indicator) { @@ -35929,9 +35870,9 @@ return _seq; } -// _tmp_178: ')' | ',' +// _tmp_177: ')' | ',' static void * -_tmp_178_rule(Parser *p) +_tmp_177_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35947,18 +35888,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_178[%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, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_178[%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_178[%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, "')'")); } { // ',' @@ -35966,18 +35907,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_178[%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, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_178[%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_178[%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; @@ -35986,9 +35927,9 @@ return _res; } -// _tmp_179: ')' | ',' (')' | '**') +// _tmp_178: ')' | ',' (')' | '**') static void * -_tmp_179_rule(Parser *p) +_tmp_178_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36004,18 +35945,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_179[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_178[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_179[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_178[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_179[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_178[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } { // ',' (')' | '**') @@ -36023,21 +35964,21 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_179[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); + D(fprintf(stderr, "%*c> _tmp_178[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); Token * _literal; - void *_tmp_265_var; + void *_tmp_264_var; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_tmp_265_var = _tmp_265_rule(p)) // ')' | '**' + (_tmp_264_var = _tmp_264_rule(p)) // ')' | '**' ) { - D(fprintf(stderr, "%*c+ _tmp_179[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); - _res = _PyPegen_dummy_name(p, _literal, _tmp_265_var); + D(fprintf(stderr, "%*c+ _tmp_178[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); + _res = _PyPegen_dummy_name(p, _literal, _tmp_264_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_179[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_178[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (')' | '**')")); } _res = NULL; @@ -36046,9 +35987,9 @@ return _res; } -// _tmp_180: param_no_default | ',' +// _tmp_179: param_no_default | ',' static void * -_tmp_180_rule(Parser *p) +_tmp_179_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36064,18 +36005,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_180[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _tmp_179[%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_180[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c+ _tmp_179[%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_180[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_179[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } { // ',' @@ -36083,18 +36024,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_180[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_179[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_180[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_179[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_180[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_179[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; @@ -36103,9 +36044,9 @@ return _res; } -// _loop0_181: param_maybe_default +// _loop0_180: param_maybe_default static asdl_seq * -_loop0_181_rule(Parser *p) +_loop0_180_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36130,7 +36071,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_181[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_180[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); NameDefaultPair* param_maybe_default_var; while ( (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default @@ -36153,7 +36094,7 @@ _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_181[%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, "param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -36170,9 +36111,9 @@ return _seq; } -// _tmp_182: param_no_default | ',' +// _tmp_181: param_no_default | ',' static void * -_tmp_182_rule(Parser *p) +_tmp_181_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36188,18 +36129,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_182[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _tmp_181[%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_182[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c+ _tmp_181[%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_182[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_181[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } { // ',' @@ -36207,18 +36148,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_182[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_181[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_182[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_181[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_182[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_181[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; @@ -36227,9 +36168,9 @@ return _res; } -// _tmp_183: '*' | '**' | '/' +// _tmp_182: '*' | '**' | '/' static void * -_tmp_183_rule(Parser *p) +_tmp_182_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36245,18 +36186,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); + D(fprintf(stderr, "%*c> _tmp_182[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' ) { - D(fprintf(stderr, "%*c+ _tmp_183[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); + D(fprintf(stderr, "%*c+ _tmp_182[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_183[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_182[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*'")); } { // '**' @@ -36264,18 +36205,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c> _tmp_182[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_183[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c+ _tmp_182[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_183[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_182[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } { // '/' @@ -36283,18 +36224,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'")); + D(fprintf(stderr, "%*c> _tmp_182[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 17)) // token='/' ) { - D(fprintf(stderr, "%*c+ _tmp_183[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'")); + D(fprintf(stderr, "%*c+ _tmp_182[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_183[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_182[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'/'")); } _res = NULL; @@ -36303,9 +36244,9 @@ return _res; } -// _loop1_184: param_with_default +// _loop1_183: param_with_default static asdl_seq * -_loop1_184_rule(Parser *p) +_loop1_183_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36330,7 +36271,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_184[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); + D(fprintf(stderr, "%*c> _loop1_183[%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 @@ -36353,7 +36294,7 @@ _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_184[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_183[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); } if (_n == 0 || p->error_indicator) { @@ -36375,9 +36316,9 @@ return _seq; } -// _tmp_185: lambda_slash_no_default | lambda_slash_with_default +// _tmp_184: lambda_slash_no_default | lambda_slash_with_default static void * -_tmp_185_rule(Parser *p) +_tmp_184_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36393,18 +36334,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_185[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + D(fprintf(stderr, "%*c> _tmp_184[%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_185[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + D(fprintf(stderr, "%*c+ _tmp_184[%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_185[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_184[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_no_default")); } { // lambda_slash_with_default @@ -36412,18 +36353,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_185[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + D(fprintf(stderr, "%*c> _tmp_184[%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_185[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + D(fprintf(stderr, "%*c+ _tmp_184[%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_185[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_184[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_with_default")); } _res = NULL; @@ -36432,9 +36373,9 @@ return _res; } -// _loop0_186: lambda_param_maybe_default +// _loop0_185: lambda_param_maybe_default static asdl_seq * -_loop0_186_rule(Parser *p) +_loop0_185_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36459,7 +36400,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_185[%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 @@ -36482,7 +36423,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_185[%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); @@ -36499,9 +36440,9 @@ return _seq; } -// _loop0_187: lambda_param_no_default +// _loop0_186: lambda_param_no_default static asdl_seq * -_loop0_187_rule(Parser *p) +_loop0_186_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36526,7 +36467,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_187[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _loop0_186[%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 @@ -36549,7 +36490,7 @@ _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_187[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_186[%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); @@ -36566,9 +36507,9 @@ return _seq; } -// _loop0_188: lambda_param_no_default +// _loop0_187: lambda_param_no_default static asdl_seq * -_loop0_188_rule(Parser *p) +_loop0_187_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36593,7 +36534,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_188[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _loop0_187[%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 @@ -36616,7 +36557,7 @@ _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_188[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_187[%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); @@ -36633,9 +36574,9 @@ return _seq; } -// _loop0_190: ',' lambda_param +// _loop0_189: ',' lambda_param static asdl_seq * -_loop0_190_rule(Parser *p) +_loop0_189_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36660,7 +36601,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_190[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' lambda_param")); + D(fprintf(stderr, "%*c> _loop0_189[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' lambda_param")); Token * _literal; arg_ty elem; while ( @@ -36692,7 +36633,7 @@ _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_190[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_189[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' lambda_param")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -36709,9 +36650,9 @@ return _seq; } -// _gather_189: lambda_param _loop0_190 +// _gather_188: lambda_param _loop0_189 static asdl_seq * -_gather_189_rule(Parser *p) +_gather_188_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36722,27 +36663,27 @@ } asdl_seq * _res = NULL; int _mark = p->mark; - { // lambda_param _loop0_190 + { // lambda_param _loop0_189 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_189[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_190")); + D(fprintf(stderr, "%*c> _gather_188[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_189")); arg_ty elem; asdl_seq * seq; if ( (elem = lambda_param_rule(p)) // lambda_param && - (seq = _loop0_190_rule(p)) // _loop0_190 + (seq = _loop0_189_rule(p)) // _loop0_189 ) { - D(fprintf(stderr, "%*c+ _gather_189[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_190")); + D(fprintf(stderr, "%*c+ _gather_188[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_189")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_189[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param _loop0_190")); + D(fprintf(stderr, "%*c%s _gather_188[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param _loop0_189")); } _res = NULL; done: @@ -36750,9 +36691,9 @@ return _res; } -// _tmp_191: lambda_slash_no_default | lambda_slash_with_default +// _tmp_190: lambda_slash_no_default | lambda_slash_with_default static void * -_tmp_191_rule(Parser *p) +_tmp_190_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36768,18 +36709,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_191[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + D(fprintf(stderr, "%*c> _tmp_190[%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_191[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + D(fprintf(stderr, "%*c+ _tmp_190[%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_191[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_190[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_no_default")); } { // lambda_slash_with_default @@ -36787,18 +36728,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_191[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + D(fprintf(stderr, "%*c> _tmp_190[%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_191[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + D(fprintf(stderr, "%*c+ _tmp_190[%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_191[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_190[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_with_default")); } _res = NULL; @@ -36807,9 +36748,9 @@ return _res; } -// _loop0_192: lambda_param_maybe_default +// _loop0_191: lambda_param_maybe_default static asdl_seq * -_loop0_192_rule(Parser *p) +_loop0_191_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36834,7 +36775,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_191[%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 @@ -36857,7 +36798,7 @@ _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_192[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_191[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -36874,9 +36815,9 @@ return _seq; } -// _tmp_193: ',' | lambda_param_no_default +// _tmp_192: ',' | lambda_param_no_default static void * -_tmp_193_rule(Parser *p) +_tmp_192_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36892,18 +36833,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_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_193[%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_193[%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 @@ -36911,18 +36852,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_193[%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_193[%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_193[%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")); } _res = NULL; @@ -36931,9 +36872,9 @@ return _res; } -// _loop0_194: lambda_param_maybe_default +// _loop0_193: lambda_param_maybe_default static asdl_seq * -_loop0_194_rule(Parser *p) +_loop0_193_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36958,7 +36899,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_194[%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 @@ -36981,7 +36922,7 @@ _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_194[%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); @@ -36998,9 +36939,9 @@ return _seq; } -// _loop1_195: lambda_param_maybe_default +// _loop1_194: lambda_param_maybe_default static asdl_seq * -_loop1_195_rule(Parser *p) +_loop1_194_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37025,7 +36966,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_195[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + D(fprintf(stderr, "%*c> _loop1_194[%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 @@ -37048,7 +36989,7 @@ _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_195[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_194[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } if (_n == 0 || p->error_indicator) { @@ -37070,9 +37011,9 @@ return _seq; } -// _loop1_196: lambda_param_with_default +// _loop1_195: lambda_param_with_default static asdl_seq * -_loop1_196_rule(Parser *p) +_loop1_195_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37097,7 +37038,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_196[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + D(fprintf(stderr, "%*c> _loop1_195[%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 @@ -37120,7 +37061,7 @@ _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_196[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_195[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); } if (_n == 0 || p->error_indicator) { @@ -37142,9 +37083,9 @@ return _seq; } -// _tmp_197: ':' | ',' (':' | '**') +// _tmp_196: ':' | ',' (':' | '**') static void * -_tmp_197_rule(Parser *p) +_tmp_196_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37160,18 +37101,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_197[%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_197[%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_197[%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, "':'")); } { // ',' (':' | '**') @@ -37179,21 +37120,21 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_197[%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; - void *_tmp_266_var; + void *_tmp_265_var; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_tmp_266_var = _tmp_266_rule(p)) // ':' | '**' + (_tmp_265_var = _tmp_265_rule(p)) // ':' | '**' ) { - D(fprintf(stderr, "%*c+ _tmp_197[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); - _res = _PyPegen_dummy_name(p, _literal, _tmp_266_var); + D(fprintf(stderr, "%*c+ _tmp_196[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); + _res = _PyPegen_dummy_name(p, _literal, _tmp_265_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_197[%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; @@ -37202,9 +37143,9 @@ return _res; } -// _tmp_198: lambda_param_no_default | ',' +// _tmp_197: lambda_param_no_default | ',' static void * -_tmp_198_rule(Parser *p) +_tmp_197_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37220,18 +37161,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_198[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _tmp_197[%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_198[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c+ _tmp_197[%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_198[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_197[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } { // ',' @@ -37239,18 +37180,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_198[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_197[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_198[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_197[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_198[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_197[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; @@ -37259,9 +37200,9 @@ return _res; } -// _loop0_199: lambda_param_maybe_default +// _loop0_198: lambda_param_maybe_default static asdl_seq * -_loop0_199_rule(Parser *p) +_loop0_198_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37286,7 +37227,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_199[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_198[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); NameDefaultPair* lambda_param_maybe_default_var; while ( (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default @@ -37309,7 +37250,7 @@ _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_199[%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, "lambda_param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -37326,9 +37267,9 @@ return _seq; } -// _tmp_200: lambda_param_no_default | ',' +// _tmp_199: lambda_param_no_default | ',' static void * -_tmp_200_rule(Parser *p) +_tmp_199_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37344,18 +37285,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_200[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _tmp_199[%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_200[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c+ _tmp_199[%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_200[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_199[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } { // ',' @@ -37363,18 +37304,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_200[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_199[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_200[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_199[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_200[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_199[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; @@ -37383,9 +37324,9 @@ return _res; } -// _tmp_201: '*' | '**' | '/' +// _tmp_200: '*' | '**' | '/' static void * -_tmp_201_rule(Parser *p) +_tmp_200_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37401,18 +37342,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); + D(fprintf(stderr, "%*c> _tmp_200[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' ) { - D(fprintf(stderr, "%*c+ _tmp_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); + D(fprintf(stderr, "%*c+ _tmp_200[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_201[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_200[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*'")); } { // '**' @@ -37420,18 +37361,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c> _tmp_200[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c+ _tmp_200[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_201[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_200[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } { // '/' @@ -37439,18 +37380,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'")); + D(fprintf(stderr, "%*c> _tmp_200[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 17)) // token='/' ) { - D(fprintf(stderr, "%*c+ _tmp_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'")); + D(fprintf(stderr, "%*c+ _tmp_200[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_201[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_200[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'/'")); } _res = NULL; @@ -37459,9 +37400,9 @@ return _res; } -// _tmp_202: ',' | ')' | ':' +// _tmp_201: ',' | ')' | ':' static void * -_tmp_202_rule(Parser *p) +_tmp_201_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37477,18 +37418,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_202[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_202[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_202[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_201[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } { // ')' @@ -37496,18 +37437,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_202[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_202[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_202[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_201[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } { // ':' @@ -37515,18 +37456,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_202[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_202[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_202[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_201[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } _res = NULL; @@ -37535,9 +37476,9 @@ return _res; } -// _loop0_204: ',' dotted_name +// _loop0_203: ',' dotted_name static asdl_seq * -_loop0_204_rule(Parser *p) +_loop0_203_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37562,7 +37503,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_204[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' dotted_name")); + D(fprintf(stderr, "%*c> _loop0_203[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' dotted_name")); Token * _literal; expr_ty elem; while ( @@ -37594,7 +37535,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_203[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' dotted_name")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -37611,9 +37552,9 @@ return _seq; } -// _gather_203: dotted_name _loop0_204 +// _gather_202: dotted_name _loop0_203 static asdl_seq * -_gather_203_rule(Parser *p) +_gather_202_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37624,27 +37565,27 @@ } asdl_seq * _res = NULL; int _mark = p->mark; - { // dotted_name _loop0_204 + { // dotted_name _loop0_203 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_203[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dotted_name _loop0_204")); + D(fprintf(stderr, "%*c> _gather_202[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dotted_name _loop0_203")); expr_ty elem; asdl_seq * seq; if ( (elem = dotted_name_rule(p)) // dotted_name && - (seq = _loop0_204_rule(p)) // _loop0_204 + (seq = _loop0_203_rule(p)) // _loop0_203 ) { - D(fprintf(stderr, "%*c+ _gather_203[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dotted_name _loop0_204")); + D(fprintf(stderr, "%*c+ _gather_202[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dotted_name _loop0_203")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_203[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dotted_name _loop0_204")); + D(fprintf(stderr, "%*c%s _gather_202[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dotted_name _loop0_203")); } _res = NULL; done: @@ -37652,9 +37593,9 @@ return _res; } -// _loop0_206: ',' (expression ['as' star_target]) +// _loop0_205: ',' (expression ['as' star_target]) static asdl_seq * -_loop0_206_rule(Parser *p) +_loop0_205_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37679,13 +37620,13 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_206[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); + D(fprintf(stderr, "%*c> _loop0_205[%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_267_rule(p)) // expression ['as' star_target] + (elem = _tmp_266_rule(p)) // expression ['as' star_target] ) { _res = elem; @@ -37711,7 +37652,7 @@ _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_206[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_205[%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); @@ -37728,9 +37669,9 @@ return _seq; } -// _gather_205: (expression ['as' star_target]) _loop0_206 +// _gather_204: (expression ['as' star_target]) _loop0_205 static asdl_seq * -_gather_205_rule(Parser *p) +_gather_204_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37741,27 +37682,27 @@ } asdl_seq * _res = NULL; int _mark = p->mark; - { // (expression ['as' star_target]) _loop0_206 + { // (expression ['as' star_target]) _loop0_205 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_205[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_206")); + D(fprintf(stderr, "%*c> _gather_204[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_205")); void *elem; asdl_seq * seq; if ( - (elem = _tmp_267_rule(p)) // expression ['as' star_target] + (elem = _tmp_266_rule(p)) // expression ['as' star_target] && - (seq = _loop0_206_rule(p)) // _loop0_206 + (seq = _loop0_205_rule(p)) // _loop0_205 ) { - D(fprintf(stderr, "%*c+ _gather_205[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_206")); + D(fprintf(stderr, "%*c+ _gather_204[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_205")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_205[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_206")); + D(fprintf(stderr, "%*c%s _gather_204[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_205")); } _res = NULL; done: @@ -37769,9 +37710,9 @@ return _res; } -// _loop0_208: ',' (expressions ['as' star_target]) +// _loop0_207: ',' (expressions ['as' star_target]) static asdl_seq * -_loop0_208_rule(Parser *p) +_loop0_207_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37796,13 +37737,13 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_208[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); + D(fprintf(stderr, "%*c> _loop0_207[%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_268_rule(p)) // expressions ['as' star_target] + (elem = _tmp_267_rule(p)) // expressions ['as' star_target] ) { _res = elem; @@ -37828,7 +37769,7 @@ _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_208[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_207[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expressions ['as' star_target])")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -37845,9 +37786,9 @@ return _seq; } -// _gather_207: (expressions ['as' star_target]) _loop0_208 +// _gather_206: (expressions ['as' star_target]) _loop0_207 static asdl_seq * -_gather_207_rule(Parser *p) +_gather_206_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37858,27 +37799,27 @@ } asdl_seq * _res = NULL; int _mark = p->mark; - { // (expressions ['as' star_target]) _loop0_208 + { // (expressions ['as' star_target]) _loop0_207 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_207[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_208")); + D(fprintf(stderr, "%*c> _gather_206[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_207")); void *elem; asdl_seq * seq; if ( - (elem = _tmp_268_rule(p)) // expressions ['as' star_target] + (elem = _tmp_267_rule(p)) // expressions ['as' star_target] && - (seq = _loop0_208_rule(p)) // _loop0_208 + (seq = _loop0_207_rule(p)) // _loop0_207 ) { - D(fprintf(stderr, "%*c+ _gather_207[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_208")); + D(fprintf(stderr, "%*c+ _gather_206[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_207")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_207[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_208")); + D(fprintf(stderr, "%*c%s _gather_206[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_207")); } _res = NULL; done: @@ -37886,9 +37827,9 @@ return _res; } -// _loop0_210: ',' (expression ['as' star_target]) +// _loop0_209: ',' (expression ['as' star_target]) static asdl_seq * -_loop0_210_rule(Parser *p) +_loop0_209_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37913,13 +37854,13 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_210[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); + D(fprintf(stderr, "%*c> _loop0_209[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); Token * _literal; void *elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_269_rule(p)) // expression ['as' star_target] + (elem = _tmp_268_rule(p)) // expression ['as' star_target] ) { _res = elem; @@ -37945,7 +37886,7 @@ _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_210[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_209[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expression ['as' star_target])")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -37962,9 +37903,9 @@ return _seq; } -// _gather_209: (expression ['as' star_target]) _loop0_210 +// _gather_208: (expression ['as' star_target]) _loop0_209 static asdl_seq * -_gather_209_rule(Parser *p) +_gather_208_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37975,27 +37916,27 @@ } asdl_seq * _res = NULL; int _mark = p->mark; - { // (expression ['as' star_target]) _loop0_210 + { // (expression ['as' star_target]) _loop0_209 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_209[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_210")); + D(fprintf(stderr, "%*c> _gather_208[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_209")); void *elem; asdl_seq * seq; if ( - (elem = _tmp_269_rule(p)) // expression ['as' star_target] + (elem = _tmp_268_rule(p)) // expression ['as' star_target] && - (seq = _loop0_210_rule(p)) // _loop0_210 + (seq = _loop0_209_rule(p)) // _loop0_209 ) { - D(fprintf(stderr, "%*c+ _gather_209[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_210")); + D(fprintf(stderr, "%*c+ _gather_208[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_209")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_209[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_210")); + D(fprintf(stderr, "%*c%s _gather_208[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_209")); } _res = NULL; done: @@ -38003,9 +37944,9 @@ return _res; } -// _loop0_212: ',' (expressions ['as' star_target]) +// _loop0_211: ',' (expressions ['as' star_target]) static asdl_seq * -_loop0_212_rule(Parser *p) +_loop0_211_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38030,13 +37971,13 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_212[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); + D(fprintf(stderr, "%*c> _loop0_211[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); Token * _literal; void *elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_270_rule(p)) // expressions ['as' star_target] + (elem = _tmp_269_rule(p)) // expressions ['as' star_target] ) { _res = elem; @@ -38062,7 +38003,7 @@ _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_212[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_211[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expressions ['as' star_target])")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -38079,9 +38020,9 @@ return _seq; } -// _gather_211: (expressions ['as' star_target]) _loop0_212 +// _gather_210: (expressions ['as' star_target]) _loop0_211 static asdl_seq * -_gather_211_rule(Parser *p) +_gather_210_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38092,27 +38033,27 @@ } asdl_seq * _res = NULL; int _mark = p->mark; - { // (expressions ['as' star_target]) _loop0_212 + { // (expressions ['as' star_target]) _loop0_211 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_211[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_212")); + D(fprintf(stderr, "%*c> _gather_210[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_211")); void *elem; asdl_seq * seq; if ( - (elem = _tmp_270_rule(p)) // expressions ['as' star_target] + (elem = _tmp_269_rule(p)) // expressions ['as' star_target] && - (seq = _loop0_212_rule(p)) // _loop0_212 + (seq = _loop0_211_rule(p)) // _loop0_211 ) { - D(fprintf(stderr, "%*c+ _gather_211[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_212")); + D(fprintf(stderr, "%*c+ _gather_210[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_211")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_211[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_212")); + D(fprintf(stderr, "%*c%s _gather_210[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_211")); } _res = NULL; done: @@ -38120,9 +38061,9 @@ return _res; } -// _tmp_213: 'except' | 'finally' +// _tmp_212: 'except' | 'finally' static void * -_tmp_213_rule(Parser *p) +_tmp_212_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38138,18 +38079,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_213[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except'")); + D(fprintf(stderr, "%*c> _tmp_212[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except'")); Token * _keyword; if ( (_keyword = _PyPegen_expect_token(p, 637)) // token='except' ) { - D(fprintf(stderr, "%*c+ _tmp_213[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except'")); + D(fprintf(stderr, "%*c+ _tmp_212[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except'")); _res = _keyword; 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_212[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'except'")); } { // 'finally' @@ -38157,18 +38098,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_213[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'finally'")); + D(fprintf(stderr, "%*c> _tmp_212[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'finally'")); Token * _keyword; if ( (_keyword = _PyPegen_expect_token(p, 633)) // token='finally' ) { - D(fprintf(stderr, "%*c+ _tmp_213[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'finally'")); + D(fprintf(stderr, "%*c+ _tmp_212[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'finally'")); _res = _keyword; 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_212[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'finally'")); } _res = NULL; @@ -38177,9 +38118,9 @@ return _res; } -// _loop0_214: block +// _loop0_213: block static asdl_seq * -_loop0_214_rule(Parser *p) +_loop0_213_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38204,7 +38145,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_214[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block")); + D(fprintf(stderr, "%*c> _loop0_213[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block")); asdl_stmt_seq* block_var; while ( (block_var = block_rule(p)) // block @@ -38227,7 +38168,7 @@ _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_214[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_213[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "block")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -38244,9 +38185,9 @@ return _seq; } -// _loop1_215: except_block +// _loop1_214: except_block static asdl_seq * -_loop1_215_rule(Parser *p) +_loop1_214_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38271,7 +38212,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_215[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_block")); + D(fprintf(stderr, "%*c> _loop1_214[%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 @@ -38294,7 +38235,7 @@ _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_215[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_214[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_block")); } if (_n == 0 || p->error_indicator) { @@ -38316,9 +38257,9 @@ return _seq; } -// _tmp_216: 'as' NAME +// _tmp_215: 'as' NAME static void * -_tmp_216_rule(Parser *p) +_tmp_215_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38334,7 +38275,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_216[%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 ( @@ -38343,12 +38284,12 @@ (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_216[%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_216[%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; @@ -38357,9 +38298,9 @@ return _res; } -// _loop0_217: block +// _loop0_216: block static asdl_seq * -_loop0_217_rule(Parser *p) +_loop0_216_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38384,7 +38325,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_217[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block")); + D(fprintf(stderr, "%*c> _loop0_216[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block")); asdl_stmt_seq* block_var; while ( (block_var = block_rule(p)) // block @@ -38407,7 +38348,7 @@ _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_217[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_216[%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); @@ -38424,9 +38365,9 @@ return _seq; } -// _loop1_218: except_star_block +// _loop1_217: except_star_block static asdl_seq * -_loop1_218_rule(Parser *p) +_loop1_217_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38451,7 +38392,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_218[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_star_block")); + D(fprintf(stderr, "%*c> _loop1_217[%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 @@ -38474,7 +38415,7 @@ _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_218[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_217[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_star_block")); } if (_n == 0 || p->error_indicator) { @@ -38496,9 +38437,9 @@ return _seq; } -// _tmp_219: expression ['as' NAME] +// _tmp_218: expression ['as' NAME] static void * -_tmp_219_rule(Parser *p) +_tmp_218_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38514,22 +38455,22 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_219[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' NAME]")); + D(fprintf(stderr, "%*c> _tmp_218[%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_271_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var = _tmp_270_rule(p), !p->error_indicator) // ['as' NAME] ) { - D(fprintf(stderr, "%*c+ _tmp_219[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' NAME]")); + D(fprintf(stderr, "%*c+ _tmp_218[%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_219[%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 ['as' NAME]")); } _res = NULL; @@ -38538,9 +38479,9 @@ return _res; } -// _tmp_220: 'as' NAME +// _tmp_219: 'as' NAME static void * -_tmp_220_rule(Parser *p) +_tmp_219_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38556,7 +38497,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_220[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_219[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty name_var; if ( @@ -38565,12 +38506,12 @@ (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_220[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_219[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = _PyPegen_dummy_name(p, _keyword, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_220[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_219[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -38579,9 +38520,9 @@ return _res; } -// _tmp_221: 'as' NAME +// _tmp_220: 'as' NAME static void * -_tmp_221_rule(Parser *p) +_tmp_220_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38597,7 +38538,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_221[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_220[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty name_var; if ( @@ -38606,12 +38547,12 @@ (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_221[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_220[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = _PyPegen_dummy_name(p, _keyword, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_221[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_220[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -38620,9 +38561,9 @@ return _res; } -// _tmp_222: NEWLINE | ':' +// _tmp_221: NEWLINE | ':' static void * -_tmp_222_rule(Parser *p) +_tmp_221_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38638,18 +38579,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_222[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE")); + D(fprintf(stderr, "%*c> _tmp_221[%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_222[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE")); + D(fprintf(stderr, "%*c+ _tmp_221[%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_222[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_221[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE")); } { // ':' @@ -38657,18 +38598,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_221[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_222[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_221[%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_221[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } _res = NULL; @@ -38677,9 +38618,9 @@ return _res; } -// _tmp_223: 'as' NAME +// _tmp_222: 'as' NAME static void * -_tmp_223_rule(Parser *p) +_tmp_222_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38695,7 +38636,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_223[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_222[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty name_var; if ( @@ -38704,12 +38645,12 @@ (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_223[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_222[%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_223[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_222[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -38718,9 +38659,9 @@ return _res; } -// _tmp_224: 'as' NAME +// _tmp_223: 'as' NAME static void * -_tmp_224_rule(Parser *p) +_tmp_223_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38736,7 +38677,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_224[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_223[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty name_var; if ( @@ -38745,12 +38686,12 @@ (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_224[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_223[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = _PyPegen_dummy_name(p, _keyword, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_224[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_223[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -38759,9 +38700,9 @@ return _res; } -// _tmp_225: positional_patterns ',' +// _tmp_224: positional_patterns ',' static void * -_tmp_225_rule(Parser *p) +_tmp_224_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38777,7 +38718,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_225[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); + D(fprintf(stderr, "%*c> _tmp_224[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); Token * _literal; asdl_pattern_seq* positional_patterns_var; if ( @@ -38786,12 +38727,12 @@ (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_225[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); + D(fprintf(stderr, "%*c+ _tmp_224[%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_225[%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, "positional_patterns ','")); } _res = NULL; @@ -38800,9 +38741,9 @@ return _res; } -// _tmp_226: '->' expression +// _tmp_225: '->' expression static void * -_tmp_226_rule(Parser *p) +_tmp_225_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38818,7 +38759,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_226[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); + D(fprintf(stderr, "%*c> _tmp_225[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); Token * _literal; expr_ty expression_var; if ( @@ -38827,12 +38768,12 @@ (expression_var = expression_rule(p)) // expression ) { - D(fprintf(stderr, "%*c+ _tmp_226[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'->' expression")); + D(fprintf(stderr, "%*c+ _tmp_225[%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_226[%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, "'->' expression")); } _res = NULL; @@ -38841,9 +38782,9 @@ return _res; } -// _tmp_227: '(' arguments? ')' +// _tmp_226: '(' arguments? ')' static void * -_tmp_227_rule(Parser *p) +_tmp_226_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38859,7 +38800,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_227[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + D(fprintf(stderr, "%*c> _tmp_226[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); Token * _literal; Token * _literal_1; void *_opt_var; @@ -38872,12 +38813,12 @@ (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_227[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + D(fprintf(stderr, "%*c+ _tmp_226[%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_227[%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, "'(' arguments? ')'")); } _res = NULL; @@ -38886,9 +38827,9 @@ return _res; } -// _tmp_228: '(' arguments? ')' +// _tmp_227: '(' arguments? ')' static void * -_tmp_228_rule(Parser *p) +_tmp_227_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38904,7 +38845,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_228[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + D(fprintf(stderr, "%*c> _tmp_227[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); Token * _literal; Token * _literal_1; void *_opt_var; @@ -38917,12 +38858,12 @@ (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_228[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + D(fprintf(stderr, "%*c+ _tmp_227[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); _res = _PyPegen_dummy_name(p, _literal, _opt_var, _literal_1); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_228[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_227[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' arguments? ')'")); } _res = NULL; @@ -38931,9 +38872,9 @@ return _res; } -// _loop0_230: ',' double_starred_kvpair +// _loop0_229: ',' double_starred_kvpair static asdl_seq * -_loop0_230_rule(Parser *p) +_loop0_229_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38958,7 +38899,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_230[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' double_starred_kvpair")); + D(fprintf(stderr, "%*c> _loop0_229[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' double_starred_kvpair")); Token * _literal; KeyValuePair* elem; while ( @@ -38990,7 +38931,7 @@ _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_230[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_229[%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); @@ -39007,9 +38948,9 @@ return _seq; } -// _gather_229: double_starred_kvpair _loop0_230 +// _gather_228: double_starred_kvpair _loop0_229 static asdl_seq * -_gather_229_rule(Parser *p) +_gather_228_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39020,27 +38961,27 @@ } asdl_seq * _res = NULL; int _mark = p->mark; - { // double_starred_kvpair _loop0_230 + { // double_starred_kvpair _loop0_229 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_229[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_230")); + D(fprintf(stderr, "%*c> _gather_228[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_229")); KeyValuePair* elem; asdl_seq * seq; if ( (elem = double_starred_kvpair_rule(p)) // double_starred_kvpair && - (seq = _loop0_230_rule(p)) // _loop0_230 + (seq = _loop0_229_rule(p)) // _loop0_229 ) { - D(fprintf(stderr, "%*c+ _gather_229[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_230")); + D(fprintf(stderr, "%*c+ _gather_228[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_229")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_229[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "double_starred_kvpair _loop0_230")); + D(fprintf(stderr, "%*c%s _gather_228[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "double_starred_kvpair _loop0_229")); } _res = NULL; done: @@ -39048,9 +38989,9 @@ return _res; } -// _tmp_231: '}' | ',' +// _tmp_230: '}' | ',' static void * -_tmp_231_rule(Parser *p) +_tmp_230_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39066,18 +39007,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_231[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c> _tmp_230[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 26)) // token='}' ) { - D(fprintf(stderr, "%*c+ _tmp_231[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c+ _tmp_230[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); _res = _literal; 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_230[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); } { // ',' @@ -39085,18 +39026,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_231[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_230[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_231[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_230[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; 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_230[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; @@ -39105,9 +39046,9 @@ return _res; } -// _tmp_232: '}' | ',' +// _tmp_231: '}' | ',' static void * -_tmp_232_rule(Parser *p) +_tmp_231_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39123,18 +39064,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_232[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c> _tmp_231[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 26)) // token='}' ) { - D(fprintf(stderr, "%*c+ _tmp_232[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c+ _tmp_231[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_232[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_231[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); } { // ',' @@ -39142,18 +39083,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_232[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_231[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_232[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_231[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_232[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_231[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; @@ -39162,9 +39103,9 @@ return _res; } -// _tmp_233: yield_expr | star_expressions +// _tmp_232: yield_expr | star_expressions static void * -_tmp_233_rule(Parser *p) +_tmp_232_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39180,18 +39121,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_233[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_232[%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_233[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_232[%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_233[%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, "yield_expr")); } { // star_expressions @@ -39199,18 +39140,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_233[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c> _tmp_232[%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_233[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c+ _tmp_232[%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_233[%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, "star_expressions")); } _res = NULL; @@ -39219,9 +39160,9 @@ return _res; } -// _tmp_234: yield_expr | star_expressions +// _tmp_233: yield_expr | star_expressions static void * -_tmp_234_rule(Parser *p) +_tmp_233_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39237,18 +39178,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_233[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); expr_ty yield_expr_var; if ( (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_233[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); _res = yield_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_234[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_233[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } { // star_expressions @@ -39256,18 +39197,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c> _tmp_233[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); expr_ty star_expressions_var; if ( (star_expressions_var = star_expressions_rule(p)) // star_expressions ) { - D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c+ _tmp_233[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); _res = star_expressions_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_234[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_233[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; @@ -39276,9 +39217,9 @@ return _res; } -// _tmp_235: '=' | '!' | ':' | '}' +// _tmp_234: '=' | '!' | ':' | '}' static void * -_tmp_235_rule(Parser *p) +_tmp_234_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39294,18 +39235,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_235[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_235[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_235[%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, "'='")); } { // '!' @@ -39313,18 +39254,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_235[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!'")); + D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 54)) // token='!' ) { - D(fprintf(stderr, "%*c+ _tmp_235[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!'")); + D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_235[%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, "'!'")); } { // ':' @@ -39332,18 +39273,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_235[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_235[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_235[%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, "':'")); } { // '}' @@ -39351,18 +39292,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_235[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 26)) // token='}' ) { - D(fprintf(stderr, "%*c+ _tmp_235[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_235[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_234[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); } _res = NULL; @@ -39371,9 +39312,9 @@ return _res; } -// _tmp_236: yield_expr | star_expressions +// _tmp_235: yield_expr | star_expressions static void * -_tmp_236_rule(Parser *p) +_tmp_235_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39389,18 +39330,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_236[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_235[%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_236[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_235[%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_236[%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, "yield_expr")); } { // star_expressions @@ -39408,18 +39349,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_236[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c> _tmp_235[%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_236[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c+ _tmp_235[%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_236[%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, "star_expressions")); } _res = NULL; @@ -39428,9 +39369,9 @@ return _res; } -// _tmp_237: '!' | ':' | '}' +// _tmp_236: '!' | ':' | '}' static void * -_tmp_237_rule(Parser *p) +_tmp_236_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39446,18 +39387,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_237[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!'")); + D(fprintf(stderr, "%*c> _tmp_236[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 54)) // token='!' ) { - D(fprintf(stderr, "%*c+ _tmp_237[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!'")); + D(fprintf(stderr, "%*c+ _tmp_236[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!'")); _res = _literal; 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_236[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'!'")); } { // ':' @@ -39465,18 +39406,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_237[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_236[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_237[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_236[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; 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_236[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } { // '}' @@ -39484,18 +39425,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_237[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c> _tmp_236[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 26)) // token='}' ) { - D(fprintf(stderr, "%*c+ _tmp_237[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c+ _tmp_236[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); _res = _literal; 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_236[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); } _res = NULL; @@ -39504,9 +39445,9 @@ return _res; } -// _tmp_238: yield_expr | star_expressions +// _tmp_237: yield_expr | star_expressions static void * -_tmp_238_rule(Parser *p) +_tmp_237_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39522,18 +39463,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_238[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_237[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); expr_ty yield_expr_var; if ( (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _tmp_238[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_237[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); _res = yield_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_238[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_237[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } { // star_expressions @@ -39541,18 +39482,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_238[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c> _tmp_237[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); expr_ty star_expressions_var; if ( (star_expressions_var = star_expressions_rule(p)) // star_expressions ) { - D(fprintf(stderr, "%*c+ _tmp_238[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c+ _tmp_237[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); _res = star_expressions_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_238[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_237[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; @@ -39561,9 +39502,9 @@ return _res; } -// _tmp_239: yield_expr | star_expressions +// _tmp_238: yield_expr | star_expressions static void * -_tmp_239_rule(Parser *p) +_tmp_238_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39579,18 +39520,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_239[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_238[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); expr_ty yield_expr_var; if ( (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _tmp_239[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_238[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); _res = yield_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_239[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_238[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } { // star_expressions @@ -39598,18 +39539,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_239[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c> _tmp_238[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); expr_ty star_expressions_var; if ( (star_expressions_var = star_expressions_rule(p)) // star_expressions ) { - D(fprintf(stderr, "%*c+ _tmp_239[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c+ _tmp_238[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); _res = star_expressions_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_239[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_238[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; @@ -39618,9 +39559,9 @@ return _res; } -// _tmp_240: '!' NAME +// _tmp_239: '!' NAME static void * -_tmp_240_rule(Parser *p) +_tmp_239_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39636,7 +39577,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_240[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!' NAME")); + D(fprintf(stderr, "%*c> _tmp_239[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!' NAME")); Token * _literal; expr_ty name_var; if ( @@ -39645,12 +39586,12 @@ (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_240[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' NAME")); + D(fprintf(stderr, "%*c+ _tmp_239[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' NAME")); _res = _PyPegen_dummy_name(p, _literal, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_240[%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, "'!' NAME")); } _res = NULL; @@ -39659,9 +39600,9 @@ return _res; } -// _tmp_241: ':' | '}' +// _tmp_240: ':' | '}' static void * -_tmp_241_rule(Parser *p) +_tmp_240_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39677,18 +39618,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_240[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_241[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_240[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_241[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_240[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } { // '}' @@ -39696,18 +39637,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_240[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 26)) // token='}' ) { - D(fprintf(stderr, "%*c+ _tmp_241[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c+ _tmp_240[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_241[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_240[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); } _res = NULL; @@ -39716,9 +39657,9 @@ return _res; } -// _tmp_242: yield_expr | star_expressions +// _tmp_241: yield_expr | star_expressions static void * -_tmp_242_rule(Parser *p) +_tmp_241_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39734,18 +39675,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_242[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_241[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); expr_ty yield_expr_var; if ( (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _tmp_242[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_241[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); _res = yield_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_242[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_241[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } { // star_expressions @@ -39753,18 +39694,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_242[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c> _tmp_241[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); expr_ty star_expressions_var; if ( (star_expressions_var = star_expressions_rule(p)) // star_expressions ) { - D(fprintf(stderr, "%*c+ _tmp_242[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c+ _tmp_241[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); _res = star_expressions_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_242[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_241[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; @@ -39773,9 +39714,9 @@ return _res; } -// _tmp_243: '!' NAME +// _tmp_242: '!' NAME static void * -_tmp_243_rule(Parser *p) +_tmp_242_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39791,7 +39732,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_243[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!' NAME")); + D(fprintf(stderr, "%*c> _tmp_242[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!' NAME")); Token * _literal; expr_ty name_var; if ( @@ -39800,12 +39741,12 @@ (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_243[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' NAME")); + D(fprintf(stderr, "%*c+ _tmp_242[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' NAME")); _res = _PyPegen_dummy_name(p, _literal, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_243[%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, "'!' NAME")); } _res = NULL; @@ -39814,9 +39755,9 @@ return _res; } -// _loop0_244: fstring_format_spec +// _loop0_243: fstring_format_spec static asdl_seq * -_loop0_244_rule(Parser *p) +_loop0_243_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39841,7 +39782,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_244[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring_format_spec")); + D(fprintf(stderr, "%*c> _loop0_243[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring_format_spec")); expr_ty fstring_format_spec_var; while ( (fstring_format_spec_var = fstring_format_spec_rule(p)) // fstring_format_spec @@ -39864,7 +39805,7 @@ _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_244[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_243[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "fstring_format_spec")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -39881,9 +39822,9 @@ return _seq; } -// _tmp_245: yield_expr | star_expressions +// _tmp_244: yield_expr | star_expressions static void * -_tmp_245_rule(Parser *p) +_tmp_244_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39899,18 +39840,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_245[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_244[%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_245[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_244[%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_245[%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, "yield_expr")); } { // star_expressions @@ -39918,18 +39859,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_245[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c> _tmp_244[%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_245[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c+ _tmp_244[%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_245[%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, "star_expressions")); } _res = NULL; @@ -39938,9 +39879,9 @@ return _res; } -// _tmp_246: '!' NAME +// _tmp_245: '!' NAME static void * -_tmp_246_rule(Parser *p) +_tmp_245_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39956,7 +39897,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_246[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!' NAME")); + D(fprintf(stderr, "%*c> _tmp_245[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!' NAME")); Token * _literal; expr_ty name_var; if ( @@ -39965,12 +39906,12 @@ (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_246[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' NAME")); + D(fprintf(stderr, "%*c+ _tmp_245[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' NAME")); _res = _PyPegen_dummy_name(p, _literal, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_246[%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, "'!' NAME")); } _res = NULL; @@ -39979,9 +39920,9 @@ return _res; } -// _tmp_247: ':' | '}' +// _tmp_246: ':' | '}' static void * -_tmp_247_rule(Parser *p) +_tmp_246_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39997,18 +39938,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_247[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_246[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_247[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_246[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; 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_246[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } { // '}' @@ -40016,18 +39957,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_247[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c> _tmp_246[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 26)) // token='}' ) { - D(fprintf(stderr, "%*c+ _tmp_247[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c+ _tmp_246[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); _res = _literal; 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_246[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); } _res = NULL; @@ -40036,9 +39977,9 @@ return _res; } -// _tmp_248: star_targets '=' +// _tmp_247: star_targets '=' static void * -_tmp_248_rule(Parser *p) +_tmp_247_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40054,7 +39995,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_248[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c> _tmp_247[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); Token * _literal; expr_ty z; if ( @@ -40063,7 +40004,7 @@ (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_248[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c+ _tmp_247[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -40073,7 +40014,7 @@ goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_248[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_247[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); } _res = NULL; @@ -40082,9 +40023,9 @@ return _res; } -// _tmp_249: '.' | '...' +// _tmp_248: '.' | '...' static void * -_tmp_249_rule(Parser *p) +_tmp_248_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40100,18 +40041,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_249[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c> _tmp_248[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 23)) // token='.' ) { - D(fprintf(stderr, "%*c+ _tmp_249[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c+ _tmp_248[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_249[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_248[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); } { // '...' @@ -40119,18 +40060,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_249[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c> _tmp_248[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 52)) // token='...' ) { - D(fprintf(stderr, "%*c+ _tmp_249[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c+ _tmp_248[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_249[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_248[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'...'")); } _res = NULL; @@ -40139,9 +40080,9 @@ return _res; } -// _tmp_250: '.' | '...' +// _tmp_249: '.' | '...' static void * -_tmp_250_rule(Parser *p) +_tmp_249_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40157,18 +40098,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_250[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c> _tmp_249[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 23)) // token='.' ) { - D(fprintf(stderr, "%*c+ _tmp_250[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c+ _tmp_249[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_250[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_249[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); } { // '...' @@ -40176,18 +40117,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_250[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c> _tmp_249[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 52)) // token='...' ) { - D(fprintf(stderr, "%*c+ _tmp_250[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c+ _tmp_249[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_250[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_249[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'...'")); } _res = NULL; @@ -40196,9 +40137,9 @@ return _res; } -// _tmp_251: '@' named_expression NEWLINE +// _tmp_250: '@' named_expression NEWLINE static void * -_tmp_251_rule(Parser *p) +_tmp_250_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40214,7 +40155,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_251[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); + D(fprintf(stderr, "%*c> _tmp_250[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); Token * _literal; expr_ty f; Token * newline_var; @@ -40226,7 +40167,7 @@ (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) { - D(fprintf(stderr, "%*c+ _tmp_251[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); + D(fprintf(stderr, "%*c+ _tmp_250[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); _res = f; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -40236,7 +40177,7 @@ 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_250[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'@' named_expression NEWLINE")); } _res = NULL; @@ -40245,9 +40186,9 @@ return _res; } -// _tmp_252: ',' expression +// _tmp_251: ',' expression static void * -_tmp_252_rule(Parser *p) +_tmp_251_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40263,7 +40204,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_252[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c> _tmp_251[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); Token * _literal; expr_ty c; if ( @@ -40272,7 +40213,7 @@ (c = expression_rule(p)) // expression ) { - D(fprintf(stderr, "%*c+ _tmp_252[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c+ _tmp_251[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -40282,7 +40223,7 @@ 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_251[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); } _res = NULL; @@ -40291,9 +40232,9 @@ return _res; } -// _tmp_253: ',' star_expression +// _tmp_252: ',' star_expression static void * -_tmp_253_rule(Parser *p) +_tmp_252_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40309,7 +40250,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_253[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_expression")); + D(fprintf(stderr, "%*c> _tmp_252[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_expression")); Token * _literal; expr_ty c; if ( @@ -40318,7 +40259,7 @@ (c = star_expression_rule(p)) // star_expression ) { - D(fprintf(stderr, "%*c+ _tmp_253[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_expression")); + D(fprintf(stderr, "%*c+ _tmp_252[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_expression")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -40328,7 +40269,7 @@ 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_252[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_expression")); } _res = NULL; @@ -40337,9 +40278,9 @@ return _res; } -// _tmp_254: 'or' conjunction +// _tmp_253: 'or' conjunction static void * -_tmp_254_rule(Parser *p) +_tmp_253_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40355,7 +40296,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_254[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); + D(fprintf(stderr, "%*c> _tmp_253[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); Token * _keyword; expr_ty c; if ( @@ -40364,7 +40305,7 @@ (c = conjunction_rule(p)) // conjunction ) { - D(fprintf(stderr, "%*c+ _tmp_254[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); + D(fprintf(stderr, "%*c+ _tmp_253[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -40374,7 +40315,7 @@ 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_253[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'or' conjunction")); } _res = NULL; @@ -40383,9 +40324,9 @@ return _res; } -// _tmp_255: 'and' inversion +// _tmp_254: 'and' inversion static void * -_tmp_255_rule(Parser *p) +_tmp_254_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40401,7 +40342,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_255[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'and' inversion")); + D(fprintf(stderr, "%*c> _tmp_254[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'and' inversion")); Token * _keyword; expr_ty c; if ( @@ -40410,7 +40351,7 @@ (c = inversion_rule(p)) // inversion ) { - D(fprintf(stderr, "%*c+ _tmp_255[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'and' inversion")); + D(fprintf(stderr, "%*c+ _tmp_254[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'and' inversion")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -40420,7 +40361,7 @@ 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_254[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'and' inversion")); } _res = NULL; @@ -40429,9 +40370,9 @@ return _res; } -// _tmp_256: slice | starred_expression +// _tmp_255: slice | starred_expression static void * -_tmp_256_rule(Parser *p) +_tmp_255_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40447,18 +40388,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_256[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slice")); + D(fprintf(stderr, "%*c> _tmp_255[%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_256[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slice")); + D(fprintf(stderr, "%*c+ _tmp_255[%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_256[%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, "slice")); } { // starred_expression @@ -40466,18 +40407,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_256[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); + D(fprintf(stderr, "%*c> _tmp_255[%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_256[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); + D(fprintf(stderr, "%*c+ _tmp_255[%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_256[%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, "starred_expression")); } _res = NULL; @@ -40486,9 +40427,9 @@ return _res; } -// _tmp_257: fstring | string +// _tmp_256: fstring | string static void * -_tmp_257_rule(Parser *p) +_tmp_256_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40504,18 +40445,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_257[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring")); + D(fprintf(stderr, "%*c> _tmp_256[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring")); expr_ty fstring_var; if ( (fstring_var = fstring_rule(p)) // fstring ) { - D(fprintf(stderr, "%*c+ _tmp_257[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "fstring")); + D(fprintf(stderr, "%*c+ _tmp_256[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "fstring")); _res = fstring_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_257[%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, "fstring")); } { // string @@ -40523,18 +40464,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_257[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "string")); + D(fprintf(stderr, "%*c> _tmp_256[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "string")); expr_ty string_var; if ( (string_var = string_rule(p)) // string ) { - D(fprintf(stderr, "%*c+ _tmp_257[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "string")); + D(fprintf(stderr, "%*c+ _tmp_256[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "string")); _res = string_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_257[%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, "string")); } _res = NULL; @@ -40543,9 +40484,9 @@ return _res; } -// _tmp_258: 'if' disjunction +// _tmp_257: 'if' disjunction static void * -_tmp_258_rule(Parser *p) +_tmp_257_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40561,7 +40502,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_258[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c> _tmp_257[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); Token * _keyword; expr_ty z; if ( @@ -40570,7 +40511,7 @@ (z = disjunction_rule(p)) // disjunction ) { - D(fprintf(stderr, "%*c+ _tmp_258[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c+ _tmp_257[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -40580,7 +40521,7 @@ goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_258[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_257[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' disjunction")); } _res = NULL; @@ -40589,9 +40530,9 @@ return _res; } -// _tmp_259: 'if' disjunction +// _tmp_258: 'if' disjunction static void * -_tmp_259_rule(Parser *p) +_tmp_258_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40607,7 +40548,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_259[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c> _tmp_258[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); Token * _keyword; expr_ty z; if ( @@ -40616,7 +40557,7 @@ (z = disjunction_rule(p)) // disjunction ) { - D(fprintf(stderr, "%*c+ _tmp_259[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c+ _tmp_258[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -40626,7 +40567,7 @@ goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_259[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_258[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' disjunction")); } _res = NULL; @@ -40635,9 +40576,9 @@ return _res; } -// _tmp_260: starred_expression | (assignment_expression | expression !':=') !'=' +// _tmp_259: starred_expression | (assignment_expression | expression !':=') !'=' static void * -_tmp_260_rule(Parser *p) +_tmp_259_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40653,18 +40594,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_260[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); + D(fprintf(stderr, "%*c> _tmp_259[%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_260[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); + D(fprintf(stderr, "%*c+ _tmp_259[%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_260[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_259[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "starred_expression")); } { // (assignment_expression | expression !':=') !'=' @@ -40672,20 +40613,20 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_260[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); - void *_tmp_272_var; + D(fprintf(stderr, "%*c> _tmp_259[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); + void *_tmp_271_var; if ( - (_tmp_272_var = _tmp_272_rule(p)) // assignment_expression | expression !':=' + (_tmp_271_var = _tmp_271_rule(p)) // assignment_expression | expression !':=' && _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 22) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_260[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); - _res = _tmp_272_var; + D(fprintf(stderr, "%*c+ _tmp_259[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); + _res = _tmp_271_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_260[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_259[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(assignment_expression | expression !':=') !'='")); } _res = NULL; @@ -40694,9 +40635,9 @@ return _res; } -// _tmp_261: ',' star_target +// _tmp_260: ',' star_target static void * -_tmp_261_rule(Parser *p) +_tmp_260_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40712,7 +40653,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_261[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c> _tmp_260[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); Token * _literal; expr_ty c; if ( @@ -40721,7 +40662,7 @@ (c = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_261[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c+ _tmp_260[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -40731,7 +40672,7 @@ goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_261[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_260[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_target")); } _res = NULL; @@ -40740,9 +40681,9 @@ return _res; } -// _tmp_262: ',' star_target +// _tmp_261: ',' star_target static void * -_tmp_262_rule(Parser *p) +_tmp_261_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40758,7 +40699,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_262[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c> _tmp_261[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); Token * _literal; expr_ty c; if ( @@ -40767,7 +40708,7 @@ (c = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_262[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c+ _tmp_261[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -40777,7 +40718,7 @@ goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_262[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_261[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_target")); } _res = NULL; @@ -40786,9 +40727,9 @@ return _res; } -// _tmp_263: star_targets '=' +// _tmp_262: star_targets '=' static void * -_tmp_263_rule(Parser *p) +_tmp_262_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40804,7 +40745,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_263[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c> _tmp_262[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); Token * _literal; expr_ty star_targets_var; if ( @@ -40813,12 +40754,12 @@ (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_263[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c+ _tmp_262[%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_263[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_262[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); } _res = NULL; @@ -40827,9 +40768,9 @@ return _res; } -// _tmp_264: star_targets '=' +// _tmp_263: star_targets '=' static void * -_tmp_264_rule(Parser *p) +_tmp_263_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40845,7 +40786,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_264[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c> _tmp_263[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); Token * _literal; expr_ty star_targets_var; if ( @@ -40854,12 +40795,12 @@ (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_264[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c+ _tmp_263[%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_264[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_263[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); } _res = NULL; @@ -40868,9 +40809,9 @@ return _res; } -// _tmp_265: ')' | '**' +// _tmp_264: ')' | '**' static void * -_tmp_265_rule(Parser *p) +_tmp_264_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40886,18 +40827,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_265[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_264[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_265[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_264[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_265[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_264[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } { // '**' @@ -40905,18 +40846,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_265[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c> _tmp_264[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_265[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c+ _tmp_264[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_265[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_264[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } _res = NULL; @@ -40925,9 +40866,9 @@ return _res; } -// _tmp_266: ':' | '**' +// _tmp_265: ':' | '**' static void * -_tmp_266_rule(Parser *p) +_tmp_265_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40943,18 +40884,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_266[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_265[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_266[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_265[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_266[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_265[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } { // '**' @@ -40962,18 +40903,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_266[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c> _tmp_265[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_266[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c+ _tmp_265[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_266[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_265[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } _res = NULL; @@ -40982,9 +40923,9 @@ return _res; } -// _tmp_267: expression ['as' star_target] +// _tmp_266: expression ['as' star_target] static void * -_tmp_267_rule(Parser *p) +_tmp_266_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41000,22 +40941,22 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_267[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + D(fprintf(stderr, "%*c> _tmp_266[%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_273_rule(p), !p->error_indicator) // ['as' star_target] + (_opt_var = _tmp_272_rule(p), !p->error_indicator) // ['as' star_target] ) { - D(fprintf(stderr, "%*c+ _tmp_267[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + D(fprintf(stderr, "%*c+ _tmp_266[%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_267[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_266[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ['as' star_target]")); } _res = NULL; @@ -41024,9 +40965,9 @@ return _res; } -// _tmp_268: expressions ['as' star_target] +// _tmp_267: expressions ['as' star_target] static void * -_tmp_268_rule(Parser *p) +_tmp_267_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41042,22 +40983,22 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_268[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + D(fprintf(stderr, "%*c> _tmp_267[%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_274_rule(p), !p->error_indicator) // ['as' star_target] + (_opt_var = _tmp_273_rule(p), !p->error_indicator) // ['as' star_target] ) { - D(fprintf(stderr, "%*c+ _tmp_268[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + D(fprintf(stderr, "%*c+ _tmp_267[%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_268[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_267[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expressions ['as' star_target]")); } _res = NULL; @@ -41066,9 +41007,9 @@ return _res; } -// _tmp_269: expression ['as' star_target] +// _tmp_268: expression ['as' star_target] static void * -_tmp_269_rule(Parser *p) +_tmp_268_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41084,22 +41025,22 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_269[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + D(fprintf(stderr, "%*c> _tmp_268[%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_275_rule(p), !p->error_indicator) // ['as' star_target] + (_opt_var = _tmp_274_rule(p), !p->error_indicator) // ['as' star_target] ) { - D(fprintf(stderr, "%*c+ _tmp_269[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + D(fprintf(stderr, "%*c+ _tmp_268[%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_269[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_268[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ['as' star_target]")); } _res = NULL; @@ -41108,9 +41049,9 @@ return _res; } -// _tmp_270: expressions ['as' star_target] +// _tmp_269: expressions ['as' star_target] static void * -_tmp_270_rule(Parser *p) +_tmp_269_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41126,22 +41067,22 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_270[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + D(fprintf(stderr, "%*c> _tmp_269[%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_276_rule(p), !p->error_indicator) // ['as' star_target] + (_opt_var = _tmp_275_rule(p), !p->error_indicator) // ['as' star_target] ) { - D(fprintf(stderr, "%*c+ _tmp_270[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + D(fprintf(stderr, "%*c+ _tmp_269[%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_270[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_269[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expressions ['as' star_target]")); } _res = NULL; @@ -41150,9 +41091,9 @@ return _res; } -// _tmp_271: 'as' NAME +// _tmp_270: 'as' NAME static void * -_tmp_271_rule(Parser *p) +_tmp_270_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41168,7 +41109,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_271[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_270[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty name_var; if ( @@ -41177,12 +41118,12 @@ (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_271[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_270[%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_271[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_270[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -41191,9 +41132,9 @@ return _res; } -// _tmp_272: assignment_expression | expression !':=' +// _tmp_271: assignment_expression | expression !':=' static void * -_tmp_272_rule(Parser *p) +_tmp_271_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41209,18 +41150,18 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_272[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression")); + D(fprintf(stderr, "%*c> _tmp_271[%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_272[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment_expression")); + D(fprintf(stderr, "%*c+ _tmp_271[%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_272[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_271[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "assignment_expression")); } { // expression !':=' @@ -41228,7 +41169,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_272[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); + D(fprintf(stderr, "%*c> _tmp_271[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); expr_ty expression_var; if ( (expression_var = expression_rule(p)) // expression @@ -41236,12 +41177,12 @@ _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 53) // token=':=' ) { - D(fprintf(stderr, "%*c+ _tmp_272[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='")); + D(fprintf(stderr, "%*c+ _tmp_271[%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_272[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_271[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression !':='")); } _res = NULL; @@ -41250,9 +41191,9 @@ return _res; } -// _tmp_273: 'as' star_target +// _tmp_272: 'as' star_target static void * -_tmp_273_rule(Parser *p) +_tmp_272_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41268,7 +41209,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_273[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c> _tmp_272[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); Token * _keyword; expr_ty star_target_var; if ( @@ -41277,12 +41218,12 @@ (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_273[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c+ _tmp_272[%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_273[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_272[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); } _res = NULL; @@ -41291,9 +41232,9 @@ return _res; } -// _tmp_274: 'as' star_target +// _tmp_273: 'as' star_target static void * -_tmp_274_rule(Parser *p) +_tmp_273_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41309,7 +41250,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_274[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c> _tmp_273[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); Token * _keyword; expr_ty star_target_var; if ( @@ -41318,12 +41259,12 @@ (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_274[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c+ _tmp_273[%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_274[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_273[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); } _res = NULL; @@ -41332,9 +41273,9 @@ return _res; } -// _tmp_275: 'as' star_target +// _tmp_274: 'as' star_target static void * -_tmp_275_rule(Parser *p) +_tmp_274_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41350,7 +41291,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_275[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c> _tmp_274[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); Token * _keyword; expr_ty star_target_var; if ( @@ -41359,12 +41300,12 @@ (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_275[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c+ _tmp_274[%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_275[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_274[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); } _res = NULL; @@ -41373,9 +41314,9 @@ return _res; } -// _tmp_276: 'as' star_target +// _tmp_275: 'as' star_target static void * -_tmp_276_rule(Parser *p) +_tmp_275_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41391,7 +41332,7 @@ p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_276[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c> _tmp_275[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); Token * _keyword; expr_ty star_target_var; if ( @@ -41400,12 +41341,12 @@ (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_276[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c+ _tmp_275[%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_276[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_275[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); } _res = NULL; diff -Nru python3.12-3.12.0~rc2/PCbuild/get_externals.bat python3.12-3.12.0/PCbuild/get_externals.bat --- python3.12-3.12.0~rc2/PCbuild/get_externals.bat 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/PCbuild/get_externals.bat 2023-10-02 11:48:14.000000000 +0000 @@ -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.10 +if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-3.0.11 set libraries=%libraries% sqlite-3.42.0.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.13.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.13.0 @@ -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.10 +if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-3.0.11 if NOT "%IncludeTkinter%"=="false" set binaries=%binaries% tcltk-8.6.13.0 if NOT "%IncludeSSLSrc%"=="false" set binaries=%binaries% nasm-2.11.06 diff -Nru python3.12-3.12.0~rc2/PCbuild/python.props python3.12-3.12.0/PCbuild/python.props --- python3.12-3.12.0~rc2/PCbuild/python.props 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/PCbuild/python.props 2023-10-02 11:48:14.000000000 +0000 @@ -74,8 +74,8 @@ $(ExternalsDir)libffi-3.4.4\ $(libffiDir)$(ArchName)\ $(libffiOutDir)include - $(ExternalsDir)openssl-3.0.10\ - $(ExternalsDir)openssl-bin-3.0.10\$(ArchName)\ + $(ExternalsDir)openssl-3.0.11\ + $(ExternalsDir)openssl-bin-3.0.11\$(ArchName)\ $(opensslOutDir)include $(ExternalsDir)\nasm-2.11.06\ $(ExternalsDir)\zlib-1.2.13\ diff -Nru python3.12-3.12.0~rc2/.pre-commit-config.yaml python3.12-3.12.0/.pre-commit-config.yaml --- python3.12-3.12.0~rc2/.pre-commit-config.yaml 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/.pre-commit-config.yaml 2023-10-02 11:48:14.000000000 +0000 @@ -1,7 +1,17 @@ repos: + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.0.288 + hooks: + - id: ruff + name: Run Ruff on Lib/test/ + args: [--exit-non-zero-on-fix] + files: ^Lib/test/ + - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.4.0 hooks: + - id: check-toml + exclude: ^Lib/test/test_tomllib/ - id: check-yaml - id: end-of-file-fixer types: [python] diff -Nru python3.12-3.12.0~rc2/Python/ast.c python3.12-3.12.0/Python/ast.c --- python3.12-3.12.0~rc2/Python/ast.c 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Python/ast.c 2023-10-02 11:48:14.000000000 +0000 @@ -768,6 +768,11 @@ validate_expr(state, stmt->v.AnnAssign.annotation, Load); break; case TypeAlias_kind: + if (stmt->v.TypeAlias.name->kind != Name_kind) { + PyErr_SetString(PyExc_TypeError, + "TypeAlias with non-Name name"); + return 0; + } ret = validate_expr(state, stmt->v.TypeAlias.name, Store) && validate_type_params(state, stmt->v.TypeAlias.type_params) && validate_expr(state, stmt->v.TypeAlias.value, Load); diff -Nru python3.12-3.12.0~rc2/Python/bytecodes.c python3.12-3.12.0/Python/bytecodes.c --- python3.12-3.12.0~rc2/Python/bytecodes.c 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Python/bytecodes.c 2023-10-02 11:48:14.000000000 +0000 @@ -1165,7 +1165,7 @@ } } - op(_LOAD_LOCALS, ( -- locals)) { + inst(LOAD_LOCALS, ( -- locals)) { locals = LOCALS(); if (locals == NULL) { _PyErr_SetString(tstate, PyExc_SystemError, @@ -1175,9 +1175,7 @@ Py_INCREF(locals); } - macro(LOAD_LOCALS) = _LOAD_LOCALS; - - op(_LOAD_FROM_DICT_OR_GLOBALS, (mod_or_class_dict -- v)) { + inst(LOAD_FROM_DICT_OR_GLOBALS, (mod_or_class_dict -- v)) { PyObject *name = GETITEM(frame->f_code->co_names, oparg); if (PyDict_CheckExact(mod_or_class_dict)) { v = PyDict_GetItemWithError(mod_or_class_dict, name); @@ -1185,7 +1183,6 @@ Py_INCREF(v); } else if (_PyErr_Occurred(tstate)) { - Py_DECREF(mod_or_class_dict); goto error; } } @@ -1193,13 +1190,11 @@ v = PyObject_GetItem(mod_or_class_dict, name); if (v == NULL) { if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - Py_DECREF(mod_or_class_dict); goto error; } _PyErr_Clear(tstate); } } - Py_DECREF(mod_or_class_dict); if (v == NULL) { v = PyDict_GetItemWithError(GLOBALS(), name); if (v != NULL) { @@ -1234,11 +1229,70 @@ } } } + DECREF_INPUTS(); } - macro(LOAD_NAME) = _LOAD_LOCALS + _LOAD_FROM_DICT_OR_GLOBALS; - - macro(LOAD_FROM_DICT_OR_GLOBALS) = _LOAD_FROM_DICT_OR_GLOBALS; + inst(LOAD_NAME, (-- v)) { + PyObject *mod_or_class_dict = LOCALS(); + if (mod_or_class_dict == NULL) { + _PyErr_SetString(tstate, PyExc_SystemError, + "no locals found"); + ERROR_IF(true, error); + } + PyObject *name = GETITEM(frame->f_code->co_names, oparg); + if (PyDict_CheckExact(mod_or_class_dict)) { + v = PyDict_GetItemWithError(mod_or_class_dict, name); + if (v != NULL) { + Py_INCREF(v); + } + else if (_PyErr_Occurred(tstate)) { + goto error; + } + } + else { + v = PyObject_GetItem(mod_or_class_dict, name); + if (v == NULL) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + goto error; + } + _PyErr_Clear(tstate); + } + } + if (v == NULL) { + v = PyDict_GetItemWithError(GLOBALS(), name); + if (v != NULL) { + Py_INCREF(v); + } + else if (_PyErr_Occurred(tstate)) { + goto error; + } + else { + if (PyDict_CheckExact(BUILTINS())) { + v = PyDict_GetItemWithError(BUILTINS(), name); + if (v == NULL) { + if (!_PyErr_Occurred(tstate)) { + format_exc_check_arg( + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + goto error; + } + Py_INCREF(v); + } + else { + v = PyObject_GetItem(BUILTINS(), name); + if (v == NULL) { + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + format_exc_check_arg( + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + goto error; + } + } + } + } + } family(load_global, INLINE_CACHE_ENTRIES_LOAD_GLOBAL) = { LOAD_GLOBAL, diff -Nru python3.12-3.12.0~rc2/Python/compile.c python3.12-3.12.0/Python/compile.c --- python3.12-3.12.0~rc2/Python/compile.c 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Python/compile.c 2023-10-02 11:48:14.000000000 +0000 @@ -3184,18 +3184,6 @@ } -static location -location_of_last_executing_statement(asdl_stmt_seq *stmts) -{ - for (Py_ssize_t i = asdl_seq_LEN(stmts) - 1; i >= 0; i++) { - location loc = LOC((stmt_ty)asdl_seq_GET(stmts, i)); - if (loc.lineno > 0) { - return loc; - } - } - return NO_LOCATION; -} - /* Code generated for "try: finally: " is as follows: SETUP_FINALLY L @@ -3264,9 +3252,9 @@ RETURN_IF_ERROR( compiler_push_fblock(c, loc, FINALLY_END, end, NO_LABEL, NULL)); VISIT_SEQ(c, stmt, s->v.Try.finalbody); - loc = location_of_last_executing_statement(s->v.Try.finalbody); compiler_pop_fblock(c, FINALLY_END, end); + loc = NO_LOCATION; ADDOP_I(c, loc, RERAISE, 0); USE_LABEL(c, cleanup); @@ -3315,9 +3303,9 @@ compiler_push_fblock(c, loc, FINALLY_END, end, NO_LABEL, NULL)); VISIT_SEQ(c, stmt, s->v.TryStar.finalbody); - loc = location_of_last_executing_statement(s->v.Try.finalbody); compiler_pop_fblock(c, FINALLY_END, end); + loc = NO_LOCATION; ADDOP_I(c, loc, RERAISE, 0); USE_LABEL(c, cleanup); @@ -4776,7 +4764,7 @@ // load super() global PyObject *super_name = e->v.Call.func->v.Name.id; - RETURN_IF_ERROR(compiler_nameop(c, loc, super_name, Load)); + RETURN_IF_ERROR(compiler_nameop(c, LOC(e->v.Call.func), super_name, Load)); if (asdl_seq_LEN(e->v.Call.args) == 2) { VISIT(c, expr, asdl_seq_GET(e->v.Call.args, 0)); diff -Nru python3.12-3.12.0~rc2/Python/flowgraph.c python3.12-3.12.0/Python/flowgraph.c --- python3.12-3.12.0~rc2/Python/flowgraph.c 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Python/flowgraph.c 2023-10-02 11:48:14.000000000 +0000 @@ -366,6 +366,7 @@ #ifndef NDEBUG static int remove_redundant_nops(basicblock *bb); +/* static bool no_redundant_nops(cfg_builder *g) { for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { @@ -375,6 +376,7 @@ } return true; } +*/ static bool no_empty_basic_blocks(cfg_builder *g) { @@ -562,16 +564,23 @@ return SUCCESS; } -/* Calculate the actual jump target from the target_label */ static int -translate_jump_labels_to_targets(basicblock *entryblock) +get_max_label(basicblock *entryblock) { - int max_label = -1; + int lbl = -1; for (basicblock *b = entryblock; b != NULL; b = b->b_next) { - if (b->b_label.id > max_label) { - max_label = b->b_label.id; + if (b->b_label.id > lbl) { + lbl = b->b_label.id; } } + return lbl; +} + +/* Calculate the actual jump target from the target_label */ +static int +translate_jump_labels_to_targets(basicblock *entryblock) +{ + int max_label = get_max_label(entryblock); size_t mapsize = sizeof(basicblock *) * (max_label + 1); basicblock **label2block = (basicblock **)PyMem_Malloc(mapsize); if (!label2block) { @@ -915,6 +924,7 @@ while(g->g_entryblock && g->g_entryblock->b_iused == 0) { g->g_entryblock = g->g_entryblock->b_next; } + int next_lbl = get_max_label(g->g_entryblock) + 1; for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { assert(b->b_iused > 0); for (int i = 0; i < b->b_iused; i++) { @@ -924,7 +934,13 @@ while (target->b_iused == 0) { target = target->b_next; } - instr->i_target = target; + if (instr->i_target != target) { + if (!IS_LABEL(target->b_label)) { + target->b_label.id = next_lbl++; + } + instr->i_target = target; + instr->i_oparg = target->b_label.id; + } assert(instr->i_target && instr->i_target->b_iused > 0); } } @@ -1581,7 +1597,11 @@ remove_redundant_nops(b); } eliminate_empty_basic_blocks(g); - assert(no_redundant_nops(g)); + /* This assertion fails in an edge case (See gh-109889). + * Remove it for the release (it's just one more NOP in the + * bytecode for unlikely code). + */ + // assert(no_redundant_nops(g)); RETURN_IF_ERROR(remove_redundant_jumps(g)); return SUCCESS; } @@ -1938,6 +1958,8 @@ } RETURN_IF_ERROR(mark_cold(entryblock)); + int next_lbl = get_max_label(g->g_entryblock) + 1; + /* If we have a cold block with fallthrough to a warm block, add */ /* an explicit jump instead of fallthrough */ for (basicblock *b = entryblock; b != NULL; b = b->b_next) { @@ -1946,6 +1968,9 @@ if (explicit_jump == NULL) { return ERROR; } + if (!IS_LABEL(b->b_next->b_label)) { + b->b_next->b_label.id = next_lbl++; + } basicblock_addop(explicit_jump, JUMP, b->b_next->b_label.id, NO_LOCATION); explicit_jump->b_cold = 1; explicit_jump->b_next = b->b_next; @@ -2035,6 +2060,7 @@ return true; } + /* PEP 626 mandates that the f_lineno of a frame is correct * after a frame terminates. It would be prohibitively expensive * to continuously update the f_lineno field at runtime, @@ -2048,6 +2074,9 @@ duplicate_exits_without_lineno(cfg_builder *g) { assert(no_empty_basic_blocks(g)); + + int next_lbl = get_max_label(g->g_entryblock) + 1; + /* Copy all exit blocks without line number that are targets of a jump. */ basicblock *entryblock = g->g_entryblock; @@ -2066,6 +2095,7 @@ target->b_predecessors--; new_target->b_predecessors = 1; new_target->b_next = target->b_next; + new_target->b_label.id = next_lbl++; target->b_next = new_target; } } diff -Nru python3.12-3.12.0~rc2/Python/generated_cases.c.h python3.12-3.12.0/Python/generated_cases.c.h --- python3.12-3.12.0~rc2/Python/generated_cases.c.h 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Python/generated_cases.c.h 2023-10-02 11:48:14.000000000 +0000 @@ -1619,174 +1619,149 @@ } TARGET(LOAD_LOCALS) { - PyObject *_tmp_1; - { - PyObject *locals; - #line 1169 "Python/bytecodes.c" - locals = LOCALS(); - if (locals == NULL) { - _PyErr_SetString(tstate, PyExc_SystemError, - "no locals found"); - if (true) goto error; - } - Py_INCREF(locals); - #line 1634 "Python/generated_cases.c.h" - _tmp_1 = locals; + PyObject *locals; + #line 1169 "Python/bytecodes.c" + locals = LOCALS(); + if (locals == NULL) { + _PyErr_SetString(tstate, PyExc_SystemError, + "no locals found"); + if (true) goto error; } + Py_INCREF(locals); + #line 1632 "Python/generated_cases.c.h" STACK_GROW(1); - stack_pointer[-1] = _tmp_1; + stack_pointer[-1] = locals; DISPATCH(); } - TARGET(LOAD_NAME) { - PyObject *_tmp_1; - { - PyObject *locals; - #line 1169 "Python/bytecodes.c" - locals = LOCALS(); - if (locals == NULL) { - _PyErr_SetString(tstate, PyExc_SystemError, - "no locals found"); - if (true) goto error; + TARGET(LOAD_FROM_DICT_OR_GLOBALS) { + PyObject *mod_or_class_dict = stack_pointer[-1]; + PyObject *v; + #line 1179 "Python/bytecodes.c" + PyObject *name = GETITEM(frame->f_code->co_names, oparg); + if (PyDict_CheckExact(mod_or_class_dict)) { + v = PyDict_GetItemWithError(mod_or_class_dict, name); + if (v != NULL) { + Py_INCREF(v); + } + else if (_PyErr_Occurred(tstate)) { + goto error; } - Py_INCREF(locals); - #line 1654 "Python/generated_cases.c.h" - _tmp_1 = locals; } - { - PyObject *mod_or_class_dict = _tmp_1; - PyObject *v; - #line 1181 "Python/bytecodes.c" - PyObject *name = GETITEM(frame->f_code->co_names, oparg); - if (PyDict_CheckExact(mod_or_class_dict)) { - v = PyDict_GetItemWithError(mod_or_class_dict, name); - if (v != NULL) { - Py_INCREF(v); - } - else if (_PyErr_Occurred(tstate)) { - Py_DECREF(mod_or_class_dict); + else { + v = PyObject_GetItem(mod_or_class_dict, name); + if (v == NULL) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { goto error; } + _PyErr_Clear(tstate); + } + } + if (v == NULL) { + v = PyDict_GetItemWithError(GLOBALS(), name); + if (v != NULL) { + Py_INCREF(v); + } + else if (_PyErr_Occurred(tstate)) { + goto error; } else { - v = PyObject_GetItem(mod_or_class_dict, name); - if (v == NULL) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - Py_DECREF(mod_or_class_dict); + if (PyDict_CheckExact(BUILTINS())) { + v = PyDict_GetItemWithError(BUILTINS(), name); + if (v == NULL) { + if (!_PyErr_Occurred(tstate)) { + format_exc_check_arg( + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } goto error; } - _PyErr_Clear(tstate); - } - } - Py_DECREF(mod_or_class_dict); - if (v == NULL) { - v = PyDict_GetItemWithError(GLOBALS(), name); - if (v != NULL) { Py_INCREF(v); } - else if (_PyErr_Occurred(tstate)) { - goto error; - } else { - if (PyDict_CheckExact(BUILTINS())) { - v = PyDict_GetItemWithError(BUILTINS(), name); - if (v == NULL) { - if (!_PyErr_Occurred(tstate)) { - format_exc_check_arg( + v = PyObject_GetItem(BUILTINS(), name); + if (v == NULL) { + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + format_exc_check_arg( tstate, PyExc_NameError, NAME_ERROR_MSG, name); - } - goto error; - } - Py_INCREF(v); - } - else { - v = PyObject_GetItem(BUILTINS(), name); - if (v == NULL) { - if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - format_exc_check_arg( - tstate, PyExc_NameError, - NAME_ERROR_MSG, name); - } - goto error; } + goto error; } } } - #line 1717 "Python/generated_cases.c.h" - _tmp_1 = v; } - STACK_GROW(1); - stack_pointer[-1] = _tmp_1; + #line 1695 "Python/generated_cases.c.h" + Py_DECREF(mod_or_class_dict); + stack_pointer[-1] = v; DISPATCH(); } - TARGET(LOAD_FROM_DICT_OR_GLOBALS) { - PyObject *_tmp_1 = stack_pointer[-1]; - { - PyObject *mod_or_class_dict = _tmp_1; - PyObject *v; - #line 1181 "Python/bytecodes.c" - PyObject *name = GETITEM(frame->f_code->co_names, oparg); - if (PyDict_CheckExact(mod_or_class_dict)) { - v = PyDict_GetItemWithError(mod_or_class_dict, name); - if (v != NULL) { - Py_INCREF(v); - } - else if (_PyErr_Occurred(tstate)) { - Py_DECREF(mod_or_class_dict); + TARGET(LOAD_NAME) { + PyObject *v; + #line 1236 "Python/bytecodes.c" + PyObject *mod_or_class_dict = LOCALS(); + if (mod_or_class_dict == NULL) { + _PyErr_SetString(tstate, PyExc_SystemError, + "no locals found"); + if (true) goto error; + } + PyObject *name = GETITEM(frame->f_code->co_names, oparg); + if (PyDict_CheckExact(mod_or_class_dict)) { + v = PyDict_GetItemWithError(mod_or_class_dict, name); + if (v != NULL) { + Py_INCREF(v); + } + else if (_PyErr_Occurred(tstate)) { + goto error; + } + } + else { + v = PyObject_GetItem(mod_or_class_dict, name); + if (v == NULL) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { goto error; } + _PyErr_Clear(tstate); + } + } + if (v == NULL) { + v = PyDict_GetItemWithError(GLOBALS(), name); + if (v != NULL) { + Py_INCREF(v); + } + else if (_PyErr_Occurred(tstate)) { + goto error; } else { - v = PyObject_GetItem(mod_or_class_dict, name); - if (v == NULL) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - Py_DECREF(mod_or_class_dict); + if (PyDict_CheckExact(BUILTINS())) { + v = PyDict_GetItemWithError(BUILTINS(), name); + if (v == NULL) { + if (!_PyErr_Occurred(tstate)) { + format_exc_check_arg( + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } goto error; } - _PyErr_Clear(tstate); - } - } - Py_DECREF(mod_or_class_dict); - if (v == NULL) { - v = PyDict_GetItemWithError(GLOBALS(), name); - if (v != NULL) { Py_INCREF(v); } - else if (_PyErr_Occurred(tstate)) { - goto error; - } else { - if (PyDict_CheckExact(BUILTINS())) { - v = PyDict_GetItemWithError(BUILTINS(), name); - if (v == NULL) { - if (!_PyErr_Occurred(tstate)) { - format_exc_check_arg( + v = PyObject_GetItem(BUILTINS(), name); + if (v == NULL) { + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + format_exc_check_arg( tstate, PyExc_NameError, NAME_ERROR_MSG, name); - } - goto error; - } - Py_INCREF(v); - } - else { - v = PyObject_GetItem(BUILTINS(), name); - if (v == NULL) { - if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - format_exc_check_arg( - tstate, PyExc_NameError, - NAME_ERROR_MSG, name); - } - goto error; } + goto error; } } } - #line 1787 "Python/generated_cases.c.h" - _tmp_1 = v; } - stack_pointer[-1] = _tmp_1; + #line 1763 "Python/generated_cases.c.h" + STACK_GROW(1); + stack_pointer[-1] = v; DISPATCH(); } @@ -1795,7 +1770,7 @@ static_assert(INLINE_CACHE_ENTRIES_LOAD_GLOBAL == 4, "incorrect cache size"); PyObject *null = NULL; PyObject *v; - #line 1250 "Python/bytecodes.c" + #line 1304 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -1847,7 +1822,7 @@ } } null = NULL; - #line 1851 "Python/generated_cases.c.h" + #line 1826 "Python/generated_cases.c.h" STACK_GROW(1); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = v; @@ -1861,7 +1836,7 @@ PyObject *res; uint16_t index = read_u16(&next_instr[1].cache); uint16_t version = read_u16(&next_instr[2].cache); - #line 1304 "Python/bytecodes.c" + #line 1358 "Python/bytecodes.c" DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL); PyDictObject *dict = (PyDictObject *)GLOBALS(); DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); @@ -1872,7 +1847,7 @@ Py_INCREF(res); STAT_INC(LOAD_GLOBAL, hit); null = NULL; - #line 1876 "Python/generated_cases.c.h" + #line 1851 "Python/generated_cases.c.h" STACK_GROW(1); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -1887,7 +1862,7 @@ uint16_t index = read_u16(&next_instr[1].cache); uint16_t mod_version = read_u16(&next_instr[2].cache); uint16_t bltn_version = read_u16(&next_instr[3].cache); - #line 1317 "Python/bytecodes.c" + #line 1371 "Python/bytecodes.c" DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL); DEOPT_IF(!PyDict_CheckExact(BUILTINS()), LOAD_GLOBAL); PyDictObject *mdict = (PyDictObject *)GLOBALS(); @@ -1902,7 +1877,7 @@ Py_INCREF(res); STAT_INC(LOAD_GLOBAL, hit); null = NULL; - #line 1906 "Python/generated_cases.c.h" + #line 1881 "Python/generated_cases.c.h" STACK_GROW(1); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -1912,16 +1887,16 @@ } TARGET(DELETE_FAST) { - #line 1334 "Python/bytecodes.c" + #line 1388 "Python/bytecodes.c" PyObject *v = GETLOCAL(oparg); if (v == NULL) goto unbound_local_error; SETLOCAL(oparg, NULL); - #line 1920 "Python/generated_cases.c.h" + #line 1895 "Python/generated_cases.c.h" DISPATCH(); } TARGET(MAKE_CELL) { - #line 1340 "Python/bytecodes.c" + #line 1394 "Python/bytecodes.c" // "initial" is probably NULL but not if it's an arg (or set // via PyFrame_LocalsToFast() before MAKE_CELL has run). PyObject *initial = GETLOCAL(oparg); @@ -1930,12 +1905,12 @@ goto resume_with_error; } SETLOCAL(oparg, cell); - #line 1934 "Python/generated_cases.c.h" + #line 1909 "Python/generated_cases.c.h" DISPATCH(); } TARGET(DELETE_DEREF) { - #line 1351 "Python/bytecodes.c" + #line 1405 "Python/bytecodes.c" PyObject *cell = GETLOCAL(oparg); PyObject *oldobj = PyCell_GET(cell); // Can't use ERROR_IF here. @@ -1946,14 +1921,14 @@ } PyCell_SET(cell, NULL); Py_DECREF(oldobj); - #line 1950 "Python/generated_cases.c.h" + #line 1925 "Python/generated_cases.c.h" DISPATCH(); } TARGET(LOAD_FROM_DICT_OR_DEREF) { PyObject *class_dict = stack_pointer[-1]; PyObject *value; - #line 1364 "Python/bytecodes.c" + #line 1418 "Python/bytecodes.c" PyObject *name; assert(class_dict); assert(oparg >= 0 && oparg < frame->f_code->co_nlocalsplus); @@ -1988,14 +1963,14 @@ } Py_INCREF(value); } - #line 1992 "Python/generated_cases.c.h" + #line 1967 "Python/generated_cases.c.h" stack_pointer[-1] = value; DISPATCH(); } TARGET(LOAD_DEREF) { PyObject *value; - #line 1401 "Python/bytecodes.c" + #line 1455 "Python/bytecodes.c" PyObject *cell = GETLOCAL(oparg); value = PyCell_GET(cell); if (value == NULL) { @@ -2003,7 +1978,7 @@ if (true) goto error; } Py_INCREF(value); - #line 2007 "Python/generated_cases.c.h" + #line 1982 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = value; DISPATCH(); @@ -2011,18 +1986,18 @@ TARGET(STORE_DEREF) { PyObject *v = stack_pointer[-1]; - #line 1411 "Python/bytecodes.c" + #line 1465 "Python/bytecodes.c" PyObject *cell = GETLOCAL(oparg); PyObject *oldobj = PyCell_GET(cell); PyCell_SET(cell, v); Py_XDECREF(oldobj); - #line 2020 "Python/generated_cases.c.h" + #line 1995 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(COPY_FREE_VARS) { - #line 1418 "Python/bytecodes.c" + #line 1472 "Python/bytecodes.c" /* Copy closure variables to free variables */ PyCodeObject *co = frame->f_code; assert(PyFunction_Check(frame->f_funcobj)); @@ -2033,22 +2008,22 @@ PyObject *o = PyTuple_GET_ITEM(closure, i); frame->localsplus[offset + i] = Py_NewRef(o); } - #line 2037 "Python/generated_cases.c.h" + #line 2012 "Python/generated_cases.c.h" DISPATCH(); } TARGET(BUILD_STRING) { PyObject **pieces = (stack_pointer - oparg); PyObject *str; - #line 1431 "Python/bytecodes.c" + #line 1485 "Python/bytecodes.c" str = _PyUnicode_JoinArray(&_Py_STR(empty), pieces, oparg); - #line 2046 "Python/generated_cases.c.h" + #line 2021 "Python/generated_cases.c.h" for (int _i = oparg; --_i >= 0;) { Py_DECREF(pieces[_i]); } - #line 1433 "Python/bytecodes.c" + #line 1487 "Python/bytecodes.c" if (str == NULL) { STACK_SHRINK(oparg); goto error; } - #line 2052 "Python/generated_cases.c.h" + #line 2027 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_GROW(1); stack_pointer[-1] = str; @@ -2058,10 +2033,10 @@ TARGET(BUILD_TUPLE) { PyObject **values = (stack_pointer - oparg); PyObject *tup; - #line 1437 "Python/bytecodes.c" + #line 1491 "Python/bytecodes.c" tup = _PyTuple_FromArraySteal(values, oparg); if (tup == NULL) { STACK_SHRINK(oparg); goto error; } - #line 2065 "Python/generated_cases.c.h" + #line 2040 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_GROW(1); stack_pointer[-1] = tup; @@ -2071,10 +2046,10 @@ TARGET(BUILD_LIST) { PyObject **values = (stack_pointer - oparg); PyObject *list; - #line 1442 "Python/bytecodes.c" + #line 1496 "Python/bytecodes.c" list = _PyList_FromArraySteal(values, oparg); if (list == NULL) { STACK_SHRINK(oparg); goto error; } - #line 2078 "Python/generated_cases.c.h" + #line 2053 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_GROW(1); stack_pointer[-1] = list; @@ -2084,7 +2059,7 @@ TARGET(LIST_EXTEND) { PyObject *iterable = stack_pointer[-1]; PyObject *list = stack_pointer[-(2 + (oparg-1))]; - #line 1447 "Python/bytecodes.c" + #line 1501 "Python/bytecodes.c" PyObject *none_val = _PyList_Extend((PyListObject *)list, iterable); if (none_val == NULL) { if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) && @@ -2095,13 +2070,13 @@ "Value after * must be an iterable, not %.200s", Py_TYPE(iterable)->tp_name); } - #line 2099 "Python/generated_cases.c.h" + #line 2074 "Python/generated_cases.c.h" Py_DECREF(iterable); - #line 1458 "Python/bytecodes.c" + #line 1512 "Python/bytecodes.c" if (true) goto pop_1_error; } assert(Py_IsNone(none_val)); - #line 2105 "Python/generated_cases.c.h" + #line 2080 "Python/generated_cases.c.h" Py_DECREF(iterable); STACK_SHRINK(1); DISPATCH(); @@ -2110,13 +2085,13 @@ TARGET(SET_UPDATE) { PyObject *iterable = stack_pointer[-1]; PyObject *set = stack_pointer[-(2 + (oparg-1))]; - #line 1465 "Python/bytecodes.c" + #line 1519 "Python/bytecodes.c" int err = _PySet_Update(set, iterable); - #line 2116 "Python/generated_cases.c.h" + #line 2091 "Python/generated_cases.c.h" Py_DECREF(iterable); - #line 1467 "Python/bytecodes.c" + #line 1521 "Python/bytecodes.c" if (err < 0) goto pop_1_error; - #line 2120 "Python/generated_cases.c.h" + #line 2095 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } @@ -2124,7 +2099,7 @@ TARGET(BUILD_SET) { PyObject **values = (stack_pointer - oparg); PyObject *set; - #line 1471 "Python/bytecodes.c" + #line 1525 "Python/bytecodes.c" set = PySet_New(NULL); if (set == NULL) goto error; @@ -2139,7 +2114,7 @@ Py_DECREF(set); if (true) { STACK_SHRINK(oparg); goto error; } } - #line 2143 "Python/generated_cases.c.h" + #line 2118 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_GROW(1); stack_pointer[-1] = set; @@ -2149,7 +2124,7 @@ TARGET(BUILD_MAP) { PyObject **values = (stack_pointer - oparg*2); PyObject *map; - #line 1488 "Python/bytecodes.c" + #line 1542 "Python/bytecodes.c" map = _PyDict_FromItems( values, 2, values+1, 2, @@ -2157,13 +2132,13 @@ if (map == NULL) goto error; - #line 2161 "Python/generated_cases.c.h" + #line 2136 "Python/generated_cases.c.h" for (int _i = oparg*2; --_i >= 0;) { Py_DECREF(values[_i]); } - #line 1496 "Python/bytecodes.c" + #line 1550 "Python/bytecodes.c" if (map == NULL) { STACK_SHRINK(oparg*2); goto error; } - #line 2167 "Python/generated_cases.c.h" + #line 2142 "Python/generated_cases.c.h" STACK_SHRINK(oparg*2); STACK_GROW(1); stack_pointer[-1] = map; @@ -2171,7 +2146,7 @@ } TARGET(SETUP_ANNOTATIONS) { - #line 1500 "Python/bytecodes.c" + #line 1554 "Python/bytecodes.c" int err; PyObject *ann_dict; if (LOCALS() == NULL) { @@ -2211,7 +2186,7 @@ Py_DECREF(ann_dict); } } - #line 2215 "Python/generated_cases.c.h" + #line 2190 "Python/generated_cases.c.h" DISPATCH(); } @@ -2219,7 +2194,7 @@ PyObject *keys = stack_pointer[-1]; PyObject **values = (stack_pointer - (1 + oparg)); PyObject *map; - #line 1542 "Python/bytecodes.c" + #line 1596 "Python/bytecodes.c" if (!PyTuple_CheckExact(keys) || PyTuple_GET_SIZE(keys) != (Py_ssize_t)oparg) { _PyErr_SetString(tstate, PyExc_SystemError, @@ -2229,14 +2204,14 @@ map = _PyDict_FromItems( &PyTuple_GET_ITEM(keys, 0), 1, values, 1, oparg); - #line 2233 "Python/generated_cases.c.h" + #line 2208 "Python/generated_cases.c.h" for (int _i = oparg; --_i >= 0;) { Py_DECREF(values[_i]); } Py_DECREF(keys); - #line 1552 "Python/bytecodes.c" + #line 1606 "Python/bytecodes.c" if (map == NULL) { STACK_SHRINK(oparg); goto pop_1_error; } - #line 2240 "Python/generated_cases.c.h" + #line 2215 "Python/generated_cases.c.h" STACK_SHRINK(oparg); stack_pointer[-1] = map; DISPATCH(); @@ -2244,7 +2219,7 @@ TARGET(DICT_UPDATE) { PyObject *update = stack_pointer[-1]; - #line 1556 "Python/bytecodes.c" + #line 1610 "Python/bytecodes.c" PyObject *dict = PEEK(oparg + 1); // update is still on the stack if (PyDict_Update(dict, update) < 0) { if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { @@ -2252,12 +2227,12 @@ "'%.200s' object is not a mapping", Py_TYPE(update)->tp_name); } - #line 2256 "Python/generated_cases.c.h" + #line 2231 "Python/generated_cases.c.h" Py_DECREF(update); - #line 1564 "Python/bytecodes.c" + #line 1618 "Python/bytecodes.c" if (true) goto pop_1_error; } - #line 2261 "Python/generated_cases.c.h" + #line 2236 "Python/generated_cases.c.h" Py_DECREF(update); STACK_SHRINK(1); DISPATCH(); @@ -2265,17 +2240,17 @@ TARGET(DICT_MERGE) { PyObject *update = stack_pointer[-1]; - #line 1570 "Python/bytecodes.c" + #line 1624 "Python/bytecodes.c" PyObject *dict = PEEK(oparg + 1); // update is still on the stack if (_PyDict_MergeEx(dict, update, 2) < 0) { format_kwargs_error(tstate, PEEK(3 + oparg), update); - #line 2274 "Python/generated_cases.c.h" + #line 2249 "Python/generated_cases.c.h" Py_DECREF(update); - #line 1575 "Python/bytecodes.c" + #line 1629 "Python/bytecodes.c" if (true) goto pop_1_error; } - #line 2279 "Python/generated_cases.c.h" + #line 2254 "Python/generated_cases.c.h" Py_DECREF(update); STACK_SHRINK(1); PREDICT(CALL_FUNCTION_EX); @@ -2285,26 +2260,26 @@ TARGET(MAP_ADD) { PyObject *value = stack_pointer[-1]; PyObject *key = stack_pointer[-2]; - #line 1582 "Python/bytecodes.c" + #line 1636 "Python/bytecodes.c" PyObject *dict = PEEK(oparg + 2); // key, value are still on the stack assert(PyDict_CheckExact(dict)); /* dict[key] = value */ // Do not DECREF INPUTS because the function steals the references if (_PyDict_SetItem_Take2((PyDictObject *)dict, key, value) != 0) goto pop_2_error; - #line 2295 "Python/generated_cases.c.h" + #line 2270 "Python/generated_cases.c.h" STACK_SHRINK(2); PREDICT(JUMP_BACKWARD); DISPATCH(); } TARGET(INSTRUMENTED_LOAD_SUPER_ATTR) { - #line 1591 "Python/bytecodes.c" + #line 1645 "Python/bytecodes.c" _PySuperAttrCache *cache = (_PySuperAttrCache *)next_instr; // cancel out the decrement that will happen in LOAD_SUPER_ATTR; we // don't want to specialize instrumented instructions INCREMENT_ADAPTIVE_COUNTER(cache->counter); GO_TO_INSTRUCTION(LOAD_SUPER_ATTR); - #line 2308 "Python/generated_cases.c.h" + #line 2283 "Python/generated_cases.c.h" } TARGET(LOAD_SUPER_ATTR) { @@ -2315,7 +2290,7 @@ PyObject *global_super = stack_pointer[-3]; PyObject *res2 = NULL; PyObject *res; - #line 1605 "Python/bytecodes.c" + #line 1659 "Python/bytecodes.c" PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 2); int load_method = oparg & 1; #if ENABLE_SPECIALIZATION @@ -2357,16 +2332,16 @@ } } } - #line 2361 "Python/generated_cases.c.h" + #line 2336 "Python/generated_cases.c.h" Py_DECREF(global_super); Py_DECREF(class); Py_DECREF(self); - #line 1647 "Python/bytecodes.c" + #line 1701 "Python/bytecodes.c" if (super == NULL) goto pop_3_error; res = PyObject_GetAttr(super, name); Py_DECREF(super); if (res == NULL) goto pop_3_error; - #line 2370 "Python/generated_cases.c.h" + #line 2345 "Python/generated_cases.c.h" STACK_SHRINK(2); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -2381,20 +2356,20 @@ PyObject *global_super = stack_pointer[-3]; PyObject *res2 = NULL; PyObject *res; - #line 1654 "Python/bytecodes.c" + #line 1708 "Python/bytecodes.c" assert(!(oparg & 1)); DEOPT_IF(global_super != (PyObject *)&PySuper_Type, LOAD_SUPER_ATTR); DEOPT_IF(!PyType_Check(class), LOAD_SUPER_ATTR); STAT_INC(LOAD_SUPER_ATTR, hit); PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 2); res = _PySuper_Lookup((PyTypeObject *)class, self, name, NULL); - #line 2392 "Python/generated_cases.c.h" + #line 2367 "Python/generated_cases.c.h" Py_DECREF(global_super); Py_DECREF(class); Py_DECREF(self); - #line 1661 "Python/bytecodes.c" + #line 1715 "Python/bytecodes.c" if (res == NULL) goto pop_3_error; - #line 2398 "Python/generated_cases.c.h" + #line 2373 "Python/generated_cases.c.h" STACK_SHRINK(2); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -2409,7 +2384,7 @@ PyObject *global_super = stack_pointer[-3]; PyObject *res2; PyObject *res; - #line 1665 "Python/bytecodes.c" + #line 1719 "Python/bytecodes.c" assert(oparg & 1); DEOPT_IF(global_super != (PyObject *)&PySuper_Type, LOAD_SUPER_ATTR); DEOPT_IF(!PyType_Check(class), LOAD_SUPER_ATTR); @@ -2432,7 +2407,7 @@ res = res2; res2 = NULL; } - #line 2436 "Python/generated_cases.c.h" + #line 2411 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; stack_pointer[-2] = res2; @@ -2446,7 +2421,7 @@ PyObject *owner = stack_pointer[-1]; PyObject *res2 = NULL; PyObject *res; - #line 1704 "Python/bytecodes.c" + #line 1758 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION _PyAttrCache *cache = (_PyAttrCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -2480,9 +2455,9 @@ NULL | meth | arg1 | ... | argN */ - #line 2484 "Python/generated_cases.c.h" + #line 2459 "Python/generated_cases.c.h" Py_DECREF(owner); - #line 1738 "Python/bytecodes.c" + #line 1792 "Python/bytecodes.c" if (meth == NULL) goto pop_1_error; res2 = NULL; res = meth; @@ -2491,12 +2466,12 @@ else { /* Classic, pushes one value. */ res = PyObject_GetAttr(owner, name); - #line 2495 "Python/generated_cases.c.h" + #line 2470 "Python/generated_cases.c.h" Py_DECREF(owner); - #line 1747 "Python/bytecodes.c" + #line 1801 "Python/bytecodes.c" if (res == NULL) goto pop_1_error; } - #line 2500 "Python/generated_cases.c.h" + #line 2475 "Python/generated_cases.c.h" STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } @@ -2510,7 +2485,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); uint16_t index = read_u16(&next_instr[3].cache); - #line 1752 "Python/bytecodes.c" + #line 1806 "Python/bytecodes.c" PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); @@ -2523,7 +2498,7 @@ STAT_INC(LOAD_ATTR, hit); Py_INCREF(res); res2 = NULL; - #line 2527 "Python/generated_cases.c.h" + #line 2502 "Python/generated_cases.c.h" Py_DECREF(owner); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -2538,7 +2513,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); uint16_t index = read_u16(&next_instr[3].cache); - #line 1768 "Python/bytecodes.c" + #line 1822 "Python/bytecodes.c" DEOPT_IF(!PyModule_CheckExact(owner), LOAD_ATTR); PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict; assert(dict != NULL); @@ -2551,7 +2526,7 @@ STAT_INC(LOAD_ATTR, hit); Py_INCREF(res); res2 = NULL; - #line 2555 "Python/generated_cases.c.h" + #line 2530 "Python/generated_cases.c.h" Py_DECREF(owner); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -2566,7 +2541,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); uint16_t index = read_u16(&next_instr[3].cache); - #line 1784 "Python/bytecodes.c" + #line 1838 "Python/bytecodes.c" PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); @@ -2593,7 +2568,7 @@ STAT_INC(LOAD_ATTR, hit); Py_INCREF(res); res2 = NULL; - #line 2597 "Python/generated_cases.c.h" + #line 2572 "Python/generated_cases.c.h" Py_DECREF(owner); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -2608,7 +2583,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); uint16_t index = read_u16(&next_instr[3].cache); - #line 1814 "Python/bytecodes.c" + #line 1868 "Python/bytecodes.c" PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); @@ -2618,7 +2593,7 @@ STAT_INC(LOAD_ATTR, hit); Py_INCREF(res); res2 = NULL; - #line 2622 "Python/generated_cases.c.h" + #line 2597 "Python/generated_cases.c.h" Py_DECREF(owner); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -2633,7 +2608,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); PyObject *descr = read_obj(&next_instr[5].cache); - #line 1827 "Python/bytecodes.c" + #line 1881 "Python/bytecodes.c" DEOPT_IF(!PyType_Check(cls), LOAD_ATTR); DEOPT_IF(((PyTypeObject *)cls)->tp_version_tag != type_version, @@ -2645,7 +2620,7 @@ res = descr; assert(res != NULL); Py_INCREF(res); - #line 2649 "Python/generated_cases.c.h" + #line 2624 "Python/generated_cases.c.h" Py_DECREF(cls); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -2659,7 +2634,7 @@ uint32_t type_version = read_u32(&next_instr[1].cache); uint32_t func_version = read_u32(&next_instr[3].cache); PyObject *fget = read_obj(&next_instr[5].cache); - #line 1842 "Python/bytecodes.c" + #line 1896 "Python/bytecodes.c" DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR); PyTypeObject *cls = Py_TYPE(owner); @@ -2683,7 +2658,7 @@ JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); frame->return_offset = 0; DISPATCH_INLINED(new_frame); - #line 2687 "Python/generated_cases.c.h" + #line 2662 "Python/generated_cases.c.h" } TARGET(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN) { @@ -2691,7 +2666,7 @@ uint32_t type_version = read_u32(&next_instr[1].cache); uint32_t func_version = read_u32(&next_instr[3].cache); PyObject *getattribute = read_obj(&next_instr[5].cache); - #line 1868 "Python/bytecodes.c" + #line 1922 "Python/bytecodes.c" DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR); PyTypeObject *cls = Py_TYPE(owner); DEOPT_IF(cls->tp_version_tag != type_version, LOAD_ATTR); @@ -2717,7 +2692,7 @@ JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); frame->return_offset = 0; DISPATCH_INLINED(new_frame); - #line 2721 "Python/generated_cases.c.h" + #line 2696 "Python/generated_cases.c.h" } TARGET(STORE_ATTR_INSTANCE_VALUE) { @@ -2725,7 +2700,7 @@ PyObject *value = stack_pointer[-2]; uint32_t type_version = read_u32(&next_instr[1].cache); uint16_t index = read_u16(&next_instr[3].cache); - #line 1896 "Python/bytecodes.c" + #line 1950 "Python/bytecodes.c" PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); @@ -2743,7 +2718,7 @@ Py_DECREF(old_value); } Py_DECREF(owner); - #line 2747 "Python/generated_cases.c.h" + #line 2722 "Python/generated_cases.c.h" STACK_SHRINK(2); next_instr += 4; DISPATCH(); @@ -2754,7 +2729,7 @@ PyObject *value = stack_pointer[-2]; uint32_t type_version = read_u32(&next_instr[1].cache); uint16_t hint = read_u16(&next_instr[3].cache); - #line 1916 "Python/bytecodes.c" + #line 1970 "Python/bytecodes.c" PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); @@ -2793,7 +2768,7 @@ /* PEP 509 */ dict->ma_version_tag = new_version; Py_DECREF(owner); - #line 2797 "Python/generated_cases.c.h" + #line 2772 "Python/generated_cases.c.h" STACK_SHRINK(2); next_instr += 4; DISPATCH(); @@ -2804,7 +2779,7 @@ PyObject *value = stack_pointer[-2]; uint32_t type_version = read_u32(&next_instr[1].cache); uint16_t index = read_u16(&next_instr[3].cache); - #line 1957 "Python/bytecodes.c" + #line 2011 "Python/bytecodes.c" PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); @@ -2814,7 +2789,7 @@ *(PyObject **)addr = value; Py_XDECREF(old_value); Py_DECREF(owner); - #line 2818 "Python/generated_cases.c.h" + #line 2793 "Python/generated_cases.c.h" STACK_SHRINK(2); next_instr += 4; DISPATCH(); @@ -2826,7 +2801,7 @@ PyObject *right = stack_pointer[-1]; PyObject *left = stack_pointer[-2]; PyObject *res; - #line 1976 "Python/bytecodes.c" + #line 2030 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION _PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -2839,12 +2814,12 @@ #endif /* ENABLE_SPECIALIZATION */ assert((oparg >> 4) <= Py_GE); res = PyObject_RichCompare(left, right, oparg>>4); - #line 2843 "Python/generated_cases.c.h" + #line 2818 "Python/generated_cases.c.h" Py_DECREF(left); Py_DECREF(right); - #line 1989 "Python/bytecodes.c" + #line 2043 "Python/bytecodes.c" if (res == NULL) goto pop_2_error; - #line 2848 "Python/generated_cases.c.h" + #line 2823 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; next_instr += 1; @@ -2855,7 +2830,7 @@ PyObject *right = stack_pointer[-1]; PyObject *left = stack_pointer[-2]; PyObject *res; - #line 1993 "Python/bytecodes.c" + #line 2047 "Python/bytecodes.c" DEOPT_IF(!PyFloat_CheckExact(left), COMPARE_OP); DEOPT_IF(!PyFloat_CheckExact(right), COMPARE_OP); STAT_INC(COMPARE_OP, hit); @@ -2866,7 +2841,7 @@ _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc); _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc); res = (sign_ish & oparg) ? Py_True : Py_False; - #line 2870 "Python/generated_cases.c.h" + #line 2845 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; next_instr += 1; @@ -2877,7 +2852,7 @@ PyObject *right = stack_pointer[-1]; PyObject *left = stack_pointer[-2]; PyObject *res; - #line 2007 "Python/bytecodes.c" + #line 2061 "Python/bytecodes.c" DEOPT_IF(!PyLong_CheckExact(left), COMPARE_OP); DEOPT_IF(!PyLong_CheckExact(right), COMPARE_OP); DEOPT_IF(!_PyLong_IsCompact((PyLongObject *)left), COMPARE_OP); @@ -2892,7 +2867,7 @@ _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); res = (sign_ish & oparg) ? Py_True : Py_False; - #line 2896 "Python/generated_cases.c.h" + #line 2871 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; next_instr += 1; @@ -2903,7 +2878,7 @@ PyObject *right = stack_pointer[-1]; PyObject *left = stack_pointer[-2]; PyObject *res; - #line 2025 "Python/bytecodes.c" + #line 2079 "Python/bytecodes.c" DEOPT_IF(!PyUnicode_CheckExact(left), COMPARE_OP); DEOPT_IF(!PyUnicode_CheckExact(right), COMPARE_OP); STAT_INC(COMPARE_OP, hit); @@ -2915,7 +2890,7 @@ assert((oparg & 0xf) == COMPARISON_NOT_EQUALS || (oparg & 0xf) == COMPARISON_EQUALS); assert(COMPARISON_NOT_EQUALS + 1 == COMPARISON_EQUALS); res = ((COMPARISON_NOT_EQUALS + eq) & oparg) ? Py_True : Py_False; - #line 2919 "Python/generated_cases.c.h" + #line 2894 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; next_instr += 1; @@ -2926,14 +2901,14 @@ PyObject *right = stack_pointer[-1]; PyObject *left = stack_pointer[-2]; PyObject *b; - #line 2039 "Python/bytecodes.c" + #line 2093 "Python/bytecodes.c" int res = Py_Is(left, right) ^ oparg; - #line 2932 "Python/generated_cases.c.h" + #line 2907 "Python/generated_cases.c.h" Py_DECREF(left); Py_DECREF(right); - #line 2041 "Python/bytecodes.c" + #line 2095 "Python/bytecodes.c" b = res ? Py_True : Py_False; - #line 2937 "Python/generated_cases.c.h" + #line 2912 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = b; DISPATCH(); @@ -2943,15 +2918,15 @@ PyObject *right = stack_pointer[-1]; PyObject *left = stack_pointer[-2]; PyObject *b; - #line 2045 "Python/bytecodes.c" + #line 2099 "Python/bytecodes.c" int res = PySequence_Contains(right, left); - #line 2949 "Python/generated_cases.c.h" + #line 2924 "Python/generated_cases.c.h" Py_DECREF(left); Py_DECREF(right); - #line 2047 "Python/bytecodes.c" + #line 2101 "Python/bytecodes.c" if (res < 0) goto pop_2_error; b = (res ^ oparg) ? Py_True : Py_False; - #line 2955 "Python/generated_cases.c.h" + #line 2930 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = b; DISPATCH(); @@ -2962,12 +2937,12 @@ PyObject *exc_value = stack_pointer[-2]; PyObject *rest; PyObject *match; - #line 2052 "Python/bytecodes.c" + #line 2106 "Python/bytecodes.c" if (check_except_star_type_valid(tstate, match_type) < 0) { - #line 2968 "Python/generated_cases.c.h" + #line 2943 "Python/generated_cases.c.h" Py_DECREF(exc_value); Py_DECREF(match_type); - #line 2054 "Python/bytecodes.c" + #line 2108 "Python/bytecodes.c" if (true) goto pop_2_error; } @@ -2975,10 +2950,10 @@ rest = NULL; int res = exception_group_match(exc_value, match_type, &match, &rest); - #line 2979 "Python/generated_cases.c.h" + #line 2954 "Python/generated_cases.c.h" Py_DECREF(exc_value); Py_DECREF(match_type); - #line 2062 "Python/bytecodes.c" + #line 2116 "Python/bytecodes.c" if (res < 0) goto pop_2_error; assert((match == NULL) == (rest == NULL)); @@ -2987,7 +2962,7 @@ if (!Py_IsNone(match)) { PyErr_SetHandledException(match); } - #line 2991 "Python/generated_cases.c.h" + #line 2966 "Python/generated_cases.c.h" stack_pointer[-1] = match; stack_pointer[-2] = rest; DISPATCH(); @@ -2997,21 +2972,21 @@ PyObject *right = stack_pointer[-1]; PyObject *left = stack_pointer[-2]; PyObject *b; - #line 2073 "Python/bytecodes.c" + #line 2127 "Python/bytecodes.c" assert(PyExceptionInstance_Check(left)); if (check_except_type_valid(tstate, right) < 0) { - #line 3004 "Python/generated_cases.c.h" + #line 2979 "Python/generated_cases.c.h" Py_DECREF(right); - #line 2076 "Python/bytecodes.c" + #line 2130 "Python/bytecodes.c" if (true) goto pop_1_error; } int res = PyErr_GivenExceptionMatches(left, right); - #line 3011 "Python/generated_cases.c.h" + #line 2986 "Python/generated_cases.c.h" Py_DECREF(right); - #line 2081 "Python/bytecodes.c" + #line 2135 "Python/bytecodes.c" b = res ? Py_True : Py_False; - #line 3015 "Python/generated_cases.c.h" + #line 2990 "Python/generated_cases.c.h" stack_pointer[-1] = b; DISPATCH(); } @@ -3020,15 +2995,15 @@ PyObject *fromlist = stack_pointer[-1]; PyObject *level = stack_pointer[-2]; PyObject *res; - #line 2085 "Python/bytecodes.c" + #line 2139 "Python/bytecodes.c" PyObject *name = GETITEM(frame->f_code->co_names, oparg); res = import_name(tstate, frame, name, fromlist, level); - #line 3027 "Python/generated_cases.c.h" + #line 3002 "Python/generated_cases.c.h" Py_DECREF(level); Py_DECREF(fromlist); - #line 2088 "Python/bytecodes.c" + #line 2142 "Python/bytecodes.c" if (res == NULL) goto pop_2_error; - #line 3032 "Python/generated_cases.c.h" + #line 3007 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; DISPATCH(); @@ -3037,29 +3012,29 @@ TARGET(IMPORT_FROM) { PyObject *from = stack_pointer[-1]; PyObject *res; - #line 2092 "Python/bytecodes.c" + #line 2146 "Python/bytecodes.c" PyObject *name = GETITEM(frame->f_code->co_names, oparg); res = import_from(tstate, from, name); if (res == NULL) goto error; - #line 3045 "Python/generated_cases.c.h" + #line 3020 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; DISPATCH(); } TARGET(JUMP_FORWARD) { - #line 2098 "Python/bytecodes.c" + #line 2152 "Python/bytecodes.c" JUMPBY(oparg); - #line 3054 "Python/generated_cases.c.h" + #line 3029 "Python/generated_cases.c.h" DISPATCH(); } TARGET(JUMP_BACKWARD) { PREDICTED(JUMP_BACKWARD); - #line 2102 "Python/bytecodes.c" + #line 2156 "Python/bytecodes.c" assert(oparg < INSTR_OFFSET()); JUMPBY(-oparg); - #line 3063 "Python/generated_cases.c.h" + #line 3038 "Python/generated_cases.c.h" CHECK_EVAL_BREAKER(); DISPATCH(); } @@ -3067,15 +3042,15 @@ TARGET(POP_JUMP_IF_FALSE) { PREDICTED(POP_JUMP_IF_FALSE); PyObject *cond = stack_pointer[-1]; - #line 2108 "Python/bytecodes.c" + #line 2162 "Python/bytecodes.c" if (Py_IsFalse(cond)) { JUMPBY(oparg); } else if (!Py_IsTrue(cond)) { int err = PyObject_IsTrue(cond); - #line 3077 "Python/generated_cases.c.h" + #line 3052 "Python/generated_cases.c.h" Py_DECREF(cond); - #line 2114 "Python/bytecodes.c" + #line 2168 "Python/bytecodes.c" if (err == 0) { JUMPBY(oparg); } @@ -3083,22 +3058,22 @@ if (err < 0) goto pop_1_error; } } - #line 3087 "Python/generated_cases.c.h" + #line 3062 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(POP_JUMP_IF_TRUE) { PyObject *cond = stack_pointer[-1]; - #line 2124 "Python/bytecodes.c" + #line 2178 "Python/bytecodes.c" if (Py_IsTrue(cond)) { JUMPBY(oparg); } else if (!Py_IsFalse(cond)) { int err = PyObject_IsTrue(cond); - #line 3100 "Python/generated_cases.c.h" + #line 3075 "Python/generated_cases.c.h" Py_DECREF(cond); - #line 2130 "Python/bytecodes.c" + #line 2184 "Python/bytecodes.c" if (err > 0) { JUMPBY(oparg); } @@ -3106,63 +3081,63 @@ if (err < 0) goto pop_1_error; } } - #line 3110 "Python/generated_cases.c.h" + #line 3085 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(POP_JUMP_IF_NOT_NONE) { PyObject *value = stack_pointer[-1]; - #line 2140 "Python/bytecodes.c" + #line 2194 "Python/bytecodes.c" if (!Py_IsNone(value)) { - #line 3119 "Python/generated_cases.c.h" + #line 3094 "Python/generated_cases.c.h" Py_DECREF(value); - #line 2142 "Python/bytecodes.c" + #line 2196 "Python/bytecodes.c" JUMPBY(oparg); } - #line 3124 "Python/generated_cases.c.h" + #line 3099 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(POP_JUMP_IF_NONE) { PyObject *value = stack_pointer[-1]; - #line 2147 "Python/bytecodes.c" + #line 2201 "Python/bytecodes.c" if (Py_IsNone(value)) { JUMPBY(oparg); } else { - #line 3136 "Python/generated_cases.c.h" + #line 3111 "Python/generated_cases.c.h" Py_DECREF(value); - #line 2152 "Python/bytecodes.c" + #line 2206 "Python/bytecodes.c" } - #line 3140 "Python/generated_cases.c.h" + #line 3115 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(JUMP_BACKWARD_NO_INTERRUPT) { - #line 2156 "Python/bytecodes.c" + #line 2210 "Python/bytecodes.c" /* This bytecode is used in the `yield from` or `await` loop. * If there is an interrupt, we want it handled in the innermost * generator or coroutine, so we deliberately do not check it here. * (see bpo-30039). */ JUMPBY(-oparg); - #line 3153 "Python/generated_cases.c.h" + #line 3128 "Python/generated_cases.c.h" DISPATCH(); } TARGET(GET_LEN) { PyObject *obj = stack_pointer[-1]; PyObject *len_o; - #line 2165 "Python/bytecodes.c" + #line 2219 "Python/bytecodes.c" // PUSH(len(TOS)) Py_ssize_t len_i = PyObject_Length(obj); if (len_i < 0) goto error; len_o = PyLong_FromSsize_t(len_i); if (len_o == NULL) goto error; - #line 3166 "Python/generated_cases.c.h" + #line 3141 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = len_o; DISPATCH(); @@ -3173,16 +3148,16 @@ PyObject *type = stack_pointer[-2]; PyObject *subject = stack_pointer[-3]; PyObject *attrs; - #line 2173 "Python/bytecodes.c" + #line 2227 "Python/bytecodes.c" // Pop TOS and TOS1. Set TOS to a tuple of attributes on success, or // None on failure. assert(PyTuple_CheckExact(names)); attrs = match_class(tstate, subject, type, oparg, names); - #line 3182 "Python/generated_cases.c.h" + #line 3157 "Python/generated_cases.c.h" Py_DECREF(subject); Py_DECREF(type); Py_DECREF(names); - #line 2178 "Python/bytecodes.c" + #line 2232 "Python/bytecodes.c" if (attrs) { assert(PyTuple_CheckExact(attrs)); // Success! } @@ -3190,7 +3165,7 @@ if (_PyErr_Occurred(tstate)) goto pop_3_error; attrs = Py_None; // Failure! } - #line 3194 "Python/generated_cases.c.h" + #line 3169 "Python/generated_cases.c.h" STACK_SHRINK(2); stack_pointer[-1] = attrs; DISPATCH(); @@ -3199,10 +3174,10 @@ TARGET(MATCH_MAPPING) { PyObject *subject = stack_pointer[-1]; PyObject *res; - #line 2188 "Python/bytecodes.c" + #line 2242 "Python/bytecodes.c" int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_MAPPING; res = match ? Py_True : Py_False; - #line 3206 "Python/generated_cases.c.h" + #line 3181 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; PREDICT(POP_JUMP_IF_FALSE); @@ -3212,10 +3187,10 @@ TARGET(MATCH_SEQUENCE) { PyObject *subject = stack_pointer[-1]; PyObject *res; - #line 2194 "Python/bytecodes.c" + #line 2248 "Python/bytecodes.c" int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_SEQUENCE; res = match ? Py_True : Py_False; - #line 3219 "Python/generated_cases.c.h" + #line 3194 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; PREDICT(POP_JUMP_IF_FALSE); @@ -3226,11 +3201,11 @@ PyObject *keys = stack_pointer[-1]; PyObject *subject = stack_pointer[-2]; PyObject *values_or_none; - #line 2200 "Python/bytecodes.c" + #line 2254 "Python/bytecodes.c" // On successful match, PUSH(values). Otherwise, PUSH(None). values_or_none = match_keys(tstate, subject, keys); if (values_or_none == NULL) goto error; - #line 3234 "Python/generated_cases.c.h" + #line 3209 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = values_or_none; DISPATCH(); @@ -3239,14 +3214,14 @@ TARGET(GET_ITER) { PyObject *iterable = stack_pointer[-1]; PyObject *iter; - #line 2206 "Python/bytecodes.c" + #line 2260 "Python/bytecodes.c" /* before: [obj]; after [getiter(obj)] */ iter = PyObject_GetIter(iterable); - #line 3246 "Python/generated_cases.c.h" + #line 3221 "Python/generated_cases.c.h" Py_DECREF(iterable); - #line 2209 "Python/bytecodes.c" + #line 2263 "Python/bytecodes.c" if (iter == NULL) goto pop_1_error; - #line 3250 "Python/generated_cases.c.h" + #line 3225 "Python/generated_cases.c.h" stack_pointer[-1] = iter; DISPATCH(); } @@ -3254,7 +3229,7 @@ TARGET(GET_YIELD_FROM_ITER) { PyObject *iterable = stack_pointer[-1]; PyObject *iter; - #line 2213 "Python/bytecodes.c" + #line 2267 "Python/bytecodes.c" /* before: [obj]; after [getiter(obj)] */ if (PyCoro_CheckExact(iterable)) { /* `iterable` is a coroutine */ @@ -3277,11 +3252,11 @@ if (iter == NULL) { goto error; } - #line 3281 "Python/generated_cases.c.h" + #line 3256 "Python/generated_cases.c.h" Py_DECREF(iterable); - #line 2236 "Python/bytecodes.c" + #line 2290 "Python/bytecodes.c" } - #line 3285 "Python/generated_cases.c.h" + #line 3260 "Python/generated_cases.c.h" stack_pointer[-1] = iter; PREDICT(LOAD_CONST); DISPATCH(); @@ -3292,7 +3267,7 @@ static_assert(INLINE_CACHE_ENTRIES_FOR_ITER == 1, "incorrect cache size"); PyObject *iter = stack_pointer[-1]; PyObject *next; - #line 2255 "Python/bytecodes.c" + #line 2309 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION _PyForIterCache *cache = (_PyForIterCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -3323,7 +3298,7 @@ DISPATCH(); } // Common case: no jump, leave it to the code generator - #line 3327 "Python/generated_cases.c.h" + #line 3302 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = next; next_instr += 1; @@ -3331,7 +3306,7 @@ } TARGET(INSTRUMENTED_FOR_ITER) { - #line 2288 "Python/bytecodes.c" + #line 2342 "Python/bytecodes.c" _Py_CODEUNIT *here = next_instr-1; _Py_CODEUNIT *target; PyObject *iter = TOP(); @@ -3357,14 +3332,14 @@ target = next_instr + INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1; } INSTRUMENTED_JUMP(here, target, PY_MONITORING_EVENT_BRANCH); - #line 3361 "Python/generated_cases.c.h" + #line 3336 "Python/generated_cases.c.h" DISPATCH(); } TARGET(FOR_ITER_LIST) { PyObject *iter = stack_pointer[-1]; PyObject *next; - #line 2316 "Python/bytecodes.c" + #line 2370 "Python/bytecodes.c" DEOPT_IF(Py_TYPE(iter) != &PyListIter_Type, FOR_ITER); _PyListIterObject *it = (_PyListIterObject *)iter; STAT_INC(FOR_ITER, hit); @@ -3384,7 +3359,7 @@ DISPATCH(); end_for_iter_list: // Common case: no jump, leave it to the code generator - #line 3388 "Python/generated_cases.c.h" + #line 3363 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = next; next_instr += 1; @@ -3394,7 +3369,7 @@ TARGET(FOR_ITER_TUPLE) { PyObject *iter = stack_pointer[-1]; PyObject *next; - #line 2338 "Python/bytecodes.c" + #line 2392 "Python/bytecodes.c" _PyTupleIterObject *it = (_PyTupleIterObject *)iter; DEOPT_IF(Py_TYPE(it) != &PyTupleIter_Type, FOR_ITER); STAT_INC(FOR_ITER, hit); @@ -3414,7 +3389,7 @@ DISPATCH(); end_for_iter_tuple: // Common case: no jump, leave it to the code generator - #line 3418 "Python/generated_cases.c.h" + #line 3393 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = next; next_instr += 1; @@ -3424,7 +3399,7 @@ TARGET(FOR_ITER_RANGE) { PyObject *iter = stack_pointer[-1]; PyObject *next; - #line 2360 "Python/bytecodes.c" + #line 2414 "Python/bytecodes.c" _PyRangeIterObject *r = (_PyRangeIterObject *)iter; DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type, FOR_ITER); STAT_INC(FOR_ITER, hit); @@ -3442,7 +3417,7 @@ if (next == NULL) { goto error; } - #line 3446 "Python/generated_cases.c.h" + #line 3421 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = next; next_instr += 1; @@ -3451,7 +3426,7 @@ TARGET(FOR_ITER_GEN) { PyObject *iter = stack_pointer[-1]; - #line 2380 "Python/bytecodes.c" + #line 2434 "Python/bytecodes.c" DEOPT_IF(tstate->interp->eval_frame, FOR_ITER); PyGenObject *gen = (PyGenObject *)iter; DEOPT_IF(Py_TYPE(gen) != &PyGen_Type, FOR_ITER); @@ -3467,14 +3442,14 @@ assert(next_instr[oparg].op.code == END_FOR || next_instr[oparg].op.code == INSTRUMENTED_END_FOR); DISPATCH_INLINED(gen_frame); - #line 3471 "Python/generated_cases.c.h" + #line 3446 "Python/generated_cases.c.h" } TARGET(BEFORE_ASYNC_WITH) { PyObject *mgr = stack_pointer[-1]; PyObject *exit; PyObject *res; - #line 2398 "Python/bytecodes.c" + #line 2452 "Python/bytecodes.c" PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__aenter__)); if (enter == NULL) { if (!_PyErr_Occurred(tstate)) { @@ -3497,16 +3472,16 @@ Py_DECREF(enter); goto error; } - #line 3501 "Python/generated_cases.c.h" + #line 3476 "Python/generated_cases.c.h" Py_DECREF(mgr); - #line 2421 "Python/bytecodes.c" + #line 2475 "Python/bytecodes.c" res = _PyObject_CallNoArgs(enter); Py_DECREF(enter); if (res == NULL) { Py_DECREF(exit); if (true) goto pop_1_error; } - #line 3510 "Python/generated_cases.c.h" + #line 3485 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; stack_pointer[-2] = exit; @@ -3518,7 +3493,7 @@ PyObject *mgr = stack_pointer[-1]; PyObject *exit; PyObject *res; - #line 2431 "Python/bytecodes.c" + #line 2485 "Python/bytecodes.c" /* pop the context manager, push its __exit__ and the * value returned from calling its __enter__ */ @@ -3544,16 +3519,16 @@ Py_DECREF(enter); goto error; } - #line 3548 "Python/generated_cases.c.h" + #line 3523 "Python/generated_cases.c.h" Py_DECREF(mgr); - #line 2457 "Python/bytecodes.c" + #line 2511 "Python/bytecodes.c" res = _PyObject_CallNoArgs(enter); Py_DECREF(enter); if (res == NULL) { Py_DECREF(exit); if (true) goto pop_1_error; } - #line 3557 "Python/generated_cases.c.h" + #line 3532 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; stack_pointer[-2] = exit; @@ -3565,7 +3540,7 @@ PyObject *lasti = stack_pointer[-3]; PyObject *exit_func = stack_pointer[-4]; PyObject *res; - #line 2466 "Python/bytecodes.c" + #line 2520 "Python/bytecodes.c" /* At the top of the stack are 4 values: - val: TOP = exc_info() - unused: SECOND = previous exception @@ -3591,7 +3566,7 @@ res = PyObject_Vectorcall(exit_func, stack + 1, 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); if (res == NULL) goto error; - #line 3595 "Python/generated_cases.c.h" + #line 3570 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; DISPATCH(); @@ -3600,7 +3575,7 @@ TARGET(PUSH_EXC_INFO) { PyObject *new_exc = stack_pointer[-1]; PyObject *prev_exc; - #line 2494 "Python/bytecodes.c" + #line 2548 "Python/bytecodes.c" _PyErr_StackItem *exc_info = tstate->exc_info; if (exc_info->exc_value != NULL) { prev_exc = exc_info->exc_value; @@ -3610,7 +3585,7 @@ } assert(PyExceptionInstance_Check(new_exc)); exc_info->exc_value = Py_NewRef(new_exc); - #line 3614 "Python/generated_cases.c.h" + #line 3589 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = new_exc; stack_pointer[-2] = prev_exc; @@ -3624,7 +3599,7 @@ uint32_t type_version = read_u32(&next_instr[1].cache); uint32_t keys_version = read_u32(&next_instr[3].cache); PyObject *descr = read_obj(&next_instr[5].cache); - #line 2506 "Python/bytecodes.c" + #line 2560 "Python/bytecodes.c" /* Cached method object */ PyTypeObject *self_cls = Py_TYPE(self); assert(type_version != 0); @@ -3641,7 +3616,7 @@ assert(_PyType_HasFeature(Py_TYPE(res2), Py_TPFLAGS_METHOD_DESCRIPTOR)); res = self; assert(oparg & 1); - #line 3645 "Python/generated_cases.c.h" + #line 3620 "Python/generated_cases.c.h" STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } @@ -3655,7 +3630,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); PyObject *descr = read_obj(&next_instr[5].cache); - #line 2525 "Python/bytecodes.c" + #line 2579 "Python/bytecodes.c" PyTypeObject *self_cls = Py_TYPE(self); DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); assert(self_cls->tp_dictoffset == 0); @@ -3665,7 +3640,7 @@ res2 = Py_NewRef(descr); res = self; assert(oparg & 1); - #line 3669 "Python/generated_cases.c.h" + #line 3644 "Python/generated_cases.c.h" STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } @@ -3679,7 +3654,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); PyObject *descr = read_obj(&next_instr[5].cache); - #line 2537 "Python/bytecodes.c" + #line 2591 "Python/bytecodes.c" PyTypeObject *self_cls = Py_TYPE(self); DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); Py_ssize_t dictoffset = self_cls->tp_dictoffset; @@ -3693,7 +3668,7 @@ res2 = Py_NewRef(descr); res = self; assert(oparg & 1); - #line 3697 "Python/generated_cases.c.h" + #line 3672 "Python/generated_cases.c.h" STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } @@ -3702,16 +3677,16 @@ } TARGET(KW_NAMES) { - #line 2553 "Python/bytecodes.c" + #line 2607 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg < PyTuple_GET_SIZE(frame->f_code->co_consts)); kwnames = GETITEM(frame->f_code->co_consts, oparg); - #line 3710 "Python/generated_cases.c.h" + #line 3685 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_CALL) { - #line 2559 "Python/bytecodes.c" + #line 2613 "Python/bytecodes.c" int is_meth = PEEK(oparg+2) != NULL; int total_args = oparg + is_meth; PyObject *function = PEEK(total_args + 1); @@ -3724,7 +3699,7 @@ _PyCallCache *cache = (_PyCallCache *)next_instr; INCREMENT_ADAPTIVE_COUNTER(cache->counter); GO_TO_INSTRUCTION(CALL); - #line 3728 "Python/generated_cases.c.h" + #line 3703 "Python/generated_cases.c.h" } TARGET(CALL) { @@ -3734,7 +3709,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2604 "Python/bytecodes.c" + #line 2658 "Python/bytecodes.c" int is_meth = method != NULL; int total_args = oparg; if (is_meth) { @@ -3816,7 +3791,7 @@ Py_DECREF(args[i]); } if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 3820 "Python/generated_cases.c.h" + #line 3795 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3828,7 +3803,7 @@ TARGET(CALL_BOUND_METHOD_EXACT_ARGS) { PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; - #line 2692 "Python/bytecodes.c" + #line 2746 "Python/bytecodes.c" DEOPT_IF(method != NULL, CALL); DEOPT_IF(Py_TYPE(callable) != &PyMethod_Type, CALL); STAT_INC(CALL, hit); @@ -3838,7 +3813,7 @@ PEEK(oparg + 2) = Py_NewRef(meth); // method Py_DECREF(callable); GO_TO_INSTRUCTION(CALL_PY_EXACT_ARGS); - #line 3842 "Python/generated_cases.c.h" + #line 3817 "Python/generated_cases.c.h" } TARGET(CALL_PY_EXACT_ARGS) { @@ -3847,7 +3822,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; uint32_t func_version = read_u32(&next_instr[1].cache); - #line 2704 "Python/bytecodes.c" + #line 2758 "Python/bytecodes.c" assert(kwnames == NULL); DEOPT_IF(tstate->interp->eval_frame, CALL); int is_meth = method != NULL; @@ -3873,7 +3848,7 @@ JUMPBY(INLINE_CACHE_ENTRIES_CALL); frame->return_offset = 0; DISPATCH_INLINED(new_frame); - #line 3877 "Python/generated_cases.c.h" + #line 3852 "Python/generated_cases.c.h" } TARGET(CALL_PY_WITH_DEFAULTS) { @@ -3881,7 +3856,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; uint32_t func_version = read_u32(&next_instr[1].cache); - #line 2732 "Python/bytecodes.c" + #line 2786 "Python/bytecodes.c" assert(kwnames == NULL); DEOPT_IF(tstate->interp->eval_frame, CALL); int is_meth = method != NULL; @@ -3917,7 +3892,7 @@ JUMPBY(INLINE_CACHE_ENTRIES_CALL); frame->return_offset = 0; DISPATCH_INLINED(new_frame); - #line 3921 "Python/generated_cases.c.h" + #line 3896 "Python/generated_cases.c.h" } TARGET(CALL_NO_KW_TYPE_1) { @@ -3925,7 +3900,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *null = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2770 "Python/bytecodes.c" + #line 2824 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 1); DEOPT_IF(null != NULL, CALL); @@ -3935,7 +3910,7 @@ res = Py_NewRef(Py_TYPE(obj)); Py_DECREF(obj); Py_DECREF(&PyType_Type); // I.e., callable - #line 3939 "Python/generated_cases.c.h" + #line 3914 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3948,7 +3923,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *null = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2782 "Python/bytecodes.c" + #line 2836 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 1); DEOPT_IF(null != NULL, CALL); @@ -3959,7 +3934,7 @@ Py_DECREF(arg); Py_DECREF(&PyUnicode_Type); // I.e., callable if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 3963 "Python/generated_cases.c.h" + #line 3938 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3973,7 +3948,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *null = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2796 "Python/bytecodes.c" + #line 2850 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 1); DEOPT_IF(null != NULL, CALL); @@ -3984,7 +3959,7 @@ Py_DECREF(arg); Py_DECREF(&PyTuple_Type); // I.e., tuple if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 3988 "Python/generated_cases.c.h" + #line 3963 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3998,7 +3973,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2810 "Python/bytecodes.c" + #line 2864 "Python/bytecodes.c" int is_meth = method != NULL; int total_args = oparg; if (is_meth) { @@ -4020,7 +3995,7 @@ } Py_DECREF(tp); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4024 "Python/generated_cases.c.h" + #line 3999 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4034,7 +4009,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2835 "Python/bytecodes.c" + #line 2889 "Python/bytecodes.c" /* Builtin METH_O functions */ assert(kwnames == NULL); int is_meth = method != NULL; @@ -4062,7 +4037,7 @@ Py_DECREF(arg); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4066 "Python/generated_cases.c.h" + #line 4041 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4076,7 +4051,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2866 "Python/bytecodes.c" + #line 2920 "Python/bytecodes.c" /* Builtin METH_FASTCALL functions, without keywords */ assert(kwnames == NULL); int is_meth = method != NULL; @@ -4108,7 +4083,7 @@ 'invalid'). In those cases an exception is set, so we must handle it. */ - #line 4112 "Python/generated_cases.c.h" + #line 4087 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4122,7 +4097,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2901 "Python/bytecodes.c" + #line 2955 "Python/bytecodes.c" /* Builtin METH_FASTCALL | METH_KEYWORDS functions */ int is_meth = method != NULL; int total_args = oparg; @@ -4154,7 +4129,7 @@ } Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4158 "Python/generated_cases.c.h" + #line 4133 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4168,7 +4143,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2936 "Python/bytecodes.c" + #line 2990 "Python/bytecodes.c" assert(kwnames == NULL); /* len(o) */ int is_meth = method != NULL; @@ -4193,7 +4168,7 @@ Py_DECREF(callable); Py_DECREF(arg); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4197 "Python/generated_cases.c.h" + #line 4172 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4206,7 +4181,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2963 "Python/bytecodes.c" + #line 3017 "Python/bytecodes.c" assert(kwnames == NULL); /* isinstance(o, o2) */ int is_meth = method != NULL; @@ -4233,7 +4208,7 @@ Py_DECREF(cls); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4237 "Python/generated_cases.c.h" + #line 4212 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4245,7 +4220,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *self = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; - #line 2993 "Python/bytecodes.c" + #line 3047 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 1); PyInterpreterState *interp = _PyInterpreterState_GET(); @@ -4263,14 +4238,14 @@ JUMPBY(INLINE_CACHE_ENTRIES_CALL + 1); assert(next_instr[-1].op.code == POP_TOP); DISPATCH(); - #line 4267 "Python/generated_cases.c.h" + #line 4242 "Python/generated_cases.c.h" } TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_O) { PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3013 "Python/bytecodes.c" + #line 3067 "Python/bytecodes.c" assert(kwnames == NULL); int is_meth = method != NULL; int total_args = oparg; @@ -4301,7 +4276,7 @@ Py_DECREF(arg); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4305 "Python/generated_cases.c.h" + #line 4280 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4314,7 +4289,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3047 "Python/bytecodes.c" + #line 3101 "Python/bytecodes.c" int is_meth = method != NULL; int total_args = oparg; if (is_meth) { @@ -4343,7 +4318,7 @@ } Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4347 "Python/generated_cases.c.h" + #line 4322 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4356,7 +4331,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3079 "Python/bytecodes.c" + #line 3133 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 0 || oparg == 1); int is_meth = method != NULL; @@ -4385,7 +4360,7 @@ Py_DECREF(self); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4389 "Python/generated_cases.c.h" + #line 4364 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4398,7 +4373,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3111 "Python/bytecodes.c" + #line 3165 "Python/bytecodes.c" assert(kwnames == NULL); int is_meth = method != NULL; int total_args = oparg; @@ -4426,7 +4401,7 @@ } Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4430 "Python/generated_cases.c.h" + #line 4405 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4436,9 +4411,9 @@ } TARGET(INSTRUMENTED_CALL_FUNCTION_EX) { - #line 3142 "Python/bytecodes.c" + #line 3196 "Python/bytecodes.c" GO_TO_INSTRUCTION(CALL_FUNCTION_EX); - #line 4442 "Python/generated_cases.c.h" + #line 4417 "Python/generated_cases.c.h" } TARGET(CALL_FUNCTION_EX) { @@ -4447,7 +4422,7 @@ PyObject *callargs = stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))]; PyObject *func = stack_pointer[-(2 + ((oparg & 1) ? 1 : 0))]; PyObject *result; - #line 3146 "Python/bytecodes.c" + #line 3200 "Python/bytecodes.c" // DICT_MERGE is called before this opcode if there are kwargs. // It converts all dict subtypes in kwargs into regular dicts. assert(kwargs == NULL || PyDict_CheckExact(kwargs)); @@ -4509,14 +4484,14 @@ } result = PyObject_Call(func, callargs, kwargs); } - #line 4513 "Python/generated_cases.c.h" + #line 4488 "Python/generated_cases.c.h" Py_DECREF(func); Py_DECREF(callargs); Py_XDECREF(kwargs); - #line 3208 "Python/bytecodes.c" + #line 3262 "Python/bytecodes.c" assert(PEEK(3 + (oparg & 1)) == NULL); if (result == NULL) { STACK_SHRINK(((oparg & 1) ? 1 : 0)); goto pop_3_error; } - #line 4520 "Python/generated_cases.c.h" + #line 4495 "Python/generated_cases.c.h" STACK_SHRINK(((oparg & 1) ? 1 : 0)); STACK_SHRINK(2); stack_pointer[-1] = result; @@ -4531,7 +4506,7 @@ PyObject *kwdefaults = (oparg & 0x02) ? stack_pointer[-(1 + ((oparg & 0x08) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0))] : NULL; PyObject *defaults = (oparg & 0x01) ? stack_pointer[-(1 + ((oparg & 0x08) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0) + ((oparg & 0x01) ? 1 : 0))] : NULL; PyObject *func; - #line 3218 "Python/bytecodes.c" + #line 3272 "Python/bytecodes.c" PyFunctionObject *func_obj = (PyFunctionObject *) PyFunction_New(codeobj, GLOBALS()); @@ -4560,14 +4535,14 @@ func_obj->func_version = ((PyCodeObject *)codeobj)->co_version; func = (PyObject *)func_obj; - #line 4564 "Python/generated_cases.c.h" + #line 4539 "Python/generated_cases.c.h" STACK_SHRINK(((oparg & 0x01) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x08) ? 1 : 0)); stack_pointer[-1] = func; DISPATCH(); } TARGET(RETURN_GENERATOR) { - #line 3249 "Python/bytecodes.c" + #line 3303 "Python/bytecodes.c" assert(PyFunction_Check(frame->f_funcobj)); PyFunctionObject *func = (PyFunctionObject *)frame->f_funcobj; PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func); @@ -4588,7 +4563,7 @@ frame = cframe.current_frame = prev; _PyFrame_StackPush(frame, (PyObject *)gen); goto resume_frame; - #line 4592 "Python/generated_cases.c.h" + #line 4567 "Python/generated_cases.c.h" } TARGET(BUILD_SLICE) { @@ -4596,15 +4571,15 @@ PyObject *stop = stack_pointer[-(1 + ((oparg == 3) ? 1 : 0))]; PyObject *start = stack_pointer[-(2 + ((oparg == 3) ? 1 : 0))]; PyObject *slice; - #line 3272 "Python/bytecodes.c" + #line 3326 "Python/bytecodes.c" slice = PySlice_New(start, stop, step); - #line 4602 "Python/generated_cases.c.h" + #line 4577 "Python/generated_cases.c.h" Py_DECREF(start); Py_DECREF(stop); Py_XDECREF(step); - #line 3274 "Python/bytecodes.c" + #line 3328 "Python/bytecodes.c" if (slice == NULL) { STACK_SHRINK(((oparg == 3) ? 1 : 0)); goto pop_2_error; } - #line 4608 "Python/generated_cases.c.h" + #line 4583 "Python/generated_cases.c.h" STACK_SHRINK(((oparg == 3) ? 1 : 0)); STACK_SHRINK(1); stack_pointer[-1] = slice; @@ -4615,7 +4590,7 @@ PyObject *fmt_spec = ((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? stack_pointer[-((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0))] : NULL; PyObject *value = stack_pointer[-(1 + (((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0))]; PyObject *result; - #line 3278 "Python/bytecodes.c" + #line 3332 "Python/bytecodes.c" /* Handles f-string value formatting. */ PyObject *(*conv_fn)(PyObject *); int which_conversion = oparg & FVC_MASK; @@ -4650,7 +4625,7 @@ Py_DECREF(value); Py_XDECREF(fmt_spec); if (result == NULL) { STACK_SHRINK((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0)); goto pop_1_error; } - #line 4654 "Python/generated_cases.c.h" + #line 4629 "Python/generated_cases.c.h" STACK_SHRINK((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0)); stack_pointer[-1] = result; DISPATCH(); @@ -4659,10 +4634,10 @@ TARGET(COPY) { PyObject *bottom = stack_pointer[-(1 + (oparg-1))]; PyObject *top; - #line 3315 "Python/bytecodes.c" + #line 3369 "Python/bytecodes.c" assert(oparg > 0); top = Py_NewRef(bottom); - #line 4666 "Python/generated_cases.c.h" + #line 4641 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = top; DISPATCH(); @@ -4674,7 +4649,7 @@ PyObject *rhs = stack_pointer[-1]; PyObject *lhs = stack_pointer[-2]; PyObject *res; - #line 3320 "Python/bytecodes.c" + #line 3374 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION _PyBinaryOpCache *cache = (_PyBinaryOpCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -4689,12 +4664,12 @@ assert((unsigned)oparg < Py_ARRAY_LENGTH(binary_ops)); assert(binary_ops[oparg]); res = binary_ops[oparg](lhs, rhs); - #line 4693 "Python/generated_cases.c.h" + #line 4668 "Python/generated_cases.c.h" Py_DECREF(lhs); Py_DECREF(rhs); - #line 3335 "Python/bytecodes.c" + #line 3389 "Python/bytecodes.c" if (res == NULL) goto pop_2_error; - #line 4698 "Python/generated_cases.c.h" + #line 4673 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; next_instr += 1; @@ -4704,16 +4679,16 @@ TARGET(SWAP) { PyObject *top = stack_pointer[-1]; PyObject *bottom = stack_pointer[-(2 + (oparg-2))]; - #line 3340 "Python/bytecodes.c" + #line 3394 "Python/bytecodes.c" assert(oparg >= 2); - #line 4710 "Python/generated_cases.c.h" + #line 4685 "Python/generated_cases.c.h" stack_pointer[-1] = bottom; stack_pointer[-(2 + (oparg-2))] = top; DISPATCH(); } TARGET(INSTRUMENTED_INSTRUCTION) { - #line 3344 "Python/bytecodes.c" + #line 3398 "Python/bytecodes.c" int next_opcode = _Py_call_instrumentation_instruction( tstate, frame, next_instr-1); if (next_opcode < 0) goto error; @@ -4725,26 +4700,26 @@ assert(next_opcode > 0 && next_opcode < 256); opcode = next_opcode; DISPATCH_GOTO(); - #line 4729 "Python/generated_cases.c.h" + #line 4704 "Python/generated_cases.c.h" } TARGET(INSTRUMENTED_JUMP_FORWARD) { - #line 3358 "Python/bytecodes.c" + #line 3412 "Python/bytecodes.c" INSTRUMENTED_JUMP(next_instr-1, next_instr+oparg, PY_MONITORING_EVENT_JUMP); - #line 4735 "Python/generated_cases.c.h" + #line 4710 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_JUMP_BACKWARD) { - #line 3362 "Python/bytecodes.c" + #line 3416 "Python/bytecodes.c" INSTRUMENTED_JUMP(next_instr-1, next_instr-oparg, PY_MONITORING_EVENT_JUMP); - #line 4742 "Python/generated_cases.c.h" + #line 4717 "Python/generated_cases.c.h" CHECK_EVAL_BREAKER(); DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_TRUE) { - #line 3367 "Python/bytecodes.c" + #line 3421 "Python/bytecodes.c" PyObject *cond = POP(); int err = PyObject_IsTrue(cond); Py_DECREF(cond); @@ -4753,12 +4728,12 @@ assert(err == 0 || err == 1); int offset = err*oparg; INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4757 "Python/generated_cases.c.h" + #line 4732 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_FALSE) { - #line 3378 "Python/bytecodes.c" + #line 3432 "Python/bytecodes.c" PyObject *cond = POP(); int err = PyObject_IsTrue(cond); Py_DECREF(cond); @@ -4767,12 +4742,12 @@ assert(err == 0 || err == 1); int offset = (1-err)*oparg; INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4771 "Python/generated_cases.c.h" + #line 4746 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_NONE) { - #line 3389 "Python/bytecodes.c" + #line 3443 "Python/bytecodes.c" PyObject *value = POP(); _Py_CODEUNIT *here = next_instr-1; int offset; @@ -4784,12 +4759,12 @@ offset = 0; } INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4788 "Python/generated_cases.c.h" + #line 4763 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_NOT_NONE) { - #line 3403 "Python/bytecodes.c" + #line 3457 "Python/bytecodes.c" PyObject *value = POP(); _Py_CODEUNIT *here = next_instr-1; int offset; @@ -4801,30 +4776,30 @@ offset = oparg; } INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4805 "Python/generated_cases.c.h" + #line 4780 "Python/generated_cases.c.h" DISPATCH(); } TARGET(EXTENDED_ARG) { - #line 3417 "Python/bytecodes.c" + #line 3471 "Python/bytecodes.c" assert(oparg); opcode = next_instr->op.code; oparg = oparg << 8 | next_instr->op.arg; PRE_DISPATCH_GOTO(); DISPATCH_GOTO(); - #line 4816 "Python/generated_cases.c.h" + #line 4791 "Python/generated_cases.c.h" } TARGET(CACHE) { - #line 3425 "Python/bytecodes.c" + #line 3479 "Python/bytecodes.c" assert(0 && "Executing a cache."); Py_UNREACHABLE(); - #line 4823 "Python/generated_cases.c.h" + #line 4798 "Python/generated_cases.c.h" } TARGET(RESERVED) { - #line 3430 "Python/bytecodes.c" + #line 3484 "Python/bytecodes.c" assert(0 && "Executing RESERVED instruction."); Py_UNREACHABLE(); - #line 4830 "Python/generated_cases.c.h" + #line 4805 "Python/generated_cases.c.h" } diff -Nru python3.12-3.12.0~rc2/Python/instrumentation.c python3.12-3.12.0/Python/instrumentation.c --- python3.12-3.12.0~rc2/Python/instrumentation.c 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Python/instrumentation.c 2023-10-02 11:48:14.000000000 +0000 @@ -1,6 +1,7 @@ + #include "Python.h" #include "pycore_call.h" #include "pycore_frame.h" @@ -355,7 +356,7 @@ } static void -dump_monitors(const char *prefix, _Py_Monitors monitors, FILE*out) +dump_global_monitors(const char *prefix, _Py_GlobalMonitors monitors, FILE*out) { fprintf(out, "%s monitors:\n", prefix); for (int event = 0; event < _PY_MONITORING_UNGROUPED_EVENTS; event++) { @@ -363,37 +364,13 @@ } } -/* Like _Py_GetBaseOpcode but without asserts. - * Does its best to give the right answer, but won't abort - * if something is wrong */ -static int -get_base_opcode_best_attempt(PyCodeObject *code, int offset) +static void +dump_local_monitors(const char *prefix, _Py_LocalMonitors monitors, FILE*out) { - int opcode = _Py_OPCODE(_PyCode_CODE(code)[offset]); - if (INSTRUMENTED_OPCODES[opcode] != opcode) { - /* Not instrumented */ - return _PyOpcode_Deopt[opcode] == 0 ? opcode : _PyOpcode_Deopt[opcode]; - } - if (opcode == INSTRUMENTED_INSTRUCTION) { - if (code->_co_monitoring->per_instruction_opcodes[offset] == 0) { - return opcode; - } - opcode = code->_co_monitoring->per_instruction_opcodes[offset]; - } - if (opcode == INSTRUMENTED_LINE) { - if (code->_co_monitoring->lines[offset].original_opcode == 0) { - return opcode; - } - opcode = code->_co_monitoring->lines[offset].original_opcode; - } - int deinstrumented = DE_INSTRUMENT[opcode]; - if (deinstrumented) { - return deinstrumented; - } - if (_PyOpcode_Deopt[opcode] == 0) { - return opcode; + fprintf(out, "%s monitors:\n", prefix); + for (int event = 0; event < _PY_MONITORING_LOCAL_EVENTS; event++) { + fprintf(out, " Event %d: Tools %x\n", event, monitors.tools[event]); } - return _PyOpcode_Deopt[opcode]; } /* No error checking -- Don't use this for anything but experimental debugging */ @@ -408,9 +385,9 @@ fprintf(out, "NULL\n"); return; } - dump_monitors("Global", PyInterpreterState_Get()->monitors, out); - dump_monitors("Code", data->local_monitors, out); - dump_monitors("Active", data->active_monitors, out); + dump_global_monitors("Global", _PyInterpreterState_GET()->monitors, out); + dump_local_monitors("Code", data->local_monitors, out); + dump_local_monitors("Active", data->active_monitors, out); int code_len = (int)Py_SIZE(code); bool starred = false; for (int i = 0; i < code_len; i += instruction_length(code, i)) { @@ -467,18 +444,23 @@ if (data == NULL) { return; } - _Py_GlobalMonitors active_monitors = _PyInterpreterState_GET()->monitors; + _Py_GlobalMonitors global_monitors = _PyInterpreterState_GET()->monitors; + _Py_LocalMonitors active_monitors; if (code->_co_monitoring) { - _Py_Monitors local_monitors = code->_co_monitoring->local_monitors; - active_monitors = local_union(active_monitors, local_monitors); + _Py_LocalMonitors local_monitors = code->_co_monitoring->local_monitors; + active_monitors = local_union(global_monitors, local_monitors); + } + else { + _Py_LocalMonitors empty = (_Py_LocalMonitors) { 0 }; + active_monitors = local_union(global_monitors, empty); } assert(monitors_equals( code->_co_monitoring->active_monitors, - active_monitors) - ); + active_monitors)); int code_len = (int)Py_SIZE(code); for (int i = 0; i < code_len;) { - int opcode = _PyCode_CODE(code)[i].op.code; + _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; + int opcode = instr->op.code; int base_opcode = _Py_GetBaseOpcode(code, i); CHECK(valid_opcode(opcode)); CHECK(valid_opcode(base_opcode)); @@ -498,23 +480,30 @@ opcode = data->lines[i].original_opcode; CHECK(opcode != END_FOR); CHECK(opcode != RESUME); + CHECK(opcode != RESUME_CHECK); CHECK(opcode != INSTRUMENTED_RESUME); if (!is_instrumented(opcode)) { CHECK(_PyOpcode_Deopt[opcode] == opcode); } CHECK(opcode != INSTRUMENTED_LINE); } - else if (data->lines && !is_instrumented(opcode)) { - CHECK(data->lines[i].original_opcode == 0 || - data->lines[i].original_opcode == base_opcode || - DE_INSTRUMENT[data->lines[i].original_opcode] == base_opcode); + else if (data->lines) { + /* If original_opcode is INSTRUMENTED_INSTRUCTION + * *and* we are executing a INSTRUMENTED_LINE instruction + * that has de-instrumented itself, then we will execute + * an invalid INSTRUMENTED_INSTRUCTION */ + CHECK(data->lines[i].original_opcode != INSTRUMENTED_INSTRUCTION); + } + if (opcode == INSTRUMENTED_INSTRUCTION) { + CHECK(data->per_instruction_opcodes[i] != 0); + opcode = data->per_instruction_opcodes[i]; } if (is_instrumented(opcode)) { CHECK(DE_INSTRUMENT[opcode] == base_opcode); int event = EVENT_FOR_OPCODE[DE_INSTRUMENT[opcode]]; if (event < 0) { /* RESUME fixup */ - event = _PyCode_CODE(code)[i].op.arg; + event = instr->op.arg ? 1: 0; } CHECK(active_monitors.tools[event] != 0); } @@ -599,30 +588,30 @@ de_instrument_line(PyCodeObject *code, int i) { _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; - uint8_t *opcode_ptr = &instr->op.code; - int opcode =*opcode_ptr; + int opcode = instr->op.code; if (opcode != INSTRUMENTED_LINE) { return; } _PyCoLineInstrumentationData *lines = &code->_co_monitoring->lines[i]; int original_opcode = lines->original_opcode; + if (original_opcode == INSTRUMENTED_INSTRUCTION) { + lines->original_opcode = code->_co_monitoring->per_instruction_opcodes[i]; + } CHECK(original_opcode != 0); CHECK(original_opcode == _PyOpcode_Deopt[original_opcode]); - *opcode_ptr = instr->op.code = original_opcode; + instr->op.code = original_opcode; if (_PyOpcode_Caches[original_opcode]) { instr[1].cache = adaptive_counter_warmup(); } - assert(*opcode_ptr != INSTRUMENTED_LINE); assert(instr->op.code != INSTRUMENTED_LINE); } - static void de_instrument_per_instruction(PyCodeObject *code, int i) { _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; uint8_t *opcode_ptr = &instr->op.code; - int opcode =*opcode_ptr; + int opcode = *opcode_ptr; if (opcode == INSTRUMENTED_LINE) { opcode_ptr = &code->_co_monitoring->lines[i].original_opcode; opcode = *opcode_ptr; @@ -633,10 +622,11 @@ int original_opcode = code->_co_monitoring->per_instruction_opcodes[i]; CHECK(original_opcode != 0); CHECK(original_opcode == _PyOpcode_Deopt[original_opcode]); - instr->op.code = original_opcode; + *opcode_ptr = original_opcode; if (_PyOpcode_Caches[original_opcode]) { instr[1].cache = adaptive_counter_warmup(); } + assert(*opcode_ptr != INSTRUMENTED_INSTRUCTION); assert(instr->op.code != INSTRUMENTED_INSTRUCTION); /* Keep things clean for sanity check */ code->_co_monitoring->per_instruction_opcodes[i] = 0; @@ -657,7 +647,7 @@ if (opcode == INSTRUMENTED_INSTRUCTION) { opcode_ptr = &code->_co_monitoring->per_instruction_opcodes[i]; opcode = *opcode_ptr; - CHECK(!is_instrumented(opcode)); + CHECK(opcode != INSTRUMENTED_INSTRUCTION && opcode != INSTRUMENTED_LINE); CHECK(opcode == _PyOpcode_Deopt[opcode]); } CHECK(opcode != 0); @@ -676,7 +666,7 @@ instrument_line(PyCodeObject *code, int i) { uint8_t *opcode_ptr = &_PyCode_CODE(code)[i].op.code; - int opcode =*opcode_ptr; + int opcode = *opcode_ptr; if (opcode == INSTRUMENTED_LINE) { return; } @@ -691,13 +681,14 @@ { _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; uint8_t *opcode_ptr = &instr->op.code; - int opcode =*opcode_ptr; + int opcode = *opcode_ptr; if (opcode == INSTRUMENTED_LINE) { _PyCoLineInstrumentationData *lines = &code->_co_monitoring->lines[i]; opcode_ptr = &lines->original_opcode; opcode = *opcode_ptr; } if (opcode == INSTRUMENTED_INSTRUCTION) { + assert(code->_co_monitoring->per_instruction_opcodes[i] > 0); return; } CHECK(opcode != 0); @@ -1127,7 +1118,6 @@ _PyCoMonitoringData *monitoring = code->_co_monitoring; _PyCoLineInstrumentationData *line_data = &monitoring->lines[i]; - uint8_t original_opcode = line_data->original_opcode; if (tstate->tracing) { goto done; } @@ -1178,7 +1168,9 @@ } } Py_DECREF(line_obj); + uint8_t original_opcode; done: + original_opcode = line_data->original_opcode; assert(original_opcode != 0); assert(original_opcode < INSTRUMENTED_LINE); assert(_PyOpcode_Deopt[original_opcode] == original_opcode); @@ -1260,6 +1252,9 @@ if (opcode == INSTRUMENTED_LINE) { opcode = code->_co_monitoring->lines[i].original_opcode; } + if (opcode == INSTRUMENTED_INSTRUCTION) { + opcode = code->_co_monitoring->per_instruction_opcodes[i]; + } bool instrumented = is_instrumented(opcode); if (instrumented) { opcode = DE_INSTRUMENT[opcode]; @@ -1633,7 +1628,9 @@ i += instruction_length(code, i); } } - +#ifdef INSTRUMENT_DEBUG + sanity_check_instrumentation(code); +#endif uint8_t new_line_tools = new_events.tools[PY_MONITORING_EVENT_LINE]; uint8_t new_per_instruction_tools = new_events.tools[PY_MONITORING_EVENT_INSTRUCTION]; diff -Nru python3.12-3.12.0~rc2/Python/opcode_metadata.h python3.12-3.12.0/Python/opcode_metadata.h --- python3.12-3.12.0~rc2/Python/opcode_metadata.h 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Python/opcode_metadata.h 2023-10-02 11:48:14.000000000 +0000 @@ -163,10 +163,10 @@ return 0; case LOAD_LOCALS: return 0; - case LOAD_NAME: - return 0+1; case LOAD_FROM_DICT_OR_GLOBALS: return 1; + case LOAD_NAME: + return 0; case LOAD_GLOBAL: return 0; case LOAD_GLOBAL_MODULE: @@ -559,10 +559,10 @@ return 0; case LOAD_LOCALS: return 1; - case LOAD_NAME: - return 1+1; case LOAD_FROM_DICT_OR_GLOBALS: return 1; + case LOAD_NAME: + return 1; case LOAD_GLOBAL: return ((oparg & 1) ? 1 : 0) + 1; case LOAD_GLOBAL_MODULE: @@ -881,9 +881,9 @@ [DELETE_ATTR] = { true, INSTR_FMT_IB }, [STORE_GLOBAL] = { true, INSTR_FMT_IB }, [DELETE_GLOBAL] = { true, INSTR_FMT_IB }, - [LOAD_LOCALS] = { true, INSTR_FMT_IB }, - [LOAD_NAME] = { true, INSTR_FMT_IB }, + [LOAD_LOCALS] = { true, INSTR_FMT_IX }, [LOAD_FROM_DICT_OR_GLOBALS] = { true, INSTR_FMT_IB }, + [LOAD_NAME] = { true, INSTR_FMT_IB }, [LOAD_GLOBAL] = { true, INSTR_FMT_IBC000 }, [LOAD_GLOBAL_MODULE] = { true, INSTR_FMT_IBC000 }, [LOAD_GLOBAL_BUILTIN] = { true, INSTR_FMT_IBC000 }, diff -Nru python3.12-3.12.0~rc2/Python/symtable.c python3.12-3.12.0/Python/symtable.c --- python3.12-3.12.0~rc2/Python/symtable.c 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Python/symtable.c 2023-10-02 11:48:14.000000000 +0000 @@ -801,8 +801,7 @@ the class that has the same name as a local or global in the class scope. */ - if (classflag && - PyLong_AS_LONG(v) & (DEF_BOUND | DEF_GLOBAL)) { + if (classflag) { long flags = PyLong_AS_LONG(v) | DEF_FREE_CLASS; v_new = PyLong_FromLong(flags); if (!v_new) { @@ -1037,7 +1036,7 @@ goto error; /* Records the results of the analysis in the symbol table entry */ if (!update_symbols(ste->ste_symbols, scopes, bound, newfree, inlined_cells, - ste->ste_type == ClassBlock)) + (ste->ste_type == ClassBlock) || ste->ste_can_see_class_scope)) goto error; temp = PyNumber_InPlaceOr(free, newfree); @@ -1969,6 +1968,17 @@ VISIT(st, expr, e->v.UnaryOp.operand); break; case Lambda_kind: { + if (st->st_cur->ste_can_see_class_scope) { + // gh-109118 + PyErr_Format(PyExc_SyntaxError, + "Cannot use lambda in annotation scope within class scope"); + PyErr_RangedSyntaxLocationObject(st->st_filename, + e->lineno, + e->col_offset + 1, + e->end_lineno, + e->end_col_offset + 1); + VISIT_QUIT(st, 0); + } if (e->v.Lambda.args->defaults) VISIT_SEQ(st, expr, e->v.Lambda.args->defaults); if (e->v.Lambda.args->kw_defaults) @@ -2418,6 +2428,18 @@ identifier scope_name, asdl_comprehension_seq *generators, expr_ty elt, expr_ty value) { + if (st->st_cur->ste_can_see_class_scope) { + // gh-109118 + PyErr_Format(PyExc_SyntaxError, + "Cannot use comprehension in annotation scope within class scope"); + PyErr_RangedSyntaxLocationObject(st->st_filename, + e->lineno, + e->col_offset + 1, + e->end_lineno, + e->end_col_offset + 1); + VISIT_QUIT(st, 0); + } + int is_generator = (e->kind == GeneratorExp_kind); comprehension_ty outermost = ((comprehension_ty) asdl_seq_GET(generators, 0)); diff -Nru python3.12-3.12.0~rc2/Python/traceback.c python3.12-3.12.0/Python/traceback.c --- python3.12-3.12.0~rc2/Python/traceback.c 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Python/traceback.c 2023-10-02 11:48:14.000000000 +0000 @@ -615,6 +615,11 @@ ++*right_anchor; } + // Keep going if the current char is not ')' + if (i+1 < right->col_offset && (segment_str[i] == ')')) { + continue; + } + // Set the error characters *primary_error_char = "~"; *secondary_error_char = "^"; @@ -625,6 +630,18 @@ case Subscript_kind: { *left_anchor = expr->v.Subscript.value->end_col_offset; *right_anchor = expr->v.Subscript.slice->end_col_offset + 1; + Py_ssize_t str_len = strlen(segment_str); + + // Move right_anchor and left_anchor forward to the first non-whitespace character that is not ']' and '[' + while (*left_anchor < str_len && (IS_WHITESPACE(segment_str[*left_anchor]) || segment_str[*left_anchor] != '[')) { + ++*left_anchor; + } + while (*right_anchor < str_len && (IS_WHITESPACE(segment_str[*right_anchor]) || segment_str[*right_anchor] != ']')) { + ++*right_anchor; + } + if (*right_anchor < str_len){ + *right_anchor += 1; + } // Set the error characters *primary_error_char = "~"; diff -Nru python3.12-3.12.0~rc2/README.rst python3.12-3.12.0/README.rst --- python3.12-3.12.0~rc2/README.rst 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/README.rst 2023-10-02 11:48:14.000000000 +0000 @@ -1,5 +1,5 @@ -This is Python version 3.12.0 release candidate 2 -================================================= +This is Python version 3.12.0 +============================= .. image:: https://github.com/python/cpython/workflows/Tests/badge.svg :alt: CPython build status on GitHub Actions diff -Nru python3.12-3.12.0~rc2/Tools/build/freeze_modules.py python3.12-3.12.0/Tools/build/freeze_modules.py --- python3.12-3.12.0~rc2/Tools/build/freeze_modules.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Tools/build/freeze_modules.py 2023-10-02 11:48:14.000000000 +0000 @@ -585,7 +585,7 @@ pyfiles = [] frozenfiles = [] rules = [''] - deepfreezerules = ["Python/deepfreeze/deepfreeze.c: $(DEEPFREEZE_DEPS)", + deepfreezerules = ["$(DEEPFREEZE_C): $(DEEPFREEZE_DEPS)", "\t$(PYTHON_FOR_FREEZE) $(srcdir)/Tools/build/deepfreeze.py \\"] for src in _iter_sources(modules): frozen_header = relpath_for_posix_display(src.frozenfile, ROOT_DIR) diff -Nru python3.12-3.12.0~rc2/Tools/build/verify_ensurepip_wheels.py python3.12-3.12.0/Tools/build/verify_ensurepip_wheels.py --- python3.12-3.12.0~rc2/Tools/build/verify_ensurepip_wheels.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Tools/build/verify_ensurepip_wheels.py 2023-10-02 11:48:14.000000000 +0000 @@ -1,4 +1,4 @@ -#! /usr/bin/env python3 +#!/usr/bin/env python3 """ Compare checksums for wheels in :mod:`ensurepip` against the Cheeseshop. @@ -35,11 +35,17 @@ def verify_wheel(package_name: str) -> bool: # Find the package on disk - package_path = next(WHEEL_DIR.glob(f"{package_name}*.whl"), None) - if not package_path: - print_error("", f"Could not find a {package_name} wheel on disk.") + package_paths = list(WHEEL_DIR.glob(f"{package_name}*.whl")) + if len(package_paths) != 1: + if package_paths: + for p in package_paths: + print_error(p, f"Found more than one wheel for package {package_name}.") + else: + print_error("", f"Could not find a {package_name} wheel on disk.") return False + package_path = package_paths[0] + print(f"Verifying checksum for {package_path}.") # Find the version of the package used by ensurepip diff -Nru python3.12-3.12.0~rc2/Tools/ssl/multissltests.py python3.12-3.12.0/Tools/ssl/multissltests.py --- python3.12-3.12.0~rc2/Tools/ssl/multissltests.py 2023-09-05 21:57:19.000000000 +0000 +++ python3.12-3.12.0/Tools/ssl/multissltests.py 2023-10-02 11:48:14.000000000 +0000 @@ -46,9 +46,9 @@ ] OPENSSL_RECENT_VERSIONS = [ - "1.1.1v", - "3.0.10", - "3.1.2", + "1.1.1w", + "3.0.11", + "3.1.3", ] LIBRESSL_OLD_VERSIONS = [