"""Sieve of Eratosthenes - find all primes up to limit."""
+
+
+
+
39
+
+
+
+
is_prime = [True] * (limit + 1)
+
+
+
+
40
+
+
+
+
is_prime[0] = is_prime[1] = False
+
+
+
+
41
+
+
+
+
+
+
+
+
42
+
+
+
+
for num in range(2, int(limit ** 0.5) + 1):
+
+
+
+
43
+
+
+
+
if is_prime[num]:
+
+
+
+
44
+
1
+
1
+
+
for multiple in range(num * num, limit + 1, num):
+
+
+
+
+
45
+
+
+
+
is_prime[multiple] = False
+
+
+
+
46
+
+
+
+
+
+
+
+
47
+
2
+
2
+
+
return [num for num, prime in enumerate(is_prime) if prime]
+
+
+
+
+
48
+
+
+
+
+
+
+
+
49
+
+
+
+
+
+
+
+
50
+
+
+
+
def string_processing(iterations):
+
+
+
+
51
+
+
+
+
"""String operations - concatenation and formatting."""
+
+
+
+
52
+
+
+
+
for _ in range(iterations):
+
+
+
+
53
+
+
+
+
result = ""
+
+
+
+
54
+
+
+
+
for i in range(50):
+
+
+
+
55
+
91
+
91
+
+
result += f"item_{i}_"
+
+
+
+
+
56
+
22
+
22
+
+
parts = result.split("_")
+
+
+
+
+
57
+
10
+
10
+
+
joined = "-".join(parts)
+
+
+
+
+
58
+
+
+
+
+
+
+
+
59
+
+
+
+
+
+
+
+
60
+
+
+
+
def list_operations(iterations):
+
+
+
+
61
+
+
+
+
"""List comprehensions and operations."""
+
+
+
+
62
+
+
+
+
for _ in range(iterations):
+
+
+
+
63
+
118
+
118
+
+
squares = [x ** 2 for x in range(500)]
+
+
+
+
+
64
+
119
+
119
+
+
evens = [x for x in squares if x % 2 == 0]
+
+
+
+
+
65
+
12
+
12
+
+
total = sum(evens)
+
+
+
+
+
66
+
+
+
+
+
+
+
+
67
+
+
+
+
+
+
+
+
68
+
+
+
+
def dict_operations(iterations):
+
+
+
+
69
+
+
+
+
"""Dictionary creation and lookups."""
+
+
+
+
70
+
+
+
+
for _ in range(iterations):
+
+
+
+
71
+
206
+
206
+
+
data = {f"key_{i}": i ** 2 for i in range(200)}
+
+
+
+
+
72
+
158
+
158
+
+
values = [data[f"key_{i}"] for i in range(200)]
+
+
+
+
+
73
+
5
+
5
+
+
total = sum(values)
+
+
+
+
+
74
+
+
+
+
+
+
+
+
75
+
+
+
+
+
+
+
+
76
+
+
+
+
def compute_heavy():
+
+
+
+
77
+
+
+
+
"""CPU-intensive computation section."""
+
+
+
+
78
+
1
+
301
+
+
fibonacci(30)
+
+
+
+
+
79
+
+
+
+
+
+
+
+
80
+
+
+
+
size = 60
+
+
+
+
81
+
+
+
+
a = [[i + j for j in range(size)] for i in range(size)]
+
+
+
+
82
+
+
+
+
b = [[i * j for j in range(size)] for i in range(size)]
+
+
+
+
83
+
+
+
+
matrix_multiply(a, b)
+
+
+
+
84
+
+
+
+
+
+
+
+
85
+
+
+
+
prime_sieve(10000)
+
+
+
+
86
+
+
+
+
+
+
+
+
87
+
+
+
+
+
+
+
+
88
+
+
+
+
def data_processing():
+
+
+
+
89
+
+
+
+
"""Data structure operations."""
+
+
+
+
90
+
+
753
+
+
string_processing(2000)
+
+
+
+
+
91
+
+
+
+
list_operations(1500)
+
+
+
+
92
+
+
+
+
dict_operations(1000)
+
+
+
+
93
+
+
+
+
+
+
+
+
94
+
+
+
+
data = list(range(800))
+
+
+
+
95
+
+
+
+
for _ in range(3):
+
+
+
+
96
+
+
+
+
data = data[::-1]
+
+
+
+
97
+
+
+
+
bubble_sort(data[:200])
+
+
+
+
98
+
+
+
+
+
+
+
+
99
+
+
+
+
+
+
+
+
100
+
+
+
+
def main():
+
+
+
+
101
+
+
+
+
"""Main entry point."""
+
+
+
+
102
+
+
1,054
+
+
compute_heavy()
+
+
+
+
+
103
+
+
+
+
data_processing()
+
+
+
+
104
+
+
+
+
+
+
+
+
105
+
+
+
+
+
+
+
+
106
+
+
+
+
if __name__ == "__main__":
+
+
+
+
107
+
+
1,054
+
+
main()
+
+
+
+
+
+
+
+
+
+
diff --git a/Doc/c-api/apiabiversion.rst b/Doc/c-api/apiabiversion.rst
index 96050f59bd5250..cb98d4307ee522 100644
--- a/Doc/c-api/apiabiversion.rst
+++ b/Doc/c-api/apiabiversion.rst
@@ -34,6 +34,23 @@ See :ref:`stable` for a discussion of API and ABI stability across versions.
This can be ``0xA`` for alpha, ``0xB`` for beta, ``0xC`` for release
candidate or ``0xF`` for final.
+
+ .. c:namespace:: NULL
+ .. c:macro:: PY_RELEASE_LEVEL_ALPHA
+ :no-typesetting:
+ .. c:macro:: PY_RELEASE_LEVEL_BETA
+ :no-typesetting:
+ .. c:macro:: PY_RELEASE_LEVEL_GAMMA
+ :no-typesetting:
+ .. c:macro:: PY_RELEASE_LEVEL_FINAL
+ :no-typesetting:
+
+ For completeness, the values are available as macros:
+ :c:macro:`!PY_RELEASE_LEVEL_ALPHA` (``0xA``),
+ :c:macro:`!PY_RELEASE_LEVEL_BETA` (``0xB``),
+ :c:macro:`!PY_RELEASE_LEVEL_GAMMA` (``0xC``), and
+ :c:macro:`!PY_RELEASE_LEVEL_FINAL` (``0xF``).
+
.. c:macro:: PY_RELEASE_SERIAL
The ``2`` in ``3.4.1a2``. Zero for final releases.
@@ -46,6 +63,12 @@ See :ref:`stable` for a discussion of API and ABI stability across versions.
Use this for numeric comparisons, for example,
``#if PY_VERSION_HEX >= ...``.
+.. c:macro:: PY_VERSION
+
+ The Python version as a string, for example, ``"3.4.1a2"``.
+
+These macros are defined in :source:`Include/patchlevel.h`.
+
Run-time version
----------------
diff --git a/Doc/c-api/call.rst b/Doc/c-api/call.rst
index 7198d6bc056eb4..9838879a528934 100644
--- a/Doc/c-api/call.rst
+++ b/Doc/c-api/call.rst
@@ -347,6 +347,8 @@ please see individual documentation for details.
.. versionadded:: 3.9
+.. c:function:: PyObject* _PyObject_Vectorcall(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames)
+ :no-typesetting:
.. c:function:: PyObject* PyObject_Vectorcall(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames)
@@ -358,7 +360,12 @@ please see individual documentation for details.
Return the result of the call on success, or raise an exception and return
*NULL* on failure.
- .. versionadded:: 3.9
+ .. versionadded:: 3.8 as ``_PyObject_Vectorcall``
+
+ .. versionchanged:: 3.9
+
+ Renamed to the current name, without the leading underscore.
+ The old provisional name is :term:`soft deprecated`.
.. c:function:: PyObject* PyObject_VectorcallDict(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwdict)
diff --git a/Doc/c-api/code.rst b/Doc/c-api/code.rst
index 45f5e83adc48c6..048bc2c2154e77 100644
--- a/Doc/c-api/code.rst
+++ b/Doc/c-api/code.rst
@@ -69,13 +69,14 @@ bound into a function.
The old name is deprecated, but will remain available until the
signature changes again.
+.. c:function:: PyCodeObject* PyCode_NewWithPosOnlyArgs(...)
+ :no-typesetting:
+
.. c:function:: PyCodeObject* PyUnstable_Code_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, PyObject *qualname, int firstlineno, PyObject *linetable, PyObject *exceptiontable)
Similar to :c:func:`PyUnstable_Code_New`, but with an extra "posonlyargcount" for positional-only arguments.
The same caveats that apply to ``PyUnstable_Code_New`` also apply to this function.
- .. index:: single: PyCode_NewWithPosOnlyArgs (C function)
-
.. versionadded:: 3.8 as ``PyCode_NewWithPosOnlyArgs``
.. versionchanged:: 3.11
@@ -298,6 +299,9 @@ These functions are part of the unstable C API tier:
this functionality is a CPython implementation detail, and the API
may change without deprecation warnings.
+.. c:function:: Py_ssize_t _PyEval_RequestCodeExtraIndex(freefunc free)
+ :no-typesetting:
+
.. c:function:: Py_ssize_t PyUnstable_Eval_RequestCodeExtraIndex(freefunc free)
Return a new opaque index value used to adding data to code objects.
@@ -310,8 +314,6 @@ may change without deprecation warnings.
*free* will be called on non-``NULL`` data stored under the new index.
Use :c:func:`Py_DecRef` when storing :c:type:`PyObject`.
- .. index:: single: _PyEval_RequestCodeExtraIndex (C function)
-
.. versionadded:: 3.6 as ``_PyEval_RequestCodeExtraIndex``
.. versionchanged:: 3.12
@@ -320,6 +322,9 @@ may change without deprecation warnings.
The old private name is deprecated, but will be available until the API
changes.
+.. c:function:: int _PyCode_GetExtra(PyObject *code, Py_ssize_t index, void **extra)
+ :no-typesetting:
+
.. c:function:: int PyUnstable_Code_GetExtra(PyObject *code, Py_ssize_t index, void **extra)
Set *extra* to the extra data stored under the given index.
@@ -328,8 +333,6 @@ may change without deprecation warnings.
If no data was set under the index, set *extra* to ``NULL`` and return
0 without setting an exception.
- .. index:: single: _PyCode_GetExtra (C function)
-
.. versionadded:: 3.6 as ``_PyCode_GetExtra``
.. versionchanged:: 3.12
@@ -338,13 +341,14 @@ may change without deprecation warnings.
The old private name is deprecated, but will be available until the API
changes.
+.. c:function:: int _PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra)
+ :no-typesetting:
+
.. c:function:: int PyUnstable_Code_SetExtra(PyObject *code, Py_ssize_t index, void *extra)
Set the extra data stored under the given index to *extra*.
Return 0 on success. Set an exception and return -1 on failure.
- .. index:: single: _PyCode_SetExtra (C function)
-
.. versionadded:: 3.6 as ``_PyCode_SetExtra``
.. versionchanged:: 3.12
diff --git a/Doc/c-api/conversion.rst b/Doc/c-api/conversion.rst
index 96078d22710527..f7c8ef8b22b955 100644
--- a/Doc/c-api/conversion.rst
+++ b/Doc/c-api/conversion.rst
@@ -130,6 +130,8 @@ The following functions provide locale-independent string to number conversions.
*flags* can be zero or more of the following values or-ed together:
+ .. c:namespace:: NULL
+
.. c:macro:: Py_DTSF_SIGN
Always precede the returned string with a sign
@@ -151,9 +153,21 @@ The following functions provide locale-independent string to number conversions.
.. versionadded:: 3.11
- If *ptype* is non-``NULL``, then the value it points to will be set to one of
- ``Py_DTST_FINITE``, ``Py_DTST_INFINITE``, or ``Py_DTST_NAN``, signifying that
- *val* is a finite number, an infinite number, or not a number, respectively.
+ If *ptype* is non-``NULL``, then the value it points to will be set to one
+ of the following constants depending on the type of *val*:
+
+ .. list-table::
+ :header-rows: 1
+ :align: left
+
+ * - *\*ptype*
+ - type of *val*
+ * - .. c:macro:: Py_DTST_FINITE
+ - finite number
+ * - .. c:macro:: Py_DTST_INFINITE
+ - infinite number
+ * - .. c:macro:: Py_DTST_NAN
+ - not a number
The return value is a pointer to *buffer* with the converted string or
``NULL`` if the conversion failed. The caller is responsible for freeing the
diff --git a/Doc/c-api/descriptor.rst b/Doc/c-api/descriptor.rst
index 313c534545a861..e23288c6a58590 100644
--- a/Doc/c-api/descriptor.rst
+++ b/Doc/c-api/descriptor.rst
@@ -10,11 +10,6 @@ found in the dictionary of type objects.
.. XXX document these!
-.. c:var:: PyTypeObject PyProperty_Type
-
- The type object for the built-in descriptor types.
-
-
.. c:function:: PyObject* PyDescr_NewGetSet(PyTypeObject *type, struct PyGetSetDef *getset)
@@ -74,9 +69,26 @@ found in the dictionary of type objects.
.. c:function:: PyObject* PyWrapper_New(PyObject *, PyObject *)
+.. c:macro:: PyDescr_COMMON
+
+ This is a :term:`soft deprecated` macro including the common fields for a
+ descriptor object.
+
+ This was included in Python's C API by mistake; do not use it in extensions.
+ For creating custom descriptor objects, create a class implementing the
+ descriptor protocol (:c:member:`~PyTypeObject.tp_descr_get` and
+ :c:member:`~PyTypeObject.tp_descr_set`).
+
+
Built-in descriptors
^^^^^^^^^^^^^^^^^^^^
+.. c:var:: PyTypeObject PyProperty_Type
+
+ The type object for property objects. This is the same object as
+ :class:`property` in the Python layer.
+
+
.. c:var:: PyTypeObject PySuper_Type
The type object for super objects. This is the same object as
diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst
index d7fe9e2c9ec9b4..59af470f59ff34 100644
--- a/Doc/c-api/exceptions.rst
+++ b/Doc/c-api/exceptions.rst
@@ -793,6 +793,17 @@ Exception Classes
Return :c:member:`~PyTypeObject.tp_name` of the exception class *ob*.
+.. c:macro:: PyException_HEAD
+
+ This is a :term:`soft deprecated` macro including the base fields for an
+ exception object.
+
+ This was included in Python's C API by mistake and is not designed for use
+ in extensions. For creating custom exception objects, use
+ :c:func:`PyErr_NewException` or otherwise create a class inheriting from
+ :c:data:`PyExc_BaseException`.
+
+
Exception Objects
=================
diff --git a/Doc/c-api/extension-modules.rst b/Doc/c-api/extension-modules.rst
index 0ce173b4bfea7c..92b531665e135d 100644
--- a/Doc/c-api/extension-modules.rst
+++ b/Doc/c-api/extension-modules.rst
@@ -29,7 +29,7 @@ and must be named after the module name plus an extension listed in
Extension export hook
.....................
-.. versionadded:: next
+.. versionadded:: 3.15
Support for the :samp:`PyModExport_{}` export hook was added in Python
3.15. The older way of defining modules is still available: consult either
@@ -191,7 +191,7 @@ the :c:data:`Py_mod_multiple_interpreters` slot.
``PyInit`` function
...................
-.. deprecated:: next
+.. deprecated:: 3.15
This functionality is :term:`soft deprecated`.
It will not get new features, but there are no plans to remove it.
@@ -272,7 +272,7 @@ For example, a module called ``spam`` would be defined like this::
Legacy single-phase initialization
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-.. deprecated:: next
+.. deprecated:: 3.15
Single-phase initialization is :term:`soft deprecated`.
It is a legacy mechanism to initialize extension
@@ -282,7 +282,7 @@ Legacy single-phase initialization
However, there are no plans to remove support for it.
In single-phase initialization, the old-style
-:ref:`initializaton function ` (``PyInit_modulename``)
+:ref:`initialization function ` (``PyInit_modulename``)
should create, populate and return a module object.
This is typically done using :c:func:`PyModule_Create` and functions like
:c:func:`PyModule_AddObjectRef`.
diff --git a/Doc/c-api/file.rst b/Doc/c-api/file.rst
index 9d01254ddb2a11..0580e4c8f79db0 100644
--- a/Doc/c-api/file.rst
+++ b/Doc/c-api/file.rst
@@ -131,3 +131,22 @@ the :mod:`io` APIs instead.
Write string *s* to file object *p*. Return ``0`` on success or ``-1`` on
failure; the appropriate exception will be set.
+
+
+Deprecated API
+^^^^^^^^^^^^^^
+
+
+These are :term:`soft deprecated` APIs that were included in Python's C API
+by mistake. They are documented solely for completeness; use other
+``PyFile*`` APIs instead.
+
+.. c:function:: PyObject *PyFile_NewStdPrinter(int fd)
+
+ Use :c:func:`PyFile_FromFd` with defaults (``fd, NULL, "w", -1, NULL, NULL, NULL, 0``) instead.
+
+.. c:var:: PyTypeObject PyStdPrinter_Type
+
+ Type of file-like objects used internally at Python startup when :py:mod:`io` is
+ not yet available.
+ Use Python :py:func:`open` or :c:func:`PyFile_FromFd` to create file objects instead.
diff --git a/Doc/c-api/gen.rst b/Doc/c-api/gen.rst
index 44f3bdbf959b9c..74db49a6814800 100644
--- a/Doc/c-api/gen.rst
+++ b/Doc/c-api/gen.rst
@@ -45,6 +45,7 @@ than explicitly calling :c:func:`PyGen_New` or :c:func:`PyGen_NewWithQualName`.
A reference to *frame* is stolen by this function. The *frame* argument
must not be ``NULL``.
+
.. c:function:: PyCodeObject* PyGen_GetCode(PyGenObject *gen)
Return a new :term:`strong reference` to the code object wrapped by *gen*.
@@ -82,3 +83,14 @@ Asynchronous Generator Objects
This function always succeeds.
.. versionadded:: 3.6
+
+
+Deprecated API
+^^^^^^^^^^^^^^
+
+.. c:macro:: PyAsyncGenASend_CheckExact(op)
+
+ This is a :term:`soft deprecated` API that was included in Python's C API
+ by mistake.
+
+ It is solely here for completeness; do not use this API.
diff --git a/Doc/c-api/import.rst b/Doc/c-api/import.rst
index 1786ac6b503895..a28c0713dd3b2f 100644
--- a/Doc/c-api/import.rst
+++ b/Doc/c-api/import.rst
@@ -129,8 +129,7 @@ Importing Modules
of :class:`~importlib.machinery.SourceFileLoader` otherwise.
The module's :attr:`~module.__file__` attribute will be set to the code
- object's :attr:`~codeobject.co_filename`. If applicable,
- :attr:`~module.__cached__` will also be set.
+ object's :attr:`~codeobject.co_filename`.
This function will reload the module if it was already imported. See
:c:func:`PyImport_ReloadModule` for the intended way to reload a module.
@@ -142,10 +141,13 @@ Importing Modules
:c:func:`PyImport_ExecCodeModuleWithPathnames`.
.. versionchanged:: 3.12
- The setting of :attr:`~module.__cached__` and :attr:`~module.__loader__`
+ The setting of ``__cached__`` and :attr:`~module.__loader__`
is deprecated. See :class:`~importlib.machinery.ModuleSpec` for
alternatives.
+ .. versionchanged:: 3.15
+ ``__cached__`` is no longer set.
+
.. c:function:: PyObject* PyImport_ExecCodeModuleEx(const char *name, PyObject *co, const char *pathname)
@@ -157,16 +159,19 @@ Importing Modules
.. c:function:: PyObject* PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, PyObject *cpathname)
- Like :c:func:`PyImport_ExecCodeModuleEx`, but the :attr:`~module.__cached__`
- attribute of the module object is set to *cpathname* if it is
- non-``NULL``. Of the three functions, this is the preferred one to use.
+ Like :c:func:`PyImport_ExecCodeModuleEx`, but the path to any compiled file
+ via *cpathname* is used appropriately when non-``NULL``. Of the three
+ functions, this is the preferred one to use.
.. versionadded:: 3.3
.. versionchanged:: 3.12
- Setting :attr:`~module.__cached__` is deprecated. See
+ Setting ``__cached__`` is deprecated. See
:class:`~importlib.machinery.ModuleSpec` for alternatives.
+ .. versionchanged:: 3.15
+ ``__cached__`` no longer set.
+
.. c:function:: PyObject* PyImport_ExecCodeModuleWithPathnames(const char *name, PyObject *co, const char *pathname, const char *cpathname)
diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst
index bb94bcb86a7899..6886cd85b09a7d 100644
--- a/Doc/c-api/intro.rst
+++ b/Doc/c-api/intro.rst
@@ -107,6 +107,46 @@ header files properly declare the entry points to be ``extern "C"``. As a result
there is no need to do anything special to use the API from C++.
+.. _capi-system-includes:
+
+System includes
+---------------
+
+ :file:`Python.h` includes several standard header files.
+ C extensions should include the standard headers that they use,
+ and should not rely on these implicit includes.
+ The implicit includes are:
+
+ * ````
+ * ```` (on Windows)
+ * ````
+ * ````
+ * ````
+ * ````
+ * ````
+ * ```` (if present)
+
+ The following are included for backwards compatibility, unless using
+ :ref:`Limited API ` 3.13 or newer:
+
+ * ````
+ * ```` (on POSIX)
+
+ The following are included for backwards compatibility, unless using
+ :ref:`Limited API ` 3.11 or newer:
+
+ * ````
+ * ````
+ * ````
+ * ````
+
+.. note::
+
+ Since Python may define some pre-processor definitions which affect the standard
+ headers on some systems, you *must* include :file:`Python.h` before any standard
+ headers are included.
+
+
Useful macros
=============
@@ -182,6 +222,14 @@ complete listing.
Equivalent to :c:macro:`Py_LOCAL` but additionally requests the function
be inlined.
+.. c:macro:: Py_LOCAL_SYMBOL
+
+ Macro used to declare a symbol as local to the shared library (hidden).
+ On supported platforms, it ensures the symbol is not exported.
+
+ On compatible versions of GCC/Clang, it
+ expands to ``__attribute__((visibility("hidden")))``.
+
.. c:macro:: Py_MAX(x, y)
Return the maximum value between ``x`` and ``y``.
@@ -336,6 +384,38 @@ complete listing.
sizeof(array) / sizeof((array)[0])
+.. c:macro:: Py_EXPORTED_SYMBOL
+
+ Macro used to declare a symbol (function or data) as exported.
+ On Windows, this expands to ``__declspec(dllexport)``.
+ On compatible versions of GCC/Clang, it
+ expands to ``__attribute__((visibility("default")))``.
+ This macro is for defining the C API itself; extension modules should not use it.
+
+
+.. c:macro:: Py_IMPORTED_SYMBOL
+
+ Macro used to declare a symbol as imported.
+ On Windows, this expands to ``__declspec(dllimport)``.
+ This macro is for defining the C API itself; extension modules should not use it.
+
+
+.. c:macro:: PyAPI_FUNC(type)
+
+ Macro used by CPython to declare a function as part of the C API.
+ Its expansion depends on the platform and build configuration.
+ This macro is intended for defining CPython's C API itself;
+ extension modules should not use it for their own symbols.
+
+
+.. c:macro:: PyAPI_DATA(type)
+
+ Macro used by CPython to declare a public global variable as part of the C API.
+ Its expansion depends on the platform and build configuration.
+ This macro is intended for defining CPython's C API itself;
+ extension modules should not use it for their own symbols.
+
+
.. _api-objects:
Objects, Types and Reference Counts
diff --git a/Doc/c-api/lifecycle.rst b/Doc/c-api/lifecycle.rst
index 5a170862a26f44..531c4080a0131c 100644
--- a/Doc/c-api/lifecycle.rst
+++ b/Doc/c-api/lifecycle.rst
@@ -256,6 +256,8 @@ To allocate and free memory, see :ref:`allocating-objects`.
collection (i.e., the :c:macro:`Py_TPFLAGS_HAVE_GC` flag is set); this may
change in the future.
+ .. versionadded:: 3.4
+
.. c:function:: int PyObject_CallFinalizerFromDealloc(PyObject *op)
@@ -266,6 +268,8 @@ To allocate and free memory, see :ref:`allocating-objects`.
should happen. Otherwise, this function returns 0 and destruction can
continue normally.
+ .. versionadded:: 3.4
+
.. seealso::
:c:member:`~PyTypeObject.tp_dealloc` for example code.
diff --git a/Doc/c-api/long.rst b/Doc/c-api/long.rst
index ed34efe716d8b9..790ec8da109ba8 100644
--- a/Doc/c-api/long.rst
+++ b/Doc/c-api/long.rst
@@ -453,8 +453,8 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
Otherwise, returns the number of bytes required to store the value.
If this is equal to or less than *n_bytes*, the entire value was copied.
- All *n_bytes* of the buffer are written: large buffers are padded with
- zeroes.
+ All *n_bytes* of the buffer are written: remaining bytes filled by
+ copies of the sign bit.
If the returned value is greater than *n_bytes*, the value was
truncated: as many of the lowest bits of the value as could fit are written,
@@ -687,7 +687,7 @@ Export API
.. versionadded:: 3.14
-.. c:struct:: PyLongLayout
+.. c:type:: PyLongLayout
Layout of an array of "digits" ("limbs" in the GMP terminology), used to
represent absolute value for arbitrary precision integers.
@@ -727,7 +727,7 @@ Export API
Get the native layout of Python :class:`int` objects.
- See the :c:struct:`PyLongLayout` structure.
+ See the :c:type:`PyLongLayout` structure.
The function must not be called before Python initialization nor after
Python finalization. The returned layout is valid until Python is
@@ -735,7 +735,7 @@ Export API
in a process, and so it can be cached.
-.. c:struct:: PyLongExport
+.. c:type:: PyLongExport
Export of a Python :class:`int` object.
@@ -769,7 +769,7 @@ Export API
Export a Python :class:`int` object.
- *export_long* must point to a :c:struct:`PyLongExport` structure allocated
+ *export_long* must point to a :c:type:`PyLongExport` structure allocated
by the caller. It must not be ``NULL``.
On success, fill in *\*export_long* and return ``0``.
@@ -799,7 +799,7 @@ The :c:type:`PyLongWriter` API can be used to import an integer.
.. versionadded:: 3.14
-.. c:struct:: PyLongWriter
+.. c:type:: PyLongWriter
A Python :class:`int` writer instance.
@@ -827,7 +827,7 @@ The :c:type:`PyLongWriter` API can be used to import an integer.
The layout of *digits* is described by :c:func:`PyLong_GetNativeLayout`.
Digits must be in the range [``0``; ``(1 << bits_per_digit) - 1``]
- (where the :c:struct:`~PyLongLayout.bits_per_digit` is the number of bits
+ (where the :c:type:`~PyLongLayout.bits_per_digit` is the number of bits
per digit).
Any unused most significant digits must be set to ``0``.
@@ -855,3 +855,31 @@ The :c:type:`PyLongWriter` API can be used to import an integer.
If *writer* is ``NULL``, no operation is performed.
The writer instance and the *digits* array are invalid after the call.
+
+
+Deprecated API
+^^^^^^^^^^^^^^
+
+These macros are :term:`soft deprecated`. They describe parameters
+of the internal representation of :c:type:`PyLongObject` instances.
+
+Use :c:func:`PyLong_GetNativeLayout` instead, along with :c:func:`PyLong_Export`
+to read integer data or :c:type:`PyLongWriter` to write it.
+These currently use the same layout, but are designed to continue working correctly
+even if CPython's internal integer representation changes.
+
+
+.. c:macro:: PyLong_SHIFT
+
+ This is equivalent to :c:member:`~PyLongLayout.bits_per_digit` in
+ the output of :c:func:`PyLong_GetNativeLayout`.
+
+
+.. c:macro:: PyLong_BASE
+
+ This is currently equivalent to :c:expr:`1 << PyLong_SHIFT`.
+
+
+.. c:macro:: PyLong_MASK
+
+ This is currently equivalent to :c:expr:`(1 << PyLong_SHIFT) - 1`
diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst
index 2395898010214d..58f0de5d0fc541 100644
--- a/Doc/c-api/memory.rst
+++ b/Doc/c-api/memory.rst
@@ -293,17 +293,39 @@ The following type-oriented macros are provided for convenience. Note that
Same as :c:func:`PyMem_Free`.
-In addition, the following macro sets are provided for calling the Python memory
-allocator directly, without involving the C API functions listed above. However,
-note that their use does not preserve binary compatibility across Python
-versions and is therefore deprecated in extension modules.
-* ``PyMem_MALLOC(size)``
-* ``PyMem_NEW(type, size)``
-* ``PyMem_REALLOC(ptr, size)``
-* ``PyMem_RESIZE(ptr, type, size)``
-* ``PyMem_FREE(ptr)``
-* ``PyMem_DEL(ptr)``
+Deprecated aliases
+------------------
+
+These are :term:`soft deprecated` aliases to existing functions and macros.
+They exist solely for backwards compatibility.
+
+.. list-table::
+ :widths: auto
+ :header-rows: 1
+
+ * * Deprecated alias
+ * Corresponding function or macro
+ * * .. c:macro:: PyMem_MALLOC(size)
+ * :c:func:`PyMem_Malloc`
+ * * .. c:macro:: PyMem_NEW(type, size)
+ * :c:macro:`PyMem_New`
+ * * .. c:macro:: PyMem_REALLOC(ptr, size)
+ * :c:func:`PyMem_Realloc`
+ * * .. c:macro:: PyMem_RESIZE(ptr, type, size)
+ * :c:macro:`PyMem_Resize`
+ * * .. c:macro:: PyMem_FREE(ptr)
+ * :c:func:`PyMem_Free`
+ * * .. c:macro:: PyMem_DEL(ptr)
+ * :c:func:`PyMem_Free`
+
+.. versionchanged:: 3.4
+
+ The macros are now aliases of the corresponding functions and macros.
+ Previously, their behavior was the same, but their use did not necessarily
+ preserve binary compatibility across Python versions.
+
+.. deprecated:: 2.0
.. _objectinterface:
@@ -655,7 +677,11 @@ The pymalloc allocator
Python has a *pymalloc* allocator optimized for small objects (smaller or equal
to 512 bytes) with a short lifetime. It uses memory mappings called "arenas"
with a fixed size of either 256 KiB on 32-bit platforms or 1 MiB on 64-bit
-platforms. It falls back to :c:func:`PyMem_RawMalloc` and
+platforms. When Python is configured with :option:`--with-pymalloc-hugepages`,
+the arena size on 64-bit platforms is increased to 2 MiB to match the huge page
+size, and arena allocation will attempt to use huge pages (``MAP_HUGETLB`` on
+Linux, ``MEM_LARGE_PAGES`` on Windows) with automatic fallback to regular pages.
+It falls back to :c:func:`PyMem_RawMalloc` and
:c:func:`PyMem_RawRealloc` for allocations larger than 512 bytes.
*pymalloc* is the :ref:`default allocator ` of the
diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst
index a12f6331c85912..e8a6e09f5554ec 100644
--- a/Doc/c-api/module.rst
+++ b/Doc/c-api/module.rst
@@ -142,7 +142,7 @@ Modules created using the C API are typically defined using an
array of :dfn:`slots`.
The slots provide a "description" of how a module should be created.
-.. versionchanged:: next
+.. versionchanged:: 3.15
Previously, a :c:type:`PyModuleDef` struct was necessary to define modules.
The older way of defining modules is still available: consult either the
@@ -190,7 +190,7 @@ Metadata slots
However, it is still recommended to include this slot for introspection
and debugging purposes.
- .. versionadded:: next
+ .. versionadded:: 3.15
Use :c:member:`PyModuleDef.m_name` instead to support previous versions.
@@ -201,7 +201,7 @@ Metadata slots
Usually it is set to a variable created with :c:macro:`PyDoc_STRVAR`.
- .. versionadded:: next
+ .. versionadded:: 3.15
Use :c:member:`PyModuleDef.m_doc` instead to support previous versions.
@@ -332,7 +332,7 @@ Creation and initialization slots
.. versionadded:: 3.5
- .. versionchanged:: next
+ .. versionchanged:: 3.15
The *slots* argument may be a ``ModuleSpec``-like object, rather than
a true :py:class:`~importlib.machinery.ModuleSpec` instance.
@@ -365,7 +365,7 @@ Creation and initialization slots
.. versionadded:: 3.5
- .. versionchanged:: next
+ .. versionchanged:: 3.15
Repeated ``Py_mod_exec`` slots are disallowed, except in
:c:type:`PyModuleDef.m_slots`.
@@ -384,7 +384,7 @@ Creation and initialization slots
The table must be statically allocated (or otherwise guaranteed to outlive
the module object).
- .. versionadded:: next
+ .. versionadded:: 3.15
Use :c:member:`PyModuleDef.m_methods` instead to support previous versions.
@@ -426,15 +426,15 @@ To retrieve the state from a given module, use the following functions:
module state.
-.. c:function:: int PyModule_GetStateSize(PyObject *, Py_ssize_t *result)
+.. c:function:: int PyModule_GetStateSize(PyObject *module, Py_ssize_t *result)
- Set *\*result* to the size of the module's state, as specified using
- :c:macro:`Py_mod_state_size` (or :c:member:`PyModuleDef.m_size`),
+ Set *\*result* to the size of *module*'s state, as specified
+ using :c:macro:`Py_mod_state_size` (or :c:member:`PyModuleDef.m_size`),
and return 0.
On error, set *\*result* to -1, and return -1 with an exception set.
- .. versionadded:: next
+ .. versionadded:: 3.15
@@ -459,7 +459,7 @@ defining the module state.
Use :c:func:`PyModule_GetStateSize` to retrieve the size of a given module.
- .. versionadded:: next
+ .. versionadded:: 3.15
Use :c:member:`PyModuleDef.m_size` instead to support previous versions.
@@ -482,7 +482,7 @@ defining the module state.
(:c:data:`Py_mod_state_size`) is greater than 0 and the module state
(as returned by :c:func:`PyModule_GetState`) is ``NULL``.
- .. versionadded:: next
+ .. versionadded:: 3.15
Use :c:member:`PyModuleDef.m_size` instead to support previous versions.
@@ -510,7 +510,7 @@ defining the module state.
the cyclic garbage collector is not involved and
the :c:macro:`Py_mod_state_free` function is called directly.
- .. versionadded:: next
+ .. versionadded:: 3.15
Use :c:member:`PyModuleDef.m_clear` instead to support previous versions.
@@ -532,7 +532,7 @@ defining the module state.
(:c:data:`Py_mod_state_size`) is greater than 0 and the module state
(as returned by :c:func:`PyModule_GetState`) is ``NULL``.
- .. versionadded:: next
+ .. versionadded:: 3.15
Use :c:member:`PyModuleDef.m_free` instead to support previous versions.
@@ -571,7 +571,7 @@ A module's token -- and the *your_token* value to use in the above code -- is:
of that slot;
- For modules created from an ``PyModExport_*``
:ref:`export hook `: the slots array that the export
- hook returned (unless overriden with :c:macro:`Py_mod_token`).
+ hook returned (unless overridden with :c:macro:`Py_mod_token`).
.. c:macro:: Py_mod_token
@@ -588,20 +588,20 @@ A module's token -- and the *your_token* value to use in the above code -- is:
behave as if it was created from that :c:type:`PyModuleDef`.
In particular, the module state must have matching layout and semantics.
- Modules created from :c:type:`PyModuleDef` allways use the address of
+ Modules created from :c:type:`PyModuleDef` always use the address of
the :c:type:`PyModuleDef` as the token.
This means that :c:macro:`!Py_mod_token` cannot be used in
:c:member:`PyModuleDef.m_slots`.
- .. versionadded:: next
+ .. versionadded:: 3.15
.. c:function:: int PyModule_GetToken(PyObject *module, void** result)
- Set *\*result* to the module's token and return 0.
+ Set *\*result* to the module token for *module* and return 0.
On error, set *\*result* to NULL, and return -1 with an exception set.
- .. versionadded:: next
+ .. versionadded:: 3.15
See also :c:func:`PyType_GetModuleByToken`.
@@ -641,11 +641,11 @@ rather than from an extension's :ref:`export hook `.
:c:func:`!PyModule_FromSlotsAndSpec` call.
In particular, it may be heap-allocated.
- .. versionadded:: next
+ .. versionadded:: 3.15
.. c:function:: int PyModule_Exec(PyObject *module)
- Execute the :c:data:`Py_mod_exec` slot(s) of the given *module*.
+ Execute the :c:data:`Py_mod_exec` slot(s) of *module*.
On success, return 0.
On error, return -1 with an exception set.
@@ -654,7 +654,7 @@ rather than from an extension's :ref:`export hook `.
:ref:`legacy single-phase initialization `,
this function does nothing and returns 0.
- .. versionadded:: next
+ .. versionadded:: 3.15
@@ -820,15 +820,18 @@ struct:
.. versionadded:: 3.5
.. c:macro:: PYTHON_API_VERSION
+ PYTHON_API_STRING
- The C API version. Defined for backwards compatibility.
+ The C API version, as an integer (``1013``) and string (``"1013"``), respectively.
+ Defined for backwards compatibility.
Currently, this constant is not updated in new Python versions, and is not
useful for versioning. This may change in the future.
.. c:macro:: PYTHON_ABI_VERSION
+ PYTHON_ABI_STRING
- Defined as ``3`` for backwards compatibility.
+ Defined as ``3`` and ``"3"``, respectively, for backwards compatibility.
Currently, this constant is not updated in new Python versions, and is not
useful for versioning. This may change in the future.
@@ -1018,6 +1021,9 @@ or code that creates modules dynamically.
``PyModuleDef`` (such as when using :ref:`multi-phase-initialization`,
``PyModule_Create``, or ``PyModule_FromDefAndSpec``).
+ Return ``0`` on success.
+ Return ``-1`` with an exception set on error.
+
.. versionadded:: 3.5
.. c:function:: int PyUnstable_Module_SetGIL(PyObject *module, void *gil)
diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst
index 76971c46c1696b..127b50ac479638 100644
--- a/Doc/c-api/object.rst
+++ b/Doc/c-api/object.rst
@@ -85,7 +85,7 @@ Object Protocol
instead of the :func:`repr`.
-.. c:function:: void PyUnstable_Object_Dump(PyObject *op)
+.. c:function:: void PyObject_Dump(PyObject *op)
Dump an object *op* to ``stderr``. This should only be used for debugging.
@@ -111,7 +111,7 @@ Object Protocol
object type name: str
object repr : 'abcdef'
- .. versionadded:: next
+ .. versionadded:: 3.15
.. c:function:: int PyObject_HasAttrWithError(PyObject *o, PyObject *attr_name)
diff --git a/Doc/c-api/set.rst b/Doc/c-api/set.rst
index 09c0fb6b9c5f23..b74859dd669c54 100644
--- a/Doc/c-api/set.rst
+++ b/Doc/c-api/set.rst
@@ -166,3 +166,20 @@ subtypes but not for instances of :class:`frozenset` or its subtypes.
Empty an existing set of all elements. Return ``0`` on
success. Return ``-1`` and raise :exc:`SystemError` if *set* is not an instance of
:class:`set` or its subtype.
+
+
+Deprecated API
+^^^^^^^^^^^^^^
+
+.. c:macro:: PySet_MINSIZE
+
+ A :term:`soft deprecated` constant representing the size of an internal
+ preallocated table inside :c:type:`PySetObject` instances.
+
+ This is documented solely for completeness, as there are no guarantees
+ that a given version of CPython uses preallocated tables with a fixed
+ size.
+ In code that does not deal with unstable set internals,
+ :c:macro:`!PySet_MINSIZE` can be replaced with a small constant like ``8``.
+
+ If looking for the size of a set, use :c:func:`PySet_Size` instead.
diff --git a/Doc/c-api/tuple.rst b/Doc/c-api/tuple.rst
index d0add48d7e8457..3e3752696c46d8 100644
--- a/Doc/c-api/tuple.rst
+++ b/Doc/c-api/tuple.rst
@@ -148,8 +148,11 @@ Tuple Objects
Struct Sequence Objects
-----------------------
-Struct sequence objects are the C equivalent of :func:`~collections.namedtuple`
-objects, i.e. a sequence whose items can also be accessed through attributes.
+A struct sequence object is a :term:`named tuple`, that is, a sequence
+whose items can also be accessed through attributes.
+It is similar to :func:`collections.namedtuple`, but provides a slightly
+different interface.
+
To create a struct sequence, you first have to create a specific struct sequence
type.
diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst
index 1f57cc04f5dc27..8cadf26cee3027 100644
--- a/Doc/c-api/type.rst
+++ b/Doc/c-api/type.rst
@@ -317,7 +317,7 @@ Type Objects
and other places where a method's defining class cannot be passed using the
:c:type:`PyCMethod` calling convention.
- .. versionadded:: next
+ .. versionadded:: 3.15
.. c:function:: PyObject* PyType_GetModuleByDef(PyTypeObject *type, struct PyModuleDef *def)
diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst
index efac86078f9af5..a33da367e6071f 100644
--- a/Doc/c-api/typeobj.rst
+++ b/Doc/c-api/typeobj.rst
@@ -1373,6 +1373,9 @@ and :c:data:`PyType_Type` effectively act as defaults.)
type structure.
+ .. c:macro:: _Py_TPFLAGS_HAVE_VECTORCALL
+ :no-typesetting:
+
.. c:macro:: Py_TPFLAGS_HAVE_VECTORCALL
This bit is set when the class implements
@@ -1384,7 +1387,12 @@ and :c:data:`PyType_Type` effectively act as defaults.)
This bit is inherited if :c:member:`~PyTypeObject.tp_call` is also
inherited.
- .. versionadded:: 3.9
+ .. versionadded:: 3.8 as ``_Py_TPFLAGS_HAVE_VECTORCALL``
+
+ .. versionchanged:: 3.9
+
+ Renamed to the current name, without the leading underscore.
+ The old provisional name is :term:`soft deprecated`.
.. versionchanged:: 3.12
diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst
index ca7c8bb11a5d78..d2b6643c700e88 100644
--- a/Doc/c-api/unicode.rst
+++ b/Doc/c-api/unicode.rst
@@ -65,6 +65,27 @@ Python:
.. versionadded:: 3.3
+ The structure of a particular object can be determined using the following
+ macros.
+ The macros cannot fail; their behavior is undefined if their argument
+ is not a Python Unicode object.
+
+ .. c:namespace:: NULL
+
+ .. c:macro:: PyUnicode_IS_COMPACT(o)
+
+ True if *o* uses the :c:struct:`PyCompactUnicodeObject` structure.
+
+ .. versionadded:: 3.3
+
+
+ .. c:macro:: PyUnicode_IS_COMPACT_ASCII(o)
+
+ True if *o* uses the :c:struct:`PyASCIIObject` structure.
+
+ .. versionadded:: 3.3
+
+
The following APIs are C macros and static inlined functions for fast checks and
access to internal read-only data of Unicode objects:
diff --git a/Doc/conf.py b/Doc/conf.py
index a4275835059efa..f6efc5ff22a5e1 100644
--- a/Doc/conf.py
+++ b/Doc/conf.py
@@ -436,7 +436,12 @@
epub_author = 'Python Documentation Authors'
epub_publisher = 'Python Software Foundation'
-epub_exclude_files = ('index.xhtml', 'download.xhtml')
+epub_exclude_files = (
+ 'index.xhtml',
+ 'download.xhtml',
+ '_static/tachyon-example-flamegraph.html',
+ '_static/tachyon-example-heatmap.html',
+)
# index pages are not valid xhtml
# https://github.com/sphinx-doc/sphinx/issues/12359
diff --git a/Doc/data/stable_abi.dat b/Doc/data/stable_abi.dat
index 9c5fdcefaf81d0..510e683c87e8b9 100644
--- a/Doc/data/stable_abi.dat
+++ b/Doc/data/stable_abi.dat
@@ -389,8 +389,14 @@ func,PyList_SetSlice,3.2,,
func,PyList_Size,3.2,,
func,PyList_Sort,3.2,,
data,PyList_Type,3.2,,
+type,PyLongExport,3.15,,full-abi
+type,PyLongLayout,3.15,,full-abi
type,PyLongObject,3.2,,opaque
data,PyLongRangeIter_Type,3.2,,
+type,PyLongWriter,3.15,,opaque
+func,PyLongWriter_Create,3.15,,
+func,PyLongWriter_Discard,3.15,,
+func,PyLongWriter_Finish,3.15,,
func,PyLong_AsDouble,3.2,,
func,PyLong_AsInt,3.13,,
func,PyLong_AsInt32,3.14,,
@@ -409,6 +415,8 @@ func,PyLong_AsUnsignedLongLong,3.2,,
func,PyLong_AsUnsignedLongLongMask,3.2,,
func,PyLong_AsUnsignedLongMask,3.2,,
func,PyLong_AsVoidPtr,3.2,,
+func,PyLong_Export,3.15,,
+func,PyLong_FreeExport,3.15,,
func,PyLong_FromDouble,3.2,,
func,PyLong_FromInt32,3.14,,
func,PyLong_FromInt64,3.14,,
@@ -425,6 +433,7 @@ func,PyLong_FromUnsignedLongLong,3.2,,
func,PyLong_FromUnsignedNativeBytes,3.14,,
func,PyLong_FromVoidPtr,3.2,,
func,PyLong_GetInfo,3.2,,
+func,PyLong_GetNativeLayout,3.15,,
data,PyLong_Type,3.2,,
macro,PyMODEXPORT_FUNC,3.15,,
data,PyMap_Type,3.2,,
diff --git a/Doc/deprecations/c-api-pending-removal-in-3.20.rst b/Doc/deprecations/c-api-pending-removal-in-3.20.rst
index 18623b19a2ab8d..8de55bbe7e695c 100644
--- a/Doc/deprecations/c-api-pending-removal-in-3.20.rst
+++ b/Doc/deprecations/c-api-pending-removal-in-3.20.rst
@@ -1,6 +1,13 @@
Pending removal in Python 3.20
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+* :c:func:`!_PyObject_CallMethodId`, :c:func:`!_PyObject_GetAttrId` and
+ :c:func:`!_PyUnicode_FromId` are deprecated since 3.15 and will be removed in
+ 3.20. Instead, use :c:func:`PyUnicode_InternFromString()` and cache the result in
+ the module state, then call :c:func:`PyObject_CallMethod` or
+ :c:func:`PyObject_GetAttr`.
+ (Contributed by Victor Stinner in :gh:`141049`.)
+
* The ``cval`` field in :c:type:`PyComplexObject` (:gh:`128813`).
Use :c:func:`PyComplex_AsCComplex` and :c:func:`PyComplex_FromCComplex`
to convert a Python complex number to/from the C :c:type:`Py_complex`
diff --git a/Doc/deprecations/index.rst b/Doc/deprecations/index.rst
index f3cecb321d633f..c91c64a1092457 100644
--- a/Doc/deprecations/index.rst
+++ b/Doc/deprecations/index.rst
@@ -7,6 +7,8 @@ Deprecations
.. include:: pending-removal-in-3.17.rst
+.. include:: pending-removal-in-3.18.rst
+
.. include:: pending-removal-in-3.19.rst
.. include:: pending-removal-in-3.20.rst
diff --git a/Doc/deprecations/pending-removal-in-3.15.rst b/Doc/deprecations/pending-removal-in-3.15.rst
index 09cbd6f01a0580..00266b1725c8a1 100644
--- a/Doc/deprecations/pending-removal-in-3.15.rst
+++ b/Doc/deprecations/pending-removal-in-3.15.rst
@@ -3,9 +3,9 @@ Pending removal in Python 3.15
* The import system:
- * Setting :attr:`~module.__cached__` on a module while
+ * Setting ``__cached__`` on a module while
failing to set :attr:`__spec__.cached `
- is deprecated. In Python 3.15, :attr:`!__cached__` will cease to be set or
+ is deprecated. In Python 3.15, ``__cached__`` will cease to be set or
take into consideration by the import system or standard library. (:gh:`97879`)
* Setting :attr:`~module.__package__` on a module while
@@ -33,16 +33,6 @@ Pending removal in Python 3.15
* ``load_module()`` method: use ``exec_module()`` instead.
-* :class:`locale`:
-
- * The :func:`~locale.getdefaultlocale` function
- has been deprecated since Python 3.11.
- Its removal was originally planned for Python 3.13 (:gh:`90817`),
- but has been postponed to Python 3.15.
- Use :func:`~locale.getlocale`, :func:`~locale.setlocale`,
- and :func:`~locale.getencoding` instead.
- (Contributed by Hugo van Kemenade in :gh:`111187`.)
-
* :mod:`pathlib`:
* :meth:`!.PurePath.is_reserved`
diff --git a/Doc/deprecations/pending-removal-in-3.18.rst b/Doc/deprecations/pending-removal-in-3.18.rst
new file mode 100644
index 00000000000000..3e799219478424
--- /dev/null
+++ b/Doc/deprecations/pending-removal-in-3.18.rst
@@ -0,0 +1,9 @@
+Pending removal in Python 3.18
+------------------------------
+
+* :mod:`decimal`:
+
+ * The non-standard and undocumented :class:`~decimal.Decimal` format
+ specifier ``'N'``, which is only supported in the :mod:`!decimal` module's
+ C implementation, has been deprecated since Python 3.13.
+ (Contributed by Serhiy Storchaka in :gh:`89902`.)
diff --git a/Doc/deprecations/pending-removal-in-3.20.rst b/Doc/deprecations/pending-removal-in-3.20.rst
index c0feda1968258d..4e4b2e1d5f8fff 100644
--- a/Doc/deprecations/pending-removal-in-3.20.rst
+++ b/Doc/deprecations/pending-removal-in-3.20.rst
@@ -1,14 +1,16 @@
Pending removal in Python 3.20
------------------------------
-* The ``__version__`` attribute has been deprecated in these standard library
- modules and will be removed in Python 3.20.
- Use :py:data:`sys.version_info` instead.
+* The ``__version__``, ``version`` and ``VERSION`` attributes have been
+ deprecated in these standard library modules and will be removed in
+ Python 3.20. Use :py:data:`sys.version_info` instead.
- :mod:`argparse`
- :mod:`csv`
+ - :mod:`ctypes`
- :mod:`!ctypes.macholib`
- :mod:`decimal` (use :data:`decimal.SPEC_VERSION` instead)
+ - :mod:`http.server`
- :mod:`imaplib`
- :mod:`ipaddress`
- :mod:`json`
@@ -21,6 +23,10 @@ Pending removal in Python 3.20
- :mod:`tabnanny`
- :mod:`tkinter.font`
- :mod:`tkinter.ttk`
+ - :mod:`wsgiref.simple_server`
+ - :mod:`xml.etree.ElementTree`
+ - :mod:`!xml.sax.expatreader`
+ - :mod:`xml.sax.handler`
- :mod:`zlib`
(Contributed by Hugo van Kemenade and Stan Ulbrych in :gh:`76007`.)
diff --git a/Doc/extending/extending.rst b/Doc/extending/extending.rst
index f9b65643dfe888..c0066d315d092b 100644
--- a/Doc/extending/extending.rst
+++ b/Doc/extending/extending.rst
@@ -3,154 +3,20 @@
.. _extending-intro:
-******************************
-Extending Python with C or C++
-******************************
+********************************
+Using the C API: Assorted topics
+********************************
-It is quite easy to add new built-in modules to Python, if you know how to
-program in C. Such :dfn:`extension modules` can do two things that can't be
-done directly in Python: they can implement new built-in object types, and they
-can call C library functions and system calls.
-
-To support extensions, the Python API (Application Programmers Interface)
-defines a set of functions, macros and variables that provide access to most
-aspects of the Python run-time system. The Python API is incorporated in a C
-source file by including the header ``"Python.h"``.
-
-The compilation of an extension module depends on its intended use as well as on
-your system setup; details are given in later chapters.
-
-.. note::
-
- The C extension interface is specific to CPython, and extension modules do
- not work on other Python implementations. In many cases, it is possible to
- avoid writing C extensions and preserve portability to other implementations.
- For example, if your use case is calling C library functions or system calls,
- you should consider using the :mod:`ctypes` module or the `cffi
- `_ library rather than writing
- custom C code.
- These modules let you write Python code to interface with C code and are more
- portable between implementations of Python than writing and compiling a C
- extension module.
-
-
-.. _extending-simpleexample:
-
-A Simple Example
-================
-
-Let's create an extension module called ``spam`` (the favorite food of Monty
-Python fans...) and let's say we want to create a Python interface to the C
-library function :c:func:`system` [#]_. This function takes a null-terminated
-character string as argument and returns an integer. We want this function to
-be callable from Python as follows:
-
-.. code-block:: pycon
-
- >>> import spam
- >>> status = spam.system("ls -l")
-
-Begin by creating a file :file:`spammodule.c`. (Historically, if a module is
-called ``spam``, the C file containing its implementation is called
-:file:`spammodule.c`; if the module name is very long, like ``spammify``, the
-module name can be just :file:`spammify.c`.)
-
-The first two lines of our file can be::
-
- #define PY_SSIZE_T_CLEAN
- #include
-
-which pulls in the Python API (you can add a comment describing the purpose of
-the module and a copyright notice if you like).
-
-.. note::
-
- Since Python may define some pre-processor definitions which affect the standard
- headers on some systems, you *must* include :file:`Python.h` before any standard
- headers are included.
-
- ``#define PY_SSIZE_T_CLEAN`` was used to indicate that ``Py_ssize_t`` should be
- used in some APIs instead of ``int``.
- It is not necessary since Python 3.13, but we keep it here for backward compatibility.
- See :ref:`arg-parsing-string-and-buffers` for a description of this macro.
-
-All user-visible symbols defined by :file:`Python.h` have a prefix of ``Py`` or
-``PY``, except those defined in standard header files.
-
-.. tip::
-
- For backward compatibility, :file:`Python.h` includes several standard header files.
- C extensions should include the standard headers that they use,
- and should not rely on these implicit includes.
- If using the limited C API version 3.13 or newer, the implicit includes are:
-
- * ````
- * ```` (on Windows)
- * ````
- * ````
- * ````
- * ````
- * ````
- * ```` (if present)
-
- If :c:macro:`Py_LIMITED_API` is not defined, or is set to version 3.12 or older,
- the headers below are also included:
-
- * ````
- * ```` (on POSIX)
-
- If :c:macro:`Py_LIMITED_API` is not defined, or is set to version 3.10 or older,
- the headers below are also included:
-
- * ````
- * ````
- * ````
- * ````
-
-The next thing we add to our module file is the C function that will be called
-when the Python expression ``spam.system(string)`` is evaluated (we'll see
-shortly how it ends up being called)::
-
- static PyObject *
- spam_system(PyObject *self, PyObject *args)
- {
- const char *command;
- int sts;
-
- if (!PyArg_ParseTuple(args, "s", &command))
- return NULL;
- sts = system(command);
- return PyLong_FromLong(sts);
- }
-
-There is a straightforward translation from the argument list in Python (for
-example, the single expression ``"ls -l"``) to the arguments passed to the C
-function. The C function always has two arguments, conventionally named *self*
-and *args*.
-
-The *self* argument points to the module object for module-level functions;
-for a method it would point to the object instance.
-
-The *args* argument will be a pointer to a Python tuple object containing the
-arguments. Each item of the tuple corresponds to an argument in the call's
-argument list. The arguments are Python objects --- in order to do anything
-with them in our C function we have to convert them to C values. The function
-:c:func:`PyArg_ParseTuple` in the Python API checks the argument types and
-converts them to C values. It uses a template string to determine the required
-types of the arguments as well as the types of the C variables into which to
-store the converted values. More about this later.
-
-:c:func:`PyArg_ParseTuple` returns true (nonzero) if all arguments have the right
-type and its components have been stored in the variables whose addresses are
-passed. It returns false (zero) if an invalid argument list was passed. In the
-latter case it also raises an appropriate exception so the calling function can
-return ``NULL`` immediately (as we saw in the example).
+The :ref:`tutorial ` walked you through
+creating a C API extension module, but left many areas unexplained.
+This document looks at several concepts that you'll need to learn
+in order to write more complex extensions.
.. _extending-errors:
-Intermezzo: Errors and Exceptions
-=================================
+Errors and Exceptions
+=====================
An important convention throughout the Python interpreter is the following: when
a function fails, it should set an exception condition and return an error value
@@ -321,194 +187,14 @@ call to :c:func:`PyErr_SetString` as shown below::
}
-.. _backtoexample:
-
-Back to the Example
-===================
-
-Going back to our example function, you should now be able to understand this
-statement::
-
- if (!PyArg_ParseTuple(args, "s", &command))
- return NULL;
-
-It returns ``NULL`` (the error indicator for functions returning object pointers)
-if an error is detected in the argument list, relying on the exception set by
-:c:func:`PyArg_ParseTuple`. Otherwise the string value of the argument has been
-copied to the local variable :c:data:`!command`. This is a pointer assignment and
-you are not supposed to modify the string to which it points (so in Standard C,
-the variable :c:data:`!command` should properly be declared as ``const char
-*command``).
-
-The next statement is a call to the Unix function :c:func:`system`, passing it
-the string we just got from :c:func:`PyArg_ParseTuple`::
-
- sts = system(command);
-
-Our :func:`!spam.system` function must return the value of :c:data:`!sts` as a
-Python object. This is done using the function :c:func:`PyLong_FromLong`. ::
-
- return PyLong_FromLong(sts);
-
-In this case, it will return an integer object. (Yes, even integers are objects
-on the heap in Python!)
-
-If you have a C function that returns no useful argument (a function returning
-:c:expr:`void`), the corresponding Python function must return ``None``. You
-need this idiom to do so (which is implemented by the :c:macro:`Py_RETURN_NONE`
-macro)::
-
- Py_INCREF(Py_None);
- return Py_None;
-
-:c:data:`Py_None` is the C name for the special Python object ``None``. It is a
-genuine Python object rather than a ``NULL`` pointer, which means "error" in most
-contexts, as we have seen.
-
-
-.. _methodtable:
-
-The Module's Method Table and Initialization Function
-=====================================================
-
-I promised to show how :c:func:`!spam_system` is called from Python programs.
-First, we need to list its name and address in a "method table"::
-
- static PyMethodDef spam_methods[] = {
- ...
- {"system", spam_system, METH_VARARGS,
- "Execute a shell command."},
- ...
- {NULL, NULL, 0, NULL} /* Sentinel */
- };
-
-Note the third entry (``METH_VARARGS``). This is a flag telling the interpreter
-the calling convention to be used for the C function. It should normally always
-be ``METH_VARARGS`` or ``METH_VARARGS | METH_KEYWORDS``; a value of ``0`` means
-that an obsolete variant of :c:func:`PyArg_ParseTuple` is used.
-
-When using only ``METH_VARARGS``, the function should expect the Python-level
-parameters to be passed in as a tuple acceptable for parsing via
-:c:func:`PyArg_ParseTuple`; more information on this function is provided below.
-
-The :c:macro:`METH_KEYWORDS` bit may be set in the third field if keyword
-arguments should be passed to the function. In this case, the C function should
-accept a third ``PyObject *`` parameter which will be a dictionary of keywords.
-Use :c:func:`PyArg_ParseTupleAndKeywords` to parse the arguments to such a
-function.
-
-The method table must be referenced in the module definition structure::
-
- static struct PyModuleDef spam_module = {
- ...
- .m_methods = spam_methods,
- ...
- };
-
-This structure, in turn, must be passed to the interpreter in the module's
-initialization function. The initialization function must be named
-:c:func:`!PyInit_name`, where *name* is the name of the module, and should be the
-only non-\ ``static`` item defined in the module file::
-
- PyMODINIT_FUNC
- PyInit_spam(void)
- {
- return PyModuleDef_Init(&spam_module);
- }
-
-Note that :c:macro:`PyMODINIT_FUNC` declares the function as ``PyObject *`` return type,
-declares any special linkage declarations required by the platform, and for C++
-declares the function as ``extern "C"``.
-
-:c:func:`!PyInit_spam` is called when each interpreter imports its module
-:mod:`!spam` for the first time. (See below for comments about embedding Python.)
-A pointer to the module definition must be returned via :c:func:`PyModuleDef_Init`,
-so that the import machinery can create the module and store it in ``sys.modules``.
-
-When embedding Python, the :c:func:`!PyInit_spam` function is not called
-automatically unless there's an entry in the :c:data:`PyImport_Inittab` table.
-To add the module to the initialization table, use :c:func:`PyImport_AppendInittab`,
-optionally followed by an import of the module::
-
- #define PY_SSIZE_T_CLEAN
- #include
-
- int
- main(int argc, char *argv[])
- {
- PyStatus status;
- PyConfig config;
- PyConfig_InitPythonConfig(&config);
-
- /* Add a built-in module, before Py_Initialize */
- if (PyImport_AppendInittab("spam", PyInit_spam) == -1) {
- fprintf(stderr, "Error: could not extend in-built modules table\n");
- exit(1);
- }
-
- /* Pass argv[0] to the Python interpreter */
- status = PyConfig_SetBytesString(&config, &config.program_name, argv[0]);
- if (PyStatus_Exception(status)) {
- goto exception;
- }
-
- /* Initialize the Python interpreter. Required.
- If this step fails, it will be a fatal error. */
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- goto exception;
- }
- PyConfig_Clear(&config);
-
- /* Optionally import the module; alternatively,
- import can be deferred until the embedded script
- imports it. */
- PyObject *pmodule = PyImport_ImportModule("spam");
- if (!pmodule) {
- PyErr_Print();
- fprintf(stderr, "Error: could not import module 'spam'\n");
- }
-
- // ... use Python C API here ...
-
- return 0;
-
- exception:
- PyConfig_Clear(&config);
- Py_ExitStatusException(status);
- }
-
-.. note::
-
- If you declare a global variable or a local static one, the module may
- experience unintended side-effects on re-initialisation, for example when
- removing entries from ``sys.modules`` or importing compiled modules into
- multiple interpreters within a process
- (or following a :c:func:`fork` without an intervening :c:func:`exec`).
- If module state is not yet fully :ref:`isolated `,
- authors should consider marking the module as having no support for subinterpreters
- (via :c:macro:`Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED`).
-
-A more substantial example module is included in the Python source distribution
-as :file:`Modules/xxlimited.c`. This file may be used as a template or simply
-read as an example.
-
-
.. _compilation:
-Compilation and Linkage
-=======================
+Embedding an extension
+======================
-There are two more things to do before you can use your new extension: compiling
-and linking it with the Python system. If you use dynamic loading, the details
-may depend on the style of dynamic loading your system uses; see the chapters
-about building extension modules (chapter :ref:`building`) and additional
-information that pertains only to building on Windows (chapter
-:ref:`building-on-windows`) for more information about this.
-
-If you can't use dynamic loading, or if you want to make your module a permanent
+If you want to make your module a permanent
part of the Python interpreter, you will have to change the configuration setup
-and rebuild the interpreter. Luckily, this is very simple on Unix: just place
+and rebuild the interpreter. On Unix, place
your file (:file:`spammodule.c` for example) in the :file:`Modules/` directory
of an unpacked source distribution, add a line to the file
:file:`Modules/Setup.local` describing your file:
@@ -536,7 +222,7 @@ on the line in the configuration file as well, for instance:
Calling Python Functions from C
===============================
-So far we have concentrated on making C functions callable from Python. The
+The tutorial concentrated on making C functions callable from Python. The
reverse is also useful: calling Python functions from C. This is especially the
case for libraries that support so-called "callback" functions. If a C
interface makes use of callbacks, the equivalent Python often needs to provide a
@@ -581,7 +267,7 @@ be part of a module definition::
}
This function must be registered with the interpreter using the
-:c:macro:`METH_VARARGS` flag; this is described in section :ref:`methodtable`. The
+:c:macro:`METH_VARARGS` flag in :c:type:`PyMethodDef.ml_flags`. The
:c:func:`PyArg_ParseTuple` function and its arguments are documented in section
:ref:`parsetuple`.
@@ -676,14 +362,21 @@ the above example, we use :c:func:`Py_BuildValue` to construct the dictionary. :
Py_DECREF(result);
+.. index:: single: PyArg_ParseTuple (C function)
+
.. _parsetuple:
Extracting Parameters in Extension Functions
============================================
-.. index:: single: PyArg_ParseTuple (C function)
+The :ref:`tutorial ` uses a ":c:data:`METH_O`"
+function, which is limited to a single Python argument.
+If you want more, you can use :c:data:`METH_VARARGS` instead.
+With this flag, the C function will receive a :py:class:`tuple` of arguments
+instead of a single object.
-The :c:func:`PyArg_ParseTuple` function is declared as follows::
+For unpacking the tuple, CPython provides the :c:func:`PyArg_ParseTuple`
+function, declared as follows::
int PyArg_ParseTuple(PyObject *arg, const char *format, ...);
@@ -693,6 +386,19 @@ whose syntax is explained in :ref:`arg-parsing` in the Python/C API Reference
Manual. The remaining arguments must be addresses of variables whose type is
determined by the format string.
+For example, to receive a single Python :py:class:`str` object and turn it
+into a C buffer, you would use ``"s"`` as the format string::
+
+ const char *command;
+ if (!PyArg_ParseTuple(args, "s", &command)) {
+ return NULL;
+ }
+
+If an error is detected in the argument list, :c:func:`!PyArg_ParseTuple`
+returns ``NULL`` (the error indicator for functions returning object pointers);
+your function may return ``NULL``, relying on the exception set by
+:c:func:`PyArg_ParseTuple`.
+
Note that while :c:func:`PyArg_ParseTuple` checks that the Python arguments have
the required types, it cannot check the validity of the addresses of C variables
passed to the call: if you make mistakes there, your code will probably crash or
@@ -703,7 +409,6 @@ Note that any Python object references which are provided to the caller are
Some example calls::
- #define PY_SSIZE_T_CLEAN
#include
::
@@ -773,6 +478,17 @@ Some example calls::
Keyword Parameters for Extension Functions
==========================================
+If you also want your function to accept
+:term:`keyword arguments `, use the :c:data:`METH_KEYWORDS`
+flag in combination with :c:data:`METH_VARARGS`.
+(:c:data:`!METH_KEYWORDS` can also be used with other flags; see its
+documentation for the allowed combinations.)
+
+In this case, the C function should accept a third ``PyObject *`` parameter
+which will be a dictionary of keywords.
+Use :c:func:`PyArg_ParseTupleAndKeywords` to parse the arguments to such a
+function.
+
.. index:: single: PyArg_ParseTupleAndKeywords (C function)
The :c:func:`PyArg_ParseTupleAndKeywords` function is declared as follows::
@@ -833,19 +549,6 @@ Philbrick (philbrick@hks.com)::
{NULL, NULL, 0, NULL} /* sentinel */
};
- static struct PyModuleDef keywdarg_module = {
- .m_base = PyModuleDef_HEAD_INIT,
- .m_name = "keywdarg",
- .m_size = 0,
- .m_methods = keywdarg_methods,
- };
-
- PyMODINIT_FUNC
- PyInit_keywdarg(void)
- {
- return PyModuleDef_Init(&keywdarg_module);
- }
-
.. _buildvalue:
@@ -986,11 +689,11 @@ needed. Ownership of a reference can be transferred. There are three ways to
dispose of an owned reference: pass it on, store it, or call :c:func:`Py_DECREF`.
Forgetting to dispose of an owned reference creates a memory leak.
-It is also possible to :dfn:`borrow` [#]_ a reference to an object. The
+It is also possible to :dfn:`borrow` [#borrow]_ a reference to an object. The
borrower of a reference should not call :c:func:`Py_DECREF`. The borrower must
not hold on to the object longer than the owner from which it was borrowed.
Using a borrowed reference after the owner has disposed of it risks using freed
-memory and should be avoided completely [#]_.
+memory and should be avoided completely [#dont-check-refcount]_.
The advantage of borrowing over owning a reference is that you don't need to
take care of disposing of the reference on all possible paths through the code
@@ -1169,7 +872,7 @@ checking.
The C function calling mechanism guarantees that the argument list passed to C
functions (``args`` in the examples) is never ``NULL`` --- in fact it guarantees
-that it is always a tuple [#]_.
+that it is always a tuple [#old-calling-convention]_.
It is a severe error to ever let a ``NULL`` pointer "escape" to the Python user.
@@ -1226,8 +929,8 @@ the module whose functions one wishes to call might not have been loaded yet!
Portability therefore requires not to make any assumptions about symbol
visibility. This means that all symbols in extension modules should be declared
``static``, except for the module's initialization function, in order to
-avoid name clashes with other extension modules (as discussed in section
-:ref:`methodtable`). And it means that symbols that *should* be accessible from
+avoid name clashes with other extension modules. And it means that symbols
+that *should* be accessible from
other extension modules must be exported in a different way.
Python provides a special mechanism to pass C-level information (pointers) from
@@ -1269,8 +972,9 @@ file corresponding to the module provides a macro that takes care of importing
the module and retrieving its C API pointers; client modules only have to call
this macro before accessing the C API.
-The exporting module is a modification of the :mod:`!spam` module from section
-:ref:`extending-simpleexample`. The function :func:`!spam.system` does not call
+The exporting module is a modification of the :mod:`!spam` module from the
+:ref:`tutorial `.
+The function :func:`!spam.system` does not call
the C library function :c:func:`system` directly, but a function
:c:func:`!PySpam_System`, which would of course do something more complicated in
reality (such as adding "spam" to every command). This function
@@ -1412,15 +1116,14 @@ code distribution).
.. rubric:: Footnotes
-.. [#] An interface for this function already exists in the standard module :mod:`os`
- --- it was chosen as a simple and straightforward example.
-
-.. [#] The metaphor of "borrowing" a reference is not completely correct: the owner
- still has a copy of the reference.
+.. [#borrow] The metaphor of "borrowing" a reference is not completely correct:
+ the owner still has a copy of the reference.
-.. [#] Checking that the reference count is at least 1 **does not work** --- the
+.. [#dont-check-refcount] Checking that the reference count is at least 1
+ **does not work** --- the
reference count itself could be in freed memory and may thus be reused for
another object!
-.. [#] These guarantees don't hold when you use the "old" style calling convention ---
+.. [#old-calling-convention] These guarantees don't hold when you use the
+ "old" style calling convention ---
this is still found in much existing code.
diff --git a/Doc/extending/first-extension-module.rst b/Doc/extending/first-extension-module.rst
new file mode 100644
index 00000000000000..5bde785c49e81e
--- /dev/null
+++ b/Doc/extending/first-extension-module.rst
@@ -0,0 +1,667 @@
+.. highlight:: c
+
+
+.. _extending-simpleexample:
+.. _first-extension-module:
+
+*********************************
+Your first C API extension module
+*********************************
+
+This tutorial will take you through creating a simple
+Python extension module written in C or C++.
+
+We will use the low-level Python C API directly.
+For easier ways to create extension modules, see
+the :ref:`recommended third party tools `.
+
+The tutorial assumes basic knowledge about Python: you should be able to
+define functions in Python code before starting to write them in C.
+See :ref:`tutorial-index` for an introduction to Python itself.
+
+The tutorial should be approachable for anyone who can write a basic C library.
+While we will mention several concepts that a C beginner would not be expected
+to know, like ``static`` functions or linkage declarations, understanding these
+is not necessary for success.
+
+We will focus on giving you a "feel" of what Python's C API is like.
+It will not teach you important concepts, like error handling
+and reference counting, which are covered in later chapters.
+
+We will assume that you use a Unix-like system (including macOS and
+Linux), or Windows.
+On other systems, you might need to adjust some details -- for example,
+a system command name.
+
+You need to have a suitable C compiler and Python development headers installed.
+On Linux, headers are often in a package like ``python3-dev``
+or ``python3-devel``.
+
+You need to be able to install Python packages.
+This tutorial uses `pip `__ (``pip install``), but you
+can substitute any tool that can build and install ``pyproject.toml``-based
+projects, like `uv `_ (``uv pip install``).
+Preferably, have a :ref:`virtual environment ` activated.
+
+
+.. note::
+
+ This tutorial uses APIs that were added in CPython 3.15.
+ To create an extension that's compatible with earlier versions of CPython,
+ please follow an earlier version of this documentation.
+
+ This tutorial uses C syntax added in C11 and C++20.
+ If your extension needs to be compatible with earlier standards,
+ please follow tutorials in documentation for Python 3.14 or below.
+
+
+What we'll do
+=============
+
+Let's create an extension module called ``spam`` [#why-spam]_,
+which will include a Python interface to the C
+standard library function :c:func:`system`.
+This function is defined in ``stdlib.h``.
+It takes a C string as argument, runs the argument as a system
+command, and returns a result value as an integer.
+A manual page for :c:func:`system` might summarize it this way::
+
+ #include
+ int system(const char *command);
+
+Note that like many functions in the C standard library,
+this function is already exposed in Python.
+In production, use :py:func:`os.system` or :py:func:`subprocess.run`
+rather than the module you'll write here.
+
+We want this function to be callable from Python as follows:
+
+.. code-block:: pycon
+
+ >>> import spam
+ >>> status = spam.system("whoami")
+ User Name
+ >>> status
+ 0
+
+.. note::
+
+ The system command ``whoami`` prints out your username.
+ It's useful in tutorials like this one because it has the same name on
+ both Unix and Windows.
+
+
+Start with the headers
+======================
+
+Begin by creating a directory for this tutorial, and switching to it
+on the command line.
+Then, create a file named :file:`spammodule.c` in your directory.
+[#why-spammodule]_
+
+In this file, we'll include two headers: :file:`Python.h` to pull in
+all declarations of the Python C API, and :file:`stdlib.h` for the
+:c:func:`system` function. [#stdlib-h]_
+
+Add the following lines to :file:`spammodule.c`:
+
+.. literalinclude:: ../includes/capi-extension/spammodule-01.c
+ :start-at:
+ :end-at:
+
+Be sure to put :file:`stdlib.h`, and any other standard library includes,
+*after* :file:`Python.h`.
+On some systems, Python may define some pre-processor definitions
+that affect the standard headers.
+
+
+Running your build tool
+=======================
+
+With only the includes in place, your extension won't do anything.
+Still, it's a good time to compile it and try to import it.
+This will ensure that your build tool works, so that you can make
+and test incremental changes as you follow the rest of the text.
+
+CPython itself does not come with a tool to build extension modules;
+it is recommended to use a third-party project for this.
+In this tutorial, we'll use `meson-python`_.
+(If you want to use another one, see :ref:`first-extension-other-tools`.)
+
+.. at the time of writing, meson-python has the least overhead for a
+ simple extension using PyModExport.
+ Change this if another tool makes things easier.
+
+``meson-python`` requires defining a "project" using two extra files.
+
+First, add ``pyproject.toml`` with these contents:
+
+.. code-block:: toml
+
+ [build-system]
+ build-backend = 'mesonpy'
+ requires = ['meson-python']
+
+ [project]
+ # Placeholder project information
+ # (change this before distributing the module)
+ name = 'sampleproject'
+ version = '0'
+
+Then, create ``meson.build`` containing the following:
+
+.. code-block:: meson
+
+ project('sampleproject', 'c')
+
+ py = import('python').find_installation(pure: false)
+
+ py.extension_module(
+ 'spam', # name of the importable Python module
+ 'spammodule.c', # the C source file
+ install: true,
+ )
+
+.. note::
+
+ See `meson-python documentation `_ for details on
+ configuration.
+
+Now, build install the *project in the current directory* (``.``) via ``pip``:
+
+.. code-block:: sh
+
+ python -m pip install .
+
+.. tip::
+
+ If you don't have ``pip`` installed, run ``python -m ensurepip``,
+ preferably in a :ref:`virtual environment `.
+ (Or, if you prefer another tool that can build and install
+ ``pyproject.toml``-based projects, use that.)
+
+.. _meson-python: https://mesonbuild.com/meson-python/
+.. _virtual environment: https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/#create-and-use-virtual-environments
+
+Note that you will need to run this command again every time you change your
+extension.
+Unlike Python, C has an explicit compilation step.
+
+When your extension is compiled and installed, start Python and try to
+import it.
+This should fail with the following exception:
+
+.. code-block:: pycon
+
+ >>> import spam
+ Traceback (most recent call last):
+ ...
+ ImportError: dynamic module does not define module export function (PyModExport_spam or PyInit_spam)
+
+
+Module export hook
+==================
+
+The exception you got when you tried to import the module told you that Python
+is looking for a "module export function", also known as a
+:ref:`module export hook `.
+Let's define one.
+
+First, add a prototype below the ``#include`` lines:
+
+.. literalinclude:: ../includes/capi-extension/spammodule-01.c
+ :start-after: /// Export hook prototype
+ :end-before: ///
+
+.. tip::
+ The prototype is not strictly necessary, but some modern compilers emit
+ warnings without it.
+ It's generally better to add the prototype than to disable the warning.
+
+The :c:macro:`PyMODEXPORT_FUNC` macro declares the function's
+return type, and adds any special linkage declarations needed
+to make the function visible and usable when CPython loads it.
+
+After the prototype, add the function itself.
+For now, make it return ``NULL``:
+
+.. code-block:: c
+
+ PyMODEXPORT_FUNC
+ PyModExport_spam(void)
+ {
+ return NULL;
+ }
+
+Compile and load the module again.
+You should get a different error this time.
+
+.. code-block:: pycon
+
+ >>> import spam
+ Traceback (most recent call last):
+ ...
+ SystemError: module export hook for module 'spam' failed without setting an exception
+
+Simply returning ``NULL`` is *not* correct behavior for an export hook,
+and CPython complains about it.
+That's good -- it means that CPython found the function!
+Let's now make it do something useful.
+
+
+The slot table
+==============
+
+Rather than ``NULL``, the export hook should return the information needed to
+create a module.
+Let's start with the basics: the name and docstring.
+
+The information should be defined in a ``static`` array of
+:c:type:`PyModuleDef_Slot` entries, which are essentially key-value pairs.
+Define this array just before your export hook:
+
+.. code-block:: c
+
+ static PyModuleDef_Slot spam_slots[] = {
+ {Py_mod_name, "spam"},
+ {Py_mod_doc, "A wonderful module with an example function"},
+ {0, NULL}
+ };
+
+For both :c:data:`Py_mod_name` and :c:data:`Py_mod_doc`, the values are C
+strings -- that is, NUL-terminated, UTF-8 encoded byte arrays.
+
+Note the zero-filled sentinel entry at the end.
+If you forget it, you'll trigger undefined behavior.
+
+The array is defined as ``static`` -- that is, not visible outside this ``.c`` file.
+This will be a common theme.
+CPython only needs to access the export hook; all global variables
+and all other functions should generally be ``static``, so that they don't
+clash with other extensions.
+
+Return this array from your export hook instead of ``NULL``:
+
+.. code-block:: c
+ :emphasize-lines: 4
+
+ PyMODEXPORT_FUNC
+ PyModExport_spam(void)
+ {
+ return spam_slots;
+ }
+
+Now, recompile and try it out:
+
+.. code-block:: pycon
+
+ >>> import spam
+ >>> print(spam)
+
+
+You have an extension module!
+Try ``help(spam)`` to see the docstring.
+
+The next step will be adding a function.
+
+
+.. _backtoexample:
+
+Exposing a function
+===================
+
+To expose the :c:func:`system` C function directly to Python,
+we'll need to write a layer of glue code to convert arguments from Python
+objects to C values, and the C return value back to Python.
+
+One of the simplest ways to write glue code is a ":c:data:`METH_O`" function,
+which takes two Python objects and returns one.
+All Python objects -- regardless of the Python type -- are represented in C
+as pointers to the :c:type:`PyObject` structure.
+
+Add such a function above the slots array::
+
+ static PyObject *
+ spam_system(PyObject *self, PyObject *arg)
+ {
+ Py_RETURN_NONE;
+ }
+
+For now, we ignore the arguments, and use the :c:macro:`Py_RETURN_NONE`
+macro, which expands to a ``return`` statement that properly returns
+a Python :py:data:`None` object.
+
+Recompile your extension to make sure you don't have syntax errors.
+We haven't yet added ``spam_system`` to the module, so you might get a
+warning that ``spam_system`` is unused.
+
+.. _methodtable:
+
+Method definitions
+------------------
+
+To expose the C function to Python, you will need to provide several pieces of
+information in a structure called
+:c:type:`PyMethodDef` [#why-pymethoddef]_:
+
+* ``ml_name``: the name of the Python function;
+* ``ml_doc``: a docstring;
+* ``ml_meth``: the C function to be called; and
+* ``ml_flags``: a set of flags describing details like how Python arguments are
+ passed to the C function.
+ We'll use :c:data:`METH_O` here -- the flag that matches our
+ ``spam_system`` function's signature.
+
+Because modules typically create several functions, these definitions
+need to be collected in an array, with a zero-filled sentinel at the end.
+Add this array just below the ``spam_system`` function:
+
+.. literalinclude:: ../includes/capi-extension/spammodule-01.c
+ :start-after: /// Module method table
+ :end-before: ///
+
+As with module slots, a zero-filled sentinel marks the end of the array.
+
+Next, we'll add the method to the module.
+Add a :c:data:`Py_mod_methods` slot to your :c:type:`PyMethodDef` array:
+
+.. literalinclude:: ../includes/capi-extension/spammodule-01.c
+ :start-after: /// Module slot table
+ :end-before: ///
+ :emphasize-lines: 5
+
+Recompile your extension again, and test it.
+Be sure to restart the Python interpreter, so that ``import spam`` picks
+up the new version of the module.
+
+You should now be able to call the function:
+
+.. code-block:: pycon
+
+ >>> import spam
+ >>> print(spam.system)
+
+ >>> print(spam.system('whoami'))
+ None
+
+Note that our ``spam.system`` does not yet run the ``whoami`` command;
+it only returns ``None``.
+
+Check that the function accepts exactly one argument, as specified by
+the :c:data:`METH_O` flag:
+
+.. code-block:: pycon
+
+ >>> print(spam.system('too', 'many', 'arguments'))
+ Traceback (most recent call last):
+ ...
+ TypeError: spam.system() takes exactly one argument (3 given)
+
+
+Returning an integer
+====================
+
+Now, let's take a look at the return value.
+Instead of ``None``, we'll want ``spam.system`` to return a number -- that is,
+a Python :py:type:`int` object.
+Eventually this will be the exit code of a system command,
+but let's start with a fixed value, say, ``3``.
+
+The Python C API provides a function to create a Python :py:type:`int` object
+from a C ``int`` value: :c:func:`PyLong_FromLong`. [#why-pylongfromlong]_
+
+To call it, replace the ``Py_RETURN_NONE`` with the following 3 lines:
+
+.. this could be a one-liner, but we want to show the data types here
+
+.. code-block:: c
+ :emphasize-lines: 4-6
+
+ static PyObject *
+ spam_system(PyObject *self, PyObject *arg)
+ {
+ int status = 3;
+ PyObject *result = PyLong_FromLong(status);
+ return result;
+ }
+
+
+Recompile, restart the Python interpreter again,
+and check that the function now returns 3:
+
+.. code-block:: pycon
+
+ >>> import spam
+ >>> spam.system('whoami')
+ 3
+
+
+Accepting a string
+==================
+
+Finally, let's handle the function argument.
+
+Our C function, :c:func:`!spam_system`, takes two arguments.
+The first one, ``PyObject *self``, will be set to the ``spam`` module
+object.
+This isn't useful in our case, so we'll ignore it.
+
+The other one, ``PyObject *arg``, will be set to the object that the user
+passed from Python.
+We expect that it should be a Python string.
+In order to use the information in it, we will need
+to convert it to a C value -- in this case, a C string (``const char *``).
+
+There's a slight type mismatch here: Python's :py:class:`str` objects store
+Unicode text, but C strings are arrays of bytes.
+So, we'll need to *encode* the data, and we'll use the UTF-8 encoding for it.
+(UTF-8 might not always be correct for system commands, but it's what
+:py:meth:`str.encode` uses by default,
+and the C API has special support for it.)
+
+The function to encode a Python string into a UTF-8 buffer is named
+:c:func:`PyUnicode_AsUTF8` [#why-pyunicodeasutf8]_.
+Call it like this:
+
+.. code-block:: c
+ :emphasize-lines: 4
+
+ static PyObject *
+ spam_system(PyObject *self, PyObject *arg)
+ {
+ const char *command = PyUnicode_AsUTF8(arg);
+ int status = 3;
+ PyObject *result = PyLong_FromLong(status);
+ return result;
+ }
+
+If :c:func:`PyUnicode_AsUTF8` is successful, *command* will point to the
+resulting array of bytes.
+This buffer is managed by the *arg* object, which means we don't need to free
+it, but we must follow some rules:
+
+* We should only use the buffer inside the ``spam_system`` function.
+ When ``spam_system`` returns, *arg* and the buffer it manages might be
+ garbage-collected.
+* We must not modify it. This is why we use ``const``.
+
+If :c:func:`PyUnicode_AsUTF8` was *not* successful, it returns a ``NULL``
+pointer.
+When calling *any* Python C API, we always need to handle such error cases.
+The way to do this in general is left for later chapters of this documentation.
+For now, be assured that we are already handling errors from
+:c:func:`PyLong_FromLong` correctly.
+
+For the :c:func:`PyUnicode_AsUTF8` call, the correct way to handle errors is
+returning ``NULL`` from ``spam_system``.
+Add an ``if`` block for this:
+
+
+.. code-block:: c
+ :emphasize-lines: 5-7
+
+ static PyObject *
+ spam_system(PyObject *self, PyObject *arg)
+ {
+ const char *command = PyUnicode_AsUTF8(arg);
+ if (command == NULL) {
+ return NULL;
+ }
+ int status = 3;
+ PyObject *result = PyLong_FromLong(status);
+ return result;
+ }
+
+That's it for the setup.
+Now, all that is left is calling the C library function :c:func:`system` with
+the ``char *`` buffer, and using its result instead of the ``3``:
+
+.. code-block:: c
+ :emphasize-lines: 8
+
+ static PyObject *
+ spam_system(PyObject *self, PyObject *arg)
+ {
+ const char *command = PyUnicode_AsUTF8(arg);
+ if (command == NULL) {
+ return NULL;
+ }
+ int status = system(command);
+ PyObject *result = PyLong_FromLong(status);
+ return result;
+ }
+
+Compile your module, restart Python, and test.
+This time, you should see your username -- the output of the ``whoami``
+system command:
+
+.. code-block:: pycon
+
+ >>> import spam
+ >>> result = spam.system('whoami')
+ User Name
+ >>> result
+ 0
+
+You might also want to test error cases:
+
+.. code-block:: pycon
+
+ >>> import spam
+ >>> result = spam.system('nonexistent-command')
+ sh: line 1: nonexistent-command: command not found
+ >>> result
+ 32512
+
+ >>> spam.system(3)
+ Traceback (most recent call last):
+ ...
+ TypeError: bad argument type for built-in operation
+
+
+The result
+==========
+
+
+Congratulations!
+You have written a complete Python C API extension module,
+and completed this tutorial!
+
+Here is the entire source file, for your convenience:
+
+.. _extending-spammodule-source:
+
+.. literalinclude:: ../includes/capi-extension/spammodule-01.c
+ :start-at: ///
+
+
+.. _first-extension-other-tools:
+
+Appendix: Other build tools
+===========================
+
+You should be able to follow this tutorial -- except the
+*Running your build tool* section itself -- with a build tool other
+than ``meson-python``.
+
+The Python Packaging User Guide has a `list of recommended tools `_;
+be sure to choose one for the C language.
+
+
+Workaround for missing PyInit function
+--------------------------------------
+
+If your build tool output complains about missing ``PyInit_spam``,
+add the following function to your module for now:
+
+.. code-block:: c
+
+ // A workaround
+ void *PyInit_spam(void) { return NULL; }
+
+This is a shim for an old-style :ref:`initialization function `,
+which was required in extension modules for CPython 3.14 and below.
+Current CPython does not need it, but some build tools may still assume that
+all extension modules need to define it.
+
+If you use this workaround, you will get the exception
+``SystemError: initialization of spam failed without raising an exception``
+instead of
+``ImportError: dynamic module does not define module export function``.
+
+
+Compiling directly
+------------------
+
+Using a third-party build tool is heavily recommended,
+as it will take care of various details of your platform and Python
+installation, of naming the resulting extension, and, later, of distributing
+your work.
+
+If you are building an extension for as *specific* system, or for yourself
+only, you might instead want to run your compiler directly.
+The way to do this is system-specific; be prepared for issues you will need
+to solve yourself.
+
+Linux
+^^^^^
+
+On Linux, the Python development package may include a ``python3-config``
+command that prints out the required compiler flags.
+If you use it, check that it corresponds to the CPython interpreter you'll use
+to load the module.
+Then, start with the following command:
+
+.. code-block:: sh
+
+ gcc --shared $(python3-config --cflags --ldflags) spammodule.c -o spam.so
+
+This should generate a ``spam.so`` file that you need to put in a directory
+on :py:attr:`sys.path`.
+
+
+.. rubric:: Footnotes
+
+.. [#why-spam] ``spam`` is the favorite food of Monty Python fans...
+.. [#why-spammodule] The source file name is entirely up to you,
+ though some tools can be picky about the ``.c`` extension.
+ This tutorial uses the traditional ``*module.c`` suffix.
+ Some people would just use :file:`spam.c` to implement a module
+ named ``spam``,
+ projects where Python isn't the primary language might use ``py_spam.c``,
+ and so on.
+.. [#stdlib-h] Including :file:`stdlib.h` is technically not necessary,
+ since :file:`Python.h` includes it and
+ :ref:`several other standard headers ` for its own use
+ or for backwards compatibility.
+ However, it is good practice to explicitly include what you need.
+.. [#why-pymethoddef] The :c:type:`!PyMethodDef` structure is also used
+ to create methods of classes, so there's no separate
+ ":c:type:`!PyFunctionDef`".
+.. [#why-pylongfromlong] The name :c:func:`PyLong_FromLong`
+ might not seem obvious.
+ ``PyLong`` refers to a the Python :py:class:`int`, which was originally
+ called ``long``; the ``FromLong`` refers to the C ``long`` (or ``long int``)
+ type.
+.. [#why-pyunicodeasutf8] Here, ``PyUnicode`` refers to the original name of
+ the Python :py:class:`str` class: ``unicode``.
diff --git a/Doc/extending/index.rst b/Doc/extending/index.rst
index 4cc2c96d8d5b47..c0c494c3059d99 100644
--- a/Doc/extending/index.rst
+++ b/Doc/extending/index.rst
@@ -5,15 +5,17 @@
##################################################
This document describes how to write modules in C or C++ to extend the Python
-interpreter with new modules. Those modules can not only define new functions
-but also new object types and their methods. The document also describes how
+interpreter with new modules. Those modules can do what Python code does --
+define functions, object types and methods -- but also interact with native
+libraries or achieve better performance by avoiding the overhead of an
+interpreter. The document also describes how
to embed the Python interpreter in another application, for use as an extension
language. Finally, it shows how to compile and link extension modules so that
they can be loaded dynamically (at run time) into the interpreter, if the
underlying operating system supports this feature.
-This document assumes basic knowledge about Python. For an informal
-introduction to the language, see :ref:`tutorial-index`. :ref:`reference-index`
+This document assumes basic knowledge about C and Python. For an informal
+introduction to Python, see :ref:`tutorial-index`. :ref:`reference-index`
gives a more formal definition of the language. :ref:`library-index` documents
the existing object types, functions and modules (both built-in and written in
Python) that give the language its wide application range.
@@ -21,37 +23,75 @@ Python) that give the language its wide application range.
For a detailed description of the whole Python/C API, see the separate
:ref:`c-api-index`.
+To support extensions, Python's C API (Application Programmers Interface)
+defines a set of functions, macros and variables that provide access to most
+aspects of the Python run-time system. The Python API is incorporated in a C
+source file by including the header ``"Python.h"``.
+
+.. note::
+
+ The C extension interface is specific to CPython, and extension modules do
+ not work on other Python implementations. In many cases, it is possible to
+ avoid writing C extensions and preserve portability to other implementations.
+ For example, if your use case is calling C library functions or system calls,
+ you should consider using the :mod:`ctypes` module or the `cffi
+ `_ library rather than writing
+ custom C code.
+ These modules let you write Python code to interface with C code and are more
+ portable between implementations of Python than writing and compiling a C
+ extension module.
+
+
+.. toctree::
+ :hidden:
+
+ first-extension-module.rst
+ extending.rst
+ newtypes_tutorial.rst
+ newtypes.rst
+ building.rst
+ windows.rst
+ embedding.rst
+
Recommended third party tools
=============================
-This guide only covers the basic tools for creating extensions provided
+This document only covers the basic tools for creating extensions provided
as part of this version of CPython. Some :ref:`third party tools
` offer both simpler and more sophisticated approaches to creating
C and C++ extensions for Python.
+While this document is aimed at extension authors, it should also be helpful to
+the authors of such tools.
+For example, the tutorial module can serve as a simple test case for a build
+tool or sample expected output of a code generator.
+
+
+C API Tutorial
+==============
+
+This tutorial describes how to write a simple module in C or C++,
+using the Python C API -- that is, using the basic tools provided
+as part of this version of CPython.
-Creating extensions without third party tools
-=============================================
+
+#. :ref:`first-extension-module`
+
+
+Guides for intermediate topics
+==============================
This section of the guide covers creating C and C++ extensions without
assistance from third party tools. It is intended primarily for creators
of those tools, rather than being a recommended way to create your own
C extensions.
-.. seealso::
-
- :pep:`489` -- Multi-phase extension module initialization
-
-.. toctree::
- :maxdepth: 2
- :numbered:
-
- extending.rst
- newtypes_tutorial.rst
- newtypes.rst
- building.rst
- windows.rst
+* :ref:`extending-intro`
+* :ref:`defining-new-types`
+* :ref:`new-types-topics`
+* :ref:`building`
+* :ref:`building-on-windows`
Embedding the CPython runtime in a larger application
=====================================================
@@ -61,8 +101,4 @@ interpreter as the main application, it is desirable to instead embed
the CPython runtime inside a larger application. This section covers
some of the details involved in doing that successfully.
-.. toctree::
- :maxdepth: 2
- :numbered:
-
- embedding.rst
+* :ref:`embedding`
diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst
index 6f9dfa8616ed44..138a5ca7a7516f 100644
--- a/Doc/faq/programming.rst
+++ b/Doc/faq/programming.rst
@@ -1226,13 +1226,13 @@ This converts the list into a set, thereby removing duplicates, and then back
into a list.
-How do you remove multiple items from a list
---------------------------------------------
+How do you remove multiple items from a list?
+---------------------------------------------
As with removing duplicates, explicitly iterating in reverse with a
delete condition is one possibility. However, it is easier and faster
to use slice replacement with an implicit or explicit forward iteration.
-Here are three variations.::
+Here are three variations::
mylist[:] = filter(keep_function, mylist)
mylist[:] = (x for x in mylist if keep_condition)
diff --git a/Doc/glossary.rst b/Doc/glossary.rst
index a4066d42927f64..68035c2dfb57d4 100644
--- a/Doc/glossary.rst
+++ b/Doc/glossary.rst
@@ -134,6 +134,14 @@ Glossary
iterator's :meth:`~object.__anext__` method until it raises a
:exc:`StopAsyncIteration` exception. Introduced by :pep:`492`.
+ atomic operation
+ An operation that appears to execute as a single, indivisible step: no
+ other thread can observe it half-done, and its effects become visible all
+ at once. Python does not guarantee that high-level statements are atomic
+ (for example, ``x += 1`` performs multiple bytecode operations and is not
+ atomic). Atomicity is only guaranteed where explicitly documented. See
+ also :term:`race condition` and :term:`data race`.
+
attached thread state
A :term:`thread state` that is active for the current OS thread.
@@ -289,6 +297,22 @@ Glossary
advanced mathematical feature. If you're not aware of a need for them,
it's almost certain you can safely ignore them.
+ concurrency
+ The ability of a computer program to perform multiple tasks at the same
+ time. Python provides libraries for writing programs that make use of
+ different forms of concurrency. :mod:`asyncio` is a library for dealing
+ with asynchronous tasks and coroutines. :mod:`threading` provides
+ access to operating system threads and :mod:`multiprocessing` to
+ operating system processes. Multi-core processors can execute threads and
+ processes on different CPU cores at the same time (see
+ :term:`parallelism`).
+
+ concurrent modification
+ When multiple threads modify shared data at the same time. Concurrent
+ modification without proper synchronization can cause
+ :term:`race conditions `, and might also trigger a
+ :term:`data race `, data corruption, or both.
+
context
This term has different meanings depending on where and how it is used.
Some common meanings:
@@ -363,6 +387,28 @@ Glossary
the :term:`cyclic garbage collector ` is to identify these groups and break the reference
cycles so that the memory can be reclaimed.
+ data race
+ A situation where multiple threads access the same memory location
+ concurrently, at least one of the accesses is a write, and the threads
+ do not use any synchronization to control their access. Data races
+ lead to :term:`non-deterministic` behavior and can cause data corruption.
+ Proper use of :term:`locks ` and other :term:`synchronization primitives
+ ` prevents data races. Note that data races
+ can only happen in native code, but that :term:`native code` might be
+ exposed in a Python API. See also :term:`race condition` and
+ :term:`thread-safe`.
+
+ deadlock
+ A situation in which two or more tasks (threads, processes, or coroutines)
+ wait indefinitely for each other to release resources or complete actions,
+ preventing any from making progress. For example, if thread A holds lock
+ 1 and waits for lock 2, while thread B holds lock 2 and waits for lock 1,
+ both threads will wait indefinitely. In Python this often arises from
+ acquiring multiple locks in conflicting orders or from circular
+ join/await dependencies. Deadlocks can be avoided by always acquiring
+ multiple :term:`locks ` in a consistent order. See also
+ :term:`lock` and :term:`reentrant`.
+
decorator
A function returning another function, usually applied as a function
transformation using the ``@wrapper`` syntax. Common examples for
@@ -662,6 +708,14 @@ Glossary
requires the GIL to be held in order to use it. This refers to having an
:term:`attached thread state`.
+ global state
+ Data that is accessible throughout a program, such as module-level
+ variables, class variables, or C static variables in :term:`extension modules
+ `. In multi-threaded programs, global state shared
+ between threads typically requires synchronization to avoid
+ :term:`race conditions ` and
+ :term:`data races `.
+
hash-based pyc
A bytecode cache file that uses the hash rather than the last-modified
time of the corresponding source file to determine its validity. See
@@ -706,7 +760,9 @@ Glossary
tuples. Such an object cannot be altered. A new object has to
be created if a different value has to be stored. They play an important
role in places where a constant hash value is needed, for example as a key
- in a dictionary.
+ in a dictionary. Immutable objects are inherently :term:`thread-safe`
+ because their state cannot be modified after creation, eliminating concerns
+ about improperly synchronized :term:`concurrent modification`.
import path
A list of locations (or :term:`path entries `) that are
@@ -796,8 +852,9 @@ Glossary
CPython does not consistently apply the requirement that an iterator
define :meth:`~iterator.__iter__`.
- And also please note that the free-threading CPython does not guarantee
- the thread-safety of iterator operations.
+ And also please note that :term:`free-threaded `
+ CPython does not guarantee :term:`thread-safe` behavior of iterator
+ operations.
key function
@@ -813,7 +870,7 @@ Glossary
:func:`itertools.groupby`.
There are several ways to create a key function. For example. the
- :meth:`str.lower` method can serve as a key function for case insensitive
+ :meth:`str.casefold` method can serve as a key function for case insensitive
sorts. Alternatively, a key function can be built from a
:keyword:`lambda` expression such as ``lambda r: (r[0], r[2])``. Also,
:func:`operator.attrgetter`, :func:`operator.itemgetter`, and
@@ -835,10 +892,11 @@ Glossary
:keyword:`if` statements.
In a multi-threaded environment, the LBYL approach can risk introducing a
- race condition between "the looking" and "the leaping". For example, the
- code, ``if key in mapping: return mapping[key]`` can fail if another
+ :term:`race condition` between "the looking" and "the leaping". For example,
+ the code, ``if key in mapping: return mapping[key]`` can fail if another
thread removes *key* from *mapping* after the test, but before the lookup.
- This issue can be solved with locks or by using the EAFP approach.
+ This issue can be solved with :term:`locks ` or by using the
+ :term:`EAFP` approach. See also :term:`thread-safe`.
lexical analyzer
@@ -857,6 +915,19 @@ Glossary
clause is optional. If omitted, all elements in ``range(256)`` are
processed.
+ lock
+ A :term:`synchronization primitive` that allows only one thread at a
+ time to access a shared resource. A thread must acquire a lock before
+ accessing the protected resource and release it afterward. If a thread
+ attempts to acquire a lock that is already held by another thread, it
+ will block until the lock becomes available. Python's :mod:`threading`
+ module provides :class:`~threading.Lock` (a basic lock) and
+ :class:`~threading.RLock` (a :term:`reentrant` lock). Locks are used
+ to prevent :term:`race conditions ` and ensure
+ :term:`thread-safe` access to shared data. Alternative design patterns
+ to locks exist such as queues, producer/consumer patterns, and
+ thread-local state. See also :term:`deadlock`, and :term:`reentrant`.
+
loader
An object that loads a module.
It must define the :meth:`!exec_module` and :meth:`!create_module` methods
@@ -942,8 +1013,11 @@ Glossary
See :term:`method resolution order`.
mutable
- Mutable objects can change their value but keep their :func:`id`. See
- also :term:`immutable`.
+ An :term:`object` with state that is allowed to change during the course
+ of the program. In multi-threaded programs, mutable objects that are
+ shared between threads require careful synchronization to avoid
+ :term:`race conditions `. See also :term:`immutable`,
+ :term:`thread-safe`, and :term:`concurrent modification`.
named tuple
The term "named tuple" applies to any type or class that inherits from
@@ -995,6 +1069,13 @@ Glossary
See also :term:`module`.
+ native code
+ Code that is compiled to machine instructions and runs directly on the
+ processor, as opposed to code that is interpreted or runs in a virtual
+ machine. In the context of Python, native code typically refers to
+ C, C++, Rust or Fortran code in :term:`extension modules `
+ that can be called from Python. See also :term:`extension module`.
+
nested scope
The ability to refer to a variable in an enclosing definition. For
instance, a function defined inside another function can refer to
@@ -1011,6 +1092,15 @@ Glossary
properties, :meth:`~object.__getattribute__`, class methods, and static
methods.
+ non-deterministic
+ Behavior where the outcome of a program can vary between executions with
+ the same inputs. In multi-threaded programs, non-deterministic behavior
+ often results from :term:`race conditions ` where the
+ relative timing or interleaving of threads affects the result.
+ Proper synchronization using :term:`locks ` and other
+ :term:`synchronization primitives ` helps
+ ensure deterministic behavior.
+
object
Any data with state (attributes or value) and defined behavior
(methods). Also the ultimate base class of any :term:`new-style
@@ -1041,6 +1131,16 @@ Glossary
See also :term:`regular package` and :term:`namespace package`.
+ parallelism
+ Executing multiple operations at the same time (e.g. on multiple CPU
+ cores). In Python builds with the
+ :term:`global interpreter lock (GIL) `, only one
+ thread runs Python bytecode at a time, so taking advantage of multiple
+ CPU cores typically involves multiple processes
+ (e.g. :mod:`multiprocessing`) or native extensions that release the GIL.
+ In :term:`free-threaded ` Python, multiple Python threads
+ can run Python code simultaneously on different cores.
+
parameter
A named entity in a :term:`function` (or method) definition that
specifies an :term:`argument` (or in some cases, arguments) that the
@@ -1215,6 +1315,18 @@ Glossary
>>> email.mime.text.__name__
'email.mime.text'
+ race condition
+ A condition of a program where the its behavior
+ depends on the relative timing or ordering of events, particularly in
+ multi-threaded programs. Race conditions can lead to
+ :term:`non-deterministic` behavior and bugs that are difficult to
+ reproduce. A :term:`data race` is a specific type of race condition
+ involving unsynchronized access to shared memory. The :term:`LBYL`
+ coding style is particularly susceptible to race conditions in
+ multi-threaded code. Using :term:`locks ` and other
+ :term:`synchronization primitives `
+ helps prevent race conditions.
+
reference count
The number of references to an object. When the reference count of an
object drops to zero, it is deallocated. Some objects are
@@ -1236,6 +1348,25 @@ Glossary
See also :term:`namespace package`.
+ reentrant
+ A property of a function or :term:`lock` that allows it to be called or
+ acquired multiple times by the same thread without causing errors or a
+ :term:`deadlock`.
+
+ For functions, reentrancy means the function can be safely called again
+ before a previous invocation has completed, which is important when
+ functions may be called recursively or from signal handlers. Thread-unsafe
+ functions may be :term:`non-deterministic` if they're called reentrantly in a
+ multithreaded program.
+
+ For locks, Python's :class:`threading.RLock` (reentrant lock) is
+ reentrant, meaning a thread that already holds the lock can acquire it
+ again without blocking. In contrast, :class:`threading.Lock` is not
+ reentrant - attempting to acquire it twice from the same thread will cause
+ a deadlock.
+
+ See also :term:`lock` and :term:`deadlock`.
+
REPL
An acronym for the "read–eval–print loop", another name for the
:term:`interactive` interpreter shell.
@@ -1340,6 +1471,18 @@ Glossary
See also :term:`borrowed reference`.
+ synchronization primitive
+ A basic building block for coordinating (synchronizing) the execution of
+ multiple threads to ensure :term:`thread-safe` access to shared resources.
+ Python's :mod:`threading` module provides several synchronization primitives
+ including :class:`~threading.Lock`, :class:`~threading.RLock`,
+ :class:`~threading.Semaphore`, :class:`~threading.Condition`,
+ :class:`~threading.Event`, and :class:`~threading.Barrier`. Additionally,
+ the :mod:`queue` module provides multi-producer, multi-consumer queues
+ that are especially useful in multithreaded programs. These
+ primitives help prevent :term:`race conditions ` and
+ coordinate thread execution. See also :term:`lock`.
+
t-string
t-strings
String literals prefixed with ``t`` or ``T`` are commonly called
@@ -1392,6 +1535,19 @@ Glossary
See :ref:`Thread State and the Global Interpreter Lock ` for more
information.
+ thread-safe
+ A module, function, or class that behaves correctly when used by multiple
+ threads concurrently. Thread-safe code uses appropriate
+ :term:`synchronization primitives ` like
+ :term:`locks ` to protect shared mutable state, or is designed
+ to avoid shared mutable state entirely. In the
+ :term:`free-threaded ` build, built-in types like
+ :class:`dict`, :class:`list`, and :class:`set` use internal locking
+ to make many operations thread-safe, although thread safety is not
+ necessarily guaranteed. Code that is not thread-safe may experience
+ :term:`race conditions ` and :term:`data races `
+ when used in multi-threaded programs.
+
token
A small unit of source code, generated by the
diff --git a/Doc/howto/gdb_helpers.rst b/Doc/howto/gdb_helpers.rst
index 98ce813ca4ab02..33d1fbf8cd9e9e 100644
--- a/Doc/howto/gdb_helpers.rst
+++ b/Doc/howto/gdb_helpers.rst
@@ -136,7 +136,7 @@ enabled::
at Objects/unicodeobject.c:551
#7 0x0000000000440d94 in PyUnicodeUCS2_FromString (u=0x5c2b8d "__lltrace__") at Objects/unicodeobject.c:569
#8 0x0000000000584abd in PyDict_GetItemString (v=
- {'Yuck': , '__builtins__': , '__file__': 'Lib/test/crashers/nasty_eq_vs_dict.py', '__package__': None, 'y': , 'dict': {0: 0, 1: 1, 2: 2, 3: 3}, '__cached__': None, '__name__': '__main__', 'z': , '__doc__': None}, key=
+ {'Yuck': , '__builtins__': , '__file__': 'Lib/test/crashers/nasty_eq_vs_dict.py', '__package__': None, 'y': , 'dict': {0: 0, 1: 1, 2: 2, 3: 3}, '__name__': '__main__', 'z': , '__doc__': None}, key=
0x5c2b8d "__lltrace__") at Objects/dictobject.c:2171
Notice how the dictionary argument to ``PyDict_GetItemString`` is displayed
diff --git a/Doc/howto/remote_debugging.rst b/Doc/howto/remote_debugging.rst
index 78b40bcdf7127b..dfe0176b75a020 100644
--- a/Doc/howto/remote_debugging.rst
+++ b/Doc/howto/remote_debugging.rst
@@ -8,6 +8,16 @@ execute Python code remotely.
Most platforms require elevated privileges to attach to another Python process.
+Disabling remote debugging
+--------------------------
+
+To disable remote debugging support, use any of the following:
+
+* Set the :envvar:`PYTHON_DISABLE_REMOTE_DEBUG` environment variable to ``1`` before
+ starting the interpreter.
+* Use the :option:`-X disable_remote_debug` command-line option.
+* Compile Python with the :option:`--without-remote-debug` build flag.
+
.. _permission-requirements:
Permission requirements
@@ -614,4 +624,3 @@ To inject and execute a Python script in a remote process:
6. Set ``_PY_EVAL_PLEASE_STOP_BIT`` in the ``eval_breaker`` field.
7. Resume the process (if suspended). The script will execute at the next safe
evaluation point.
-
diff --git a/Doc/includes/capi-extension/spammodule-01.c b/Doc/includes/capi-extension/spammodule-01.c
new file mode 100644
index 00000000000000..86c9840359d9c7
--- /dev/null
+++ b/Doc/includes/capi-extension/spammodule-01.c
@@ -0,0 +1,55 @@
+/* This file needs to be kept in sync with the tutorial
+ * at Doc/extending/first-extension-module.rst
+ */
+
+/// Includes
+
+#include
+#include // for system()
+
+/// Implementation of spam.system
+
+static PyObject *
+spam_system(PyObject *self, PyObject *arg)
+{
+ const char *command = PyUnicode_AsUTF8(arg);
+ if (command == NULL) {
+ return NULL;
+ }
+ int status = system(command);
+ PyObject *result = PyLong_FromLong(status);
+ return result;
+}
+
+/// Module method table
+
+static PyMethodDef spam_methods[] = {
+ {
+ .ml_name="system",
+ .ml_meth=spam_system,
+ .ml_flags=METH_O,
+ .ml_doc="Execute a shell command.",
+ },
+ {NULL, NULL, 0, NULL} /* Sentinel */
+};
+
+/// Module slot table
+
+static PyModuleDef_Slot spam_slots[] = {
+ {Py_mod_name, "spam"},
+ {Py_mod_doc, "A wonderful module with an example function"},
+ {Py_mod_methods, spam_methods},
+ {0, NULL}
+};
+
+/// Export hook prototype
+
+PyMODEXPORT_FUNC PyModExport_spam(void);
+
+/// Module export hook
+
+PyMODEXPORT_FUNC
+PyModExport_spam(void)
+{
+ return spam_slots;
+}
diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst
index d50ec34e54d710..f4109fe0e5f2bf 100644
--- a/Doc/library/argparse.rst
+++ b/Doc/library/argparse.rst
@@ -645,6 +645,27 @@ are set.
.. versionadded:: 3.14
+To highlight inline code in your description or epilog text, you can use
+backticks::
+
+ >>> parser = argparse.ArgumentParser(
+ ... formatter_class=argparse.RawDescriptionHelpFormatter,
+ ... epilog='''Examples:
+ ... `python -m myapp --verbose`
+ ... `python -m myapp --config settings.json`
+ ... ''')
+
+When colors are enabled, the text inside backticks will be displayed in a
+distinct color to help examples stand out. When colors are disabled, backticks
+are preserved as-is, which is readable in plain text.
+
+.. note::
+
+ Backtick markup only applies to description and epilog text. It does not
+ apply to individual argument ``help`` strings.
+
+.. versionadded:: 3.15
+
The add_argument() method
-------------------------
@@ -732,7 +753,7 @@ upper-cased name. For example::
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo-bar')
- >>> parser.parse_args(['--foo-bar', 'FOO-BAR']
+ >>> parser.parse_args(['--foo-bar', 'FOO-BAR'])
Namespace(foo_bar='FOO-BAR')
>>> parser.print_help()
usage: [-h] [--foo-bar FOO-BAR]
@@ -1349,7 +1370,7 @@ behavior::
>>> parser.parse_args('--foo XXX'.split())
Namespace(bar='XXX')
-.. versionchanged:: next
+.. versionchanged:: 3.15
Single-dash long option now takes precedence over short options.
@@ -1452,7 +1473,7 @@ this API may be passed as the ``action`` parameter to
.. versionadded:: 3.9
- .. versionchanged:: next
+ .. versionchanged:: 3.15
Added support for single-dash options.
Added support for alternate prefix_chars_.
diff --git a/Doc/library/array.rst b/Doc/library/array.rst
index 1f04f697c7507f..5592bd7089ba49 100644
--- a/Doc/library/array.rst
+++ b/Doc/library/array.rst
@@ -9,7 +9,7 @@
--------------
This module defines an object type which can compactly represent an array of
-basic values: characters, integers, floating-point numbers. Arrays are sequence
+basic values: characters, integers, floating-point numbers. Arrays are mutable :term:`sequence`
types and behave very much like lists, except that the type of objects stored in
them is constrained. The type is specified at object creation time by using a
:dfn:`type code`, which is a single character. The following type codes are
@@ -93,7 +93,7 @@ The module defines the following type:
otherwise, the initializer's iterator is passed to the :meth:`extend` method
to add initial items to the array.
- Array objects support the ordinary sequence operations of indexing, slicing,
+ Array objects support the ordinary :ref:`mutable ` :term:`sequence` operations of indexing, slicing,
concatenation, and multiplication. When using slice assignment, the assigned
value must be an array object with the same type code; in all other cases,
:exc:`TypeError` is raised. Array objects also implement the buffer interface,
diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst
index 2e7d0dbc26e5bc..bf37540e5faf42 100644
--- a/Doc/library/ast.rst
+++ b/Doc/library/ast.rst
@@ -139,12 +139,13 @@ Node classes
The :meth:`~object.__repr__` output of :class:`~ast.AST` nodes includes
the values of the node fields.
-.. deprecated:: 3.8
+.. deprecated-removed:: 3.8 3.14
- Old classes :class:`!ast.Num`, :class:`!ast.Str`, :class:`!ast.Bytes`,
- :class:`!ast.NameConstant` and :class:`!ast.Ellipsis` are still available,
- but they will be removed in future Python releases. In the meantime,
- instantiating them will return an instance of a different class.
+ Previous versions of Python provided the AST classes :class:`!ast.Num`,
+ :class:`!ast.Str`, :class:`!ast.Bytes`, :class:`!ast.NameConstant` and
+ :class:`!ast.Ellipsis`, which were deprecated in Python 3.8. These classes
+ were removed in Python 3.14, and their functionality has been replaced with
+ :class:`ast.Constant`.
.. deprecated:: 3.9
@@ -2419,12 +2420,12 @@ and classes for traversing abstract syntax trees:
during traversal. For this a special visitor exists
(:class:`NodeTransformer`) that allows modifications.
- .. deprecated:: 3.8
+ .. deprecated-removed:: 3.8 3.14
Methods :meth:`!visit_Num`, :meth:`!visit_Str`, :meth:`!visit_Bytes`,
- :meth:`!visit_NameConstant` and :meth:`!visit_Ellipsis` are deprecated
- now and will not be called in future Python versions. Add the
- :meth:`visit_Constant` method to handle all constant nodes.
+ :meth:`!visit_NameConstant` and :meth:`!visit_Ellipsis` will not be called
+ in Python 3.14+. Add the :meth:`visit_Constant` method instead to handle
+ all constant nodes.
.. class:: NodeTransformer()
diff --git a/Doc/library/asyncio-queue.rst b/Doc/library/asyncio-queue.rst
index d481a1921d532b..a9735ae80652df 100644
--- a/Doc/library/asyncio-queue.rst
+++ b/Doc/library/asyncio-queue.rst
@@ -107,7 +107,7 @@ Queue
The queue can no longer grow.
Future calls to :meth:`~Queue.put` raise :exc:`QueueShutDown`.
Currently blocked callers of :meth:`~Queue.put` will be unblocked
- and will raise :exc:`QueueShutDown` in the formerly blocked thread.
+ and will raise :exc:`QueueShutDown` in the formerly awaiting task.
If *immediate* is false (the default), the queue can be wound
down normally with :meth:`~Queue.get` calls to extract tasks
diff --git a/Doc/library/base64.rst b/Doc/library/base64.rst
index 529a7242443820..65b8aeaef8e939 100644
--- a/Doc/library/base64.rst
+++ b/Doc/library/base64.rst
@@ -51,7 +51,7 @@ The :rfc:`4648` encodings are suitable for encoding binary data so that it can b
safely sent by email, used as parts of URLs, or included as part of an HTTP
POST request.
-.. function:: b64encode(s, altchars=None)
+.. function:: b64encode(s, altchars=None, *, wrapcol=0)
Encode the :term:`bytes-like object` *s* using Base64 and return the encoded
:class:`bytes`.
@@ -61,11 +61,19 @@ POST request.
This allows an application to e.g. generate URL or filesystem safe Base64
strings. The default is ``None``, for which the standard Base64 alphabet is used.
+ If *wrapcol* is non-zero, insert a newline (``b'\n'``) character
+ after at most every *wrapcol* characters.
+ If *wrapcol* is zero (default), do not insert any newlines.
+
May assert or raise a :exc:`ValueError` if the length of *altchars* is not 2. Raises a
:exc:`TypeError` if *altchars* is not a :term:`bytes-like object`.
+ .. versionchanged:: 3.15
+ Added the *wrapcol* parameter.
+
.. function:: b64decode(s, altchars=None, validate=False)
+ b64decode(s, altchars=None, validate=True, *, ignorechars)
Decode the Base64 encoded :term:`bytes-like object` or ASCII string
*s* and return the decoded :class:`bytes`.
@@ -77,15 +85,30 @@ POST request.
A :exc:`binascii.Error` exception is raised
if *s* is incorrectly padded.
- If *validate* is ``False`` (the default), characters that are neither
+ If *ignorechars* is specified, it should be a :term:`bytes-like object`
+ containing characters to ignore from the input when *validate* is true.
+ The default value of *validate* is ``True`` if *ignorechars* is specified,
+ ``False`` otherwise.
+
+ If *validate* is false, characters that are neither
in the normal base-64 alphabet nor the alternative alphabet are
- discarded prior to the padding check. If *validate* is ``True``,
- these non-alphabet characters in the input result in a
- :exc:`binascii.Error`.
+ discarded prior to the padding check, but the ``+`` and ``/`` characters
+ keep their meaning if they are not in *altchars* (they will be discarded
+ in future Python versions).
+
+ If *validate* is true, these non-alphabet characters in the input
+ result in a :exc:`binascii.Error`.
For more information about the strict base64 check, see :func:`binascii.a2b_base64`
- May assert or raise a :exc:`ValueError` if the length of *altchars* is not 2.
+ .. deprecated:: next
+ Accepting the ``+`` and ``/`` characters with an alternative alphabet
+ is now deprecated.
+
+
+ .. versionchanged:: next
+ Added the *ignorechars* parameter.
+
.. function:: standard_b64encode(s)
@@ -116,6 +139,9 @@ POST request.
``/`` in the standard Base64 alphabet, and return the decoded
:class:`bytes`.
+ .. deprecated:: next
+ Accepting the ``+`` and ``/`` characters is now deprecated.
+
.. function:: b32encode(s)
@@ -214,9 +240,9 @@ Refer to the documentation of the individual functions for more information.
instead of 4 consecutive spaces (ASCII 0x20) as supported by 'btoa'. This
feature is not supported by the "standard" Ascii85 encoding.
- *wrapcol* controls whether the output should have newline (``b'\n'``)
- characters added to it. If this is non-zero, each output line will be
- at most this many characters long, excluding the trailing newline.
+ If *wrapcol* is non-zero, insert a newline (``b'\n'``) character
+ after at most every *wrapcol* characters.
+ If *wrapcol* is zero (default), do not insert any newlines.
*pad* controls whether the input is padded to a multiple of 4
before encoding. Note that the ``btoa`` implementation always pads.
@@ -239,8 +265,7 @@ Refer to the documentation of the individual functions for more information.
*adobe* controls whether the input sequence is in Adobe Ascii85 format
(i.e. is framed with <~ and ~>).
- *ignorechars* should be a :term:`bytes-like object` or ASCII string
- containing characters to ignore
+ *ignorechars* should be a byte string containing characters to ignore
from the input. This should only contain whitespace characters, and by
default contains all whitespace characters in ASCII.
@@ -267,14 +292,20 @@ Refer to the documentation of the individual functions for more information.
.. versionadded:: 3.4
-.. function:: z85encode(s)
+.. function:: z85encode(s, pad=False)
Encode the :term:`bytes-like object` *s* using Z85 (as used in ZeroMQ)
and return the encoded :class:`bytes`. See `Z85 specification
`_ for more information.
+ If *pad* is true, the input is padded with ``b'\0'`` so its length is a
+ multiple of 4 bytes before encoding.
+
.. versionadded:: 3.13
+ .. versionchanged:: 3.15
+ The *pad* parameter was added.
+
.. function:: z85decode(s)
diff --git a/Doc/library/binascii.rst b/Doc/library/binascii.rst
index 1bab785684bbab..d9f0baedec85f2 100644
--- a/Doc/library/binascii.rst
+++ b/Doc/library/binascii.rst
@@ -49,16 +49,22 @@ The :mod:`binascii` module defines the following functions:
.. function:: a2b_base64(string, /, *, strict_mode=False)
+ a2b_base64(string, /, *, strict_mode=True, ignorechars)
Convert a block of base64 data back to binary and return the binary data. More
than one line may be passed at a time.
+ If *ignorechars* is specified, it should be a :term:`bytes-like object`
+ containing characters to ignore from the input when *strict_mode* is true.
+ The default value of *strict_mode* is ``True`` if *ignorechars* is specified,
+ ``False`` otherwise.
+
If *strict_mode* is true, only valid base64 data will be converted. Invalid base64
data will raise :exc:`binascii.Error`.
Valid base64:
- * Conforms to :rfc:`3548`.
+ * Conforms to :rfc:`4648`.
* Contains only characters from the base64 alphabet.
* Contains no excess data after padding (including excess padding, newlines, etc.).
* Does not start with a padding.
@@ -66,16 +72,28 @@ The :mod:`binascii` module defines the following functions:
.. versionchanged:: 3.11
Added the *strict_mode* parameter.
+ .. versionchanged:: next
+ Added the *ignorechars* parameter.
+
+
+.. function:: b2a_base64(data, *, wrapcol=0, newline=True)
-.. function:: b2a_base64(data, *, newline=True)
+ Convert binary data to a line(s) of ASCII characters in base64 coding,
+ as specified in :rfc:`4648`.
- Convert binary data to a line of ASCII characters in base64 coding. The return
- value is the converted line, including a newline char if *newline* is
- true. The output of this function conforms to :rfc:`3548`.
+ If *wrapcol* is non-zero, insert a newline (``b'\n'``) character
+ after at most every *wrapcol* characters.
+ If *wrapcol* is zero (default), do not insert any newlines.
+
+ If *newline* is true (default), a newline character will be added
+ at the end of the output.
.. versionchanged:: 3.6
Added the *newline* parameter.
+ .. versionchanged:: 3.15
+ Added the *wrapcol* parameter.
+
.. function:: a2b_qp(data, header=False)
diff --git a/Doc/library/compression.zstd.rst b/Doc/library/compression.zstd.rst
index 89b6fe540f5ba7..7ca843f27f5e9a 100644
--- a/Doc/library/compression.zstd.rst
+++ b/Doc/library/compression.zstd.rst
@@ -73,7 +73,7 @@ Reading and writing compressed files
argument is not None, a :exc:`!TypeError` will be raised.
When writing, the *options* argument can be a dictionary
- providing advanced decompression parameters; see
+ providing advanced compression parameters; see
:class:`CompressionParameter` for detailed information about supported
parameters. The *level* argument is the compression level to use when
writing compressed data. Only one of *level* or *options* may be non-None.
@@ -117,7 +117,7 @@ Reading and writing compressed files
argument is not None, a :exc:`!TypeError` will be raised.
When writing, the *options* argument can be a dictionary
- providing advanced decompression parameters; see
+ providing advanced compression parameters; see
:class:`CompressionParameter` for detailed information about supported
parameters. The *level* argument is the compression level to use when
writing compressed data. Only one of *level* or *options* may be passed. The
diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst
index c2e2f7f820f4ef..e4b505c3f9761e 100644
--- a/Doc/library/concurrent.futures.rst
+++ b/Doc/library/concurrent.futures.rst
@@ -21,6 +21,11 @@ or separate processes, using :class:`ProcessPoolExecutor`.
Each implements the same interface, which is defined
by the abstract :class:`Executor` class.
+:class:`concurrent.futures.Future` must not be confused with
+:class:`asyncio.Future`, which is designed for use with :mod:`asyncio`
+tasks and coroutines. See the :doc:`asyncio's Future `
+documentation for a detailed comparison of the two.
+
.. include:: ../includes/wasm-notavail.rst
Executor Objects
@@ -308,7 +313,7 @@ the bytes over a shared :mod:`socket ` or
.. note::
The executor may replace uncaught exceptions from *initializer*
- with :class:`~concurrent.futures.interpreter.ExecutionFailed`.
+ with :class:`~concurrent.interpreters.ExecutionFailed`.
Other caveats from parent :class:`ThreadPoolExecutor` apply here.
@@ -320,11 +325,11 @@ likewise serializes the return value when sending it back.
When a worker's current task raises an uncaught exception, the worker
always tries to preserve the exception as-is. If that is successful
then it also sets the ``__cause__`` to a corresponding
-:class:`~concurrent.futures.interpreter.ExecutionFailed`
+:class:`~concurrent.interpreters.ExecutionFailed`
instance, which contains a summary of the original exception.
In the uncommon case that the worker is not able to preserve the
original as-is then it directly preserves the corresponding
-:class:`~concurrent.futures.interpreter.ExecutionFailed`
+:class:`~concurrent.interpreters.ExecutionFailed`
instance instead.
@@ -379,6 +384,11 @@ in a REPL or a lambda should not be expected to work.
default in absence of a *mp_context* parameter. This feature is incompatible
with the "fork" start method.
+ .. note::
+ Bugs have been reported when using the *max_tasks_per_child* feature that
+ can result in the :class:`ProcessPoolExecutor` hanging in some
+ circumstances. Follow its eventual resolution in :gh:`115634`.
+
.. versionchanged:: 3.3
When one of the worker processes terminates abruptly, a
:exc:`~concurrent.futures.process.BrokenProcessPool` error is now raised.
@@ -715,15 +725,6 @@ Exception classes
.. versionadded:: 3.14
-.. exception:: ExecutionFailed
-
- Raised from :class:`~concurrent.futures.InterpreterPoolExecutor` when
- the given initializer fails or from
- :meth:`~concurrent.futures.Executor.submit` when there's an uncaught
- exception from the submitted task.
-
- .. versionadded:: 3.14
-
.. currentmodule:: concurrent.futures.process
.. exception:: BrokenProcessPool
diff --git a/Doc/library/contextvars.rst b/Doc/library/contextvars.rst
index b218468a084db1..653d8b597c2362 100644
--- a/Doc/library/contextvars.rst
+++ b/Doc/library/contextvars.rst
@@ -77,6 +77,32 @@ Context Variables
to restore the variable to its previous value via the
:meth:`ContextVar.reset` method.
+ For convenience, the token object can be used as a context manager
+ to avoid calling :meth:`ContextVar.reset` manually::
+
+ var = ContextVar('var', default='default value')
+
+ with var.set('new value'):
+ assert var.get() == 'new value'
+
+ assert var.get() == 'default value'
+
+ It is a shorthand for::
+
+ var = ContextVar('var', default='default value')
+
+ token = var.set('new value')
+ try:
+ assert var.get() == 'new value'
+ finally:
+ var.reset(token)
+
+ assert var.get() == 'default value'
+
+ .. versionadded:: 3.14
+
+ Added support for using tokens as context managers.
+
.. method:: reset(token)
Reset the context variable to the value it had before the
@@ -93,24 +119,18 @@ Context Variables
# After the reset call the var has no value again, so
# var.get() would raise a LookupError.
+ The same *token* cannot be used twice.
+
.. class:: Token
*Token* objects are returned by the :meth:`ContextVar.set` method.
They can be passed to the :meth:`ContextVar.reset` method to revert
the value of the variable to what it was before the corresponding
- *set*.
-
- The token supports :ref:`context manager protocol `
- to restore the corresponding context variable value at the exit from
- :keyword:`with` block::
-
- var = ContextVar('var', default='default value')
-
- with var.set('new value'):
- assert var.get() == 'new value'
+ *set*. A single token cannot reset a context variable more than once.
- assert var.get() == 'default value'
+ Tokens support the :ref:`context manager protocol `
+ to automatically reset context variables. See :meth:`ContextVar.set`.
.. versionadded:: 3.14
diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst
index 9c0b246c095483..6038af99009d02 100644
--- a/Doc/library/ctypes.rst
+++ b/Doc/library/ctypes.rst
@@ -1388,6 +1388,9 @@ On Linux, :func:`~ctypes.util.find_library` tries to run external programs
(``/sbin/ldconfig``, ``gcc``, ``objdump`` and ``ld``) to find the library file.
It returns the filename of the library file.
+Note that if the output of these programs does not correspond to the dynamic
+linker used by Python, the result of this function may be misleading.
+
.. versionchanged:: 3.6
On Linux, the value of the environment variable ``LD_LIBRARY_PATH`` is used
when searching for libraries, if a library cannot be found by any other means.
@@ -2132,6 +2135,8 @@ Utility functions
The exact functionality is system dependent.
+ See :ref:`ctypes-finding-shared-libraries` for complete documentation.
+
.. function:: find_msvcrt()
:module: ctypes.util
diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst
index 8ae1c1fb9e46bb..48e7080da6c525 100644
--- a/Doc/library/datetime.rst
+++ b/Doc/library/datetime.rst
@@ -2651,9 +2651,42 @@ Broadly speaking, ``d.strftime(fmt)`` acts like the :mod:`time` module's
``time.strftime(fmt, d.timetuple())`` although not all objects support a
:meth:`~date.timetuple` method.
-For the :meth:`.datetime.strptime` class method, the default value is
-``1900-01-01T00:00:00.000``: any components not specified in the format string
-will be pulled from the default value. [#]_
+For the :meth:`.datetime.strptime` and :meth:`.date.strptime` class methods,
+the default value is ``1900-01-01T00:00:00.000``: any components not specified
+in the format string will be pulled from the default value.
+
+.. note::
+ When used to parse partial dates lacking a year, :meth:`.datetime.strptime`
+ and :meth:`.date.strptime` will raise when encountering February 29 because
+ the default year of 1900 is *not* a leap year. Always add a default leap
+ year to partial date strings before parsing.
+
+
+.. testsetup::
+
+ # doctest seems to turn the warning into an error which makes it
+ # show up and require matching and prevents the actual interesting
+ # exception from being raised.
+ # Manually apply the catch_warnings context manager
+ import warnings
+ catch_warnings = warnings.catch_warnings()
+ catch_warnings.__enter__()
+ warnings.simplefilter("ignore")
+
+.. testcleanup::
+
+ catch_warnings.__exit__()
+
+.. doctest::
+
+ >>> from datetime import datetime
+ >>> value = "2/29"
+ >>> datetime.strptime(value, "%m/%d")
+ Traceback (most recent call last):
+ ...
+ ValueError: day 29 must be in range 1..28 for month 2 in year 1900
+ >>> datetime.strptime(f"1904 {value}", "%Y %m/%d")
+ datetime.datetime(1904, 2, 29, 0, 0)
Using ``datetime.strptime(date_string, format)`` is equivalent to::
@@ -2790,7 +2823,7 @@ Notes:
include a year in the format. If the value you need to parse lacks a year,
append an explicit dummy leap year. Otherwise your code will raise an
exception when it encounters leap day because the default year used by the
- parser is not a leap year. Users run into this bug every four years...
+ parser (1900) is not a leap year. Users run into that bug every leap year.
.. doctest::
@@ -2817,5 +2850,3 @@ Notes:
.. [#] See R. H. van Gent's `guide to the mathematics of the ISO 8601 calendar
`_
for a good explanation.
-
-.. [#] Passing ``datetime.strptime('Feb 29', '%b %d')`` will fail since 1900 is not a leap year.
diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst
index 621aa23ecc8057..376bcc7aaf9eb2 100644
--- a/Doc/library/decimal.rst
+++ b/Doc/library/decimal.rst
@@ -34,10 +34,12 @@ The :mod:`decimal` module provides support for fast correctly rounded
decimal floating-point arithmetic. It offers several advantages over the
:class:`float` datatype:
-* Decimal "is based on a floating-point model which was designed with people
- in mind, and necessarily has a paramount guiding principle -- computers must
- provide an arithmetic that works in the same way as the arithmetic that
- people learn at school." -- excerpt from the decimal arithmetic specification.
+* Decimal "is based on a `floating-point model
+ `__ which was designed
+ with people in mind, and necessarily has a paramount guiding principle --
+ computers must provide an arithmetic that works in the same way as the
+ arithmetic that people learn at school." -- excerpt from the decimal
+ arithmetic specification.
* Decimal numbers can be represented exactly. In contrast, numbers like
``1.1`` and ``2.2`` do not have exact representations in binary
@@ -238,6 +240,26 @@ floating-point flying circus:
>>> c % a
Decimal('0.77')
+Decimals can be formatted (with :func:`format` built-in or :ref:`f-strings`) in
+fixed-point or scientific notation, using the same formatting syntax (see
+:ref:`formatspec`) as builtin :class:`float` type:
+
+.. doctest::
+
+ >>> format(Decimal('2.675'), "f")
+ '2.675'
+ >>> format(Decimal('2.675'), ".2f")
+ '2.68'
+ >>> f"{Decimal('2.675'):.2f}"
+ '2.68'
+ >>> format(Decimal('2.675'), ".2e")
+ '2.68e+0'
+ >>> with localcontext() as ctx:
+ ... ctx.rounding = ROUND_DOWN
+ ... print(format(Decimal('2.675'), ".2f"))
+ ...
+ 2.67
+
And some mathematical functions are also available to Decimal:
>>> getcontext().prec = 28
diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst
index a24589fd0a5af3..755d681b9df2be 100644
--- a/Doc/library/dis.rst
+++ b/Doc/library/dis.rst
@@ -768,7 +768,7 @@ not have to be) the original ``STACK[-2]``.
end = STACK.pop()
start = STACK.pop()
container = STACK.pop()
- values = STACK.pop()
+ value = STACK.pop()
container[start:end] = value
.. versionadded:: 3.12
diff --git a/Doc/library/email.message.rst b/Doc/library/email.message.rst
index 71d6e321f387bc..0aa8e632c2ca80 100644
--- a/Doc/library/email.message.rst
+++ b/Doc/library/email.message.rst
@@ -57,7 +57,7 @@ message objects.
:class:`~email.policy.default` policy, which follows the rules of the email
RFCs except for line endings (instead of the RFC mandated ``\r\n``, it uses
the Python standard ``\n`` line endings). For more information see the
- :mod:`~email.policy` documentation.
+ :mod:`~email.policy` documentation. [2]_
.. method:: as_string(unixfrom=False, maxheaderlen=None, policy=None)
@@ -749,3 +749,9 @@ message objects.
.. [1] Originally added in 3.4 as a :term:`provisional module `. Docs for legacy message class moved to
:ref:`compat32_message`.
+
+.. [2] The :class:`EmailMessage` class requires a policy that provides a
+ ``content_manager`` attribute for content management methods like
+ ``set_content()`` and ``get_content()`` to work. The legacy
+ :const:`~email.policy.compat32` policy does not support these methods
+ and should not be used with :class:`EmailMessage`.
diff --git a/Doc/library/email.policy.rst b/Doc/library/email.policy.rst
index 6b997ee784f6e4..1ff3e2c3f8df6b 100644
--- a/Doc/library/email.policy.rst
+++ b/Doc/library/email.policy.rst
@@ -662,6 +662,13 @@ The header objects and their attributes are described in
An instance of :class:`Compat32`, providing backward compatibility with the
behavior of the email package in Python 3.2.
+ .. note::
+
+ The :const:`compat32` policy should not be used as a policy for
+ :class:`~email.message.EmailMessage` objects, and should only be used
+ to serialize messages that were created using the :const:`compat32`
+ policy.
+
.. rubric:: Footnotes
diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst
index a8a7e671aadca2..b39164e54753a7 100644
--- a/Doc/library/enum.rst
+++ b/Doc/library/enum.rst
@@ -153,6 +153,12 @@ Module Contents
Return a list of all power-of-two integers contained in a flag.
+ :func:`enum.bin`
+
+ Like built-in :func:`bin`, except negative values are represented in
+ two's complement, and the leading bit always indicates sign
+ (``0`` implies positive, ``1`` implies negative).
+
.. versionadded:: 3.6 ``Flag``, ``IntFlag``, ``auto``
.. versionadded:: 3.11 ``StrEnum``, ``EnumCheck``, ``ReprEnum``, ``FlagBoundary``, ``property``, ``member``, ``nonmember``, ``global_enum``, ``show_flag_values``
@@ -947,12 +953,13 @@ Utilities and Decorators
the member's name. Care must be taken if mixing *auto()* with manually
specified values.
- *auto* instances are only resolved when at the top level of an assignment:
+ *auto* instances are only resolved when at the top level of an assignment, either by
+ itself or as part of a tuple:
* ``FIRST = auto()`` will work (auto() is replaced with ``1``);
* ``SECOND = auto(), -2`` will work (auto is replaced with ``2``, so ``2, -2`` is
used to create the ``SECOND`` enum member;
- * ``THREE = [auto(), -3]`` will *not* work (``, -3`` is used to
+ * ``THREE = [auto(), -3]`` will *not* work (``[, -3]`` is used to
create the ``THREE`` enum member)
.. versionchanged:: 3.11.1
@@ -1034,6 +1041,20 @@ Utilities and Decorators
.. versionadded:: 3.11
+.. function:: bin(num, max_bits=None)
+
+ Like built-in :func:`bin`, except negative values are represented in
+ two's complement, and the leading bit always indicates sign
+ (``0`` implies positive, ``1`` implies negative).
+
+ >>> import enum
+ >>> enum.bin(10)
+ '0b0 1010'
+ >>> enum.bin(~10) # ~10 is -11
+ '0b1 0101'
+
+ .. versionadded:: 3.10
+
---------------
Notes
diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst
index b5e3a84b4556dd..f3aca1ba49257b 100644
--- a/Doc/library/exceptions.rst
+++ b/Doc/library/exceptions.rst
@@ -742,8 +742,8 @@ depending on the system error code.
.. attribute:: characters_written
- An integer containing the number of characters written to the stream
- before it blocked. This attribute is available when using the
+ An integer containing the number of **bytes** written to the stream
+ before it blocked. This attribute is available when using the
buffered I/O classes from the :mod:`io` module.
.. exception:: ChildProcessError
diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst
index bb15322067245e..88eb0be9de88b8 100644
--- a/Doc/library/ftplib.rst
+++ b/Doc/library/ftplib.rst
@@ -524,14 +524,9 @@ FTP_TLS objects
:class:`!FTP_TLS` class inherits from :class:`FTP`,
defining these additional methods and attributes:
- .. attribute:: FTP_TLS.ssl_version
-
- The SSL version to use (defaults to :data:`ssl.PROTOCOL_SSLv23`).
-
.. method:: FTP_TLS.auth()
- Set up a secure control connection by using TLS or SSL, depending on what
- is specified in the :attr:`ssl_version` attribute.
+ Set up a secure control connection by using TLS.
.. versionchanged:: 3.4
The method now supports hostname check with
@@ -548,7 +543,7 @@ FTP_TLS objects
.. method:: FTP_TLS.prot_p()
- Set up secure data connection.
+ Set up secure data connection by using TLS.
.. method:: FTP_TLS.prot_c()
diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst
index 8314fed80fa512..cd819b8d06480a 100644
--- a/Doc/library/functions.rst
+++ b/Doc/library/functions.rst
@@ -138,6 +138,8 @@ are always available. They are listed here in alphabetical order.
>>> f'{14:#b}', f'{14:b}'
('0b1110', '1110')
+ See also :func:`enum.bin` to represent negative values as twos-complement.
+
See also :func:`format` for more information.
@@ -340,8 +342,8 @@ are always available. They are listed here in alphabetical order.
It is needed to unambiguous :ref:`filter ` syntax warnings
by module name.
- This function raises :exc:`SyntaxError` if the compiled source is invalid,
- and :exc:`ValueError` if the source contains null bytes.
+ This function raises :exc:`SyntaxError` or :exc:`ValueError` if the compiled
+ source is invalid.
If you want to parse Python code into its AST representation, see
:func:`ast.parse`.
@@ -526,7 +528,7 @@ are always available. They are listed here in alphabetical order.
>>> dir() # show the names in the module namespace # doctest: +SKIP
['__builtins__', '__name__', 'struct']
>>> dir(struct) # show the names in the struct module # doctest: +SKIP
- ['Struct', '__all__', '__builtins__', '__cached__', '__doc__', '__file__',
+ ['Struct', '__all__', '__builtins__', '__doc__', '__file__',
'__initializing__', '__loader__', '__name__', '__package__',
'_clearcache', 'calcsize', 'error', 'pack', 'pack_into',
'unpack', 'unpack_from']
@@ -606,16 +608,16 @@ are always available. They are listed here in alphabetical order.
This function executes arbitrary code. Calling it with
user-supplied input may lead to security vulnerabilities.
- The *expression* argument is parsed and evaluated as a Python expression
+ The *source* argument is parsed and evaluated as a Python expression
(technically speaking, a condition list) using the *globals* and *locals*
mappings as global and local namespace. If the *globals* dictionary is
present and does not contain a value for the key ``__builtins__``, a
reference to the dictionary of the built-in module :mod:`builtins` is
- inserted under that key before *expression* is parsed. That way you can
+ inserted under that key before *source* is parsed. That way you can
control what builtins are available to the executed code by inserting your
own ``__builtins__`` dictionary into *globals* before passing it to
:func:`eval`. If the *locals* mapping is omitted it defaults to the
- *globals* dictionary. If both mappings are omitted, the expression is
+ *globals* dictionary. If both mappings are omitted, the source is
executed with the *globals* and *locals* in the environment where
:func:`eval` is called. Note, *eval()* will only have access to the
:term:`nested scopes ` (non-locals) in the enclosing
diff --git a/Doc/library/gc.rst b/Doc/library/gc.rst
index 79a8c38626f002..0e041b5395ec93 100644
--- a/Doc/library/gc.rst
+++ b/Doc/library/gc.rst
@@ -118,7 +118,7 @@ The :mod:`gc` module provides the following functions:
.. versionadded:: 3.4
- .. versionchanged:: next
+ .. versionchanged:: 3.15
Add ``duration`` and ``candidates``.
@@ -340,7 +340,7 @@ values but should not rebind them):
.. versionadded:: 3.3
- .. versionchanged:: next
+ .. versionchanged:: 3.15
Add "duration" and "candidates".
diff --git a/Doc/library/http.client.rst b/Doc/library/http.client.rst
index 7c258b324d9867..ddf3d40d221fcd 100644
--- a/Doc/library/http.client.rst
+++ b/Doc/library/http.client.rst
@@ -319,6 +319,12 @@ HTTPConnection Objects
:class:`str` or bytes-like object that is not also a file as the
body representation.
+ .. note::
+
+ Note that you must have read the whole response or call :meth:`close`
+ if :meth:`getresponse` raised an non-:exc:`ConnectionError` exception
+ before you can send a new request to the server.
+
.. versionchanged:: 3.2
*body* can now be an iterable.
@@ -334,16 +340,15 @@ HTTPConnection Objects
Should be called after a request is sent to get the response from the server.
Returns an :class:`HTTPResponse` instance.
- .. note::
-
- Note that you must have read the whole response before you can send a new
- request to the server.
-
.. versionchanged:: 3.5
If a :exc:`ConnectionError` or subclass is raised, the
:class:`HTTPConnection` object will be ready to reconnect when
a new request is sent.
+ Note that this does not apply to :exc:`OSError`\s raised by the underlying
+ socket. Instead the caller is responsible to call :meth:`close` on the
+ existing connection.
+
.. method:: HTTPConnection.set_debuglevel(level)
diff --git a/Doc/library/http.cookies.rst b/Doc/library/http.cookies.rst
index 88e978d7f5eafb..50b65459d2f699 100644
--- a/Doc/library/http.cookies.rst
+++ b/Doc/library/http.cookies.rst
@@ -294,9 +294,9 @@ The following example demonstrates how to use the :mod:`http.cookies` module.
Set-Cookie: chips=ahoy
Set-Cookie: vienna=finger
>>> C = cookies.SimpleCookie()
- >>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=\\012;";')
+ >>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=;";')
>>> print(C)
- Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;"
+ Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=;"
>>> C = cookies.SimpleCookie()
>>> C["oreo"] = "doublestuff"
>>> C["oreo"]["path"] = "/"
diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst
index a16f46ef812400..89be225b6baae4 100644
--- a/Doc/library/idle.rst
+++ b/Doc/library/idle.rst
@@ -158,7 +158,7 @@ Go to Line
Show Completions
Open a scrollable list allowing selection of existing names. See
- :ref:`Completions ` in the Editing and navigation section below.
+ :ref:`Completions ` in the Editing and Navigation section below.
Expand Word
Expand a prefix you have typed to match a full word in the same window;
@@ -167,7 +167,7 @@ Expand Word
Show Call Tip
After an unclosed parenthesis for a function, open a small window with
function parameter hints. See :ref:`Calltips ` in the
- Editing and navigation section below.
+ Editing and Navigation section below.
Show Surrounding Parens
Highlight the surrounding parenthesis.
@@ -178,9 +178,9 @@ Format menu (Editor window only)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Format Paragraph
- Reformat the current blank-line-delimited paragraph in comment block or
- multiline string or selected line in a string. All lines in the
- paragraph will be formatted to less than N columns, where N defaults to 72.
+ Rewrap the text block containing the text insert cursor.
+ Avoid code lines. See :ref:`Format block` in the
+ Editing and Navigation section below.
Indent Region
Shift selected lines right by the indent width (default 4 spaces).
@@ -566,6 +566,20 @@ In an editor, import statements have no effect until one runs the file.
One might want to run a file after writing import statements, after
adding function definitions, or after opening an existing file.
+.. _format-block:
+
+Format block
+^^^^^^^^^^^^
+
+Reformat Paragraph rewraps a block ('paragraph') of contiguous equally
+indented non-blank comments, a similar block of text within a multiline
+string, or a selected subset of either.
+If needed, add a blank line to separate string from code.
+Partial lines in a selection expand to complete lines.
+The resulting lines have the same indent as before
+but have maximum total length of N columns (characters).
+Change the default N of 72 on the Window tab of IDLE Settings.
+
.. _code-context:
Code Context
diff --git a/Doc/library/importlib.metadata.rst b/Doc/library/importlib.metadata.rst
index 12014309e26ec9..9e08e5aa989cf7 100644
--- a/Doc/library/importlib.metadata.rst
+++ b/Doc/library/importlib.metadata.rst
@@ -418,6 +418,16 @@ Distributions
equal, even if they relate to the same installed distribution and
accordingly have the same attributes.
+ .. method:: discover(cls, *, context=None, **kwargs)
+
+ Returns an iterable of :class:`Distribution` instances for all packages.
+
+ The optional argument *context* is a :class:`DistributionFinder.Context`
+ instance, used to modify the search for distributions. Alternatively,
+ *kwargs* may contain keyword arguments for constructing a new
+ :class:`!DistributionFinder.Context`.
+
+
While the module level API described above is the most common and convenient usage,
you can get all of that information from the :class:`!Distribution` class.
:class:`!Distribution` is an abstract object that represents the metadata for
@@ -466,6 +476,61 @@ This metadata finder search defaults to ``sys.path``, but varies slightly in how
- ``importlib.metadata`` does not honor :class:`bytes` objects on ``sys.path``.
- ``importlib.metadata`` will incidentally honor :py:class:`pathlib.Path` objects on ``sys.path`` even though such values will be ignored for imports.
+.. class:: DistributionFinder
+
+ A :class:`~importlib.abc.MetaPathFinder` subclass capable of discovering
+ installed distributions.
+
+ Custom providers should implement this interface in order to
+ supply metadata.
+
+ .. class:: Context(**kwargs)
+
+ A :class:`!Context` gives a custom provider a means to
+ solicit additional details from the callers of distribution discovery
+ functions like :func:`distributions` or :meth:`Distribution.discover`
+ beyond :attr:`!.name` and :attr:`!.path` when searching
+ for distributions.
+
+ For example, a provider could expose suites of packages in either a
+ "public" or "private" ``realm``. A caller of distribution discovery
+ functions may wish to query only for distributions in a particular realm
+ and could call ``distributions(realm="private")`` to signal to the
+ custom provider to only include distributions from that
+ realm.
+
+ Each :class:`!DistributionFinder` must expect any parameters and should
+ attempt to honor the canonical parameters defined below when
+ appropriate.
+
+ See the section on :ref:`implementing-custom-providers` for more details.
+
+ .. attribute:: name
+
+ Specific name for which a distribution finder should match.
+
+ A :attr:`!.name` of ``None`` matches all distributions.
+
+ .. attribute:: path
+
+ A property providing the sequence of directory paths that a
+ distribution finder should search.
+
+ Typically refers to Python installed package paths such as
+ "site-packages" directories and defaults to :attr:`sys.path`.
+
+
+.. function:: distributions(**kwargs)
+
+ Returns an iterable of :class:`Distribution` instances for all packages.
+
+ The *kwargs* argument may contain either a keyword argument ``context``, a
+ :class:`DistributionFinder.Context` instance, or pass keyword arguments for
+ constructing a new :class:`!DistributionFinder.Context`. The
+ :class:`!DistributionFinder.Context` is used to modify the search for
+ distributions.
+
+.. _implementing-custom-providers:
Implementing Custom Providers
=============================
@@ -493,7 +558,7 @@ interface expected of finders by Python's import system.
``importlib.metadata`` extends this protocol by looking for an optional
``find_distributions`` callable on the finders from
:data:`sys.meta_path` and presents this extended interface as the
-``DistributionFinder`` abstract base class, which defines this abstract
+:class:`DistributionFinder` abstract base class, which defines this abstract
method::
@abc.abstractmethod
@@ -502,9 +567,11 @@ method::
loading the metadata for packages for the indicated ``context``.
"""
-The ``DistributionFinder.Context`` object provides ``.path`` and ``.name``
-properties indicating the path to search and name to match and may
-supply other relevant context sought by the consumer.
+The :class:`DistributionFinder.Context` object provides
+:attr:`~DistributionFinder.Context.path` and
+:attr:`~DistributionFinder.Context.name` properties indicating the path to
+search and name to match and may supply other relevant context sought by the
+consumer.
In practice, to support finding distribution package
metadata in locations other than the file system, subclass
@@ -529,7 +596,7 @@ Imagine a custom finder that loads Python modules from a database::
That importer now presumably provides importable modules from a
database, but it provides no metadata or entry points. For this
custom importer to provide metadata, it would also need to implement
-``DistributionFinder``::
+:class:`DistributionFinder`::
from importlib.metadata import DistributionFinder
diff --git a/Doc/library/importlib.resources.abc.rst b/Doc/library/importlib.resources.abc.rst
index 8253a33f591a0b..45979c5691270a 100644
--- a/Doc/library/importlib.resources.abc.rst
+++ b/Doc/library/importlib.resources.abc.rst
@@ -63,11 +63,14 @@
If the resource does not concretely exist on the file system,
raise :exc:`FileNotFoundError`.
- .. method:: is_resource(name)
+ .. method:: is_resource(path)
:abstractmethod:
- Returns ``True`` if the named *name* is considered a resource.
- :exc:`FileNotFoundError` is raised if *name* does not exist.
+ Returns ``True`` if the named *path* is considered a resource.
+ :exc:`FileNotFoundError` is raised if *path* does not exist.
+
+ .. versionchanged:: 3.10
+ The argument *name* was renamed to *path*.
.. method:: contents()
:abstractmethod:
diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst
index b851b929b7e2fb..26964348f5cd25 100644
--- a/Doc/library/importlib.rst
+++ b/Doc/library/importlib.rst
@@ -596,172 +596,6 @@ ABC hierarchy::
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 e.g. in a 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.
-
- .. method:: open_resource(resource)
- :abstractmethod:
-
- Returns an opened, :term:`file-like object` for binary reading
- of the *resource*.
-
- If the resource cannot be found, :exc:`FileNotFoundError` is
- raised.
-
- .. method:: resource_path(resource)
- :abstractmethod:
-
- Returns the file system path to the *resource*.
-
- If the resource does not concretely exist on the file system,
- raise :exc:`FileNotFoundError`.
-
- .. method:: is_resource(name)
- :abstractmethod:
-
- Returns ``True`` if the named *name* is considered a resource.
- :exc:`FileNotFoundError` is raised if *name* does not exist.
-
- .. method:: contents()
- :abstractmethod:
-
- 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.
-
- .. method:: iterdir()
- :abstractmethod:
-
- Yield ``Traversable`` objects in ``self``.
-
- .. method:: is_dir()
- :abstractmethod:
-
- Return ``True`` if ``self`` is a directory.
-
- .. method:: is_file()
- :abstractmethod:
-
- Return ``True`` if ``self`` is a file.
-
- .. method:: joinpath(child)
- :abstractmethod:
-
- Return Traversable child in ``self``.
-
- .. method:: __truediv__(child)
- :abstractmethod:
-
- Return ``Traversable`` child in ``self``.
-
- .. method:: open(mode='r', *args, **kwargs)
- :abstractmethod:
-
- *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 :class:`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.
-
- .. method:: files()
- :abstractmethod:
-
- Returns a :class:`importlib.resources.abc.Traversable` object for the loaded
- package.
-
-
-
:mod:`importlib.machinery` -- Importers and path hooks
------------------------------------------------------
@@ -1197,8 +1031,7 @@ find and load modules.
.. attribute:: cached
- The filename of a compiled version of the module's code
- (see :attr:`module.__cached__`).
+ The filename of a compiled version of the module's code.
The :term:`finder` should always set this attribute but it may be ``None``
for modules that do not need compiled code stored.
diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst
index 5220c559d3d857..5133f9f0c8e43b 100644
--- a/Doc/library/inspect.rst
+++ b/Doc/library/inspect.rst
@@ -273,6 +273,9 @@ attributes (see :ref:`import-mod-attrs` for module attributes):
+-----------------+-------------------+---------------------------+
| | ag_running | is the generator running? |
+-----------------+-------------------+---------------------------+
+| | ag_suspended | is the generator |
+| | | suspended? |
++-----------------+-------------------+---------------------------+
| | ag_code | code |
+-----------------+-------------------+---------------------------+
| coroutine | __name__ | name |
@@ -286,6 +289,9 @@ attributes (see :ref:`import-mod-attrs` for module attributes):
+-----------------+-------------------+---------------------------+
| | cr_running | is the coroutine running? |
+-----------------+-------------------+---------------------------+
+| | cr_suspended | is the coroutine |
+| | | suspended? |
++-----------------+-------------------+---------------------------+
| | cr_code | code |
+-----------------+-------------------+---------------------------+
| | cr_origin | where coroutine was |
@@ -319,6 +325,18 @@ attributes (see :ref:`import-mod-attrs` for module attributes):
Add ``__builtins__`` attribute to functions.
+.. versionchanged:: 3.11
+
+ Add ``gi_suspended`` attribute to generators.
+
+.. versionchanged:: 3.11
+
+ Add ``cr_suspended`` attribute to coroutines.
+
+.. versionchanged:: 3.12
+
+ Add ``ag_suspended`` attribute to async generators.
+
.. versionchanged:: 3.14
Add ``f_generator`` attribute to frames.
@@ -506,7 +524,7 @@ attributes (see :ref:`import-mod-attrs` for module attributes):
.. versionchanged:: 3.13
Functions wrapped in :func:`functools.partialmethod` now return ``True``
- if the wrapped function is a :term:`coroutine function`.
+ if the wrapped function is a :term:`asynchronous generator` function.
.. function:: isasyncgen(object)
@@ -640,7 +658,7 @@ Retrieving source code
Added parameters *inherit_class_doc* and *fallback_to_class_doc*.
Documentation strings on :class:`~functools.cached_property`
- objects are now inherited if not overriden.
+ objects are now inherited if not overridden.
.. function:: getcomments(object)
diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst
index aa46920d3526f0..08dacb505f7748 100644
--- a/Doc/library/itertools.rst
+++ b/Doc/library/itertools.rst
@@ -47,7 +47,7 @@ Iterator Arguments Results
Iterator Arguments Results Example
============================ ============================ ================================================= =============================================================
:func:`accumulate` p [,func] p0, p0+p1, p0+p1+p2, ... ``accumulate([1,2,3,4,5]) → 1 3 6 10 15``
-:func:`batched` p, n (p0, p1, ..., p_n-1), ... ``batched('ABCDEFG', n=2) → AB CD EF G``
+:func:`batched` p, n (p0, p1, ..., p_n-1), ... ``batched('ABCDEFG', n=3) → ABC DEF G``
:func:`chain` p, q, ... p0, p1, ... plast, q0, q1, ... ``chain('ABC', 'DEF') → A B C D E F``
:func:`chain.from_iterable` iterable p0, p1, ... plast, q0, q1, ... ``chain.from_iterable(['ABC', 'DEF']) → A B C D E F``
:func:`compress` data, selectors (d[0] if s[0]), (d[1] if s[1]), ... ``compress('ABCDEF', [1,0,1,0,1,1]) → A C E F``
@@ -181,7 +181,7 @@ loops that truncate the stream.
Roughly equivalent to::
def batched(iterable, n, *, strict=False):
- # batched('ABCDEFG', 2) → AB CD EF G
+ # batched('ABCDEFG', 3) → ABC DEF G
if n < 1:
raise ValueError('n must be at least one')
iterator = iter(iterable)
@@ -819,7 +819,7 @@ well as with the built-in itertools such as ``map()``, ``filter()``,
A secondary purpose of the recipes is to serve as an incubator. The
``accumulate()``, ``compress()``, and ``pairwise()`` itertools started out as
-recipes. Currently, the ``sliding_window()``, ``iter_index()``, and ``sieve()``
+recipes. Currently, the ``sliding_window()``, ``derangements()``, and ``sieve()``
recipes are being tested to see whether they prove their worth.
Substantially all of these recipes and many, many others can be installed from
@@ -838,11 +838,16 @@ and :term:`generators ` which incur interpreter overhead.
.. testcode::
+ from itertools import (accumulate, batched, chain, combinations, compress,
+ count, cycle, filterfalse, groupby, islice, permutations, product,
+ repeat, starmap, tee, zip_longest)
from collections import Counter, deque
from contextlib import suppress
from functools import reduce
- from math import comb, prod, sumprod, isqrt
- from operator import itemgetter, getitem, mul, neg
+ from math import comb, isqrt, prod, sumprod
+ from operator import getitem, is_not, itemgetter, mul, neg
+
+ # ==== Basic one liners ====
def take(n, iterable):
"Return first n items of the iterable as a list."
@@ -899,8 +904,8 @@ and :term:`generators ` which incur interpreter overhead.
def first_true(iterable, default=False, predicate=None):
"Returns the first true value or the *default* if there is no true value."
- # first_true([a,b,c], x) → a or b or c or x
- # first_true([a,b], x, f) → a if f(a) else b if f(b) else x
+ # first_true([a, b, c], x) → a or b or c or x
+ # first_true([a, b], x, f) → a if f(a) else b if f(b) else x
return next(filter(predicate, iterable), default)
def all_equal(iterable, key=None):
@@ -908,6 +913,8 @@ and :term:`generators ` which incur interpreter overhead.
# all_equal('4٤௪౪໔', key=int) → True
return len(take(2, groupby(iterable, key))) <= 1
+ # ==== Data pipelines ====
+
def unique_justseen(iterable, key=None):
"Yield unique elements, preserving order. Remember only the element just seen."
# unique_justseen('AAAABBBCCDAABBB') → A B C D A B
@@ -940,7 +947,7 @@ and :term:`generators ` which incur interpreter overhead.
def sliding_window(iterable, n):
"Collect data into overlapping fixed-length chunks or blocks."
- # sliding_window('ABCDEFG', 4) → ABCD BCDE CDEF DEFG
+ # sliding_window('ABCDEFG', 3) → ABC BCD CDE DEF EFG
iterator = iter(iterable)
window = deque(islice(iterator, n - 1), maxlen=n)
for x in iterator:
@@ -949,7 +956,7 @@ and :term:`generators ` which incur interpreter overhead.
def grouper(iterable, n, *, incomplete='fill', fillvalue=None):
"Collect data into non-overlapping fixed-length chunks or blocks."
- # grouper('ABCDEFG', 3, fillvalue='x') → ABC DEF Gxx
+ # grouper('ABCDEFG', 3, fillvalue='x') → ABC DEF Gxx
# grouper('ABCDEFG', 3, incomplete='strict') → ABC DEF ValueError
# grouper('ABCDEFG', 3, incomplete='ignore') → ABC DEF
iterators = [iter(iterable)] * n
@@ -978,6 +985,16 @@ and :term:`generators ` which incur interpreter overhead.
slices = starmap(slice, combinations(range(len(seq) + 1), 2))
return map(getitem, repeat(seq), slices)
+ def derangements(iterable, r=None):
+ "Produce r length permutations without fixed points."
+ # derangements('ABCD') → BADC BCDA BDAC CADB CDAB CDBA DABC DCAB DCBA
+ # Algorithm credited to Stefan Pochmann
+ seq = tuple(iterable)
+ pos = tuple(range(len(seq)))
+ have_moved = map(map, repeat(is_not), repeat(pos), permutations(pos, r=r))
+ valid_derangements = map(all, have_moved)
+ return compress(permutations(seq, r=r), valid_derangements)
+
def iter_index(iterable, value, start=0, stop=None):
"Return indices where a value occurs in a sequence or iterable."
# iter_index('AABCADEAF', 'A') → 0 1 4 7
@@ -1004,10 +1021,7 @@ and :term:`generators ` which incur interpreter overhead.
while True:
yield function()
-
-The following recipes have a more mathematical flavor:
-
-.. testcode::
+ # ==== Mathematical operations ====
def multinomial(*counts):
"Number of distinct arrangements of a multiset."
@@ -1026,9 +1040,11 @@ The following recipes have a more mathematical flavor:
# sum_of_squares([10, 20, 30]) → 1400
return sumprod(*tee(iterable))
+ # ==== Matrix operations ====
+
def reshape(matrix, columns):
"Reshape a 2-D matrix to have a given number of columns."
- # reshape([(0, 1), (2, 3), (4, 5)], 3) → (0, 1, 2), (3, 4, 5)
+ # reshape([(0, 1), (2, 3), (4, 5)], 3) → (0, 1, 2) (3, 4, 5)
return batched(chain.from_iterable(matrix), columns, strict=True)
def transpose(matrix):
@@ -1038,10 +1054,12 @@ The following recipes have a more mathematical flavor:
def matmul(m1, m2):
"Multiply two matrices."
- # matmul([(7, 5), (3, 5)], [(2, 5), (7, 9)]) → (49, 80), (41, 60)
+ # matmul([(7, 5), (3, 5)], [(2, 5), (7, 9)]) → (49, 80) (41, 60)
n = len(m2[0])
return batched(starmap(sumprod, product(m1, transpose(m2))), n)
+ # ==== Polynomial arithmetic ====
+
def convolve(signal, kernel):
"""Discrete linear convolution of two iterables.
Equivalent to polynomial multiplication.
@@ -1096,6 +1114,8 @@ The following recipes have a more mathematical flavor:
powers = reversed(range(1, n))
return list(map(mul, coefficients, powers))
+ # ==== Number theory ====
+
def sieve(n):
"Primes less than n."
# sieve(30) → 2 3 5 7 11 13 17 19 23 29
@@ -1663,6 +1683,36 @@ The following recipes have a more mathematical flavor:
['A', 'AB', 'ABC', 'ABCD', 'B', 'BC', 'BCD', 'C', 'CD', 'D']
+ >>> ' '.join(map(''.join, derangements('ABCD')))
+ 'BADC BCDA BDAC CADB CDAB CDBA DABC DCAB DCBA'
+ >>> ' '.join(map(''.join, derangements('ABCD', 3)))
+ 'BAD BCA BCD BDA CAB CAD CDA CDB DAB DCA DCB'
+ >>> ' '.join(map(''.join, derangements('ABCD', 2)))
+ 'BA BC BD CA CD DA DC'
+ >>> ' '.join(map(''.join, derangements('ABCD', 1)))
+ 'B C D'
+ >>> ' '.join(map(''.join, derangements('ABCD', 0)))
+ ''
+ >>> # Compare number of derangements to https://oeis.org/A000166
+ >>> [len(list(derangements(range(n)))) for n in range(10)]
+ [1, 0, 1, 2, 9, 44, 265, 1854, 14833, 133496]
+ >>> # Verify that identical objects are treated as unique by position
+ >>> identical = 'X'
+ >>> distinct = 'x'
+ >>> seq1 = ('A', identical, 'B', identical)
+ >>> result1 = ' '.join(map(''.join, derangements(seq1)))
+ >>> result1
+ 'XAXB XBXA XXAB BAXX BXAX BXXA XAXB XBAX XBXA'
+ >>> seq2 = ('A', identical, 'B', distinct)
+ >>> result2 = ' '.join(map(''.join, derangements(seq2)))
+ >>> result2
+ 'XAxB XBxA XxAB BAxX BxAX BxXA xAXB xBAX xBXA'
+ >>> result1 == result2
+ False
+ >>> result1.casefold() == result2.casefold()
+ True
+
+
>>> list(powerset([1,2,3]))
[(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]
>>> all(len(list(powerset(range(n)))) == 2**n for n in range(18))
diff --git a/Doc/library/linecache.rst b/Doc/library/linecache.rst
index e766a9280946d3..07305a2a39b252 100644
--- a/Doc/library/linecache.rst
+++ b/Doc/library/linecache.rst
@@ -31,7 +31,7 @@ The :mod:`linecache` module defines the following functions:
.. index:: triple: module; search; path
If *filename* indicates a frozen module (starting with ``'>> import locale
+ >>> loc = locale.setlocale(locale.LC_ALL) # get current locale
+ # use German locale; name and availability varies with platform
+ >>> locale.setlocale(locale.LC_ALL, 'de_DE.UTF-8')
+ >>> locale.strcoll('f\xe4n', 'foo') # compare a string containing an umlaut
+ >>> locale.setlocale(locale.LC_ALL, '') # use user's preferred locale
+ >>> locale.setlocale(locale.LC_ALL, 'C') # use default (C) locale
+ >>> locale.setlocale(locale.LC_ALL, loc) # restore saved locale
+
:func:`setlocale` is not thread-safe on most systems. Applications typically
- start with a call of ::
+ start with a call of::
import locale
locale.setlocale(locale.LC_ALL, '')
@@ -359,8 +370,6 @@ The :mod:`locale` module defines the following exception and functions:
determined.
The "C" locale is represented as ``(None, None)``.
- .. deprecated-removed:: 3.11 3.15
-
.. function:: getlocale(category=LC_CTYPE)
@@ -580,18 +589,6 @@ The :mod:`locale` module defines the following exception and functions:
:func:`localeconv`.
-Example::
-
- >>> import locale
- >>> loc = locale.getlocale() # get current locale
- # use German locale; name might vary with platform
- >>> locale.setlocale(locale.LC_ALL, 'de_DE')
- >>> locale.strcoll('f\xe4n', 'foo') # compare a string containing an umlaut
- >>> locale.setlocale(locale.LC_ALL, '') # use user's preferred locale
- >>> locale.setlocale(locale.LC_ALL, 'C') # use default (C) locale
- >>> locale.setlocale(locale.LC_ALL, loc) # restore saved locale
-
-
Background, details, hints, tips and caveats
--------------------------------------------
diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst
index 0cf5b1c0d9bc3e..d17f36bc7131d6 100644
--- a/Doc/library/logging.rst
+++ b/Doc/library/logging.rst
@@ -1011,6 +1011,11 @@ the options available to you.
| exc_info | You shouldn't need to | Exception tuple (à la ``sys.exc_info``) or, |
| | format this yourself. | if no exception has occurred, ``None``. |
+----------------+-------------------------+-----------------------------------------------+
+| exc_text | You shouldn't need to | Exception information formatted as a string. |
+| | format this yourself. | This is set when :meth:`Formatter.format` is |
+| | | invoked, or ``None`` if no exception has |
+| | | occurred. |
++----------------+-------------------------+-----------------------------------------------+
| filename | ``%(filename)s`` | Filename portion of ``pathname``. |
+----------------+-------------------------+-----------------------------------------------+
| funcName | ``%(funcName)s`` | Name of function containing the logging call. |
diff --git a/Doc/library/mmap.rst b/Doc/library/mmap.rst
index f32aa322c40dbb..774d05fdcaa300 100644
--- a/Doc/library/mmap.rst
+++ b/Doc/library/mmap.rst
@@ -212,7 +212,7 @@ To map anonymous memory, -1 should be passed as the fileno along with the length
Writable :term:`bytes-like object` is now accepted.
- .. method:: flush([offset[, size]])
+ .. method:: flush([offset[, size]], *, flags=MS_SYNC)
Flushes changes made to the in-memory copy of a file back to disk. Without
use of this call there is no guarantee that changes are written back before
@@ -221,6 +221,12 @@ To map anonymous memory, -1 should be passed as the fileno along with the length
whole extent of the mapping is flushed. *offset* must be a multiple of the
:const:`PAGESIZE` or :const:`ALLOCATIONGRANULARITY`.
+ The *flags* parameter specifies the synchronization behavior.
+ *flags* must be one of the :ref:`MS_* constants ` available
+ on the system.
+
+ On Windows, the *flags* parameter is ignored.
+
``None`` is returned to indicate success. An exception is raised when the
call failed.
@@ -235,6 +241,9 @@ To map anonymous memory, -1 should be passed as the fileno along with the length
specified alone, and the flush operation will extend from *offset*
to the end of the mmap.
+ .. versionchanged:: 3.15
+ Added *flags* parameter to control synchronization behavior.
+
.. method:: madvise(option[, start[, length]])
@@ -328,6 +337,17 @@ To map anonymous memory, -1 should be passed as the fileno along with the length
.. versionadded:: 3.13
+ .. method:: set_name(name, /)
+
+ Annotate the memory mapping with the given *name* for easier identification
+ in ``/proc//maps`` if the kernel supports the feature and :option:`-X dev <-X>` is passed
+ to Python or if Python is built in :ref:`debug mode `.
+ The length of *name* must not exceed 67 bytes including the ``'\0'`` terminator.
+
+ .. availability:: Linux >= 5.17 (kernel built with ``CONFIG_ANON_VMA_NAME`` option)
+
+ .. versionadded:: 3.15
+
.. method:: size()
Return the length of the file, which can be larger than the size of the
@@ -450,3 +470,22 @@ MAP_* Constants
:data:`MAP_TPRO`, :data:`MAP_TRANSLATED_ALLOW_EXECUTE`, and
:data:`MAP_UNIX03` constants.
+.. _ms-constants:
+
+MS_* Constants
+++++++++++++++
+
+.. data:: MS_SYNC
+ MS_ASYNC
+ MS_INVALIDATE
+
+ These flags control the synchronization behavior for :meth:`mmap.flush`:
+
+ * :data:`MS_SYNC` - Synchronous flush: writes are scheduled and the call
+ blocks until they are physically written to storage.
+ * :data:`MS_ASYNC` - Asynchronous flush: writes are scheduled but the call
+ returns immediately without waiting for completion.
+ * :data:`MS_INVALIDATE` - Invalidate cached data: invalidates other mappings
+ of the same file so they can see the changes.
+
+ .. versionadded:: 3.15
diff --git a/Doc/library/msvcrt.rst b/Doc/library/msvcrt.rst
index a2c5e375d2cc4f..80f3ae4ee3f5c1 100644
--- a/Doc/library/msvcrt.rst
+++ b/Doc/library/msvcrt.rst
@@ -7,6 +7,8 @@
.. sectionauthor:: Fred L. Drake, Jr.
+**Source code:** :source:`PC/msvcrtmodule.c`
+
--------------
These functions provide access to some useful capabilities on Windows platforms.
diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst
index 92605c57527887..b158ee1d42c774 100644
--- a/Doc/library/multiprocessing.rst
+++ b/Doc/library/multiprocessing.rst
@@ -521,6 +521,21 @@ Reference
The :mod:`multiprocessing` package mostly replicates the API of the
:mod:`threading` module.
+.. _global-start-method:
+
+Global start method
+^^^^^^^^^^^^^^^^^^^
+
+Python supports several ways to create and initialize a process.
+The global start method sets the default mechanism for creating a process.
+
+Several multiprocessing functions and methods that may also instantiate
+certain objects will implicitly set the global start method to the system's default,
+if it hasn’t been set already. The global start method can only be set once.
+If you need to change the start method from the system default, you must
+proactively set the global start method before calling functions or methods,
+or creating these objects.
+
:class:`Process` and exceptions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -910,6 +925,9 @@ For an example of the usage of queues for interprocess communication see
locks/semaphores. When a process first puts an item on the queue a feeder
thread is started which transfers objects from a buffer into the pipe.
+ Instantiating this class may set the global start method. See
+ :ref:`global-start-method` for more details.
+
The usual :exc:`queue.Empty` and :exc:`queue.Full` exceptions from the
standard library's :mod:`queue` module are raised to signal timeouts.
@@ -1025,6 +1043,9 @@ For an example of the usage of queues for interprocess communication see
It is a simplified :class:`Queue` type, very close to a locked :class:`Pipe`.
+ Instantiating this class may set the global start method. See
+ :ref:`global-start-method` for more details.
+
.. method:: close()
Close the queue: release internal resources.
@@ -1055,6 +1076,9 @@ For an example of the usage of queues for interprocess communication see
:class:`JoinableQueue`, a :class:`Queue` subclass, is a queue which
additionally has :meth:`task_done` and :meth:`join` methods.
+ Instantiating this class may set the global start method. See
+ :ref:`global-start-method` for more details.
+
.. method:: task_done()
Indicate that a formerly enqueued task is complete. Used by queue
@@ -1167,8 +1191,8 @@ Miscellaneous
:mod:`multiprocessing` module.
If *method* is ``None`` then the default context is returned. Note that if
- the global start method has not been set, this will set it to the
- default method.
+ the global start method has not been set, this will set it to the system default
+ See :ref:`global-start-method` for more details.
Otherwise *method* should be ``'fork'``, ``'spawn'``,
``'forkserver'``. :exc:`ValueError` is raised if the specified
start method is not available. See :ref:`multiprocessing-start-methods`.
@@ -1179,10 +1203,9 @@ Miscellaneous
Return the name of start method used for starting processes.
- If the global start method has not been set and *allow_none* is
- ``False``, then the start method is set to the default and the name
- is returned. If the start method has not been set and *allow_none* is
- ``True`` then ``None`` is returned.
+ If the global start method is not set and *allow_none* is ``False``, the global start
+ method is set to the default, and its name is returned. See
+ :ref:`global-start-method` for more details.
The return value can be ``'fork'``, ``'spawn'``, ``'forkserver'``
or ``None``. See :ref:`multiprocessing-start-methods`.
@@ -1211,22 +1234,32 @@ Miscellaneous
.. versionchanged:: 3.11
Accepts a :term:`path-like object`.
-.. function:: set_forkserver_preload(module_names)
+.. function:: set_forkserver_preload(module_names, *, on_error='ignore')
Set a list of module names for the forkserver main process to attempt to
import so that their already imported state is inherited by forked
- processes. Any :exc:`ImportError` when doing so is silently ignored.
- This can be used as a performance enhancement to avoid repeated work
- in every process.
+ processes. This can be used as a performance enhancement to avoid repeated
+ work in every process.
For this to work, it must be called before the forkserver process has been
launched (before creating a :class:`Pool` or starting a :class:`Process`).
+ The *on_error* parameter controls how :exc:`ImportError` exceptions during
+ module preloading are handled: ``"ignore"`` (default) silently ignores
+ failures, ``"warn"`` causes the forkserver subprocess to emit an
+ :exc:`ImportWarning` to stderr, and ``"fail"`` causes the forkserver
+ subprocess to exit with the exception traceback on stderr, making
+ subsequent process creation fail with :exc:`EOFError` or
+ :exc:`ConnectionError`.
+
Only meaningful when using the ``'forkserver'`` start method.
See :ref:`multiprocessing-start-methods`.
.. versionadded:: 3.4
+ .. versionchanged:: next
+ Added the *on_error* parameter.
+
.. function:: set_start_method(method, force=False)
Set the method which should be used to start child processes.
@@ -1409,6 +1442,9 @@ object -- see :ref:`multiprocessing-managers`.
A barrier object: a clone of :class:`threading.Barrier`.
+ Instantiating this class may set the global start method. See
+ :ref:`global-start-method` for more details.
+
.. versionadded:: 3.3
.. class:: BoundedSemaphore([value])
@@ -1416,6 +1452,9 @@ object -- see :ref:`multiprocessing-managers`.
A bounded semaphore object: a close analog of
:class:`threading.BoundedSemaphore`.
+ Instantiating this class may set the global start method. See
+ :ref:`global-start-method` for more details.
+
A solitary difference from its close analog exists: its ``acquire`` method's
first argument is named *block*, as is consistent with :meth:`Lock.acquire`.
@@ -1436,6 +1475,9 @@ object -- see :ref:`multiprocessing-managers`.
If *lock* is specified then it should be a :class:`Lock` or :class:`RLock`
object from :mod:`multiprocessing`.
+ Instantiating this class may set the global start method. See
+ :ref:`global-start-method` for more details.
+
.. versionchanged:: 3.3
The :meth:`~threading.Condition.wait_for` method was added.
@@ -1443,6 +1485,8 @@ object -- see :ref:`multiprocessing-managers`.
A clone of :class:`threading.Event`.
+ Instantiating this class may set the global start method. See
+ :ref:`global-start-method` for more details.
.. class:: Lock()
@@ -1458,6 +1502,9 @@ object -- see :ref:`multiprocessing-managers`.
instance of ``multiprocessing.synchronize.Lock`` initialized with a
default context.
+ Instantiating this class may set the global start method. See
+ :ref:`global-start-method` for more details.
+
:class:`Lock` supports the :term:`context manager` protocol and thus may be
used in :keyword:`with` statements.
@@ -1515,6 +1562,9 @@ object -- see :ref:`multiprocessing-managers`.
instance of ``multiprocessing.synchronize.RLock`` initialized with a
default context.
+ Instantiating this class may set the global start method. See
+ :ref:`global-start-method` for more details.
+
:class:`RLock` supports the :term:`context manager` protocol and thus may be
used in :keyword:`with` statements.
@@ -1574,6 +1624,9 @@ object -- see :ref:`multiprocessing-managers`.
A semaphore object: a close analog of :class:`threading.Semaphore`.
+ Instantiating this class may set the global start method. See
+ :ref:`global-start-method` for more details.
+
A solitary difference from its close analog exists: its ``acquire`` method's
first argument is named *block*, as is consistent with :meth:`Lock.acquire`.
@@ -1650,11 +1703,14 @@ inherited by child processes.
value is actually a synchronized wrapper for the array.
*typecode_or_type* determines the type of the elements of the returned array:
- it is either a ctypes type or a one character typecode of the kind used by
- the :mod:`array` module. If *size_or_initializer* is an integer, then it
- determines the length of the array, and the array will be initially zeroed.
- Otherwise, *size_or_initializer* is a sequence which is used to initialize
- the array and whose length determines the length of the array.
+ it is either a :ref:`ctypes type ` or a one
+ character typecode of the kind used by the :mod:`array` module with the
+ exception of ``'w'``, which is not supported. In addition, the ``'c'``
+ typecode is an alias for :class:`ctypes.c_char`. If *size_or_initializer*
+ is an integer, then it determines the length of the array, and the array
+ will be initially zeroed. Otherwise, *size_or_initializer* is a sequence
+ which is used to initialize the array and whose length determines the length
+ of the array.
If *lock* is ``True`` (the default) then a new lock object is created to
synchronize access to the value. If *lock* is a :class:`Lock` or
@@ -1718,7 +1774,7 @@ processes.
attributes which allow one to use it to store and retrieve strings -- see
documentation for :mod:`ctypes`.
-.. function:: Array(typecode_or_type, size_or_initializer, *, lock=True)
+.. function:: Array(typecode_or_type, size_or_initializer, *, lock=True, ctx=None)
The same as :func:`RawArray` except that depending on the value of *lock* a
process-safe synchronization wrapper may be returned instead of a raw ctypes
@@ -1732,9 +1788,13 @@ processes.
automatically protected by a lock, so it will not necessarily be
"process-safe".
- Note that *lock* is a keyword-only argument.
+ *ctx* is a context object, or ``None`` (use the current context). If ``None``,
+ calling this may set the global start method. See
+ :ref:`global-start-method` for more details.
-.. function:: Value(typecode_or_type, *args, lock=True)
+ Note that *lock* and *ctx* are keyword-only parameters.
+
+.. function:: Value(typecode_or_type, *args, lock=True, ctx=None)
The same as :func:`RawValue` except that depending on the value of *lock* a
process-safe synchronization wrapper may be returned instead of a raw ctypes
@@ -1747,19 +1807,27 @@ processes.
automatically protected by a lock, so it will not necessarily be
"process-safe".
- Note that *lock* is a keyword-only argument.
+ *ctx* is a context object, or ``None`` (use the current context). If ``None``,
+ calling this may set the global start method. See
+ :ref:`global-start-method` for more details.
+
+ Note that *lock* and *ctx* are keyword-only parameters.
.. function:: copy(obj)
Return a ctypes object allocated from shared memory which is a copy of the
ctypes object *obj*.
-.. function:: synchronized(obj[, lock])
+.. function:: synchronized(obj, lock=None, ctx=None)
Return a process-safe wrapper object for a ctypes object which uses *lock* to
synchronize access. If *lock* is ``None`` (the default) then a
:class:`multiprocessing.RLock` object is created automatically.
+ *ctx* is a context object, or ``None`` (use the current context). If ``None``,
+ calling this may set the global start method. See
+ :ref:`global-start-method` for more details.
+
A synchronized wrapper will have two methods in addition to those of the
object it wraps: :meth:`get_obj` returns the wrapped object and
:meth:`get_lock` returns the lock object used for synchronization.
@@ -1877,8 +1945,9 @@ their parent process exits. The manager classes are defined in the
*serializer* must be ``'pickle'`` (use :mod:`pickle` serialization) or
``'xmlrpclib'`` (use :mod:`xmlrpc.client` serialization).
- *ctx* is a context object, or ``None`` (use the current context). See the
- :func:`get_context` function.
+ *ctx* is a context object, or ``None`` (use the current context). If ``None``,
+ calling this may set the global start method. See
+ :ref:`global-start-method` for more details.
*shutdown_timeout* is a timeout in seconds used to wait until the process
used by the manager completes in the :meth:`shutdown` method. If the
@@ -2371,7 +2440,9 @@ with the :class:`Pool` class.
the worker processes. Usually a pool is created using the
function :func:`multiprocessing.Pool` or the :meth:`Pool` method
of a context object. In both cases *context* is set
- appropriately.
+ appropriately. If ``None``, calling this function will have the side effect
+ of setting the current global start method if it has not been set already.
+ See the :func:`get_context` function.
Note that the methods of the pool object should only be called by
the process which created the pool.
diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst
index c90e30ccf4fb8a..3cfe08a1fe1f7a 100644
--- a/Doc/library/os.path.rst
+++ b/Doc/library/os.path.rst
@@ -57,8 +57,9 @@ the :mod:`glob` module.)
.. function:: abspath(path)
Return a normalized absolutized version of the pathname *path*. On most
- platforms, this is equivalent to calling the function :func:`normpath` as
- follows: ``normpath(join(os.getcwd(), path))``.
+ platforms, this is equivalent to calling ``normpath(join(os.getcwd(), path))``.
+
+ .. seealso:: :func:`os.path.join` and :func:`os.path.normpath`.
.. versionchanged:: 3.6
Accepts a :term:`path-like object`.
@@ -243,6 +244,8 @@ the :mod:`glob` module.)
begins with a slash, on Windows that it begins with two (back)slashes, or a
drive letter, colon, and (back)slash together.
+ .. seealso:: :func:`abspath`
+
.. versionchanged:: 3.6
Accepts a :term:`path-like object`.
@@ -357,14 +360,28 @@ the :mod:`glob` module.)
concatenation of *path* and all members of *\*paths*, with exactly one
directory separator following each non-empty part, except the last. That is,
the result will only end in a separator if the last part is either empty or
- ends in a separator. If a segment is an absolute path (which on Windows
- requires both a drive and a root), then all previous segments are ignored and
- joining continues from the absolute path segment.
+ ends in a separator.
+
+ If a segment is an absolute path (which on Windows requires both a drive and
+ a root), then all previous segments are ignored and joining continues from the
+ absolute path segment. On Linux, for example::
+
+ >>> os.path.join('/home/foo', 'bar')
+ '/home/foo/bar'
+ >>> os.path.join('/home/foo', '/home/bar')
+ '/home/bar'
On Windows, the drive is not reset when a rooted path segment (e.g.,
``r'\foo'``) is encountered. If a segment is on a different drive or is an
- absolute path, all previous segments are ignored and the drive is reset. Note
- that since there is a current directory for each drive,
+ absolute path, all previous segments are ignored and the drive is reset. For
+ example::
+
+ >>> os.path.join('c:\\', 'foo')
+ 'c:\\foo'
+ >>> os.path.join('c:\\foo', 'd:\\bar')
+ 'd:\\bar'
+
+ Note that since there is a current directory for each drive,
``os.path.join("c:", "foo")`` represents a path relative to the current
directory on drive :file:`C:` (:file:`c:foo`), not :file:`c:\\foo`.
@@ -527,8 +544,8 @@ the :mod:`glob` module.)
*path* is empty, both *head* and *tail* are empty. Trailing slashes are
stripped from *head* unless it is the root (one or more slashes only). In
all cases, ``join(head, tail)`` returns a path to the same location as *path*
- (but the strings may differ). Also see the functions :func:`dirname` and
- :func:`basename`.
+ (but the strings may differ). Also see the functions :func:`join`,
+ :func:`dirname` and :func:`basename`.
.. versionchanged:: 3.6
Accepts a :term:`path-like object`.
diff --git a/Doc/library/os.rst b/Doc/library/os.rst
index 671270d6112212..dad54c0e82bbc2 100644
--- a/Doc/library/os.rst
+++ b/Doc/library/os.rst
@@ -1556,6 +1556,15 @@ or `the MSDN `_ on Windo
.. versionadded:: 3.15
+.. data:: RWF_ATOMIC
+
+ Write data atomically. Requires alignment to the device's atomic write unit.
+
+ .. availability:: Linux >= 6.11
+
+ .. versionadded:: 3.15
+
+
.. function:: ptsname(fd, /)
Return the name of the slave pseudo-terminal device associated with the
@@ -1598,6 +1607,7 @@ or `the MSDN `_ on Windo
- :data:`RWF_SYNC`
- :data:`RWF_APPEND`
- :data:`RWF_DONTCACHE`
+ - :data:`RWF_ATOMIC`
Return the total number of bytes actually written.
@@ -1969,7 +1979,8 @@ can be inherited by child processes. Since Python 3.4, file descriptors
created by Python are non-inheritable by default.
On UNIX, non-inheritable file descriptors are closed in child processes at the
-execution of a new program, other file descriptors are inherited.
+execution of a new program, other file descriptors are inherited. Note that
+non-inheritable file descriptors are still *inherited* by child processes on :func:`os.fork`.
On Windows, non-inheritable handles and file descriptors are closed in child
processes, except for standard streams (file descriptors 0, 1 and 2: stdin, stdout
@@ -4251,7 +4262,7 @@ features:
import os
# semaphore with start value '1'
- fd = os.eventfd(1, os.EFD_SEMAPHORE | os.EFC_CLOEXEC)
+ fd = os.eventfd(1, os.EFD_SEMAPHORE | os.EFD_CLOEXEC)
try:
# acquire semaphore
v = os.eventfd_read(fd)
@@ -5993,7 +6004,7 @@ Miscellaneous System Information
.. versionchanged:: 3.13
If :option:`-X cpu_count <-X>` is given or :envvar:`PYTHON_CPU_COUNT` is set,
- :func:`cpu_count` returns the overridden value *n*.
+ :func:`cpu_count` returns the override value *n*.
.. function:: getloadavg()
@@ -6015,7 +6026,7 @@ Miscellaneous System Information
in the **system**.
If :option:`-X cpu_count <-X>` is given or :envvar:`PYTHON_CPU_COUNT` is set,
- :func:`process_cpu_count` returns the overridden value *n*.
+ :func:`process_cpu_count` returns the override value *n*.
See also the :func:`sched_getaffinity` function.
diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst
index 79e0b7f09eaa77..1575de6c6f5935 100644
--- a/Doc/library/pathlib.rst
+++ b/Doc/library/pathlib.rst
@@ -1331,6 +1331,10 @@ Reading directories
PosixPath('setup.py'),
PosixPath('test_pathlib.py')]
+ .. note::
+ The paths are returned in no particular order.
+ If you need a specific order, sort the results.
+
.. seealso::
:ref:`pathlib-pattern-language` documentation.
@@ -1365,6 +1369,10 @@ Reading directories
Glob the given relative *pattern* recursively. This is like calling
:func:`Path.glob` with "``**/``" added in front of the *pattern*.
+ .. note::
+ The paths are returned in no particular order.
+ If you need a specific order, sort the results.
+
.. seealso::
:ref:`pathlib-pattern-language` and :meth:`Path.glob` documentation.
diff --git a/Doc/library/pdb.rst b/Doc/library/pdb.rst
index 0bbdc42535290a..8ab3e7ec9ef9d2 100644
--- a/Doc/library/pdb.rst
+++ b/Doc/library/pdb.rst
@@ -520,7 +520,8 @@ can be overridden by the local file.
To remove all commands from a breakpoint, type ``commands`` and follow it
immediately with ``end``; that is, give no commands.
- With no *bpnumber* argument, ``commands`` refers to the last breakpoint set.
+ With no *bpnumber* argument, ``commands`` refers to the most recently set
+ breakpoint that still exists.
You can use breakpoint commands to start your program up again. Simply use
the :pdbcmd:`continue` command, or :pdbcmd:`step`,
diff --git a/Doc/library/pickle.rst b/Doc/library/pickle.rst
index 3a9b66ec7e7088..7b0d979d61a36c 100644
--- a/Doc/library/pickle.rst
+++ b/Doc/library/pickle.rst
@@ -56,19 +56,6 @@ files.
The :mod:`pickle` module differs from :mod:`marshal` in several significant ways:
-* The :mod:`pickle` module keeps track of the objects it has already serialized,
- so that later references to the same object won't be serialized again.
- :mod:`marshal` doesn't do this.
-
- This has implications both for recursive objects and object sharing. Recursive
- objects are objects that contain references to themselves. These are not
- handled by marshal, and in fact, attempting to marshal recursive objects will
- crash your Python interpreter. Object sharing happens when there are multiple
- references to the same object in different places in the object hierarchy being
- serialized. :mod:`pickle` stores such objects only once, and ensures that all
- other references point to the master copy. Shared objects remain shared, which
- can be very important for mutable objects.
-
* :mod:`marshal` cannot be used to serialize user-defined classes and their
instances. :mod:`pickle` can save and restore class instances transparently,
however the class definition must be importable and live in the same module as
diff --git a/Doc/library/profiling.rst b/Doc/library/profiling.rst
index 4b56d9c4b7b1b8..0df9a5120a5df0 100644
--- a/Doc/library/profiling.rst
+++ b/Doc/library/profiling.rst
@@ -1,4 +1,4 @@
-.. highlight:: shell-session
+.. highlight:: sh
.. _profiling-module:
diff --git a/Doc/library/profiling.sampling.rst b/Doc/library/profiling.sampling.rst
index 23e9173a815d22..ac1098698c8cbb 100644
--- a/Doc/library/profiling.sampling.rst
+++ b/Doc/library/profiling.sampling.rst
@@ -1,4 +1,4 @@
-.. highlight:: shell-session
+.. highlight:: sh
.. _profiling-sampling:
@@ -53,7 +53,7 @@ counts**, not direct measurements. Tachyon counts how many times each function
appears in the collected samples, then multiplies by the sampling interval to
estimate time.
-For example, with a 100 microsecond sampling interval over a 10-second profile,
+For example, with a 10 kHz sampling rate over a 10-second profile,
Tachyon collects approximately 100,000 samples. If a function appears in 5,000
samples (5% of total), Tachyon estimates it consumed 5% of the 10-second
duration, or about 500 milliseconds. This is a statistical estimate, not a
@@ -142,7 +142,7 @@ Use live mode for real-time monitoring (press ``q`` to quit)::
Profile for 60 seconds with a faster sampling rate::
- python -m profiling.sampling run -d 60 -i 50 script.py
+ python -m profiling.sampling run -d 60 -r 20khz script.py
Generate a line-by-line heatmap::
@@ -191,10 +191,45 @@ production systems. The target process requires no modification and need not
be restarted. The profiler attaches, collects samples for the specified
duration, then detaches and produces output.
+::
+
+ python -m profiling.sampling attach --live 12345
+ python -m profiling.sampling attach --flamegraph -d 30 -o profile.html 12345
+
On most systems, attaching to another process requires appropriate permissions.
See :ref:`profiling-permissions` for platform-specific requirements.
+.. _replay-command:
+
+The ``replay`` command
+----------------------
+
+The ``replay`` command converts binary profile files to other output formats::
+
+ python -m profiling.sampling replay profile.bin
+ python -m profiling.sampling replay --flamegraph -o profile.html profile.bin
+
+This command is useful when you have captured profiling data in binary format
+and want to analyze it later or convert it to a visualization format. Binary
+profiles can be replayed multiple times to different formats without
+re-profiling.
+
+::
+
+ # Convert binary to pstats (default, prints to stdout)
+ python -m profiling.sampling replay profile.bin
+
+ # Convert binary to flame graph
+ python -m profiling.sampling replay --flamegraph -o output.html profile.bin
+
+ # Convert binary to gecko format for Firefox Profiler
+ python -m profiling.sampling replay --gecko -o profile.json profile.bin
+
+ # Convert binary to heatmap
+ python -m profiling.sampling replay --heatmap -o my_heatmap profile.bin
+
+
Profiling in production
-----------------------
@@ -206,8 +241,8 @@ is unaware it is being profiled.
When profiling production systems, keep these guidelines in mind:
Start with shorter durations (10-30 seconds) to get quick results, then extend
-if you need more statistical accuracy. The default 10-second duration is usually
-sufficient to identify major hotspots.
+if you need more statistical accuracy. By default, profiling runs until the
+target process completes, which is usually sufficient to identify major hotspots.
If possible, profile during representative load rather than peak traffic.
Profiles collected during normal operation are easier to interpret than those
@@ -290,50 +325,52 @@ The default configuration works well for most use cases:
:widths: 25 75
* - Option
- - Default behavior
- * - ``--interval`` / ``-i``
- - 100 µs between samples (~10,000 samples/sec)
- * - ``--duration`` / ``-d``
- - Profile for 10 seconds
- * - ``--all-threads`` / ``-a``
- - Sample main thread only
- * - ``--native``
+ - Default
+ * - Default for ``--sampling-rate`` / ``-r``
+ - 1 kHz
+ * - Default for ``--duration`` / ``-d``
+ - Run to completion
+ * - Default for ``--all-threads`` / ``-a``
+ - Main thread only
+ * - Default for ``--native``
- No ```` frames (C code time attributed to caller)
- * - ``--no-gc``
- - Include ```` frames when garbage collection is active
- * - ``--mode``
+ * - Default for ``--no-gc``
+ - ```` frames included when garbage collection is active
+ * - Default for ``--mode``
- Wall-clock mode (all samples recorded)
- * - ``--realtime-stats``
- - No live statistics display during profiling
+ * - Default for ``--realtime-stats``
+ - Disabled
+ * - Default for ``--subprocesses``
+ - Disabled
+ * - Default for ``--blocking``
+ - Disabled (non-blocking sampling)
-Sampling interval and duration
-------------------------------
+Sampling rate and duration
+--------------------------
-The two most fundamental parameters are the sampling interval and duration.
+The two most fundamental parameters are the sampling rate and duration.
Together, these determine how many samples will be collected during a profiling
session.
-The :option:`--interval` option (:option:`-i`) sets the time between samples in
-microseconds. The default is 100 microseconds, which produces approximately
-10,000 samples per second::
+The :option:`--sampling-rate` option (:option:`-r`) sets how frequently samples
+are collected. The default is 1 kHz (10,000 samples per second)::
- python -m profiling.sampling run -i 50 script.py
+ python -m profiling.sampling run -r 20khz script.py
-Lower intervals capture more samples and provide finer-grained data at the
-cost of slightly higher profiler CPU usage. Higher intervals reduce profiler
+Higher rates capture more samples and provide finer-grained data at the
+cost of slightly higher profiler CPU usage. Lower rates reduce profiler
overhead but may miss short-lived functions. For most applications, the
-default interval provides a good balance between accuracy and overhead.
+default rate provides a good balance between accuracy and overhead.
-The :option:`--duration` option (:option:`-d`) sets how long to profile in seconds. The
-default is 10 seconds::
+The :option:`--duration` option (:option:`-d`) sets how long to profile in seconds. By
+default, profiling continues until the target process exits or is interrupted::
python -m profiling.sampling run -d 60 script.py
-Longer durations collect more samples and produce more statistically reliable
-results, especially for code paths that execute infrequently. When profiling
-a program that runs for a fixed time, you may want to set the duration to
-match or exceed the expected runtime.
+Specifying a duration is useful when attaching to long-running processes or when
+you want to limit profiling to a specific time window. When profiling a script,
+the default behavior of running to completion is usually what you want.
Thread selection
@@ -355,6 +392,50 @@ This option is particularly useful when investigating concurrency issues or
when work is distributed across a thread pool.
+.. _blocking-mode:
+
+Blocking mode
+-------------
+
+By default, Tachyon reads the target process's memory without stopping it.
+This non-blocking approach is ideal for most profiling scenarios because it
+imposes virtually zero overhead on the target application: the profiled
+program runs at full speed and is unaware it is being observed.
+
+However, non-blocking sampling can occasionally produce incomplete or
+inconsistent stack traces in applications with many generators or coroutines
+that rapidly switch between yield points, or in programs with very fast-changing
+call stacks where functions enter and exit between the start and end of a single
+stack read, resulting in reconstructed stacks that mix frames from different
+execution states or that never actually existed.
+
+For these cases, the :option:`--blocking` option stops the target process during
+each sample::
+
+ python -m profiling.sampling run --blocking script.py
+ python -m profiling.sampling attach --blocking 12345
+
+When blocking mode is enabled, the profiler suspends the target process,
+reads its stack, then resumes it. This guarantees that each captured stack
+represents a real, consistent snapshot of what the process was doing at that
+instant. The trade-off is that the target process runs slower because it is
+repeatedly paused.
+
+.. warning::
+
+ Do not use very high sample rates (low ``--interval`` values) with blocking
+ mode. Suspending and resuming a process takes time, and if the sampling
+ interval is too short, the target will spend more time stopped than running.
+ For blocking mode, intervals of 1000 microseconds (1 millisecond) or higher
+ are recommended. The default 100 microsecond interval may cause noticeable
+ slowdown in the target application.
+
+Use blocking mode only when you observe inconsistent stacks in your profiles,
+particularly with generator-heavy or coroutine-heavy code. For most
+applications, the default non-blocking mode provides accurate results with
+zero impact on the target process.
+
+
Special frames
--------------
@@ -401,12 +482,12 @@ and the base instruction.
Opcode information appears in several output formats:
-- **Live mode**: An opcode panel shows instruction-level statistics for the
- selected function, accessible via keyboard navigation
-- **Flame graphs**: Nodes display opcode information when available, helping
- identify which instructions consume the most time
+- **Flame graphs**: Hovering over a frame displays a tooltip with a bytecode
+ instruction breakdown, showing which opcodes consumed time in that function
- **Heatmap**: Expandable bytecode panels per source line show instruction
breakdown with specialization percentages
+- **Live mode**: An opcode panel shows instruction-level statistics for the
+ selected function, accessible via keyboard navigation
- **Gecko format**: Opcode transitions are emitted as interval markers in the
Firefox Profiler timeline
@@ -437,6 +518,78 @@ working correctly and that sufficient samples are being collected. See
:ref:`sampling-efficiency` for details on interpreting these metrics.
+Subprocess profiling
+--------------------
+
+The :option:`--subprocesses` option enables automatic profiling of subprocesses
+spawned by the target::
+
+ python -m profiling.sampling run --subprocesses script.py
+ python -m profiling.sampling attach --subprocesses 12345
+
+When enabled, the profiler monitors the target process for child process
+creation. When a new Python child process is detected, a separate profiler
+instance is automatically spawned to profile it. This is useful for
+applications that use :mod:`multiprocessing`, :mod:`subprocess`,
+:mod:`concurrent.futures` with :class:`~concurrent.futures.ProcessPoolExecutor`,
+or other process spawning mechanisms.
+
+.. code-block:: python
+ :caption: worker_pool.py
+
+ from concurrent.futures import ProcessPoolExecutor
+ import math
+
+ def compute_factorial(n):
+ total = 0
+ for i in range(50):
+ total += math.factorial(n)
+ return total
+
+ if __name__ == "__main__":
+ numbers = [5000 + i * 100 for i in range(50)]
+ with ProcessPoolExecutor(max_workers=4) as executor:
+ results = list(executor.map(compute_factorial, numbers))
+ print(f"Computed {len(results)} factorials")
+
+::
+
+ python -m profiling.sampling run --subprocesses --flamegraph worker_pool.py
+
+This produces separate flame graphs for the main process and each worker
+process: ``flamegraph_.html``, ``flamegraph_.html``,
+and so on.
+
+Each subprocess receives its own output file. The filename is derived from
+the specified output path (or the default) with the subprocess's process ID
+appended:
+
+- If you specify ``-o profile.html``, subprocesses produce ``profile_12345.html``,
+ ``profile_12346.html``, and so on
+- With default output, subprocesses produce files like ``flamegraph_12345.html``
+ or directories like ``heatmap_12345``
+- For pstats format (which defaults to stdout), subprocesses produce files like
+ ``profile_12345.pstats``
+
+The subprocess profilers inherit most sampling options from the parent (sampling
+rate, duration, thread selection, native frames, GC frames, async-aware mode,
+and output format). All Python descendant processes are profiled recursively,
+including grandchildren and further descendants.
+
+Subprocess detection works by periodically scanning for new descendants of
+the target process and checking whether each new process is a Python process
+by probing the process memory for Python runtime structures. Non-Python
+subprocesses (such as shell commands or external tools) are ignored.
+
+There is a limit of 100 concurrent subprocess profilers to prevent resource
+exhaustion in programs that spawn many processes. If this limit is reached,
+additional subprocesses are not profiled and a warning is printed.
+
+The :option:`--subprocesses` option is incompatible with :option:`--live` mode
+because live mode uses an interactive terminal interface that cannot
+accommodate multiple concurrent profiler displays.
+
+
.. _sampling-efficiency:
Sampling efficiency
@@ -470,9 +623,10 @@ which you can use to judge whether the data is sufficient for your analysis.
Profiling modes
===============
-The sampling profiler supports three modes that control which samples are
+The sampling profiler supports four modes that control which samples are
recorded. The mode determines what the profile measures: total elapsed time,
-CPU execution time, or time spent holding the global interpreter lock.
+CPU execution time, time spent holding the global interpreter lock, or
+exception handling.
Wall-clock mode
@@ -528,6 +682,25 @@ I/O-bound or waiting. The function spends most of its time waiting for network,
disk, locks, or sleep. CPU optimization won't help here; consider async I/O,
connection pooling, or reducing wait time instead.
+.. code-block:: python
+
+ import time
+
+ def do_sleep():
+ time.sleep(2)
+
+ def do_compute():
+ sum(i**2 for i in range(1000000))
+
+ if __name__ == "__main__":
+ do_sleep()
+ do_compute()
+
+::
+
+ python -m profiling.sampling run --mode=wall script.py # do_sleep ~98%, do_compute ~1%
+ python -m profiling.sampling run --mode=cpu script.py # do_sleep absent, do_compute dominates
+
GIL mode
--------
@@ -552,6 +725,90 @@ GIL?" and "why are my other threads starving?" It can also be useful in
single-threaded programs to distinguish Python execution time from time spent
in C extensions or I/O.
+.. code-block:: python
+
+ import hashlib
+
+ def hash_work():
+ # C extension - releases GIL during computation
+ for _ in range(200):
+ hashlib.sha256(b"data" * 250000).hexdigest()
+
+ def python_work():
+ # Pure Python - holds GIL during computation
+ for _ in range(3):
+ sum(i**2 for i in range(1000000))
+
+ if __name__ == "__main__":
+ hash_work()
+ python_work()
+
+::
+
+ python -m profiling.sampling run --mode=cpu script.py # hash_work ~42%, python_work ~38%
+ python -m profiling.sampling run --mode=gil script.py # hash_work ~5%, python_work ~60%
+
+
+Exception mode
+--------------
+
+Exception mode (``--mode=exception``) records samples only when a thread has
+an active exception::
+
+ python -m profiling.sampling run --mode=exception script.py
+
+Samples are recorded in two situations: when an exception is being propagated
+up the call stack (after ``raise`` but before being caught), or when code is
+executing inside an ``except`` block where exception information is still
+present in the thread state.
+
+The following example illustrates which code regions are captured:
+
+.. code-block:: python
+
+ def example():
+ try:
+ raise ValueError("error") # Captured: exception being raised
+ except ValueError:
+ process_error() # Captured: inside except block
+ finally:
+ cleanup() # NOT captured: exception already handled
+
+ def example_propagating():
+ try:
+ try:
+ raise ValueError("error")
+ finally:
+ cleanup() # Captured: exception propagating through
+ except ValueError:
+ pass
+
+ def example_no_exception():
+ try:
+ do_work()
+ finally:
+ cleanup() # NOT captured: no exception involved
+
+Note that ``finally`` blocks are only captured when an exception is actively
+propagating through them. Once an ``except`` block finishes executing, Python
+clears the exception information before running any subsequent ``finally``
+block. Similarly, ``finally`` blocks that run during normal execution (when no
+exception was raised) are not captured because no exception state is present.
+
+This mode is useful for understanding where your program spends time handling
+errors. Exception handling can be a significant source of overhead in code
+that uses exceptions for flow control (such as ``StopIteration`` in iterators)
+or in applications that process many error conditions (such as network servers
+handling connection failures).
+
+Exception mode helps answer questions like "how much time is spent handling
+exceptions?" and "which exception handlers are the most expensive?" It can
+reveal hidden performance costs in code that catches and processes many
+exceptions, even when those exceptions are handled gracefully. For example,
+if a parsing library uses exceptions internally to signal format errors, this
+mode will capture time spent in those handlers even if the calling code never
+sees the exceptions.
+
Output formats
==============
@@ -570,6 +827,14 @@ deterministic profilers generate. This is the default output format::
python -m profiling.sampling run script.py
python -m profiling.sampling run --pstats script.py
+.. figure:: tachyon-pstats.png
+ :alt: Tachyon pstats terminal output
+ :align: center
+ :width: 100%
+
+ The pstats format displays profiling results in a color-coded table showing
+ function hotspots, sample counts, and timing estimates.
+
Output appears on stdout by default::
Profile Stats (Mode: wall):
@@ -613,9 +878,9 @@ interesting functions that highlights:
Use :option:`--no-summary` to suppress both the legend and summary sections.
-To save pstats output to a file instead of stdout::
+To save pstats output to a binary file instead of stdout::
- python -m profiling.sampling run -o profile.txt script.py
+ python -m profiling.sampling run -o profile.pstats script.py
The pstats format supports several options for controlling the display.
The :option:`--sort` option determines the column used for ordering results::
@@ -671,6 +936,19 @@ an interactive flame graph visualization::
python -m profiling.sampling run --flamegraph script.py
python -m profiling.sampling run --flamegraph -o profile.html script.py
+.. figure:: tachyon-flamegraph.png
+ :alt: Tachyon interactive flame graph
+ :align: center
+ :width: 100%
+
+ The flame graph visualization shows call stacks as nested rectangles, with
+ width proportional to time spent. The sidebar displays runtime statistics,
+ GIL metrics, and hotspot functions.
+
+.. only:: html
+
+ `Try the interactive example <../_static/tachyon-example-flamegraph.html>`__!
+
If no output file is specified, the profiler generates a filename based on
the process ID (for example, ``flamegraph.12345.html``).
@@ -741,6 +1019,33 @@ Firefox Profiler timeline:
For this reason, the :option:`--mode` option is not available with Gecko format;
all relevant data is captured automatically.
+.. figure:: tachyon-gecko-calltree.png
+ :alt: Firefox Profiler Call Tree view
+ :align: center
+ :width: 100%
+
+ The Call Tree view shows the complete call hierarchy with sample counts
+ and percentages. The sidebar displays detailed statistics for the
+ selected function including running time and sample distribution.
+
+.. figure:: tachyon-gecko-flamegraph.png
+ :alt: Firefox Profiler Flame Graph view
+ :align: center
+ :width: 100%
+
+ The Flame Graph visualization shows call stacks as nested rectangles.
+ Functions names are visible in the call hierarchy.
+
+.. figure:: tachyon-gecko-opcodes.png
+ :alt: Firefox Profiler Marker Chart with opcodes
+ :align: center
+ :width: 100%
+
+ The Marker Chart displays interval markers including CPU state, GIL
+ status, and opcodes. With ``--opcodes`` enabled, bytecode instructions
+ like ``BINARY_OP_ADD_FLOAT``, ``CALL_PY_EXACT_ARGS``, and
+ ``CALL_LIST_APPEND`` appear as markers showing execution over time.
+
Heatmap format
--------------
@@ -751,6 +1056,15 @@ showing sample counts at the source line level::
python -m profiling.sampling run --heatmap script.py
python -m profiling.sampling run --heatmap -o my_heatmap script.py
+.. figure:: tachyon-heatmap.png
+ :alt: Tachyon heatmap visualization
+ :align: center
+ :width: 100%
+
+ The heatmap overlays sample counts directly on your source code. Lines are
+ color-coded from cool (few samples) to hot (many samples). Navigation
+ buttons (▲▼) let you jump between callers and callees.
+
Unlike other formats that produce a single file, heatmap output creates a
directory containing HTML files for each profiled source file. If no output
path is specified, the directory is named ``heatmap_PID``.
@@ -777,6 +1091,22 @@ The heatmap interface provides several interactive features:
- **Dark/light theme**: toggle with preference saved across sessions
- **Line linking**: click line numbers to create shareable URLs
+When opcode-level profiling is enabled with :option:`--opcodes`, each hot line
+can be expanded to show which bytecode instructions consumed time:
+
+.. figure:: tachyon-heatmap-with-opcodes.png
+ :alt: Heatmap with expanded bytecode panel
+ :align: center
+ :width: 100%
+
+ Expanding a hot line reveals the bytecode instructions executed, including
+ specialized variants. The panel shows sample counts per instruction and the
+ overall specialization percentage for the line.
+
+.. only:: html
+
+ `Try the interactive example <../_static/tachyon-example-heatmap.html>`__!
+
Heatmaps are especially useful when you know which file contains a performance
issue but need to identify the specific lines. Many developers prefer this
format because it maps directly to their source code, making it easy to read
@@ -785,6 +1115,59 @@ intuitive view that shows exactly where time is spent without requiring
interpretation of hierarchical visualizations.
+Binary format
+-------------
+
+Binary format (:option:`--binary`) produces a compact binary file for efficient
+storage of profiling data::
+
+ python -m profiling.sampling run --binary -o profile.bin script.py
+ python -m profiling.sampling attach --binary -o profile.bin 12345
+
+The :option:`--compression` option controls data compression:
+
+- ``auto`` (default): Use zstd compression if available, otherwise no
+ compression
+- ``zstd``: Force zstd compression (requires :mod:`compression.zstd` support)
+- ``none``: Disable compression
+
+::
+
+ python -m profiling.sampling run --binary --compression=zstd -o profile.bin script.py
+
+To analyze binary profiles, use the :ref:`replay-command` to convert them to
+other formats like flame graphs or pstats output.
+
+
+Record and replay workflow
+==========================
+
+The binary format combined with the replay command enables a record-and-replay
+workflow that separates data capture from analysis. Rather than generating
+visualizations during profiling, you capture raw data to a compact binary file
+and convert it to different formats later.
+
+This approach has three main benefits:
+
+- Sampling runs faster because the work of building data structures for
+ visualization is deferred until replay.
+- A single binary capture can be converted to multiple output formats
+ without re-profiling: pstats for a quick overview, flame graph for visual
+ exploration, heatmap for line-level detail.
+- Binary files are compact and easy to share with colleagues who can convert
+ them to their preferred format.
+
+A typical workflow::
+
+ # Capture profile in production or during tests
+ python -m profiling.sampling attach --binary -o profile.bin 12345
+
+ # Later, analyze with different formats
+ python -m profiling.sampling replay profile.bin
+ python -m profiling.sampling replay --flamegraph -o profile.html profile.bin
+ python -m profiling.sampling replay --heatmap -o heatmap profile.bin
+
+
Live mode
=========
@@ -794,6 +1177,14 @@ data, similar to the ``top`` command for system processes::
python -m profiling.sampling run --live script.py
python -m profiling.sampling attach --live 12345
+.. figure:: tachyon-live-mode-2.gif
+ :alt: Tachyon live mode showing all threads
+ :align: center
+ :width: 100%
+
+ Live mode displays real-time profiling statistics, showing combined
+ data from multiple threads in a multi-threaded application.
+
The display updates continuously as new samples arrive, showing the current
hottest functions. This mode requires the :mod:`curses` module, which is
available on Unix-like systems but not on Windows. The terminal must be at
@@ -809,6 +1200,14 @@ main table, showing instruction-level statistics for the currently selected
function. This panel displays which bytecode instructions are executing most
frequently, including specialized variants and their base opcodes.
+.. figure:: tachyon-live-mode-1.gif
+ :alt: Tachyon live mode with opcode panel
+ :align: center
+ :width: 100%
+
+ Live mode with ``--opcodes`` enabled shows an opcode panel with a bytecode
+ instruction breakdown for the selected function.
+
Keyboard commands
-----------------
@@ -890,6 +1289,25 @@ stack often shows event loop internals rather than the logical flow of your
coroutines. Async-aware mode addresses this by tracking which task is running
and presenting stacks that reflect the ``await`` chain.
+.. code-block:: python
+
+ import asyncio
+
+ async def fetch(url):
+ await asyncio.sleep(0.1)
+ return url
+
+ async def main():
+ for _ in range(50):
+ await asyncio.gather(fetch("a"), fetch("b"), fetch("c"))
+
+ if __name__ == "__main__":
+ asyncio.run(main())
+
+::
+
+ python -m profiling.sampling run --async-aware --flamegraph -o out.html script.py
+
.. note::
Async-aware profiling requires the target process to have the :mod:`asyncio`
@@ -961,17 +1379,21 @@ Global options
Attach to and profile a running process by PID.
+.. option:: replay
+
+ Convert a binary profile file to another output format.
+
Sampling options
----------------
-.. option:: -i , --interval
+.. option:: -r , --sampling-rate
- Sampling interval in microseconds. Default: 100.
+ Sampling rate (for example, ``10000``, ``10khz``, ``10k``). Default: ``1khz``.
.. option:: -d , --duration
- Profiling duration in seconds. Default: 10.
+ Profiling duration in seconds. Default: run to completion.
.. option:: -a, --all-threads
@@ -1000,14 +1422,27 @@ Sampling options
Compatible with ``--live``, ``--flamegraph``, ``--heatmap``, and ``--gecko``
formats only.
+.. option:: --subprocesses
+
+ Also profile subprocesses. Each subprocess gets its own profiler
+ instance and output file. Incompatible with ``--live``.
+
+.. option:: --blocking
+
+ Pause the target process during each sample. This ensures consistent
+ stack traces at the cost of slowing down the target. Use with longer
+ intervals (1000 µs or higher) to minimize impact. See :ref:`blocking-mode`
+ for details.
+
Mode options
------------
.. option:: --mode
- Sampling mode: ``wall`` (default), ``cpu``, or ``gil``.
- The ``cpu`` and ``gil`` modes are incompatible with ``--async-aware``.
+ Sampling mode: ``wall`` (default), ``cpu``, ``gil``, or ``exception``.
+ The ``cpu``, ``gil``, and ``exception`` modes are incompatible with
+ ``--async-aware``.
.. option:: --async-mode
@@ -1020,7 +1455,9 @@ Output options
.. option:: --pstats
- Generate text statistics output. This is the default.
+ Generate pstats statistics. This is the default.
+ When written to stdout, the output is a text table; with :option:`-o`,
+ it is a binary pstats file.
.. option:: --collapsed
@@ -1038,12 +1475,30 @@ Output options
Generate HTML heatmap with line-level sample counts.
+.. option:: --binary
+
+ Generate high-performance binary format for later conversion with the
+ ``replay`` command.
+
+.. option:: --compression
+
+ Compression for binary format: ``auto`` (use zstd if available, default),
+ ``zstd``, or ``none``.
+
.. option:: -o , --output
Output file or directory path. Default behavior varies by format:
- ``--pstats`` writes to stdout, ``--flamegraph`` and ``--gecko`` generate
- files like ``flamegraph.PID.html``, and ``--heatmap`` creates a directory
- named ``heatmap_PID``.
+ :option:`--pstats` prints a text table to stdout, while ``-o`` writes a
+ binary pstats file. Other formats generate a file named
+ ``_.`` (for example, ``flamegraph_12345.html``).
+ :option:`--heatmap` creates a directory named ``heatmap_``.
+
+.. option:: --browser
+
+ Automatically open HTML output (:option:`--flamegraph` and
+ :option:`--heatmap`) in your default web browser after generation.
+ When profiling with :option:`--subprocesses`, only the main process
+ opens the browser; subprocess outputs are never auto-opened.
pstats display options
diff --git a/Doc/library/random.rst b/Doc/library/random.rst
index 4e55e301b89095..4c37a69079dcd6 100644
--- a/Doc/library/random.rst
+++ b/Doc/library/random.rst
@@ -78,7 +78,7 @@ Bookkeeping functions
instead of the system time (see the :func:`os.urandom` function for details
on availability).
- If *a* is an int, it is used directly.
+ If *a* is an int, its absolute value is used directly.
With version 2 (the default), a :class:`str`, :class:`bytes`, or :class:`bytearray`
object gets converted to an :class:`int` and all of its bits are used.
@@ -634,11 +634,12 @@ from the combinatoric iterators in the :mod:`itertools` module
or the :pypi:`more-itertools` project:
.. testcode::
+
import random
- def random_product(*args, repeat=1):
- "Random selection from itertools.product(*args, **kwds)"
- pools = [tuple(pool) for pool in args] * repeat
+ def random_product(*iterables, repeat=1):
+ "Random selection from itertools.product(*iterables, repeat=repeat)"
+ pools = tuple(map(tuple, iterables)) * repeat
return tuple(map(random.choice, pools))
def random_permutation(iterable, r=None):
@@ -663,15 +664,89 @@ or the :pypi:`more-itertools` project:
return tuple(pool[i] for i in indices)
def random_derangement(iterable):
- "Choose a permutation where no element is in its original position."
+ "Choose a permutation where no element stays in its original position."
seq = tuple(iterable)
if len(seq) < 2:
- raise ValueError('derangements require at least two values')
- perm = list(seq)
+ if not seq:
+ return ()
+ raise IndexError('No derangments to choose from')
+ perm = list(range(len(seq)))
+ start = tuple(perm)
while True:
random.shuffle(perm)
- if all(p != q for p, q in zip(seq, perm)):
- return tuple(perm)
+ if all(p != q for p, q in zip(start, perm)):
+ return tuple([seq[i] for i in perm])
+
+.. doctest::
+ :hide:
+
+ >>> import random
+
+
+ >>> random.seed(8675309)
+ >>> random_product('ABCDEFG', repeat=5)
+ ('D', 'B', 'E', 'F', 'E')
+
+
+ >>> random.seed(8675309)
+ >>> random_permutation('ABCDEFG')
+ ('D', 'B', 'E', 'C', 'G', 'A', 'F')
+ >>> random_permutation('ABCDEFG', 5)
+ ('A', 'G', 'D', 'C', 'B')
+
+
+ >>> random.seed(8675309)
+ >>> random_combination('ABCDEFG', 7)
+ ('A', 'B', 'C', 'D', 'E', 'F', 'G')
+ >>> random_combination('ABCDEFG', 6)
+ ('A', 'B', 'C', 'D', 'F', 'G')
+ >>> random_combination('ABCDEFG', 5)
+ ('A', 'B', 'C', 'E', 'F')
+ >>> random_combination('ABCDEFG', 4)
+ ('B', 'C', 'D', 'G')
+ >>> random_combination('ABCDEFG', 3)
+ ('B', 'E', 'G')
+ >>> random_combination('ABCDEFG', 2)
+ ('E', 'G')
+ >>> random_combination('ABCDEFG', 1)
+ ('C',)
+ >>> random_combination('ABCDEFG', 0)
+ ()
+
+
+ >>> random.seed(8675309)
+ >>> random_combination_with_replacement('ABCDEFG', 7)
+ ('B', 'C', 'D', 'E', 'E', 'E', 'G')
+ >>> random_combination_with_replacement('ABCDEFG', 3)
+ ('A', 'B', 'E')
+ >>> random_combination_with_replacement('ABCDEFG', 2)
+ ('A', 'G')
+ >>> random_combination_with_replacement('ABCDEFG', 1)
+ ('E',)
+ >>> random_combination_with_replacement('ABCDEFG', 0)
+ ()
+
+
+ >>> random.seed(8675309)
+ >>> random_derangement('')
+ ()
+ >>> random_derangement('A')
+ Traceback (most recent call last):
+ ...
+ IndexError: No derangments to choose from
+ >>> random_derangement('AB')
+ ('B', 'A')
+ >>> random_derangement('ABC')
+ ('C', 'A', 'B')
+ >>> random_derangement('ABCD')
+ ('B', 'A', 'D', 'C')
+ >>> random_derangement('ABCDE')
+ ('B', 'C', 'A', 'E', 'D')
+ >>> # Identical inputs treated as distinct
+ >>> identical = 20
+ >>> random_derangement((10, identical, 30, identical))
+ (20, 30, 10, 20)
+
The default :func:`.random` returns multiples of 2⁻⁵³ in the range
*0.0 ≤ x < 1.0*. All such numbers are evenly spaced and are exactly
diff --git a/Doc/library/readline.rst b/Doc/library/readline.rst
index 780cc77340366a..199e17595f41ac 100644
--- a/Doc/library/readline.rst
+++ b/Doc/library/readline.rst
@@ -252,7 +252,7 @@ Startup hooks
function has been set. This function only exists if Python was compiled
for a version of the library that supports it.
- .. versionadded:: next
+ .. versionadded:: 3.15
.. _readline-completion:
@@ -403,3 +403,9 @@ support history save/restore. ::
def save_history(self, histfile):
readline.set_history_length(1000)
readline.write_history_file(histfile)
+
+.. note::
+
+ The new :term:`REPL` introduced in version 3.13 doesn't support readline.
+ However, readline can still be used by setting the :envvar:`PYTHON_BASIC_REPL`
+ environment variable.
diff --git a/Doc/library/runpy.rst b/Doc/library/runpy.rst
index b07ec6e93f80ab..64735b5a109e66 100644
--- a/Doc/library/runpy.rst
+++ b/Doc/library/runpy.rst
@@ -50,10 +50,10 @@ The :mod:`runpy` module provides two functions:
overridden by :func:`run_module`.
The special global variables ``__name__``, ``__spec__``, ``__file__``,
- ``__cached__``, ``__loader__`` and ``__package__`` are set in the globals
- dictionary before the module code is executed. (Note that this is a
- minimal set of variables - other variables may be set implicitly as an
- interpreter implementation detail.)
+ ``__loader__`` and ``__package__`` are set in the globals dictionary before
+ the module code is executed. (Note that this is a minimal set of variables -
+ other variables may be set implicitly as an interpreter implementation
+ detail.)
``__name__`` is set to *run_name* if this optional argument is not
:const:`None`, to ``mod_name + '.__main__'`` if the named module is a
@@ -63,7 +63,7 @@ The :mod:`runpy` module provides two functions:
module (that is, ``__spec__.name`` will always be *mod_name* or
``mod_name + '.__main__'``, never *run_name*).
- ``__file__``, ``__cached__``, ``__loader__`` and ``__package__`` are
+ ``__file__``, ``__loader__`` and ``__package__`` are
:ref:`set as normal ` based on the module spec.
If the argument *alter_sys* is supplied and evaluates to :const:`True`,
@@ -98,6 +98,9 @@ The :mod:`runpy` module provides two functions:
``__package__`` are deprecated. See
:class:`~importlib.machinery.ModuleSpec` for alternatives.
+ .. versionchanged:: 3.15
+ ``__cached__`` is no longer set.
+
.. function:: run_path(path_name, init_globals=None, run_name=None)
.. index::
@@ -125,23 +128,23 @@ The :mod:`runpy` module provides two functions:
overridden by :func:`run_path`.
The special global variables ``__name__``, ``__spec__``, ``__file__``,
- ``__cached__``, ``__loader__`` and ``__package__`` are set in the globals
- dictionary before the module code is executed. (Note that this is a
- minimal set of variables - other variables may be set implicitly as an
- interpreter implementation detail.)
+ ``__loader__`` and ``__package__`` are set in the globals dictionary before
+ the module code is executed. (Note that this is a minimal set of variables -
+ other variables may be set implicitly as an interpreter implementation
+ detail.)
``__name__`` is set to *run_name* if this optional argument is not
:const:`None` and to ``''`` otherwise.
If *file_path* directly references a script file (whether as source
or as precompiled byte code), then ``__file__`` will be set to
- *file_path*, and ``__spec__``, ``__cached__``, ``__loader__`` and
+ *file_path*, and ``__spec__``, ``__loader__`` and
``__package__`` will all be set to :const:`None`.
If *file_path* is a reference to a valid :data:`sys.path` entry, then
``__spec__`` will be set appropriately for the imported :mod:`__main__`
module (that is, ``__spec__.name`` will always be ``__main__``).
- ``__file__``, ``__cached__``, ``__loader__`` and ``__package__`` will be
+ ``__file__``, ``__loader__`` and ``__package__`` will be
:ref:`set as normal ` based on the module spec.
A number of alterations are also made to the :mod:`sys` module. Firstly,
@@ -173,6 +176,9 @@ The :mod:`runpy` module provides two functions:
The setting of ``__cached__``, ``__loader__``, and
``__package__`` are deprecated.
+ .. versionchanged:: 3.15
+ ``__cached__`` is no longer set.
+
.. seealso::
:pep:`338` -- Executing modules as scripts
diff --git a/Doc/library/select.rst b/Doc/library/select.rst
index 62b5161fb80634..ce4e92654d5932 100644
--- a/Doc/library/select.rst
+++ b/Doc/library/select.rst
@@ -478,6 +478,8 @@ linearly scanned again. :c:func:`!select` is *O*\ (*highest file descriptor*), w
.. versionchanged:: 3.15
Accepts any real number as *timeout*, not only integer or float.
+ If ``ppoll()`` function is available, *timeout* has a resolution
+ of ``1`` ns (``1e-6`` ms) instead of ``1`` ms.
.. _kqueue-objects:
diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst
index 3a4631e7c657fe..2c15fed8dd5e4d 100644
--- a/Doc/library/shutil.rst
+++ b/Doc/library/shutil.rst
@@ -515,7 +515,7 @@ Directory and files operations
.. exception:: Error
- This exception collects exceptions that are raised during a multi-file
+ Subclass of :exc:`OSError` collecting exceptions raised during a multi-file
operation. For :func:`copytree`, the exception argument is a list of 3-tuples
(*srcname*, *dstname*, *exception*).
diff --git a/Doc/library/smtplib.rst b/Doc/library/smtplib.rst
index 3ee8b82a1880f3..3bf5ec6099facb 100644
--- a/Doc/library/smtplib.rst
+++ b/Doc/library/smtplib.rst
@@ -458,9 +458,11 @@ An :class:`SMTP` instance has the following methods:
Send mail. The required arguments are an :rfc:`822` from-address string, a list
of :rfc:`822` to-address strings (a bare string will be treated as a list with 1
address), and a message string. The caller may pass a list of ESMTP options
- (such as ``8bitmime``) to be used in ``MAIL FROM`` commands as *mail_options*.
+ (such as ``"8bitmime"``) to be used in ``MAIL FROM`` commands as *mail_options*.
ESMTP options (such as ``DSN`` commands) that should be used with all ``RCPT``
- commands can be passed as *rcpt_options*. (If you need to use different ESMTP
+ commands can be passed as *rcpt_options*. Each option should be passed as a string
+ containing the full text of the option, including any potential key
+ (for instance, ``"NOTIFY=SUCCESS,FAILURE"``). (If you need to use different ESMTP
options to different recipients you have to use the low-level methods such as
:meth:`!mail`, :meth:`!rcpt` and :meth:`!data` to send the message.)
diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst
index b16cde34ec1ef5..b7115942d1fdd1 100644
--- a/Doc/library/socket.rst
+++ b/Doc/library/socket.rst
@@ -482,7 +482,7 @@ The AF_* and SOCK_* constants are now :class:`AddressFamily` and
.. versionchanged:: 3.14
Added support for ``TCP_QUICKACK`` on Windows platforms when available.
- .. versionchanged:: next
+ .. versionchanged:: 3.15
``IPV6_HDRINCL`` was added.
@@ -1072,10 +1072,16 @@ The :mod:`socket` module also offers various network-related services:
a string representing the canonical name of the *host* if
:const:`AI_CANONNAME` is part of the *flags* argument; else *canonname*
will be empty. *sockaddr* is a tuple describing a socket address, whose
- format depends on the returned *family* (a ``(address, port)`` 2-tuple for
- :const:`AF_INET`, a ``(address, port, flowinfo, scope_id)`` 4-tuple for
- :const:`AF_INET6`), and is meant to be passed to the :meth:`socket.connect`
- method.
+ format depends on the returned *family* and flags Python was compiled with,
+ and is meant to be passed to the :meth:`socket.connect` method.
+
+ *sockaddr* can be one of the following:
+
+ * a ``(address, port)`` 2-tuple for :const:`AF_INET`
+ * a ``(address, port, flowinfo, scope_id)`` 4-tuple for :const:`AF_INET6` if
+ Python was compiled with ``--enable-ipv6`` (the default)
+ * a 2-tuple containing raw data for :const:`AF_INET6` if Python was
+ compiled with ``--disable-ipv6``
.. note::
diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst
index 3899e5b59d8852..ce0d7cbb2e4276 100644
--- a/Doc/library/stdtypes.rst
+++ b/Doc/library/stdtypes.rst
@@ -46,8 +46,10 @@ Any object can be tested for truth value, for use in an :keyword:`if` or
By default, an object is considered true unless its class defines either a
:meth:`~object.__bool__` method that returns ``False`` or a
:meth:`~object.__len__` method that
-returns zero, when called with the object. [1]_ Here are most of the built-in
-objects considered false:
+returns zero, when called with the object. [1]_ If one of the methods raises an
+exception when called, the exception is propagated and the object does
+not have a truth value (for example, :data:`NotImplemented`).
+Here are most of the built-in objects considered false:
.. index::
single: None (Built-in object)
@@ -164,7 +166,7 @@ This table summarizes the comparison operations:
pair: object; numeric
pair: objects; comparing
-Objects of different types, except different numeric types, never compare equal.
+Unless stated otherwise, objects of different types never compare equal.
The ``==`` operator is always defined but for some object types (for example,
class objects) is equivalent to :keyword:`is`. The ``<``, ``<=``, ``>`` and ``>=``
operators are only defined where they make sense; for example, they raise a
@@ -1091,11 +1093,14 @@ Notes:
still ``0``.
(4)
- The slice of *s* from *i* to *j* is defined as the sequence of items with index
- *k* such that ``i <= k < j``. If *i* or *j* is greater than ``len(s)``, use
- ``len(s)``. If *i* is omitted or ``None``, use ``0``. If *j* is omitted or
- ``None``, use ``len(s)``. If *i* is greater than or equal to *j*, the slice is
- empty.
+ The slice of *s* from *i* to *j* is defined as the sequence of items with
+ index *k* such that ``i <= k < j``.
+
+ * If *i* is omitted or ``None``, use ``0``.
+ * If *j* is omitted or ``None``, use ``len(s)``.
+ * If *i* or *j* is less than ``-len(s)``, use ``0``.
+ * If *i* or *j* is greater than ``len(s)``, use ``len(s)``.
+ * If *i* is greater than or equal to *j*, the slice is empty.
(5)
The slice of *s* from *i* to *j* with step *k* is defined as the sequence of
@@ -1436,6 +1441,109 @@ application).
list appear empty for the duration, and raises :exc:`ValueError` if it can
detect that the list has been mutated during a sort.
+.. admonition:: Thread safety
+
+ Reading a single element from a :class:`list` is
+ :term:`atomic `:
+
+ .. code-block::
+ :class: green
+
+ lst[i] # list.__getitem__
+
+ The following methods traverse the list and use :term:`atomic `
+ reads of each item to perform their function. That means that they may
+ return results affected by concurrent modifications:
+
+ .. code-block::
+ :class: maybe
+
+ item in lst
+ lst.index(item)
+ lst.count(item)
+
+ All of the above methods/operations are also lock-free. They do not block
+ concurrent modifications. Other operations that hold a lock will not block
+ these from observing intermediate states.
+
+ All other operations from here on block using the per-object lock.
+
+ Writing a single item via ``lst[i] = x`` is safe to call from multiple
+ threads and will not corrupt the list.
+
+ The following operations return new objects and appear
+ :term:`atomic ` to other threads:
+
+ .. code-block::
+ :class: good
+
+ lst1 + lst2 # concatenates two lists into a new list
+ x * lst # repeats lst x times into a new list
+ lst.copy() # returns a shallow copy of the list
+
+ Methods that only operate on a single elements with no shifting required are
+ :term:`atomic `:
+
+ .. code-block::
+ :class: good
+
+ lst.append(x) # append to the end of the list, no shifting required
+ lst.pop() # pop element from the end of the list, no shifting required
+
+ The :meth:`~list.clear` method is also :term:`atomic `.
+ Other threads cannot observe elements being removed.
+
+ The :meth:`~list.sort` method is not :term:`atomic `.
+ Other threads cannot observe intermediate states during sorting, but the
+ list appears empty for the duration of the sort.
+
+ The following operations may allow lock-free operations to observe
+ intermediate states since they modify multiple elements in place:
+
+ .. code-block::
+ :class: maybe
+
+ lst.insert(idx, item) # shifts elements
+ lst.pop(idx) # idx not at the end of the list, shifts elements
+ lst *= x # copies elements in place
+
+ The :meth:`~list.remove` method may allow concurrent modifications since
+ element comparison may execute arbitrary Python code (via
+ :meth:`~object.__eq__`).
+
+ :meth:`~list.extend` is safe to call from multiple threads. However, its
+ guarantees depend on the iterable passed to it. If it is a :class:`list`, a
+ :class:`tuple`, a :class:`set`, a :class:`frozenset`, a :class:`dict` or a
+ :ref:`dictionary view object ` (but not their subclasses), the
+ ``extend`` operation is safe from concurrent modifications to the iterable.
+ Otherwise, an iterator is created which can be concurrently modified by
+ another thread. The same applies to inplace concatenation of a list with
+ other iterables when using ``lst += iterable``.
+
+ Similarly, assigning to a list slice with ``lst[i:j] = iterable`` is safe
+ to call from multiple threads, but ``iterable`` is only locked when it is
+ also a :class:`list` (but not its subclasses).
+
+ Operations that involve multiple accesses, as well as iteration, are never
+ atomic. For example:
+
+ .. code-block::
+ :class: bad
+
+ # NOT atomic: read-modify-write
+ lst[i] = lst[i] + 1
+
+ # NOT atomic: check-then-act
+ if lst:
+ item = lst.pop()
+
+ # NOT thread-safe: iteration while modifying
+ for item in lst:
+ process(item) # another thread may modify lst
+
+ Consider external synchronization when sharing :class:`list` instances
+ across threads. See :ref:`freethreading-python-howto` for more information.
+
.. _typesseq-tuple:
@@ -1842,6 +1950,14 @@ expression support in the :mod:`re` module).
lowercase letter ``'ß'`` is equivalent to ``"ss"``. Since it is already
lowercase, :meth:`lower` would do nothing to ``'ß'``; :meth:`casefold`
converts it to ``"ss"``.
+ For example:
+
+ .. doctest::
+
+ >>> 'straße'.lower()
+ 'straße'
+ >>> 'straße'.casefold()
+ 'strasse'
The casefolding algorithm is `described in section 3.13.3 'Default Case
Folding' of the Unicode Standard
@@ -2043,7 +2159,18 @@ expression support in the :mod:`re` module).
.. method:: str.index(sub[, start[, end]])
Like :meth:`~str.find`, but raise :exc:`ValueError` when the substring is
- not found.
+ not found. For example:
+
+ .. doctest::
+
+ >>> 'spam, spam, spam'.index('eggs')
+ Traceback (most recent call last):
+ File "", line 1, in
+ 'spam, spam, spam'.index('eggs')
+ ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^
+ ValueError: substring not found
+
+ See also :meth:`rindex`.
.. method:: str.isalnum()
@@ -2155,6 +2282,21 @@ expression support in the :mod:`re` module).
that have the Unicode numeric value property, e.g. U+2155,
VULGAR FRACTION ONE FIFTH. Formally, numeric characters are those with the property
value Numeric_Type=Digit, Numeric_Type=Decimal or Numeric_Type=Numeric.
+ For example:
+
+ .. doctest::
+
+ >>> '0123456789'.isnumeric()
+ True
+ >>> '٠١٢٣٤٥٦٧٨٩'.isnumeric() # Arabic-indic digit zero to nine
+ True
+ >>> '⅕'.isnumeric() # Vulgar fraction one fifth
+ True
+ >>> '²'.isdecimal(), '²'.isdigit(), '²'.isnumeric()
+ (False, True, True)
+
+ See also :meth:`isdecimal` and :meth:`isdigit`. Numeric characters are
+ a superset of decimal numbers.
.. method:: str.isprintable()
@@ -2173,6 +2315,15 @@ expression support in the :mod:`re` module).
Nonprintable characters are those in group Separator or Other (Z or C),
except the ASCII space.
+ For example:
+
+ .. doctest::
+
+ >>> ''.isprintable(), ' '.isprintable()
+ (True, True)
+ >>> '\t'.isprintable(), '\n'.isprintable()
+ (False, False)
+
.. method:: str.isspace()
@@ -2246,11 +2397,29 @@ expression support in the :mod:`re` module).
done using the specified *fillchar* (default is an ASCII space). The
original string is returned if *width* is less than or equal to ``len(s)``.
+ For example:
+
+ .. doctest::
+
+ >>> 'Python'.ljust(10)
+ 'Python '
+ >>> 'Python'.ljust(10, '.')
+ 'Python....'
+ >>> 'Monty Python'.ljust(10, '.')
+ 'Monty Python'
+
+ See also :meth:`rjust`.
+
.. method:: str.lower()
Return a copy of the string with all the cased characters [4]_ converted to
- lowercase.
+ lowercase. For example:
+
+ .. doctest::
+
+ >>> 'Lower Method Example'.lower()
+ 'lower method example'
The lowercasing algorithm used is `described in section 3.13.2 'Default Case
Conversion' of the Unicode Standard
@@ -2306,7 +2475,9 @@ expression support in the :mod:`re` module).
If the string starts with the *prefix* string, return
``string[len(prefix):]``. Otherwise, return a copy of the original
- string::
+ string:
+
+ .. doctest::
>>> 'TestHook'.removeprefix('Test')
'Hook'
@@ -2315,12 +2486,16 @@ expression support in the :mod:`re` module).
.. versionadded:: 3.9
+ See also :meth:`removesuffix` and :meth:`startswith`.
+
.. method:: str.removesuffix(suffix, /)
If the string ends with the *suffix* string and that *suffix* is not empty,
return ``string[:-len(suffix)]``. Otherwise, return a copy of the
- original string::
+ original string:
+
+ .. doctest::
>>> 'MiscTests'.removesuffix('Tests')
'Misc'
@@ -2329,12 +2504,22 @@ expression support in the :mod:`re` module).
.. versionadded:: 3.9
+ See also :meth:`removeprefix` and :meth:`endswith`.
+
.. method:: str.replace(old, new, /, count=-1)
Return a copy of the string with all occurrences of substring *old* replaced by
*new*. If *count* is given, only the first *count* occurrences are replaced.
If *count* is not specified or ``-1``, then all occurrences are replaced.
+ For example:
+
+ .. doctest::
+
+ >>> 'spam, spam, spam'.replace('spam', 'eggs')
+ 'eggs, eggs, eggs'
+ >>> 'spam, spam, spam'.replace('spam', 'eggs', 1)
+ 'eggs, spam, spam'
.. versionchanged:: 3.13
*count* is now supported as a keyword argument.
@@ -2345,6 +2530,16 @@ expression support in the :mod:`re` module).
Return the highest index in the string where substring *sub* is found, such
that *sub* is contained within ``s[start:end]``. Optional arguments *start*
and *end* are interpreted as in slice notation. Return ``-1`` on failure.
+ For example:
+
+ .. doctest::
+
+ >>> 'spam, spam, spam'.rfind('sp')
+ 12
+ >>> 'spam, spam, spam'.rfind('sp', 0, 10)
+ 6
+
+ See also :meth:`find` and :meth:`rindex`.
.. method:: str.rindex(sub[, start[, end]])
@@ -2367,6 +2562,19 @@ expression support in the :mod:`re` module).
after the separator. If the separator is not found, return a 3-tuple containing
two empty strings, followed by the string itself.
+ For example:
+
+ .. doctest::
+
+ >>> 'Monty Python'.rpartition(' ')
+ ('Monty', ' ', 'Python')
+ >>> "Monty Python's Flying Circus".rpartition(' ')
+ ("Monty Python's Flying", ' ', 'Circus')
+ >>> 'Monty Python'.rpartition('-')
+ ('', '', 'Monty Python')
+
+ See also :meth:`partition`.
+
.. method:: str.rsplit(sep=None, maxsplit=-1)
@@ -5072,9 +5280,6 @@ can be used interchangeably to index the same dictionary entry.
being added is already present, the value from the keyword argument
replaces the value from the positional argument.
- Providing keyword arguments as in the first example only works for keys that
- are valid Python identifiers. Otherwise, any valid keys can be used.
-
Dictionaries compare equal if and only if they have the same ``(key,
value)`` pairs (regardless of ordering). Order comparisons ('<', '<=', '>=', '>') raise
:exc:`TypeError`. To illustrate dictionary creation and equality,
@@ -5460,9 +5665,11 @@ before the statement body is executed and exited when the statement ends:
Returning a true value from this method will cause the :keyword:`with` statement
to suppress the exception and continue execution with the statement immediately
following the :keyword:`!with` statement. Otherwise the exception continues
- propagating after this method has finished executing. Exceptions that occur
- during execution of this method will replace any exception that occurred in the
- body of the :keyword:`!with` statement.
+ propagating after this method has finished executing.
+
+ If this method raises an exception while handling an earlier exception from the
+ :keyword:`with` block, the new exception is raised, and the original exception
+ is stored in its :attr:`~BaseException.__context__` attribute.
The exception passed in should never be reraised explicitly - instead, this
method should return a false value to indicate that the method completed
diff --git a/Doc/library/string.rst b/Doc/library/string.rst
index 58c836c7382330..e3ad018d1d073b 100644
--- a/Doc/library/string.rst
+++ b/Doc/library/string.rst
@@ -546,6 +546,9 @@ The available presentation types for :class:`float` and
| | :class:`float`, and shows all coefficient digits |
| | for :class:`~decimal.Decimal`. If ``p=0``, the decimal |
| | point is omitted unless the ``#`` option is used. |
+ | | |
+ | | For :class:`float`, the exponent always contains at |
+ | | least two digits, and is zero if the value is zero. |
+---------+----------------------------------------------------------+
| ``'E'`` | Scientific notation. Same as ``'e'`` except it uses |
| | an upper case 'E' as the separator character. |
diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst
index b8dfcc310771fe..cc4f032fb26fd7 100644
--- a/Doc/library/subprocess.rst
+++ b/Doc/library/subprocess.rst
@@ -803,14 +803,29 @@ Instances of the :class:`Popen` class have the following methods:
.. note::
- When the ``timeout`` parameter is not ``None``, then (on POSIX) the
- function is implemented using a busy loop (non-blocking call and short
- sleeps). Use the :mod:`asyncio` module for an asynchronous wait: see
+ When ``timeout`` is not ``None`` and the platform supports it, an
+ efficient event-driven mechanism is used to wait for process termination:
+
+ - Linux >= 5.3 uses :func:`os.pidfd_open` + :func:`select.poll`
+ - macOS and other BSD variants use :func:`select.kqueue` +
+ ``KQ_FILTER_PROC`` + ``KQ_NOTE_EXIT``
+ - Windows uses ``WaitForSingleObject``
+
+ If none of these mechanisms are available, the function falls back to a
+ busy loop (non-blocking call and short sleeps).
+
+ .. note::
+
+ Use the :mod:`asyncio` module for an asynchronous wait: see
:class:`asyncio.create_subprocess_exec`.
.. versionchanged:: 3.3
*timeout* was added.
+ .. versionchanged:: 3.15
+ if *timeout* is not ``None``, use efficient event-driven implementation
+ on Linux >= 5.3 and macOS / BSD.
+
.. method:: Popen.communicate(input=None, timeout=None)
Interact with process: Send data to stdin. Read data from stdout and stderr,
diff --git a/Doc/library/symtable.rst b/Doc/library/symtable.rst
index f5e6f9f8acfdb8..0b722d7d4e35cf 100644
--- a/Doc/library/symtable.rst
+++ b/Doc/library/symtable.rst
@@ -180,6 +180,12 @@ Examining Symbol Tables
Return a tuple containing names of :term:`free (closure) variables `
in this function.
+ .. method:: get_cells()
+
+ Return a tuple containing names of :term:`cell variables ` in this table.
+
+ .. versionadded:: next
+
.. class:: Class
@@ -291,6 +297,12 @@ Examining Symbol Tables
Return ``True`` if the symbol is referenced in its block, but not assigned
to.
+ .. method:: is_cell()
+
+ Return ``True`` if the symbol is referenced but not assigned in a nested block.
+
+ .. versionadded:: next
+
.. method:: is_free_class()
Return *True* if a class-scoped symbol is free from
diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst
index a0621d4b0dbd09..f977f1389b61a5 100644
--- a/Doc/library/sys.rst
+++ b/Doc/library/sys.rst
@@ -1997,6 +1997,9 @@ always available. Unless explicitly noted otherwise, all variables are read-only
interpreter is pre-release (alpha, beta, or release candidate) then the
local and remote interpreters must be the same exact version.
+ See :ref:`remote-debugging` for more information about the remote debugging
+ mechanism.
+
.. audit-event:: sys.remote_exec pid script_path
When the code is executed in the remote process, an
@@ -2015,6 +2018,7 @@ always available. Unless explicitly noted otherwise, all variables are read-only
.. availability:: Unix, Windows.
.. versionadded:: 3.14
+ See :pep:`768` for more details.
.. function:: _enablelegacywindowsfsencoding()
diff --git a/Doc/library/tachyon-flamegraph.png b/Doc/library/tachyon-flamegraph.png
new file mode 100644
index 00000000000000..a17cd304f8bb28
Binary files /dev/null and b/Doc/library/tachyon-flamegraph.png differ
diff --git a/Doc/library/tachyon-gecko-calltree.png b/Doc/library/tachyon-gecko-calltree.png
new file mode 100644
index 00000000000000..71b096940e8fcd
Binary files /dev/null and b/Doc/library/tachyon-gecko-calltree.png differ
diff --git a/Doc/library/tachyon-gecko-flamegraph.png b/Doc/library/tachyon-gecko-flamegraph.png
new file mode 100644
index 00000000000000..d427ed85ac04e7
Binary files /dev/null and b/Doc/library/tachyon-gecko-flamegraph.png differ
diff --git a/Doc/library/tachyon-gecko-opcodes.png b/Doc/library/tachyon-gecko-opcodes.png
new file mode 100644
index 00000000000000..9741eb659120b8
Binary files /dev/null and b/Doc/library/tachyon-gecko-opcodes.png differ
diff --git a/Doc/library/tachyon-heatmap-with-opcodes.png b/Doc/library/tachyon-heatmap-with-opcodes.png
new file mode 100644
index 00000000000000..5ad67d131548e4
Binary files /dev/null and b/Doc/library/tachyon-heatmap-with-opcodes.png differ
diff --git a/Doc/library/tachyon-heatmap.png b/Doc/library/tachyon-heatmap.png
new file mode 100644
index 00000000000000..47ac1119f4e572
Binary files /dev/null and b/Doc/library/tachyon-heatmap.png differ
diff --git a/Doc/library/tachyon-live-mode-1.gif b/Doc/library/tachyon-live-mode-1.gif
new file mode 100644
index 00000000000000..2d58e807d6a7c1
Binary files /dev/null and b/Doc/library/tachyon-live-mode-1.gif differ
diff --git a/Doc/library/tachyon-live-mode-2.gif b/Doc/library/tachyon-live-mode-2.gif
new file mode 100644
index 00000000000000..bbc2163fe603eb
Binary files /dev/null and b/Doc/library/tachyon-live-mode-2.gif differ
diff --git a/Doc/library/tachyon-logo.png b/Doc/library/tachyon-logo.png
index fddeaafe7e09a5..bf0901ec9f313e 100644
Binary files a/Doc/library/tachyon-logo.png and b/Doc/library/tachyon-logo.png differ
diff --git a/Doc/library/tachyon-pstats.png b/Doc/library/tachyon-pstats.png
new file mode 100644
index 00000000000000..d0281ade660914
Binary files /dev/null and b/Doc/library/tachyon-pstats.png differ
diff --git a/Doc/library/tempfile.rst b/Doc/library/tempfile.rst
index f0a81a093b435b..9d26f47820b134 100644
--- a/Doc/library/tempfile.rst
+++ b/Doc/library/tempfile.rst
@@ -225,8 +225,9 @@ The module defines the following user-callable items:
properly implements the :const:`os.O_EXCL` flag for :func:`os.open`. The
file is readable and writable only by the creating user ID. If the
platform uses permission bits to indicate whether a file is executable,
- the file is executable by no one. The file descriptor is not inherited
- by child processes.
+ the file is executable by no one.
+
+ The file descriptor is :ref:`not inherited by child processes `.
Unlike :func:`TemporaryFile`, the user of :func:`mkstemp` is responsible
for deleting the temporary file when done with it.
diff --git a/Doc/library/test.rst b/Doc/library/test.rst
index 395cde21ccf449..44b1d395a27d13 100644
--- a/Doc/library/test.rst
+++ b/Doc/library/test.rst
@@ -492,6 +492,12 @@ The :mod:`test.support` module defines the following functions:
tests.
+.. function:: get_resource_value(resource)
+
+ Return the value specified for *resource* (as :samp:`-u {resource}={value}`).
+ Return ``None`` if *resource* is disabled or no value is specified.
+
+
.. function:: python_is_optimized()
Return ``True`` if Python was not built with ``-O0`` or ``-Og``.
diff --git a/Doc/library/textwrap.rst b/Doc/library/textwrap.rst
index a58b460fef409c..3c96c0e9cc0a38 100644
--- a/Doc/library/textwrap.rst
+++ b/Doc/library/textwrap.rst
@@ -102,6 +102,10 @@ functions should be good enough; otherwise, you should use an instance of
print(repr(s)) # prints ' hello\n world\n '
print(repr(dedent(s))) # prints 'hello\n world\n'
+ .. versionchanged:: 3.14
+ The :func:`!dedent` function now correctly normalizes blank lines containing
+ only whitespace characters. Previously, the implementation only normalized
+ blank lines containing tabs and spaces.
.. function:: indent(text, prefix, predicate=None)
diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst
index 81177533be84c9..07ce8c40577280 100644
--- a/Doc/library/tkinter.rst
+++ b/Doc/library/tkinter.rst
@@ -177,12 +177,12 @@ the modern themed widget set and API::
.. attribute:: master
The widget object that contains this widget. For :class:`Tk`, the
- *master* is :const:`None` because it is the main window. The terms
+ :attr:`!master` is :const:`None` because it is the main window. The terms
*master* and *parent* are similar and sometimes used interchangeably
as argument names; however, calling :meth:`winfo_parent` returns a
- string of the widget name whereas :attr:`master` returns the object.
+ string of the widget name whereas :attr:`!master` returns the object.
*parent*/*child* reflects the tree-like relationship while
- *master*/*slave* reflects the container structure.
+ *master* (or *container*)/*content* reflects the container structure.
.. attribute:: children
@@ -638,15 +638,15 @@ The Packer
.. index:: single: packing (widgets)
The packer is one of Tk's geometry-management mechanisms. Geometry managers
-are used to specify the relative positioning of widgets within their container -
-their mutual *master*. In contrast to the more cumbersome *placer* (which is
+are used to specify the relative positioning of widgets within their container.
+In contrast to the more cumbersome *placer* (which is
used less commonly, and we do not cover here), the packer takes qualitative
relationship specification - *above*, *to the left of*, *filling*, etc - and
works everything out to determine the exact placement coordinates for you.
-The size of any *master* widget is determined by the size of the "slave widgets"
-inside. The packer is used to control where slave widgets appear inside the
-master into which they are packed. You can pack widgets into frames, and frames
+The size of any container widget is determined by the size of the "content widgets"
+inside. The packer is used to control where content widgets appear inside the
+container into which they are packed. You can pack widgets into frames, and frames
into other frames, in order to achieve the kind of layout you desire.
Additionally, the arrangement is dynamically adjusted to accommodate incremental
changes to the configuration, once it is packed.
@@ -673,7 +673,7 @@ For more extensive information on the packer and the options that it can take,
see the man pages and page 183 of John Ousterhout's book.
anchor
- Anchor type. Denotes where the packer is to place each slave in its parcel.
+ Anchor type. Denotes where the packer is to place each content in its parcel.
expand
Boolean, ``0`` or ``1``.
@@ -682,10 +682,10 @@ fill
Legal values: ``'x'``, ``'y'``, ``'both'``, ``'none'``.
ipadx and ipady
- A distance - designating internal padding on each side of the slave widget.
+ A distance - designating internal padding on each side of the content.
padx and pady
- A distance - designating external padding on each side of the slave widget.
+ A distance - designating external padding on each side of the content.
side
Legal values are: ``'left'``, ``'right'``, ``'top'``, ``'bottom'``.
@@ -758,8 +758,8 @@ subclassed from the :class:`Wm` class, and so can call the :class:`Wm` methods
directly.
To get at the toplevel window that contains a given widget, you can often just
-refer to the widget's master. Of course if the widget has been packed inside of
-a frame, the master won't represent a toplevel window. To get at the toplevel
+refer to the widget's :attr:`master`. Of course if the widget has been packed inside of
+a frame, the :attr:`!master` won't represent a toplevel window. To get at the toplevel
window that contains an arbitrary widget, you can call the :meth:`_root` method.
This method begins with an underscore to denote the fact that this function is
part of the implementation, and not an interface to Tk functionality.
diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst
index 58f3a8ecd7c2e0..eaa0ba54af18e7 100644
--- a/Doc/library/typing.rst
+++ b/Doc/library/typing.rst
@@ -2442,6 +2442,10 @@ types.
Removed the ``_field_types`` attribute in favor of the more
standard ``__annotations__`` attribute which has the same information.
+ .. versionchanged:: 3.9
+ ``NamedTuple`` is now a function rather than a class.
+ It can still be used as a class base, as described above.
+
.. versionchanged:: 3.11
Added support for generic namedtuples.
@@ -2588,7 +2592,7 @@ types.
.. class:: TypedDict(dict)
Special construct to add type hints to a dictionary.
- At runtime it is a plain :class:`dict`.
+ At runtime ":class:`!TypedDict` instances" are simply :class:`dicts `.
``TypedDict`` declares a dictionary type that expects all of its
instances to have a certain set of keys, where each key is
@@ -2811,6 +2815,10 @@ types.
.. versionadded:: 3.8
+ .. versionchanged:: 3.9
+ ``TypedDict`` is now a function rather than a class.
+ It can still be used as a class base, as described above.
+
.. versionchanged:: 3.11
Added support for marking individual keys as :data:`Required` or :data:`NotRequired`.
See :pep:`655`.
@@ -2869,8 +2877,8 @@ ABCs and Protocols for working with I/O
---------------------------------------
.. class:: IO[AnyStr]
- TextIO[AnyStr]
- BinaryIO[AnyStr]
+ TextIO
+ BinaryIO
Generic class ``IO[AnyStr]`` and its subclasses ``TextIO(IO[str])``
and ``BinaryIO(IO[bytes])``
diff --git a/Doc/library/unicodedata.rst b/Doc/library/unicodedata.rst
index 34f21f49b4bcb1..838744c3f899b9 100644
--- a/Doc/library/unicodedata.rst
+++ b/Doc/library/unicodedata.rst
@@ -184,6 +184,28 @@ following functions:
'0041 0303'
+.. function:: grapheme_cluster_break(chr, /)
+
+ Returns the Grapheme_Cluster_Break property assigned to the character.
+
+ .. versionadded:: 3.15
+
+
+.. function:: indic_conjunct_break(chr, /)
+
+ Returns the Indic_Conjunct_Break property assigned to the character.
+
+ .. versionadded:: 3.15
+
+
+.. function:: extended_pictographic(chr, /)
+
+ Returns ``True`` if the character has the Extended_Pictographic property,
+ ``False`` otherwise.
+
+ .. versionadded:: 3.15
+
+
.. function:: normalize(form, unistr, /)
Return the normal form *form* for the Unicode string *unistr*. Valid values for
@@ -225,6 +247,24 @@ following functions:
.. versionadded:: 3.8
+.. function:: iter_graphemes(unistr, start=0, end=sys.maxsize, /)
+
+ Returns an iterator to iterate over grapheme clusters.
+ With optional *start*, iteration begins at that position.
+ With optional *end*, iteration stops at that position.
+
+ Converting an emitted item to string returns a substring corresponding to
+ the grapheme cluster.
+ Its ``start`` and ``end`` attributes denote the start and end of
+ the grapheme cluster.
+
+ It uses extended grapheme cluster rules defined by Unicode
+ Standard Annex #29, `"Unicode Text Segmentation"
+ `_.
+
+ .. versionadded:: 3.15
+
+
In addition, the module exposes the following constant:
.. data:: unidata_version
@@ -234,7 +274,7 @@ In addition, the module exposes the following constant:
.. data:: ucd_3_2_0
- This is an object that has the same methods as the entire module, but uses the
+ This is an object that has most of the methods of the entire module, but uses the
Unicode database version 3.2 instead, for applications that require this
specific version of the Unicode database (such as IDNA).
diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst
index 44a9c79cba2216..ba6e46858f9d26 100644
--- a/Doc/library/urllib.parse.rst
+++ b/Doc/library/urllib.parse.rst
@@ -50,12 +50,16 @@ URL Parsing
The URL parsing functions focus on splitting a URL string into its components,
or on combining URL components into a URL string.
-.. function:: urlparse(urlstring, scheme='', allow_fragments=True)
+.. function:: urlparse(urlstring, scheme=None, allow_fragments=True, *, missing_as_none=False)
Parse a URL into six components, returning a 6-item :term:`named tuple`. This
corresponds to the general structure of a URL:
``scheme://netloc/path;parameters?query#fragment``.
- Each tuple item is a string, possibly empty. The components are not broken up
+ Each tuple item is a string, possibly empty, or ``None`` if
+ *missing_as_none* is true.
+ Not defined component are represented an empty string (by default) or
+ ``None`` if *missing_as_none* is true.
+ The components are not broken up
into smaller parts (for example, the network location is a single string), and %
escapes are not expanded. The delimiters as shown above are not part of the
result, except for a leading slash in the *path* component, which is retained if
@@ -84,6 +88,12 @@ or on combining URL components into a URL string.
80
>>> o._replace(fragment="").geturl()
'http://docs.python.org:80/3/library/urllib.parse.html?highlight=params'
+ >>> urlparse("http://docs.python.org?")
+ ParseResult(scheme='http', netloc='docs.python.org',
+ path='', params='', query='', fragment='')
+ >>> urlparse("http://docs.python.org?", missing_as_none=True)
+ ParseResult(scheme='http', netloc='docs.python.org',
+ path='', params=None, query='', fragment=None)
Following the syntax specifications in :rfc:`1808`, urlparse recognizes
a netloc only if it is properly introduced by '//'. Otherwise the
@@ -101,47 +111,53 @@ or on combining URL components into a URL string.
ParseResult(scheme='', netloc='', path='www.cwi.nl/%7Eguido/Python.html',
params='', query='', fragment='')
>>> urlparse('help/Python.html')
- ParseResult(scheme='', netloc='', path='help/Python.html', params='',
- query='', fragment='')
+ ParseResult(scheme='', netloc='', path='help/Python.html',
+ params='', query='', fragment='')
+ >>> urlparse('help/Python.html', missing_as_none=True)
+ ParseResult(scheme=None, netloc=None, path='help/Python.html',
+ params=None, query=None, fragment=None)
The *scheme* argument gives the default addressing scheme, to be
used only if the URL does not specify one. It should be the same type
- (text or bytes) as *urlstring*, except that the default value ``''`` is
+ (text or bytes) as *urlstring* or ``None``, except that the ``''`` is
always allowed, and is automatically converted to ``b''`` if appropriate.
If the *allow_fragments* argument is false, fragment identifiers are not
recognized. Instead, they are parsed as part of the path, parameters
- or query component, and :attr:`fragment` is set to the empty string in
- the return value.
+ or query component, and :attr:`fragment` is set to ``None`` or the empty
+ string (depending on the value of *missing_as_none*) in the return value.
The return value is a :term:`named tuple`, which means that its items can
be accessed by index or as named attributes, which are:
- +------------------+-------+-------------------------+------------------------+
- | Attribute | Index | Value | Value if not present |
- +==================+=======+=========================+========================+
- | :attr:`scheme` | 0 | URL scheme specifier | *scheme* parameter |
- +------------------+-------+-------------------------+------------------------+
- | :attr:`netloc` | 1 | Network location part | empty string |
- +------------------+-------+-------------------------+------------------------+
- | :attr:`path` | 2 | Hierarchical path | empty string |
- +------------------+-------+-------------------------+------------------------+
- | :attr:`params` | 3 | Parameters for last | empty string |
- | | | path element | |
- +------------------+-------+-------------------------+------------------------+
- | :attr:`query` | 4 | Query component | empty string |
- +------------------+-------+-------------------------+------------------------+
- | :attr:`fragment` | 5 | Fragment identifier | empty string |
- +------------------+-------+-------------------------+------------------------+
- | :attr:`username` | | User name | :const:`None` |
- +------------------+-------+-------------------------+------------------------+
- | :attr:`password` | | Password | :const:`None` |
- +------------------+-------+-------------------------+------------------------+
- | :attr:`hostname` | | Host name (lower case) | :const:`None` |
- +------------------+-------+-------------------------+------------------------+
- | :attr:`port` | | Port number as integer, | :const:`None` |
- | | | if present | |
- +------------------+-------+-------------------------+------------------------+
+ +------------------+-------+-------------------------+-------------------------------+
+ | Attribute | Index | Value | Value if not present |
+ +==================+=======+=========================+===============================+
+ | :attr:`scheme` | 0 | URL scheme specifier | *scheme* parameter or |
+ | | | | empty string [1]_ |
+ +------------------+-------+-------------------------+-------------------------------+
+ | :attr:`netloc` | 1 | Network location part | ``None`` or empty string [1]_ |
+ +------------------+-------+-------------------------+-------------------------------+
+ | :attr:`path` | 2 | Hierarchical path | empty string |
+ +------------------+-------+-------------------------+-------------------------------+
+ | :attr:`params` | 3 | Parameters for last | ``None`` or empty string [1]_ |
+ | | | path element | |
+ +------------------+-------+-------------------------+-------------------------------+
+ | :attr:`query` | 4 | Query component | ``None`` or empty string [1]_ |
+ +------------------+-------+-------------------------+-------------------------------+
+ | :attr:`fragment` | 5 | Fragment identifier | ``None`` or empty string [1]_ |
+ +------------------+-------+-------------------------+-------------------------------+
+ | :attr:`username` | | User name | ``None`` |
+ +------------------+-------+-------------------------+-------------------------------+
+ | :attr:`password` | | Password | ``None`` |
+ +------------------+-------+-------------------------+-------------------------------+
+ | :attr:`hostname` | | Host name (lower case) | ``None`` |
+ +------------------+-------+-------------------------+-------------------------------+
+ | :attr:`port` | | Port number as integer, | ``None`` |
+ | | | if present | |
+ +------------------+-------+-------------------------+-------------------------------+
+
+ .. [1] Depending on the value of the *missing_as_none* argument.
Reading the :attr:`port` attribute will raise a :exc:`ValueError` if
an invalid port is specified in the URL. See section
@@ -187,12 +203,15 @@ or on combining URL components into a URL string.
.. versionchanged:: 3.6
Out-of-range port numbers now raise :exc:`ValueError`, instead of
- returning :const:`None`.
+ returning ``None``.
.. versionchanged:: 3.8
Characters that affect netloc parsing under NFKC normalization will
now raise :exc:`ValueError`.
+ .. versionchanged:: next
+ Added the *missing_as_none* parameter.
+
.. function:: parse_qs(qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', errors='replace', max_num_fields=None, separator='&')
@@ -288,15 +307,27 @@ or on combining URL components into a URL string.
.. function:: urlunparse(parts)
+ urlunparse(parts, *, keep_empty)
Construct a URL from a tuple as returned by ``urlparse()``. The *parts*
- argument can be any six-item iterable. This may result in a slightly
- different, but equivalent URL, if the URL that was parsed originally had
- unnecessary delimiters (for example, a ``?`` with an empty query; the RFC
- states that these are equivalent).
+ argument can be any six-item iterable.
+
+ This may result in a slightly different, but equivalent URL, if the
+ URL that was parsed originally had unnecessary delimiters (for example,
+ a ``?`` with an empty query; the RFC states that these are equivalent).
+ If *keep_empty* is true, empty strings are kept in the result (for example,
+ a ``?`` for an empty query), only ``None`` components are omitted.
+ This allows rebuilding a URL that was parsed with option
+ ``missing_as_none=True``.
+ By default, *keep_empty* is true if *parts* is the result of the
+ :func:`urlparse` call with ``missing_as_none=True``.
-.. function:: urlsplit(urlstring, scheme='', allow_fragments=True)
+ .. versionchanged:: next
+ Added the *keep_empty* parameter.
+
+
+.. function:: urlsplit(urlstring, scheme=None, allow_fragments=True, *, missing_as_none=False)
This is similar to :func:`urlparse`, but does not split the params from the URL.
This should generally be used instead of :func:`urlparse` if the more recent URL
@@ -310,28 +341,31 @@ or on combining URL components into a URL string.
The return value is a :term:`named tuple`, its items can be accessed by index
or as named attributes:
- +------------------+-------+-------------------------+----------------------+
- | Attribute | Index | Value | Value if not present |
- +==================+=======+=========================+======================+
- | :attr:`scheme` | 0 | URL scheme specifier | *scheme* parameter |
- +------------------+-------+-------------------------+----------------------+
- | :attr:`netloc` | 1 | Network location part | empty string |
- +------------------+-------+-------------------------+----------------------+
- | :attr:`path` | 2 | Hierarchical path | empty string |
- +------------------+-------+-------------------------+----------------------+
- | :attr:`query` | 3 | Query component | empty string |
- +------------------+-------+-------------------------+----------------------+
- | :attr:`fragment` | 4 | Fragment identifier | empty string |
- +------------------+-------+-------------------------+----------------------+
- | :attr:`username` | | User name | :const:`None` |
- +------------------+-------+-------------------------+----------------------+
- | :attr:`password` | | Password | :const:`None` |
- +------------------+-------+-------------------------+----------------------+
- | :attr:`hostname` | | Host name (lower case) | :const:`None` |
- +------------------+-------+-------------------------+----------------------+
- | :attr:`port` | | Port number as integer, | :const:`None` |
- | | | if present | |
- +------------------+-------+-------------------------+----------------------+
+ +------------------+-------+-------------------------+-------------------------------+
+ | Attribute | Index | Value | Value if not present |
+ +==================+=======+=========================+===============================+
+ | :attr:`scheme` | 0 | URL scheme specifier | *scheme* parameter or |
+ | | | | empty string [1]_ |
+ +------------------+-------+-------------------------+-------------------------------+
+ | :attr:`netloc` | 1 | Network location part | ``None`` or empty string [2]_ |
+ +------------------+-------+-------------------------+-------------------------------+
+ | :attr:`path` | 2 | Hierarchical path | empty string |
+ +------------------+-------+-------------------------+-------------------------------+
+ | :attr:`query` | 3 | Query component | ``None`` or empty string [2]_ |
+ +------------------+-------+-------------------------+-------------------------------+
+ | :attr:`fragment` | 4 | Fragment identifier | ``None`` or empty string [2]_ |
+ +------------------+-------+-------------------------+-------------------------------+
+ | :attr:`username` | | User name | ``None`` |
+ +------------------+-------+-------------------------+-------------------------------+
+ | :attr:`password` | | Password | ``None`` |
+ +------------------+-------+-------------------------+-------------------------------+
+ | :attr:`hostname` | | Host name (lower case) | ``None`` |
+ +------------------+-------+-------------------------+-------------------------------+
+ | :attr:`port` | | Port number as integer, | ``None`` |
+ | | | if present | |
+ +------------------+-------+-------------------------+-------------------------------+
+
+ .. [2] Depending on the value of the *missing_as_none* argument.
Reading the :attr:`port` attribute will raise a :exc:`ValueError` if
an invalid port is specified in the URL. See section
@@ -356,7 +390,7 @@ or on combining URL components into a URL string.
.. versionchanged:: 3.6
Out-of-range port numbers now raise :exc:`ValueError`, instead of
- returning :const:`None`.
+ returning ``None``.
.. versionchanged:: 3.8
Characters that affect netloc parsing under NFKC normalization will
@@ -368,15 +402,31 @@ or on combining URL components into a URL string.
.. versionchanged:: 3.12
Leading WHATWG C0 control and space characters are stripped from the URL.
+ .. versionchanged:: next
+ Added the *missing_as_none* parameter.
+
.. _WHATWG spec: https://url.spec.whatwg.org/#concept-basic-url-parser
.. function:: urlunsplit(parts)
+ urlunsplit(parts, *, keep_empty)
Combine the elements of a tuple as returned by :func:`urlsplit` into a
complete URL as a string. The *parts* argument can be any five-item
- iterable. This may result in a slightly different, but equivalent URL, if the
- URL that was parsed originally had unnecessary delimiters (for example, a ?
- with an empty query; the RFC states that these are equivalent).
+ iterable.
+
+ This may result in a slightly different, but equivalent URL, if the
+ URL that was parsed originally had unnecessary delimiters (for example,
+ a ``?`` with an empty query; the RFC states that these are equivalent).
+
+ If *keep_empty* is true, empty strings are kept in the result (for example,
+ a ``?`` for an empty query), only ``None`` components are omitted.
+ This allows rebuilding a URL that was parsed with option
+ ``missing_as_none=True``.
+ By default, *keep_empty* is true if *parts* is the result of the
+ :func:`urlsplit` call with ``missing_as_none=True``.
+
+ .. versionchanged:: next
+ Added the *keep_empty* parameter.
.. function:: urljoin(base, url, allow_fragments=True)
@@ -422,23 +472,25 @@ or on combining URL components into a URL string.
Behavior updated to match the semantics defined in :rfc:`3986`.
-.. function:: urldefrag(url)
+.. function:: urldefrag(url, *, missing_as_none=False)
If *url* contains a fragment identifier, return a modified version of *url*
with no fragment identifier, and the fragment identifier as a separate
string. If there is no fragment identifier in *url*, return *url* unmodified
- and an empty string.
+ and an empty string (by default) or ``None`` if *missing_as_none* is true.
The return value is a :term:`named tuple`, its items can be accessed by index
or as named attributes:
- +------------------+-------+-------------------------+----------------------+
- | Attribute | Index | Value | Value if not present |
- +==================+=======+=========================+======================+
- | :attr:`url` | 0 | URL with no fragment | empty string |
- +------------------+-------+-------------------------+----------------------+
- | :attr:`fragment` | 1 | Fragment identifier | empty string |
- +------------------+-------+-------------------------+----------------------+
+ +------------------+-------+-------------------------+-------------------------------+
+ | Attribute | Index | Value | Value if not present |
+ +==================+=======+=========================+===============================+
+ | :attr:`url` | 0 | URL with no fragment | empty string |
+ +------------------+-------+-------------------------+-------------------------------+
+ | :attr:`fragment` | 1 | Fragment identifier | ``None`` or empty string [3]_ |
+ +------------------+-------+-------------------------+-------------------------------+
+
+ .. [3] Depending on the value of the *missing_as_none* argument.
See section :ref:`urlparse-result-object` for more information on the result
object.
@@ -446,6 +498,9 @@ or on combining URL components into a URL string.
.. versionchanged:: 3.2
Result is a structured object rather than a simple 2-tuple.
+ .. versionchanged:: next
+ Added the *missing_as_none* parameter.
+
.. function:: unwrap(url)
Extract the url from a wrapped URL (that is, a string formatted as
@@ -465,8 +520,9 @@ URLs elsewhere. Their purpose is for practical functionality rather than
purity.
Instead of raising an exception on unusual input, they may instead return some
-component parts as empty strings. Or components may contain more than perhaps
-they should.
+component parts as empty strings or ``None`` (depending on the value of the
+*missing_as_none* argument).
+Or components may contain more than perhaps they should.
We recommend that users of these APIs where the values may be used anywhere
with security implications code defensively. Do some verification within your
@@ -542,7 +598,8 @@ previous section, as well as an additional method:
Return the re-combined version of the original URL as a string. This may
differ from the original URL in that the scheme may be normalized to lower
case and empty components may be dropped. Specifically, empty parameters,
- queries, and fragment identifiers will be removed.
+ queries, and fragment identifiers will be removed unless the URL was parsed
+ with ``missing_as_none=True``.
For :func:`urldefrag` results, only empty fragment identifiers will be removed.
For :func:`urlsplit` and :func:`urlparse` results, all noted changes will be
@@ -559,6 +616,9 @@ previous section, as well as an additional method:
>>> r2 = urlsplit(r1.geturl())
>>> r2.geturl()
'http://www.Python.org/doc/'
+ >>> r3 = urlsplit(url, missing_as_none=True)
+ >>> r3.geturl()
+ 'http://www.Python.org/doc/#'
The following classes provide the implementations of the structured parse
diff --git a/Doc/library/winreg.rst b/Doc/library/winreg.rst
index 89def6e2afe088..d167c41ab72c34 100644
--- a/Doc/library/winreg.rst
+++ b/Doc/library/winreg.rst
@@ -7,6 +7,8 @@
.. sectionauthor:: Mark Hammond
+**Source code:** :source:`PC/winreg.c`
+
--------------
These functions expose the Windows registry API to Python. Instead of using an
@@ -25,7 +27,7 @@ to explicitly close them.
.. _functions:
Functions
-------------------
+---------
This module offers the following functions:
@@ -554,7 +556,7 @@ This module offers the following functions:
.. _constants:
Constants
-------------------
+---------
The following constants are defined for use in many :mod:`winreg` functions.
diff --git a/Doc/library/winsound.rst b/Doc/library/winsound.rst
index 93c0c025982076..755b94fc0fbe1e 100644
--- a/Doc/library/winsound.rst
+++ b/Doc/library/winsound.rst
@@ -8,6 +8,8 @@
.. moduleauthor:: Toby Dickenson
.. sectionauthor:: Fred L. Drake, Jr.
+**Source code:** :source:`PC/winsound.c`
+
--------------
The :mod:`winsound` module provides access to the basic sound-playing machinery
@@ -16,6 +18,9 @@ provided by Windows platforms. It includes functions and several constants.
.. availability:: Windows.
+Functions
+---------
+
.. function:: Beep(frequency, duration)
Beep the PC's speaker. The *frequency* parameter specifies frequency, in hertz,
@@ -46,6 +51,9 @@ provided by Windows platforms. It includes functions and several constants.
error, :exc:`RuntimeError` is raised.
+Constants
+---------
+
.. data:: SND_FILENAME
The *sound* parameter is the name of a WAV file. Do not use with
diff --git a/Doc/library/zoneinfo.rst b/Doc/library/zoneinfo.rst
index 8147e58d322667..759ec4277b8b7d 100644
--- a/Doc/library/zoneinfo.rst
+++ b/Doc/library/zoneinfo.rst
@@ -206,6 +206,9 @@ The ``ZoneInfo`` class has two alternate constructors:
Objects created via this constructor cannot be pickled (see `pickling`_).
+ :exc:`ValueError` is raised if the data read from *file_obj* is not a valid
+ TZif file.
+
.. classmethod:: ZoneInfo.no_cache(key)
An alternate constructor that bypasses the constructor's cache. It is
diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst
index 6521b4bee50758..861c221502ed4d 100644
--- a/Doc/reference/compound_stmts.rst
+++ b/Doc/reference/compound_stmts.rst
@@ -388,7 +388,7 @@ type of the target ``e`` is consistently :exc:`BaseExceptionGroup`::
... except* BlockingIOError as e:
... print(repr(e))
...
- ExceptionGroup('', (BlockingIOError()))
+ ExceptionGroup('', (BlockingIOError(),))
:keyword:`break`, :keyword:`continue` and :keyword:`return`
cannot appear in an :keyword:`!except*` clause.
diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst
index 5f79c6fe8f50ff..f784d963f9d3e1 100644
--- a/Doc/reference/datamodel.rst
+++ b/Doc/reference/datamodel.rst
@@ -546,6 +546,7 @@ Special read-only attributes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. index::
+ single: __builtins__ (function attribute)
single: __closure__ (function attribute)
single: __globals__ (function attribute)
pair: global; namespace
@@ -556,6 +557,12 @@ Special read-only attributes
* - Attribute
- Meaning
+ * - .. attribute:: function.__builtins__
+ - A reference to the :class:`dictionary ` that holds the function's
+ builtins namespace.
+
+ .. versionadded:: 3.10
+
* - .. attribute:: function.__globals__
- A reference to the :class:`dictionary ` that holds the function's
:ref:`global variables ` -- the global namespace of the module
@@ -895,7 +902,6 @@ Attribute assignment updates the module's namespace dictionary, e.g.,
single: __loader__ (module attribute)
single: __path__ (module attribute)
single: __file__ (module attribute)
- single: __cached__ (module attribute)
single: __doc__ (module attribute)
single: __annotations__ (module attribute)
single: __annotate__ (module attribute)
@@ -1044,43 +1050,28 @@ this approach.
instead of :attr:`!module.__path__`.
.. attribute:: module.__file__
-.. attribute:: module.__cached__
- :attr:`!__file__` and :attr:`!__cached__` are both optional attributes that
+ :attr:`!__file__` is an optional attribute that
may or may not be set. Both attributes should be a :class:`str` when they
are available.
- :attr:`!__file__` indicates the pathname of the file from which the module
- was loaded (if loaded from a file), or the pathname of the shared library
- file for extension modules loaded dynamically from a shared library.
- It might be missing for certain types of modules, such as C modules that are
- statically linked into the interpreter, and the
+ An optional attribute, :attr:`!__file__` indicates the pathname of the file
+ from which the module was loaded (if loaded from a file), or the pathname of
+ the shared library file for extension modules loaded dynamically from a
+ shared library. It might be missing for certain types of modules, such as C
+ modules that are statically linked into the interpreter, and the
:ref:`import system ` may opt to leave it unset if it
has no semantic meaning (for example, a module loaded from a database).
- If :attr:`!__file__` is set then the :attr:`!__cached__` attribute might
- also be set, which is the path to any compiled version of
- the code (for example, a byte-compiled file). The file does not need to exist
- to set this attribute; the path can simply point to where the
- compiled file *would* exist (see :pep:`3147`).
-
- Note that :attr:`!__cached__` may be set even if :attr:`!__file__` is not
- set. However, that scenario is quite atypical. Ultimately, the
- :term:`loader` is what makes use of the module spec provided by the
- :term:`finder` (from which :attr:`!__file__` and :attr:`!__cached__` are
- derived). So if a loader can load from a cached module but otherwise does
- not load from a file, that atypical scenario may be appropriate.
-
- It is **strongly** recommended that you use
- :attr:`module.__spec__.cached `
- instead of :attr:`!module.__cached__`.
-
.. deprecated-removed:: 3.13 3.15
- Setting :attr:`!__cached__` on a module while failing to set
+ Setting ``__cached__`` on a module while failing to set
:attr:`!__spec__.cached` is deprecated. In Python 3.15,
- :attr:`!__cached__` will cease to be set or taken into consideration by
+ ``__cached__`` will cease to be set or taken into consideration by
the import system or standard library.
+ .. versionchanged:: 3.15
+ ``__cached__`` is no longer set.
+
Other writable attributes on module objects
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -1835,6 +1826,12 @@ Slice objects are used to represent slices for
:meth:`~object.__getitem__`
methods. They are also created by the built-in :func:`slice` function.
+.. versionadded:: 3.15
+
+ The :func:`slice` type now supports :ref:`subscription `. For
+ example, ``slice[float]`` may be used in type annotations to indicate a slice
+ containing :type:`float` objects.
+
.. index::
single: start (slice object attribute)
single: stop (slice object attribute)
@@ -2633,7 +2630,7 @@ Notes on using *__slots__*:
* :exc:`TypeError` will be raised if *__slots__* other than *__dict__* and
*__weakref__* are defined for a class derived from a
:c:member:`"variable-length" built-in type ` such as
- :class:`int`, :class:`bytes`, and :class:`tuple`.
+ :class:`int`, :class:`bytes`, and :class:`type`, except :class:`tuple`.
* Any non-string :term:`iterable` may be assigned to *__slots__*.
@@ -2656,8 +2653,9 @@ Notes on using *__slots__*:
of the iterator's values. However, the *__slots__* attribute will be an empty
iterator.
-.. versionchanged:: next
+.. versionchanged:: 3.15
Allowed defining the *__dict__* and *__weakref__* *__slots__* for any class.
+ Allowed defining any *__slots__* for a class derived from :class:`tuple`.
.. _class-customization:
diff --git a/Doc/reference/grammar.rst b/Doc/reference/grammar.rst
index 1037feb691f6bc..0ce8e42ddf3b0c 100644
--- a/Doc/reference/grammar.rst
+++ b/Doc/reference/grammar.rst
@@ -12,8 +12,17 @@ The notation used here is the same as in the preceding docs,
and is described in the :ref:`notation ` section,
except for an extra complication:
-* ``~`` ("cut"): commit to the current alternative and fail the rule
- even if this fails to parse
+* ``~`` ("cut"): commit to the current alternative; fail the rule
+ if the alternative fails to parse
+
+ Python mainly uses cuts for optimizations or improved error
+ messages. They often appear to be useless in the listing below.
+
+ .. see gh-143054, and CutValidator in the source, if you want to change this:
+
+ Cuts currently don't appear inside parentheses, brackets, lookaheads
+ and similar.
+ Their behavior in these contexts is deliberately left unspecified.
.. literalinclude:: ../../Grammar/python.gram
:language: peg
diff --git a/Doc/reference/import.rst b/Doc/reference/import.rst
index f50d02a0ef03b9..83f0ee75e7aebd 100644
--- a/Doc/reference/import.rst
+++ b/Doc/reference/import.rst
@@ -832,9 +832,7 @@ entirely with a custom meta path hook.
If it is acceptable to only alter the behaviour of import statements
without affecting other APIs that access the import system, then replacing
-the builtin :func:`__import__` function may be sufficient. This technique
-may also be employed at the module level to only alter the behaviour of
-import statements within that module.
+the builtin :func:`__import__` function may be sufficient.
To selectively prevent the import of some modules from a hook early on the
meta path (rather than disabling the standard import system entirely),
diff --git a/Doc/reference/lexical_analysis.rst b/Doc/reference/lexical_analysis.rst
index 9322d8571f7ab6..046c759854c4df 100644
--- a/Doc/reference/lexical_analysis.rst
+++ b/Doc/reference/lexical_analysis.rst
@@ -1227,7 +1227,7 @@ Whitespace is significant in these situations:
string contents.
* In ``fstring_replacement_field``, if ``f_debug_specifier`` is present,
all whitespace after the opening brace until the ``f_debug_specifier``,
- as well as whitespace immediatelly following ``f_debug_specifier``,
+ as well as whitespace immediately following ``f_debug_specifier``,
is retained as part of the expression.
.. impl-detail::
diff --git a/Doc/requirements.txt b/Doc/requirements.txt
index 716772b7f28d99..d0107744ecbe85 100644
--- a/Doc/requirements.txt
+++ b/Doc/requirements.txt
@@ -7,7 +7,7 @@
# won't suddenly cause build failures. Updating the version is fine as long
# as no warnings are raised by doing so.
# Keep this version in sync with ``Doc/conf.py``.
-sphinx~=9.0.0
+sphinx<9.0.0
blurb
diff --git a/Doc/tools/check-warnings.py b/Doc/tools/check-warnings.py
index 2f2bb9e2dcb7ef..859bc1e2d5f5b5 100644
--- a/Doc/tools/check-warnings.py
+++ b/Doc/tools/check-warnings.py
@@ -311,8 +311,11 @@ def main(argv: list[str] | None = None) -> int:
if not Path("Doc").exists() or not Path("Doc").is_dir():
raise RuntimeError(wrong_directory_msg)
- with Path("Doc/sphinx-warnings.txt").open(encoding="UTF-8") as f:
- warnings = f.read().splitlines()
+ warnings = (
+ Path("Doc/sphinx-warnings.txt")
+ .read_text(encoding="UTF-8")
+ .splitlines()
+ )
cwd = str(Path.cwd()) + os.path.sep
files_with_nits = {
diff --git a/Doc/tools/extensions/grammar_snippet.py b/Doc/tools/extensions/grammar_snippet.py
index 1e059f111e4091..8078b7ebeb8076 100644
--- a/Doc/tools/extensions/grammar_snippet.py
+++ b/Doc/tools/extensions/grammar_snippet.py
@@ -191,7 +191,7 @@ class GrammarSnippetDirective(GrammarSnippetBase):
into something similar to Sphinx productionlist, but better suited
for our needs:
- Instead of `::=`, use a colon, as in `Grammar/python.gram`
- - Show the listing almost as is, with no auto-aligment.
+ - Show the listing almost as is, with no auto-alignment.
The only special character is the backtick, which marks tokens.
Unlike Sphinx's productionlist, this directive supports options.
diff --git a/Doc/tools/extensions/lexers/asdl_lexer.py b/Doc/tools/extensions/lexers/asdl_lexer.py
index 3a74174a1f7dfb..548ce1271a1db8 100644
--- a/Doc/tools/extensions/lexers/asdl_lexer.py
+++ b/Doc/tools/extensions/lexers/asdl_lexer.py
@@ -22,7 +22,7 @@ class ASDLLexer(RegexLexer):
bygroups(Keyword, Text, Name.Tag),
),
(
- r"(\w+)(\*\s|\?\s|\s)(\w+)",
+ r"(\w+)([\?\*]*\s)(\w+)",
bygroups(Name.Builtin.Pseudo, Operator, Name),
),
# Keep in line with ``builtin_types`` from Parser/asdl.py.
diff --git a/Doc/tools/extensions/pydoc_topics.py b/Doc/tools/extensions/pydoc_topics.py
index 01efbba628324f..a65d77433b255b 100644
--- a/Doc/tools/extensions/pydoc_topics.py
+++ b/Doc/tools/extensions/pydoc_topics.py
@@ -109,6 +109,7 @@ class PydocTopicsBuilder(TextBuilder):
def init(self) -> None:
super().init()
self.topics: dict[str, str] = {}
+ self.module_docs: dict[str, str] = {}
def get_outdated_docs(self) -> str:
# Return a string describing what an update build will build.
@@ -130,6 +131,15 @@ def write_documents(self, _docnames: Set[str]) -> None:
continue
doc_labels.setdefault(docname, []).append((topic_label, label_id))
+ py_domain = env.domains['py']
+ for module_name, module_info in py_domain.data['modules'].items():
+ docname = module_info[0]
+ if docname.startswith('library/'):
+ doc_file = docname.replace('library/', '')
+ self.module_docs[module_name] = (
+ f"{doc_file}#module-{module_name}"
+ )
+
for docname, label_ids in status_iterator(
doc_labels.items(),
"building topics... ",
@@ -161,6 +171,22 @@ def finish(self) -> None:
"""
self.outdir.joinpath("topics.py").write_text(topics, encoding="utf-8")
+ module_docs_repr = "\n".join(
+ f" '{module}': '{doc_file}',"
+ for module, doc_file in sorted(self.module_docs.items())
+ )
+ module_docs = f"""\
+# Autogenerated by Sphinx on {asctime()}
+# as part of the release process.
+
+module_docs = {{
+{module_docs_repr}
+}}
+"""
+ self.outdir.joinpath("module_docs.py").write_text(
+ module_docs, encoding="utf-8"
+ )
+
def _display_labels(item: tuple[str, Sequence[tuple[str, str]]]) -> str:
_docname, label_ids = item
diff --git a/Doc/tools/templates/customsourcelink.html b/Doc/tools/templates/customsourcelink.html
index 8e271bca1e08c8..0d83ac9f78adb9 100644
--- a/Doc/tools/templates/customsourcelink.html
+++ b/Doc/tools/templates/customsourcelink.html
@@ -8,6 +8,12 @@
{{ _('This page') }}
rel="nofollow">{{ _('Show source') }}
+ {% if language != "en" %}
+
+ {% endif %}
{%- endif %}
diff --git a/Doc/tutorial/appendix.rst b/Doc/tutorial/appendix.rst
index 5020c428741feb..2539edb51ba3a0 100644
--- a/Doc/tutorial/appendix.rst
+++ b/Doc/tutorial/appendix.rst
@@ -14,8 +14,7 @@ There are two variants of the interactive :term:`REPL`. The classic
basic interpreter is supported on all platforms with minimal line
control capabilities.
-On Windows, or Unix-like systems with :mod:`curses` support,
-a new interactive shell is used by default since Python 3.13.
+Since Python 3.13, a new interactive shell is used by default.
This one supports color, multiline editing, history browsing, and
paste mode. To disable color, see :ref:`using-on-controlling-color` for
details. Function keys provide some additional functionality.
diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst
index 5ec8789f98c701..f3e69756401b8b 100644
--- a/Doc/tutorial/controlflow.rst
+++ b/Doc/tutorial/controlflow.rst
@@ -1039,31 +1039,28 @@ blank, visually separating the summary from the rest of the description. The
following lines should be one or more paragraphs describing the object's calling
conventions, its side effects, etc.
-The Python parser does not strip indentation from multi-line string literals in
-Python, so tools that process documentation have to strip indentation if
-desired. This is done using the following convention. The first non-blank line
-*after* the first line of the string determines the amount of indentation for
-the entire documentation string. (We can't use the first line since it is
-generally adjacent to the string's opening quotes so its indentation is not
-apparent in the string literal.) Whitespace "equivalent" to this indentation is
-then stripped from the start of all lines of the string. Lines that are
-indented less should not occur, but if they occur all their leading whitespace
-should be stripped. Equivalence of whitespace should be tested after expansion
-of tabs (to 8 spaces, normally).
+The Python parser strips indentation from multi-line string literals when they
+serve as module, class, or function docstrings.
Here is an example of a multi-line docstring::
>>> def my_function():
... """Do nothing, but document it.
...
- ... No, really, it doesn't do anything.
+ ... No, really, it doesn't do anything:
+ ...
+ ... >>> my_function()
+ ... >>>
... """
... pass
...
>>> print(my_function.__doc__)
Do nothing, but document it.
- No, really, it doesn't do anything.
+ No, really, it doesn't do anything:
+
+ >>> my_function()
+ >>>
.. _tut-annotations:
diff --git a/Doc/tutorial/interpreter.rst b/Doc/tutorial/interpreter.rst
index cd52607142485e..72cac1c1e909d3 100644
--- a/Doc/tutorial/interpreter.rst
+++ b/Doc/tutorial/interpreter.rst
@@ -34,13 +34,13 @@ status. If that doesn't work, you can exit the interpreter by typing the
following command: ``quit()``.
The interpreter's line-editing features include interactive editing, history
-substitution and code completion on systems that support the `GNU Readline
-`_ library.
+substitution and code completion on most systems.
Perhaps the quickest check to see whether command line editing is supported is
-typing :kbd:`Control-P` to the first Python prompt you get. If it beeps, you
-have command line editing; see Appendix :ref:`tut-interacting` for an
-introduction to the keys. If nothing appears to happen, or if ``^P`` is
-echoed, command line editing isn't available; you'll only be able to use
+typing a word in on the Python prompt, then pressing Left arrow (or :kbd:`Control-b`).
+If the cursor moves, you have command line editing; see Appendix
+:ref:`tut-interacting` for an introduction to the keys.
+If nothing appears to happen, or if a sequence like ``^[[D`` or ``^B`` appears,
+command line editing isn't available; you'll only be able to use
backspace to remove characters from the current line.
The interpreter operates somewhat like the Unix shell: when called with standard
diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst
index aff165191b76e8..c97058119ae838 100644
--- a/Doc/using/cmdline.rst
+++ b/Doc/using/cmdline.rst
@@ -1087,6 +1087,27 @@ conflict.
It now has no effect if set to an empty string.
+.. envvar:: PYTHON_PYMALLOC_HUGEPAGES
+
+ If set to a non-zero integer, enable huge page support for
+ :ref:`pymalloc ` arenas. Set to ``0`` or unset to disable.
+ Python must be compiled with :option:`--with-pymalloc-hugepages` for this
+ variable to have any effect.
+
+ When enabled, arena allocation uses ``MAP_HUGETLB`` (Linux) or
+ ``MEM_LARGE_PAGES`` (Windows) with automatic fallback to regular pages if
+ huge pages are not available.
+
+ .. warning::
+
+ On Linux, if the huge-page pool is exhausted, page faults — including
+ copy-on-write faults triggered by :func:`os.fork` — deliver ``SIGBUS``
+ and kill the process. Only enable this in environments where the
+ huge-page pool is properly sized and fork-safety is not a concern.
+
+ .. versionadded:: next
+
+
.. envvar:: PYTHONLEGACYWINDOWSFSENCODING
If set to a non-empty string, the default :term:`filesystem encoding and
diff --git a/Doc/using/configure.rst b/Doc/using/configure.rst
index dff0fe036ea53a..26322045879cb2 100644
--- a/Doc/using/configure.rst
+++ b/Doc/using/configure.rst
@@ -344,7 +344,7 @@ General Options
"_tkinter": "Install the python-tk package to use tkinter",
}
- .. versionadded:: next
+ .. versionadded:: 3.15
.. option:: --enable-pystats
@@ -783,6 +783,27 @@ also be used to improve performance.
See also :envvar:`PYTHONMALLOC` environment variable.
+.. option:: --with-pymalloc-hugepages
+
+ Enable huge page support for :ref:`pymalloc ` arenas (disabled by
+ default). When enabled, the arena size on 64-bit platforms is increased to
+ 2 MiB and arena allocation uses ``MAP_HUGETLB`` (Linux) or
+ ``MEM_LARGE_PAGES`` (Windows) with automatic fallback to regular pages.
+
+ Even when compiled with this option, huge pages are **not** used at runtime
+ unless the :envvar:`PYTHON_PYMALLOC_HUGEPAGES` environment variable is set
+ to ``1``. This opt-in is required because huge pages carry risks on Linux:
+ if the huge-page pool is exhausted, page faults (including copy-on-write
+ faults after :func:`os.fork`) deliver ``SIGBUS`` and kill the process.
+
+ The configure script checks that the platform supports ``MAP_HUGETLB``
+ and emits a warning if it is not available.
+
+ On Windows, use the ``--pymalloc-hugepages`` flag with ``build.bat`` or
+ set the ``UsePymallocHugepages`` MSBuild property.
+
+ .. versionadded:: 3.15
+
.. option:: --without-doc-strings
Disable static documentation strings to reduce the memory footprint (enabled
diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst
index a4bc336cc92618..d286788e8054cc 100644
--- a/Doc/using/windows.rst
+++ b/Doc/using/windows.rst
@@ -126,9 +126,8 @@ is also an unambiguous ``pymanager`` command. Scripted installs that are
intending to use Python install manager should consider using ``pymanager``, due
to the lower chance of encountering a conflict with existing installs. The only
difference between the two commands is when running without any arguments:
-``py`` will install and launch your default interpreter, while ``pymanager``
-will display help (``pymanager exec ...`` provides equivalent behaviour to
-``py ...``).
+``py`` will launch your default interpreter, while ``pymanager`` will display
+help (``pymanager exec ...`` provides equivalent behaviour to ``py ...``).
Each of these commands also has a windowed version that avoids creating a
console window. These are ``pyw``, ``pythonw`` and ``pymanagerw``. A ``python3``
@@ -187,12 +186,11 @@ that virtual environment. In this scenario, the ``python`` command was likely
already overridden and none of these checks occurred. However, this behaviour
ensures that the ``py`` command can be used interchangeably.
-When you launch either ``python`` or ``py`` but do not have any runtimes
-installed, and the requested version is the default, it will be installed
-automatically and then launched. Otherwise, the requested version will be
-installed if automatic installation is configured (most likely by setting
-``PYTHON_MANAGER_AUTOMATIC_INSTALL`` to ``true``), or if the ``py exec`` or
-``pymanager exec`` forms of the command were used.
+When no runtimes are installed, any launch command will try to install the
+requested version and launch it. However, after any version is installed, only
+the ``py exec ...`` and ``pymanager exec ...`` commands will install if the
+requested version is absent. Other forms of commands will display an error and
+direct you to use ``py install`` first.
Command help
@@ -301,6 +299,14 @@ To launch the runtime, directly execute the main executable (typically
$> py install ... [-t=|--target=]
+The ``py exec`` command will install the requested runtime if it is not already
+present. This is controlled by the ``automatic_install`` configuration
+(:envvar:`PYTHON_MANAGER_AUTOMATIC_INSTALL`), and is enabled by default.
+If no runtimes are available at all, all launch commands will do an automatic
+install if the configuration setting allows. This is to ensure a good experience
+for new users, but should not generally be relied on rather than using the
+``py exec`` command or explicit install commands.
+
.. _pymanager-offline:
@@ -426,9 +432,11 @@ customization.
By default, :file:`%TEMP%`.
* - ``automatic_install``
- - ``PYTHON_MANAGER_AUTOMATIC_INSTALL``
- - True to allow automatic installs when using ``py exec`` to launch.
- Other commands will not automatically install.
+ - .. envvar:: PYTHON_MANAGER_AUTOMATIC_INSTALL
+ - True to allow automatic installs when using ``py exec`` to launch (or
+ ``py`` when no runtimes are installed yet).
+ Other commands will not automatically install, regardless of this
+ setting.
By default, true.
* - ``include_unmanaged``
@@ -777,7 +785,7 @@ Troubleshooting
If your Python install manager does not seem to be working correctly, please
work through these tests and fixes to see if it helps. If not, please report an
-issue at `our bug tracker `_,
+issue at `our bug tracker `_,
including any relevant log files (written to your :file:`%TEMP%` directory by
default).
diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst
index 8badfe9a6b49b9..221956f3dd3819 100644
--- a/Doc/whatsnew/3.12.rst
+++ b/Doc/whatsnew/3.12.rst
@@ -1337,7 +1337,7 @@ Deprecated
it was :exc:`ImportWarning`).
(Contributed by Brett Cannon in :gh:`65961`.)
-* Setting :attr:`~module.__package__` or :attr:`~module.__cached__` on a
+* Setting :attr:`~module.__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`.)
diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst
index dc105156f33080..f4489bfa1b74e8 100644
--- a/Doc/whatsnew/3.13.rst
+++ b/Doc/whatsnew/3.13.rst
@@ -1861,6 +1861,7 @@ New Deprecations
* Deprecate the non-standard and undocumented :class:`~decimal.Decimal`
format specifier ``'N'``,
which is only supported in the :mod:`!decimal` module's C implementation.
+ Scheduled to be removed in Python 3.18.
(Contributed by Serhiy Storchaka in :gh:`89902`.)
* :mod:`dis`:
@@ -2024,6 +2025,8 @@ New Deprecations
.. include:: ../deprecations/pending-removal-in-3.17.rst
+.. include:: ../deprecations/pending-removal-in-3.18.rst
+
.. include:: ../deprecations/pending-removal-in-3.19.rst
.. include:: ../deprecations/pending-removal-in-3.20.rst
@@ -2337,7 +2340,7 @@ Limited C API Changes
* :c:func:`PySys_AuditTuple`
* :c:func:`PyType_GetModuleByDef`
- (Contributed by Victor Stinner in :gh:`85283`, :gh:`85283`, and :gh:`116936`.)
+ (Contributed by Victor Stinner in :gh:`85283` and :gh:`116936`.)
* Python built with :option:`--with-trace-refs` (tracing references)
now supports the :ref:`Limited API `.
diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst
index 9459b73bcb502f..d4517183d697f1 100644
--- a/Doc/whatsnew/3.14.rst
+++ b/Doc/whatsnew/3.14.rst
@@ -2265,6 +2265,15 @@ pdb
(Contributed by Tian Gao in :gh:`124533`.)
+textwrap
+--------
+
+* Optimize the :func:`~textwrap.dedent` function, improving performance by
+ an average of 2.4x, with larger improvements for bigger inputs,
+ and fix a bug with incomplete normalization of blank lines with whitespace
+ characters other than space and tab.
+
+
uuid
----
@@ -2709,6 +2718,8 @@ New deprecations
.. include:: ../deprecations/pending-removal-in-3.17.rst
+.. include:: ../deprecations/pending-removal-in-3.18.rst
+
.. include:: ../deprecations/pending-removal-in-3.19.rst
.. include:: ../deprecations/pending-removal-in-3.20.rst
diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst
index 853c47d4402f20..637dd0cca24bb9 100644
--- a/Doc/whatsnew/3.15.rst
+++ b/Doc/whatsnew/3.15.rst
@@ -73,6 +73,7 @@ Summary -- Release highlights
`
* :pep:`782`: :ref:`A new PyBytesWriter C API to create a Python bytes object
`
+* :ref:`The JIT compiler has been significantly upgraded `
* :ref:`Improved error messages `
@@ -146,6 +147,8 @@ Key features include:
and blocking. Use this to identify CPU-bound bottlenecks and optimize computational work.
* **GIL-holding time** (``--mode gil``): Measures time spent holding Python's Global Interpreter
Lock. Use this to identify which threads dominate GIL usage in multi-threaded applications.
+ * **Exception handling time** (``--mode exception``): Captures samples only from threads with
+ an active exception. Use this to analyze exception handling overhead.
* **Thread-aware profiling**: Option to profile all threads (``-a``) or just the main thread,
essential for understanding multi-threaded application behavior.
@@ -175,6 +178,10 @@ Key features include:
(``--async-aware``). See which coroutines are consuming time, with options to show only
running tasks or all tasks including those waiting.
+* **Opcode-level profiling**: Gather bytecode opcode information for instruction-level
+ profiling (``--opcodes``). Shows which bytecode instructions are executing, including
+ specializations from the adaptive interpreter.
+
See :mod:`profiling.sampling` for the complete documentation, including all
available output formats, profiling modes, and configuration options.
@@ -391,6 +398,13 @@ Other language changes
for any class.
(Contributed by Serhiy Storchaka in :gh:`41779`.)
+* Allowed defining any :ref:`__slots__ ` for a class derived from
+ :class:`tuple` (including classes created by :func:`collections.namedtuple`).
+ (Contributed by Serhiy Storchaka in :gh:`41779`.)
+
+* The :class:`slice` type now supports subscription,
+ making it a :term:`generic type`.
+ (Contributed by James Hilton-Balfe in :gh:`128335`.)
New modules
===========
@@ -417,6 +431,32 @@ argparse
default to ``True``. This enables suggestions for mistyped arguments by default.
(Contributed by Jakob Schluse in :gh:`140450`.)
+* Added backtick markup support in description and epilog text to highlight
+ inline code when color output is enabled.
+ (Contributed by Savannah Ostrowski in :gh:`142390`.)
+
+base64
+------
+
+* Added the *pad* parameter in :func:`~base64.z85encode`.
+ (Contributed by Hauke Dämpfling in :gh:`143103`.)
+
+* Added the *wrapcol* parameter in :func:`~base64.b64encode`.
+ (Contributed by Serhiy Storchaka in :gh:`143214`.)
+
+* Added the *ignorechars* parameter in :func:`~base64.b64decode`.
+ (Contributed by Serhiy Storchaka in :gh:`144001`.)
+
+binascii
+--------
+
+* Added the *wrapcol* parameter in :func:`~binascii.b2a_base64`.
+ (Contributed by Serhiy Storchaka in :gh:`143214`.)
+
+* Added the *ignorechars* parameter in :func:`~binascii.a2b_base64`.
+ (Contributed by Serhiy Storchaka in :gh:`144001`.)
+
+
calendar
--------
@@ -551,6 +591,9 @@ locale
but included in the language code.
(Contributed by Serhiy Storchaka in :gh:`137729`.)
+* Undeprecate the :func:`locale.getdefaultlocale` function.
+ (Contributed by Victor Stinner in :gh:`130796`.)
+
math
----
@@ -565,8 +608,10 @@ math
mimetypes
---------
+* Add ``application/dicom`` MIME type for ``.dcm`` extension. (Contributed by Benedikt Johannes in :gh:`144217`.)
* Add ``application/node`` MIME type for ``.cjs`` extension. (Contributed by John Franey in :gh:`140937`.)
* Add ``application/toml``. (Contributed by Gil Forcada in :gh:`139959`.)
+* Add ``image/jxl``. (Contributed by Foolbar in :gh:`144213`.)
* Rename ``application/x-texinfo`` to ``application/texinfo``.
(Contributed by Charlie Lin in :gh:`140165`.)
* Changed the MIME type for ``.ai`` files to ``application/pdf``.
@@ -581,6 +626,11 @@ mmap
not be duplicated.
(Contributed by Serhiy Storchaka in :gh:`78502`.)
+* Added the :meth:`mmap.mmap.set_name` method
+ to annotate an anonymous memory mapping
+ if Linux kernel supports :manpage:`PR_SET_VMA_ANON_NAME ` (Linux 5.17 or newer).
+ (Contributed by Donghee Na in :gh:`142419`.)
+
os
--
@@ -693,6 +743,27 @@ ssl
(Contributed by Ron Frederick in :gh:`138252`.)
+subprocess
+----------
+
+* :meth:`subprocess.Popen.wait`: when ``timeout`` is not ``None`` and the
+ platform supports it, an efficient event-driven mechanism is used to wait for
+ process termination:
+
+ - Linux >= 5.3 uses :func:`os.pidfd_open` + :func:`select.poll`.
+ - macOS and other BSD variants use :func:`select.kqueue` + ``KQ_FILTER_PROC`` + ``KQ_NOTE_EXIT``.
+ - Windows keeps using ``WaitForSingleObject`` (unchanged).
+
+ If none of these mechanisms are available, the function falls back to the
+ traditional busy loop (non-blocking call and short sleeps).
+ (Contributed by Giampaolo Rodola in :gh:`83069`).
+
+symtable
+--------
+
+* Add :meth:`symtable.Function.get_cells` and :meth:`symtable.Symbol.is_cell` methods.
+ (Contributed by Yashp002 in :gh:`143504`.)
+
sys
---
@@ -749,6 +820,12 @@ tkinter
using Tcl's ``-all`` and ``-overlap`` options.
(Contributed by Rihaan Meher in :gh:`130848`)
+* Added new methods :meth:`!pack_content`, :meth:`!place_content` and
+ :meth:`!grid_content` which use Tk commands with new names (introduced
+ in Tk 8.6) instead of :meth:`!*_slaves` methods which use Tk commands
+ with outdated names.
+ (Contributed by Serhiy Storchaka in :gh:`143754`)
+
types
------
@@ -768,6 +845,16 @@ unicodedata
`Unicode Standard Annex #31 `_ identifier.
(Contributed by Stan Ulbrych in :gh:`129117`.)
+* Add the :func:`~unicodedata.iter_graphemes`
+ function to iterate over grapheme clusters according to rules defined in
+ `Unicode Standard Annex #29, "Unicode Text Segmentation"
+ `_.
+ Add :func:`~unicodedata.grapheme_cluster_break`,
+ :func:`~unicodedata.indic_conjunct_break` and
+ :func:`~unicodedata.extended_pictographic` functions to get the properties
+ of the character which are related to the above algorithm.
+ (Contributed by Serhiy Storchaka and Guillaume Sanchez in :gh:`74902`.)
+
unittest
--------
@@ -777,6 +864,18 @@ unittest
(Contributed by Garry Cairns in :gh:`134567`.)
+urllib.parse
+------------
+
+* Add the *missing_as_none* parameter to :func:`~urllib.parse.urlparse`,
+ :func:`~urllib.parse.urlsplit` and :func:`~urllib.parse.urldefrag` functions.
+ Add the *keep_empty* parameter to :func:`~urllib.parse.urlunparse` and
+ :func:`~urllib.parse.urlunsplit` functions.
+ This allows to distinguish between empty and not defined URI components
+ and preserve empty components.
+ (Contributed by Serhiy Storchaka in :gh:`67041`.)
+
+
venv
----
@@ -833,6 +932,25 @@ zlib
Optimizations
=============
+* Builds using Visual Studio 2026 (MSVC 18) may now use the new
+ :ref:`tail-calling interpreter `.
+ Results on Visual Studio 18.1.1 report between
+ `15-20% `__
+ speedup on the geometric mean of pyperformance on Windows x86-64 over
+ the switch-case interpreter on an AMD Ryzen 7 5800X. We have
+ observed speedups ranging from 14% for large pure-Python libraries
+ to 40% for long-running small pure-Python scripts on Windows.
+ This was made possible by a new feature introduced in MSVC 18.
+ (Contributed by Chris Eibl, Ken Jin, and Brandt Bucher in :gh:`143068`.
+ Special thanks to the MSVC team including Hulon Jenkins.)
+
+base64 & binascii
+-----------------
+
+* CPython's underlying base64 implementation now encodes 2x faster and decodes 3x
+ faster thanks to simple CPU pipelining optimizations.
+ (Contributed by Gregory P. Smith and Serhiy Storchaka in :gh:`143262`.)
+
csv
---
@@ -840,6 +958,95 @@ csv
(Contributed by Maurycy Pawłowski-Wieroński in :gh:`137628`.)
+.. _whatsnew315-jit:
+
+Upgraded JIT compiler
+=====================
+
+Results from the `pyperformance `__
+benchmark suite report
+`4-5% `__
+geometric mean performance improvement for the JIT over the standard CPython
+interpreter built with all optimizations enabled on x86-64 Linux. On AArch64
+macOS, the JIT has a
+`7-8% `__
+speedup over the :ref:`tail calling interpreter `
+with all optimizations enabled. The speedups for JIT
+builds versus no JIT builds range from roughly 15% slowdown to over
+100% speedup (ignoring the ``unpack_sequence`` microbenchmark) on
+x86-64 Linux and AArch64 macOS systems.
+
+.. attention::
+ These results are not yet final.
+
+The major upgrades to the JIT are:
+
+* LLVM 21 build-time dependency
+* New tracing frontend
+* Basic register allocation in the JIT
+* More JIT optimizations
+* Better machine code generation
+
+.. rubric:: LLVM 21 build-time dependency
+
+The JIT compiler now uses LLVM 21 for build-time stencil generation. As
+always, LLVM is only needed when building CPython with the JIT enabled;
+end users running Python do not need LLVM installed. Instructions for
+installing LLVM can be found in the `JIT compiler documentation
+`__
+for all supported platforms.
+
+(Contributed by Savannah Ostrowski in :gh:`140973`.)
+
+.. rubric:: A new tracing frontend
+
+The JIT compiler now supports significantly more bytecode operations and
+control flow than in Python 3.14, enabling speedups on a wider variety of
+code. For example, simple Python object creation is now understood by the
+3.15 JIT compiler. Overloaded operations and generators are also partially
+supported. This was made possible by an overhauled JIT tracing frontend
+that records actual execution paths through code, rather than estimating
+them as the previous implementation did.
+
+(Contributed by Ken Jin in :gh:`139109`. Support for Windows added by
+Mark Shannon in :gh:`141703`.)
+
+.. rubric:: Basic register allocation in the JIT
+
+A basic form of register allocation has been added to the JIT compiler's
+optimizer. This allows the JIT compiler to avoid certain stack operations
+altogether and instead operate on registers. This allows the JIT to produce
+more efficient traces by avoiding reads and writes to memory.
+
+(Contributed by Mark Shannon in :gh:`135379`.)
+
+.. rubric:: More JIT optimizations
+
+More `constant-propagation `__
+is now performed. This means when the JIT compiler detects that certain user
+code results in constants, the code can be simplified by the JIT.
+
+(Contributed by Ken Jin and Savannah Ostrowski in :gh:`132732`.)
+
+The JIT avoids :term:`reference count`\ s where possible. This generally
+reduces the cost of most operations in Python.
+
+(Contributed by Ken Jin, Donghee Na, Zheao Li, Hai Zhu, Savannah Ostrowski,
+Reiden Ong, Noam Cohen, Tomas Roun, PuQing, and Cajetan Rodrigues in :gh:`134584`.)
+
+.. rubric:: Better machine code generation
+
+The JIT compiler's machine code generator now produces better machine code
+for x86-64 and AArch64 macOS and Linux targets. In general, users should
+experience lower memory usage for generated machine code and more efficient
+machine code versus the old JIT.
+
+(Contributed by Brandt Bucher in :gh:`136528` and :gh:`136528`.
+Implementation for AArch64 contributed by Mark Shannon in :gh:`139855`.
+Additional optimizations for AArch64 contributed by Mark Shannon and
+Diego Russo in :gh:`140683` and :gh:`142305`.)
+
+
Removed
=======
@@ -982,6 +1189,15 @@ Deprecated
New deprecations
----------------
+* :mod:`base64`:
+
+ * Accepting the ``+`` and ``/`` characters with an alternative alphabet in
+ :func:`~base64.b64decode` and :func:`~base64.urlsafe_b64decode` is now
+ deprecated.
+ In future Python versions they will be errors in the strict mode and
+ discarded in the non-strict mode.
+ (Contributed by Serhiy Storchaka in :gh:`125346`.)
+
* CLI:
* Deprecate :option:`-b` and :option:`!-bb` command-line options
@@ -1008,14 +1224,16 @@ New deprecations
* ``__version__``
- * The ``__version__`` attribute has been deprecated in these standard library
- modules and will be removed in Python 3.20.
- Use :py:data:`sys.version_info` instead.
+ * The ``__version__``, ``version`` and ``VERSION`` attributes have been
+ deprecated in these standard library modules and will be removed in
+ Python 3.20. Use :py:data:`sys.version_info` instead.
- :mod:`argparse`
- :mod:`csv`
+ - :mod:`ctypes`
- :mod:`!ctypes.macholib`
- :mod:`decimal` (use :data:`decimal.SPEC_VERSION` instead)
+ - :mod:`http.server`
- :mod:`imaplib`
- :mod:`ipaddress`
- :mod:`json`
@@ -1028,6 +1246,10 @@ New deprecations
- :mod:`tabnanny`
- :mod:`tkinter.font`
- :mod:`tkinter.ttk`
+ - :mod:`wsgiref.simple_server`
+ - :mod:`xml.etree.ElementTree`
+ - :mod:`!xml.sax.expatreader`
+ - :mod:`xml.sax.handler`
- :mod:`zlib`
(Contributed by Hugo van Kemenade and Stan Ulbrych in :gh:`76007`.)
@@ -1038,6 +1260,8 @@ New deprecations
.. include:: ../deprecations/pending-removal-in-3.17.rst
+.. include:: ../deprecations/pending-removal-in-3.18.rst
+
.. include:: ../deprecations/pending-removal-in-3.19.rst
.. include:: ../deprecations/pending-removal-in-3.20.rst
@@ -1092,7 +1316,7 @@ New features
* Add :c:func:`PyTuple_FromArray` to create a :class:`tuple` from an array.
(Contributed by Victor Stinner in :gh:`111489`.)
-* Add :c:func:`PyUnstable_Object_Dump` to dump an object to ``stderr``.
+* Add :c:func:`PyObject_Dump` to dump an object to ``stderr``.
It should only be used for debugging.
(Contributed by Victor Stinner in :gh:`141070`.)
@@ -1204,6 +1428,13 @@ Deprecated C APIs
use the :c:type:`PyBytesWriter` API instead.
(Contributed by Victor Stinner in :gh:`129813`.)
+* :c:func:`!_PyObject_CallMethodId`, :c:func:`!_PyObject_GetAttrId` and
+ :c:func:`!_PyUnicode_FromId` are deprecated since 3.15 and will be removed in
+ 3.20. Instead, use :c:func:`PyUnicode_InternFromString()` and cache the result in
+ the module state, then call :c:func:`PyObject_CallMethod` or
+ :c:func:`PyObject_GetAttr`.
+ (Contributed by Victor Stinner in :gh:`141049`.)
+
* Deprecate :c:member:`~PyComplexObject.cval` field of the
:c:type:`PyComplexObject` type.
Use :c:func:`PyComplex_AsCComplex` and :c:func:`PyComplex_FromCComplex`
@@ -1246,6 +1477,14 @@ Build changes
modules that are missing or packaged separately.
(Contributed by Stan Ulbrych and Petr Viktorin in :gh:`139707`.)
+* The new configure option :option:`--with-pymalloc-hugepages` enables huge
+ page support for :ref:`pymalloc ` arenas. When enabled, arena size
+ increases to 2 MiB and allocation uses ``MAP_HUGETLB`` (Linux) or
+ ``MEM_LARGE_PAGES`` (Windows) with automatic fallback to regular pages.
+ On Windows, use ``build.bat --pymalloc-hugepages``.
+ At runtime, huge pages must be explicitly enabled by setting the
+ :envvar:`PYTHON_PYMALLOC_HUGEPAGES` environment variable to ``1``.
+
* Annotating anonymous mmap usage is now supported if Linux kernel supports
:manpage:`PR_SET_VMA_ANON_NAME ` (Linux 5.17 or newer).
Annotations are visible in ``/proc//maps`` if the kernel supports the feature
@@ -1276,7 +1515,7 @@ that may require changes to your code.
:func:`resource.setrlimit` and :func:`resource.prlimit` is now deprecated.
(Contributed by Serhiy Storchaka in :gh:`137044`.)
-* :meth:`~mmap.mmap.resize` has been removed on platforms that don't support the
+* :meth:`mmap.mmap.resize` has been removed on platforms that don't support the
underlying syscall, instead of raising a :exc:`SystemError`.
* A resource warning is now emitted for an unclosed
diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst
index 47c4d9acbc870e..3b13d90f7692cd 100644
--- a/Doc/whatsnew/3.2.rst
+++ b/Doc/whatsnew/3.2.rst
@@ -312,7 +312,7 @@ cluttering source directories, the *pyc* files are now collected in a
Aside from the filenames and target directories, the new scheme has a few
aspects that are visible to the programmer:
-* Imported modules now have a :attr:`~module.__cached__` attribute which stores
+* Imported modules now have a ``__cached__`` attribute which stores
the name of the actual file that was imported:
>>> import collections
diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst
index 32ca965b7d0ed0..5dd47cdac96a5c 100644
--- a/Doc/whatsnew/3.7.rst
+++ b/Doc/whatsnew/3.7.rst
@@ -604,7 +604,7 @@ new ABC for access to, opening, and reading *resources* inside packages.
Resources are roughly similar to files inside packages, but they needn't
be actual files on the physical file system. Module loaders can provide a
:meth:`!get_resource_reader` function which returns
-a :class:`importlib.abc.ResourceReader` instance to support this
+a :class:`!importlib.abc.ResourceReader` instance to support this
new API. Built-in file path loaders and zip file loaders both support this.
Contributed by Barry Warsaw and Brett Cannon in :issue:`32248`.
@@ -1043,7 +1043,7 @@ window are shown and hidden in the Options menu.
importlib
---------
-The :class:`importlib.abc.ResourceReader` ABC was introduced to
+The :class:`!importlib.abc.ResourceReader` ABC was introduced to
support the loading of resources from packages. See also
:ref:`whatsnew37_importlib_resources`.
(Contributed by Barry Warsaw, Brett Cannon in :issue:`32248`.)
@@ -2032,7 +2032,7 @@ both deprecated in Python 3.4 now emit :exc:`DeprecationWarning`.
(Contributed by Matthias Bussonnier in :issue:`29576`.)
The :class:`importlib.abc.ResourceLoader` ABC has been deprecated in
-favour of :class:`importlib.abc.ResourceReader`.
+favour of :class:`!importlib.abc.ResourceReader`.
locale
diff --git a/Include/cpython/abstract.h b/Include/cpython/abstract.h
index ffd19ccd3500fa..7490ece52e5220 100644
--- a/Include/cpython/abstract.h
+++ b/Include/cpython/abstract.h
@@ -6,7 +6,7 @@
/* Like PyObject_CallMethod(), but expect a _Py_Identifier*
as the method name. */
-PyAPI_FUNC(PyObject*) _PyObject_CallMethodId(
+Py_DEPRECATED(3.15) PyAPI_FUNC(PyObject*) _PyObject_CallMethodId(
PyObject *obj,
_Py_Identifier *name,
const char *format, ...);
diff --git a/Include/cpython/initconfig.h b/Include/cpython/initconfig.h
index 1c979d91a40850..5606ebeb7c95e0 100644
--- a/Include/cpython/initconfig.h
+++ b/Include/cpython/initconfig.h
@@ -149,6 +149,7 @@ typedef struct PyConfig {
int dump_refs;
wchar_t *dump_refs_file;
int malloc_stats;
+ int pymalloc_hugepages;
wchar_t *filesystem_encoding;
wchar_t *filesystem_errors;
wchar_t *pycache_prefix;
diff --git a/Include/cpython/longintrepr.h b/Include/cpython/longintrepr.h
index 4b6f97a5e475d6..804c1e9427e063 100644
--- a/Include/cpython/longintrepr.h
+++ b/Include/cpython/longintrepr.h
@@ -138,45 +138,6 @@ _PyLong_CompactValue(const PyLongObject *op)
#define PyUnstable_Long_CompactValue _PyLong_CompactValue
-
-/* --- Import/Export API -------------------------------------------------- */
-
-typedef struct PyLongLayout {
- uint8_t bits_per_digit;
- uint8_t digit_size;
- int8_t digits_order;
- int8_t digit_endianness;
-} PyLongLayout;
-
-PyAPI_FUNC(const PyLongLayout*) PyLong_GetNativeLayout(void);
-
-typedef struct PyLongExport {
- int64_t value;
- uint8_t negative;
- Py_ssize_t ndigits;
- const void *digits;
- // Member used internally, must not be used for other purpose.
- Py_uintptr_t _reserved;
-} PyLongExport;
-
-PyAPI_FUNC(int) PyLong_Export(
- PyObject *obj,
- PyLongExport *export_long);
-PyAPI_FUNC(void) PyLong_FreeExport(
- PyLongExport *export_long);
-
-
-/* --- PyLongWriter API --------------------------------------------------- */
-
-typedef struct PyLongWriter PyLongWriter;
-
-PyAPI_FUNC(PyLongWriter*) PyLongWriter_Create(
- int negative,
- Py_ssize_t ndigits,
- void **digits);
-PyAPI_FUNC(PyObject*) PyLongWriter_Finish(PyLongWriter *writer);
-PyAPI_FUNC(void) PyLongWriter_Discard(PyLongWriter *writer);
-
#ifdef __cplusplus
}
#endif
diff --git a/Include/cpython/object.h b/Include/cpython/object.h
index 8693390aeda624..28c909531dba64 100644
--- a/Include/cpython/object.h
+++ b/Include/cpython/object.h
@@ -295,12 +295,12 @@ PyAPI_FUNC(PyObject *) PyType_GetDict(PyTypeObject *);
PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int);
PyAPI_FUNC(void) _Py_BreakPoint(void);
-PyAPI_FUNC(void) PyUnstable_Object_Dump(PyObject *);
+PyAPI_FUNC(void) PyObject_Dump(PyObject *);
// Alias for backward compatibility
-#define _PyObject_Dump PyUnstable_Object_Dump
+#define _PyObject_Dump PyObject_Dump
-PyAPI_FUNC(PyObject*) _PyObject_GetAttrId(PyObject *, _Py_Identifier *);
+Py_DEPRECATED(3.15) PyAPI_FUNC(PyObject*) _PyObject_GetAttrId(PyObject *, _Py_Identifier *);
PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *);
PyAPI_FUNC(void) PyObject_CallFinalizer(PyObject *);
@@ -391,7 +391,7 @@ PyAPI_FUNC(PyObject *) _PyObject_FunctionStr(PyObject *);
but compile away to nothing if NDEBUG is defined.
However, before aborting, Python will also try to call
- PyUnstable_Object_Dump() on the given object. This may be of use when
+ PyObject_Dump() on the given object. This may be of use when
investigating bugs in which a particular object is corrupt (e.g. buggy a
tp_visit method in an extension module breaking the garbage collector), to
help locate the broken objects.
diff --git a/Include/cpython/pyatomic.h b/Include/cpython/pyatomic.h
index 2a0c11e7b3ad66..ce907fd6a4c453 100644
--- a/Include/cpython/pyatomic.h
+++ b/Include/cpython/pyatomic.h
@@ -523,6 +523,9 @@ _Py_atomic_store_uintptr_release(uintptr_t *obj, uintptr_t value);
static inline void
_Py_atomic_store_ssize_release(Py_ssize_t *obj, Py_ssize_t value);
+static inline void
+_Py_atomic_store_int8_release(int8_t *obj, int8_t value);
+
static inline void
_Py_atomic_store_int_release(int *obj, int value);
@@ -591,6 +594,17 @@ static inline void _Py_atomic_fence_release(void);
// --- aliases ---------------------------------------------------------------
+// Compilers don't really support "consume" semantics, so we fake it. Use
+// "acquire" with TSan to support false positives. Use "relaxed" otherwise,
+// because CPUs on all platforms we support respect address dependencies without
+// extra barriers.
+// See 2.6.7 in https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2055r0.pdf
+#if defined(_Py_THREAD_SANITIZER)
+# define _Py_atomic_load_ptr_consume _Py_atomic_load_ptr_acquire
+#else
+# define _Py_atomic_load_ptr_consume _Py_atomic_load_ptr_relaxed
+#endif
+
#if SIZEOF_LONG == 8
# define _Py_atomic_load_ulong(p) \
_Py_atomic_load_uint64((uint64_t *)p)
diff --git a/Include/cpython/pyatomic_gcc.h b/Include/cpython/pyatomic_gcc.h
index 1566b83b9f6a1b..c045213c898a03 100644
--- a/Include/cpython/pyatomic_gcc.h
+++ b/Include/cpython/pyatomic_gcc.h
@@ -572,6 +572,10 @@ static inline void
_Py_atomic_store_int_release(int *obj, int value)
{ __atomic_store_n(obj, value, __ATOMIC_RELEASE); }
+static inline void
+_Py_atomic_store_int8_release(int8_t *obj, int8_t value)
+{ __atomic_store_n(obj, value, __ATOMIC_RELEASE); }
+
static inline void
_Py_atomic_store_ssize_release(Py_ssize_t *obj, Py_ssize_t value)
{ __atomic_store_n(obj, value, __ATOMIC_RELEASE); }
diff --git a/Include/cpython/pyatomic_msc.h b/Include/cpython/pyatomic_msc.h
index d155955df0cddf..8b9dd3eb0f8e16 100644
--- a/Include/cpython/pyatomic_msc.h
+++ b/Include/cpython/pyatomic_msc.h
@@ -1066,6 +1066,19 @@ _Py_atomic_store_int_release(int *obj, int value)
#endif
}
+static inline void
+_Py_atomic_store_int8_release(int8_t *obj, int8_t value)
+{
+#if defined(_M_X64) || defined(_M_IX86)
+ *(int8_t volatile *)obj = value;
+#elif defined(_M_ARM64)
+ _Py_atomic_ASSERT_ARG_TYPE(unsigned __int8);
+ __stlr8((unsigned __int8 volatile *)obj, (unsigned __int8)value);
+#else
+# error "no implementation of _Py_atomic_store_int8_release"
+#endif
+}
+
static inline void
_Py_atomic_store_ssize_release(Py_ssize_t *obj, Py_ssize_t value)
{
diff --git a/Include/cpython/pyatomic_std.h b/Include/cpython/pyatomic_std.h
index 7176f667a4082c..cfc8dbefc63d09 100644
--- a/Include/cpython/pyatomic_std.h
+++ b/Include/cpython/pyatomic_std.h
@@ -1023,6 +1023,14 @@ _Py_atomic_store_int_release(int *obj, int value)
memory_order_release);
}
+static inline void
+_Py_atomic_store_int8_release(int8_t *obj, int8_t value)
+{
+ _Py_USING_STD;
+ atomic_store_explicit((_Atomic(int8_t)*)obj, value,
+ memory_order_release);
+}
+
static inline void
_Py_atomic_store_uint_release(unsigned int *obj, unsigned int value)
{
diff --git a/Include/cpython/unicodeobject.h b/Include/cpython/unicodeobject.h
index 2853d24c34b66e..631a6570658410 100644
--- a/Include/cpython/unicodeobject.h
+++ b/Include/cpython/unicodeobject.h
@@ -778,4 +778,4 @@ static inline int Py_UNICODE_ISALNUM(Py_UCS4 ch) {
// Return an interned Unicode object for an Identifier; may fail if there is no
// memory.
-PyAPI_FUNC(PyObject*) _PyUnicode_FromId(_Py_Identifier*);
+Py_DEPRECATED(3.15) PyAPI_FUNC(PyObject*) _PyUnicode_FromId(_Py_Identifier*);
diff --git a/Include/descrobject.h b/Include/descrobject.h
index fd66d17b497a31..340de4e0e1e6ff 100644
--- a/Include/descrobject.h
+++ b/Include/descrobject.h
@@ -80,10 +80,14 @@ struct PyMemberDef {
#define _Py_T_NONE 20 // Deprecated. Value is always None.
/* Flags */
-#define Py_READONLY 1
-#define Py_AUDIT_READ 2 // Added in 3.10, harmless no-op before that
-#define _Py_WRITE_RESTRICTED 4 // Deprecated, no-op. Do not reuse the value.
-#define Py_RELATIVE_OFFSET 8
+#define Py_READONLY (1 << 0)
+#define Py_AUDIT_READ (1 << 1) // Added in 3.10, harmless no-op before that
+#define _Py_WRITE_RESTRICTED (1 << 2) // Deprecated, no-op. Do not reuse the value.
+#define Py_RELATIVE_OFFSET (1 << 3)
+
+#ifndef Py_LIMITED_API
+# define _Py_AFTER_ITEMS (1 << 4) // For internal use.
+#endif
PyAPI_FUNC(PyObject *) PyMember_GetOne(const char *, PyMemberDef *);
PyAPI_FUNC(int) PyMember_SetOne(char *, PyMemberDef *, PyObject *);
diff --git a/Include/exports.h b/Include/exports.h
index 62feb09ed2b433..97a674ec2403a4 100644
--- a/Include/exports.h
+++ b/Include/exports.h
@@ -35,6 +35,12 @@
#define Py_EXPORTED_SYMBOL
#define Py_LOCAL_SYMBOL
#endif
+ /* module init functions outside the core must be exported */
+ #if defined(Py_BUILD_CORE)
+ #define _PyINIT_EXPORTED_SYMBOL Py_EXPORTED_SYMBOL
+ #else
+ #define _PyINIT_EXPORTED_SYMBOL __declspec(dllexport)
+ #endif
#else
/*
* If we only ever used gcc >= 5, we could use __has_attribute(visibility)
@@ -52,19 +58,16 @@
#define Py_EXPORTED_SYMBOL
#define Py_LOCAL_SYMBOL
#endif
+ #define _PyINIT_EXPORTED_SYMBOL Py_EXPORTED_SYMBOL
#endif
/* only get special linkage if built as shared or platform is Cygwin */
#if defined(Py_ENABLE_SHARED) || defined(__CYGWIN__)
# if defined(HAVE_DECLSPEC_DLL)
# if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
-# define PyAPI_FUNC(RTYPE) Py_EXPORTED_SYMBOL RTYPE
-# define PyAPI_DATA(RTYPE) extern Py_EXPORTED_SYMBOL RTYPE
/* module init functions inside the core need no external linkage */
/* except for Cygwin to handle embedding */
-# if defined(__CYGWIN__)
-# define _PyINIT_FUNC_DECLSPEC Py_EXPORTED_SYMBOL
-# else /* __CYGWIN__ */
+# if !defined(__CYGWIN__)
# define _PyINIT_FUNC_DECLSPEC
# endif /* __CYGWIN__ */
# else /* Py_BUILD_CORE */
@@ -77,12 +80,6 @@
# define PyAPI_FUNC(RTYPE) Py_IMPORTED_SYMBOL RTYPE
# endif /* !__CYGWIN__ */
# define PyAPI_DATA(RTYPE) extern Py_IMPORTED_SYMBOL RTYPE
- /* module init functions outside the core must be exported */
-# if defined(__cplusplus)
-# define _PyINIT_FUNC_DECLSPEC extern "C" Py_EXPORTED_SYMBOL
-# else /* __cplusplus */
-# define _PyINIT_FUNC_DECLSPEC Py_EXPORTED_SYMBOL
-# endif /* __cplusplus */
# endif /* Py_BUILD_CORE */
# endif /* HAVE_DECLSPEC_DLL */
#endif /* Py_ENABLE_SHARED */
@@ -96,13 +93,17 @@
#endif
#ifndef _PyINIT_FUNC_DECLSPEC
# if defined(__cplusplus)
-# define _PyINIT_FUNC_DECLSPEC extern "C" Py_EXPORTED_SYMBOL
+# define _PyINIT_FUNC_DECLSPEC extern "C" _PyINIT_EXPORTED_SYMBOL
# else /* __cplusplus */
-# define _PyINIT_FUNC_DECLSPEC Py_EXPORTED_SYMBOL
+# define _PyINIT_FUNC_DECLSPEC _PyINIT_EXPORTED_SYMBOL
# endif /* __cplusplus */
#endif
-#define PyMODINIT_FUNC _PyINIT_FUNC_DECLSPEC PyObject*
-#define PyMODEXPORT_FUNC _PyINIT_FUNC_DECLSPEC PyModuleDef_Slot*
+#ifndef PyMODINIT_FUNC
+ #define PyMODINIT_FUNC _PyINIT_FUNC_DECLSPEC PyObject*
+#endif
+#ifndef PyMODEXPORT_FUNC
+ #define PyMODEXPORT_FUNC _PyINIT_FUNC_DECLSPEC PyModuleDef_Slot*
+#endif
#endif /* Py_EXPORTS_H */
diff --git a/Include/internal/pycore_backoff.h b/Include/internal/pycore_backoff.h
index 23ca7299e0d2bd..ee907ae0534e4f 100644
--- a/Include/internal/pycore_backoff.h
+++ b/Include/internal/pycore_backoff.h
@@ -12,6 +12,7 @@ extern "C" {
#include
#include
#include "pycore_structs.h" // _Py_BackoffCounter
+#include "pycore_interp_structs.h" // _PyOptimizationConfig
/* 16-bit countdown counters using exponential backoff.
@@ -127,10 +128,11 @@ trigger_backoff_counter(void)
#define JUMP_BACKWARD_INITIAL_VALUE 4000
#define JUMP_BACKWARD_INITIAL_BACKOFF 6
static inline _Py_BackoffCounter
-initial_jump_backoff_counter(void)
+initial_jump_backoff_counter(_PyOptimizationConfig *opt_config)
{
- return make_backoff_counter(JUMP_BACKWARD_INITIAL_VALUE,
- JUMP_BACKWARD_INITIAL_BACKOFF);
+ return make_backoff_counter(
+ opt_config->jump_backward_initial_value,
+ opt_config->jump_backward_initial_backoff);
}
/* Initial exit temperature.
@@ -141,10 +143,11 @@ initial_jump_backoff_counter(void)
#define SIDE_EXIT_INITIAL_BACKOFF 6
static inline _Py_BackoffCounter
-initial_temperature_backoff_counter(void)
+initial_temperature_backoff_counter(_PyOptimizationConfig *opt_config)
{
- return make_backoff_counter(SIDE_EXIT_INITIAL_VALUE,
- SIDE_EXIT_INITIAL_BACKOFF);
+ return make_backoff_counter(
+ opt_config->side_exit_initial_value,
+ opt_config->side_exit_initial_backoff);
}
/* Unreachable backoff counter. */
diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h
index 6bf33bddd5b877..f6bdba3e9916c0 100644
--- a/Include/internal/pycore_ceval.h
+++ b/Include/internal/pycore_ceval.h
@@ -103,7 +103,6 @@ extern int _PyPerfTrampoline_SetCallbacks(_PyPerf_Callbacks *);
extern void _PyPerfTrampoline_GetCallbacks(_PyPerf_Callbacks *);
extern int _PyPerfTrampoline_Init(int activate);
extern int _PyPerfTrampoline_Fini(void);
-extern void _PyPerfTrampoline_FreeArenas(void);
extern int _PyIsPerfTrampolineActive(void);
extern PyStatus _PyPerfTrampoline_AfterFork_Child(void);
#ifdef PY_HAVE_PERF_TRAMPOLINE
@@ -123,7 +122,7 @@ _PyEval_EvalFrame(PyThreadState *tstate, _PyInterpreterFrame *frame, int throwfl
#ifdef _Py_TIER2
#ifdef _Py_JIT
-_Py_CODEUNIT *_Py_LazyJitTrampoline(
+_Py_CODEUNIT *_Py_LazyJitShim(
struct _PyExecutorObject *current_executor, _PyInterpreterFrame *frame,
_PyStackRef *stack_pointer, PyThreadState *tstate
);
@@ -377,8 +376,6 @@ _Py_eval_breaker_bit_is_set(PyThreadState *tstate, uintptr_t bit)
void _Py_set_eval_breaker_bit_all(PyInterpreterState *interp, uintptr_t bit);
void _Py_unset_eval_breaker_bit_all(PyInterpreterState *interp, uintptr_t bit);
-PyAPI_FUNC(_PyStackRef) _PyFloat_FromDouble_ConsumeInputs(_PyStackRef left, _PyStackRef right, double value);
-
#ifndef Py_SUPPORTS_REMOTE_DEBUG
#if defined(__APPLE__)
#include
@@ -417,6 +414,17 @@ _Py_VectorCall_StackRefSteal(
int total_args,
_PyStackRef kwnames);
+PyAPI_FUNC(PyObject*)
+_Py_VectorCallInstrumentation_StackRefSteal(
+ _PyStackRef callable,
+ _PyStackRef* arguments,
+ int total_args,
+ _PyStackRef kwnames,
+ bool call_instrumentation,
+ _PyInterpreterFrame* frame,
+ _Py_CODEUNIT* this_instr,
+ PyThreadState* tstate);
+
PyAPI_FUNC(PyObject *)
_Py_BuiltinCallFast_StackRefSteal(
_PyStackRef callable,
@@ -466,6 +474,11 @@ _Py_assert_within_stack_bounds(
_PyInterpreterFrame *frame, _PyStackRef *stack_pointer,
const char *filename, int lineno);
+// Like PyMapping_GetOptionalItem, but returns the PyObject* instead of taking
+// it as an out parameter. This helps MSVC's escape analysis when used with
+// tail calling.
+PyAPI_FUNC(PyObject*) _PyMapping_GetOptionalItem2(PyObject* obj, PyObject* key, int* err);
+
#ifdef __cplusplus
}
#endif
diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h
index cb9c0aa27a1785..efae3b38654c41 100644
--- a/Include/internal/pycore_code.h
+++ b/Include/internal/pycore_code.h
@@ -160,6 +160,12 @@ typedef struct {
#define INLINE_CACHE_ENTRIES_CONTAINS_OP CACHE_ENTRIES(_PyContainsOpCache)
+typedef struct {
+ _Py_BackoffCounter counter;
+} _PyCallFunctionExCache;
+
+#define INLINE_CACHE_ENTRIES_CALL_FUNCTION_EX CACHE_ENTRIES(_PyCallFunctionExCache)
+
/* "Locals plus" for a code object is the set of locals + cell vars +
* free vars. This relates to variable names as well as offsets into
* the "fast locals" storage array of execution frames. The compiler
@@ -286,17 +292,7 @@ extern int _PyCode_SafeAddr2Line(PyCodeObject *co, int addr);
extern void _PyCode_Clear_Executors(PyCodeObject *code);
-#ifdef Py_GIL_DISABLED
-// gh-115999 tracks progress on addressing this.
-#define ENABLE_SPECIALIZATION 0
-// Use this to enable specialization families once they are thread-safe. All
-// uses will be replaced with ENABLE_SPECIALIZATION once all families are
-// thread-safe.
-#define ENABLE_SPECIALIZATION_FT 1
-#else
#define ENABLE_SPECIALIZATION 1
-#define ENABLE_SPECIALIZATION_FT ENABLE_SPECIALIZATION
-#endif
/* Specialization functions, these are exported only for other re-generated
* interpreters to call */
@@ -326,6 +322,7 @@ PyAPI_FUNC(void) _Py_Specialize_Send(_PyStackRef receiver, _Py_CODEUNIT *instr);
PyAPI_FUNC(void) _Py_Specialize_ToBool(_PyStackRef value, _Py_CODEUNIT *instr);
PyAPI_FUNC(void) _Py_Specialize_ContainsOp(_PyStackRef value, _Py_CODEUNIT *instr);
PyAPI_FUNC(void) _Py_GatherStats_GetIter(_PyStackRef iterable);
+PyAPI_FUNC(void) _Py_Specialize_CallFunctionEx(_PyStackRef func_st, _Py_CODEUNIT *instr);
// Utility functions for reading/writing 32/64-bit values in the inline caches.
// Great care should be taken to ensure that these functions remain correct and
@@ -556,7 +553,7 @@ _PyCode_GetTLBCFast(PyThreadState *tstate, PyCodeObject *co)
// Return a pointer to the thread-local bytecode for the current thread,
// creating it if necessary.
-extern _Py_CODEUNIT *_PyCode_GetTLBC(PyCodeObject *co);
+PyAPI_FUNC(_Py_CODEUNIT *) _PyCode_GetTLBC(PyCodeObject *co);
// Reserve an index for the current thread into thread-local bytecode
// arrays
diff --git a/Include/internal/pycore_context.h b/Include/internal/pycore_context.h
index c77ef7910c09aa..a833f790a621b1 100644
--- a/Include/internal/pycore_context.h
+++ b/Include/internal/pycore_context.h
@@ -55,5 +55,8 @@ struct _pycontexttokenobject {
// Export for '_testcapi' shared extension
PyAPI_FUNC(PyObject*) _PyContext_NewHamtForTests(void);
+PyAPI_FUNC(int) _PyContext_Enter(PyThreadState *ts, PyObject *octx);
+PyAPI_FUNC(int) _PyContext_Exit(PyThreadState *ts, PyObject *octx);
+
#endif /* !Py_INTERNAL_CONTEXT_H */
diff --git a/Include/internal/pycore_debug_offsets.h b/Include/internal/pycore_debug_offsets.h
index 1cdc4449b173e8..66f14e69f33f44 100644
--- a/Include/internal/pycore_debug_offsets.h
+++ b/Include/internal/pycore_debug_offsets.h
@@ -110,8 +110,15 @@ typedef struct _Py_DebugOffsets {
uint64_t status;
uint64_t holds_gil;
uint64_t gil_requested;
+ uint64_t current_exception;
+ uint64_t exc_state;
} thread_state;
+ // Exception stack item offset
+ struct {
+ uint64_t exc_value;
+ } err_stackitem;
+
// InterpreterFrame offset;
struct _interpreter_frame {
uint64_t size;
@@ -282,6 +289,11 @@ typedef struct _Py_DebugOffsets {
.status = offsetof(PyThreadState, _status), \
.holds_gil = offsetof(PyThreadState, holds_gil), \
.gil_requested = offsetof(PyThreadState, gil_requested), \
+ .current_exception = offsetof(PyThreadState, current_exception), \
+ .exc_state = offsetof(PyThreadState, exc_state), \
+ }, \
+ .err_stackitem = { \
+ .exc_value = offsetof(_PyErr_StackItem, exc_value), \
}, \
.interpreter_frame = { \
.size = sizeof(_PyInterpreterFrame), \
diff --git a/Include/internal/pycore_descrobject.h b/Include/internal/pycore_descrobject.h
index 3cec59a68a3d2b..6143f82176a1f2 100644
--- a/Include/internal/pycore_descrobject.h
+++ b/Include/internal/pycore_descrobject.h
@@ -22,6 +22,8 @@ typedef propertyobject _PyPropertyObject;
extern PyTypeObject _PyMethodWrapper_Type;
+extern void *_PyMember_GetOffset(PyObject *, PyMemberDef *);
+
#ifdef __cplusplus
}
#endif
diff --git a/Include/internal/pycore_dict.h b/Include/internal/pycore_dict.h
index 1193f496da132d..950547cb002f4c 100644
--- a/Include/internal/pycore_dict.h
+++ b/Include/internal/pycore_dict.h
@@ -114,6 +114,7 @@ extern Py_ssize_t _Py_dict_lookup_threadsafe_stackref(PyDictObject *mp, PyObject
extern int _PyDict_GetMethodStackRef(PyDictObject *dict, PyObject *name, _PyStackRef *method);
+extern Py_ssize_t _PyDict_LookupIndexAndValue(PyDictObject *, PyObject *, PyObject **);
extern Py_ssize_t _PyDict_LookupIndex(PyDictObject *, PyObject *);
extern Py_ssize_t _PyDictKeys_StringLookup(PyDictKeysObject* dictkeys, PyObject *key);
@@ -272,8 +273,7 @@ _PyDict_SendEvent(int watcher_bits,
PyObject *value);
static inline void
-_PyDict_NotifyEvent(PyInterpreterState *interp,
- PyDict_WatchEvent event,
+_PyDict_NotifyEvent(PyDict_WatchEvent event,
PyDictObject *mp,
PyObject *key,
PyObject *value)
diff --git a/Include/internal/pycore_flowgraph.h b/Include/internal/pycore_flowgraph.h
index 5043260d2fd99f..fc3ae6b369c54c 100644
--- a/Include/internal/pycore_flowgraph.h
+++ b/Include/internal/pycore_flowgraph.h
@@ -27,7 +27,7 @@ int _PyCfg_OptimizeCodeUnit(struct _PyCfgBuilder *g, PyObject *consts, PyObject
struct _PyCfgBuilder* _PyCfg_FromInstructionSequence(_PyInstructionSequence *seq);
int _PyCfg_ToInstructionSequence(struct _PyCfgBuilder *g, _PyInstructionSequence *seq);
int _PyCfg_OptimizedCfgToInstructionSequence(struct _PyCfgBuilder *g, _PyCompile_CodeUnitMetadata *umd,
- int code_flags, int *stackdepth, int *nlocalsplus,
+ int *stackdepth, int *nlocalsplus,
_PyInstructionSequence *seq);
PyCodeObject *
diff --git a/Include/internal/pycore_frame.h b/Include/internal/pycore_frame.h
index 8c410e9e208340..50908f2cb7a1d2 100644
--- a/Include/internal/pycore_frame.h
+++ b/Include/internal/pycore_frame.h
@@ -44,15 +44,16 @@ extern PyFrameObject* _PyFrame_New_NoTrack(PyCodeObject *code);
/* other API */
typedef enum _framestate {
- FRAME_CREATED = -3,
- FRAME_SUSPENDED = -2,
- FRAME_SUSPENDED_YIELD_FROM = -1,
+ FRAME_CREATED = -4,
+ FRAME_SUSPENDED = -3,
+ FRAME_SUSPENDED_YIELD_FROM = -2,
+ FRAME_SUSPENDED_YIELD_FROM_LOCKED = -1,
FRAME_EXECUTING = 0,
FRAME_COMPLETED = 1,
FRAME_CLEARED = 4
} PyFrameState;
-#define FRAME_STATE_SUSPENDED(S) ((S) == FRAME_SUSPENDED || (S) == FRAME_SUSPENDED_YIELD_FROM)
+#define FRAME_STATE_SUSPENDED(S) ((S) >= FRAME_SUSPENDED && (S) <= FRAME_SUSPENDED_YIELD_FROM_LOCKED)
#define FRAME_STATE_FINISHED(S) ((S) >= FRAME_COMPLETED)
#ifdef __cplusplus
diff --git a/Include/internal/pycore_genobject.h b/Include/internal/pycore_genobject.h
index b08c8c52221f4b..a3badb59cb771a 100644
--- a/Include/internal/pycore_genobject.h
+++ b/Include/internal/pycore_genobject.h
@@ -22,7 +22,7 @@ PyGenObject *_PyGen_GetGeneratorFromFrame(_PyInterpreterFrame *frame)
}
PyAPI_FUNC(PyObject *)_PyGen_yf(PyGenObject *);
-extern void _PyGen_Finalize(PyObject *self);
+extern int _PyGen_ClearFrame(PyGenObject *self);
// Export for '_asyncio' shared extension
PyAPI_FUNC(int) _PyGen_SetStopIterationValue(PyObject *);
diff --git a/Include/internal/pycore_global_objects_fini_generated.h b/Include/internal/pycore_global_objects_fini_generated.h
index 6473a3c64a6c23..fc297a2933a786 100644
--- a/Include/internal/pycore_global_objects_fini_generated.h
+++ b/Include/internal/pycore_global_objects_fini_generated.h
@@ -13,7 +13,7 @@ static inline void
_PyStaticObject_CheckRefcnt(PyObject *obj) {
if (!_Py_IsImmortal(obj)) {
fprintf(stderr, "Immortal Object has less refcnt than expected.\n");
- PyUnstable_Object_Dump(obj);
+ PyObject_Dump(obj);
}
}
#endif
@@ -1653,9 +1653,11 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_varnames));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(code));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(col_offset));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(collector));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(command));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(comment_factory));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(compile_mode));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(compression));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(config));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(consts));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(context));
@@ -1718,7 +1720,9 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(event));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(eventmask));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(exc));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(exc_tb));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(exc_type));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(exc_val));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(exc_value));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(excepthook));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(exception));
@@ -1793,6 +1797,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ident));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(identity_hint));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ignore));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ignorechars));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(imag));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(implieslink));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(importlib));
@@ -1974,6 +1979,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(print_file_and_line));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(priority));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(progress));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(progress_callback));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(progress_routine));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(proto));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(protocol));
@@ -1994,6 +2000,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(readline));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(readonly));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(real));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(recursive));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(reducer_override));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(registry));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(rel_tol));
@@ -2013,6 +2020,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(reversed));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(rounding));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(salt));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sample_interval_us));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sched_priority));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(scheduler));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(script));
@@ -2052,8 +2060,10 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(spam));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(src));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(src_dir_fd));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(stack_frames));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(stacklevel));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(start));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(start_time_us));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(statement));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(stats));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(status));
@@ -2094,6 +2104,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(times));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(timespec));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(timestamp));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(timestamp_us));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(timetuple));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(timeunit));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(top));
@@ -2132,6 +2143,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(which));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(who));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(withdata));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(wrapcol));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(writable));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(write));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(write_through));
diff --git a/Include/internal/pycore_global_strings.h b/Include/internal/pycore_global_strings.h
index ec720de2524e6e..563ccd7cf6d3f4 100644
--- a/Include/internal/pycore_global_strings.h
+++ b/Include/internal/pycore_global_strings.h
@@ -376,9 +376,11 @@ struct _Py_global_strings {
STRUCT_FOR_ID(co_varnames)
STRUCT_FOR_ID(code)
STRUCT_FOR_ID(col_offset)
+ STRUCT_FOR_ID(collector)
STRUCT_FOR_ID(command)
STRUCT_FOR_ID(comment_factory)
STRUCT_FOR_ID(compile_mode)
+ STRUCT_FOR_ID(compression)
STRUCT_FOR_ID(config)
STRUCT_FOR_ID(consts)
STRUCT_FOR_ID(context)
@@ -441,7 +443,9 @@ struct _Py_global_strings {
STRUCT_FOR_ID(event)
STRUCT_FOR_ID(eventmask)
STRUCT_FOR_ID(exc)
+ STRUCT_FOR_ID(exc_tb)
STRUCT_FOR_ID(exc_type)
+ STRUCT_FOR_ID(exc_val)
STRUCT_FOR_ID(exc_value)
STRUCT_FOR_ID(excepthook)
STRUCT_FOR_ID(exception)
@@ -516,6 +520,7 @@ struct _Py_global_strings {
STRUCT_FOR_ID(ident)
STRUCT_FOR_ID(identity_hint)
STRUCT_FOR_ID(ignore)
+ STRUCT_FOR_ID(ignorechars)
STRUCT_FOR_ID(imag)
STRUCT_FOR_ID(implieslink)
STRUCT_FOR_ID(importlib)
@@ -697,6 +702,7 @@ struct _Py_global_strings {
STRUCT_FOR_ID(print_file_and_line)
STRUCT_FOR_ID(priority)
STRUCT_FOR_ID(progress)
+ STRUCT_FOR_ID(progress_callback)
STRUCT_FOR_ID(progress_routine)
STRUCT_FOR_ID(proto)
STRUCT_FOR_ID(protocol)
@@ -717,6 +723,7 @@ struct _Py_global_strings {
STRUCT_FOR_ID(readline)
STRUCT_FOR_ID(readonly)
STRUCT_FOR_ID(real)
+ STRUCT_FOR_ID(recursive)
STRUCT_FOR_ID(reducer_override)
STRUCT_FOR_ID(registry)
STRUCT_FOR_ID(rel_tol)
@@ -736,6 +743,7 @@ struct _Py_global_strings {
STRUCT_FOR_ID(reversed)
STRUCT_FOR_ID(rounding)
STRUCT_FOR_ID(salt)
+ STRUCT_FOR_ID(sample_interval_us)
STRUCT_FOR_ID(sched_priority)
STRUCT_FOR_ID(scheduler)
STRUCT_FOR_ID(script)
@@ -775,8 +783,10 @@ struct _Py_global_strings {
STRUCT_FOR_ID(spam)
STRUCT_FOR_ID(src)
STRUCT_FOR_ID(src_dir_fd)
+ STRUCT_FOR_ID(stack_frames)
STRUCT_FOR_ID(stacklevel)
STRUCT_FOR_ID(start)
+ STRUCT_FOR_ID(start_time_us)
STRUCT_FOR_ID(statement)
STRUCT_FOR_ID(stats)
STRUCT_FOR_ID(status)
@@ -817,6 +827,7 @@ struct _Py_global_strings {
STRUCT_FOR_ID(times)
STRUCT_FOR_ID(timespec)
STRUCT_FOR_ID(timestamp)
+ STRUCT_FOR_ID(timestamp_us)
STRUCT_FOR_ID(timetuple)
STRUCT_FOR_ID(timeunit)
STRUCT_FOR_ID(top)
@@ -855,6 +866,7 @@ struct _Py_global_strings {
STRUCT_FOR_ID(which)
STRUCT_FOR_ID(who)
STRUCT_FOR_ID(withdata)
+ STRUCT_FOR_ID(wrapcol)
STRUCT_FOR_ID(writable)
STRUCT_FOR_ID(write)
STRUCT_FOR_ID(write_through)
diff --git a/Include/internal/pycore_instruction_sequence.h b/Include/internal/pycore_instruction_sequence.h
index b5c927735374be..6257b771fd9539 100644
--- a/Include/internal/pycore_instruction_sequence.h
+++ b/Include/internal/pycore_instruction_sequence.h
@@ -73,6 +73,7 @@ int _PyInstructionSequence_SetAnnotationsCode(_PyInstructionSequence *seq,
_PyInstructionSequence *annotations);
int _PyInstructionSequence_AddNested(_PyInstructionSequence *seq, _PyInstructionSequence *nested);
void PyInstructionSequence_Fini(_PyInstructionSequence *seq);
+_PyInstruction _PyInstructionSequence_GetInstruction(_PyInstructionSequence *seq, int pos);
extern PyTypeObject _PyInstructionSequence_Type;
#define _PyInstructionSequence_Check(v) Py_IS_TYPE((v), &_PyInstructionSequence_Type)
diff --git a/Include/internal/pycore_instruments.h b/Include/internal/pycore_instruments.h
index ebc5622912f0cb..3775b074ecf54c 100644
--- a/Include/internal/pycore_instruments.h
+++ b/Include/internal/pycore_instruments.h
@@ -67,8 +67,8 @@ _Py_call_instrumentation_exc2(PyThreadState *tstate, int event,
extern int
_Py_Instrumentation_GetLine(PyCodeObject *code, int index);
-extern PyObject _PyInstrumentation_MISSING;
-extern PyObject _PyInstrumentation_DISABLE;
+PyAPI_DATA(PyObject) _PyInstrumentation_MISSING;
+PyAPI_DATA(PyObject) _PyInstrumentation_DISABLE;
/* Total tool ids available */
diff --git a/Include/internal/pycore_interp_structs.h b/Include/internal/pycore_interp_structs.h
index 6b3d5711b92971..723657e4cef10d 100644
--- a/Include/internal/pycore_interp_structs.h
+++ b/Include/internal/pycore_interp_structs.h
@@ -87,7 +87,9 @@ struct _ceval_runtime_state {
struct trampoline_api_st trampoline_api;
FILE *map_file;
Py_ssize_t persist_after_fork;
- _PyFrameEvalFunction prev_eval_frame;
+ _PyFrameEvalFunction prev_eval_frame;
+ Py_ssize_t trampoline_refcount;
+ int code_watcher_id;
#else
int _not_used;
#endif
@@ -396,6 +398,22 @@ typedef struct _rare_events {
uint8_t func_modification;
} _rare_events;
+// Optimization configuration for the interpreter.
+// This groups all thresholds and optimization flags for both JIT and interpreter.
+typedef struct _PyOptimizationConfig {
+ // Interpreter optimization thresholds
+ uint16_t jump_backward_initial_value;
+ uint16_t jump_backward_initial_backoff;
+
+ // JIT optimization thresholds
+ uint16_t side_exit_initial_value;
+ uint16_t side_exit_initial_backoff;
+
+ // Optimization flags
+ bool specialization_enabled;
+ bool uops_optimize_enabled;
+} _PyOptimizationConfig;
+
struct
Bigint {
struct Bigint *next;
@@ -943,11 +961,13 @@ struct _is {
PyObject *common_consts[NUM_COMMON_CONSTANTS];
bool jit;
bool compiling;
+
+ // Optimization configuration (thresholds and flags for JIT and interpreter)
+ _PyOptimizationConfig opt_config;
struct _PyExecutorObject *executor_list_head;
struct _PyExecutorObject *executor_deletion_list_head;
struct _PyExecutorObject *cold_executor;
struct _PyExecutorObject *cold_dynamic_executor;
- int executor_deletion_list_remaining_capacity;
size_t executor_creation_counter;
_rare_events rare_events;
PyDict_WatchCallback builtins_dict_watcher;
diff --git a/Include/internal/pycore_interpframe.h b/Include/internal/pycore_interpframe.h
index 8949d6cc2fc4bb..14e2f245834dca 100644
--- a/Include/internal/pycore_interpframe.h
+++ b/Include/internal/pycore_interpframe.h
@@ -27,7 +27,7 @@ static inline PyCodeObject *_PyFrame_GetCode(_PyInterpreterFrame *f) {
// Similar to _PyFrame_GetCode(), but return NULL if the frame is invalid or
// freed. Used by dump_frame() in Python/traceback.c. The function uses
// heuristics to detect freed memory, it's not 100% reliable.
-static inline PyCodeObject*
+static inline PyCodeObject* _Py_NO_SANITIZE_THREAD
_PyFrame_SafeGetCode(_PyInterpreterFrame *f)
{
// globals and builtins may be NULL on a legit frame, but it's unlikely.
@@ -70,7 +70,7 @@ _PyFrame_GetBytecode(_PyInterpreterFrame *f)
// Similar to PyUnstable_InterpreterFrame_GetLasti(), but return NULL if the
// frame is invalid or freed. Used by dump_frame() in Python/traceback.c. The
// function uses heuristics to detect freed memory, it's not 100% reliable.
-static inline int
+static inline int _Py_NO_SANITIZE_THREAD
_PyFrame_SafeGetLasti(struct _PyInterpreterFrame *f)
{
// Code based on _PyFrame_GetBytecode() but replace _PyFrame_GetCode()
@@ -279,7 +279,7 @@ _PyThreadState_GetFrame(PyThreadState *tstate)
/* For use by _PyFrame_GetFrameObject
Do not call directly. */
-PyFrameObject *
+PyAPI_FUNC(PyFrameObject *)
_PyFrame_MakeAndSetFrameObject(_PyInterpreterFrame *frame);
/* Gets the PyFrameObject for this frame, lazily
@@ -395,6 +395,10 @@ _PyEvalFramePushAndInit(PyThreadState *tstate, _PyStackRef func,
size_t argcount, PyObject *kwnames,
_PyInterpreterFrame *previous);
+PyAPI_FUNC(_PyInterpreterFrame *)
+_PyEvalFramePushAndInit_Ex(PyThreadState *tstate, _PyStackRef func,
+ PyObject *locals, Py_ssize_t nargs, PyObject *callargs, PyObject *kwargs, _PyInterpreterFrame *previous);
+
#ifdef __cplusplus
}
#endif
diff --git a/Include/internal/pycore_jit.h b/Include/internal/pycore_jit.h
index a7041ef8d4b000..70bccce4166c18 100644
--- a/Include/internal/pycore_jit.h
+++ b/Include/internal/pycore_jit.h
@@ -19,12 +19,14 @@ extern "C" {
#ifdef _Py_JIT
typedef _Py_CODEUNIT *(*jit_func)(
- _PyInterpreterFrame *frame, _PyStackRef *stack_pointer, PyThreadState *tstate,
+ _PyExecutorObject *executor, _PyInterpreterFrame *frame, _PyStackRef *stack_pointer, PyThreadState *tstate,
_PyStackRef _tos_cache0, _PyStackRef _tos_cache1, _PyStackRef _tos_cache2
);
int _PyJIT_Compile(_PyExecutorObject *executor, const _PyUOpInstruction *trace, size_t length);
void _PyJIT_Free(_PyExecutorObject *executor);
+void _PyJIT_Fini(void);
+PyAPI_FUNC(int) _PyJIT_AddressInJitCode(PyInterpreterState *interp, uintptr_t addr);
#endif // _Py_JIT
diff --git a/Include/internal/pycore_list.h b/Include/internal/pycore_list.h
index ffbcebdb7dfb50..b39639a9063260 100644
--- a/Include/internal/pycore_list.h
+++ b/Include/internal/pycore_list.h
@@ -17,12 +17,12 @@ PyAPI_FUNC(PyObject) *_PyList_SliceSubscript(PyObject*, PyObject*);
extern void _PyList_DebugMallocStats(FILE *out);
// _PyList_GetItemRef should be used only when the object is known as a list
// because it doesn't raise TypeError when the object is not a list, whereas PyList_GetItemRef does.
-extern PyObject* _PyList_GetItemRef(PyListObject *, Py_ssize_t i);
+PyAPI_FUNC(PyObject *) _PyList_GetItemRef(PyListObject *, Py_ssize_t i);
#ifdef Py_GIL_DISABLED
// Returns -1 in case of races with other threads.
-extern int _PyList_GetItemRefNoLock(PyListObject *, Py_ssize_t, _PyStackRef *);
+PyAPI_FUNC(int) _PyList_GetItemRefNoLock(PyListObject *, Py_ssize_t, _PyStackRef *);
#endif
#define _PyList_ITEMS(op) _Py_RVALUE(_PyList_CAST(op)->ob_item)
diff --git a/Include/internal/pycore_lock.h b/Include/internal/pycore_lock.h
index c4e007e744ce0f..e31d8b4e5c68c9 100644
--- a/Include/internal/pycore_lock.h
+++ b/Include/internal/pycore_lock.h
@@ -70,6 +70,9 @@ PyMutex_LockFlags(PyMutex *m, _PyLockFlags flags)
// error messages) otherwise returns 0.
extern int _PyMutex_TryUnlock(PyMutex *m);
+// Yield the processor to other threads (e.g., sched_yield).
+extern void _Py_yield(void);
+
// PyEvent is a one-time event notification
typedef struct {
diff --git a/Include/internal/pycore_magic_number.h b/Include/internal/pycore_magic_number.h
index 2fb46a6df50bb3..919a2ec0d1aa9e 100644
--- a/Include/internal/pycore_magic_number.h
+++ b/Include/internal/pycore_magic_number.h
@@ -286,7 +286,11 @@ Known values:
Python 3.15a1 3653 (Fix handling of opcodes that may leave operands on the stack when optimizing LOAD_FAST)
Python 3.15a1 3654 (Fix missing exception handlers in logical expression)
Python 3.15a1 3655 (Fix miscompilation of some module-level annotations)
- Python 3.15a1 3656 (Add TRACE_RECORD instruction, for platforms with switch based interpreter)
+ Python 3.15a2 3656 (Add TRACE_RECORD instruction, for platforms with switch based interpreter)
+ Python 3.15a4 3657 (Add BINARY_OP_SUBSCR_USTR_INT)
+ Python 3.15a4 3658 (Optimize bytecode for list/set called on genexp)
+ Python 3.15a4 3659 (Add CALL_FUNCTION_EX specialization)
+ Python 3.15a4 3660 (Change generator preamble code)
Python 3.16 will start with 3700
@@ -300,7 +304,7 @@ PC/launcher.c must also be updated.
*/
-#define PYC_MAGIC_NUMBER 3656
+#define PYC_MAGIC_NUMBER 3660
/* This is equivalent to converting PYC_MAGIC_NUMBER to 2 bytes
(little-endian) and then appending b'\r\n'. */
#define PYC_MAGIC_NUMBER_TOKEN \
diff --git a/Include/internal/pycore_mmap.h b/Include/internal/pycore_mmap.h
index 214fd4362a55fe..897816db01077f 100644
--- a/Include/internal/pycore_mmap.h
+++ b/Include/internal/pycore_mmap.h
@@ -17,25 +17,27 @@ extern "C" {
#endif
#if defined(HAVE_PR_SET_VMA_ANON_NAME) && defined(__linux__)
-static inline void
+static inline int
_PyAnnotateMemoryMap(void *addr, size_t size, const char *name)
{
#ifndef Py_DEBUG
if (!_Py_GetConfig()->dev_mode) {
- return;
+ return 0;
}
#endif
+ // The name length cannot exceed 80 (including the '\0').
assert(strlen(name) < 80);
- int old_errno = errno;
- prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, (unsigned long)addr, size, name);
- /* Ignore errno from prctl */
- /* See: https://bugzilla.redhat.com/show_bug.cgi?id=2302746 */
- errno = old_errno;
+ int res = prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, (unsigned long)addr, size, name);
+ if (res < 0) {
+ return -1;
+ }
+ return 0;
}
#else
-static inline void
+static inline int
_PyAnnotateMemoryMap(void *Py_UNUSED(addr), size_t Py_UNUSED(size), const char *Py_UNUSED(name))
{
+ return 0;
}
#endif
diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h
index fb50acd62da5eb..d14cee6af66103 100644
--- a/Include/internal/pycore_object.h
+++ b/Include/internal/pycore_object.h
@@ -252,25 +252,6 @@ _Py_DECREF_SPECIALIZED(PyObject *op, const destructor destruct)
}
}
-static inline void
-_Py_DECREF_NO_DEALLOC(PyObject *op)
-{
- if (_Py_IsImmortal(op)) {
- _Py_DECREF_IMMORTAL_STAT_INC();
- return;
- }
- _Py_DECREF_STAT_INC();
-#ifdef Py_REF_DEBUG
- _Py_DEC_REFTOTAL(PyInterpreterState_Get());
-#endif
- op->ob_refcnt--;
-#ifdef Py_DEBUG
- if (op->ob_refcnt <= 0) {
- _Py_FatalRefcountError("Expected a positive remaining refcount");
- }
-#endif
-}
-
#else
// TODO: implement Py_DECREF specializations for Py_GIL_DISABLED build
static inline void
@@ -279,12 +260,6 @@ _Py_DECREF_SPECIALIZED(PyObject *op, const destructor destruct)
Py_DECREF(op);
}
-static inline void
-_Py_DECREF_NO_DEALLOC(PyObject *op)
-{
- Py_DECREF(op);
-}
-
static inline int
_Py_REF_IS_MERGED(Py_ssize_t ob_ref_shared)
{
@@ -496,6 +471,9 @@ static inline void Py_DECREF_MORTAL_SPECIALIZED(PyObject *op, destructor destruc
#define Py_DECREF_MORTAL_SPECIALIZED(op, destruct) Py_DECREF_MORTAL_SPECIALIZED(_PyObject_CAST(op), destruct)
#endif
+#else // Py_GIL_DISABLED
+# define Py_DECREF_MORTAL(op) Py_DECREF(op)
+# define Py_DECREF_MORTAL_SPECIALIZED(op, destruct) Py_DECREF(op)
#endif
/* Inline functions trading binary compatibility for speed:
@@ -1045,6 +1023,8 @@ static inline Py_ALWAYS_INLINE void _Py_INCREF_MORTAL(PyObject *op)
}
#endif
}
+#else
+# define _Py_INCREF_MORTAL(op) Py_INCREF(op)
#endif
/* Utility for the tp_traverse slot of mutable heap types that have no other
diff --git a/Include/internal/pycore_obmalloc.h b/Include/internal/pycore_obmalloc.h
index a7ba8f340737aa..0b23bb48dd5c1b 100644
--- a/Include/internal/pycore_obmalloc.h
+++ b/Include/internal/pycore_obmalloc.h
@@ -208,7 +208,11 @@ typedef unsigned int pymem_uint; /* assuming >= 16 bits */
* mappings to reduce heap fragmentation.
*/
#ifdef USE_LARGE_ARENAS
-#define ARENA_BITS 20 /* 1 MiB */
+# ifdef PYMALLOC_USE_HUGEPAGES
+# define ARENA_BITS 21 /* 2 MiB */
+# else
+# define ARENA_BITS 20 /* 1 MiB */
+# endif
#else
#define ARENA_BITS 18 /* 256 KiB */
#endif
@@ -469,7 +473,7 @@ nfp free pools in usable_arenas.
*/
/* How many arena_objects do we initially allocate?
- * 16 = can allocate 16 arenas = 16 * ARENA_SIZE = 4MB before growing the
+ * 16 = can allocate 16 arenas = 16 * ARENA_SIZE before growing the
* `arenas` vector.
*/
#define INITIAL_ARENA_OBJECTS 16
@@ -512,7 +516,11 @@ struct _obmalloc_mgmt {
memory address bit allocation for keys
- 64-bit pointers, IGNORE_BITS=0 and 2^20 arena size:
+ ARENA_BITS is configurable: 20 (1 MiB) by default on 64-bit, or
+ 21 (2 MiB) when PYMALLOC_USE_HUGEPAGES is enabled. All bit widths
+ below are derived from ARENA_BITS automatically.
+
+ 64-bit pointers, IGNORE_BITS=0 and 2^20 arena size (default):
15 -> MAP_TOP_BITS
15 -> MAP_MID_BITS
14 -> MAP_BOT_BITS
@@ -520,6 +528,14 @@ struct _obmalloc_mgmt {
----
64
+ 64-bit pointers, IGNORE_BITS=0 and 2^21 arena size (hugepages):
+ 15 -> MAP_TOP_BITS
+ 15 -> MAP_MID_BITS
+ 13 -> MAP_BOT_BITS
+ 21 -> ideal aligned arena
+ ----
+ 64
+
64-bit pointers, IGNORE_BITS=16, and 2^20 arena size:
16 -> IGNORE_BITS
10 -> MAP_TOP_BITS
diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h
index 35659de22b799d..fe94dc6a24fcc0 100644
--- a/Include/internal/pycore_opcode_metadata.h
+++ b/Include/internal/pycore_opcode_metadata.h
@@ -66,6 +66,8 @@ int _PyOpcode_num_popped(int opcode, int oparg) {
return 2;
case BINARY_OP_SUBSCR_TUPLE_INT:
return 2;
+ case BINARY_OP_SUBSCR_USTR_INT:
+ return 2;
case BINARY_OP_SUBTRACT_FLOAT:
return 2;
case BINARY_OP_SUBTRACT_INT:
@@ -106,6 +108,10 @@ int _PyOpcode_num_popped(int opcode, int oparg) {
return 2 + oparg;
case CALL_BUILTIN_O:
return 2 + oparg;
+ case CALL_EX_NON_PY_GENERAL:
+ return 4;
+ case CALL_EX_PY:
+ return 4;
case CALL_FUNCTION_EX:
return 4;
case CALL_INTRINSIC_1:
@@ -534,7 +540,7 @@ int _PyOpcode_num_pushed(int opcode, int oparg) {
case BINARY_OP_EXTEND:
return 1;
case BINARY_OP_INPLACE_ADD_UNICODE:
- return 0;
+ return 1;
case BINARY_OP_MULTIPLY_FLOAT:
return 1;
case BINARY_OP_MULTIPLY_INT:
@@ -551,6 +557,8 @@ int _PyOpcode_num_pushed(int opcode, int oparg) {
return 1;
case BINARY_OP_SUBSCR_TUPLE_INT:
return 1;
+ case BINARY_OP_SUBSCR_USTR_INT:
+ return 1;
case BINARY_OP_SUBTRACT_FLOAT:
return 1;
case BINARY_OP_SUBTRACT_INT:
@@ -591,6 +599,10 @@ int _PyOpcode_num_pushed(int opcode, int oparg) {
return 1;
case CALL_BUILTIN_O:
return 1;
+ case CALL_EX_NON_PY_GENERAL:
+ return 1;
+ case CALL_EX_PY:
+ return 0;
case CALL_FUNCTION_EX:
return 1;
case CALL_INTRINSIC_1:
@@ -610,7 +622,7 @@ int _PyOpcode_num_pushed(int opcode, int oparg) {
case CALL_LEN:
return 1;
case CALL_LIST_APPEND:
- return 0;
+ return 1;
case CALL_METHOD_DESCRIPTOR_FAST:
return 1;
case CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS:
@@ -1075,24 +1087,25 @@ struct opcode_metadata {
uint32_t flags;
};
-extern const struct opcode_metadata _PyOpcode_opcode_metadata[267];
+PyAPI_DATA(const struct opcode_metadata) _PyOpcode_opcode_metadata[267];
#ifdef NEED_OPCODE_METADATA
const struct opcode_metadata _PyOpcode_opcode_metadata[267] = {
[BINARY_OP] = { true, INSTR_FMT_IBC0000, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
- [BINARY_OP_ADD_FLOAT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
+ [BINARY_OP_ADD_FLOAT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG },
[BINARY_OP_ADD_INT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG },
- [BINARY_OP_ADD_UNICODE] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
- [BINARY_OP_EXTEND] = { true, INSTR_FMT_IXC0000, HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
+ [BINARY_OP_ADD_UNICODE] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG },
+ [BINARY_OP_EXTEND] = { true, INSTR_FMT_IXC0000, HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
[BINARY_OP_INPLACE_ADD_UNICODE] = { true, INSTR_FMT_IXC0000, HAS_LOCAL_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [BINARY_OP_MULTIPLY_FLOAT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
+ [BINARY_OP_MULTIPLY_FLOAT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG },
[BINARY_OP_MULTIPLY_INT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG },
- [BINARY_OP_SUBSCR_DICT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [BINARY_OP_SUBSCR_DICT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
[BINARY_OP_SUBSCR_GETITEM] = { true, INSTR_FMT_IXC0000, HAS_DEOPT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
[BINARY_OP_SUBSCR_LIST_INT] = { true, INSTR_FMT_IXC0000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
[BINARY_OP_SUBSCR_LIST_SLICE] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [BINARY_OP_SUBSCR_STR_INT] = { true, INSTR_FMT_IXC0000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
+ [BINARY_OP_SUBSCR_STR_INT] = { true, INSTR_FMT_IXC0000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
[BINARY_OP_SUBSCR_TUPLE_INT] = { true, INSTR_FMT_IXC0000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
- [BINARY_OP_SUBTRACT_FLOAT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
+ [BINARY_OP_SUBSCR_USTR_INT] = { true, INSTR_FMT_IXC0000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
+ [BINARY_OP_SUBTRACT_FLOAT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG },
[BINARY_OP_SUBTRACT_INT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG },
[BINARY_SLICE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[BUILD_INTERPOLATION] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
@@ -1111,8 +1124,10 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = {
[CALL_BUILTIN_CLASS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[CALL_BUILTIN_FAST] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[CALL_BUILTIN_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [CALL_BUILTIN_O] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [CALL_FUNCTION_EX] = { true, INSTR_FMT_IX, HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
+ [CALL_BUILTIN_O] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [CALL_EX_NON_PY_GENERAL] = { true, INSTR_FMT_IXC, HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [CALL_EX_PY] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
+ [CALL_FUNCTION_EX] = { true, INSTR_FMT_IXC, HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
[CALL_INTRINSIC_1] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[CALL_INTRINSIC_2] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[CALL_ISINSTANCE] = { true, INSTR_FMT_IXC00, HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
@@ -1121,16 +1136,16 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = {
[CALL_KW_NON_PY] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[CALL_KW_PY] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
[CALL_LEN] = { true, INSTR_FMT_IXC00, HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
- [CALL_LIST_APPEND] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [CALL_LIST_APPEND] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
[CALL_METHOD_DESCRIPTOR_FAST] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[CALL_METHOD_DESCRIPTOR_NOARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [CALL_METHOD_DESCRIPTOR_O] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [CALL_METHOD_DESCRIPTOR_O] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
[CALL_NON_PY_GENERAL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[CALL_PY_EXACT_ARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
[CALL_PY_GENERAL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
- [CALL_STR_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [CALL_TUPLE_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [CALL_STR_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [CALL_TUPLE_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
[CALL_TYPE_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
[CHECK_EG_MATCH] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[CHECK_EXC_MATCH] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
@@ -1139,9 +1154,9 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = {
[COMPARE_OP_FLOAT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_EXIT_FLAG },
[COMPARE_OP_INT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_EXIT_FLAG },
[COMPARE_OP_STR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_EXIT_FLAG },
- [CONTAINS_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [CONTAINS_OP_DICT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [CONTAINS_OP_SET] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [CONTAINS_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [CONTAINS_OP_DICT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [CONTAINS_OP_SET] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
[CONVERT_VALUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[COPY] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_PURE_FLAG },
[COPY_FREE_VARS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
@@ -1175,7 +1190,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = {
[IMPORT_FROM] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[IMPORT_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[INSTRUMENTED_CALL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
- [INSTRUMENTED_CALL_FUNCTION_EX] = { true, INSTR_FMT_IX, HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
+ [INSTRUMENTED_CALL_FUNCTION_EX] = { true, INSTR_FMT_IXC, HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
[INSTRUMENTED_CALL_KW] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
[INSTRUMENTED_END_ASYNC_FOR] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_UNPREDICTABLE_JUMP_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
[INSTRUMENTED_END_FOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_NO_SAVE_IP_FLAG },
@@ -1289,14 +1304,14 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = {
[TO_BOOL] = { true, INSTR_FMT_IXC00, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[TO_BOOL_ALWAYS_TRUE] = { true, INSTR_FMT_IXC00, HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
[TO_BOOL_BOOL] = { true, INSTR_FMT_IXC00, HAS_EXIT_FLAG },
- [TO_BOOL_INT] = { true, INSTR_FMT_IXC00, HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
+ [TO_BOOL_INT] = { true, INSTR_FMT_IXC00, HAS_EXIT_FLAG },
[TO_BOOL_LIST] = { true, INSTR_FMT_IXC00, HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
[TO_BOOL_NONE] = { true, INSTR_FMT_IXC00, HAS_EXIT_FLAG },
- [TO_BOOL_STR] = { true, INSTR_FMT_IXC00, HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
+ [TO_BOOL_STR] = { true, INSTR_FMT_IXC00, HAS_EXIT_FLAG },
[TRACE_RECORD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [UNARY_INVERT] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [UNARY_NEGATIVE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [UNARY_NOT] = { true, INSTR_FMT_IX, HAS_PURE_FLAG },
+ [UNARY_INVERT] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [UNARY_NEGATIVE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [UNARY_NOT] = { true, INSTR_FMT_IX, 0 },
[UNPACK_EX] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[UNPACK_SEQUENCE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[UNPACK_SEQUENCE_LIST] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
@@ -1328,22 +1343,23 @@ extern const struct opcode_macro_expansion _PyOpcode_macro_expansion[256];
#ifdef NEED_OPCODE_METADATA
const struct opcode_macro_expansion
_PyOpcode_macro_expansion[256] = {
- [BINARY_OP] = { .nuops = 1, .uops = { { _BINARY_OP, OPARG_SIMPLE, 4 } } },
- [BINARY_OP_ADD_FLOAT] = { .nuops = 3, .uops = { { _GUARD_TOS_FLOAT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_FLOAT, OPARG_SIMPLE, 0 }, { _BINARY_OP_ADD_FLOAT, OPARG_SIMPLE, 5 } } },
- [BINARY_OP_ADD_INT] = { .nuops = 3, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_INT, OPARG_SIMPLE, 0 }, { _BINARY_OP_ADD_INT, OPARG_SIMPLE, 5 } } },
- [BINARY_OP_ADD_UNICODE] = { .nuops = 3, .uops = { { _GUARD_TOS_UNICODE, OPARG_SIMPLE, 0 }, { _GUARD_NOS_UNICODE, OPARG_SIMPLE, 0 }, { _BINARY_OP_ADD_UNICODE, OPARG_SIMPLE, 5 } } },
- [BINARY_OP_EXTEND] = { .nuops = 2, .uops = { { _GUARD_BINARY_OP_EXTEND, 4, 1 }, { _BINARY_OP_EXTEND, 4, 1 } } },
+ [BINARY_OP] = { .nuops = 3, .uops = { { _BINARY_OP, OPARG_SIMPLE, 4 }, { _POP_TOP, OPARG_SIMPLE, 4 }, { _POP_TOP, OPARG_SIMPLE, 4 } } },
+ [BINARY_OP_ADD_FLOAT] = { .nuops = 5, .uops = { { _GUARD_TOS_FLOAT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_FLOAT, OPARG_SIMPLE, 0 }, { _BINARY_OP_ADD_FLOAT, OPARG_SIMPLE, 5 }, { _POP_TOP_FLOAT, OPARG_SIMPLE, 5 }, { _POP_TOP_FLOAT, OPARG_SIMPLE, 5 } } },
+ [BINARY_OP_ADD_INT] = { .nuops = 5, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_INT, OPARG_SIMPLE, 0 }, { _BINARY_OP_ADD_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 } } },
+ [BINARY_OP_ADD_UNICODE] = { .nuops = 5, .uops = { { _GUARD_TOS_UNICODE, OPARG_SIMPLE, 0 }, { _GUARD_NOS_UNICODE, OPARG_SIMPLE, 0 }, { _BINARY_OP_ADD_UNICODE, OPARG_SIMPLE, 5 }, { _POP_TOP_UNICODE, OPARG_SIMPLE, 5 }, { _POP_TOP_UNICODE, OPARG_SIMPLE, 5 } } },
+ [BINARY_OP_EXTEND] = { .nuops = 4, .uops = { { _GUARD_BINARY_OP_EXTEND, 4, 1 }, { _BINARY_OP_EXTEND, 4, 1 }, { _POP_TOP, OPARG_SIMPLE, 5 }, { _POP_TOP, OPARG_SIMPLE, 5 } } },
[BINARY_OP_INPLACE_ADD_UNICODE] = { .nuops = 3, .uops = { { _GUARD_TOS_UNICODE, OPARG_SIMPLE, 0 }, { _GUARD_NOS_UNICODE, OPARG_SIMPLE, 0 }, { _BINARY_OP_INPLACE_ADD_UNICODE, OPARG_SIMPLE, 5 } } },
- [BINARY_OP_MULTIPLY_FLOAT] = { .nuops = 3, .uops = { { _GUARD_TOS_FLOAT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_FLOAT, OPARG_SIMPLE, 0 }, { _BINARY_OP_MULTIPLY_FLOAT, OPARG_SIMPLE, 5 } } },
- [BINARY_OP_MULTIPLY_INT] = { .nuops = 3, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_INT, OPARG_SIMPLE, 0 }, { _BINARY_OP_MULTIPLY_INT, OPARG_SIMPLE, 5 } } },
- [BINARY_OP_SUBSCR_DICT] = { .nuops = 2, .uops = { { _GUARD_NOS_DICT, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_DICT, OPARG_SIMPLE, 5 } } },
+ [BINARY_OP_MULTIPLY_FLOAT] = { .nuops = 5, .uops = { { _GUARD_TOS_FLOAT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_FLOAT, OPARG_SIMPLE, 0 }, { _BINARY_OP_MULTIPLY_FLOAT, OPARG_SIMPLE, 5 }, { _POP_TOP_FLOAT, OPARG_SIMPLE, 5 }, { _POP_TOP_FLOAT, OPARG_SIMPLE, 5 } } },
+ [BINARY_OP_MULTIPLY_INT] = { .nuops = 5, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_INT, OPARG_SIMPLE, 0 }, { _BINARY_OP_MULTIPLY_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 } } },
+ [BINARY_OP_SUBSCR_DICT] = { .nuops = 4, .uops = { { _GUARD_NOS_DICT, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_DICT, OPARG_SIMPLE, 5 }, { _POP_TOP, OPARG_SIMPLE, 5 }, { _POP_TOP, OPARG_SIMPLE, 5 } } },
[BINARY_OP_SUBSCR_GETITEM] = { .nuops = 4, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 5 }, { _BINARY_OP_SUBSCR_CHECK_FUNC, OPARG_SIMPLE, 5 }, { _BINARY_OP_SUBSCR_INIT_CALL, OPARG_SIMPLE, 5 }, { _PUSH_FRAME, OPARG_SIMPLE, 5 } } },
- [BINARY_OP_SUBSCR_LIST_INT] = { .nuops = 3, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_LIST, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_LIST_INT, OPARG_SIMPLE, 5 } } },
+ [BINARY_OP_SUBSCR_LIST_INT] = { .nuops = 5, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_LIST, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_LIST_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 }, { _POP_TOP, OPARG_SIMPLE, 5 } } },
[BINARY_OP_SUBSCR_LIST_SLICE] = { .nuops = 3, .uops = { { _GUARD_TOS_SLICE, OPARG_SIMPLE, 0 }, { _GUARD_NOS_LIST, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_LIST_SLICE, OPARG_SIMPLE, 5 } } },
- [BINARY_OP_SUBSCR_STR_INT] = { .nuops = 3, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_UNICODE, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_STR_INT, OPARG_SIMPLE, 5 } } },
- [BINARY_OP_SUBSCR_TUPLE_INT] = { .nuops = 3, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_TUPLE, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_TUPLE_INT, OPARG_SIMPLE, 5 } } },
- [BINARY_OP_SUBTRACT_FLOAT] = { .nuops = 3, .uops = { { _GUARD_TOS_FLOAT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_FLOAT, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBTRACT_FLOAT, OPARG_SIMPLE, 5 } } },
- [BINARY_OP_SUBTRACT_INT] = { .nuops = 3, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_INT, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBTRACT_INT, OPARG_SIMPLE, 5 } } },
+ [BINARY_OP_SUBSCR_STR_INT] = { .nuops = 5, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_COMPACT_ASCII, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_STR_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_UNICODE, OPARG_SIMPLE, 5 } } },
+ [BINARY_OP_SUBSCR_TUPLE_INT] = { .nuops = 6, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_TUPLE, OPARG_SIMPLE, 0 }, { _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_TUPLE_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 }, { _POP_TOP, OPARG_SIMPLE, 5 } } },
+ [BINARY_OP_SUBSCR_USTR_INT] = { .nuops = 5, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_UNICODE, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_USTR_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_UNICODE, OPARG_SIMPLE, 5 } } },
+ [BINARY_OP_SUBTRACT_FLOAT] = { .nuops = 5, .uops = { { _GUARD_TOS_FLOAT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_FLOAT, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBTRACT_FLOAT, OPARG_SIMPLE, 5 }, { _POP_TOP_FLOAT, OPARG_SIMPLE, 5 }, { _POP_TOP_FLOAT, OPARG_SIMPLE, 5 } } },
+ [BINARY_OP_SUBTRACT_INT] = { .nuops = 5, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_INT, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBTRACT_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 } } },
[BINARY_SLICE] = { .nuops = 1, .uops = { { _BINARY_SLICE, OPARG_SIMPLE, 0 } } },
[BUILD_INTERPOLATION] = { .nuops = 1, .uops = { { _BUILD_INTERPOLATION, OPARG_SIMPLE, 0 } } },
[BUILD_LIST] = { .nuops = 1, .uops = { { _BUILD_LIST, OPARG_SIMPLE, 0 } } },
@@ -1359,7 +1375,9 @@ _PyOpcode_macro_expansion[256] = {
[CALL_BUILTIN_CLASS] = { .nuops = 2, .uops = { { _CALL_BUILTIN_CLASS, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
[CALL_BUILTIN_FAST] = { .nuops = 2, .uops = { { _CALL_BUILTIN_FAST, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
[CALL_BUILTIN_FAST_WITH_KEYWORDS] = { .nuops = 2, .uops = { { _CALL_BUILTIN_FAST_WITH_KEYWORDS, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
- [CALL_BUILTIN_O] = { .nuops = 2, .uops = { { _CALL_BUILTIN_O, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
+ [CALL_BUILTIN_O] = { .nuops = 4, .uops = { { _CALL_BUILTIN_O, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
+ [CALL_EX_NON_PY_GENERAL] = { .nuops = 4, .uops = { { _CHECK_IS_NOT_PY_CALLABLE_EX, OPARG_SIMPLE, 1 }, { _MAKE_CALLARGS_A_TUPLE, OPARG_SIMPLE, 1 }, { _CALL_FUNCTION_EX_NON_PY_GENERAL, OPARG_SIMPLE, 1 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 1 } } },
+ [CALL_EX_PY] = { .nuops = 6, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _MAKE_CALLARGS_A_TUPLE, OPARG_SIMPLE, 1 }, { _CHECK_IS_PY_CALLABLE_EX, OPARG_SIMPLE, 1 }, { _PY_FRAME_EX, OPARG_SIMPLE, 1 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 1 }, { _PUSH_FRAME, OPARG_SIMPLE, 1 } } },
[CALL_INTRINSIC_1] = { .nuops = 1, .uops = { { _CALL_INTRINSIC_1, OPARG_SIMPLE, 0 } } },
[CALL_INTRINSIC_2] = { .nuops = 1, .uops = { { _CALL_INTRINSIC_2, OPARG_SIMPLE, 0 } } },
[CALL_ISINSTANCE] = { .nuops = 3, .uops = { { _GUARD_THIRD_NULL, OPARG_SIMPLE, 3 }, { _GUARD_CALLABLE_ISINSTANCE, OPARG_SIMPLE, 3 }, { _CALL_ISINSTANCE, OPARG_SIMPLE, 3 } } },
@@ -1367,26 +1385,26 @@ _PyOpcode_macro_expansion[256] = {
[CALL_KW_NON_PY] = { .nuops = 3, .uops = { { _CHECK_IS_NOT_PY_CALLABLE_KW, OPARG_SIMPLE, 3 }, { _CALL_KW_NON_PY, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
[CALL_KW_PY] = { .nuops = 6, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_FUNCTION_VERSION_KW, 2, 1 }, { _CHECK_RECURSION_REMAINING, OPARG_SIMPLE, 3 }, { _PY_FRAME_KW, OPARG_SIMPLE, 3 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 3 }, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } },
[CALL_LEN] = { .nuops = 5, .uops = { { _GUARD_NOS_NULL, OPARG_SIMPLE, 3 }, { _GUARD_CALLABLE_LEN, OPARG_SIMPLE, 3 }, { _CALL_LEN, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 } } },
- [CALL_LIST_APPEND] = { .nuops = 4, .uops = { { _GUARD_CALLABLE_LIST_APPEND, OPARG_SIMPLE, 3 }, { _GUARD_NOS_NOT_NULL, OPARG_SIMPLE, 3 }, { _GUARD_NOS_LIST, OPARG_SIMPLE, 3 }, { _CALL_LIST_APPEND, OPARG_SIMPLE, 3 } } },
+ [CALL_LIST_APPEND] = { .nuops = 6, .uops = { { _GUARD_CALLABLE_LIST_APPEND, OPARG_SIMPLE, 3 }, { _GUARD_NOS_NOT_NULL, OPARG_SIMPLE, 3 }, { _GUARD_NOS_LIST, OPARG_SIMPLE, 3 }, { _CALL_LIST_APPEND, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 } } },
[CALL_METHOD_DESCRIPTOR_FAST] = { .nuops = 2, .uops = { { _CALL_METHOD_DESCRIPTOR_FAST, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
[CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = { .nuops = 2, .uops = { { _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
[CALL_METHOD_DESCRIPTOR_NOARGS] = { .nuops = 2, .uops = { { _CALL_METHOD_DESCRIPTOR_NOARGS, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
- [CALL_METHOD_DESCRIPTOR_O] = { .nuops = 2, .uops = { { _CALL_METHOD_DESCRIPTOR_O, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
+ [CALL_METHOD_DESCRIPTOR_O] = { .nuops = 5, .uops = { { _CALL_METHOD_DESCRIPTOR_O, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
[CALL_NON_PY_GENERAL] = { .nuops = 3, .uops = { { _CHECK_IS_NOT_PY_CALLABLE, OPARG_SIMPLE, 3 }, { _CALL_NON_PY_GENERAL, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
[CALL_PY_EXACT_ARGS] = { .nuops = 8, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_FUNCTION_VERSION, 2, 1 }, { _CHECK_FUNCTION_EXACT_ARGS, OPARG_SIMPLE, 3 }, { _CHECK_STACK_SPACE, OPARG_SIMPLE, 3 }, { _CHECK_RECURSION_REMAINING, OPARG_SIMPLE, 3 }, { _INIT_CALL_PY_EXACT_ARGS, OPARG_SIMPLE, 3 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 3 }, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } },
[CALL_PY_GENERAL] = { .nuops = 6, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_FUNCTION_VERSION, 2, 1 }, { _CHECK_RECURSION_REMAINING, OPARG_SIMPLE, 3 }, { _PY_FRAME_GENERAL, OPARG_SIMPLE, 3 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 3 }, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } },
- [CALL_STR_1] = { .nuops = 4, .uops = { { _GUARD_NOS_NULL, OPARG_SIMPLE, 3 }, { _GUARD_CALLABLE_STR_1, OPARG_SIMPLE, 3 }, { _CALL_STR_1, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
+ [CALL_STR_1] = { .nuops = 5, .uops = { { _GUARD_NOS_NULL, OPARG_SIMPLE, 3 }, { _GUARD_CALLABLE_STR_1, OPARG_SIMPLE, 3 }, { _CALL_STR_1, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
[CALL_TUPLE_1] = { .nuops = 5, .uops = { { _GUARD_NOS_NULL, OPARG_SIMPLE, 3 }, { _GUARD_CALLABLE_TUPLE_1, OPARG_SIMPLE, 3 }, { _CALL_TUPLE_1, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
- [CALL_TYPE_1] = { .nuops = 3, .uops = { { _GUARD_NOS_NULL, OPARG_SIMPLE, 3 }, { _GUARD_CALLABLE_TYPE_1, OPARG_SIMPLE, 3 }, { _CALL_TYPE_1, OPARG_SIMPLE, 3 } } },
+ [CALL_TYPE_1] = { .nuops = 4, .uops = { { _GUARD_NOS_NULL, OPARG_SIMPLE, 3 }, { _GUARD_CALLABLE_TYPE_1, OPARG_SIMPLE, 3 }, { _CALL_TYPE_1, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 } } },
[CHECK_EG_MATCH] = { .nuops = 1, .uops = { { _CHECK_EG_MATCH, OPARG_SIMPLE, 0 } } },
[CHECK_EXC_MATCH] = { .nuops = 1, .uops = { { _CHECK_EXC_MATCH, OPARG_SIMPLE, 0 } } },
[COMPARE_OP] = { .nuops = 1, .uops = { { _COMPARE_OP, OPARG_SIMPLE, 0 } } },
- [COMPARE_OP_FLOAT] = { .nuops = 3, .uops = { { _GUARD_TOS_FLOAT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_FLOAT, OPARG_SIMPLE, 0 }, { _COMPARE_OP_FLOAT, OPARG_SIMPLE, 1 } } },
- [COMPARE_OP_INT] = { .nuops = 3, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_INT, OPARG_SIMPLE, 0 }, { _COMPARE_OP_INT, OPARG_SIMPLE, 1 } } },
- [COMPARE_OP_STR] = { .nuops = 3, .uops = { { _GUARD_TOS_UNICODE, OPARG_SIMPLE, 0 }, { _GUARD_NOS_UNICODE, OPARG_SIMPLE, 0 }, { _COMPARE_OP_STR, OPARG_SIMPLE, 1 } } },
- [CONTAINS_OP] = { .nuops = 1, .uops = { { _CONTAINS_OP, OPARG_SIMPLE, 0 } } },
- [CONTAINS_OP_DICT] = { .nuops = 2, .uops = { { _GUARD_TOS_DICT, OPARG_SIMPLE, 0 }, { _CONTAINS_OP_DICT, OPARG_SIMPLE, 1 } } },
- [CONTAINS_OP_SET] = { .nuops = 2, .uops = { { _GUARD_TOS_ANY_SET, OPARG_SIMPLE, 0 }, { _CONTAINS_OP_SET, OPARG_SIMPLE, 1 } } },
+ [COMPARE_OP_FLOAT] = { .nuops = 5, .uops = { { _GUARD_TOS_FLOAT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_FLOAT, OPARG_SIMPLE, 0 }, { _COMPARE_OP_FLOAT, OPARG_SIMPLE, 1 }, { _POP_TOP_FLOAT, OPARG_SIMPLE, 1 }, { _POP_TOP_FLOAT, OPARG_SIMPLE, 1 } } },
+ [COMPARE_OP_INT] = { .nuops = 5, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_INT, OPARG_SIMPLE, 0 }, { _COMPARE_OP_INT, OPARG_SIMPLE, 1 }, { _POP_TOP_INT, OPARG_SIMPLE, 1 }, { _POP_TOP_INT, OPARG_SIMPLE, 1 } } },
+ [COMPARE_OP_STR] = { .nuops = 5, .uops = { { _GUARD_TOS_UNICODE, OPARG_SIMPLE, 0 }, { _GUARD_NOS_UNICODE, OPARG_SIMPLE, 0 }, { _COMPARE_OP_STR, OPARG_SIMPLE, 1 }, { _POP_TOP_UNICODE, OPARG_SIMPLE, 1 }, { _POP_TOP_UNICODE, OPARG_SIMPLE, 1 } } },
+ [CONTAINS_OP] = { .nuops = 3, .uops = { { _CONTAINS_OP, OPARG_SIMPLE, 0 }, { _POP_TOP, OPARG_SIMPLE, 0 }, { _POP_TOP, OPARG_SIMPLE, 0 } } },
+ [CONTAINS_OP_DICT] = { .nuops = 4, .uops = { { _GUARD_TOS_DICT, OPARG_SIMPLE, 0 }, { _CONTAINS_OP_DICT, OPARG_SIMPLE, 1 }, { _POP_TOP, OPARG_SIMPLE, 1 }, { _POP_TOP, OPARG_SIMPLE, 1 } } },
+ [CONTAINS_OP_SET] = { .nuops = 4, .uops = { { _GUARD_TOS_ANY_SET, OPARG_SIMPLE, 0 }, { _CONTAINS_OP_SET, OPARG_SIMPLE, 1 }, { _POP_TOP, OPARG_SIMPLE, 1 }, { _POP_TOP, OPARG_SIMPLE, 1 } } },
[CONVERT_VALUE] = { .nuops = 1, .uops = { { _CONVERT_VALUE, OPARG_SIMPLE, 0 } } },
[COPY] = { .nuops = 1, .uops = { { _COPY, OPARG_SIMPLE, 0 } } },
[COPY_FREE_VARS] = { .nuops = 1, .uops = { { _COPY_FREE_VARS, OPARG_SIMPLE, 0 } } },
@@ -1416,7 +1434,7 @@ _PyOpcode_macro_expansion[256] = {
[GET_YIELD_FROM_ITER] = { .nuops = 1, .uops = { { _GET_YIELD_FROM_ITER, OPARG_SIMPLE, 0 } } },
[IMPORT_FROM] = { .nuops = 1, .uops = { { _IMPORT_FROM, OPARG_SIMPLE, 0 } } },
[IMPORT_NAME] = { .nuops = 1, .uops = { { _IMPORT_NAME, OPARG_SIMPLE, 0 } } },
- [IS_OP] = { .nuops = 1, .uops = { { _IS_OP, OPARG_SIMPLE, 0 } } },
+ [IS_OP] = { .nuops = 3, .uops = { { _IS_OP, OPARG_SIMPLE, 0 }, { _POP_TOP, OPARG_SIMPLE, 0 }, { _POP_TOP, OPARG_SIMPLE, 0 } } },
[JUMP_BACKWARD] = { .nuops = 2, .uops = { { _CHECK_PERIODIC, OPARG_SIMPLE, 1 }, { _JUMP_BACKWARD_NO_INTERRUPT, OPARG_REPLACED, 1 } } },
[JUMP_BACKWARD_NO_INTERRUPT] = { .nuops = 1, .uops = { { _JUMP_BACKWARD_NO_INTERRUPT, OPARG_REPLACED, 0 } } },
[JUMP_BACKWARD_NO_JIT] = { .nuops = 2, .uops = { { _CHECK_PERIODIC, OPARG_SIMPLE, 1 }, { _JUMP_BACKWARD_NO_INTERRUPT, OPARG_REPLACED, 1 } } },
@@ -1425,16 +1443,16 @@ _PyOpcode_macro_expansion[256] = {
[LOAD_ATTR] = { .nuops = 1, .uops = { { _LOAD_ATTR, OPARG_SIMPLE, 8 } } },
[LOAD_ATTR_CLASS] = { .nuops = 3, .uops = { { _CHECK_ATTR_CLASS, 2, 1 }, { _LOAD_ATTR_CLASS, 4, 5 }, { _PUSH_NULL_CONDITIONAL, OPARG_SIMPLE, 9 } } },
[LOAD_ATTR_CLASS_WITH_METACLASS_CHECK] = { .nuops = 4, .uops = { { _CHECK_ATTR_CLASS, 2, 1 }, { _GUARD_TYPE_VERSION, 2, 3 }, { _LOAD_ATTR_CLASS, 4, 5 }, { _PUSH_NULL_CONDITIONAL, OPARG_SIMPLE, 9 } } },
- [LOAD_ATTR_INSTANCE_VALUE] = { .nuops = 4, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_MANAGED_OBJECT_HAS_VALUES, OPARG_SIMPLE, 3 }, { _LOAD_ATTR_INSTANCE_VALUE, 1, 3 }, { _PUSH_NULL_CONDITIONAL, OPARG_SIMPLE, 9 } } },
+ [LOAD_ATTR_INSTANCE_VALUE] = { .nuops = 5, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_MANAGED_OBJECT_HAS_VALUES, OPARG_SIMPLE, 3 }, { _LOAD_ATTR_INSTANCE_VALUE, 1, 3 }, { _POP_TOP, OPARG_SIMPLE, 4 }, { _PUSH_NULL_CONDITIONAL, OPARG_SIMPLE, 9 } } },
[LOAD_ATTR_METHOD_LAZY_DICT] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_ATTR_METHOD_LAZY_DICT, 1, 3 }, { _LOAD_ATTR_METHOD_LAZY_DICT, 4, 5 } } },
[LOAD_ATTR_METHOD_NO_DICT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_METHOD_NO_DICT, 4, 5 } } },
[LOAD_ATTR_METHOD_WITH_VALUES] = { .nuops = 4, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT, OPARG_SIMPLE, 3 }, { _GUARD_KEYS_VERSION, 2, 3 }, { _LOAD_ATTR_METHOD_WITH_VALUES, 4, 5 } } },
- [LOAD_ATTR_MODULE] = { .nuops = 3, .uops = { { _LOAD_ATTR_MODULE, 2, 1 }, { _LOAD_ATTR_MODULE, OPERAND1_1, 3 }, { _PUSH_NULL_CONDITIONAL, OPARG_SIMPLE, 9 } } },
+ [LOAD_ATTR_MODULE] = { .nuops = 4, .uops = { { _LOAD_ATTR_MODULE, 2, 1 }, { _LOAD_ATTR_MODULE, OPERAND1_1, 3 }, { _POP_TOP, OPARG_SIMPLE, 4 }, { _PUSH_NULL_CONDITIONAL, OPARG_SIMPLE, 9 } } },
[LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_NONDESCRIPTOR_NO_DICT, 4, 5 } } },
[LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { .nuops = 4, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT, OPARG_SIMPLE, 3 }, { _GUARD_KEYS_VERSION, 2, 3 }, { _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES, 4, 5 } } },
[LOAD_ATTR_PROPERTY] = { .nuops = 5, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_PROPERTY_FRAME, 4, 5 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 9 }, { _PUSH_FRAME, OPARG_SIMPLE, 9 } } },
- [LOAD_ATTR_SLOT] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_SLOT, 1, 3 }, { _PUSH_NULL_CONDITIONAL, OPARG_SIMPLE, 9 } } },
- [LOAD_ATTR_WITH_HINT] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_WITH_HINT, 1, 3 }, { _PUSH_NULL_CONDITIONAL, OPARG_SIMPLE, 9 } } },
+ [LOAD_ATTR_SLOT] = { .nuops = 4, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_SLOT, 1, 3 }, { _POP_TOP, OPARG_SIMPLE, 4 }, { _PUSH_NULL_CONDITIONAL, OPARG_SIMPLE, 9 } } },
+ [LOAD_ATTR_WITH_HINT] = { .nuops = 4, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_WITH_HINT, 1, 3 }, { _POP_TOP, OPARG_SIMPLE, 4 }, { _PUSH_NULL_CONDITIONAL, OPARG_SIMPLE, 9 } } },
[LOAD_BUILD_CLASS] = { .nuops = 1, .uops = { { _LOAD_BUILD_CLASS, OPARG_SIMPLE, 0 } } },
[LOAD_COMMON_CONSTANT] = { .nuops = 1, .uops = { { _LOAD_COMMON_CONSTANT, OPARG_SIMPLE, 0 } } },
[LOAD_CONST] = { .nuops = 1, .uops = { { _LOAD_CONST, OPARG_SIMPLE, 0 } } },
@@ -1482,29 +1500,29 @@ _PyOpcode_macro_expansion[256] = {
[SET_FUNCTION_ATTRIBUTE] = { .nuops = 1, .uops = { { _SET_FUNCTION_ATTRIBUTE, OPARG_SIMPLE, 0 } } },
[SET_UPDATE] = { .nuops = 1, .uops = { { _SET_UPDATE, OPARG_SIMPLE, 0 } } },
[STORE_ATTR] = { .nuops = 1, .uops = { { _STORE_ATTR, OPARG_SIMPLE, 3 } } },
- [STORE_ATTR_INSTANCE_VALUE] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION_AND_LOCK, 2, 1 }, { _GUARD_DORV_NO_DICT, OPARG_SIMPLE, 3 }, { _STORE_ATTR_INSTANCE_VALUE, 1, 3 } } },
- [STORE_ATTR_SLOT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _STORE_ATTR_SLOT, 1, 3 } } },
- [STORE_ATTR_WITH_HINT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _STORE_ATTR_WITH_HINT, 1, 3 } } },
+ [STORE_ATTR_INSTANCE_VALUE] = { .nuops = 4, .uops = { { _GUARD_TYPE_VERSION_AND_LOCK, 2, 1 }, { _GUARD_DORV_NO_DICT, OPARG_SIMPLE, 3 }, { _STORE_ATTR_INSTANCE_VALUE, 1, 3 }, { _POP_TOP, OPARG_SIMPLE, 4 } } },
+ [STORE_ATTR_SLOT] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _STORE_ATTR_SLOT, 1, 3 }, { _POP_TOP, OPARG_SIMPLE, 4 } } },
+ [STORE_ATTR_WITH_HINT] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _STORE_ATTR_WITH_HINT, 1, 3 }, { _POP_TOP, OPARG_SIMPLE, 4 } } },
[STORE_DEREF] = { .nuops = 1, .uops = { { _STORE_DEREF, OPARG_SIMPLE, 0 } } },
- [STORE_FAST] = { .nuops = 1, .uops = { { _STORE_FAST, OPARG_SIMPLE, 0 } } },
- [STORE_FAST_LOAD_FAST] = { .nuops = 2, .uops = { { _STORE_FAST, OPARG_TOP, 0 }, { _LOAD_FAST, OPARG_BOTTOM, 0 } } },
- [STORE_FAST_STORE_FAST] = { .nuops = 2, .uops = { { _STORE_FAST, OPARG_TOP, 0 }, { _STORE_FAST, OPARG_BOTTOM, 0 } } },
+ [STORE_FAST] = { .nuops = 2, .uops = { { _SWAP_FAST, OPARG_SIMPLE, 0 }, { _POP_TOP, OPARG_SIMPLE, 0 } } },
+ [STORE_FAST_LOAD_FAST] = { .nuops = 3, .uops = { { _SWAP_FAST, OPARG_TOP, 0 }, { _POP_TOP, OPARG_TOP, 0 }, { _LOAD_FAST, OPARG_BOTTOM, 0 } } },
+ [STORE_FAST_STORE_FAST] = { .nuops = 4, .uops = { { _SWAP_FAST, OPARG_TOP, 0 }, { _POP_TOP, OPARG_TOP, 0 }, { _SWAP_FAST, OPARG_BOTTOM, 0 }, { _POP_TOP, OPARG_BOTTOM, 0 } } },
[STORE_GLOBAL] = { .nuops = 1, .uops = { { _STORE_GLOBAL, OPARG_SIMPLE, 0 } } },
[STORE_NAME] = { .nuops = 1, .uops = { { _STORE_NAME, OPARG_SIMPLE, 0 } } },
[STORE_SLICE] = { .nuops = 1, .uops = { { _STORE_SLICE, OPARG_SIMPLE, 0 } } },
[STORE_SUBSCR] = { .nuops = 1, .uops = { { _STORE_SUBSCR, OPARG_SIMPLE, 0 } } },
- [STORE_SUBSCR_DICT] = { .nuops = 2, .uops = { { _GUARD_NOS_DICT, OPARG_SIMPLE, 0 }, { _STORE_SUBSCR_DICT, OPARG_SIMPLE, 1 } } },
- [STORE_SUBSCR_LIST_INT] = { .nuops = 3, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_LIST, OPARG_SIMPLE, 0 }, { _STORE_SUBSCR_LIST_INT, OPARG_SIMPLE, 1 } } },
+ [STORE_SUBSCR_DICT] = { .nuops = 3, .uops = { { _GUARD_NOS_DICT, OPARG_SIMPLE, 0 }, { _STORE_SUBSCR_DICT, OPARG_SIMPLE, 1 }, { _POP_TOP, OPARG_SIMPLE, 1 } } },
+ [STORE_SUBSCR_LIST_INT] = { .nuops = 5, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_LIST, OPARG_SIMPLE, 0 }, { _STORE_SUBSCR_LIST_INT, OPARG_SIMPLE, 1 }, { _POP_TOP_INT, OPARG_SIMPLE, 1 }, { _POP_TOP, OPARG_SIMPLE, 1 } } },
[SWAP] = { .nuops = 1, .uops = { { _SWAP, OPARG_SIMPLE, 0 } } },
[TO_BOOL] = { .nuops = 1, .uops = { { _TO_BOOL, OPARG_SIMPLE, 2 } } },
- [TO_BOOL_ALWAYS_TRUE] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _REPLACE_WITH_TRUE, OPARG_SIMPLE, 3 } } },
+ [TO_BOOL_ALWAYS_TRUE] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _REPLACE_WITH_TRUE, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 } } },
[TO_BOOL_BOOL] = { .nuops = 1, .uops = { { _TO_BOOL_BOOL, OPARG_SIMPLE, 3 } } },
- [TO_BOOL_INT] = { .nuops = 1, .uops = { { _TO_BOOL_INT, OPARG_SIMPLE, 3 } } },
- [TO_BOOL_LIST] = { .nuops = 2, .uops = { { _GUARD_TOS_LIST, OPARG_SIMPLE, 0 }, { _TO_BOOL_LIST, OPARG_SIMPLE, 3 } } },
+ [TO_BOOL_INT] = { .nuops = 3, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _TO_BOOL_INT, OPARG_SIMPLE, 3 }, { _POP_TOP_INT, OPARG_SIMPLE, 3 } } },
+ [TO_BOOL_LIST] = { .nuops = 3, .uops = { { _GUARD_TOS_LIST, OPARG_SIMPLE, 0 }, { _TO_BOOL_LIST, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 } } },
[TO_BOOL_NONE] = { .nuops = 1, .uops = { { _TO_BOOL_NONE, OPARG_SIMPLE, 3 } } },
- [TO_BOOL_STR] = { .nuops = 2, .uops = { { _GUARD_TOS_UNICODE, OPARG_SIMPLE, 0 }, { _TO_BOOL_STR, OPARG_SIMPLE, 3 } } },
- [UNARY_INVERT] = { .nuops = 1, .uops = { { _UNARY_INVERT, OPARG_SIMPLE, 0 } } },
- [UNARY_NEGATIVE] = { .nuops = 1, .uops = { { _UNARY_NEGATIVE, OPARG_SIMPLE, 0 } } },
+ [TO_BOOL_STR] = { .nuops = 3, .uops = { { _GUARD_TOS_UNICODE, OPARG_SIMPLE, 0 }, { _TO_BOOL_STR, OPARG_SIMPLE, 3 }, { _POP_TOP_UNICODE, OPARG_SIMPLE, 3 } } },
+ [UNARY_INVERT] = { .nuops = 2, .uops = { { _UNARY_INVERT, OPARG_SIMPLE, 0 }, { _POP_TOP, OPARG_SIMPLE, 0 } } },
+ [UNARY_NEGATIVE] = { .nuops = 2, .uops = { { _UNARY_NEGATIVE, OPARG_SIMPLE, 0 }, { _POP_TOP, OPARG_SIMPLE, 0 } } },
[UNARY_NOT] = { .nuops = 1, .uops = { { _UNARY_NOT, OPARG_SIMPLE, 0 } } },
[UNPACK_EX] = { .nuops = 1, .uops = { { _UNPACK_EX, OPARG_SIMPLE, 0 } } },
[UNPACK_SEQUENCE] = { .nuops = 1, .uops = { { _UNPACK_SEQUENCE, OPARG_SIMPLE, 0 } } },
@@ -1516,7 +1534,7 @@ _PyOpcode_macro_expansion[256] = {
};
#endif // NEED_OPCODE_METADATA
-extern const char *_PyOpcode_OpName[267];
+PyAPI_DATA(const char) *_PyOpcode_OpName[267];
#ifdef NEED_OPCODE_METADATA
const char *_PyOpcode_OpName[267] = {
[ANNOTATIONS_PLACEHOLDER] = "ANNOTATIONS_PLACEHOLDER",
@@ -1534,6 +1552,7 @@ const char *_PyOpcode_OpName[267] = {
[BINARY_OP_SUBSCR_LIST_SLICE] = "BINARY_OP_SUBSCR_LIST_SLICE",
[BINARY_OP_SUBSCR_STR_INT] = "BINARY_OP_SUBSCR_STR_INT",
[BINARY_OP_SUBSCR_TUPLE_INT] = "BINARY_OP_SUBSCR_TUPLE_INT",
+ [BINARY_OP_SUBSCR_USTR_INT] = "BINARY_OP_SUBSCR_USTR_INT",
[BINARY_OP_SUBTRACT_FLOAT] = "BINARY_OP_SUBTRACT_FLOAT",
[BINARY_OP_SUBTRACT_INT] = "BINARY_OP_SUBTRACT_INT",
[BINARY_SLICE] = "BINARY_SLICE",
@@ -1554,6 +1573,8 @@ const char *_PyOpcode_OpName[267] = {
[CALL_BUILTIN_FAST] = "CALL_BUILTIN_FAST",
[CALL_BUILTIN_FAST_WITH_KEYWORDS] = "CALL_BUILTIN_FAST_WITH_KEYWORDS",
[CALL_BUILTIN_O] = "CALL_BUILTIN_O",
+ [CALL_EX_NON_PY_GENERAL] = "CALL_EX_NON_PY_GENERAL",
+ [CALL_EX_PY] = "CALL_EX_PY",
[CALL_FUNCTION_EX] = "CALL_FUNCTION_EX",
[CALL_INTRINSIC_1] = "CALL_INTRINSIC_1",
[CALL_INTRINSIC_2] = "CALL_INTRINSIC_2",
@@ -1759,7 +1780,7 @@ const char *_PyOpcode_OpName[267] = {
};
#endif
-extern const uint8_t _PyOpcode_Caches[256];
+PyAPI_DATA(const uint8_t) _PyOpcode_Caches[256];
#ifdef NEED_OPCODE_METADATA
const uint8_t _PyOpcode_Caches[256] = {
[TO_BOOL] = 3,
@@ -1780,11 +1801,12 @@ const uint8_t _PyOpcode_Caches[256] = {
[FOR_ITER] = 1,
[CALL] = 3,
[CALL_KW] = 3,
+ [CALL_FUNCTION_EX] = 1,
[BINARY_OP] = 5,
};
#endif
-extern const uint8_t _PyOpcode_Deopt[256];
+PyAPI_DATA(const uint8_t) _PyOpcode_Deopt[256];
#ifdef NEED_OPCODE_METADATA
const uint8_t _PyOpcode_Deopt[256] = {
[121] = 121,
@@ -1794,9 +1816,6 @@ const uint8_t _PyOpcode_Deopt[256] = {
[125] = 125,
[126] = 126,
[127] = 127,
- [210] = 210,
- [211] = 211,
- [212] = 212,
[213] = 213,
[214] = 214,
[215] = 215,
@@ -1831,6 +1850,7 @@ const uint8_t _PyOpcode_Deopt[256] = {
[BINARY_OP_SUBSCR_LIST_SLICE] = BINARY_OP,
[BINARY_OP_SUBSCR_STR_INT] = BINARY_OP,
[BINARY_OP_SUBSCR_TUPLE_INT] = BINARY_OP,
+ [BINARY_OP_SUBSCR_USTR_INT] = BINARY_OP,
[BINARY_OP_SUBTRACT_FLOAT] = BINARY_OP,
[BINARY_OP_SUBTRACT_INT] = BINARY_OP,
[BINARY_SLICE] = BINARY_SLICE,
@@ -1851,6 +1871,8 @@ const uint8_t _PyOpcode_Deopt[256] = {
[CALL_BUILTIN_FAST] = CALL,
[CALL_BUILTIN_FAST_WITH_KEYWORDS] = CALL,
[CALL_BUILTIN_O] = CALL,
+ [CALL_EX_NON_PY_GENERAL] = CALL_FUNCTION_EX,
+ [CALL_EX_PY] = CALL_FUNCTION_EX,
[CALL_FUNCTION_EX] = CALL_FUNCTION_EX,
[CALL_INTRINSIC_1] = CALL_INTRINSIC_1,
[CALL_INTRINSIC_2] = CALL_INTRINSIC_2,
@@ -2055,9 +2077,6 @@ const uint8_t _PyOpcode_Deopt[256] = {
case 125: \
case 126: \
case 127: \
- case 210: \
- case 211: \
- case 212: \
case 213: \
case 214: \
case 215: \
diff --git a/Include/internal/pycore_opcode_utils.h b/Include/internal/pycore_opcode_utils.h
index 79a1a242556a52..e4d859fcc47d02 100644
--- a/Include/internal/pycore_opcode_utils.h
+++ b/Include/internal/pycore_opcode_utils.h
@@ -73,7 +73,9 @@ extern "C" {
#define CONSTANT_BUILTIN_TUPLE 2
#define CONSTANT_BUILTIN_ALL 3
#define CONSTANT_BUILTIN_ANY 4
-#define NUM_COMMON_CONSTANTS 5
+#define CONSTANT_BUILTIN_LIST 5
+#define CONSTANT_BUILTIN_SET 6
+#define NUM_COMMON_CONSTANTS 7
/* Values used in the oparg for RESUME */
#define RESUME_AT_FUNC_START 0
diff --git a/Include/internal/pycore_optimizer.h b/Include/internal/pycore_optimizer.h
index 295d4909e14735..89e08e86ed6982 100644
--- a/Include/internal/pycore_optimizer.h
+++ b/Include/internal/pycore_optimizer.h
@@ -12,22 +12,118 @@ extern "C" {
#include "pycore_uop.h" // _PyUOpInstruction
#include "pycore_uop_ids.h"
#include "pycore_stackref.h" // _PyStackRef
+#include "pycore_optimizer_types.h"
#include
+typedef struct _PyJitUopBuffer {
+ _PyUOpInstruction *start;
+ _PyUOpInstruction *next;
+ _PyUOpInstruction *end;
+} _PyJitUopBuffer;
+
+
+typedef struct _JitOptContext {
+ char done;
+ char out_of_space;
+ bool contradiction;
+ // Has the builtins dict been watched?
+ bool builtins_watched;
+ // The current "executing" frame.
+ _Py_UOpsAbstractFrame *frame;
+ _Py_UOpsAbstractFrame frames[MAX_ABSTRACT_FRAME_DEPTH];
+ int curr_frame_depth;
+
+ // Arena for the symbolic types.
+ ty_arena t_arena;
+
+ // Arena for the descriptor mappings.
+ descr_arena d_arena;
+
+ JitOptRef *n_consumed;
+ JitOptRef *limit;
+ JitOptRef locals_and_stack[MAX_ABSTRACT_INTERP_SIZE];
+ _PyJitUopBuffer out_buffer;
+ // Index of the last escaped uop in out_buffer.
+ int last_escape_index;
+} JitOptContext;
+
+
+static inline void
+uop_buffer_init(_PyJitUopBuffer *trace, _PyUOpInstruction *start, uint32_t size)
+{
+ trace->next = trace->start = start;
+ trace->end = start + size;
+}
+
+static inline _PyUOpInstruction *
+uop_buffer_last(_PyJitUopBuffer *trace)
+{
+ assert(trace->next > trace->start);
+ return trace->next-1;
+}
+
+static inline int
+uop_buffer_length(_PyJitUopBuffer *trace)
+{
+ return (int)(trace->next - trace->start);
+}
+
+static inline int
+uop_buffer_remaining_space(_PyJitUopBuffer *trace)
+{
+ return (int)(trace->end - trace->next);
+}
+
+typedef struct _PyJitTracerInitialState {
+ int stack_depth;
+ int chain_depth;
+ struct _PyExitData *exit;
+ PyCodeObject *code; // Strong
+ PyFunctionObject *func; // Strong
+ struct _PyExecutorObject *executor; // Strong
+ _Py_CODEUNIT *start_instr;
+ _Py_CODEUNIT *close_loop_instr;
+ _Py_CODEUNIT *jump_backward_instr;
+} _PyJitTracerInitialState;
+
+typedef struct _PyJitTracerPreviousState {
+ bool dependencies_still_valid;
+ int instr_oparg;
+ int instr_stacklevel;
+ _Py_CODEUNIT *instr;
+ PyCodeObject *instr_code; // Strong
+ struct _PyInterpreterFrame *instr_frame;
+ _PyBloomFilter dependencies;
+} _PyJitTracerPreviousState;
+
+typedef struct _PyJitTracerTranslatorState {
+ int jump_backward_seen;
+} _PyJitTracerTranslatorState;
+
+typedef struct _PyJitTracerState {
+ bool is_tracing;
+ _PyJitTracerInitialState initial_state;
+ _PyJitTracerPreviousState prev_state;
+ _PyJitTracerTranslatorState translator_state;
+ JitOptContext opt_context;
+ _PyJitUopBuffer code_buffer;
+ _PyJitUopBuffer out_buffer;
+ _PyUOpInstruction uop_array[2 * UOP_MAX_TRACE_LENGTH];
+} _PyJitTracerState;
+
typedef struct _PyExecutorLinkListNode {
struct _PyExecutorObject *next;
struct _PyExecutorObject *previous;
} _PyExecutorLinkListNode;
-
typedef struct {
uint8_t opcode;
uint8_t oparg;
uint8_t valid;
- uint8_t linked;
uint8_t chain_depth; // Must be big enough for MAX_CHAIN_DEPTH - 1.
- bool warm;
+ bool cold;
+ uint8_t pending_deletion;
int32_t index; // Index of ENTER_EXECUTOR (if code isn't NULL, below).
_PyBloomFilter bloom;
_PyExecutorLinkListNode links;
@@ -55,11 +151,6 @@ typedef struct _PyExecutorObject {
_PyExitData exits[1];
} _PyExecutorObject;
-/* If pending deletion list gets large enough, then scan,
- * and free any executors that aren't executing
- * i.e. any that aren't a thread's current_executor. */
-#define EXECUTOR_DELETE_LIST_MAX 100
-
// Export for '_opcode' shared extension (JIT compiler).
PyAPI_FUNC(_PyExecutorObject*) _Py_GetExecutor(PyCodeObject *code, int offset);
@@ -80,7 +171,6 @@ PyAPI_FUNC(void) _Py_Executors_InvalidateCold(PyInterpreterState *interp);
#else
# define _Py_Executors_InvalidateDependency(A, B, C) ((void)0)
# define _Py_Executors_InvalidateAll(A, B) ((void)0)
-# define _Py_Executors_InvalidateCold(A) ((void)0)
#endif
@@ -90,9 +180,9 @@ PyAPI_FUNC(void) _Py_Executors_InvalidateCold(PyInterpreterState *interp);
#define JIT_CLEANUP_THRESHOLD 1000
int _Py_uop_analyze_and_optimize(
- PyFunctionObject *func,
- _PyUOpInstruction *trace, int trace_len, int curr_stackentries,
- _PyBloomFilter *dependencies);
+ _PyThreadStateImpl *tstate,
+ _PyUOpInstruction *input, int trace_len, int curr_stackentries,
+ _PyUOpInstruction *output, _PyBloomFilter *dependencies);
extern PyTypeObject _PyUOpExecutor_Type;
@@ -118,90 +208,12 @@ static inline uint16_t uop_get_error_target(const _PyUOpInstruction *inst)
return inst->error_target;
}
-// Holds locals, stack, locals, stack ... co_consts (in that order)
-#define MAX_ABSTRACT_INTERP_SIZE 4096
-
-#define TY_ARENA_SIZE (UOP_MAX_TRACE_LENGTH * 5)
-
-// Need extras for root frame and for overflow frame (see TRACE_STACK_PUSH())
-#define MAX_ABSTRACT_FRAME_DEPTH (16)
-
-// The maximum number of side exits that we can take before requiring forward
-// progress (and inserting a new ENTER_EXECUTOR instruction). In practice, this
-// is the "maximum amount of polymorphism" that an isolated trace tree can
-// handle before rejoining the rest of the program.
-#define MAX_CHAIN_DEPTH 4
-
-/* Symbols */
-/* See explanation in optimizer_symbols.c */
-
-
-typedef enum _JitSymType {
- JIT_SYM_UNKNOWN_TAG = 1,
- JIT_SYM_NULL_TAG = 2,
- JIT_SYM_NON_NULL_TAG = 3,
- JIT_SYM_BOTTOM_TAG = 4,
- JIT_SYM_TYPE_VERSION_TAG = 5,
- JIT_SYM_KNOWN_CLASS_TAG = 6,
- JIT_SYM_KNOWN_VALUE_TAG = 7,
- JIT_SYM_TUPLE_TAG = 8,
- JIT_SYM_TRUTHINESS_TAG = 9,
- JIT_SYM_COMPACT_INT = 10,
-} JitSymType;
-
-typedef struct _jit_opt_known_class {
- uint8_t tag;
- uint32_t version;
- PyTypeObject *type;
-} JitOptKnownClass;
-
-typedef struct _jit_opt_known_version {
- uint8_t tag;
- uint32_t version;
-} JitOptKnownVersion;
-
-typedef struct _jit_opt_known_value {
- uint8_t tag;
- PyObject *value;
-} JitOptKnownValue;
-
-#define MAX_SYMBOLIC_TUPLE_SIZE 7
-
-typedef struct _jit_opt_tuple {
- uint8_t tag;
- uint8_t length;
- uint16_t items[MAX_SYMBOLIC_TUPLE_SIZE];
-} JitOptTuple;
-
-typedef struct {
- uint8_t tag;
- bool invert;
- uint16_t value;
-} JitOptTruthiness;
-
-typedef struct {
- uint8_t tag;
-} JitOptCompactInt;
-
-typedef union _jit_opt_symbol {
- uint8_t tag;
- JitOptKnownClass cls;
- JitOptKnownValue value;
- JitOptKnownVersion version;
- JitOptTuple tuple;
- JitOptTruthiness truthiness;
- JitOptCompactInt compact;
-} JitOptSymbol;
-
-
-// This mimics the _PyStackRef API
-typedef union {
- uintptr_t bits;
-} JitOptRef;
#define REF_IS_BORROWED 1
+#define REF_IS_INVALID 2
+#define REF_TAG_BITS 3
-#define JIT_BITS_TO_PTR_MASKED(REF) ((JitOptSymbol *)(((REF).bits) & (~REF_IS_BORROWED)))
+#define JIT_BITS_TO_PTR_MASKED(REF) ((JitOptSymbol *)(((REF).bits) & (~REF_TAG_BITS)))
static inline JitOptSymbol *
PyJitRef_Unwrap(JitOptRef ref)
@@ -218,6 +230,18 @@ PyJitRef_Wrap(JitOptSymbol *sym)
return (JitOptRef){.bits=(uintptr_t)sym};
}
+static inline JitOptRef
+PyJitRef_WrapInvalid(void *ptr)
+{
+ return (JitOptRef){.bits=(uintptr_t)ptr | REF_IS_INVALID};
+}
+
+static inline bool
+PyJitRef_IsInvalid(JitOptRef ref)
+{
+ return (ref.bits & REF_IS_INVALID) == REF_IS_INVALID;
+}
+
static inline JitOptRef
PyJitRef_StripReferenceInfo(JitOptRef ref)
{
@@ -244,48 +268,6 @@ PyJitRef_IsBorrowed(JitOptRef ref)
return (ref.bits & REF_IS_BORROWED) == REF_IS_BORROWED;
}
-struct _Py_UOpsAbstractFrame {
- bool globals_watched;
- // The version number of the globals dicts, once checked. 0 if unchecked.
- uint32_t globals_checked_version;
- // Max stacklen
- int stack_len;
- int locals_len;
- PyFunctionObject *func;
- PyCodeObject *code;
-
- JitOptRef *stack_pointer;
- JitOptRef *stack;
- JitOptRef *locals;
-};
-
-typedef struct _Py_UOpsAbstractFrame _Py_UOpsAbstractFrame;
-
-typedef struct ty_arena {
- int ty_curr_number;
- int ty_max_number;
- JitOptSymbol arena[TY_ARENA_SIZE];
-} ty_arena;
-
-typedef struct _JitOptContext {
- char done;
- char out_of_space;
- bool contradiction;
- // Has the builtins dict been watched?
- bool builtins_watched;
- // The current "executing" frame.
- _Py_UOpsAbstractFrame *frame;
- _Py_UOpsAbstractFrame frames[MAX_ABSTRACT_FRAME_DEPTH];
- int curr_frame_depth;
-
- // Arena for the symbolic types.
- ty_arena t_arena;
-
- JitOptRef *n_consumed;
- JitOptRef *limit;
- JitOptRef locals_and_stack[MAX_ABSTRACT_INTERP_SIZE];
-} JitOptContext;
-
extern bool _Py_uop_sym_is_null(JitOptRef sym);
extern bool _Py_uop_sym_is_not_null(JitOptRef sym);
extern bool _Py_uop_sym_is_const(JitOptContext *ctx, JitOptRef sym);
@@ -318,6 +300,11 @@ extern JitOptRef _Py_uop_sym_new_truthiness(JitOptContext *ctx, JitOptRef value,
extern bool _Py_uop_sym_is_compact_int(JitOptRef sym);
extern JitOptRef _Py_uop_sym_new_compact_int(JitOptContext *ctx);
extern void _Py_uop_sym_set_compact_int(JitOptContext *ctx, JitOptRef sym);
+extern JitOptRef _Py_uop_sym_new_descr_object(JitOptContext *ctx, unsigned int type_version);
+extern JitOptRef _Py_uop_sym_get_attr(JitOptContext *ctx, JitOptRef ref, uint16_t slot_index);
+extern JitOptRef _Py_uop_sym_set_attr(JitOptContext *ctx, JitOptRef ref, uint16_t slot_index, JitOptRef value);
+extern JitOptRef _Py_uop_sym_new_predicate(JitOptContext *ctx, JitOptRef lhs_ref, JitOptRef rhs_ref, JitOptPredicateKind kind);
+extern void _Py_uop_sym_apply_predicate_narrowing(JitOptContext *ctx, JitOptRef sym, bool branch_is_true);
extern void _Py_uop_abstractcontext_init(JitOptContext *ctx);
extern void _Py_uop_abstractcontext_fini(JitOptContext *ctx);
@@ -349,18 +336,19 @@ extern void _PyExecutor_Free(_PyExecutorObject *self);
PyAPI_FUNC(int) _PyDumpExecutors(FILE *out);
#ifdef _Py_TIER2
-extern void _Py_ClearExecutorDeletionList(PyInterpreterState *interp);
+PyAPI_FUNC(void) _Py_ClearExecutorDeletionList(PyInterpreterState *interp);
#endif
-int _PyJit_translate_single_bytecode_to_trace(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *next_instr, int stop_tracing_opcode);
+PyAPI_FUNC(int) _PyJit_translate_single_bytecode_to_trace(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *next_instr, int stop_tracing_opcode);
PyAPI_FUNC(int)
_PyJit_TryInitializeTracing(PyThreadState *tstate, _PyInterpreterFrame *frame,
_Py_CODEUNIT *curr_instr, _Py_CODEUNIT *start_instr,
_Py_CODEUNIT *close_loop_instr, int curr_stackdepth, int chain_depth, _PyExitData *exit,
- int oparg);
+ int oparg, _PyExecutorObject *current_executor);
-void _PyJit_FinalizeTracing(PyThreadState *tstate);
+PyAPI_FUNC(void) _PyJit_FinalizeTracing(PyThreadState *tstate, int err);
+void _PyJit_TracerFree(_PyThreadStateImpl *_tstate);
void _PyJit_Tracer_InvalidateDependency(PyThreadState *old_tstate, void *obj);
diff --git a/Include/internal/pycore_optimizer_types.h b/Include/internal/pycore_optimizer_types.h
new file mode 100644
index 00000000000000..1996ce10735736
--- /dev/null
+++ b/Include/internal/pycore_optimizer_types.h
@@ -0,0 +1,171 @@
+#ifndef Py_INTERNAL_OPTIMIZER_TYPES_H
+#define Py_INTERNAL_OPTIMIZER_TYPES_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+#include
+#include "pycore_uop.h" // UOP_MAX_TRACE_LENGTH
+
+// Holds locals, stack, locals, stack ... (in that order)
+#define MAX_ABSTRACT_INTERP_SIZE 512
+
+#define TY_ARENA_SIZE (UOP_MAX_TRACE_LENGTH * 5)
+
+// Maximum descriptor mappings per object tracked symbolically
+#define MAX_SYMBOLIC_DESCR_SIZE 16
+#define DESCR_ARENA_SIZE (MAX_SYMBOLIC_DESCR_SIZE * 100)
+
+// Need extras for root frame and for overflow frame (see TRACE_STACK_PUSH())
+#define MAX_ABSTRACT_FRAME_DEPTH (16)
+
+// The maximum number of side exits that we can take before requiring forward
+// progress (and inserting a new ENTER_EXECUTOR instruction). In practice, this
+// is the "maximum amount of polymorphism" that an isolated trace tree can
+// handle before rejoining the rest of the program.
+#define MAX_CHAIN_DEPTH 4
+
+/* Symbols */
+/* See explanation in optimizer_symbols.c */
+
+
+typedef enum _JitSymType {
+ JIT_SYM_UNKNOWN_TAG = 1,
+ JIT_SYM_NULL_TAG = 2,
+ JIT_SYM_NON_NULL_TAG = 3,
+ JIT_SYM_BOTTOM_TAG = 4,
+ JIT_SYM_TYPE_VERSION_TAG = 5,
+ JIT_SYM_KNOWN_CLASS_TAG = 6,
+ JIT_SYM_KNOWN_VALUE_TAG = 7,
+ JIT_SYM_TUPLE_TAG = 8,
+ JIT_SYM_TRUTHINESS_TAG = 9,
+ JIT_SYM_COMPACT_INT = 10,
+ JIT_SYM_PREDICATE_TAG = 11,
+ JIT_SYM_DESCR_TAG = 12,
+} JitSymType;
+
+typedef struct _jit_opt_known_class {
+ uint8_t tag;
+ uint32_t version;
+ PyTypeObject *type;
+} JitOptKnownClass;
+
+typedef struct _jit_opt_known_version {
+ uint8_t tag;
+ uint32_t version;
+} JitOptKnownVersion;
+
+typedef struct _jit_opt_known_value {
+ uint8_t tag;
+ PyObject *value;
+} JitOptKnownValue;
+
+#define MAX_SYMBOLIC_TUPLE_SIZE 7
+
+typedef struct _jit_opt_tuple {
+ uint8_t tag;
+ uint8_t length;
+ uint16_t items[MAX_SYMBOLIC_TUPLE_SIZE];
+} JitOptTuple;
+
+typedef struct {
+ uint8_t tag;
+ bool invert;
+ uint16_t value;
+} JitOptTruthiness;
+
+typedef enum {
+ JIT_PRED_IS,
+ JIT_PRED_IS_NOT,
+ JIT_PRED_EQ,
+ JIT_PRED_NE,
+} JitOptPredicateKind;
+
+typedef struct {
+ uint8_t tag;
+ uint8_t kind;
+ uint16_t lhs;
+ uint16_t rhs;
+} JitOptPredicate;
+
+typedef struct {
+ uint8_t tag;
+} JitOptCompactInt;
+
+/*
+Mapping from slot index or attribute offset to its symbolic value.
+SAFETY:
+This structure is used for both STORE_ATTR_SLOT and STORE_ATTR_INSTANCE_VALUE.
+These two never appear on the same object type because:
+__slots__ classes don't have Py_TPFLAGS_INLINE_VALUES
+Therefore, there is no index collision between slot offsets and inline value offsets.
+Note:
+STORE_ATTR_WITH_HINT is NOT currently tracked.
+If we want to track it in the future, we need to be careful about
+potential index collisions with STORE_ATTR_INSTANCE_VALUE.
+*/
+typedef struct {
+ uint16_t slot_index;
+ uint16_t symbol;
+} JitOptDescrMapping;
+
+typedef struct _jit_opt_descr {
+ uint8_t tag;
+ uint8_t num_descrs;
+ uint16_t last_modified_index; // Index in out_buffer when this object was last modified
+ uint32_t type_version;
+ JitOptDescrMapping *descrs;
+} JitOptDescrObject;
+
+typedef union _jit_opt_symbol {
+ uint8_t tag;
+ JitOptKnownClass cls;
+ JitOptKnownValue value;
+ JitOptKnownVersion version;
+ JitOptTuple tuple;
+ JitOptTruthiness truthiness;
+ JitOptCompactInt compact;
+ JitOptDescrObject descr;
+ JitOptPredicate predicate;
+} JitOptSymbol;
+
+// This mimics the _PyStackRef API
+typedef union {
+ uintptr_t bits;
+} JitOptRef;
+
+typedef struct _Py_UOpsAbstractFrame {
+ bool globals_watched;
+ // The version number of the globals dicts, once checked. 0 if unchecked.
+ uint32_t globals_checked_version;
+ // Max stacklen
+ int stack_len;
+ int locals_len;
+ PyFunctionObject *func;
+ PyCodeObject *code;
+
+ JitOptRef *stack_pointer;
+ JitOptRef *stack;
+ JitOptRef *locals;
+} _Py_UOpsAbstractFrame;
+
+typedef struct ty_arena {
+ int ty_curr_number;
+ int ty_max_number;
+ JitOptSymbol arena[TY_ARENA_SIZE];
+} ty_arena;
+
+typedef struct descr_arena {
+ int descr_curr_number;
+ int descr_max_number;
+ JitOptDescrMapping arena[DESCR_ARENA_SIZE];
+} descr_arena;
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_OPTIMIZER_TYPES_H */
diff --git a/Include/internal/pycore_parser.h b/Include/internal/pycore_parser.h
index 2c46f59ab7da9f..b89d02035db71f 100644
--- a/Include/internal/pycore_parser.h
+++ b/Include/internal/pycore_parser.h
@@ -14,10 +14,8 @@ extern "C" {
#include "pycore_pyarena.h" // PyArena
_Py_DECLARE_STR(empty, "")
-#if defined(Py_DEBUG) && defined(Py_GIL_DISABLED)
#define _parser_runtime_state_INIT \
{ \
- .mutex = {0}, \
.dummy_name = { \
.kind = Name_kind, \
.v.Name.id = &_Py_STR(empty), \
@@ -28,20 +26,6 @@ _Py_DECLARE_STR(empty, "")
.end_col_offset = 0, \
}, \
}
-#else
-#define _parser_runtime_state_INIT \
- { \
- .dummy_name = { \
- .kind = Name_kind, \
- .v.Name.id = &_Py_STR(empty), \
- .v.Name.ctx = Load, \
- .lineno = 1, \
- .col_offset = 0, \
- .end_lineno = 1, \
- .end_col_offset = 0, \
- }, \
- }
-#endif
extern struct _mod* _PyParser_ASTFromString(
const char *str,
diff --git a/Include/internal/pycore_pyatomic_ft_wrappers.h b/Include/internal/pycore_pyatomic_ft_wrappers.h
index 2ae0185226f847..70a32db663b293 100644
--- a/Include/internal/pycore_pyatomic_ft_wrappers.h
+++ b/Include/internal/pycore_pyatomic_ft_wrappers.h
@@ -31,6 +31,8 @@ extern "C" {
_Py_atomic_store_ptr(&value, new_value)
#define FT_ATOMIC_LOAD_PTR_ACQUIRE(value) \
_Py_atomic_load_ptr_acquire(&value)
+#define FT_ATOMIC_LOAD_PTR_CONSUME(value) \
+ _Py_atomic_load_ptr_consume(&value)
#define FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(value) \
_Py_atomic_load_uintptr_acquire(&value)
#define FT_ATOMIC_LOAD_PTR_RELAXED(value) \
@@ -39,6 +41,8 @@ extern "C" {
_Py_atomic_load_uint8(&value)
#define FT_ATOMIC_STORE_UINT8(value, new_value) \
_Py_atomic_store_uint8(&value, new_value)
+#define FT_ATOMIC_LOAD_INT8_RELAXED(value) \
+ _Py_atomic_load_int8_relaxed(&value)
#define FT_ATOMIC_LOAD_UINT8_RELAXED(value) \
_Py_atomic_load_uint8_relaxed(&value)
#define FT_ATOMIC_LOAD_UINT16_RELAXED(value) \
@@ -53,8 +57,14 @@ extern "C" {
_Py_atomic_store_ptr_release(&value, new_value)
#define FT_ATOMIC_STORE_UINTPTR_RELEASE(value, new_value) \
_Py_atomic_store_uintptr_release(&value, new_value)
+#define FT_ATOMIC_STORE_INT8_RELAXED(value, new_value) \
+ _Py_atomic_store_int8_relaxed(&value, new_value)
+#define FT_ATOMIC_STORE_INT8_RELEASE(value, new_value) \
+ _Py_atomic_store_int8_release(&value, new_value)
#define FT_ATOMIC_STORE_SSIZE_RELAXED(value, new_value) \
_Py_atomic_store_ssize_relaxed(&value, new_value)
+#define FT_ATOMIC_STORE_SSIZE_RELEASE(value, new_value) \
+ _Py_atomic_store_ssize_release(&value, new_value)
#define FT_ATOMIC_STORE_UINT8_RELAXED(value, new_value) \
_Py_atomic_store_uint8_relaxed(&value, new_value)
#define FT_ATOMIC_STORE_UINT16_RELAXED(value, new_value) \
@@ -125,10 +135,12 @@ extern "C" {
#define FT_ATOMIC_LOAD_SSIZE_ACQUIRE(value) value
#define FT_ATOMIC_LOAD_SSIZE_RELAXED(value) value
#define FT_ATOMIC_LOAD_PTR_ACQUIRE(value) value
+#define FT_ATOMIC_LOAD_PTR_CONSUME(value) value
#define FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(value) value
#define FT_ATOMIC_LOAD_PTR_RELAXED(value) value
#define FT_ATOMIC_LOAD_UINT8(value) value
#define FT_ATOMIC_STORE_UINT8(value, new_value) value = new_value
+#define FT_ATOMIC_LOAD_INT8_RELAXED(value) value
#define FT_ATOMIC_LOAD_UINT8_RELAXED(value) value
#define FT_ATOMIC_LOAD_UINT16_RELAXED(value) value
#define FT_ATOMIC_LOAD_UINT32_RELAXED(value) value
@@ -136,7 +148,10 @@ extern "C" {
#define FT_ATOMIC_STORE_PTR_RELAXED(value, new_value) value = new_value
#define FT_ATOMIC_STORE_PTR_RELEASE(value, new_value) value = new_value
#define FT_ATOMIC_STORE_UINTPTR_RELEASE(value, new_value) value = new_value
+#define FT_ATOMIC_STORE_INT8_RELAXED(value, new_value) value = new_value
+#define FT_ATOMIC_STORE_INT8_RELEASE(value, new_value) value = new_value
#define FT_ATOMIC_STORE_SSIZE_RELAXED(value, new_value) value = new_value
+#define FT_ATOMIC_STORE_SSIZE_RELEASE(value, new_value) value = new_value
#define FT_ATOMIC_STORE_UINT8_RELAXED(value, new_value) value = new_value
#define FT_ATOMIC_STORE_UINT16_RELAXED(value, new_value) value = new_value
#define FT_ATOMIC_STORE_UINT32_RELAXED(value, new_value) value = new_value
diff --git a/Include/internal/pycore_pyerrors.h b/Include/internal/pycore_pyerrors.h
index f80808fcc8c4d7..1023dbc3395b2f 100644
--- a/Include/internal/pycore_pyerrors.h
+++ b/Include/internal/pycore_pyerrors.h
@@ -11,8 +11,8 @@ extern "C" {
/* Error handling definitions */
-extern _PyErr_StackItem* _PyErr_GetTopmostException(PyThreadState *tstate);
-extern PyObject* _PyErr_GetHandledException(PyThreadState *);
+PyAPI_FUNC(_PyErr_StackItem*) _PyErr_GetTopmostException(PyThreadState *tstate);
+PyAPI_FUNC(PyObject*) _PyErr_GetHandledException(PyThreadState *);
extern void _PyErr_SetHandledException(PyThreadState *, PyObject *);
extern void _PyErr_GetExcInfo(PyThreadState *, PyObject **, PyObject **, PyObject **);
@@ -108,7 +108,7 @@ extern void _PyErr_Restore(
PyObject *value,
PyObject *traceback);
-extern void _PyErr_SetObject(
+PyAPI_FUNC(void) _PyErr_SetObject(
PyThreadState *tstate,
PyObject *type,
PyObject *value);
diff --git a/Include/internal/pycore_runtime_init_generated.h b/Include/internal/pycore_runtime_init_generated.h
index b32083db98e29e..ba7c0e68434517 100644
--- a/Include/internal/pycore_runtime_init_generated.h
+++ b/Include/internal/pycore_runtime_init_generated.h
@@ -1651,9 +1651,11 @@ extern "C" {
INIT_ID(co_varnames), \
INIT_ID(code), \
INIT_ID(col_offset), \
+ INIT_ID(collector), \
INIT_ID(command), \
INIT_ID(comment_factory), \
INIT_ID(compile_mode), \
+ INIT_ID(compression), \
INIT_ID(config), \
INIT_ID(consts), \
INIT_ID(context), \
@@ -1716,7 +1718,9 @@ extern "C" {
INIT_ID(event), \
INIT_ID(eventmask), \
INIT_ID(exc), \
+ INIT_ID(exc_tb), \
INIT_ID(exc_type), \
+ INIT_ID(exc_val), \
INIT_ID(exc_value), \
INIT_ID(excepthook), \
INIT_ID(exception), \
@@ -1791,6 +1795,7 @@ extern "C" {
INIT_ID(ident), \
INIT_ID(identity_hint), \
INIT_ID(ignore), \
+ INIT_ID(ignorechars), \
INIT_ID(imag), \
INIT_ID(implieslink), \
INIT_ID(importlib), \
@@ -1972,6 +1977,7 @@ extern "C" {
INIT_ID(print_file_and_line), \
INIT_ID(priority), \
INIT_ID(progress), \
+ INIT_ID(progress_callback), \
INIT_ID(progress_routine), \
INIT_ID(proto), \
INIT_ID(protocol), \
@@ -1992,6 +1998,7 @@ extern "C" {
INIT_ID(readline), \
INIT_ID(readonly), \
INIT_ID(real), \
+ INIT_ID(recursive), \
INIT_ID(reducer_override), \
INIT_ID(registry), \
INIT_ID(rel_tol), \
@@ -2011,6 +2018,7 @@ extern "C" {
INIT_ID(reversed), \
INIT_ID(rounding), \
INIT_ID(salt), \
+ INIT_ID(sample_interval_us), \
INIT_ID(sched_priority), \
INIT_ID(scheduler), \
INIT_ID(script), \
@@ -2050,8 +2058,10 @@ extern "C" {
INIT_ID(spam), \
INIT_ID(src), \
INIT_ID(src_dir_fd), \
+ INIT_ID(stack_frames), \
INIT_ID(stacklevel), \
INIT_ID(start), \
+ INIT_ID(start_time_us), \
INIT_ID(statement), \
INIT_ID(stats), \
INIT_ID(status), \
@@ -2092,6 +2102,7 @@ extern "C" {
INIT_ID(times), \
INIT_ID(timespec), \
INIT_ID(timestamp), \
+ INIT_ID(timestamp_us), \
INIT_ID(timetuple), \
INIT_ID(timeunit), \
INIT_ID(top), \
@@ -2130,6 +2141,7 @@ extern "C" {
INIT_ID(which), \
INIT_ID(who), \
INIT_ID(withdata), \
+ INIT_ID(wrapcol), \
INIT_ID(writable), \
INIT_ID(write), \
INIT_ID(write_through), \
diff --git a/Include/internal/pycore_runtime_structs.h b/Include/internal/pycore_runtime_structs.h
index 995f49e78dcda3..f48d203dda00fc 100644
--- a/Include/internal/pycore_runtime_structs.h
+++ b/Include/internal/pycore_runtime_structs.h
@@ -31,6 +31,7 @@ struct _pymem_allocators {
debug_alloc_api_t obj;
} debug;
int is_debug_enabled;
+ int use_hugepages;
PyObjectArenaAllocator obj_arena;
};
@@ -77,9 +78,7 @@ struct _fileutils_state {
struct _parser_runtime_state {
#ifdef Py_DEBUG
long memo_statistics[_PYPEGEN_NSTATISTICS];
-#ifdef Py_GIL_DISABLED
PyMutex mutex;
-#endif
#else
int _not_used;
#endif
diff --git a/Include/internal/pycore_stackref.h b/Include/internal/pycore_stackref.h
index 996f87874ee65a..69d667b4be47d2 100644
--- a/Include/internal/pycore_stackref.h
+++ b/Include/internal/pycore_stackref.h
@@ -452,184 +452,6 @@ PyStackRef_IncrementTaggedIntNoOverflow(_PyStackRef ref)
return (_PyStackRef){ .bits = ref.bits + (1 << Py_TAGGED_SHIFT) };
}
-#define PyStackRef_IsDeferredOrTaggedInt(ref) (((ref).bits & Py_TAG_REFCNT) != 0)
-
-#ifdef Py_GIL_DISABLED
-
-#define Py_TAG_DEFERRED Py_TAG_REFCNT
-
-#define Py_TAG_PTR ((uintptr_t)0)
-
-
-static const _PyStackRef PyStackRef_NULL = { .bits = Py_TAG_DEFERRED};
-
-#define PyStackRef_IsNull(stackref) ((stackref).bits == PyStackRef_NULL.bits)
-#define PyStackRef_True ((_PyStackRef){.bits = ((uintptr_t)&_Py_TrueStruct) | Py_TAG_DEFERRED })
-#define PyStackRef_False ((_PyStackRef){.bits = ((uintptr_t)&_Py_FalseStruct) | Py_TAG_DEFERRED })
-#define PyStackRef_None ((_PyStackRef){.bits = ((uintptr_t)&_Py_NoneStruct) | Py_TAG_DEFERRED })
-
-// Checks that mask out the deferred bit in the free threading build.
-#define PyStackRef_IsNone(ref) (PyStackRef_AsPyObjectBorrow(ref) == Py_None)
-#define PyStackRef_IsTrue(ref) (PyStackRef_AsPyObjectBorrow(ref) == Py_True)
-#define PyStackRef_IsFalse(ref) (PyStackRef_AsPyObjectBorrow(ref) == Py_False)
-
-#define PyStackRef_IsNullOrInt(stackref) (PyStackRef_IsNull(stackref) || PyStackRef_IsTaggedInt(stackref))
-
-static inline PyObject *
-PyStackRef_AsPyObjectBorrow(_PyStackRef stackref)
-{
- assert(!PyStackRef_IsTaggedInt(stackref));
- PyObject *cleared = ((PyObject *)((stackref).bits & (~Py_TAG_BITS)));
- return cleared;
-}
-
-#define PyStackRef_IsDeferred(ref) (((ref).bits & Py_TAG_BITS) == Py_TAG_DEFERRED)
-
-static inline PyObject *
-PyStackRef_AsPyObjectSteal(_PyStackRef stackref)
-{
- assert(!PyStackRef_IsNull(stackref));
- if (PyStackRef_IsDeferred(stackref)) {
- return Py_NewRef(PyStackRef_AsPyObjectBorrow(stackref));
- }
- return PyStackRef_AsPyObjectBorrow(stackref);
-}
-
-static inline _PyStackRef
-_PyStackRef_FromPyObjectSteal(PyObject *obj)
-{
- assert(obj != NULL);
- // Make sure we don't take an already tagged value.
- assert(((uintptr_t)obj & Py_TAG_BITS) == 0);
- return (_PyStackRef){ .bits = (uintptr_t)obj };
-}
-# define PyStackRef_FromPyObjectSteal(obj) _PyStackRef_FromPyObjectSteal(_PyObject_CAST(obj))
-
-static inline bool
-PyStackRef_IsHeapSafe(_PyStackRef stackref)
-{
- if (PyStackRef_IsDeferred(stackref)) {
- PyObject *obj = PyStackRef_AsPyObjectBorrow(stackref);
- return obj == NULL || _Py_IsImmortal(obj) || _PyObject_HasDeferredRefcount(obj);
- }
- return true;
-}
-
-static inline _PyStackRef
-PyStackRef_MakeHeapSafe(_PyStackRef stackref)
-{
- if (PyStackRef_IsHeapSafe(stackref)) {
- return stackref;
- }
- PyObject *obj = PyStackRef_AsPyObjectBorrow(stackref);
- return (_PyStackRef){ .bits = (uintptr_t)(Py_NewRef(obj)) | Py_TAG_PTR };
-}
-
-static inline _PyStackRef
-PyStackRef_FromPyObjectStealMortal(PyObject *obj)
-{
- assert(obj != NULL);
- assert(!_Py_IsImmortal(obj));
- // Make sure we don't take an already tagged value.
- assert(((uintptr_t)obj & Py_TAG_BITS) == 0);
- return (_PyStackRef){ .bits = (uintptr_t)obj };
-}
-
-static inline _PyStackRef
-PyStackRef_FromPyObjectNew(PyObject *obj)
-{
- // Make sure we don't take an already tagged value.
- assert(((uintptr_t)obj & Py_TAG_BITS) == 0);
- assert(obj != NULL);
- if (_PyObject_HasDeferredRefcount(obj)) {
- return (_PyStackRef){ .bits = (uintptr_t)obj | Py_TAG_DEFERRED };
- }
- else {
- return (_PyStackRef){ .bits = (uintptr_t)(Py_NewRef(obj)) | Py_TAG_PTR };
- }
-}
-#define PyStackRef_FromPyObjectNew(obj) PyStackRef_FromPyObjectNew(_PyObject_CAST(obj))
-
-static inline _PyStackRef
-PyStackRef_FromPyObjectBorrow(PyObject *obj)
-{
- // Make sure we don't take an already tagged value.
- assert(((uintptr_t)obj & Py_TAG_BITS) == 0);
- assert(obj != NULL);
- return (_PyStackRef){ .bits = (uintptr_t)obj | Py_TAG_DEFERRED };
-}
-#define PyStackRef_FromPyObjectBorrow(obj) PyStackRef_FromPyObjectBorrow(_PyObject_CAST(obj))
-
-#define PyStackRef_CLOSE(REF) \
- do { \
- _PyStackRef _close_tmp = (REF); \
- assert(!PyStackRef_IsNull(_close_tmp)); \
- if (!PyStackRef_IsDeferredOrTaggedInt(_close_tmp)) { \
- Py_DECREF(PyStackRef_AsPyObjectBorrow(_close_tmp)); \
- } \
- } while (0)
-
-static inline void
-PyStackRef_CLOSE_SPECIALIZED(_PyStackRef ref, destructor destruct)
-{
- (void)destruct;
- PyStackRef_CLOSE(ref);
-}
-
-static inline int
-PyStackRef_RefcountOnObject(_PyStackRef ref)
-{
- return (ref.bits & Py_TAG_REFCNT) == 0;
-}
-
-static inline _PyStackRef
-PyStackRef_DUP(_PyStackRef stackref)
-{
- assert(!PyStackRef_IsNull(stackref));
- if (PyStackRef_IsDeferredOrTaggedInt(stackref)) {
- return stackref;
- }
- Py_INCREF(PyStackRef_AsPyObjectBorrow(stackref));
- return stackref;
-}
-
-static inline _PyStackRef
-PyStackRef_Borrow(_PyStackRef stackref)
-{
- return (_PyStackRef){ .bits = stackref.bits | Py_TAG_DEFERRED };
-}
-
-// Convert a possibly deferred reference to a strong reference.
-static inline _PyStackRef
-PyStackRef_AsStrongReference(_PyStackRef stackref)
-{
- return PyStackRef_FromPyObjectSteal(PyStackRef_AsPyObjectSteal(stackref));
-}
-
-#define PyStackRef_XCLOSE(stackref) \
- do { \
- _PyStackRef _tmp = (stackref); \
- if (!PyStackRef_IsNull(_tmp)) { \
- PyStackRef_CLOSE(_tmp); \
- } \
- } while (0);
-
-#define PyStackRef_CLEAR(op) \
- do { \
- _PyStackRef *_tmp_op_ptr = &(op); \
- _PyStackRef _tmp_old_op = (*_tmp_op_ptr); \
- if (!PyStackRef_IsNull(_tmp_old_op)) { \
- *_tmp_op_ptr = PyStackRef_NULL; \
- PyStackRef_CLOSE(_tmp_old_op); \
- } \
- } while (0)
-
-#define PyStackRef_FromPyObjectNewMortal PyStackRef_FromPyObjectNew
-
-#else // Py_GIL_DISABLED
-
-// With GIL
-
/* References to immortal objects always have their tag bit set to Py_TAG_REFCNT
* as they can (must) have their reclamation deferred */
@@ -648,13 +470,24 @@ static const _PyStackRef PyStackRef_NULL = { .bits = PyStackRef_NULL_BITS };
#define PyStackRef_False ((_PyStackRef){.bits = ((uintptr_t)&_Py_FalseStruct) | Py_TAG_REFCNT })
#define PyStackRef_None ((_PyStackRef){.bits = ((uintptr_t)&_Py_NoneStruct) | Py_TAG_REFCNT })
+#ifdef Py_GIL_DISABLED
+// Checks that mask out the deferred bit in the free threading build.
+#define PyStackRef_IsNone(REF) (((REF).bits & ~Py_TAG_REFCNT) == (uintptr_t)&_Py_NoneStruct)
+#define PyStackRef_IsTrue(REF) (((REF).bits & ~Py_TAG_REFCNT) == (uintptr_t)&_Py_TrueStruct)
+#define PyStackRef_IsFalse(REF) (((REF).bits & ~Py_TAG_REFCNT) == (uintptr_t)&_Py_FalseStruct)
+#else
#define PyStackRef_IsTrue(REF) ((REF).bits == (((uintptr_t)&_Py_TrueStruct) | Py_TAG_REFCNT))
#define PyStackRef_IsFalse(REF) ((REF).bits == (((uintptr_t)&_Py_FalseStruct) | Py_TAG_REFCNT))
#define PyStackRef_IsNone(REF) ((REF).bits == (((uintptr_t)&_Py_NoneStruct) | Py_TAG_REFCNT))
+#endif
-#ifdef Py_DEBUG
+#define PyStackRef_IsNullOrInt(stackref) (PyStackRef_IsNull(stackref) || PyStackRef_IsTaggedInt(stackref))
+
+#if defined(Py_DEBUG) && !defined(Py_GIL_DISABLED)
-static inline void PyStackRef_CheckValid(_PyStackRef ref) {
+static inline void
+PyStackRef_CheckValid(_PyStackRef ref)
+{
assert(ref.bits != 0);
int tag = ref.bits & Py_TAG_BITS;
PyObject *obj = BITS_TO_PTR_MASKED(ref);
@@ -705,6 +538,8 @@ PyStackRef_Borrow(_PyStackRef ref)
static inline PyObject *
PyStackRef_AsPyObjectSteal(_PyStackRef ref)
{
+ assert(!PyStackRef_IsNull(ref));
+ assert(!PyStackRef_IsTaggedInt(ref));
if (PyStackRef_RefcountOnObject(ref)) {
return BITS_TO_PTR(ref);
}
@@ -717,14 +552,18 @@ static inline _PyStackRef
PyStackRef_FromPyObjectSteal(PyObject *obj)
{
assert(obj != NULL);
-#if SIZEOF_VOID_P > 4
- unsigned int tag = obj->ob_flags & Py_TAG_REFCNT;
+#ifdef Py_GIL_DISABLED
+ return (_PyStackRef){ .bits = (uintptr_t)obj };
#else
+# if SIZEOF_VOID_P > 4
+ unsigned int tag = obj->ob_flags & Py_TAG_REFCNT;
+# else
unsigned int tag = _Py_IsImmortal(obj) ? Py_TAG_REFCNT : 0;
-#endif
+# endif
_PyStackRef ref = ((_PyStackRef){.bits = ((uintptr_t)(obj)) | tag});
PyStackRef_CheckValid(ref);
return ref;
+#endif
}
static inline _PyStackRef
@@ -732,7 +571,7 @@ PyStackRef_FromPyObjectStealMortal(PyObject *obj)
{
assert(obj != NULL);
assert(!_Py_IsImmortal(obj));
- _PyStackRef ref = ((_PyStackRef){.bits = ((uintptr_t)(obj)) });
+ _PyStackRef ref = (_PyStackRef){ .bits = (uintptr_t)obj };
PyStackRef_CheckValid(ref);
return ref;
}
@@ -741,9 +580,15 @@ static inline _PyStackRef
_PyStackRef_FromPyObjectNew(PyObject *obj)
{
assert(obj != NULL);
+#ifdef Py_GIL_DISABLED
+ if (_PyObject_HasDeferredRefcount(obj)) {
+ return (_PyStackRef){ .bits = (uintptr_t)obj | Py_TAG_REFCNT };
+ }
+#else
if (_Py_IsImmortal(obj)) {
- return (_PyStackRef){ .bits = ((uintptr_t)obj) | Py_TAG_REFCNT};
+ return (_PyStackRef){ .bits = (uintptr_t)obj | Py_TAG_REFCNT };
}
+#endif
_Py_INCREF_MORTAL(obj);
_PyStackRef ref = (_PyStackRef){ .bits = (uintptr_t)obj };
PyStackRef_CheckValid(ref);
@@ -766,6 +611,7 @@ _PyStackRef_FromPyObjectNewMortal(PyObject *obj)
static inline _PyStackRef
PyStackRef_FromPyObjectBorrow(PyObject *obj)
{
+ assert(obj != NULL);
return (_PyStackRef){ .bits = (uintptr_t)obj | Py_TAG_REFCNT};
}
@@ -788,7 +634,15 @@ PyStackRef_DUP(_PyStackRef ref)
static inline bool
PyStackRef_IsHeapSafe(_PyStackRef ref)
{
- return (ref.bits & Py_TAG_BITS) != Py_TAG_REFCNT || ref.bits == PyStackRef_NULL_BITS || _Py_IsImmortal(BITS_TO_PTR_MASKED(ref));
+#ifdef Py_GIL_DISABLED
+ if ((ref.bits & Py_TAG_BITS) != Py_TAG_REFCNT) {
+ return true;
+ }
+ PyObject *obj = BITS_TO_PTR_MASKED(ref);
+ return obj == NULL || _PyObject_HasDeferredRefcount(obj);
+#else
+ return (ref.bits & Py_TAG_BITS) != Py_TAG_REFCNT || ref.bits == PyStackRef_NULL_BITS || _Py_IsImmortal(BITS_TO_PTR_MASKED(ref));
+#endif
}
static inline _PyStackRef
@@ -804,6 +658,13 @@ PyStackRef_MakeHeapSafe(_PyStackRef ref)
return ref;
}
+// Convert a possibly deferred reference to a strong reference.
+static inline _PyStackRef
+PyStackRef_AsStrongReference(_PyStackRef stackref)
+{
+ return PyStackRef_FromPyObjectSteal(PyStackRef_AsPyObjectSteal(stackref));
+}
+
#ifdef _WIN32
#define PyStackRef_CLOSE(REF) \
do { \
@@ -821,12 +682,6 @@ PyStackRef_CLOSE(_PyStackRef ref)
}
#endif
-static inline bool
-PyStackRef_IsNullOrInt(_PyStackRef ref)
-{
- return PyStackRef_IsNull(ref) || PyStackRef_IsTaggedInt(ref);
-}
-
static inline void
PyStackRef_CLOSE_SPECIALIZED(_PyStackRef ref, destructor destruct)
{
@@ -859,8 +714,6 @@ PyStackRef_XCLOSE(_PyStackRef ref)
} while (0)
-#endif // Py_GIL_DISABLED
-
// Note: this is a macro because MSVC (Windows) has trouble inlining it.
#define PyStackRef_Is(a, b) (((a).bits & (~Py_TAG_REFCNT)) == ((b).bits & (~Py_TAG_REFCNT)))
@@ -945,7 +798,7 @@ static inline int
_Py_TryIncrefCompareStackRef(PyObject **src, PyObject *op, _PyStackRef *out)
{
if (_PyObject_HasDeferredRefcount(op)) {
- *out = (_PyStackRef){ .bits = (uintptr_t)op | Py_TAG_DEFERRED };
+ *out = (_PyStackRef){ .bits = (uintptr_t)op | Py_TAG_REFCNT };
return 1;
}
if (_Py_TryIncrefCompare(src, op)) {
diff --git a/Include/internal/pycore_tracemalloc.h b/Include/internal/pycore_tracemalloc.h
index 693385f9a46d12..9974ea3c4143fa 100644
--- a/Include/internal/pycore_tracemalloc.h
+++ b/Include/internal/pycore_tracemalloc.h
@@ -21,7 +21,10 @@ struct _PyTraceMalloc_Config {
} initialized;
/* Is tracemalloc tracing memory allocations?
- Variable protected by the TABLES_LOCK(). */
+ Variable protected by the TABLES_LOCK() and stored atomically.
+ Atomic store is used so that it can read without locking for the
+ general case of checking if tracemalloc is enabled.
+ */
int tracing;
/* limit of the number of frames in a traceback, 1 by default.
diff --git a/Include/internal/pycore_tstate.h b/Include/internal/pycore_tstate.h
index c4f723ac8abbbe..64b90710b8e664 100644
--- a/Include/internal/pycore_tstate.h
+++ b/Include/internal/pycore_tstate.h
@@ -23,37 +23,6 @@ struct _gc_thread_state {
};
#endif
-#if _Py_TIER2
-typedef struct _PyJitTracerInitialState {
- int stack_depth;
- int chain_depth;
- struct _PyExitData *exit;
- PyCodeObject *code; // Strong
- PyFunctionObject *func; // Strong
- _Py_CODEUNIT *start_instr;
- _Py_CODEUNIT *close_loop_instr;
- _Py_CODEUNIT *jump_backward_instr;
-} _PyJitTracerInitialState;
-
-typedef struct _PyJitTracerPreviousState {
- bool dependencies_still_valid;
- bool instr_is_super;
- int code_max_size;
- int code_curr_size;
- int instr_oparg;
- int instr_stacklevel;
- _Py_CODEUNIT *instr;
- PyCodeObject *instr_code; // Strong
- struct _PyInterpreterFrame *instr_frame;
- _PyBloomFilter dependencies;
-} _PyJitTracerPreviousState;
-
-typedef struct _PyJitTracerState {
- _PyUOpInstruction *code_buffer;
- _PyJitTracerInitialState initial_state;
- _PyJitTracerPreviousState prev_state;
-} _PyJitTracerState;
-#endif
// Every PyThreadState is actually allocated as a _PyThreadStateImpl. The
// PyThreadState fields are exposed as part of the C API, although most fields
@@ -82,6 +51,13 @@ typedef struct _PyThreadStateImpl {
PyObject *asyncio_running_loop; // Strong reference
PyObject *asyncio_running_task; // Strong reference
+ // Distinguishes between yield and return from PyEval_EvalFrame().
+ // See gen_send_ex2() in Objects/genobject.c
+ enum {
+ GENERATOR_RETURN = 0,
+ GENERATOR_YIELD = 1,
+ } generator_return_kind;
+
/* Head of circular linked-list of all tasks which are instances of `asyncio.Task`
or subclasses of it used in `asyncio.all_tasks`.
*/
@@ -124,7 +100,7 @@ typedef struct _PyThreadStateImpl {
Py_ssize_t reftotal; // this thread's total refcount operations
#endif
#if _Py_TIER2
- _PyJitTracerState jit_tracer_state;
+ struct _PyJitTracerState *jit_tracer_state;
#endif
} _PyThreadStateImpl;
diff --git a/Include/internal/pycore_unicodeobject_generated.h b/Include/internal/pycore_unicodeobject_generated.h
index f3756fde2c4073..44063794293990 100644
--- a/Include/internal/pycore_unicodeobject_generated.h
+++ b/Include/internal/pycore_unicodeobject_generated.h
@@ -1284,6 +1284,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(collector);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(command);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -1296,6 +1300,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(compression);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(config);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -1544,10 +1552,18 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(exc_tb);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(exc_type);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(exc_val);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(exc_value);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -1844,6 +1860,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(ignorechars);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(imag);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -2568,6 +2588,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(progress_callback);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(progress_routine);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -2648,6 +2672,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(recursive);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(reducer_override);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -2724,6 +2752,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(sample_interval_us);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(sched_priority);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -2880,6 +2912,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(stack_frames);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(stacklevel);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -2888,6 +2924,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(start_time_us);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(statement);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -3048,6 +3088,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(timestamp_us);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(timetuple);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -3200,6 +3244,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(wrapcol);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(writable);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
diff --git a/Include/internal/pycore_uop.h b/Include/internal/pycore_uop.h
index e828a1cc5a5722..f9be01acb57197 100644
--- a/Include/internal/pycore_uop.h
+++ b/Include/internal/pycore_uop.h
@@ -38,11 +38,10 @@ typedef struct _PyUOpInstruction{
// This is the length of the trace we translate initially.
#ifdef Py_DEBUG
// With asserts, the stencils are a lot larger
-#define UOP_MAX_TRACE_LENGTH 2000
+#define UOP_MAX_TRACE_LENGTH 1000
#else
-#define UOP_MAX_TRACE_LENGTH 5000
+#define UOP_MAX_TRACE_LENGTH 2500
#endif
-#define UOP_BUFFER_SIZE (UOP_MAX_TRACE_LENGTH * sizeof(_PyUOpInstruction))
/* Bloom filter with m = 256
* https://en.wikipedia.org/wiki/Bloom_filter */
diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h
index ce1ad5a4c8a5f6..a1abe168605cd5 100644
--- a/Include/internal/pycore_uop_ids.h
+++ b/Include/internal/pycore_uop_ids.h
@@ -13,25 +13,23 @@ extern "C" {
#define _SET_IP 301
#define _BINARY_OP 302
#define _BINARY_OP_ADD_FLOAT 303
-#define _BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS 304
-#define _BINARY_OP_ADD_INT 305
-#define _BINARY_OP_ADD_UNICODE 306
-#define _BINARY_OP_EXTEND 307
-#define _BINARY_OP_INPLACE_ADD_UNICODE 308
-#define _BINARY_OP_MULTIPLY_FLOAT 309
-#define _BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS 310
-#define _BINARY_OP_MULTIPLY_INT 311
-#define _BINARY_OP_SUBSCR_CHECK_FUNC 312
-#define _BINARY_OP_SUBSCR_DICT 313
-#define _BINARY_OP_SUBSCR_INIT_CALL 314
-#define _BINARY_OP_SUBSCR_LIST_INT 315
-#define _BINARY_OP_SUBSCR_LIST_SLICE 316
-#define _BINARY_OP_SUBSCR_STR_INT 317
-#define _BINARY_OP_SUBSCR_TUPLE_INT 318
-#define _BINARY_OP_SUBTRACT_FLOAT 319
-#define _BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS 320
-#define _BINARY_OP_SUBTRACT_INT 321
-#define _BINARY_SLICE 322
+#define _BINARY_OP_ADD_INT 304
+#define _BINARY_OP_ADD_UNICODE 305
+#define _BINARY_OP_EXTEND 306
+#define _BINARY_OP_INPLACE_ADD_UNICODE 307
+#define _BINARY_OP_MULTIPLY_FLOAT 308
+#define _BINARY_OP_MULTIPLY_INT 309
+#define _BINARY_OP_SUBSCR_CHECK_FUNC 310
+#define _BINARY_OP_SUBSCR_DICT 311
+#define _BINARY_OP_SUBSCR_INIT_CALL 312
+#define _BINARY_OP_SUBSCR_LIST_INT 313
+#define _BINARY_OP_SUBSCR_LIST_SLICE 314
+#define _BINARY_OP_SUBSCR_STR_INT 315
+#define _BINARY_OP_SUBSCR_TUPLE_INT 316
+#define _BINARY_OP_SUBSCR_USTR_INT 317
+#define _BINARY_OP_SUBTRACT_FLOAT 318
+#define _BINARY_OP_SUBTRACT_INT 319
+#define _BINARY_SLICE 320
#define _BUILD_INTERPOLATION BUILD_INTERPOLATION
#define _BUILD_LIST BUILD_LIST
#define _BUILD_MAP BUILD_MAP
@@ -40,148 +38,166 @@ extern "C" {
#define _BUILD_STRING BUILD_STRING
#define _BUILD_TEMPLATE BUILD_TEMPLATE
#define _BUILD_TUPLE BUILD_TUPLE
-#define _CALL_BUILTIN_CLASS 323
-#define _CALL_BUILTIN_FAST 324
-#define _CALL_BUILTIN_FAST_WITH_KEYWORDS 325
-#define _CALL_BUILTIN_O 326
+#define _CALL_BUILTIN_CLASS 321
+#define _CALL_BUILTIN_FAST 322
+#define _CALL_BUILTIN_FAST_WITH_KEYWORDS 323
+#define _CALL_BUILTIN_O 324
+#define _CALL_FUNCTION_EX_NON_PY_GENERAL 325
#define _CALL_INTRINSIC_1 CALL_INTRINSIC_1
#define _CALL_INTRINSIC_2 CALL_INTRINSIC_2
-#define _CALL_ISINSTANCE 327
-#define _CALL_KW_NON_PY 328
-#define _CALL_LEN 329
-#define _CALL_LIST_APPEND 330
-#define _CALL_METHOD_DESCRIPTOR_FAST 331
-#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 332
-#define _CALL_METHOD_DESCRIPTOR_NOARGS 333
-#define _CALL_METHOD_DESCRIPTOR_O 334
-#define _CALL_NON_PY_GENERAL 335
-#define _CALL_STR_1 336
-#define _CALL_TUPLE_1 337
-#define _CALL_TYPE_1 338
-#define _CHECK_AND_ALLOCATE_OBJECT 339
-#define _CHECK_ATTR_CLASS 340
-#define _CHECK_ATTR_METHOD_LAZY_DICT 341
-#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS 342
+#define _CALL_ISINSTANCE 326
+#define _CALL_KW_NON_PY 327
+#define _CALL_LEN 328
+#define _CALL_LIST_APPEND 329
+#define _CALL_METHOD_DESCRIPTOR_FAST 330
+#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 331
+#define _CALL_METHOD_DESCRIPTOR_NOARGS 332
+#define _CALL_METHOD_DESCRIPTOR_O 333
+#define _CALL_NON_PY_GENERAL 334
+#define _CALL_STR_1 335
+#define _CALL_TUPLE_1 336
+#define _CALL_TYPE_1 337
+#define _CHECK_AND_ALLOCATE_OBJECT 338
+#define _CHECK_ATTR_CLASS 339
+#define _CHECK_ATTR_METHOD_LAZY_DICT 340
+#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS 341
#define _CHECK_EG_MATCH CHECK_EG_MATCH
#define _CHECK_EXC_MATCH CHECK_EXC_MATCH
-#define _CHECK_FUNCTION_EXACT_ARGS 343
-#define _CHECK_FUNCTION_VERSION 344
-#define _CHECK_FUNCTION_VERSION_INLINE 345
-#define _CHECK_FUNCTION_VERSION_KW 346
-#define _CHECK_IS_NOT_PY_CALLABLE 347
+#define _CHECK_FUNCTION_EXACT_ARGS 342
+#define _CHECK_FUNCTION_VERSION 343
+#define _CHECK_FUNCTION_VERSION_INLINE 344
+#define _CHECK_FUNCTION_VERSION_KW 345
+#define _CHECK_IS_NOT_PY_CALLABLE 346
+#define _CHECK_IS_NOT_PY_CALLABLE_EX 347
#define _CHECK_IS_NOT_PY_CALLABLE_KW 348
-#define _CHECK_MANAGED_OBJECT_HAS_VALUES 349
-#define _CHECK_METHOD_VERSION 350
-#define _CHECK_METHOD_VERSION_KW 351
-#define _CHECK_PEP_523 352
-#define _CHECK_PERIODIC 353
-#define _CHECK_PERIODIC_AT_END 354
-#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM 355
-#define _CHECK_RECURSION_REMAINING 356
-#define _CHECK_STACK_SPACE 357
-#define _CHECK_STACK_SPACE_OPERAND 358
-#define _CHECK_VALIDITY 359
-#define _COLD_DYNAMIC_EXIT 360
-#define _COLD_EXIT 361
-#define _COMPARE_OP 362
-#define _COMPARE_OP_FLOAT 363
-#define _COMPARE_OP_INT 364
-#define _COMPARE_OP_STR 365
-#define _CONTAINS_OP 366
-#define _CONTAINS_OP_DICT 367
-#define _CONTAINS_OP_SET 368
+#define _CHECK_IS_PY_CALLABLE_EX 349
+#define _CHECK_MANAGED_OBJECT_HAS_VALUES 350
+#define _CHECK_METHOD_VERSION 351
+#define _CHECK_METHOD_VERSION_KW 352
+#define _CHECK_PEP_523 353
+#define _CHECK_PERIODIC 354
+#define _CHECK_PERIODIC_AT_END 355
+#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM 356
+#define _CHECK_RECURSION_REMAINING 357
+#define _CHECK_STACK_SPACE 358
+#define _CHECK_STACK_SPACE_OPERAND 359
+#define _CHECK_VALIDITY 360
+#define _COLD_DYNAMIC_EXIT 361
+#define _COLD_EXIT 362
+#define _COMPARE_OP 363
+#define _COMPARE_OP_FLOAT 364
+#define _COMPARE_OP_INT 365
+#define _COMPARE_OP_STR 366
+#define _CONTAINS_OP 367
+#define _CONTAINS_OP_DICT 368
+#define _CONTAINS_OP_SET 369
#define _CONVERT_VALUE CONVERT_VALUE
-#define _COPY 369
-#define _COPY_1 370
-#define _COPY_2 371
-#define _COPY_3 372
+#define _COPY 370
+#define _COPY_1 371
+#define _COPY_2 372
+#define _COPY_3 373
#define _COPY_FREE_VARS COPY_FREE_VARS
-#define _CREATE_INIT_FRAME 373
+#define _CREATE_INIT_FRAME 374
#define _DELETE_ATTR DELETE_ATTR
#define _DELETE_DEREF DELETE_DEREF
#define _DELETE_FAST DELETE_FAST
#define _DELETE_GLOBAL DELETE_GLOBAL
#define _DELETE_NAME DELETE_NAME
#define _DELETE_SUBSCR DELETE_SUBSCR
-#define _DEOPT 374
+#define _DEOPT 375
#define _DICT_MERGE DICT_MERGE
#define _DICT_UPDATE DICT_UPDATE
-#define _DO_CALL 375
-#define _DO_CALL_FUNCTION_EX 376
-#define _DO_CALL_KW 377
-#define _DYNAMIC_EXIT 378
+#define _DO_CALL 376
+#define _DO_CALL_FUNCTION_EX 377
+#define _DO_CALL_KW 378
+#define _DYNAMIC_EXIT 379
#define _END_FOR END_FOR
#define _END_SEND END_SEND
-#define _ERROR_POP_N 379
+#define _ERROR_POP_N 380
#define _EXIT_INIT_CHECK EXIT_INIT_CHECK
-#define _EXPAND_METHOD 380
-#define _EXPAND_METHOD_KW 381
-#define _FATAL_ERROR 382
+#define _EXPAND_METHOD 381
+#define _EXPAND_METHOD_KW 382
+#define _FATAL_ERROR 383
#define _FORMAT_SIMPLE FORMAT_SIMPLE
#define _FORMAT_WITH_SPEC FORMAT_WITH_SPEC
-#define _FOR_ITER 383
-#define _FOR_ITER_GEN_FRAME 384
-#define _FOR_ITER_TIER_TWO 385
+#define _FOR_ITER 384
+#define _FOR_ITER_GEN_FRAME 385
+#define _FOR_ITER_TIER_TWO 386
#define _GET_AITER GET_AITER
#define _GET_ANEXT GET_ANEXT
#define _GET_AWAITABLE GET_AWAITABLE
#define _GET_ITER GET_ITER
#define _GET_LEN GET_LEN
#define _GET_YIELD_FROM_ITER GET_YIELD_FROM_ITER
-#define _GUARD_BINARY_OP_EXTEND 386
-#define _GUARD_CALLABLE_ISINSTANCE 387
-#define _GUARD_CALLABLE_LEN 388
-#define _GUARD_CALLABLE_LIST_APPEND 389
-#define _GUARD_CALLABLE_STR_1 390
-#define _GUARD_CALLABLE_TUPLE_1 391
-#define _GUARD_CALLABLE_TYPE_1 392
-#define _GUARD_DORV_NO_DICT 393
-#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 394
-#define _GUARD_GLOBALS_VERSION 395
-#define _GUARD_IP_RETURN_GENERATOR 396
-#define _GUARD_IP_RETURN_VALUE 397
-#define _GUARD_IP_YIELD_VALUE 398
-#define _GUARD_IP__PUSH_FRAME 399
-#define _GUARD_IS_FALSE_POP 400
-#define _GUARD_IS_NONE_POP 401
-#define _GUARD_IS_NOT_NONE_POP 402
-#define _GUARD_IS_TRUE_POP 403
-#define _GUARD_KEYS_VERSION 404
-#define _GUARD_NOS_DICT 405
-#define _GUARD_NOS_FLOAT 406
-#define _GUARD_NOS_INT 407
-#define _GUARD_NOS_LIST 408
-#define _GUARD_NOS_NOT_NULL 409
-#define _GUARD_NOS_NULL 410
-#define _GUARD_NOS_OVERFLOWED 411
-#define _GUARD_NOS_TUPLE 412
-#define _GUARD_NOS_UNICODE 413
-#define _GUARD_NOT_EXHAUSTED_LIST 414
-#define _GUARD_NOT_EXHAUSTED_RANGE 415
-#define _GUARD_NOT_EXHAUSTED_TUPLE 416
-#define _GUARD_THIRD_NULL 417
-#define _GUARD_TOS_ANY_SET 418
-#define _GUARD_TOS_DICT 419
-#define _GUARD_TOS_FLOAT 420
-#define _GUARD_TOS_INT 421
-#define _GUARD_TOS_LIST 422
-#define _GUARD_TOS_OVERFLOWED 423
-#define _GUARD_TOS_SLICE 424
-#define _GUARD_TOS_TUPLE 425
-#define _GUARD_TOS_UNICODE 426
-#define _GUARD_TYPE_VERSION 427
-#define _GUARD_TYPE_VERSION_AND_LOCK 428
-#define _HANDLE_PENDING_AND_DEOPT 429
+#define _GUARD_BINARY_OP_EXTEND 387
+#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS 388
+#define _GUARD_BIT_IS_SET_POP 389
+#define _GUARD_BIT_IS_SET_POP_4 390
+#define _GUARD_BIT_IS_SET_POP_5 391
+#define _GUARD_BIT_IS_SET_POP_6 392
+#define _GUARD_BIT_IS_SET_POP_7 393
+#define _GUARD_BIT_IS_UNSET_POP 394
+#define _GUARD_BIT_IS_UNSET_POP_4 395
+#define _GUARD_BIT_IS_UNSET_POP_5 396
+#define _GUARD_BIT_IS_UNSET_POP_6 397
+#define _GUARD_BIT_IS_UNSET_POP_7 398
+#define _GUARD_CALLABLE_ISINSTANCE 399
+#define _GUARD_CALLABLE_LEN 400
+#define _GUARD_CALLABLE_LIST_APPEND 401
+#define _GUARD_CALLABLE_STR_1 402
+#define _GUARD_CALLABLE_TUPLE_1 403
+#define _GUARD_CALLABLE_TYPE_1 404
+#define _GUARD_DORV_NO_DICT 405
+#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 406
+#define _GUARD_GLOBALS_VERSION 407
+#define _GUARD_IP_RETURN_GENERATOR 408
+#define _GUARD_IP_RETURN_VALUE 409
+#define _GUARD_IP_YIELD_VALUE 410
+#define _GUARD_IP__PUSH_FRAME 411
+#define _GUARD_IS_FALSE_POP 412
+#define _GUARD_IS_NONE_POP 413
+#define _GUARD_IS_NOT_NONE_POP 414
+#define _GUARD_IS_TRUE_POP 415
+#define _GUARD_KEYS_VERSION 416
+#define _GUARD_NOS_COMPACT_ASCII 417
+#define _GUARD_NOS_DICT 418
+#define _GUARD_NOS_FLOAT 419
+#define _GUARD_NOS_INT 420
+#define _GUARD_NOS_LIST 421
+#define _GUARD_NOS_NOT_NULL 422
+#define _GUARD_NOS_NULL 423
+#define _GUARD_NOS_OVERFLOWED 424
+#define _GUARD_NOS_TUPLE 425
+#define _GUARD_NOS_UNICODE 426
+#define _GUARD_NOT_EXHAUSTED_LIST 427
+#define _GUARD_NOT_EXHAUSTED_RANGE 428
+#define _GUARD_NOT_EXHAUSTED_TUPLE 429
+#define _GUARD_THIRD_NULL 430
+#define _GUARD_TOS_ANY_SET 431
+#define _GUARD_TOS_DICT 432
+#define _GUARD_TOS_FLOAT 433
+#define _GUARD_TOS_INT 434
+#define _GUARD_TOS_LIST 435
+#define _GUARD_TOS_OVERFLOWED 436
+#define _GUARD_TOS_SLICE 437
+#define _GUARD_TOS_TUPLE 438
+#define _GUARD_TOS_UNICODE 439
+#define _GUARD_TYPE_VERSION 440
+#define _GUARD_TYPE_VERSION_AND_LOCK 441
+#define _HANDLE_PENDING_AND_DEOPT 442
#define _IMPORT_FROM IMPORT_FROM
#define _IMPORT_NAME IMPORT_NAME
-#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 430
-#define _INIT_CALL_PY_EXACT_ARGS 431
-#define _INIT_CALL_PY_EXACT_ARGS_0 432
-#define _INIT_CALL_PY_EXACT_ARGS_1 433
-#define _INIT_CALL_PY_EXACT_ARGS_2 434
-#define _INIT_CALL_PY_EXACT_ARGS_3 435
-#define _INIT_CALL_PY_EXACT_ARGS_4 436
-#define _INSERT_NULL 437
+#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 443
+#define _INIT_CALL_PY_EXACT_ARGS 444
+#define _INIT_CALL_PY_EXACT_ARGS_0 445
+#define _INIT_CALL_PY_EXACT_ARGS_1 446
+#define _INIT_CALL_PY_EXACT_ARGS_2 447
+#define _INIT_CALL_PY_EXACT_ARGS_3 448
+#define _INIT_CALL_PY_EXACT_ARGS_4 449
+#define _INSERT_1_LOAD_CONST_INLINE 450
+#define _INSERT_1_LOAD_CONST_INLINE_BORROW 451
+#define _INSERT_2_LOAD_CONST_INLINE_BORROW 452
+#define _INSERT_NULL 453
#define _INSTRUMENTED_FOR_ITER INSTRUMENTED_FOR_ITER
#define _INSTRUMENTED_INSTRUCTION INSTRUMENTED_INSTRUCTION
#define _INSTRUMENTED_JUMP_FORWARD INSTRUMENTED_JUMP_FORWARD
@@ -191,924 +207,1048 @@ extern "C" {
#define _INSTRUMENTED_POP_JUMP_IF_NONE INSTRUMENTED_POP_JUMP_IF_NONE
#define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE INSTRUMENTED_POP_JUMP_IF_NOT_NONE
#define _INSTRUMENTED_POP_JUMP_IF_TRUE INSTRUMENTED_POP_JUMP_IF_TRUE
-#define _IS_NONE 438
-#define _IS_OP IS_OP
-#define _ITER_CHECK_LIST 439
-#define _ITER_CHECK_RANGE 440
-#define _ITER_CHECK_TUPLE 441
-#define _ITER_JUMP_LIST 442
-#define _ITER_JUMP_RANGE 443
-#define _ITER_JUMP_TUPLE 444
-#define _ITER_NEXT_LIST 445
-#define _ITER_NEXT_LIST_TIER_TWO 446
-#define _ITER_NEXT_RANGE 447
-#define _ITER_NEXT_TUPLE 448
+#define _IS_NONE 454
+#define _IS_OP 455
+#define _ITER_CHECK_LIST 456
+#define _ITER_CHECK_RANGE 457
+#define _ITER_CHECK_TUPLE 458
+#define _ITER_JUMP_LIST 459
+#define _ITER_JUMP_RANGE 460
+#define _ITER_JUMP_TUPLE 461
+#define _ITER_NEXT_LIST 462
+#define _ITER_NEXT_LIST_TIER_TWO 463
+#define _ITER_NEXT_RANGE 464
+#define _ITER_NEXT_TUPLE 465
#define _JUMP_BACKWARD_NO_INTERRUPT JUMP_BACKWARD_NO_INTERRUPT
-#define _JUMP_TO_TOP 449
+#define _JUMP_TO_TOP 466
#define _LIST_APPEND LIST_APPEND
#define _LIST_EXTEND LIST_EXTEND
-#define _LOAD_ATTR 450
-#define _LOAD_ATTR_CLASS 451
+#define _LOAD_ATTR 467
+#define _LOAD_ATTR_CLASS 468
#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN
-#define _LOAD_ATTR_INSTANCE_VALUE 452
-#define _LOAD_ATTR_METHOD_LAZY_DICT 453
-#define _LOAD_ATTR_METHOD_NO_DICT 454
-#define _LOAD_ATTR_METHOD_WITH_VALUES 455
-#define _LOAD_ATTR_MODULE 456
-#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 457
-#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 458
-#define _LOAD_ATTR_PROPERTY_FRAME 459
-#define _LOAD_ATTR_SLOT 460
-#define _LOAD_ATTR_WITH_HINT 461
+#define _LOAD_ATTR_INSTANCE_VALUE 469
+#define _LOAD_ATTR_METHOD_LAZY_DICT 470
+#define _LOAD_ATTR_METHOD_NO_DICT 471
+#define _LOAD_ATTR_METHOD_WITH_VALUES 472
+#define _LOAD_ATTR_MODULE 473
+#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 474
+#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 475
+#define _LOAD_ATTR_PROPERTY_FRAME 476
+#define _LOAD_ATTR_SLOT 477
+#define _LOAD_ATTR_WITH_HINT 478
#define _LOAD_BUILD_CLASS LOAD_BUILD_CLASS
-#define _LOAD_BYTECODE 462
+#define _LOAD_BYTECODE 479
#define _LOAD_COMMON_CONSTANT LOAD_COMMON_CONSTANT
#define _LOAD_CONST LOAD_CONST
-#define _LOAD_CONST_INLINE 463
-#define _LOAD_CONST_INLINE_BORROW 464
-#define _LOAD_CONST_UNDER_INLINE 465
-#define _LOAD_CONST_UNDER_INLINE_BORROW 466
+#define _LOAD_CONST_INLINE 480
+#define _LOAD_CONST_INLINE_BORROW 481
+#define _LOAD_CONST_UNDER_INLINE 482
+#define _LOAD_CONST_UNDER_INLINE_BORROW 483
#define _LOAD_DEREF LOAD_DEREF
-#define _LOAD_FAST 467
-#define _LOAD_FAST_0 468
-#define _LOAD_FAST_1 469
-#define _LOAD_FAST_2 470
-#define _LOAD_FAST_3 471
-#define _LOAD_FAST_4 472
-#define _LOAD_FAST_5 473
-#define _LOAD_FAST_6 474
-#define _LOAD_FAST_7 475
+#define _LOAD_FAST 484
+#define _LOAD_FAST_0 485
+#define _LOAD_FAST_1 486
+#define _LOAD_FAST_2 487
+#define _LOAD_FAST_3 488
+#define _LOAD_FAST_4 489
+#define _LOAD_FAST_5 490
+#define _LOAD_FAST_6 491
+#define _LOAD_FAST_7 492
#define _LOAD_FAST_AND_CLEAR LOAD_FAST_AND_CLEAR
-#define _LOAD_FAST_BORROW 476
-#define _LOAD_FAST_BORROW_0 477
-#define _LOAD_FAST_BORROW_1 478
-#define _LOAD_FAST_BORROW_2 479
-#define _LOAD_FAST_BORROW_3 480
-#define _LOAD_FAST_BORROW_4 481
-#define _LOAD_FAST_BORROW_5 482
-#define _LOAD_FAST_BORROW_6 483
-#define _LOAD_FAST_BORROW_7 484
+#define _LOAD_FAST_BORROW 493
+#define _LOAD_FAST_BORROW_0 494
+#define _LOAD_FAST_BORROW_1 495
+#define _LOAD_FAST_BORROW_2 496
+#define _LOAD_FAST_BORROW_3 497
+#define _LOAD_FAST_BORROW_4 498
+#define _LOAD_FAST_BORROW_5 499
+#define _LOAD_FAST_BORROW_6 500
+#define _LOAD_FAST_BORROW_7 501
#define _LOAD_FAST_CHECK LOAD_FAST_CHECK
#define _LOAD_FROM_DICT_OR_DEREF LOAD_FROM_DICT_OR_DEREF
#define _LOAD_FROM_DICT_OR_GLOBALS LOAD_FROM_DICT_OR_GLOBALS
-#define _LOAD_GLOBAL 485
-#define _LOAD_GLOBAL_BUILTINS 486
-#define _LOAD_GLOBAL_MODULE 487
+#define _LOAD_GLOBAL 502
+#define _LOAD_GLOBAL_BUILTINS 503
+#define _LOAD_GLOBAL_MODULE 504
#define _LOAD_LOCALS LOAD_LOCALS
#define _LOAD_NAME LOAD_NAME
-#define _LOAD_SMALL_INT 488
-#define _LOAD_SMALL_INT_0 489
-#define _LOAD_SMALL_INT_1 490
-#define _LOAD_SMALL_INT_2 491
-#define _LOAD_SMALL_INT_3 492
-#define _LOAD_SPECIAL 493
+#define _LOAD_SMALL_INT 505
+#define _LOAD_SMALL_INT_0 506
+#define _LOAD_SMALL_INT_1 507
+#define _LOAD_SMALL_INT_2 508
+#define _LOAD_SMALL_INT_3 509
+#define _LOAD_SPECIAL 510
#define _LOAD_SUPER_ATTR_ATTR LOAD_SUPER_ATTR_ATTR
#define _LOAD_SUPER_ATTR_METHOD LOAD_SUPER_ATTR_METHOD
-#define _MAKE_CALLARGS_A_TUPLE 494
+#define _MAKE_CALLARGS_A_TUPLE 511
#define _MAKE_CELL MAKE_CELL
#define _MAKE_FUNCTION MAKE_FUNCTION
-#define _MAKE_WARM 495
+#define _MAKE_WARM 512
#define _MAP_ADD MAP_ADD
#define _MATCH_CLASS MATCH_CLASS
#define _MATCH_KEYS MATCH_KEYS
#define _MATCH_MAPPING MATCH_MAPPING
#define _MATCH_SEQUENCE MATCH_SEQUENCE
-#define _MAYBE_EXPAND_METHOD 496
-#define _MAYBE_EXPAND_METHOD_KW 497
-#define _MONITOR_CALL 498
-#define _MONITOR_CALL_KW 499
-#define _MONITOR_JUMP_BACKWARD 500
-#define _MONITOR_RESUME 501
+#define _MAYBE_EXPAND_METHOD 513
+#define _MAYBE_EXPAND_METHOD_KW 514
+#define _MONITOR_CALL 515
+#define _MONITOR_CALL_KW 516
+#define _MONITOR_JUMP_BACKWARD 517
+#define _MONITOR_RESUME 518
#define _NOP NOP
-#define _POP_CALL 502
-#define _POP_CALL_LOAD_CONST_INLINE_BORROW 503
-#define _POP_CALL_ONE 504
-#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW 505
-#define _POP_CALL_TWO 506
-#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW 507
+#define _POP_CALL 519
+#define _POP_CALL_LOAD_CONST_INLINE_BORROW 520
+#define _POP_CALL_ONE 521
+#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW 522
+#define _POP_CALL_TWO 523
+#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW 524
#define _POP_EXCEPT POP_EXCEPT
#define _POP_ITER POP_ITER
-#define _POP_JUMP_IF_FALSE 508
-#define _POP_JUMP_IF_TRUE 509
+#define _POP_JUMP_IF_FALSE 525
+#define _POP_JUMP_IF_TRUE 526
#define _POP_TOP POP_TOP
-#define _POP_TOP_FLOAT 510
-#define _POP_TOP_INT 511
-#define _POP_TOP_LOAD_CONST_INLINE 512
-#define _POP_TOP_LOAD_CONST_INLINE_BORROW 513
-#define _POP_TOP_NOP 514
-#define _POP_TOP_UNICODE 515
-#define _POP_TWO 516
-#define _POP_TWO_LOAD_CONST_INLINE_BORROW 517
+#define _POP_TOP_FLOAT 527
+#define _POP_TOP_INT 528
+#define _POP_TOP_LOAD_CONST_INLINE 529
+#define _POP_TOP_LOAD_CONST_INLINE_BORROW 530
+#define _POP_TOP_NOP 531
+#define _POP_TOP_UNICODE 532
+#define _POP_TWO 533
+#define _POP_TWO_LOAD_CONST_INLINE_BORROW 534
#define _PUSH_EXC_INFO PUSH_EXC_INFO
-#define _PUSH_FRAME 518
+#define _PUSH_FRAME 535
#define _PUSH_NULL PUSH_NULL
-#define _PUSH_NULL_CONDITIONAL 519
-#define _PY_FRAME_GENERAL 520
-#define _PY_FRAME_KW 521
-#define _QUICKEN_RESUME 522
-#define _REPLACE_WITH_TRUE 523
+#define _PUSH_NULL_CONDITIONAL 536
+#define _PY_FRAME_EX 537
+#define _PY_FRAME_GENERAL 538
+#define _PY_FRAME_KW 539
+#define _QUICKEN_RESUME 540
+#define _REPLACE_WITH_TRUE 541
#define _RESUME_CHECK RESUME_CHECK
#define _RETURN_GENERATOR RETURN_GENERATOR
#define _RETURN_VALUE RETURN_VALUE
-#define _SAVE_RETURN_OFFSET 524
-#define _SEND 525
-#define _SEND_GEN_FRAME 526
+#define _SAVE_RETURN_OFFSET 542
+#define _SEND 543
+#define _SEND_GEN_FRAME 544
#define _SETUP_ANNOTATIONS SETUP_ANNOTATIONS
#define _SET_ADD SET_ADD
#define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE
#define _SET_UPDATE SET_UPDATE
-#define _SPILL_OR_RELOAD 527
-#define _START_EXECUTOR 528
-#define _STORE_ATTR 529
-#define _STORE_ATTR_INSTANCE_VALUE 530
-#define _STORE_ATTR_SLOT 531
-#define _STORE_ATTR_WITH_HINT 532
+#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW 545
+#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW 546
+#define _SPILL_OR_RELOAD 547
+#define _START_EXECUTOR 548
+#define _STORE_ATTR 549
+#define _STORE_ATTR_INSTANCE_VALUE 550
+#define _STORE_ATTR_INSTANCE_VALUE_NULL 551
+#define _STORE_ATTR_SLOT 552
+#define _STORE_ATTR_SLOT_NULL 553
+#define _STORE_ATTR_WITH_HINT 554
#define _STORE_DEREF STORE_DEREF
-#define _STORE_FAST 533
-#define _STORE_FAST_0 534
-#define _STORE_FAST_1 535
-#define _STORE_FAST_2 536
-#define _STORE_FAST_3 537
-#define _STORE_FAST_4 538
-#define _STORE_FAST_5 539
-#define _STORE_FAST_6 540
-#define _STORE_FAST_7 541
#define _STORE_GLOBAL STORE_GLOBAL
#define _STORE_NAME STORE_NAME
-#define _STORE_SLICE 542
-#define _STORE_SUBSCR 543
-#define _STORE_SUBSCR_DICT 544
-#define _STORE_SUBSCR_LIST_INT 545
-#define _SWAP 546
-#define _SWAP_2 547
-#define _SWAP_3 548
-#define _TIER2_RESUME_CHECK 549
-#define _TO_BOOL 550
+#define _STORE_SLICE 555
+#define _STORE_SUBSCR 556
+#define _STORE_SUBSCR_DICT 557
+#define _STORE_SUBSCR_LIST_INT 558
+#define _SWAP 559
+#define _SWAP_2 560
+#define _SWAP_3 561
+#define _SWAP_FAST 562
+#define _SWAP_FAST_0 563
+#define _SWAP_FAST_1 564
+#define _SWAP_FAST_2 565
+#define _SWAP_FAST_3 566
+#define _SWAP_FAST_4 567
+#define _SWAP_FAST_5 568
+#define _SWAP_FAST_6 569
+#define _SWAP_FAST_7 570
+#define _TIER2_RESUME_CHECK 571
+#define _TO_BOOL 572
#define _TO_BOOL_BOOL TO_BOOL_BOOL
-#define _TO_BOOL_INT TO_BOOL_INT
-#define _TO_BOOL_LIST 551
+#define _TO_BOOL_INT 573
+#define _TO_BOOL_LIST 574
#define _TO_BOOL_NONE TO_BOOL_NONE
-#define _TO_BOOL_STR 552
+#define _TO_BOOL_STR 575
#define _TRACE_RECORD TRACE_RECORD
-#define _UNARY_INVERT UNARY_INVERT
-#define _UNARY_NEGATIVE UNARY_NEGATIVE
+#define _UNARY_INVERT 576
+#define _UNARY_NEGATIVE 577
#define _UNARY_NOT UNARY_NOT
#define _UNPACK_EX UNPACK_EX
-#define _UNPACK_SEQUENCE 553
-#define _UNPACK_SEQUENCE_LIST 554
-#define _UNPACK_SEQUENCE_TUPLE 555
-#define _UNPACK_SEQUENCE_TWO_TUPLE 556
+#define _UNPACK_SEQUENCE 578
+#define _UNPACK_SEQUENCE_LIST 579
+#define _UNPACK_SEQUENCE_TUPLE 580
+#define _UNPACK_SEQUENCE_TWO_TUPLE 581
#define _WITH_EXCEPT_START WITH_EXCEPT_START
#define _YIELD_VALUE YIELD_VALUE
-#define MAX_UOP_ID 556
-#define _BINARY_OP_r21 557
-#define _BINARY_OP_ADD_FLOAT_r01 558
-#define _BINARY_OP_ADD_FLOAT_r11 559
-#define _BINARY_OP_ADD_FLOAT_r21 560
-#define _BINARY_OP_ADD_FLOAT_r32 561
-#define _BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS_r01 562
-#define _BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS_r11 563
-#define _BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS_r21 564
-#define _BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS_r32 565
-#define _BINARY_OP_ADD_INT_r01 566
-#define _BINARY_OP_ADD_INT_r11 567
-#define _BINARY_OP_ADD_INT_r21 568
-#define _BINARY_OP_ADD_INT_r32 569
-#define _BINARY_OP_ADD_UNICODE_r01 570
-#define _BINARY_OP_ADD_UNICODE_r11 571
-#define _BINARY_OP_ADD_UNICODE_r21 572
-#define _BINARY_OP_ADD_UNICODE_r32 573
-#define _BINARY_OP_EXTEND_r21 574
-#define _BINARY_OP_INPLACE_ADD_UNICODE_r20 575
-#define _BINARY_OP_MULTIPLY_FLOAT_r01 576
-#define _BINARY_OP_MULTIPLY_FLOAT_r11 577
-#define _BINARY_OP_MULTIPLY_FLOAT_r21 578
-#define _BINARY_OP_MULTIPLY_FLOAT_r32 579
-#define _BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS_r01 580
-#define _BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS_r11 581
-#define _BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS_r21 582
-#define _BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS_r32 583
-#define _BINARY_OP_MULTIPLY_INT_r01 584
-#define _BINARY_OP_MULTIPLY_INT_r11 585
-#define _BINARY_OP_MULTIPLY_INT_r21 586
-#define _BINARY_OP_MULTIPLY_INT_r32 587
-#define _BINARY_OP_SUBSCR_CHECK_FUNC_r23 588
-#define _BINARY_OP_SUBSCR_DICT_r21 589
-#define _BINARY_OP_SUBSCR_INIT_CALL_r01 590
-#define _BINARY_OP_SUBSCR_INIT_CALL_r11 591
-#define _BINARY_OP_SUBSCR_INIT_CALL_r21 592
-#define _BINARY_OP_SUBSCR_INIT_CALL_r31 593
-#define _BINARY_OP_SUBSCR_LIST_INT_r21 594
-#define _BINARY_OP_SUBSCR_LIST_SLICE_r21 595
-#define _BINARY_OP_SUBSCR_STR_INT_r21 596
-#define _BINARY_OP_SUBSCR_TUPLE_INT_r21 597
-#define _BINARY_OP_SUBTRACT_FLOAT_r01 598
-#define _BINARY_OP_SUBTRACT_FLOAT_r11 599
-#define _BINARY_OP_SUBTRACT_FLOAT_r21 600
-#define _BINARY_OP_SUBTRACT_FLOAT_r32 601
-#define _BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS_r01 602
-#define _BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS_r11 603
-#define _BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS_r21 604
-#define _BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS_r32 605
-#define _BINARY_OP_SUBTRACT_INT_r01 606
-#define _BINARY_OP_SUBTRACT_INT_r11 607
-#define _BINARY_OP_SUBTRACT_INT_r21 608
-#define _BINARY_OP_SUBTRACT_INT_r32 609
-#define _BINARY_SLICE_r31 610
-#define _BUILD_INTERPOLATION_r01 611
-#define _BUILD_LIST_r01 612
-#define _BUILD_MAP_r01 613
-#define _BUILD_SET_r01 614
-#define _BUILD_SLICE_r01 615
-#define _BUILD_STRING_r01 616
-#define _BUILD_TEMPLATE_r21 617
-#define _BUILD_TUPLE_r01 618
-#define _CALL_BUILTIN_CLASS_r01 619
-#define _CALL_BUILTIN_FAST_r01 620
-#define _CALL_BUILTIN_FAST_WITH_KEYWORDS_r01 621
-#define _CALL_BUILTIN_O_r01 622
-#define _CALL_INTRINSIC_1_r11 623
-#define _CALL_INTRINSIC_2_r21 624
-#define _CALL_ISINSTANCE_r31 625
-#define _CALL_KW_NON_PY_r11 626
-#define _CALL_LEN_r33 627
-#define _CALL_LIST_APPEND_r30 628
-#define _CALL_METHOD_DESCRIPTOR_FAST_r01 629
-#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS_r01 630
-#define _CALL_METHOD_DESCRIPTOR_NOARGS_r01 631
-#define _CALL_METHOD_DESCRIPTOR_O_r01 632
-#define _CALL_NON_PY_GENERAL_r01 633
-#define _CALL_STR_1_r31 634
-#define _CALL_TUPLE_1_r32 635
-#define _CALL_TYPE_1_r31 636
-#define _CHECK_AND_ALLOCATE_OBJECT_r00 637
-#define _CHECK_ATTR_CLASS_r01 638
-#define _CHECK_ATTR_CLASS_r11 639
-#define _CHECK_ATTR_CLASS_r22 640
-#define _CHECK_ATTR_CLASS_r33 641
-#define _CHECK_ATTR_METHOD_LAZY_DICT_r01 642
-#define _CHECK_ATTR_METHOD_LAZY_DICT_r11 643
-#define _CHECK_ATTR_METHOD_LAZY_DICT_r22 644
-#define _CHECK_ATTR_METHOD_LAZY_DICT_r33 645
-#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS_r00 646
-#define _CHECK_EG_MATCH_r22 647
-#define _CHECK_EXC_MATCH_r22 648
-#define _CHECK_FUNCTION_EXACT_ARGS_r00 649
-#define _CHECK_FUNCTION_VERSION_r00 650
-#define _CHECK_FUNCTION_VERSION_INLINE_r00 651
-#define _CHECK_FUNCTION_VERSION_INLINE_r11 652
-#define _CHECK_FUNCTION_VERSION_INLINE_r22 653
-#define _CHECK_FUNCTION_VERSION_INLINE_r33 654
-#define _CHECK_FUNCTION_VERSION_KW_r11 655
-#define _CHECK_IS_NOT_PY_CALLABLE_r00 656
-#define _CHECK_IS_NOT_PY_CALLABLE_KW_r11 657
-#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r01 658
-#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r11 659
-#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r22 660
-#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r33 661
-#define _CHECK_METHOD_VERSION_r00 662
-#define _CHECK_METHOD_VERSION_KW_r11 663
-#define _CHECK_PEP_523_r00 664
-#define _CHECK_PEP_523_r11 665
-#define _CHECK_PEP_523_r22 666
-#define _CHECK_PEP_523_r33 667
-#define _CHECK_PERIODIC_r00 668
-#define _CHECK_PERIODIC_AT_END_r00 669
-#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM_r00 670
-#define _CHECK_RECURSION_REMAINING_r00 671
-#define _CHECK_RECURSION_REMAINING_r11 672
-#define _CHECK_RECURSION_REMAINING_r22 673
-#define _CHECK_RECURSION_REMAINING_r33 674
-#define _CHECK_STACK_SPACE_r00 675
-#define _CHECK_STACK_SPACE_OPERAND_r00 676
-#define _CHECK_STACK_SPACE_OPERAND_r11 677
-#define _CHECK_STACK_SPACE_OPERAND_r22 678
-#define _CHECK_STACK_SPACE_OPERAND_r33 679
-#define _CHECK_VALIDITY_r00 680
-#define _CHECK_VALIDITY_r11 681
-#define _CHECK_VALIDITY_r22 682
-#define _CHECK_VALIDITY_r33 683
-#define _COLD_DYNAMIC_EXIT_r00 684
-#define _COLD_EXIT_r00 685
-#define _COMPARE_OP_r21 686
-#define _COMPARE_OP_FLOAT_r01 687
-#define _COMPARE_OP_FLOAT_r11 688
-#define _COMPARE_OP_FLOAT_r21 689
-#define _COMPARE_OP_FLOAT_r32 690
-#define _COMPARE_OP_INT_r21 691
-#define _COMPARE_OP_STR_r21 692
-#define _CONTAINS_OP_r21 693
-#define _CONTAINS_OP_DICT_r21 694
-#define _CONTAINS_OP_SET_r21 695
-#define _CONVERT_VALUE_r11 696
-#define _COPY_r01 697
-#define _COPY_1_r02 698
-#define _COPY_1_r12 699
-#define _COPY_1_r23 700
-#define _COPY_2_r03 701
-#define _COPY_2_r13 702
-#define _COPY_2_r23 703
-#define _COPY_3_r03 704
-#define _COPY_3_r13 705
-#define _COPY_3_r23 706
-#define _COPY_3_r33 707
-#define _COPY_FREE_VARS_r00 708
-#define _COPY_FREE_VARS_r11 709
-#define _COPY_FREE_VARS_r22 710
-#define _COPY_FREE_VARS_r33 711
-#define _CREATE_INIT_FRAME_r01 712
-#define _DELETE_ATTR_r10 713
-#define _DELETE_DEREF_r00 714
-#define _DELETE_FAST_r00 715
-#define _DELETE_GLOBAL_r00 716
-#define _DELETE_NAME_r00 717
-#define _DELETE_SUBSCR_r20 718
-#define _DEOPT_r00 719
-#define _DEOPT_r10 720
-#define _DEOPT_r20 721
-#define _DEOPT_r30 722
-#define _DICT_MERGE_r10 723
-#define _DICT_UPDATE_r10 724
-#define _DO_CALL_r01 725
-#define _DO_CALL_FUNCTION_EX_r31 726
-#define _DO_CALL_KW_r11 727
-#define _DYNAMIC_EXIT_r00 728
-#define _DYNAMIC_EXIT_r10 729
-#define _DYNAMIC_EXIT_r20 730
-#define _DYNAMIC_EXIT_r30 731
-#define _END_FOR_r10 732
-#define _END_SEND_r21 733
-#define _ERROR_POP_N_r00 734
-#define _EXIT_INIT_CHECK_r10 735
-#define _EXIT_TRACE_r00 736
-#define _EXIT_TRACE_r10 737
-#define _EXIT_TRACE_r20 738
-#define _EXIT_TRACE_r30 739
-#define _EXPAND_METHOD_r00 740
-#define _EXPAND_METHOD_KW_r11 741
-#define _FATAL_ERROR_r00 742
-#define _FATAL_ERROR_r11 743
-#define _FATAL_ERROR_r22 744
-#define _FATAL_ERROR_r33 745
-#define _FORMAT_SIMPLE_r11 746
-#define _FORMAT_WITH_SPEC_r21 747
-#define _FOR_ITER_r23 748
-#define _FOR_ITER_GEN_FRAME_r23 749
-#define _FOR_ITER_TIER_TWO_r23 750
-#define _GET_AITER_r11 751
-#define _GET_ANEXT_r12 752
-#define _GET_AWAITABLE_r11 753
-#define _GET_ITER_r12 754
-#define _GET_LEN_r12 755
-#define _GET_YIELD_FROM_ITER_r11 756
-#define _GUARD_BINARY_OP_EXTEND_r22 757
-#define _GUARD_CALLABLE_ISINSTANCE_r03 758
-#define _GUARD_CALLABLE_ISINSTANCE_r13 759
-#define _GUARD_CALLABLE_ISINSTANCE_r23 760
-#define _GUARD_CALLABLE_ISINSTANCE_r33 761
-#define _GUARD_CALLABLE_LEN_r03 762
-#define _GUARD_CALLABLE_LEN_r13 763
-#define _GUARD_CALLABLE_LEN_r23 764
-#define _GUARD_CALLABLE_LEN_r33 765
-#define _GUARD_CALLABLE_LIST_APPEND_r03 766
-#define _GUARD_CALLABLE_LIST_APPEND_r13 767
-#define _GUARD_CALLABLE_LIST_APPEND_r23 768
-#define _GUARD_CALLABLE_LIST_APPEND_r33 769
-#define _GUARD_CALLABLE_STR_1_r03 770
-#define _GUARD_CALLABLE_STR_1_r13 771
-#define _GUARD_CALLABLE_STR_1_r23 772
-#define _GUARD_CALLABLE_STR_1_r33 773
-#define _GUARD_CALLABLE_TUPLE_1_r03 774
-#define _GUARD_CALLABLE_TUPLE_1_r13 775
-#define _GUARD_CALLABLE_TUPLE_1_r23 776
-#define _GUARD_CALLABLE_TUPLE_1_r33 777
-#define _GUARD_CALLABLE_TYPE_1_r03 778
-#define _GUARD_CALLABLE_TYPE_1_r13 779
-#define _GUARD_CALLABLE_TYPE_1_r23 780
-#define _GUARD_CALLABLE_TYPE_1_r33 781
-#define _GUARD_DORV_NO_DICT_r01 782
-#define _GUARD_DORV_NO_DICT_r11 783
-#define _GUARD_DORV_NO_DICT_r22 784
-#define _GUARD_DORV_NO_DICT_r33 785
-#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r01 786
-#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r11 787
-#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r22 788
-#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r33 789
-#define _GUARD_GLOBALS_VERSION_r00 790
-#define _GUARD_GLOBALS_VERSION_r11 791
-#define _GUARD_GLOBALS_VERSION_r22 792
-#define _GUARD_GLOBALS_VERSION_r33 793
-#define _GUARD_IP_RETURN_GENERATOR_r00 794
-#define _GUARD_IP_RETURN_GENERATOR_r11 795
-#define _GUARD_IP_RETURN_GENERATOR_r22 796
-#define _GUARD_IP_RETURN_GENERATOR_r33 797
-#define _GUARD_IP_RETURN_VALUE_r00 798
-#define _GUARD_IP_RETURN_VALUE_r11 799
-#define _GUARD_IP_RETURN_VALUE_r22 800
-#define _GUARD_IP_RETURN_VALUE_r33 801
-#define _GUARD_IP_YIELD_VALUE_r00 802
-#define _GUARD_IP_YIELD_VALUE_r11 803
-#define _GUARD_IP_YIELD_VALUE_r22 804
-#define _GUARD_IP_YIELD_VALUE_r33 805
-#define _GUARD_IP__PUSH_FRAME_r00 806
-#define _GUARD_IP__PUSH_FRAME_r11 807
-#define _GUARD_IP__PUSH_FRAME_r22 808
-#define _GUARD_IP__PUSH_FRAME_r33 809
-#define _GUARD_IS_FALSE_POP_r00 810
-#define _GUARD_IS_FALSE_POP_r10 811
-#define _GUARD_IS_FALSE_POP_r21 812
-#define _GUARD_IS_FALSE_POP_r32 813
-#define _GUARD_IS_NONE_POP_r00 814
-#define _GUARD_IS_NONE_POP_r10 815
-#define _GUARD_IS_NONE_POP_r21 816
-#define _GUARD_IS_NONE_POP_r32 817
-#define _GUARD_IS_NOT_NONE_POP_r10 818
-#define _GUARD_IS_TRUE_POP_r00 819
-#define _GUARD_IS_TRUE_POP_r10 820
-#define _GUARD_IS_TRUE_POP_r21 821
-#define _GUARD_IS_TRUE_POP_r32 822
-#define _GUARD_KEYS_VERSION_r01 823
-#define _GUARD_KEYS_VERSION_r11 824
-#define _GUARD_KEYS_VERSION_r22 825
-#define _GUARD_KEYS_VERSION_r33 826
-#define _GUARD_NOS_DICT_r02 827
-#define _GUARD_NOS_DICT_r12 828
-#define _GUARD_NOS_DICT_r22 829
-#define _GUARD_NOS_DICT_r33 830
-#define _GUARD_NOS_FLOAT_r02 831
-#define _GUARD_NOS_FLOAT_r12 832
-#define _GUARD_NOS_FLOAT_r22 833
-#define _GUARD_NOS_FLOAT_r33 834
-#define _GUARD_NOS_INT_r02 835
-#define _GUARD_NOS_INT_r12 836
-#define _GUARD_NOS_INT_r22 837
-#define _GUARD_NOS_INT_r33 838
-#define _GUARD_NOS_LIST_r02 839
-#define _GUARD_NOS_LIST_r12 840
-#define _GUARD_NOS_LIST_r22 841
-#define _GUARD_NOS_LIST_r33 842
-#define _GUARD_NOS_NOT_NULL_r02 843
-#define _GUARD_NOS_NOT_NULL_r12 844
-#define _GUARD_NOS_NOT_NULL_r22 845
-#define _GUARD_NOS_NOT_NULL_r33 846
-#define _GUARD_NOS_NULL_r02 847
-#define _GUARD_NOS_NULL_r12 848
-#define _GUARD_NOS_NULL_r22 849
-#define _GUARD_NOS_NULL_r33 850
-#define _GUARD_NOS_OVERFLOWED_r02 851
-#define _GUARD_NOS_OVERFLOWED_r12 852
-#define _GUARD_NOS_OVERFLOWED_r22 853
-#define _GUARD_NOS_OVERFLOWED_r33 854
-#define _GUARD_NOS_TUPLE_r02 855
-#define _GUARD_NOS_TUPLE_r12 856
-#define _GUARD_NOS_TUPLE_r22 857
-#define _GUARD_NOS_TUPLE_r33 858
-#define _GUARD_NOS_UNICODE_r02 859
-#define _GUARD_NOS_UNICODE_r12 860
-#define _GUARD_NOS_UNICODE_r22 861
-#define _GUARD_NOS_UNICODE_r33 862
-#define _GUARD_NOT_EXHAUSTED_LIST_r02 863
-#define _GUARD_NOT_EXHAUSTED_LIST_r12 864
-#define _GUARD_NOT_EXHAUSTED_LIST_r22 865
-#define _GUARD_NOT_EXHAUSTED_LIST_r33 866
-#define _GUARD_NOT_EXHAUSTED_RANGE_r02 867
-#define _GUARD_NOT_EXHAUSTED_RANGE_r12 868
-#define _GUARD_NOT_EXHAUSTED_RANGE_r22 869
-#define _GUARD_NOT_EXHAUSTED_RANGE_r33 870
-#define _GUARD_NOT_EXHAUSTED_TUPLE_r02 871
-#define _GUARD_NOT_EXHAUSTED_TUPLE_r12 872
-#define _GUARD_NOT_EXHAUSTED_TUPLE_r22 873
-#define _GUARD_NOT_EXHAUSTED_TUPLE_r33 874
-#define _GUARD_THIRD_NULL_r03 875
-#define _GUARD_THIRD_NULL_r13 876
-#define _GUARD_THIRD_NULL_r23 877
-#define _GUARD_THIRD_NULL_r33 878
-#define _GUARD_TOS_ANY_SET_r01 879
-#define _GUARD_TOS_ANY_SET_r11 880
-#define _GUARD_TOS_ANY_SET_r22 881
-#define _GUARD_TOS_ANY_SET_r33 882
-#define _GUARD_TOS_DICT_r01 883
-#define _GUARD_TOS_DICT_r11 884
-#define _GUARD_TOS_DICT_r22 885
-#define _GUARD_TOS_DICT_r33 886
-#define _GUARD_TOS_FLOAT_r01 887
-#define _GUARD_TOS_FLOAT_r11 888
-#define _GUARD_TOS_FLOAT_r22 889
-#define _GUARD_TOS_FLOAT_r33 890
-#define _GUARD_TOS_INT_r01 891
-#define _GUARD_TOS_INT_r11 892
-#define _GUARD_TOS_INT_r22 893
-#define _GUARD_TOS_INT_r33 894
-#define _GUARD_TOS_LIST_r01 895
-#define _GUARD_TOS_LIST_r11 896
-#define _GUARD_TOS_LIST_r22 897
-#define _GUARD_TOS_LIST_r33 898
-#define _GUARD_TOS_OVERFLOWED_r01 899
-#define _GUARD_TOS_OVERFLOWED_r11 900
-#define _GUARD_TOS_OVERFLOWED_r22 901
-#define _GUARD_TOS_OVERFLOWED_r33 902
-#define _GUARD_TOS_SLICE_r01 903
-#define _GUARD_TOS_SLICE_r11 904
-#define _GUARD_TOS_SLICE_r22 905
-#define _GUARD_TOS_SLICE_r33 906
-#define _GUARD_TOS_TUPLE_r01 907
-#define _GUARD_TOS_TUPLE_r11 908
-#define _GUARD_TOS_TUPLE_r22 909
-#define _GUARD_TOS_TUPLE_r33 910
-#define _GUARD_TOS_UNICODE_r01 911
-#define _GUARD_TOS_UNICODE_r11 912
-#define _GUARD_TOS_UNICODE_r22 913
-#define _GUARD_TOS_UNICODE_r33 914
-#define _GUARD_TYPE_VERSION_r01 915
-#define _GUARD_TYPE_VERSION_r11 916
-#define _GUARD_TYPE_VERSION_r22 917
-#define _GUARD_TYPE_VERSION_r33 918
-#define _GUARD_TYPE_VERSION_AND_LOCK_r01 919
-#define _GUARD_TYPE_VERSION_AND_LOCK_r11 920
-#define _GUARD_TYPE_VERSION_AND_LOCK_r22 921
-#define _GUARD_TYPE_VERSION_AND_LOCK_r33 922
-#define _HANDLE_PENDING_AND_DEOPT_r00 923
-#define _HANDLE_PENDING_AND_DEOPT_r10 924
-#define _HANDLE_PENDING_AND_DEOPT_r20 925
-#define _HANDLE_PENDING_AND_DEOPT_r30 926
-#define _IMPORT_FROM_r12 927
-#define _IMPORT_NAME_r21 928
-#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS_r00 929
-#define _INIT_CALL_PY_EXACT_ARGS_r01 930
-#define _INIT_CALL_PY_EXACT_ARGS_0_r01 931
-#define _INIT_CALL_PY_EXACT_ARGS_1_r01 932
-#define _INIT_CALL_PY_EXACT_ARGS_2_r01 933
-#define _INIT_CALL_PY_EXACT_ARGS_3_r01 934
-#define _INIT_CALL_PY_EXACT_ARGS_4_r01 935
-#define _INSERT_NULL_r10 936
-#define _INSTRUMENTED_FOR_ITER_r23 937
-#define _INSTRUMENTED_INSTRUCTION_r00 938
-#define _INSTRUMENTED_JUMP_FORWARD_r00 939
-#define _INSTRUMENTED_JUMP_FORWARD_r11 940
-#define _INSTRUMENTED_JUMP_FORWARD_r22 941
-#define _INSTRUMENTED_JUMP_FORWARD_r33 942
-#define _INSTRUMENTED_LINE_r00 943
-#define _INSTRUMENTED_NOT_TAKEN_r00 944
-#define _INSTRUMENTED_NOT_TAKEN_r11 945
-#define _INSTRUMENTED_NOT_TAKEN_r22 946
-#define _INSTRUMENTED_NOT_TAKEN_r33 947
-#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r00 948
-#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r10 949
-#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r21 950
-#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r32 951
-#define _INSTRUMENTED_POP_JUMP_IF_NONE_r10 952
-#define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE_r10 953
-#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r00 954
-#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r10 955
-#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r21 956
-#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r32 957
-#define _IS_NONE_r11 958
-#define _IS_OP_r21 959
-#define _ITER_CHECK_LIST_r02 960
-#define _ITER_CHECK_LIST_r12 961
-#define _ITER_CHECK_LIST_r22 962
-#define _ITER_CHECK_LIST_r33 963
-#define _ITER_CHECK_RANGE_r02 964
-#define _ITER_CHECK_RANGE_r12 965
-#define _ITER_CHECK_RANGE_r22 966
-#define _ITER_CHECK_RANGE_r33 967
-#define _ITER_CHECK_TUPLE_r02 968
-#define _ITER_CHECK_TUPLE_r12 969
-#define _ITER_CHECK_TUPLE_r22 970
-#define _ITER_CHECK_TUPLE_r33 971
-#define _ITER_JUMP_LIST_r02 972
-#define _ITER_JUMP_LIST_r12 973
-#define _ITER_JUMP_LIST_r22 974
-#define _ITER_JUMP_LIST_r33 975
-#define _ITER_JUMP_RANGE_r02 976
-#define _ITER_JUMP_RANGE_r12 977
-#define _ITER_JUMP_RANGE_r22 978
-#define _ITER_JUMP_RANGE_r33 979
-#define _ITER_JUMP_TUPLE_r02 980
-#define _ITER_JUMP_TUPLE_r12 981
-#define _ITER_JUMP_TUPLE_r22 982
-#define _ITER_JUMP_TUPLE_r33 983
-#define _ITER_NEXT_LIST_r23 984
-#define _ITER_NEXT_LIST_TIER_TWO_r23 985
-#define _ITER_NEXT_RANGE_r03 986
-#define _ITER_NEXT_RANGE_r13 987
-#define _ITER_NEXT_RANGE_r23 988
-#define _ITER_NEXT_TUPLE_r03 989
-#define _ITER_NEXT_TUPLE_r13 990
-#define _ITER_NEXT_TUPLE_r23 991
-#define _JUMP_BACKWARD_NO_INTERRUPT_r00 992
-#define _JUMP_BACKWARD_NO_INTERRUPT_r11 993
-#define _JUMP_BACKWARD_NO_INTERRUPT_r22 994
-#define _JUMP_BACKWARD_NO_INTERRUPT_r33 995
-#define _JUMP_TO_TOP_r00 996
-#define _LIST_APPEND_r10 997
-#define _LIST_EXTEND_r10 998
-#define _LOAD_ATTR_r10 999
-#define _LOAD_ATTR_CLASS_r11 1000
-#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_r11 1001
-#define _LOAD_ATTR_INSTANCE_VALUE_r11 1002
-#define _LOAD_ATTR_METHOD_LAZY_DICT_r02 1003
-#define _LOAD_ATTR_METHOD_LAZY_DICT_r12 1004
-#define _LOAD_ATTR_METHOD_LAZY_DICT_r23 1005
-#define _LOAD_ATTR_METHOD_NO_DICT_r02 1006
-#define _LOAD_ATTR_METHOD_NO_DICT_r12 1007
-#define _LOAD_ATTR_METHOD_NO_DICT_r23 1008
-#define _LOAD_ATTR_METHOD_WITH_VALUES_r02 1009
-#define _LOAD_ATTR_METHOD_WITH_VALUES_r12 1010
-#define _LOAD_ATTR_METHOD_WITH_VALUES_r23 1011
-#define _LOAD_ATTR_MODULE_r11 1012
-#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT_r11 1013
-#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES_r11 1014
-#define _LOAD_ATTR_PROPERTY_FRAME_r11 1015
-#define _LOAD_ATTR_SLOT_r11 1016
-#define _LOAD_ATTR_WITH_HINT_r11 1017
-#define _LOAD_BUILD_CLASS_r01 1018
-#define _LOAD_BYTECODE_r00 1019
-#define _LOAD_COMMON_CONSTANT_r01 1020
-#define _LOAD_COMMON_CONSTANT_r12 1021
-#define _LOAD_COMMON_CONSTANT_r23 1022
-#define _LOAD_CONST_r01 1023
-#define _LOAD_CONST_r12 1024
-#define _LOAD_CONST_r23 1025
-#define _LOAD_CONST_INLINE_r01 1026
-#define _LOAD_CONST_INLINE_r12 1027
-#define _LOAD_CONST_INLINE_r23 1028
-#define _LOAD_CONST_INLINE_BORROW_r01 1029
-#define _LOAD_CONST_INLINE_BORROW_r12 1030
-#define _LOAD_CONST_INLINE_BORROW_r23 1031
-#define _LOAD_CONST_UNDER_INLINE_r02 1032
-#define _LOAD_CONST_UNDER_INLINE_r12 1033
-#define _LOAD_CONST_UNDER_INLINE_r23 1034
-#define _LOAD_CONST_UNDER_INLINE_BORROW_r02 1035
-#define _LOAD_CONST_UNDER_INLINE_BORROW_r12 1036
-#define _LOAD_CONST_UNDER_INLINE_BORROW_r23 1037
-#define _LOAD_DEREF_r01 1038
-#define _LOAD_FAST_r01 1039
-#define _LOAD_FAST_r12 1040
-#define _LOAD_FAST_r23 1041
-#define _LOAD_FAST_0_r01 1042
-#define _LOAD_FAST_0_r12 1043
-#define _LOAD_FAST_0_r23 1044
-#define _LOAD_FAST_1_r01 1045
-#define _LOAD_FAST_1_r12 1046
-#define _LOAD_FAST_1_r23 1047
-#define _LOAD_FAST_2_r01 1048
-#define _LOAD_FAST_2_r12 1049
-#define _LOAD_FAST_2_r23 1050
-#define _LOAD_FAST_3_r01 1051
-#define _LOAD_FAST_3_r12 1052
-#define _LOAD_FAST_3_r23 1053
-#define _LOAD_FAST_4_r01 1054
-#define _LOAD_FAST_4_r12 1055
-#define _LOAD_FAST_4_r23 1056
-#define _LOAD_FAST_5_r01 1057
-#define _LOAD_FAST_5_r12 1058
-#define _LOAD_FAST_5_r23 1059
-#define _LOAD_FAST_6_r01 1060
-#define _LOAD_FAST_6_r12 1061
-#define _LOAD_FAST_6_r23 1062
-#define _LOAD_FAST_7_r01 1063
-#define _LOAD_FAST_7_r12 1064
-#define _LOAD_FAST_7_r23 1065
-#define _LOAD_FAST_AND_CLEAR_r01 1066
-#define _LOAD_FAST_AND_CLEAR_r12 1067
-#define _LOAD_FAST_AND_CLEAR_r23 1068
-#define _LOAD_FAST_BORROW_r01 1069
-#define _LOAD_FAST_BORROW_r12 1070
-#define _LOAD_FAST_BORROW_r23 1071
-#define _LOAD_FAST_BORROW_0_r01 1072
-#define _LOAD_FAST_BORROW_0_r12 1073
-#define _LOAD_FAST_BORROW_0_r23 1074
-#define _LOAD_FAST_BORROW_1_r01 1075
-#define _LOAD_FAST_BORROW_1_r12 1076
-#define _LOAD_FAST_BORROW_1_r23 1077
-#define _LOAD_FAST_BORROW_2_r01 1078
-#define _LOAD_FAST_BORROW_2_r12 1079
-#define _LOAD_FAST_BORROW_2_r23 1080
-#define _LOAD_FAST_BORROW_3_r01 1081
-#define _LOAD_FAST_BORROW_3_r12 1082
-#define _LOAD_FAST_BORROW_3_r23 1083
-#define _LOAD_FAST_BORROW_4_r01 1084
-#define _LOAD_FAST_BORROW_4_r12 1085
-#define _LOAD_FAST_BORROW_4_r23 1086
-#define _LOAD_FAST_BORROW_5_r01 1087
-#define _LOAD_FAST_BORROW_5_r12 1088
-#define _LOAD_FAST_BORROW_5_r23 1089
-#define _LOAD_FAST_BORROW_6_r01 1090
-#define _LOAD_FAST_BORROW_6_r12 1091
-#define _LOAD_FAST_BORROW_6_r23 1092
-#define _LOAD_FAST_BORROW_7_r01 1093
-#define _LOAD_FAST_BORROW_7_r12 1094
-#define _LOAD_FAST_BORROW_7_r23 1095
-#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r02 1096
-#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r13 1097
-#define _LOAD_FAST_CHECK_r01 1098
-#define _LOAD_FAST_LOAD_FAST_r02 1099
-#define _LOAD_FAST_LOAD_FAST_r13 1100
-#define _LOAD_FROM_DICT_OR_DEREF_r11 1101
-#define _LOAD_FROM_DICT_OR_GLOBALS_r11 1102
-#define _LOAD_GLOBAL_r00 1103
-#define _LOAD_GLOBAL_BUILTINS_r01 1104
-#define _LOAD_GLOBAL_MODULE_r01 1105
-#define _LOAD_LOCALS_r01 1106
-#define _LOAD_NAME_r01 1107
-#define _LOAD_SMALL_INT_r01 1108
-#define _LOAD_SMALL_INT_r12 1109
-#define _LOAD_SMALL_INT_r23 1110
-#define _LOAD_SMALL_INT_0_r01 1111
-#define _LOAD_SMALL_INT_0_r12 1112
-#define _LOAD_SMALL_INT_0_r23 1113
-#define _LOAD_SMALL_INT_1_r01 1114
-#define _LOAD_SMALL_INT_1_r12 1115
-#define _LOAD_SMALL_INT_1_r23 1116
-#define _LOAD_SMALL_INT_2_r01 1117
-#define _LOAD_SMALL_INT_2_r12 1118
-#define _LOAD_SMALL_INT_2_r23 1119
-#define _LOAD_SMALL_INT_3_r01 1120
-#define _LOAD_SMALL_INT_3_r12 1121
-#define _LOAD_SMALL_INT_3_r23 1122
-#define _LOAD_SPECIAL_r00 1123
-#define _LOAD_SUPER_ATTR_ATTR_r31 1124
-#define _LOAD_SUPER_ATTR_METHOD_r32 1125
-#define _MAKE_CALLARGS_A_TUPLE_r33 1126
-#define _MAKE_CELL_r00 1127
-#define _MAKE_FUNCTION_r11 1128
-#define _MAKE_WARM_r00 1129
-#define _MAKE_WARM_r11 1130
-#define _MAKE_WARM_r22 1131
-#define _MAKE_WARM_r33 1132
-#define _MAP_ADD_r20 1133
-#define _MATCH_CLASS_r31 1134
-#define _MATCH_KEYS_r23 1135
-#define _MATCH_MAPPING_r02 1136
-#define _MATCH_MAPPING_r12 1137
-#define _MATCH_MAPPING_r23 1138
-#define _MATCH_SEQUENCE_r02 1139
-#define _MATCH_SEQUENCE_r12 1140
-#define _MATCH_SEQUENCE_r23 1141
-#define _MAYBE_EXPAND_METHOD_r00 1142
-#define _MAYBE_EXPAND_METHOD_KW_r11 1143
-#define _MONITOR_CALL_r00 1144
-#define _MONITOR_CALL_KW_r11 1145
-#define _MONITOR_JUMP_BACKWARD_r00 1146
-#define _MONITOR_JUMP_BACKWARD_r11 1147
-#define _MONITOR_JUMP_BACKWARD_r22 1148
-#define _MONITOR_JUMP_BACKWARD_r33 1149
-#define _MONITOR_RESUME_r00 1150
-#define _NOP_r00 1151
-#define _NOP_r11 1152
-#define _NOP_r22 1153
-#define _NOP_r33 1154
-#define _POP_CALL_r20 1155
-#define _POP_CALL_LOAD_CONST_INLINE_BORROW_r21 1156
-#define _POP_CALL_ONE_r30 1157
-#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW_r31 1158
-#define _POP_CALL_TWO_r30 1159
-#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW_r31 1160
-#define _POP_EXCEPT_r10 1161
-#define _POP_ITER_r20 1162
-#define _POP_JUMP_IF_FALSE_r00 1163
-#define _POP_JUMP_IF_FALSE_r10 1164
-#define _POP_JUMP_IF_FALSE_r21 1165
-#define _POP_JUMP_IF_FALSE_r32 1166
-#define _POP_JUMP_IF_TRUE_r00 1167
-#define _POP_JUMP_IF_TRUE_r10 1168
-#define _POP_JUMP_IF_TRUE_r21 1169
-#define _POP_JUMP_IF_TRUE_r32 1170
-#define _POP_TOP_r10 1171
-#define _POP_TOP_FLOAT_r00 1172
-#define _POP_TOP_FLOAT_r10 1173
-#define _POP_TOP_FLOAT_r21 1174
-#define _POP_TOP_FLOAT_r32 1175
-#define _POP_TOP_INT_r00 1176
-#define _POP_TOP_INT_r10 1177
-#define _POP_TOP_INT_r21 1178
-#define _POP_TOP_INT_r32 1179
-#define _POP_TOP_LOAD_CONST_INLINE_r11 1180
-#define _POP_TOP_LOAD_CONST_INLINE_BORROW_r11 1181
-#define _POP_TOP_NOP_r00 1182
-#define _POP_TOP_NOP_r10 1183
-#define _POP_TOP_NOP_r21 1184
-#define _POP_TOP_NOP_r32 1185
-#define _POP_TOP_UNICODE_r00 1186
-#define _POP_TOP_UNICODE_r10 1187
-#define _POP_TOP_UNICODE_r21 1188
-#define _POP_TOP_UNICODE_r32 1189
-#define _POP_TWO_r20 1190
-#define _POP_TWO_LOAD_CONST_INLINE_BORROW_r21 1191
-#define _PUSH_EXC_INFO_r02 1192
-#define _PUSH_EXC_INFO_r12 1193
-#define _PUSH_EXC_INFO_r23 1194
-#define _PUSH_FRAME_r10 1195
-#define _PUSH_NULL_r01 1196
-#define _PUSH_NULL_r12 1197
-#define _PUSH_NULL_r23 1198
-#define _PUSH_NULL_CONDITIONAL_r00 1199
-#define _PY_FRAME_GENERAL_r01 1200
-#define _PY_FRAME_KW_r11 1201
-#define _QUICKEN_RESUME_r00 1202
-#define _QUICKEN_RESUME_r11 1203
-#define _QUICKEN_RESUME_r22 1204
-#define _QUICKEN_RESUME_r33 1205
-#define _REPLACE_WITH_TRUE_r11 1206
-#define _RESUME_CHECK_r00 1207
-#define _RESUME_CHECK_r11 1208
-#define _RESUME_CHECK_r22 1209
-#define _RESUME_CHECK_r33 1210
-#define _RETURN_GENERATOR_r01 1211
-#define _RETURN_VALUE_r11 1212
-#define _SAVE_RETURN_OFFSET_r00 1213
-#define _SAVE_RETURN_OFFSET_r11 1214
-#define _SAVE_RETURN_OFFSET_r22 1215
-#define _SAVE_RETURN_OFFSET_r33 1216
-#define _SEND_r22 1217
-#define _SEND_GEN_FRAME_r22 1218
-#define _SETUP_ANNOTATIONS_r00 1219
-#define _SET_ADD_r10 1220
-#define _SET_FUNCTION_ATTRIBUTE_r01 1221
-#define _SET_FUNCTION_ATTRIBUTE_r11 1222
-#define _SET_FUNCTION_ATTRIBUTE_r21 1223
-#define _SET_FUNCTION_ATTRIBUTE_r32 1224
-#define _SET_IP_r00 1225
-#define _SET_IP_r11 1226
-#define _SET_IP_r22 1227
-#define _SET_IP_r33 1228
-#define _SET_UPDATE_r10 1229
-#define _SPILL_OR_RELOAD_r01 1230
-#define _SPILL_OR_RELOAD_r02 1231
-#define _SPILL_OR_RELOAD_r03 1232
-#define _SPILL_OR_RELOAD_r10 1233
-#define _SPILL_OR_RELOAD_r12 1234
-#define _SPILL_OR_RELOAD_r13 1235
-#define _SPILL_OR_RELOAD_r20 1236
-#define _SPILL_OR_RELOAD_r21 1237
-#define _SPILL_OR_RELOAD_r23 1238
-#define _SPILL_OR_RELOAD_r30 1239
-#define _SPILL_OR_RELOAD_r31 1240
-#define _SPILL_OR_RELOAD_r32 1241
-#define _START_EXECUTOR_r00 1242
-#define _STORE_ATTR_r20 1243
-#define _STORE_ATTR_INSTANCE_VALUE_r20 1244
-#define _STORE_ATTR_SLOT_r20 1245
-#define _STORE_ATTR_WITH_HINT_r20 1246
-#define _STORE_DEREF_r10 1247
-#define _STORE_FAST_r10 1248
-#define _STORE_FAST_0_r10 1249
-#define _STORE_FAST_1_r10 1250
-#define _STORE_FAST_2_r10 1251
-#define _STORE_FAST_3_r10 1252
-#define _STORE_FAST_4_r10 1253
-#define _STORE_FAST_5_r10 1254
-#define _STORE_FAST_6_r10 1255
-#define _STORE_FAST_7_r10 1256
-#define _STORE_FAST_LOAD_FAST_r11 1257
-#define _STORE_FAST_STORE_FAST_r20 1258
-#define _STORE_GLOBAL_r10 1259
-#define _STORE_NAME_r10 1260
-#define _STORE_SLICE_r30 1261
-#define _STORE_SUBSCR_r30 1262
-#define _STORE_SUBSCR_DICT_r30 1263
-#define _STORE_SUBSCR_LIST_INT_r30 1264
-#define _SWAP_r11 1265
-#define _SWAP_2_r02 1266
-#define _SWAP_2_r12 1267
-#define _SWAP_2_r22 1268
-#define _SWAP_2_r33 1269
-#define _SWAP_3_r03 1270
-#define _SWAP_3_r13 1271
-#define _SWAP_3_r23 1272
-#define _SWAP_3_r33 1273
-#define _TIER2_RESUME_CHECK_r00 1274
-#define _TIER2_RESUME_CHECK_r11 1275
-#define _TIER2_RESUME_CHECK_r22 1276
-#define _TIER2_RESUME_CHECK_r33 1277
-#define _TO_BOOL_r11 1278
-#define _TO_BOOL_BOOL_r01 1279
-#define _TO_BOOL_BOOL_r11 1280
-#define _TO_BOOL_BOOL_r22 1281
-#define _TO_BOOL_BOOL_r33 1282
-#define _TO_BOOL_INT_r11 1283
-#define _TO_BOOL_LIST_r11 1284
-#define _TO_BOOL_NONE_r01 1285
-#define _TO_BOOL_NONE_r11 1286
-#define _TO_BOOL_NONE_r22 1287
-#define _TO_BOOL_NONE_r33 1288
-#define _TO_BOOL_STR_r11 1289
-#define _TRACE_RECORD_r00 1290
-#define _UNARY_INVERT_r11 1291
-#define _UNARY_NEGATIVE_r11 1292
-#define _UNARY_NOT_r01 1293
-#define _UNARY_NOT_r11 1294
-#define _UNARY_NOT_r22 1295
-#define _UNARY_NOT_r33 1296
-#define _UNPACK_EX_r10 1297
-#define _UNPACK_SEQUENCE_r10 1298
-#define _UNPACK_SEQUENCE_LIST_r10 1299
-#define _UNPACK_SEQUENCE_TUPLE_r10 1300
-#define _UNPACK_SEQUENCE_TWO_TUPLE_r12 1301
-#define _WITH_EXCEPT_START_r33 1302
-#define _YIELD_VALUE_r11 1303
-#define MAX_UOP_REGS_ID 1303
+#define MAX_UOP_ID 581
+#define _BINARY_OP_r23 582
+#define _BINARY_OP_ADD_FLOAT_r03 583
+#define _BINARY_OP_ADD_FLOAT_r13 584
+#define _BINARY_OP_ADD_FLOAT_r23 585
+#define _BINARY_OP_ADD_INT_r03 586
+#define _BINARY_OP_ADD_INT_r13 587
+#define _BINARY_OP_ADD_INT_r23 588
+#define _BINARY_OP_ADD_UNICODE_r03 589
+#define _BINARY_OP_ADD_UNICODE_r13 590
+#define _BINARY_OP_ADD_UNICODE_r23 591
+#define _BINARY_OP_EXTEND_r23 592
+#define _BINARY_OP_INPLACE_ADD_UNICODE_r21 593
+#define _BINARY_OP_MULTIPLY_FLOAT_r03 594
+#define _BINARY_OP_MULTIPLY_FLOAT_r13 595
+#define _BINARY_OP_MULTIPLY_FLOAT_r23 596
+#define _BINARY_OP_MULTIPLY_INT_r03 597
+#define _BINARY_OP_MULTIPLY_INT_r13 598
+#define _BINARY_OP_MULTIPLY_INT_r23 599
+#define _BINARY_OP_SUBSCR_CHECK_FUNC_r23 600
+#define _BINARY_OP_SUBSCR_DICT_r23 601
+#define _BINARY_OP_SUBSCR_INIT_CALL_r01 602
+#define _BINARY_OP_SUBSCR_INIT_CALL_r11 603
+#define _BINARY_OP_SUBSCR_INIT_CALL_r21 604
+#define _BINARY_OP_SUBSCR_INIT_CALL_r31 605
+#define _BINARY_OP_SUBSCR_LIST_INT_r23 606
+#define _BINARY_OP_SUBSCR_LIST_SLICE_r21 607
+#define _BINARY_OP_SUBSCR_STR_INT_r23 608
+#define _BINARY_OP_SUBSCR_TUPLE_INT_r03 609
+#define _BINARY_OP_SUBSCR_TUPLE_INT_r13 610
+#define _BINARY_OP_SUBSCR_TUPLE_INT_r23 611
+#define _BINARY_OP_SUBSCR_USTR_INT_r23 612
+#define _BINARY_OP_SUBTRACT_FLOAT_r03 613
+#define _BINARY_OP_SUBTRACT_FLOAT_r13 614
+#define _BINARY_OP_SUBTRACT_FLOAT_r23 615
+#define _BINARY_OP_SUBTRACT_INT_r03 616
+#define _BINARY_OP_SUBTRACT_INT_r13 617
+#define _BINARY_OP_SUBTRACT_INT_r23 618
+#define _BINARY_SLICE_r31 619
+#define _BUILD_INTERPOLATION_r01 620
+#define _BUILD_LIST_r01 621
+#define _BUILD_MAP_r01 622
+#define _BUILD_SET_r01 623
+#define _BUILD_SLICE_r01 624
+#define _BUILD_STRING_r01 625
+#define _BUILD_TEMPLATE_r21 626
+#define _BUILD_TUPLE_r01 627
+#define _CALL_BUILTIN_CLASS_r01 628
+#define _CALL_BUILTIN_FAST_r01 629
+#define _CALL_BUILTIN_FAST_WITH_KEYWORDS_r01 630
+#define _CALL_BUILTIN_O_r03 631
+#define _CALL_FUNCTION_EX_NON_PY_GENERAL_r31 632
+#define _CALL_INTRINSIC_1_r11 633
+#define _CALL_INTRINSIC_2_r21 634
+#define _CALL_ISINSTANCE_r31 635
+#define _CALL_KW_NON_PY_r11 636
+#define _CALL_LEN_r33 637
+#define _CALL_LIST_APPEND_r03 638
+#define _CALL_LIST_APPEND_r13 639
+#define _CALL_LIST_APPEND_r23 640
+#define _CALL_LIST_APPEND_r33 641
+#define _CALL_METHOD_DESCRIPTOR_FAST_r01 642
+#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS_r01 643
+#define _CALL_METHOD_DESCRIPTOR_NOARGS_r01 644
+#define _CALL_METHOD_DESCRIPTOR_O_r03 645
+#define _CALL_NON_PY_GENERAL_r01 646
+#define _CALL_STR_1_r32 647
+#define _CALL_TUPLE_1_r32 648
+#define _CALL_TYPE_1_r02 649
+#define _CALL_TYPE_1_r12 650
+#define _CALL_TYPE_1_r22 651
+#define _CALL_TYPE_1_r32 652
+#define _CHECK_AND_ALLOCATE_OBJECT_r00 653
+#define _CHECK_ATTR_CLASS_r01 654
+#define _CHECK_ATTR_CLASS_r11 655
+#define _CHECK_ATTR_CLASS_r22 656
+#define _CHECK_ATTR_CLASS_r33 657
+#define _CHECK_ATTR_METHOD_LAZY_DICT_r01 658
+#define _CHECK_ATTR_METHOD_LAZY_DICT_r11 659
+#define _CHECK_ATTR_METHOD_LAZY_DICT_r22 660
+#define _CHECK_ATTR_METHOD_LAZY_DICT_r33 661
+#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS_r00 662
+#define _CHECK_EG_MATCH_r22 663
+#define _CHECK_EXC_MATCH_r22 664
+#define _CHECK_FUNCTION_EXACT_ARGS_r00 665
+#define _CHECK_FUNCTION_VERSION_r00 666
+#define _CHECK_FUNCTION_VERSION_INLINE_r00 667
+#define _CHECK_FUNCTION_VERSION_INLINE_r11 668
+#define _CHECK_FUNCTION_VERSION_INLINE_r22 669
+#define _CHECK_FUNCTION_VERSION_INLINE_r33 670
+#define _CHECK_FUNCTION_VERSION_KW_r11 671
+#define _CHECK_IS_NOT_PY_CALLABLE_r00 672
+#define _CHECK_IS_NOT_PY_CALLABLE_EX_r03 673
+#define _CHECK_IS_NOT_PY_CALLABLE_EX_r13 674
+#define _CHECK_IS_NOT_PY_CALLABLE_EX_r23 675
+#define _CHECK_IS_NOT_PY_CALLABLE_EX_r33 676
+#define _CHECK_IS_NOT_PY_CALLABLE_KW_r11 677
+#define _CHECK_IS_PY_CALLABLE_EX_r03 678
+#define _CHECK_IS_PY_CALLABLE_EX_r13 679
+#define _CHECK_IS_PY_CALLABLE_EX_r23 680
+#define _CHECK_IS_PY_CALLABLE_EX_r33 681
+#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r01 682
+#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r11 683
+#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r22 684
+#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r33 685
+#define _CHECK_METHOD_VERSION_r00 686
+#define _CHECK_METHOD_VERSION_KW_r11 687
+#define _CHECK_PEP_523_r00 688
+#define _CHECK_PEP_523_r11 689
+#define _CHECK_PEP_523_r22 690
+#define _CHECK_PEP_523_r33 691
+#define _CHECK_PERIODIC_r00 692
+#define _CHECK_PERIODIC_AT_END_r00 693
+#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM_r00 694
+#define _CHECK_RECURSION_REMAINING_r00 695
+#define _CHECK_RECURSION_REMAINING_r11 696
+#define _CHECK_RECURSION_REMAINING_r22 697
+#define _CHECK_RECURSION_REMAINING_r33 698
+#define _CHECK_STACK_SPACE_r00 699
+#define _CHECK_STACK_SPACE_OPERAND_r00 700
+#define _CHECK_STACK_SPACE_OPERAND_r11 701
+#define _CHECK_STACK_SPACE_OPERAND_r22 702
+#define _CHECK_STACK_SPACE_OPERAND_r33 703
+#define _CHECK_VALIDITY_r00 704
+#define _CHECK_VALIDITY_r11 705
+#define _CHECK_VALIDITY_r22 706
+#define _CHECK_VALIDITY_r33 707
+#define _COLD_DYNAMIC_EXIT_r00 708
+#define _COLD_EXIT_r00 709
+#define _COMPARE_OP_r21 710
+#define _COMPARE_OP_FLOAT_r03 711
+#define _COMPARE_OP_FLOAT_r13 712
+#define _COMPARE_OP_FLOAT_r23 713
+#define _COMPARE_OP_INT_r23 714
+#define _COMPARE_OP_STR_r23 715
+#define _CONTAINS_OP_r23 716
+#define _CONTAINS_OP_DICT_r23 717
+#define _CONTAINS_OP_SET_r23 718
+#define _CONVERT_VALUE_r11 719
+#define _COPY_r01 720
+#define _COPY_1_r02 721
+#define _COPY_1_r12 722
+#define _COPY_1_r23 723
+#define _COPY_2_r03 724
+#define _COPY_2_r13 725
+#define _COPY_2_r23 726
+#define _COPY_3_r03 727
+#define _COPY_3_r13 728
+#define _COPY_3_r23 729
+#define _COPY_3_r33 730
+#define _COPY_FREE_VARS_r00 731
+#define _COPY_FREE_VARS_r11 732
+#define _COPY_FREE_VARS_r22 733
+#define _COPY_FREE_VARS_r33 734
+#define _CREATE_INIT_FRAME_r01 735
+#define _DELETE_ATTR_r10 736
+#define _DELETE_DEREF_r00 737
+#define _DELETE_FAST_r00 738
+#define _DELETE_GLOBAL_r00 739
+#define _DELETE_NAME_r00 740
+#define _DELETE_SUBSCR_r20 741
+#define _DEOPT_r00 742
+#define _DEOPT_r10 743
+#define _DEOPT_r20 744
+#define _DEOPT_r30 745
+#define _DICT_MERGE_r10 746
+#define _DICT_UPDATE_r10 747
+#define _DO_CALL_r01 748
+#define _DO_CALL_FUNCTION_EX_r31 749
+#define _DO_CALL_KW_r11 750
+#define _DYNAMIC_EXIT_r00 751
+#define _DYNAMIC_EXIT_r10 752
+#define _DYNAMIC_EXIT_r20 753
+#define _DYNAMIC_EXIT_r30 754
+#define _END_FOR_r10 755
+#define _END_SEND_r21 756
+#define _ERROR_POP_N_r00 757
+#define _EXIT_INIT_CHECK_r10 758
+#define _EXIT_TRACE_r00 759
+#define _EXIT_TRACE_r10 760
+#define _EXIT_TRACE_r20 761
+#define _EXIT_TRACE_r30 762
+#define _EXPAND_METHOD_r00 763
+#define _EXPAND_METHOD_KW_r11 764
+#define _FATAL_ERROR_r00 765
+#define _FATAL_ERROR_r11 766
+#define _FATAL_ERROR_r22 767
+#define _FATAL_ERROR_r33 768
+#define _FORMAT_SIMPLE_r11 769
+#define _FORMAT_WITH_SPEC_r21 770
+#define _FOR_ITER_r23 771
+#define _FOR_ITER_GEN_FRAME_r03 772
+#define _FOR_ITER_GEN_FRAME_r13 773
+#define _FOR_ITER_GEN_FRAME_r23 774
+#define _FOR_ITER_TIER_TWO_r23 775
+#define _GET_AITER_r11 776
+#define _GET_ANEXT_r12 777
+#define _GET_AWAITABLE_r11 778
+#define _GET_ITER_r12 779
+#define _GET_LEN_r12 780
+#define _GET_YIELD_FROM_ITER_r11 781
+#define _GUARD_BINARY_OP_EXTEND_r22 782
+#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r02 783
+#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r12 784
+#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r22 785
+#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r33 786
+#define _GUARD_BIT_IS_SET_POP_r00 787
+#define _GUARD_BIT_IS_SET_POP_r10 788
+#define _GUARD_BIT_IS_SET_POP_r21 789
+#define _GUARD_BIT_IS_SET_POP_r32 790
+#define _GUARD_BIT_IS_SET_POP_4_r00 791
+#define _GUARD_BIT_IS_SET_POP_4_r10 792
+#define _GUARD_BIT_IS_SET_POP_4_r21 793
+#define _GUARD_BIT_IS_SET_POP_4_r32 794
+#define _GUARD_BIT_IS_SET_POP_5_r00 795
+#define _GUARD_BIT_IS_SET_POP_5_r10 796
+#define _GUARD_BIT_IS_SET_POP_5_r21 797
+#define _GUARD_BIT_IS_SET_POP_5_r32 798
+#define _GUARD_BIT_IS_SET_POP_6_r00 799
+#define _GUARD_BIT_IS_SET_POP_6_r10 800
+#define _GUARD_BIT_IS_SET_POP_6_r21 801
+#define _GUARD_BIT_IS_SET_POP_6_r32 802
+#define _GUARD_BIT_IS_SET_POP_7_r00 803
+#define _GUARD_BIT_IS_SET_POP_7_r10 804
+#define _GUARD_BIT_IS_SET_POP_7_r21 805
+#define _GUARD_BIT_IS_SET_POP_7_r32 806
+#define _GUARD_BIT_IS_UNSET_POP_r00 807
+#define _GUARD_BIT_IS_UNSET_POP_r10 808
+#define _GUARD_BIT_IS_UNSET_POP_r21 809
+#define _GUARD_BIT_IS_UNSET_POP_r32 810
+#define _GUARD_BIT_IS_UNSET_POP_4_r00 811
+#define _GUARD_BIT_IS_UNSET_POP_4_r10 812
+#define _GUARD_BIT_IS_UNSET_POP_4_r21 813
+#define _GUARD_BIT_IS_UNSET_POP_4_r32 814
+#define _GUARD_BIT_IS_UNSET_POP_5_r00 815
+#define _GUARD_BIT_IS_UNSET_POP_5_r10 816
+#define _GUARD_BIT_IS_UNSET_POP_5_r21 817
+#define _GUARD_BIT_IS_UNSET_POP_5_r32 818
+#define _GUARD_BIT_IS_UNSET_POP_6_r00 819
+#define _GUARD_BIT_IS_UNSET_POP_6_r10 820
+#define _GUARD_BIT_IS_UNSET_POP_6_r21 821
+#define _GUARD_BIT_IS_UNSET_POP_6_r32 822
+#define _GUARD_BIT_IS_UNSET_POP_7_r00 823
+#define _GUARD_BIT_IS_UNSET_POP_7_r10 824
+#define _GUARD_BIT_IS_UNSET_POP_7_r21 825
+#define _GUARD_BIT_IS_UNSET_POP_7_r32 826
+#define _GUARD_CALLABLE_ISINSTANCE_r03 827
+#define _GUARD_CALLABLE_ISINSTANCE_r13 828
+#define _GUARD_CALLABLE_ISINSTANCE_r23 829
+#define _GUARD_CALLABLE_ISINSTANCE_r33 830
+#define _GUARD_CALLABLE_LEN_r03 831
+#define _GUARD_CALLABLE_LEN_r13 832
+#define _GUARD_CALLABLE_LEN_r23 833
+#define _GUARD_CALLABLE_LEN_r33 834
+#define _GUARD_CALLABLE_LIST_APPEND_r03 835
+#define _GUARD_CALLABLE_LIST_APPEND_r13 836
+#define _GUARD_CALLABLE_LIST_APPEND_r23 837
+#define _GUARD_CALLABLE_LIST_APPEND_r33 838
+#define _GUARD_CALLABLE_STR_1_r03 839
+#define _GUARD_CALLABLE_STR_1_r13 840
+#define _GUARD_CALLABLE_STR_1_r23 841
+#define _GUARD_CALLABLE_STR_1_r33 842
+#define _GUARD_CALLABLE_TUPLE_1_r03 843
+#define _GUARD_CALLABLE_TUPLE_1_r13 844
+#define _GUARD_CALLABLE_TUPLE_1_r23 845
+#define _GUARD_CALLABLE_TUPLE_1_r33 846
+#define _GUARD_CALLABLE_TYPE_1_r03 847
+#define _GUARD_CALLABLE_TYPE_1_r13 848
+#define _GUARD_CALLABLE_TYPE_1_r23 849
+#define _GUARD_CALLABLE_TYPE_1_r33 850
+#define _GUARD_DORV_NO_DICT_r01 851
+#define _GUARD_DORV_NO_DICT_r11 852
+#define _GUARD_DORV_NO_DICT_r22 853
+#define _GUARD_DORV_NO_DICT_r33 854
+#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r01 855
+#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r11 856
+#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r22 857
+#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r33 858
+#define _GUARD_GLOBALS_VERSION_r00 859
+#define _GUARD_GLOBALS_VERSION_r11 860
+#define _GUARD_GLOBALS_VERSION_r22 861
+#define _GUARD_GLOBALS_VERSION_r33 862
+#define _GUARD_IP_RETURN_GENERATOR_r00 863
+#define _GUARD_IP_RETURN_GENERATOR_r11 864
+#define _GUARD_IP_RETURN_GENERATOR_r22 865
+#define _GUARD_IP_RETURN_GENERATOR_r33 866
+#define _GUARD_IP_RETURN_VALUE_r00 867
+#define _GUARD_IP_RETURN_VALUE_r11 868
+#define _GUARD_IP_RETURN_VALUE_r22 869
+#define _GUARD_IP_RETURN_VALUE_r33 870
+#define _GUARD_IP_YIELD_VALUE_r00 871
+#define _GUARD_IP_YIELD_VALUE_r11 872
+#define _GUARD_IP_YIELD_VALUE_r22 873
+#define _GUARD_IP_YIELD_VALUE_r33 874
+#define _GUARD_IP__PUSH_FRAME_r00 875
+#define _GUARD_IP__PUSH_FRAME_r11 876
+#define _GUARD_IP__PUSH_FRAME_r22 877
+#define _GUARD_IP__PUSH_FRAME_r33 878
+#define _GUARD_IS_FALSE_POP_r00 879
+#define _GUARD_IS_FALSE_POP_r10 880
+#define _GUARD_IS_FALSE_POP_r21 881
+#define _GUARD_IS_FALSE_POP_r32 882
+#define _GUARD_IS_NONE_POP_r00 883
+#define _GUARD_IS_NONE_POP_r10 884
+#define _GUARD_IS_NONE_POP_r21 885
+#define _GUARD_IS_NONE_POP_r32 886
+#define _GUARD_IS_NOT_NONE_POP_r10 887
+#define _GUARD_IS_TRUE_POP_r00 888
+#define _GUARD_IS_TRUE_POP_r10 889
+#define _GUARD_IS_TRUE_POP_r21 890
+#define _GUARD_IS_TRUE_POP_r32 891
+#define _GUARD_KEYS_VERSION_r01 892
+#define _GUARD_KEYS_VERSION_r11 893
+#define _GUARD_KEYS_VERSION_r22 894
+#define _GUARD_KEYS_VERSION_r33 895
+#define _GUARD_NOS_COMPACT_ASCII_r02 896
+#define _GUARD_NOS_COMPACT_ASCII_r12 897
+#define _GUARD_NOS_COMPACT_ASCII_r22 898
+#define _GUARD_NOS_COMPACT_ASCII_r33 899
+#define _GUARD_NOS_DICT_r02 900
+#define _GUARD_NOS_DICT_r12 901
+#define _GUARD_NOS_DICT_r22 902
+#define _GUARD_NOS_DICT_r33 903
+#define _GUARD_NOS_FLOAT_r02 904
+#define _GUARD_NOS_FLOAT_r12 905
+#define _GUARD_NOS_FLOAT_r22 906
+#define _GUARD_NOS_FLOAT_r33 907
+#define _GUARD_NOS_INT_r02 908
+#define _GUARD_NOS_INT_r12 909
+#define _GUARD_NOS_INT_r22 910
+#define _GUARD_NOS_INT_r33 911
+#define _GUARD_NOS_LIST_r02 912
+#define _GUARD_NOS_LIST_r12 913
+#define _GUARD_NOS_LIST_r22 914
+#define _GUARD_NOS_LIST_r33 915
+#define _GUARD_NOS_NOT_NULL_r02 916
+#define _GUARD_NOS_NOT_NULL_r12 917
+#define _GUARD_NOS_NOT_NULL_r22 918
+#define _GUARD_NOS_NOT_NULL_r33 919
+#define _GUARD_NOS_NULL_r02 920
+#define _GUARD_NOS_NULL_r12 921
+#define _GUARD_NOS_NULL_r22 922
+#define _GUARD_NOS_NULL_r33 923
+#define _GUARD_NOS_OVERFLOWED_r02 924
+#define _GUARD_NOS_OVERFLOWED_r12 925
+#define _GUARD_NOS_OVERFLOWED_r22 926
+#define _GUARD_NOS_OVERFLOWED_r33 927
+#define _GUARD_NOS_TUPLE_r02 928
+#define _GUARD_NOS_TUPLE_r12 929
+#define _GUARD_NOS_TUPLE_r22 930
+#define _GUARD_NOS_TUPLE_r33 931
+#define _GUARD_NOS_UNICODE_r02 932
+#define _GUARD_NOS_UNICODE_r12 933
+#define _GUARD_NOS_UNICODE_r22 934
+#define _GUARD_NOS_UNICODE_r33 935
+#define _GUARD_NOT_EXHAUSTED_LIST_r02 936
+#define _GUARD_NOT_EXHAUSTED_LIST_r12 937
+#define _GUARD_NOT_EXHAUSTED_LIST_r22 938
+#define _GUARD_NOT_EXHAUSTED_LIST_r33 939
+#define _GUARD_NOT_EXHAUSTED_RANGE_r02 940
+#define _GUARD_NOT_EXHAUSTED_RANGE_r12 941
+#define _GUARD_NOT_EXHAUSTED_RANGE_r22 942
+#define _GUARD_NOT_EXHAUSTED_RANGE_r33 943
+#define _GUARD_NOT_EXHAUSTED_TUPLE_r02 944
+#define _GUARD_NOT_EXHAUSTED_TUPLE_r12 945
+#define _GUARD_NOT_EXHAUSTED_TUPLE_r22 946
+#define _GUARD_NOT_EXHAUSTED_TUPLE_r33 947
+#define _GUARD_THIRD_NULL_r03 948
+#define _GUARD_THIRD_NULL_r13 949
+#define _GUARD_THIRD_NULL_r23 950
+#define _GUARD_THIRD_NULL_r33 951
+#define _GUARD_TOS_ANY_SET_r01 952
+#define _GUARD_TOS_ANY_SET_r11 953
+#define _GUARD_TOS_ANY_SET_r22 954
+#define _GUARD_TOS_ANY_SET_r33 955
+#define _GUARD_TOS_DICT_r01 956
+#define _GUARD_TOS_DICT_r11 957
+#define _GUARD_TOS_DICT_r22 958
+#define _GUARD_TOS_DICT_r33 959
+#define _GUARD_TOS_FLOAT_r01 960
+#define _GUARD_TOS_FLOAT_r11 961
+#define _GUARD_TOS_FLOAT_r22 962
+#define _GUARD_TOS_FLOAT_r33 963
+#define _GUARD_TOS_INT_r01 964
+#define _GUARD_TOS_INT_r11 965
+#define _GUARD_TOS_INT_r22 966
+#define _GUARD_TOS_INT_r33 967
+#define _GUARD_TOS_LIST_r01 968
+#define _GUARD_TOS_LIST_r11 969
+#define _GUARD_TOS_LIST_r22 970
+#define _GUARD_TOS_LIST_r33 971
+#define _GUARD_TOS_OVERFLOWED_r01 972
+#define _GUARD_TOS_OVERFLOWED_r11 973
+#define _GUARD_TOS_OVERFLOWED_r22 974
+#define _GUARD_TOS_OVERFLOWED_r33 975
+#define _GUARD_TOS_SLICE_r01 976
+#define _GUARD_TOS_SLICE_r11 977
+#define _GUARD_TOS_SLICE_r22 978
+#define _GUARD_TOS_SLICE_r33 979
+#define _GUARD_TOS_TUPLE_r01 980
+#define _GUARD_TOS_TUPLE_r11 981
+#define _GUARD_TOS_TUPLE_r22 982
+#define _GUARD_TOS_TUPLE_r33 983
+#define _GUARD_TOS_UNICODE_r01 984
+#define _GUARD_TOS_UNICODE_r11 985
+#define _GUARD_TOS_UNICODE_r22 986
+#define _GUARD_TOS_UNICODE_r33 987
+#define _GUARD_TYPE_VERSION_r01 988
+#define _GUARD_TYPE_VERSION_r11 989
+#define _GUARD_TYPE_VERSION_r22 990
+#define _GUARD_TYPE_VERSION_r33 991
+#define _GUARD_TYPE_VERSION_AND_LOCK_r01 992
+#define _GUARD_TYPE_VERSION_AND_LOCK_r11 993
+#define _GUARD_TYPE_VERSION_AND_LOCK_r22 994
+#define _GUARD_TYPE_VERSION_AND_LOCK_r33 995
+#define _HANDLE_PENDING_AND_DEOPT_r00 996
+#define _HANDLE_PENDING_AND_DEOPT_r10 997
+#define _HANDLE_PENDING_AND_DEOPT_r20 998
+#define _HANDLE_PENDING_AND_DEOPT_r30 999
+#define _IMPORT_FROM_r12 1000
+#define _IMPORT_NAME_r21 1001
+#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS_r00 1002
+#define _INIT_CALL_PY_EXACT_ARGS_r01 1003
+#define _INIT_CALL_PY_EXACT_ARGS_0_r01 1004
+#define _INIT_CALL_PY_EXACT_ARGS_1_r01 1005
+#define _INIT_CALL_PY_EXACT_ARGS_2_r01 1006
+#define _INIT_CALL_PY_EXACT_ARGS_3_r01 1007
+#define _INIT_CALL_PY_EXACT_ARGS_4_r01 1008
+#define _INSERT_1_LOAD_CONST_INLINE_r02 1009
+#define _INSERT_1_LOAD_CONST_INLINE_r12 1010
+#define _INSERT_1_LOAD_CONST_INLINE_r23 1011
+#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r02 1012
+#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r12 1013
+#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r23 1014
+#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r03 1015
+#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r13 1016
+#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r23 1017
+#define _INSERT_NULL_r10 1018
+#define _INSTRUMENTED_FOR_ITER_r23 1019
+#define _INSTRUMENTED_INSTRUCTION_r00 1020
+#define _INSTRUMENTED_JUMP_FORWARD_r00 1021
+#define _INSTRUMENTED_JUMP_FORWARD_r11 1022
+#define _INSTRUMENTED_JUMP_FORWARD_r22 1023
+#define _INSTRUMENTED_JUMP_FORWARD_r33 1024
+#define _INSTRUMENTED_LINE_r00 1025
+#define _INSTRUMENTED_NOT_TAKEN_r00 1026
+#define _INSTRUMENTED_NOT_TAKEN_r11 1027
+#define _INSTRUMENTED_NOT_TAKEN_r22 1028
+#define _INSTRUMENTED_NOT_TAKEN_r33 1029
+#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r00 1030
+#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r10 1031
+#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r21 1032
+#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r32 1033
+#define _INSTRUMENTED_POP_JUMP_IF_NONE_r10 1034
+#define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE_r10 1035
+#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r00 1036
+#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r10 1037
+#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r21 1038
+#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r32 1039
+#define _IS_NONE_r11 1040
+#define _IS_OP_r03 1041
+#define _IS_OP_r13 1042
+#define _IS_OP_r23 1043
+#define _ITER_CHECK_LIST_r02 1044
+#define _ITER_CHECK_LIST_r12 1045
+#define _ITER_CHECK_LIST_r22 1046
+#define _ITER_CHECK_LIST_r33 1047
+#define _ITER_CHECK_RANGE_r02 1048
+#define _ITER_CHECK_RANGE_r12 1049
+#define _ITER_CHECK_RANGE_r22 1050
+#define _ITER_CHECK_RANGE_r33 1051
+#define _ITER_CHECK_TUPLE_r02 1052
+#define _ITER_CHECK_TUPLE_r12 1053
+#define _ITER_CHECK_TUPLE_r22 1054
+#define _ITER_CHECK_TUPLE_r33 1055
+#define _ITER_JUMP_LIST_r02 1056
+#define _ITER_JUMP_LIST_r12 1057
+#define _ITER_JUMP_LIST_r22 1058
+#define _ITER_JUMP_LIST_r33 1059
+#define _ITER_JUMP_RANGE_r02 1060
+#define _ITER_JUMP_RANGE_r12 1061
+#define _ITER_JUMP_RANGE_r22 1062
+#define _ITER_JUMP_RANGE_r33 1063
+#define _ITER_JUMP_TUPLE_r02 1064
+#define _ITER_JUMP_TUPLE_r12 1065
+#define _ITER_JUMP_TUPLE_r22 1066
+#define _ITER_JUMP_TUPLE_r33 1067
+#define _ITER_NEXT_LIST_r23 1068
+#define _ITER_NEXT_LIST_TIER_TWO_r23 1069
+#define _ITER_NEXT_RANGE_r03 1070
+#define _ITER_NEXT_RANGE_r13 1071
+#define _ITER_NEXT_RANGE_r23 1072
+#define _ITER_NEXT_TUPLE_r03 1073
+#define _ITER_NEXT_TUPLE_r13 1074
+#define _ITER_NEXT_TUPLE_r23 1075
+#define _JUMP_BACKWARD_NO_INTERRUPT_r00 1076
+#define _JUMP_BACKWARD_NO_INTERRUPT_r11 1077
+#define _JUMP_BACKWARD_NO_INTERRUPT_r22 1078
+#define _JUMP_BACKWARD_NO_INTERRUPT_r33 1079
+#define _JUMP_TO_TOP_r00 1080
+#define _LIST_APPEND_r10 1081
+#define _LIST_EXTEND_r10 1082
+#define _LOAD_ATTR_r10 1083
+#define _LOAD_ATTR_CLASS_r11 1084
+#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_r11 1085
+#define _LOAD_ATTR_INSTANCE_VALUE_r02 1086
+#define _LOAD_ATTR_INSTANCE_VALUE_r12 1087
+#define _LOAD_ATTR_INSTANCE_VALUE_r23 1088
+#define _LOAD_ATTR_METHOD_LAZY_DICT_r02 1089
+#define _LOAD_ATTR_METHOD_LAZY_DICT_r12 1090
+#define _LOAD_ATTR_METHOD_LAZY_DICT_r23 1091
+#define _LOAD_ATTR_METHOD_NO_DICT_r02 1092
+#define _LOAD_ATTR_METHOD_NO_DICT_r12 1093
+#define _LOAD_ATTR_METHOD_NO_DICT_r23 1094
+#define _LOAD_ATTR_METHOD_WITH_VALUES_r02 1095
+#define _LOAD_ATTR_METHOD_WITH_VALUES_r12 1096
+#define _LOAD_ATTR_METHOD_WITH_VALUES_r23 1097
+#define _LOAD_ATTR_MODULE_r12 1098
+#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT_r11 1099
+#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES_r11 1100
+#define _LOAD_ATTR_PROPERTY_FRAME_r11 1101
+#define _LOAD_ATTR_SLOT_r02 1102
+#define _LOAD_ATTR_SLOT_r12 1103
+#define _LOAD_ATTR_SLOT_r23 1104
+#define _LOAD_ATTR_WITH_HINT_r12 1105
+#define _LOAD_BUILD_CLASS_r01 1106
+#define _LOAD_BYTECODE_r00 1107
+#define _LOAD_COMMON_CONSTANT_r01 1108
+#define _LOAD_COMMON_CONSTANT_r12 1109
+#define _LOAD_COMMON_CONSTANT_r23 1110
+#define _LOAD_CONST_r01 1111
+#define _LOAD_CONST_r12 1112
+#define _LOAD_CONST_r23 1113
+#define _LOAD_CONST_INLINE_r01 1114
+#define _LOAD_CONST_INLINE_r12 1115
+#define _LOAD_CONST_INLINE_r23 1116
+#define _LOAD_CONST_INLINE_BORROW_r01 1117
+#define _LOAD_CONST_INLINE_BORROW_r12 1118
+#define _LOAD_CONST_INLINE_BORROW_r23 1119
+#define _LOAD_CONST_UNDER_INLINE_r02 1120
+#define _LOAD_CONST_UNDER_INLINE_r12 1121
+#define _LOAD_CONST_UNDER_INLINE_r23 1122
+#define _LOAD_CONST_UNDER_INLINE_BORROW_r02 1123
+#define _LOAD_CONST_UNDER_INLINE_BORROW_r12 1124
+#define _LOAD_CONST_UNDER_INLINE_BORROW_r23 1125
+#define _LOAD_DEREF_r01 1126
+#define _LOAD_FAST_r01 1127
+#define _LOAD_FAST_r12 1128
+#define _LOAD_FAST_r23 1129
+#define _LOAD_FAST_0_r01 1130
+#define _LOAD_FAST_0_r12 1131
+#define _LOAD_FAST_0_r23 1132
+#define _LOAD_FAST_1_r01 1133
+#define _LOAD_FAST_1_r12 1134
+#define _LOAD_FAST_1_r23 1135
+#define _LOAD_FAST_2_r01 1136
+#define _LOAD_FAST_2_r12 1137
+#define _LOAD_FAST_2_r23 1138
+#define _LOAD_FAST_3_r01 1139
+#define _LOAD_FAST_3_r12 1140
+#define _LOAD_FAST_3_r23 1141
+#define _LOAD_FAST_4_r01 1142
+#define _LOAD_FAST_4_r12 1143
+#define _LOAD_FAST_4_r23 1144
+#define _LOAD_FAST_5_r01 1145
+#define _LOAD_FAST_5_r12 1146
+#define _LOAD_FAST_5_r23 1147
+#define _LOAD_FAST_6_r01 1148
+#define _LOAD_FAST_6_r12 1149
+#define _LOAD_FAST_6_r23 1150
+#define _LOAD_FAST_7_r01 1151
+#define _LOAD_FAST_7_r12 1152
+#define _LOAD_FAST_7_r23 1153
+#define _LOAD_FAST_AND_CLEAR_r01 1154
+#define _LOAD_FAST_AND_CLEAR_r12 1155
+#define _LOAD_FAST_AND_CLEAR_r23 1156
+#define _LOAD_FAST_BORROW_r01 1157
+#define _LOAD_FAST_BORROW_r12 1158
+#define _LOAD_FAST_BORROW_r23 1159
+#define _LOAD_FAST_BORROW_0_r01 1160
+#define _LOAD_FAST_BORROW_0_r12 1161
+#define _LOAD_FAST_BORROW_0_r23 1162
+#define _LOAD_FAST_BORROW_1_r01 1163
+#define _LOAD_FAST_BORROW_1_r12 1164
+#define _LOAD_FAST_BORROW_1_r23 1165
+#define _LOAD_FAST_BORROW_2_r01 1166
+#define _LOAD_FAST_BORROW_2_r12 1167
+#define _LOAD_FAST_BORROW_2_r23 1168
+#define _LOAD_FAST_BORROW_3_r01 1169
+#define _LOAD_FAST_BORROW_3_r12 1170
+#define _LOAD_FAST_BORROW_3_r23 1171
+#define _LOAD_FAST_BORROW_4_r01 1172
+#define _LOAD_FAST_BORROW_4_r12 1173
+#define _LOAD_FAST_BORROW_4_r23 1174
+#define _LOAD_FAST_BORROW_5_r01 1175
+#define _LOAD_FAST_BORROW_5_r12 1176
+#define _LOAD_FAST_BORROW_5_r23 1177
+#define _LOAD_FAST_BORROW_6_r01 1178
+#define _LOAD_FAST_BORROW_6_r12 1179
+#define _LOAD_FAST_BORROW_6_r23 1180
+#define _LOAD_FAST_BORROW_7_r01 1181
+#define _LOAD_FAST_BORROW_7_r12 1182
+#define _LOAD_FAST_BORROW_7_r23 1183
+#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r02 1184
+#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r13 1185
+#define _LOAD_FAST_CHECK_r01 1186
+#define _LOAD_FAST_CHECK_r12 1187
+#define _LOAD_FAST_CHECK_r23 1188
+#define _LOAD_FAST_LOAD_FAST_r02 1189
+#define _LOAD_FAST_LOAD_FAST_r13 1190
+#define _LOAD_FROM_DICT_OR_DEREF_r11 1191
+#define _LOAD_FROM_DICT_OR_GLOBALS_r11 1192
+#define _LOAD_GLOBAL_r00 1193
+#define _LOAD_GLOBAL_BUILTINS_r01 1194
+#define _LOAD_GLOBAL_MODULE_r01 1195
+#define _LOAD_LOCALS_r01 1196
+#define _LOAD_LOCALS_r12 1197
+#define _LOAD_LOCALS_r23 1198
+#define _LOAD_NAME_r01 1199
+#define _LOAD_SMALL_INT_r01 1200
+#define _LOAD_SMALL_INT_r12 1201
+#define _LOAD_SMALL_INT_r23 1202
+#define _LOAD_SMALL_INT_0_r01 1203
+#define _LOAD_SMALL_INT_0_r12 1204
+#define _LOAD_SMALL_INT_0_r23 1205
+#define _LOAD_SMALL_INT_1_r01 1206
+#define _LOAD_SMALL_INT_1_r12 1207
+#define _LOAD_SMALL_INT_1_r23 1208
+#define _LOAD_SMALL_INT_2_r01 1209
+#define _LOAD_SMALL_INT_2_r12 1210
+#define _LOAD_SMALL_INT_2_r23 1211
+#define _LOAD_SMALL_INT_3_r01 1212
+#define _LOAD_SMALL_INT_3_r12 1213
+#define _LOAD_SMALL_INT_3_r23 1214
+#define _LOAD_SPECIAL_r00 1215
+#define _LOAD_SUPER_ATTR_ATTR_r31 1216
+#define _LOAD_SUPER_ATTR_METHOD_r32 1217
+#define _MAKE_CALLARGS_A_TUPLE_r33 1218
+#define _MAKE_CELL_r00 1219
+#define _MAKE_FUNCTION_r11 1220
+#define _MAKE_WARM_r00 1221
+#define _MAKE_WARM_r11 1222
+#define _MAKE_WARM_r22 1223
+#define _MAKE_WARM_r33 1224
+#define _MAP_ADD_r20 1225
+#define _MATCH_CLASS_r31 1226
+#define _MATCH_KEYS_r23 1227
+#define _MATCH_MAPPING_r02 1228
+#define _MATCH_MAPPING_r12 1229
+#define _MATCH_MAPPING_r23 1230
+#define _MATCH_SEQUENCE_r02 1231
+#define _MATCH_SEQUENCE_r12 1232
+#define _MATCH_SEQUENCE_r23 1233
+#define _MAYBE_EXPAND_METHOD_r00 1234
+#define _MAYBE_EXPAND_METHOD_KW_r11 1235
+#define _MONITOR_CALL_r00 1236
+#define _MONITOR_CALL_KW_r11 1237
+#define _MONITOR_JUMP_BACKWARD_r00 1238
+#define _MONITOR_JUMP_BACKWARD_r11 1239
+#define _MONITOR_JUMP_BACKWARD_r22 1240
+#define _MONITOR_JUMP_BACKWARD_r33 1241
+#define _MONITOR_RESUME_r00 1242
+#define _NOP_r00 1243
+#define _NOP_r11 1244
+#define _NOP_r22 1245
+#define _NOP_r33 1246
+#define _POP_CALL_r20 1247
+#define _POP_CALL_LOAD_CONST_INLINE_BORROW_r21 1248
+#define _POP_CALL_ONE_r30 1249
+#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW_r31 1250
+#define _POP_CALL_TWO_r30 1251
+#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW_r31 1252
+#define _POP_EXCEPT_r10 1253
+#define _POP_ITER_r20 1254
+#define _POP_JUMP_IF_FALSE_r00 1255
+#define _POP_JUMP_IF_FALSE_r10 1256
+#define _POP_JUMP_IF_FALSE_r21 1257
+#define _POP_JUMP_IF_FALSE_r32 1258
+#define _POP_JUMP_IF_TRUE_r00 1259
+#define _POP_JUMP_IF_TRUE_r10 1260
+#define _POP_JUMP_IF_TRUE_r21 1261
+#define _POP_JUMP_IF_TRUE_r32 1262
+#define _POP_TOP_r10 1263
+#define _POP_TOP_FLOAT_r00 1264
+#define _POP_TOP_FLOAT_r10 1265
+#define _POP_TOP_FLOAT_r21 1266
+#define _POP_TOP_FLOAT_r32 1267
+#define _POP_TOP_INT_r00 1268
+#define _POP_TOP_INT_r10 1269
+#define _POP_TOP_INT_r21 1270
+#define _POP_TOP_INT_r32 1271
+#define _POP_TOP_LOAD_CONST_INLINE_r11 1272
+#define _POP_TOP_LOAD_CONST_INLINE_BORROW_r11 1273
+#define _POP_TOP_NOP_r00 1274
+#define _POP_TOP_NOP_r10 1275
+#define _POP_TOP_NOP_r21 1276
+#define _POP_TOP_NOP_r32 1277
+#define _POP_TOP_UNICODE_r00 1278
+#define _POP_TOP_UNICODE_r10 1279
+#define _POP_TOP_UNICODE_r21 1280
+#define _POP_TOP_UNICODE_r32 1281
+#define _POP_TWO_r20 1282
+#define _POP_TWO_LOAD_CONST_INLINE_BORROW_r21 1283
+#define _PUSH_EXC_INFO_r02 1284
+#define _PUSH_EXC_INFO_r12 1285
+#define _PUSH_EXC_INFO_r23 1286
+#define _PUSH_FRAME_r10 1287
+#define _PUSH_NULL_r01 1288
+#define _PUSH_NULL_r12 1289
+#define _PUSH_NULL_r23 1290
+#define _PUSH_NULL_CONDITIONAL_r00 1291
+#define _PY_FRAME_EX_r31 1292
+#define _PY_FRAME_GENERAL_r01 1293
+#define _PY_FRAME_KW_r11 1294
+#define _QUICKEN_RESUME_r00 1295
+#define _QUICKEN_RESUME_r11 1296
+#define _QUICKEN_RESUME_r22 1297
+#define _QUICKEN_RESUME_r33 1298
+#define _REPLACE_WITH_TRUE_r02 1299
+#define _REPLACE_WITH_TRUE_r12 1300
+#define _REPLACE_WITH_TRUE_r23 1301
+#define _RESUME_CHECK_r00 1302
+#define _RESUME_CHECK_r11 1303
+#define _RESUME_CHECK_r22 1304
+#define _RESUME_CHECK_r33 1305
+#define _RETURN_GENERATOR_r01 1306
+#define _RETURN_VALUE_r11 1307
+#define _SAVE_RETURN_OFFSET_r00 1308
+#define _SAVE_RETURN_OFFSET_r11 1309
+#define _SAVE_RETURN_OFFSET_r22 1310
+#define _SAVE_RETURN_OFFSET_r33 1311
+#define _SEND_r22 1312
+#define _SEND_GEN_FRAME_r22 1313
+#define _SETUP_ANNOTATIONS_r00 1314
+#define _SET_ADD_r10 1315
+#define _SET_FUNCTION_ATTRIBUTE_r01 1316
+#define _SET_FUNCTION_ATTRIBUTE_r11 1317
+#define _SET_FUNCTION_ATTRIBUTE_r21 1318
+#define _SET_FUNCTION_ATTRIBUTE_r32 1319
+#define _SET_IP_r00 1320
+#define _SET_IP_r11 1321
+#define _SET_IP_r22 1322
+#define _SET_IP_r33 1323
+#define _SET_UPDATE_r10 1324
+#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r02 1325
+#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r12 1326
+#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r22 1327
+#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r32 1328
+#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03 1329
+#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13 1330
+#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23 1331
+#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33 1332
+#define _SPILL_OR_RELOAD_r01 1333
+#define _SPILL_OR_RELOAD_r02 1334
+#define _SPILL_OR_RELOAD_r03 1335
+#define _SPILL_OR_RELOAD_r10 1336
+#define _SPILL_OR_RELOAD_r12 1337
+#define _SPILL_OR_RELOAD_r13 1338
+#define _SPILL_OR_RELOAD_r20 1339
+#define _SPILL_OR_RELOAD_r21 1340
+#define _SPILL_OR_RELOAD_r23 1341
+#define _SPILL_OR_RELOAD_r30 1342
+#define _SPILL_OR_RELOAD_r31 1343
+#define _SPILL_OR_RELOAD_r32 1344
+#define _START_EXECUTOR_r00 1345
+#define _STORE_ATTR_r20 1346
+#define _STORE_ATTR_INSTANCE_VALUE_r21 1347
+#define _STORE_ATTR_INSTANCE_VALUE_NULL_r01 1348
+#define _STORE_ATTR_INSTANCE_VALUE_NULL_r11 1349
+#define _STORE_ATTR_INSTANCE_VALUE_NULL_r21 1350
+#define _STORE_ATTR_INSTANCE_VALUE_NULL_r32 1351
+#define _STORE_ATTR_SLOT_r21 1352
+#define _STORE_ATTR_SLOT_NULL_r01 1353
+#define _STORE_ATTR_SLOT_NULL_r11 1354
+#define _STORE_ATTR_SLOT_NULL_r21 1355
+#define _STORE_ATTR_SLOT_NULL_r32 1356
+#define _STORE_ATTR_WITH_HINT_r21 1357
+#define _STORE_DEREF_r10 1358
+#define _STORE_FAST_LOAD_FAST_r11 1359
+#define _STORE_FAST_STORE_FAST_r20 1360
+#define _STORE_GLOBAL_r10 1361
+#define _STORE_NAME_r10 1362
+#define _STORE_SLICE_r30 1363
+#define _STORE_SUBSCR_r30 1364
+#define _STORE_SUBSCR_DICT_r31 1365
+#define _STORE_SUBSCR_LIST_INT_r32 1366
+#define _SWAP_r11 1367
+#define _SWAP_2_r02 1368
+#define _SWAP_2_r12 1369
+#define _SWAP_2_r22 1370
+#define _SWAP_2_r33 1371
+#define _SWAP_3_r03 1372
+#define _SWAP_3_r13 1373
+#define _SWAP_3_r23 1374
+#define _SWAP_3_r33 1375
+#define _SWAP_FAST_r01 1376
+#define _SWAP_FAST_r11 1377
+#define _SWAP_FAST_r22 1378
+#define _SWAP_FAST_r33 1379
+#define _SWAP_FAST_0_r01 1380
+#define _SWAP_FAST_0_r11 1381
+#define _SWAP_FAST_0_r22 1382
+#define _SWAP_FAST_0_r33 1383
+#define _SWAP_FAST_1_r01 1384
+#define _SWAP_FAST_1_r11 1385
+#define _SWAP_FAST_1_r22 1386
+#define _SWAP_FAST_1_r33 1387
+#define _SWAP_FAST_2_r01 1388
+#define _SWAP_FAST_2_r11 1389
+#define _SWAP_FAST_2_r22 1390
+#define _SWAP_FAST_2_r33 1391
+#define _SWAP_FAST_3_r01 1392
+#define _SWAP_FAST_3_r11 1393
+#define _SWAP_FAST_3_r22 1394
+#define _SWAP_FAST_3_r33 1395
+#define _SWAP_FAST_4_r01 1396
+#define _SWAP_FAST_4_r11 1397
+#define _SWAP_FAST_4_r22 1398
+#define _SWAP_FAST_4_r33 1399
+#define _SWAP_FAST_5_r01 1400
+#define _SWAP_FAST_5_r11 1401
+#define _SWAP_FAST_5_r22 1402
+#define _SWAP_FAST_5_r33 1403
+#define _SWAP_FAST_6_r01 1404
+#define _SWAP_FAST_6_r11 1405
+#define _SWAP_FAST_6_r22 1406
+#define _SWAP_FAST_6_r33 1407
+#define _SWAP_FAST_7_r01 1408
+#define _SWAP_FAST_7_r11 1409
+#define _SWAP_FAST_7_r22 1410
+#define _SWAP_FAST_7_r33 1411
+#define _TIER2_RESUME_CHECK_r00 1412
+#define _TIER2_RESUME_CHECK_r11 1413
+#define _TIER2_RESUME_CHECK_r22 1414
+#define _TIER2_RESUME_CHECK_r33 1415
+#define _TO_BOOL_r11 1416
+#define _TO_BOOL_BOOL_r01 1417
+#define _TO_BOOL_BOOL_r11 1418
+#define _TO_BOOL_BOOL_r22 1419
+#define _TO_BOOL_BOOL_r33 1420
+#define _TO_BOOL_INT_r02 1421
+#define _TO_BOOL_INT_r12 1422
+#define _TO_BOOL_INT_r23 1423
+#define _TO_BOOL_LIST_r02 1424
+#define _TO_BOOL_LIST_r12 1425
+#define _TO_BOOL_LIST_r23 1426
+#define _TO_BOOL_NONE_r01 1427
+#define _TO_BOOL_NONE_r11 1428
+#define _TO_BOOL_NONE_r22 1429
+#define _TO_BOOL_NONE_r33 1430
+#define _TO_BOOL_STR_r02 1431
+#define _TO_BOOL_STR_r12 1432
+#define _TO_BOOL_STR_r23 1433
+#define _TRACE_RECORD_r00 1434
+#define _UNARY_INVERT_r12 1435
+#define _UNARY_NEGATIVE_r12 1436
+#define _UNARY_NOT_r01 1437
+#define _UNARY_NOT_r11 1438
+#define _UNARY_NOT_r22 1439
+#define _UNARY_NOT_r33 1440
+#define _UNPACK_EX_r10 1441
+#define _UNPACK_SEQUENCE_r10 1442
+#define _UNPACK_SEQUENCE_LIST_r10 1443
+#define _UNPACK_SEQUENCE_TUPLE_r10 1444
+#define _UNPACK_SEQUENCE_TWO_TUPLE_r12 1445
+#define _WITH_EXCEPT_START_r33 1446
+#define _YIELD_VALUE_r11 1447
+#define MAX_UOP_REGS_ID 1447
#ifdef __cplusplus
}
diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h
index 1e74588d3aa62e..d19f219c165324 100644
--- a/Include/internal/pycore_uop_metadata.h
+++ b/Include/internal/pycore_uop_metadata.h
@@ -65,15 +65,15 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_LOAD_SMALL_INT_2] = 0,
[_LOAD_SMALL_INT_3] = 0,
[_LOAD_SMALL_INT] = HAS_ARG_FLAG,
- [_STORE_FAST_0] = HAS_LOCAL_FLAG | HAS_ESCAPES_FLAG,
- [_STORE_FAST_1] = HAS_LOCAL_FLAG | HAS_ESCAPES_FLAG,
- [_STORE_FAST_2] = HAS_LOCAL_FLAG | HAS_ESCAPES_FLAG,
- [_STORE_FAST_3] = HAS_LOCAL_FLAG | HAS_ESCAPES_FLAG,
- [_STORE_FAST_4] = HAS_LOCAL_FLAG | HAS_ESCAPES_FLAG,
- [_STORE_FAST_5] = HAS_LOCAL_FLAG | HAS_ESCAPES_FLAG,
- [_STORE_FAST_6] = HAS_LOCAL_FLAG | HAS_ESCAPES_FLAG,
- [_STORE_FAST_7] = HAS_LOCAL_FLAG | HAS_ESCAPES_FLAG,
- [_STORE_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_ESCAPES_FLAG,
+ [_SWAP_FAST_0] = HAS_LOCAL_FLAG,
+ [_SWAP_FAST_1] = HAS_LOCAL_FLAG,
+ [_SWAP_FAST_2] = HAS_LOCAL_FLAG,
+ [_SWAP_FAST_3] = HAS_LOCAL_FLAG,
+ [_SWAP_FAST_4] = HAS_LOCAL_FLAG,
+ [_SWAP_FAST_5] = HAS_LOCAL_FLAG,
+ [_SWAP_FAST_6] = HAS_LOCAL_FLAG,
+ [_SWAP_FAST_7] = HAS_LOCAL_FLAG,
+ [_SWAP_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG,
[_POP_TOP] = HAS_ESCAPES_FLAG | HAS_PURE_FLAG,
[_POP_TOP_NOP] = 0,
[_POP_TOP_INT] = 0,
@@ -84,21 +84,22 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_END_FOR] = HAS_ESCAPES_FLAG | HAS_NO_SAVE_IP_FLAG,
[_POP_ITER] = HAS_ESCAPES_FLAG,
[_END_SEND] = HAS_ESCAPES_FLAG | HAS_PURE_FLAG,
- [_UNARY_NEGATIVE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
- [_UNARY_NOT] = HAS_PURE_FLAG,
+ [_UNARY_NEGATIVE] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
+ [_UNARY_NOT] = 0,
[_TO_BOOL] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_TO_BOOL_BOOL] = HAS_EXIT_FLAG,
- [_TO_BOOL_INT] = HAS_EXIT_FLAG | HAS_ESCAPES_FLAG,
+ [_TO_BOOL_INT] = 0,
[_GUARD_NOS_LIST] = HAS_EXIT_FLAG,
[_GUARD_TOS_LIST] = HAS_EXIT_FLAG,
[_GUARD_TOS_SLICE] = HAS_EXIT_FLAG,
- [_TO_BOOL_LIST] = HAS_ESCAPES_FLAG,
+ [_TO_BOOL_LIST] = 0,
[_TO_BOOL_NONE] = HAS_EXIT_FLAG,
+ [_GUARD_NOS_COMPACT_ASCII] = HAS_EXIT_FLAG,
[_GUARD_NOS_UNICODE] = HAS_EXIT_FLAG,
[_GUARD_TOS_UNICODE] = HAS_EXIT_FLAG,
- [_TO_BOOL_STR] = HAS_ESCAPES_FLAG,
- [_REPLACE_WITH_TRUE] = HAS_ESCAPES_FLAG,
- [_UNARY_INVERT] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_TO_BOOL_STR] = 0,
+ [_REPLACE_WITH_TRUE] = 0,
+ [_UNARY_INVERT] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
[_GUARD_NOS_INT] = HAS_EXIT_FLAG,
[_GUARD_TOS_INT] = HAS_EXIT_FLAG,
[_GUARD_NOS_OVERFLOWED] = HAS_EXIT_FLAG,
@@ -108,27 +109,26 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_BINARY_OP_SUBTRACT_INT] = HAS_EXIT_FLAG | HAS_PURE_FLAG,
[_GUARD_NOS_FLOAT] = HAS_EXIT_FLAG,
[_GUARD_TOS_FLOAT] = HAS_EXIT_FLAG,
- [_BINARY_OP_MULTIPLY_FLOAT] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
- [_BINARY_OP_ADD_FLOAT] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
- [_BINARY_OP_SUBTRACT_FLOAT] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
- [_BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
- [_BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
- [_BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
- [_BINARY_OP_ADD_UNICODE] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
+ [_BINARY_OP_MULTIPLY_FLOAT] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_PURE_FLAG,
+ [_BINARY_OP_ADD_FLOAT] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_PURE_FLAG,
+ [_BINARY_OP_SUBTRACT_FLOAT] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_PURE_FLAG,
+ [_BINARY_OP_ADD_UNICODE] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_PURE_FLAG,
[_BINARY_OP_INPLACE_ADD_UNICODE] = HAS_LOCAL_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_GUARD_BINARY_OP_EXTEND] = HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
- [_BINARY_OP_EXTEND] = HAS_ESCAPES_FLAG,
+ [_BINARY_OP_EXTEND] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
[_BINARY_SLICE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_STORE_SLICE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_BINARY_OP_SUBSCR_LIST_INT] = HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
[_BINARY_OP_SUBSCR_LIST_SLICE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
- [_BINARY_OP_SUBSCR_STR_INT] = HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
+ [_BINARY_OP_SUBSCR_STR_INT] = HAS_DEOPT_FLAG,
+ [_BINARY_OP_SUBSCR_USTR_INT] = HAS_DEOPT_FLAG,
[_GUARD_NOS_TUPLE] = HAS_EXIT_FLAG,
[_GUARD_TOS_TUPLE] = HAS_EXIT_FLAG,
- [_BINARY_OP_SUBSCR_TUPLE_INT] = HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
+ [_GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS] = HAS_DEOPT_FLAG,
+ [_BINARY_OP_SUBSCR_TUPLE_INT] = 0,
[_GUARD_NOS_DICT] = HAS_EXIT_FLAG,
[_GUARD_TOS_DICT] = HAS_EXIT_FLAG,
- [_BINARY_OP_SUBSCR_DICT] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_BINARY_OP_SUBSCR_DICT] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
[_BINARY_OP_SUBSCR_CHECK_FUNC] = HAS_DEOPT_FLAG,
[_BINARY_OP_SUBSCR_INIT_CALL] = 0,
[_LIST_APPEND] = HAS_ARG_FLAG | HAS_ERROR_FLAG,
@@ -192,26 +192,28 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_GUARD_TYPE_VERSION] = HAS_EXIT_FLAG,
[_GUARD_TYPE_VERSION_AND_LOCK] = HAS_EXIT_FLAG,
[_CHECK_MANAGED_OBJECT_HAS_VALUES] = HAS_DEOPT_FLAG,
- [_LOAD_ATTR_INSTANCE_VALUE] = HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
- [_LOAD_ATTR_MODULE] = HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
- [_LOAD_ATTR_WITH_HINT] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
- [_LOAD_ATTR_SLOT] = HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
+ [_LOAD_ATTR_INSTANCE_VALUE] = HAS_DEOPT_FLAG,
+ [_LOAD_ATTR_MODULE] = HAS_DEOPT_FLAG,
+ [_LOAD_ATTR_WITH_HINT] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG,
+ [_LOAD_ATTR_SLOT] = HAS_DEOPT_FLAG,
[_CHECK_ATTR_CLASS] = HAS_EXIT_FLAG,
[_LOAD_ATTR_CLASS] = HAS_ESCAPES_FLAG,
[_LOAD_ATTR_PROPERTY_FRAME] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
[_GUARD_DORV_NO_DICT] = HAS_EXIT_FLAG,
[_STORE_ATTR_INSTANCE_VALUE] = HAS_ESCAPES_FLAG,
+ [_STORE_ATTR_INSTANCE_VALUE_NULL] = HAS_DEOPT_FLAG,
[_STORE_ATTR_WITH_HINT] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
[_STORE_ATTR_SLOT] = HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
+ [_STORE_ATTR_SLOT_NULL] = HAS_DEOPT_FLAG,
[_COMPARE_OP] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_COMPARE_OP_FLOAT] = HAS_ARG_FLAG,
[_COMPARE_OP_INT] = HAS_ARG_FLAG,
[_COMPARE_OP_STR] = HAS_ARG_FLAG,
- [_IS_OP] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG,
- [_CONTAINS_OP] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_IS_OP] = HAS_ARG_FLAG,
+ [_CONTAINS_OP] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
[_GUARD_TOS_ANY_SET] = HAS_DEOPT_FLAG,
- [_CONTAINS_OP_SET] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
- [_CONTAINS_OP_DICT] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CONTAINS_OP_SET] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
+ [_CONTAINS_OP_DICT] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
[_CHECK_EG_MATCH] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_CHECK_EXC_MATCH] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
[_IMPORT_NAME] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
@@ -272,16 +274,16 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_GUARD_NOS_NOT_NULL] = HAS_EXIT_FLAG,
[_GUARD_THIRD_NULL] = HAS_DEOPT_FLAG,
[_GUARD_CALLABLE_TYPE_1] = HAS_DEOPT_FLAG,
- [_CALL_TYPE_1] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG,
+ [_CALL_TYPE_1] = HAS_ARG_FLAG,
[_GUARD_CALLABLE_STR_1] = HAS_DEOPT_FLAG,
- [_CALL_STR_1] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CALL_STR_1] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
[_GUARD_CALLABLE_TUPLE_1] = HAS_DEOPT_FLAG,
- [_CALL_TUPLE_1] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CALL_TUPLE_1] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
[_CHECK_AND_ALLOCATE_OBJECT] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
[_CREATE_INIT_FRAME] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG,
[_EXIT_INIT_CHECK] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
[_CALL_BUILTIN_CLASS] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
- [_CALL_BUILTIN_O] = HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CALL_BUILTIN_O] = HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
[_CALL_BUILTIN_FAST] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_CALL_BUILTIN_FAST_WITH_KEYWORDS] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_GUARD_CALLABLE_LEN] = HAS_DEOPT_FLAG,
@@ -289,8 +291,8 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_GUARD_CALLABLE_ISINSTANCE] = HAS_DEOPT_FLAG,
[_CALL_ISINSTANCE] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
[_GUARD_CALLABLE_LIST_APPEND] = HAS_DEOPT_FLAG,
- [_CALL_LIST_APPEND] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
- [_CALL_METHOD_DESCRIPTOR_O] = HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CALL_LIST_APPEND] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG,
+ [_CALL_METHOD_DESCRIPTOR_O] = HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
[_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_CALL_METHOD_DESCRIPTOR_NOARGS] = HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_CALL_METHOD_DESCRIPTOR_FAST] = HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
@@ -302,6 +304,10 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_CHECK_IS_NOT_PY_CALLABLE_KW] = HAS_ARG_FLAG | HAS_EXIT_FLAG,
[_CALL_KW_NON_PY] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_MAKE_CALLARGS_A_TUPLE] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
+ [_CHECK_IS_PY_CALLABLE_EX] = HAS_EXIT_FLAG,
+ [_PY_FRAME_EX] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG,
+ [_CHECK_IS_NOT_PY_CALLABLE_EX] = HAS_EXIT_FLAG,
+ [_CALL_FUNCTION_EX_NON_PY_GENERAL] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_MAKE_FUNCTION] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_SET_FUNCTION_ATTRIBUTE] = HAS_ARG_FLAG,
[_RETURN_GENERATOR] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_NEEDS_GUARD_IP_FLAG,
@@ -319,6 +325,16 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_SWAP] = HAS_ARG_FLAG | HAS_PURE_FLAG,
[_GUARD_IS_TRUE_POP] = HAS_EXIT_FLAG,
[_GUARD_IS_FALSE_POP] = HAS_EXIT_FLAG,
+ [_GUARD_BIT_IS_SET_POP_4] = HAS_EXIT_FLAG,
+ [_GUARD_BIT_IS_SET_POP_5] = HAS_EXIT_FLAG,
+ [_GUARD_BIT_IS_SET_POP_6] = HAS_EXIT_FLAG,
+ [_GUARD_BIT_IS_SET_POP_7] = HAS_EXIT_FLAG,
+ [_GUARD_BIT_IS_SET_POP] = HAS_ARG_FLAG | HAS_EXIT_FLAG,
+ [_GUARD_BIT_IS_UNSET_POP_4] = HAS_EXIT_FLAG,
+ [_GUARD_BIT_IS_UNSET_POP_5] = HAS_EXIT_FLAG,
+ [_GUARD_BIT_IS_UNSET_POP_6] = HAS_EXIT_FLAG,
+ [_GUARD_BIT_IS_UNSET_POP_7] = HAS_EXIT_FLAG,
+ [_GUARD_BIT_IS_UNSET_POP] = HAS_ARG_FLAG | HAS_EXIT_FLAG,
[_GUARD_IS_NONE_POP] = HAS_EXIT_FLAG,
[_GUARD_IS_NOT_NONE_POP] = HAS_EXIT_FLAG | HAS_ESCAPES_FLAG,
[_JUMP_TO_TOP] = 0,
@@ -338,6 +354,11 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_POP_TWO_LOAD_CONST_INLINE_BORROW] = HAS_ESCAPES_FLAG,
[_POP_CALL_LOAD_CONST_INLINE_BORROW] = HAS_ESCAPES_FLAG,
[_POP_CALL_ONE_LOAD_CONST_INLINE_BORROW] = HAS_ESCAPES_FLAG,
+ [_INSERT_1_LOAD_CONST_INLINE] = 0,
+ [_INSERT_1_LOAD_CONST_INLINE_BORROW] = 0,
+ [_INSERT_2_LOAD_CONST_INLINE_BORROW] = 0,
+ [_SHUFFLE_2_LOAD_CONST_INLINE_BORROW] = 0,
+ [_SHUFFLE_3_LOAD_CONST_INLINE_BORROW] = 0,
[_POP_CALL_TWO_LOAD_CONST_INLINE_BORROW] = HAS_ESCAPES_FLAG,
[_LOAD_CONST_UNDER_INLINE] = 0,
[_LOAD_CONST_UNDER_INLINE_BORROW] = 0,
@@ -361,10 +382,12 @@ const ReplicationRange _PyUop_Replication[MAX_UOP_ID+1] = {
[_LOAD_FAST] = { 0, 8 },
[_LOAD_FAST_BORROW] = { 0, 8 },
[_LOAD_SMALL_INT] = { 0, 4 },
- [_STORE_FAST] = { 0, 8 },
+ [_SWAP_FAST] = { 0, 8 },
[_INIT_CALL_PY_EXACT_ARGS] = { 0, 5 },
[_COPY] = { 1, 4 },
[_SWAP] = { 2, 4 },
+ [_GUARD_BIT_IS_SET_POP] = { 4, 8 },
+ [_GUARD_BIT_IS_UNSET_POP] = { 4, 8 },
};
const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
@@ -405,11 +428,11 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
},
},
[_LOAD_FAST_CHECK] = {
- .best = { 0, 0, 0, 0 },
+ .best = { 0, 1, 2, 2 },
.entries = {
{ 1, 0, _LOAD_FAST_CHECK_r01 },
- { -1, -1, -1 },
- { -1, -1, -1 },
+ { 2, 1, _LOAD_FAST_CHECK_r12 },
+ { 3, 2, _LOAD_FAST_CHECK_r23 },
{ -1, -1, -1 },
},
},
@@ -638,85 +661,85 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
{ -1, -1, -1 },
},
},
- [_STORE_FAST_0] = {
- .best = { 1, 1, 1, 1 },
+ [_SWAP_FAST_0] = {
+ .best = { 0, 1, 2, 3 },
.entries = {
- { -1, -1, -1 },
- { 0, 1, _STORE_FAST_0_r10 },
- { -1, -1, -1 },
- { -1, -1, -1 },
+ { 1, 0, _SWAP_FAST_0_r01 },
+ { 1, 1, _SWAP_FAST_0_r11 },
+ { 2, 2, _SWAP_FAST_0_r22 },
+ { 3, 3, _SWAP_FAST_0_r33 },
},
},
- [_STORE_FAST_1] = {
- .best = { 1, 1, 1, 1 },
+ [_SWAP_FAST_1] = {
+ .best = { 0, 1, 2, 3 },
.entries = {
- { -1, -1, -1 },
- { 0, 1, _STORE_FAST_1_r10 },
- { -1, -1, -1 },
- { -1, -1, -1 },
+ { 1, 0, _SWAP_FAST_1_r01 },
+ { 1, 1, _SWAP_FAST_1_r11 },
+ { 2, 2, _SWAP_FAST_1_r22 },
+ { 3, 3, _SWAP_FAST_1_r33 },
},
},
- [_STORE_FAST_2] = {
- .best = { 1, 1, 1, 1 },
+ [_SWAP_FAST_2] = {
+ .best = { 0, 1, 2, 3 },
.entries = {
- { -1, -1, -1 },
- { 0, 1, _STORE_FAST_2_r10 },
- { -1, -1, -1 },
- { -1, -1, -1 },
+ { 1, 0, _SWAP_FAST_2_r01 },
+ { 1, 1, _SWAP_FAST_2_r11 },
+ { 2, 2, _SWAP_FAST_2_r22 },
+ { 3, 3, _SWAP_FAST_2_r33 },
},
},
- [_STORE_FAST_3] = {
- .best = { 1, 1, 1, 1 },
+ [_SWAP_FAST_3] = {
+ .best = { 0, 1, 2, 3 },
.entries = {
- { -1, -1, -1 },
- { 0, 1, _STORE_FAST_3_r10 },
- { -1, -1, -1 },
- { -1, -1, -1 },
+ { 1, 0, _SWAP_FAST_3_r01 },
+ { 1, 1, _SWAP_FAST_3_r11 },
+ { 2, 2, _SWAP_FAST_3_r22 },
+ { 3, 3, _SWAP_FAST_3_r33 },
},
},
- [_STORE_FAST_4] = {
- .best = { 1, 1, 1, 1 },
+ [_SWAP_FAST_4] = {
+ .best = { 0, 1, 2, 3 },
.entries = {
- { -1, -1, -1 },
- { 0, 1, _STORE_FAST_4_r10 },
- { -1, -1, -1 },
- { -1, -1, -1 },
+ { 1, 0, _SWAP_FAST_4_r01 },
+ { 1, 1, _SWAP_FAST_4_r11 },
+ { 2, 2, _SWAP_FAST_4_r22 },
+ { 3, 3, _SWAP_FAST_4_r33 },
},
},
- [_STORE_FAST_5] = {
- .best = { 1, 1, 1, 1 },
+ [_SWAP_FAST_5] = {
+ .best = { 0, 1, 2, 3 },
.entries = {
- { -1, -1, -1 },
- { 0, 1, _STORE_FAST_5_r10 },
- { -1, -1, -1 },
- { -1, -1, -1 },
+ { 1, 0, _SWAP_FAST_5_r01 },
+ { 1, 1, _SWAP_FAST_5_r11 },
+ { 2, 2, _SWAP_FAST_5_r22 },
+ { 3, 3, _SWAP_FAST_5_r33 },
},
},
- [_STORE_FAST_6] = {
- .best = { 1, 1, 1, 1 },
+ [_SWAP_FAST_6] = {
+ .best = { 0, 1, 2, 3 },
.entries = {
- { -1, -1, -1 },
- { 0, 1, _STORE_FAST_6_r10 },
- { -1, -1, -1 },
- { -1, -1, -1 },
+ { 1, 0, _SWAP_FAST_6_r01 },
+ { 1, 1, _SWAP_FAST_6_r11 },
+ { 2, 2, _SWAP_FAST_6_r22 },
+ { 3, 3, _SWAP_FAST_6_r33 },
},
},
- [_STORE_FAST_7] = {
- .best = { 1, 1, 1, 1 },
+ [_SWAP_FAST_7] = {
+ .best = { 0, 1, 2, 3 },
.entries = {
- { -1, -1, -1 },
- { 0, 1, _STORE_FAST_7_r10 },
- { -1, -1, -1 },
- { -1, -1, -1 },
+ { 1, 0, _SWAP_FAST_7_r01 },
+ { 1, 1, _SWAP_FAST_7_r11 },
+ { 2, 2, _SWAP_FAST_7_r22 },
+ { 3, 3, _SWAP_FAST_7_r33 },
},
},
- [_STORE_FAST] = {
- .best = { 1, 1, 1, 1 },
+ [_SWAP_FAST] = {
+ .best = { 0, 1, 2, 3 },
.entries = {
- { -1, -1, -1 },
- { 0, 1, _STORE_FAST_r10 },
- { -1, -1, -1 },
- { -1, -1, -1 },
+ { 1, 0, _SWAP_FAST_r01 },
+ { 1, 1, _SWAP_FAST_r11 },
+ { 2, 2, _SWAP_FAST_r22 },
+ { 3, 3, _SWAP_FAST_r33 },
},
},
[_POP_TOP] = {
@@ -813,7 +836,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 1, 0, _UNARY_NEGATIVE_r11 },
+ { 2, 1, _UNARY_NEGATIVE_r12 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -831,7 +854,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 1, 0, _TO_BOOL_r11 },
+ { 1, 1, _TO_BOOL_r11 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -846,11 +869,11 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
},
},
[_TO_BOOL_INT] = {
- .best = { 1, 1, 1, 1 },
+ .best = { 0, 1, 2, 2 },
.entries = {
- { -1, -1, -1 },
- { 1, 1, _TO_BOOL_INT_r11 },
- { -1, -1, -1 },
+ { 2, 0, _TO_BOOL_INT_r02 },
+ { 2, 1, _TO_BOOL_INT_r12 },
+ { 3, 2, _TO_BOOL_INT_r23 },
{ -1, -1, -1 },
},
},
@@ -882,11 +905,11 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
},
},
[_TO_BOOL_LIST] = {
- .best = { 1, 1, 1, 1 },
+ .best = { 0, 1, 2, 2 },
.entries = {
- { -1, -1, -1 },
- { 1, 1, _TO_BOOL_LIST_r11 },
- { -1, -1, -1 },
+ { 2, 0, _TO_BOOL_LIST_r02 },
+ { 2, 1, _TO_BOOL_LIST_r12 },
+ { 3, 2, _TO_BOOL_LIST_r23 },
{ -1, -1, -1 },
},
},
@@ -899,6 +922,15 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
{ 3, 3, _TO_BOOL_NONE_r33 },
},
},
+ [_GUARD_NOS_COMPACT_ASCII] = {
+ .best = { 0, 1, 2, 3 },
+ .entries = {
+ { 2, 0, _GUARD_NOS_COMPACT_ASCII_r02 },
+ { 2, 1, _GUARD_NOS_COMPACT_ASCII_r12 },
+ { 2, 2, _GUARD_NOS_COMPACT_ASCII_r22 },
+ { 3, 3, _GUARD_NOS_COMPACT_ASCII_r33 },
+ },
+ },
[_GUARD_NOS_UNICODE] = {
.best = { 0, 1, 2, 3 },
.entries = {
@@ -918,20 +950,20 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
},
},
[_TO_BOOL_STR] = {
- .best = { 1, 1, 1, 1 },
+ .best = { 0, 1, 2, 2 },
.entries = {
- { -1, -1, -1 },
- { 1, 1, _TO_BOOL_STR_r11 },
- { -1, -1, -1 },
+ { 2, 0, _TO_BOOL_STR_r02 },
+ { 2, 1, _TO_BOOL_STR_r12 },
+ { 3, 2, _TO_BOOL_STR_r23 },
{ -1, -1, -1 },
},
},
[_REPLACE_WITH_TRUE] = {
- .best = { 1, 1, 1, 1 },
+ .best = { 0, 1, 2, 2 },
.entries = {
- { -1, -1, -1 },
- { 1, 1, _REPLACE_WITH_TRUE_r11 },
- { -1, -1, -1 },
+ { 2, 0, _REPLACE_WITH_TRUE_r02 },
+ { 2, 1, _REPLACE_WITH_TRUE_r12 },
+ { 3, 2, _REPLACE_WITH_TRUE_r23 },
{ -1, -1, -1 },
},
},
@@ -939,7 +971,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 1, 0, _UNARY_INVERT_r11 },
+ { 2, 1, _UNARY_INVERT_r12 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -981,30 +1013,30 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
},
},
[_BINARY_OP_MULTIPLY_INT] = {
- .best = { 0, 1, 2, 3 },
+ .best = { 0, 1, 2, 2 },
.entries = {
- { 1, 0, _BINARY_OP_MULTIPLY_INT_r01 },
- { 1, 1, _BINARY_OP_MULTIPLY_INT_r11 },
- { 1, 2, _BINARY_OP_MULTIPLY_INT_r21 },
- { 2, 3, _BINARY_OP_MULTIPLY_INT_r32 },
+ { 3, 0, _BINARY_OP_MULTIPLY_INT_r03 },
+ { 3, 1, _BINARY_OP_MULTIPLY_INT_r13 },
+ { 3, 2, _BINARY_OP_MULTIPLY_INT_r23 },
+ { -1, -1, -1 },
},
},
[_BINARY_OP_ADD_INT] = {
- .best = { 0, 1, 2, 3 },
+ .best = { 0, 1, 2, 2 },
.entries = {
- { 1, 0, _BINARY_OP_ADD_INT_r01 },
- { 1, 1, _BINARY_OP_ADD_INT_r11 },
- { 1, 2, _BINARY_OP_ADD_INT_r21 },
- { 2, 3, _BINARY_OP_ADD_INT_r32 },
+ { 3, 0, _BINARY_OP_ADD_INT_r03 },
+ { 3, 1, _BINARY_OP_ADD_INT_r13 },
+ { 3, 2, _BINARY_OP_ADD_INT_r23 },
+ { -1, -1, -1 },
},
},
[_BINARY_OP_SUBTRACT_INT] = {
- .best = { 0, 1, 2, 3 },
+ .best = { 0, 1, 2, 2 },
.entries = {
- { 1, 0, _BINARY_OP_SUBTRACT_INT_r01 },
- { 1, 1, _BINARY_OP_SUBTRACT_INT_r11 },
- { 1, 2, _BINARY_OP_SUBTRACT_INT_r21 },
- { 2, 3, _BINARY_OP_SUBTRACT_INT_r32 },
+ { 3, 0, _BINARY_OP_SUBTRACT_INT_r03 },
+ { 3, 1, _BINARY_OP_SUBTRACT_INT_r13 },
+ { 3, 2, _BINARY_OP_SUBTRACT_INT_r23 },
+ { -1, -1, -1 },
},
},
[_GUARD_NOS_FLOAT] = {
@@ -1026,66 +1058,39 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
},
},
[_BINARY_OP_MULTIPLY_FLOAT] = {
- .best = { 0, 1, 2, 3 },
+ .best = { 0, 1, 2, 2 },
.entries = {
- { 1, 0, _BINARY_OP_MULTIPLY_FLOAT_r01 },
- { 1, 1, _BINARY_OP_MULTIPLY_FLOAT_r11 },
- { 1, 2, _BINARY_OP_MULTIPLY_FLOAT_r21 },
- { 2, 3, _BINARY_OP_MULTIPLY_FLOAT_r32 },
+ { 3, 0, _BINARY_OP_MULTIPLY_FLOAT_r03 },
+ { 3, 1, _BINARY_OP_MULTIPLY_FLOAT_r13 },
+ { 3, 2, _BINARY_OP_MULTIPLY_FLOAT_r23 },
+ { -1, -1, -1 },
},
},
[_BINARY_OP_ADD_FLOAT] = {
- .best = { 0, 1, 2, 3 },
+ .best = { 0, 1, 2, 2 },
.entries = {
- { 1, 0, _BINARY_OP_ADD_FLOAT_r01 },
- { 1, 1, _BINARY_OP_ADD_FLOAT_r11 },
- { 1, 2, _BINARY_OP_ADD_FLOAT_r21 },
- { 2, 3, _BINARY_OP_ADD_FLOAT_r32 },
+ { 3, 0, _BINARY_OP_ADD_FLOAT_r03 },
+ { 3, 1, _BINARY_OP_ADD_FLOAT_r13 },
+ { 3, 2, _BINARY_OP_ADD_FLOAT_r23 },
+ { -1, -1, -1 },
},
},
[_BINARY_OP_SUBTRACT_FLOAT] = {
- .best = { 0, 1, 2, 3 },
- .entries = {
- { 1, 0, _BINARY_OP_SUBTRACT_FLOAT_r01 },
- { 1, 1, _BINARY_OP_SUBTRACT_FLOAT_r11 },
- { 1, 2, _BINARY_OP_SUBTRACT_FLOAT_r21 },
- { 2, 3, _BINARY_OP_SUBTRACT_FLOAT_r32 },
- },
- },
- [_BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS] = {
- .best = { 0, 1, 2, 3 },
- .entries = {
- { 1, 0, _BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS_r01 },
- { 1, 1, _BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS_r11 },
- { 1, 2, _BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS_r21 },
- { 2, 3, _BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS_r32 },
- },
- },
- [_BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS] = {
- .best = { 0, 1, 2, 3 },
- .entries = {
- { 1, 0, _BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS_r01 },
- { 1, 1, _BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS_r11 },
- { 1, 2, _BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS_r21 },
- { 2, 3, _BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS_r32 },
- },
- },
- [_BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS] = {
- .best = { 0, 1, 2, 3 },
+ .best = { 0, 1, 2, 2 },
.entries = {
- { 1, 0, _BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS_r01 },
- { 1, 1, _BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS_r11 },
- { 1, 2, _BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS_r21 },
- { 2, 3, _BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS_r32 },
+ { 3, 0, _BINARY_OP_SUBTRACT_FLOAT_r03 },
+ { 3, 1, _BINARY_OP_SUBTRACT_FLOAT_r13 },
+ { 3, 2, _BINARY_OP_SUBTRACT_FLOAT_r23 },
+ { -1, -1, -1 },
},
},
[_BINARY_OP_ADD_UNICODE] = {
- .best = { 0, 1, 2, 3 },
+ .best = { 0, 1, 2, 2 },
.entries = {
- { 1, 0, _BINARY_OP_ADD_UNICODE_r01 },
- { 1, 1, _BINARY_OP_ADD_UNICODE_r11 },
- { 1, 2, _BINARY_OP_ADD_UNICODE_r21 },
- { 2, 3, _BINARY_OP_ADD_UNICODE_r32 },
+ { 3, 0, _BINARY_OP_ADD_UNICODE_r03 },
+ { 3, 1, _BINARY_OP_ADD_UNICODE_r13 },
+ { 3, 2, _BINARY_OP_ADD_UNICODE_r23 },
+ { -1, -1, -1 },
},
},
[_BINARY_OP_INPLACE_ADD_UNICODE] = {
@@ -1093,7 +1098,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.entries = {
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 0, 0, _BINARY_OP_INPLACE_ADD_UNICODE_r20 },
+ { 1, 2, _BINARY_OP_INPLACE_ADD_UNICODE_r21 },
{ -1, -1, -1 },
},
},
@@ -1102,7 +1107,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.entries = {
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 2, 0, _GUARD_BINARY_OP_EXTEND_r22 },
+ { 2, 2, _GUARD_BINARY_OP_EXTEND_r22 },
{ -1, -1, -1 },
},
},
@@ -1111,7 +1116,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.entries = {
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 1, 0, _BINARY_OP_EXTEND_r21 },
+ { 3, 2, _BINARY_OP_EXTEND_r23 },
{ -1, -1, -1 },
},
},
@@ -1121,7 +1126,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
{ -1, -1, -1 },
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 1, 0, _BINARY_SLICE_r31 },
+ { 1, 3, _BINARY_SLICE_r31 },
},
},
[_STORE_SLICE] = {
@@ -1130,7 +1135,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
{ -1, -1, -1 },
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 0, 0, _STORE_SLICE_r30 },
+ { 0, 3, _STORE_SLICE_r30 },
},
},
[_BINARY_OP_SUBSCR_LIST_INT] = {
@@ -1138,7 +1143,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.entries = {
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 1, 0, _BINARY_OP_SUBSCR_LIST_INT_r21 },
+ { 3, 2, _BINARY_OP_SUBSCR_LIST_INT_r23 },
{ -1, -1, -1 },
},
},
@@ -1147,7 +1152,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.entries = {
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 1, 0, _BINARY_OP_SUBSCR_LIST_SLICE_r21 },
+ { 1, 2, _BINARY_OP_SUBSCR_LIST_SLICE_r21 },
{ -1, -1, -1 },
},
},
@@ -1156,7 +1161,16 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.entries = {
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 1, 2, _BINARY_OP_SUBSCR_STR_INT_r21 },
+ { 3, 2, _BINARY_OP_SUBSCR_STR_INT_r23 },
+ { -1, -1, -1 },
+ },
+ },
+ [_BINARY_OP_SUBSCR_USTR_INT] = {
+ .best = { 2, 2, 2, 2 },
+ .entries = {
+ { -1, -1, -1 },
+ { -1, -1, -1 },
+ { 3, 2, _BINARY_OP_SUBSCR_USTR_INT_r23 },
{ -1, -1, -1 },
},
},
@@ -1178,12 +1192,21 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
{ 3, 3, _GUARD_TOS_TUPLE_r33 },
},
},
+ [_GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS] = {
+ .best = { 0, 1, 2, 3 },
+ .entries = {
+ { 2, 0, _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r02 },
+ { 2, 1, _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r12 },
+ { 2, 2, _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r22 },
+ { 3, 3, _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r33 },
+ },
+ },
[_BINARY_OP_SUBSCR_TUPLE_INT] = {
- .best = { 2, 2, 2, 2 },
+ .best = { 0, 1, 2, 2 },
.entries = {
- { -1, -1, -1 },
- { -1, -1, -1 },
- { 1, 2, _BINARY_OP_SUBSCR_TUPLE_INT_r21 },
+ { 3, 0, _BINARY_OP_SUBSCR_TUPLE_INT_r03 },
+ { 3, 1, _BINARY_OP_SUBSCR_TUPLE_INT_r13 },
+ { 3, 2, _BINARY_OP_SUBSCR_TUPLE_INT_r23 },
{ -1, -1, -1 },
},
},
@@ -1210,7 +1233,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.entries = {
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 1, 0, _BINARY_OP_SUBSCR_DICT_r21 },
+ { 3, 2, _BINARY_OP_SUBSCR_DICT_r23 },
{ -1, -1, -1 },
},
},
@@ -1245,7 +1268,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 0, 0, _SET_ADD_r10 },
+ { 0, 1, _SET_ADD_r10 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -1256,7 +1279,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
{ -1, -1, -1 },
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 0, 0, _STORE_SUBSCR_r30 },
+ { 0, 3, _STORE_SUBSCR_r30 },
},
},
[_STORE_SUBSCR_LIST_INT] = {
@@ -1265,7 +1288,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
{ -1, -1, -1 },
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 0, 3, _STORE_SUBSCR_LIST_INT_r30 },
+ { 2, 3, _STORE_SUBSCR_LIST_INT_r32 },
},
},
[_STORE_SUBSCR_DICT] = {
@@ -1274,7 +1297,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
{ -1, -1, -1 },
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 0, 0, _STORE_SUBSCR_DICT_r30 },
+ { 1, 3, _STORE_SUBSCR_DICT_r31 },
},
},
[_DELETE_SUBSCR] = {
@@ -1282,7 +1305,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.entries = {
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 0, 0, _DELETE_SUBSCR_r20 },
+ { 0, 2, _DELETE_SUBSCR_r20 },
{ -1, -1, -1 },
},
},
@@ -1290,7 +1313,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 1, 0, _CALL_INTRINSIC_1_r11 },
+ { 1, 1, _CALL_INTRINSIC_1_r11 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -1300,7 +1323,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.entries = {
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 1, 0, _CALL_INTRINSIC_2_r21 },
+ { 1, 2, _CALL_INTRINSIC_2_r21 },
{ -1, -1, -1 },
},
},
@@ -1308,7 +1331,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 1, 0, _RETURN_VALUE_r11 },
+ { 1, 1, _RETURN_VALUE_r11 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -1317,7 +1340,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 1, 0, _GET_AITER_r11 },
+ { 1, 1, _GET_AITER_r11 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -1326,7 +1349,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 2, 0, _GET_ANEXT_r12 },
+ { 2, 1, _GET_ANEXT_r12 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -1335,7 +1358,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 1, 0, _GET_AWAITABLE_r11 },
+ { 1, 1, _GET_AWAITABLE_r11 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -1362,7 +1385,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 0, 0, _POP_EXCEPT_r10 },
+ { 0, 1, _POP_EXCEPT_r10 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -1389,7 +1412,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 0, 0, _STORE_NAME_r10 },
+ { 0, 1, _STORE_NAME_r10 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -1407,7 +1430,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 0, 0, _UNPACK_SEQUENCE_r10 },
+ { 0, 1, _UNPACK_SEQUENCE_r10 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -1443,7 +1466,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 0, 0, _UNPACK_EX_r10 },
+ { 0, 1, _UNPACK_EX_r10 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -1453,7 +1476,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.entries = {
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 0, 0, _STORE_ATTR_r20 },
+ { 0, 2, _STORE_ATTR_r20 },
{ -1, -1, -1 },
},
},
@@ -1461,7 +1484,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 0, 0, _DELETE_ATTR_r10 },
+ { 0, 1, _DELETE_ATTR_r10 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -1470,7 +1493,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 0, 0, _STORE_GLOBAL_r10 },
+ { 0, 1, _STORE_GLOBAL_r10 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -1485,11 +1508,11 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
},
},
[_LOAD_LOCALS] = {
- .best = { 0, 0, 0, 0 },
+ .best = { 0, 1, 2, 2 },
.entries = {
{ 1, 0, _LOAD_LOCALS_r01 },
- { -1, -1, -1 },
- { -1, -1, -1 },
+ { 2, 1, _LOAD_LOCALS_r12 },
+ { 3, 2, _LOAD_LOCALS_r23 },
{ -1, -1, -1 },
},
},
@@ -1578,7 +1601,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 1, 0, _LOAD_FROM_DICT_OR_DEREF_r11 },
+ { 1, 1, _LOAD_FROM_DICT_OR_DEREF_r11 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -1596,7 +1619,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 0, 0, _STORE_DEREF_r10 },
+ { 0, 1, _STORE_DEREF_r10 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -1633,7 +1656,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.entries = {
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 1, 0, _BUILD_TEMPLATE_r21 },
+ { 1, 2, _BUILD_TEMPLATE_r21 },
{ -1, -1, -1 },
},
},
@@ -1659,7 +1682,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 0, 0, _LIST_EXTEND_r10 },
+ { 0, 1, _LIST_EXTEND_r10 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -1668,7 +1691,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 0, 0, _SET_UPDATE_r10 },
+ { 0, 1, _SET_UPDATE_r10 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -1704,7 +1727,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 0, 0, _DICT_UPDATE_r10 },
+ { 0, 1, _DICT_UPDATE_r10 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -1713,7 +1736,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 0, 0, _DICT_MERGE_r10 },
+ { 0, 1, _DICT_MERGE_r10 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -1723,7 +1746,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.entries = {
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 0, 0, _MAP_ADD_r20 },
+ { 0, 2, _MAP_ADD_r20 },
{ -1, -1, -1 },
},
},
@@ -1733,7 +1756,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
{ -1, -1, -1 },
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 1, 0, _LOAD_SUPER_ATTR_ATTR_r31 },
+ { 1, 3, _LOAD_SUPER_ATTR_ATTR_r31 },
},
},
[_LOAD_SUPER_ATTR_METHOD] = {
@@ -1742,14 +1765,14 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
{ -1, -1, -1 },
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 2, 0, _LOAD_SUPER_ATTR_METHOD_r32 },
+ { 2, 3, _LOAD_SUPER_ATTR_METHOD_r32 },
},
},
[_LOAD_ATTR] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 0, 0, _LOAD_ATTR_r10 },
+ { 0, 1, _LOAD_ATTR_r10 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -1782,11 +1805,11 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
},
},
[_LOAD_ATTR_INSTANCE_VALUE] = {
- .best = { 1, 1, 1, 1 },
+ .best = { 0, 1, 2, 2 },
.entries = {
- { -1, -1, -1 },
- { 1, 1, _LOAD_ATTR_INSTANCE_VALUE_r11 },
- { -1, -1, -1 },
+ { 2, 0, _LOAD_ATTR_INSTANCE_VALUE_r02 },
+ { 2, 1, _LOAD_ATTR_INSTANCE_VALUE_r12 },
+ { 3, 2, _LOAD_ATTR_INSTANCE_VALUE_r23 },
{ -1, -1, -1 },
},
},
@@ -1794,7 +1817,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 1, 1, _LOAD_ATTR_MODULE_r11 },
+ { 2, 1, _LOAD_ATTR_MODULE_r12 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -1803,17 +1826,17 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 1, 1, _LOAD_ATTR_WITH_HINT_r11 },
+ { 2, 1, _LOAD_ATTR_WITH_HINT_r12 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
},
[_LOAD_ATTR_SLOT] = {
- .best = { 1, 1, 1, 1 },
+ .best = { 0, 1, 2, 2 },
.entries = {
- { -1, -1, -1 },
- { 1, 1, _LOAD_ATTR_SLOT_r11 },
- { -1, -1, -1 },
+ { 2, 0, _LOAD_ATTR_SLOT_r02 },
+ { 2, 1, _LOAD_ATTR_SLOT_r12 },
+ { 3, 2, _LOAD_ATTR_SLOT_r23 },
{ -1, -1, -1 },
},
},
@@ -1858,16 +1881,25 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.entries = {
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 0, 2, _STORE_ATTR_INSTANCE_VALUE_r20 },
+ { 1, 2, _STORE_ATTR_INSTANCE_VALUE_r21 },
{ -1, -1, -1 },
},
},
+ [_STORE_ATTR_INSTANCE_VALUE_NULL] = {
+ .best = { 0, 1, 2, 3 },
+ .entries = {
+ { 1, 0, _STORE_ATTR_INSTANCE_VALUE_NULL_r01 },
+ { 1, 1, _STORE_ATTR_INSTANCE_VALUE_NULL_r11 },
+ { 1, 2, _STORE_ATTR_INSTANCE_VALUE_NULL_r21 },
+ { 2, 3, _STORE_ATTR_INSTANCE_VALUE_NULL_r32 },
+ },
+ },
[_STORE_ATTR_WITH_HINT] = {
.best = { 2, 2, 2, 2 },
.entries = {
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 0, 0, _STORE_ATTR_WITH_HINT_r20 },
+ { 1, 2, _STORE_ATTR_WITH_HINT_r21 },
{ -1, -1, -1 },
},
},
@@ -1876,26 +1908,35 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.entries = {
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 0, 2, _STORE_ATTR_SLOT_r20 },
+ { 1, 2, _STORE_ATTR_SLOT_r21 },
{ -1, -1, -1 },
},
},
+ [_STORE_ATTR_SLOT_NULL] = {
+ .best = { 0, 1, 2, 3 },
+ .entries = {
+ { 1, 0, _STORE_ATTR_SLOT_NULL_r01 },
+ { 1, 1, _STORE_ATTR_SLOT_NULL_r11 },
+ { 1, 2, _STORE_ATTR_SLOT_NULL_r21 },
+ { 2, 3, _STORE_ATTR_SLOT_NULL_r32 },
+ },
+ },
[_COMPARE_OP] = {
.best = { 2, 2, 2, 2 },
.entries = {
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 1, 0, _COMPARE_OP_r21 },
+ { 1, 2, _COMPARE_OP_r21 },
{ -1, -1, -1 },
},
},
[_COMPARE_OP_FLOAT] = {
- .best = { 0, 1, 2, 3 },
+ .best = { 0, 1, 2, 2 },
.entries = {
- { 1, 0, _COMPARE_OP_FLOAT_r01 },
- { 1, 1, _COMPARE_OP_FLOAT_r11 },
- { 1, 2, _COMPARE_OP_FLOAT_r21 },
- { 2, 3, _COMPARE_OP_FLOAT_r32 },
+ { 3, 0, _COMPARE_OP_FLOAT_r03 },
+ { 3, 1, _COMPARE_OP_FLOAT_r13 },
+ { 3, 2, _COMPARE_OP_FLOAT_r23 },
+ { -1, -1, -1 },
},
},
[_COMPARE_OP_INT] = {
@@ -1903,7 +1944,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.entries = {
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 1, 2, _COMPARE_OP_INT_r21 },
+ { 3, 2, _COMPARE_OP_INT_r23 },
{ -1, -1, -1 },
},
},
@@ -1912,16 +1953,16 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.entries = {
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 1, 2, _COMPARE_OP_STR_r21 },
+ { 3, 2, _COMPARE_OP_STR_r23 },
{ -1, -1, -1 },
},
},
[_IS_OP] = {
- .best = { 2, 2, 2, 2 },
+ .best = { 0, 1, 2, 2 },
.entries = {
- { -1, -1, -1 },
- { -1, -1, -1 },
- { 1, 2, _IS_OP_r21 },
+ { 3, 0, _IS_OP_r03 },
+ { 3, 1, _IS_OP_r13 },
+ { 3, 2, _IS_OP_r23 },
{ -1, -1, -1 },
},
},
@@ -1930,7 +1971,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.entries = {
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 1, 0, _CONTAINS_OP_r21 },
+ { 3, 2, _CONTAINS_OP_r23 },
{ -1, -1, -1 },
},
},
@@ -1948,7 +1989,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.entries = {
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 1, 0, _CONTAINS_OP_SET_r21 },
+ { 3, 2, _CONTAINS_OP_SET_r23 },
{ -1, -1, -1 },
},
},
@@ -1957,7 +1998,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.entries = {
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 1, 0, _CONTAINS_OP_DICT_r21 },
+ { 3, 2, _CONTAINS_OP_DICT_r23 },
{ -1, -1, -1 },
},
},
@@ -1966,7 +2007,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.entries = {
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 2, 0, _CHECK_EG_MATCH_r22 },
+ { 2, 2, _CHECK_EG_MATCH_r22 },
{ -1, -1, -1 },
},
},
@@ -1975,7 +2016,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.entries = {
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 2, 0, _CHECK_EXC_MATCH_r22 },
+ { 2, 2, _CHECK_EXC_MATCH_r22 },
{ -1, -1, -1 },
},
},
@@ -1984,7 +2025,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.entries = {
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 1, 0, _IMPORT_NAME_r21 },
+ { 1, 2, _IMPORT_NAME_r21 },
{ -1, -1, -1 },
},
},
@@ -1992,7 +2033,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 2, 0, _IMPORT_FROM_r12 },
+ { 2, 1, _IMPORT_FROM_r12 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -2010,7 +2051,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 2, 0, _GET_LEN_r12 },
+ { 2, 1, _GET_LEN_r12 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -2021,7 +2062,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
{ -1, -1, -1 },
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 1, 0, _MATCH_CLASS_r31 },
+ { 1, 3, _MATCH_CLASS_r31 },
},
},
[_MATCH_MAPPING] = {
@@ -2047,7 +2088,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.entries = {
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 3, 0, _MATCH_KEYS_r23 },
+ { 3, 2, _MATCH_KEYS_r23 },
{ -1, -1, -1 },
},
},
@@ -2055,7 +2096,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 2, 0, _GET_ITER_r12 },
+ { 2, 1, _GET_ITER_r12 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -2064,7 +2105,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 1, 0, _GET_YIELD_FROM_ITER_r11 },
+ { 1, 1, _GET_YIELD_FROM_ITER_r11 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -2074,7 +2115,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.entries = {
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 3, 0, _FOR_ITER_TIER_TWO_r23 },
+ { 3, 2, _FOR_ITER_TIER_TWO_r23 },
{ -1, -1, -1 },
},
},
@@ -2101,7 +2142,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.entries = {
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 3, 0, _ITER_NEXT_LIST_TIER_TWO_r23 },
+ { 3, 2, _ITER_NEXT_LIST_TIER_TWO_r23 },
{ -1, -1, -1 },
},
},
@@ -2160,10 +2201,10 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
},
},
[_FOR_ITER_GEN_FRAME] = {
- .best = { 2, 2, 2, 2 },
+ .best = { 0, 1, 2, 2 },
.entries = {
- { -1, -1, -1 },
- { -1, -1, -1 },
+ { 3, 0, _FOR_ITER_GEN_FRAME_r03 },
+ { 3, 1, _FOR_ITER_GEN_FRAME_r13 },
{ 3, 2, _FOR_ITER_GEN_FRAME_r23 },
{ -1, -1, -1 },
},
@@ -2192,7 +2233,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
{ -1, -1, -1 },
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 3, 0, _WITH_EXCEPT_START_r33 },
+ { 3, 3, _WITH_EXCEPT_START_r33 },
},
},
[_PUSH_EXC_INFO] = {
@@ -2288,7 +2329,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
[_PY_FRAME_GENERAL] = {
.best = { 0, 0, 0, 0 },
.entries = {
- { 1, 0, _PY_FRAME_GENERAL_r01 },
+ { 1, 1, _PY_FRAME_GENERAL_r01 },
{ -1, -1, -1 },
{ -1, -1, -1 },
{ -1, -1, -1 },
@@ -2502,12 +2543,12 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
},
},
[_CALL_TYPE_1] = {
- .best = { 3, 3, 3, 3 },
+ .best = { 0, 1, 2, 3 },
.entries = {
- { -1, -1, -1 },
- { -1, -1, -1 },
- { -1, -1, -1 },
- { 1, 3, _CALL_TYPE_1_r31 },
+ { 2, 0, _CALL_TYPE_1_r02 },
+ { 2, 1, _CALL_TYPE_1_r12 },
+ { 2, 2, _CALL_TYPE_1_r22 },
+ { 2, 3, _CALL_TYPE_1_r32 },
},
},
[_GUARD_CALLABLE_STR_1] = {
@@ -2525,7 +2566,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
{ -1, -1, -1 },
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 1, 0, _CALL_STR_1_r31 },
+ { 2, 3, _CALL_STR_1_r32 },
},
},
[_GUARD_CALLABLE_TUPLE_1] = {
@@ -2543,7 +2584,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
{ -1, -1, -1 },
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 2, 0, _CALL_TUPLE_1_r32 },
+ { 2, 3, _CALL_TUPLE_1_r32 },
},
},
[_CHECK_AND_ALLOCATE_OBJECT] = {
@@ -2558,7 +2599,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
[_CREATE_INIT_FRAME] = {
.best = { 0, 0, 0, 0 },
.entries = {
- { 1, 0, _CREATE_INIT_FRAME_r01 },
+ { 1, 1, _CREATE_INIT_FRAME_r01 },
{ -1, -1, -1 },
{ -1, -1, -1 },
{ -1, -1, -1 },
@@ -2568,7 +2609,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 0, 0, _EXIT_INIT_CHECK_r10 },
+ { 0, 1, _EXIT_INIT_CHECK_r10 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -2585,7 +2626,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
[_CALL_BUILTIN_O] = {
.best = { 0, 0, 0, 0 },
.entries = {
- { 1, 0, _CALL_BUILTIN_O_r01 },
+ { 3, 0, _CALL_BUILTIN_O_r03 },
{ -1, -1, -1 },
{ -1, -1, -1 },
{ -1, -1, -1 },
@@ -2624,7 +2665,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
{ -1, -1, -1 },
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 3, 0, _CALL_LEN_r33 },
+ { 3, 3, _CALL_LEN_r33 },
},
},
[_GUARD_CALLABLE_ISINSTANCE] = {
@@ -2642,7 +2683,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
{ -1, -1, -1 },
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 1, 0, _CALL_ISINSTANCE_r31 },
+ { 1, 3, _CALL_ISINSTANCE_r31 },
},
},
[_GUARD_CALLABLE_LIST_APPEND] = {
@@ -2655,18 +2696,18 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
},
},
[_CALL_LIST_APPEND] = {
- .best = { 3, 3, 3, 3 },
+ .best = { 0, 1, 2, 3 },
.entries = {
- { -1, -1, -1 },
- { -1, -1, -1 },
- { -1, -1, -1 },
- { 0, 3, _CALL_LIST_APPEND_r30 },
+ { 3, 0, _CALL_LIST_APPEND_r03 },
+ { 3, 1, _CALL_LIST_APPEND_r13 },
+ { 3, 2, _CALL_LIST_APPEND_r23 },
+ { 3, 3, _CALL_LIST_APPEND_r33 },
},
},
[_CALL_METHOD_DESCRIPTOR_O] = {
.best = { 0, 0, 0, 0 },
.entries = {
- { 1, 0, _CALL_METHOD_DESCRIPTOR_O_r01 },
+ { 3, 0, _CALL_METHOD_DESCRIPTOR_O_r03 },
{ -1, -1, -1 },
{ -1, -1, -1 },
{ -1, -1, -1 },
@@ -2712,7 +2753,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 1, 0, _PY_FRAME_KW_r11 },
+ { 1, 1, _PY_FRAME_KW_r11 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -2757,7 +2798,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 1, 0, _CALL_KW_NON_PY_r11 },
+ { 1, 1, _CALL_KW_NON_PY_r11 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -2768,14 +2809,50 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
{ -1, -1, -1 },
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 3, 0, _MAKE_CALLARGS_A_TUPLE_r33 },
+ { 3, 3, _MAKE_CALLARGS_A_TUPLE_r33 },
+ },
+ },
+ [_CHECK_IS_PY_CALLABLE_EX] = {
+ .best = { 0, 1, 2, 3 },
+ .entries = {
+ { 3, 0, _CHECK_IS_PY_CALLABLE_EX_r03 },
+ { 3, 1, _CHECK_IS_PY_CALLABLE_EX_r13 },
+ { 3, 2, _CHECK_IS_PY_CALLABLE_EX_r23 },
+ { 3, 3, _CHECK_IS_PY_CALLABLE_EX_r33 },
+ },
+ },
+ [_PY_FRAME_EX] = {
+ .best = { 3, 3, 3, 3 },
+ .entries = {
+ { -1, -1, -1 },
+ { -1, -1, -1 },
+ { -1, -1, -1 },
+ { 1, 1, _PY_FRAME_EX_r31 },
+ },
+ },
+ [_CHECK_IS_NOT_PY_CALLABLE_EX] = {
+ .best = { 0, 1, 2, 3 },
+ .entries = {
+ { 3, 0, _CHECK_IS_NOT_PY_CALLABLE_EX_r03 },
+ { 3, 1, _CHECK_IS_NOT_PY_CALLABLE_EX_r13 },
+ { 3, 2, _CHECK_IS_NOT_PY_CALLABLE_EX_r23 },
+ { 3, 3, _CHECK_IS_NOT_PY_CALLABLE_EX_r33 },
+ },
+ },
+ [_CALL_FUNCTION_EX_NON_PY_GENERAL] = {
+ .best = { 3, 3, 3, 3 },
+ .entries = {
+ { -1, -1, -1 },
+ { -1, -1, -1 },
+ { -1, -1, -1 },
+ { 1, 3, _CALL_FUNCTION_EX_NON_PY_GENERAL_r31 },
},
},
[_MAKE_FUNCTION] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 1, 0, _MAKE_FUNCTION_r11 },
+ { 1, 1, _MAKE_FUNCTION_r11 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -2811,7 +2888,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 1, 0, _CONVERT_VALUE_r11 },
+ { 1, 1, _CONVERT_VALUE_r11 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -2820,7 +2897,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
- { 1, 0, _FORMAT_SIMPLE_r11 },
+ { 1, 1, _FORMAT_SIMPLE_r11 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@@ -2830,7 +2907,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.entries = {
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 1, 0, _FORMAT_WITH_SPEC_r21 },
+ { 1, 2, _FORMAT_WITH_SPEC_r21 },
{ -1, -1, -1 },
},
},
@@ -2875,7 +2952,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.entries = {
{ -1, -1, -1 },
{ -1, -1, -1 },
- { 1, 0, _BINARY_OP_r21 },
+ { 3, 2, _BINARY_OP_r23 },
{ -1, -1, -1 },
},
},
@@ -2924,6 +3001,96 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
{ 2, 2, _GUARD_IS_FALSE_POP_r32 },
},
},
+ [_GUARD_BIT_IS_SET_POP_4] = {
+ .best = { 0, 1, 2, 3 },
+ .entries = {
+ { 0, 0, _GUARD_BIT_IS_SET_POP_4_r00 },
+ { 0, 0, _GUARD_BIT_IS_SET_POP_4_r10 },
+ { 1, 1, _GUARD_BIT_IS_SET_POP_4_r21 },
+ { 2, 2, _GUARD_BIT_IS_SET_POP_4_r32 },
+ },
+ },
+ [_GUARD_BIT_IS_SET_POP_5] = {
+ .best = { 0, 1, 2, 3 },
+ .entries = {
+ { 0, 0, _GUARD_BIT_IS_SET_POP_5_r00 },
+ { 0, 0, _GUARD_BIT_IS_SET_POP_5_r10 },
+ { 1, 1, _GUARD_BIT_IS_SET_POP_5_r21 },
+ { 2, 2, _GUARD_BIT_IS_SET_POP_5_r32 },
+ },
+ },
+ [_GUARD_BIT_IS_SET_POP_6] = {
+ .best = { 0, 1, 2, 3 },
+ .entries = {
+ { 0, 0, _GUARD_BIT_IS_SET_POP_6_r00 },
+ { 0, 0, _GUARD_BIT_IS_SET_POP_6_r10 },
+ { 1, 1, _GUARD_BIT_IS_SET_POP_6_r21 },
+ { 2, 2, _GUARD_BIT_IS_SET_POP_6_r32 },
+ },
+ },
+ [_GUARD_BIT_IS_SET_POP_7] = {
+ .best = { 0, 1, 2, 3 },
+ .entries = {
+ { 0, 0, _GUARD_BIT_IS_SET_POP_7_r00 },
+ { 0, 0, _GUARD_BIT_IS_SET_POP_7_r10 },
+ { 1, 1, _GUARD_BIT_IS_SET_POP_7_r21 },
+ { 2, 2, _GUARD_BIT_IS_SET_POP_7_r32 },
+ },
+ },
+ [_GUARD_BIT_IS_SET_POP] = {
+ .best = { 0, 1, 2, 3 },
+ .entries = {
+ { 0, 0, _GUARD_BIT_IS_SET_POP_r00 },
+ { 0, 0, _GUARD_BIT_IS_SET_POP_r10 },
+ { 1, 1, _GUARD_BIT_IS_SET_POP_r21 },
+ { 2, 2, _GUARD_BIT_IS_SET_POP_r32 },
+ },
+ },
+ [_GUARD_BIT_IS_UNSET_POP_4] = {
+ .best = { 0, 1, 2, 3 },
+ .entries = {
+ { 0, 0, _GUARD_BIT_IS_UNSET_POP_4_r00 },
+ { 0, 0, _GUARD_BIT_IS_UNSET_POP_4_r10 },
+ { 1, 1, _GUARD_BIT_IS_UNSET_POP_4_r21 },
+ { 2, 2, _GUARD_BIT_IS_UNSET_POP_4_r32 },
+ },
+ },
+ [_GUARD_BIT_IS_UNSET_POP_5] = {
+ .best = { 0, 1, 2, 3 },
+ .entries = {
+ { 0, 0, _GUARD_BIT_IS_UNSET_POP_5_r00 },
+ { 0, 0, _GUARD_BIT_IS_UNSET_POP_5_r10 },
+ { 1, 1, _GUARD_BIT_IS_UNSET_POP_5_r21 },
+ { 2, 2, _GUARD_BIT_IS_UNSET_POP_5_r32 },
+ },
+ },
+ [_GUARD_BIT_IS_UNSET_POP_6] = {
+ .best = { 0, 1, 2, 3 },
+ .entries = {
+ { 0, 0, _GUARD_BIT_IS_UNSET_POP_6_r00 },
+ { 0, 0, _GUARD_BIT_IS_UNSET_POP_6_r10 },
+ { 1, 1, _GUARD_BIT_IS_UNSET_POP_6_r21 },
+ { 2, 2, _GUARD_BIT_IS_UNSET_POP_6_r32 },
+ },
+ },
+ [_GUARD_BIT_IS_UNSET_POP_7] = {
+ .best = { 0, 1, 2, 3 },
+ .entries = {
+ { 0, 0, _GUARD_BIT_IS_UNSET_POP_7_r00 },
+ { 0, 0, _GUARD_BIT_IS_UNSET_POP_7_r10 },
+ { 1, 1, _GUARD_BIT_IS_UNSET_POP_7_r21 },
+ { 2, 2, _GUARD_BIT_IS_UNSET_POP_7_r32 },
+ },
+ },
+ [_GUARD_BIT_IS_UNSET_POP] = {
+ .best = { 0, 1, 2, 3 },
+ .entries = {
+ { 0, 0, _GUARD_BIT_IS_UNSET_POP_r00 },
+ { 0, 0, _GUARD_BIT_IS_UNSET_POP_r10 },
+ { 1, 1, _GUARD_BIT_IS_UNSET_POP_r21 },
+ { 2, 2, _GUARD_BIT_IS_UNSET_POP_r32 },
+ },
+ },
[_GUARD_IS_NONE_POP] = {
.best = { 0, 1, 2, 3 },
.entries = {
@@ -3095,6 +3262,51 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
{ 1, 3, _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW_r31 },
},
},
+ [_INSERT_1_LOAD_CONST_INLINE] = {
+ .best = { 0, 1, 2, 2 },
+ .entries = {
+ { 2, 0, _INSERT_1_LOAD_CONST_INLINE_r02 },
+ { 2, 1, _INSERT_1_LOAD_CONST_INLINE_r12 },
+ { 3, 2, _INSERT_1_LOAD_CONST_INLINE_r23 },
+ { -1, -1, -1 },
+ },
+ },
+ [_INSERT_1_LOAD_CONST_INLINE_BORROW] = {
+ .best = { 0, 1, 2, 2 },
+ .entries = {
+ { 2, 0, _INSERT_1_LOAD_CONST_INLINE_BORROW_r02 },
+ { 2, 1, _INSERT_1_LOAD_CONST_INLINE_BORROW_r12 },
+ { 3, 2, _INSERT_1_LOAD_CONST_INLINE_BORROW_r23 },
+ { -1, -1, -1 },
+ },
+ },
+ [_INSERT_2_LOAD_CONST_INLINE_BORROW] = {
+ .best = { 0, 1, 2, 2 },
+ .entries = {
+ { 3, 0, _INSERT_2_LOAD_CONST_INLINE_BORROW_r03 },
+ { 3, 1, _INSERT_2_LOAD_CONST_INLINE_BORROW_r13 },
+ { 3, 2, _INSERT_2_LOAD_CONST_INLINE_BORROW_r23 },
+ { -1, -1, -1 },
+ },
+ },
+ [_SHUFFLE_2_LOAD_CONST_INLINE_BORROW] = {
+ .best = { 0, 1, 2, 3 },
+ .entries = {
+ { 2, 0, _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r02 },
+ { 2, 1, _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r12 },
+ { 2, 2, _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r22 },
+ { 2, 3, _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r32 },
+ },
+ },
+ [_SHUFFLE_3_LOAD_CONST_INLINE_BORROW] = {
+ .best = { 0, 1, 2, 3 },
+ .entries = {
+ { 3, 0, _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03 },
+ { 3, 1, _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13 },
+ { 3, 2, _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23 },
+ { 3, 3, _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33 },
+ },
+ },
[_POP_CALL_TWO_LOAD_CONST_INLINE_BORROW] = {
.best = { 3, 3, 3, 3 },
.entries = {
@@ -3253,6 +3465,8 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {
[_RESUME_CHECK_r22] = _RESUME_CHECK,
[_RESUME_CHECK_r33] = _RESUME_CHECK,
[_LOAD_FAST_CHECK_r01] = _LOAD_FAST_CHECK,
+ [_LOAD_FAST_CHECK_r12] = _LOAD_FAST_CHECK,
+ [_LOAD_FAST_CHECK_r23] = _LOAD_FAST_CHECK,
[_LOAD_FAST_0_r01] = _LOAD_FAST_0,
[_LOAD_FAST_0_r12] = _LOAD_FAST_0,
[_LOAD_FAST_0_r23] = _LOAD_FAST_0,
@@ -3328,15 +3542,42 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {
[_LOAD_SMALL_INT_r01] = _LOAD_SMALL_INT,
[_LOAD_SMALL_INT_r12] = _LOAD_SMALL_INT,
[_LOAD_SMALL_INT_r23] = _LOAD_SMALL_INT,
- [_STORE_FAST_0_r10] = _STORE_FAST_0,
- [_STORE_FAST_1_r10] = _STORE_FAST_1,
- [_STORE_FAST_2_r10] = _STORE_FAST_2,
- [_STORE_FAST_3_r10] = _STORE_FAST_3,
- [_STORE_FAST_4_r10] = _STORE_FAST_4,
- [_STORE_FAST_5_r10] = _STORE_FAST_5,
- [_STORE_FAST_6_r10] = _STORE_FAST_6,
- [_STORE_FAST_7_r10] = _STORE_FAST_7,
- [_STORE_FAST_r10] = _STORE_FAST,
+ [_SWAP_FAST_0_r01] = _SWAP_FAST_0,
+ [_SWAP_FAST_0_r11] = _SWAP_FAST_0,
+ [_SWAP_FAST_0_r22] = _SWAP_FAST_0,
+ [_SWAP_FAST_0_r33] = _SWAP_FAST_0,
+ [_SWAP_FAST_1_r01] = _SWAP_FAST_1,
+ [_SWAP_FAST_1_r11] = _SWAP_FAST_1,
+ [_SWAP_FAST_1_r22] = _SWAP_FAST_1,
+ [_SWAP_FAST_1_r33] = _SWAP_FAST_1,
+ [_SWAP_FAST_2_r01] = _SWAP_FAST_2,
+ [_SWAP_FAST_2_r11] = _SWAP_FAST_2,
+ [_SWAP_FAST_2_r22] = _SWAP_FAST_2,
+ [_SWAP_FAST_2_r33] = _SWAP_FAST_2,
+ [_SWAP_FAST_3_r01] = _SWAP_FAST_3,
+ [_SWAP_FAST_3_r11] = _SWAP_FAST_3,
+ [_SWAP_FAST_3_r22] = _SWAP_FAST_3,
+ [_SWAP_FAST_3_r33] = _SWAP_FAST_3,
+ [_SWAP_FAST_4_r01] = _SWAP_FAST_4,
+ [_SWAP_FAST_4_r11] = _SWAP_FAST_4,
+ [_SWAP_FAST_4_r22] = _SWAP_FAST_4,
+ [_SWAP_FAST_4_r33] = _SWAP_FAST_4,
+ [_SWAP_FAST_5_r01] = _SWAP_FAST_5,
+ [_SWAP_FAST_5_r11] = _SWAP_FAST_5,
+ [_SWAP_FAST_5_r22] = _SWAP_FAST_5,
+ [_SWAP_FAST_5_r33] = _SWAP_FAST_5,
+ [_SWAP_FAST_6_r01] = _SWAP_FAST_6,
+ [_SWAP_FAST_6_r11] = _SWAP_FAST_6,
+ [_SWAP_FAST_6_r22] = _SWAP_FAST_6,
+ [_SWAP_FAST_6_r33] = _SWAP_FAST_6,
+ [_SWAP_FAST_7_r01] = _SWAP_FAST_7,
+ [_SWAP_FAST_7_r11] = _SWAP_FAST_7,
+ [_SWAP_FAST_7_r22] = _SWAP_FAST_7,
+ [_SWAP_FAST_7_r33] = _SWAP_FAST_7,
+ [_SWAP_FAST_r01] = _SWAP_FAST,
+ [_SWAP_FAST_r11] = _SWAP_FAST,
+ [_SWAP_FAST_r22] = _SWAP_FAST,
+ [_SWAP_FAST_r33] = _SWAP_FAST,
[_POP_TOP_r10] = _POP_TOP,
[_POP_TOP_NOP_r00] = _POP_TOP_NOP,
[_POP_TOP_NOP_r10] = _POP_TOP_NOP,
@@ -3361,7 +3602,7 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {
[_END_FOR_r10] = _END_FOR,
[_POP_ITER_r20] = _POP_ITER,
[_END_SEND_r21] = _END_SEND,
- [_UNARY_NEGATIVE_r11] = _UNARY_NEGATIVE,
+ [_UNARY_NEGATIVE_r12] = _UNARY_NEGATIVE,
[_UNARY_NOT_r01] = _UNARY_NOT,
[_UNARY_NOT_r11] = _UNARY_NOT,
[_UNARY_NOT_r22] = _UNARY_NOT,
@@ -3371,7 +3612,9 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {
[_TO_BOOL_BOOL_r11] = _TO_BOOL_BOOL,
[_TO_BOOL_BOOL_r22] = _TO_BOOL_BOOL,
[_TO_BOOL_BOOL_r33] = _TO_BOOL_BOOL,
- [_TO_BOOL_INT_r11] = _TO_BOOL_INT,
+ [_TO_BOOL_INT_r02] = _TO_BOOL_INT,
+ [_TO_BOOL_INT_r12] = _TO_BOOL_INT,
+ [_TO_BOOL_INT_r23] = _TO_BOOL_INT,
[_GUARD_NOS_LIST_r02] = _GUARD_NOS_LIST,
[_GUARD_NOS_LIST_r12] = _GUARD_NOS_LIST,
[_GUARD_NOS_LIST_r22] = _GUARD_NOS_LIST,
@@ -3384,11 +3627,17 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {
[_GUARD_TOS_SLICE_r11] = _GUARD_TOS_SLICE,
[_GUARD_TOS_SLICE_r22] = _GUARD_TOS_SLICE,
[_GUARD_TOS_SLICE_r33] = _GUARD_TOS_SLICE,
- [_TO_BOOL_LIST_r11] = _TO_BOOL_LIST,
+ [_TO_BOOL_LIST_r02] = _TO_BOOL_LIST,
+ [_TO_BOOL_LIST_r12] = _TO_BOOL_LIST,
+ [_TO_BOOL_LIST_r23] = _TO_BOOL_LIST,
[_TO_BOOL_NONE_r01] = _TO_BOOL_NONE,
[_TO_BOOL_NONE_r11] = _TO_BOOL_NONE,
[_TO_BOOL_NONE_r22] = _TO_BOOL_NONE,
[_TO_BOOL_NONE_r33] = _TO_BOOL_NONE,
+ [_GUARD_NOS_COMPACT_ASCII_r02] = _GUARD_NOS_COMPACT_ASCII,
+ [_GUARD_NOS_COMPACT_ASCII_r12] = _GUARD_NOS_COMPACT_ASCII,
+ [_GUARD_NOS_COMPACT_ASCII_r22] = _GUARD_NOS_COMPACT_ASCII,
+ [_GUARD_NOS_COMPACT_ASCII_r33] = _GUARD_NOS_COMPACT_ASCII,
[_GUARD_NOS_UNICODE_r02] = _GUARD_NOS_UNICODE,
[_GUARD_NOS_UNICODE_r12] = _GUARD_NOS_UNICODE,
[_GUARD_NOS_UNICODE_r22] = _GUARD_NOS_UNICODE,
@@ -3397,9 +3646,13 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {
[_GUARD_TOS_UNICODE_r11] = _GUARD_TOS_UNICODE,
[_GUARD_TOS_UNICODE_r22] = _GUARD_TOS_UNICODE,
[_GUARD_TOS_UNICODE_r33] = _GUARD_TOS_UNICODE,
- [_TO_BOOL_STR_r11] = _TO_BOOL_STR,
- [_REPLACE_WITH_TRUE_r11] = _REPLACE_WITH_TRUE,
- [_UNARY_INVERT_r11] = _UNARY_INVERT,
+ [_TO_BOOL_STR_r02] = _TO_BOOL_STR,
+ [_TO_BOOL_STR_r12] = _TO_BOOL_STR,
+ [_TO_BOOL_STR_r23] = _TO_BOOL_STR,
+ [_REPLACE_WITH_TRUE_r02] = _REPLACE_WITH_TRUE,
+ [_REPLACE_WITH_TRUE_r12] = _REPLACE_WITH_TRUE,
+ [_REPLACE_WITH_TRUE_r23] = _REPLACE_WITH_TRUE,
+ [_UNARY_INVERT_r12] = _UNARY_INVERT,
[_GUARD_NOS_INT_r02] = _GUARD_NOS_INT,
[_GUARD_NOS_INT_r12] = _GUARD_NOS_INT,
[_GUARD_NOS_INT_r22] = _GUARD_NOS_INT,
@@ -3416,18 +3669,15 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {
[_GUARD_TOS_OVERFLOWED_r11] = _GUARD_TOS_OVERFLOWED,
[_GUARD_TOS_OVERFLOWED_r22] = _GUARD_TOS_OVERFLOWED,
[_GUARD_TOS_OVERFLOWED_r33] = _GUARD_TOS_OVERFLOWED,
- [_BINARY_OP_MULTIPLY_INT_r01] = _BINARY_OP_MULTIPLY_INT,
- [_BINARY_OP_MULTIPLY_INT_r11] = _BINARY_OP_MULTIPLY_INT,
- [_BINARY_OP_MULTIPLY_INT_r21] = _BINARY_OP_MULTIPLY_INT,
- [_BINARY_OP_MULTIPLY_INT_r32] = _BINARY_OP_MULTIPLY_INT,
- [_BINARY_OP_ADD_INT_r01] = _BINARY_OP_ADD_INT,
- [_BINARY_OP_ADD_INT_r11] = _BINARY_OP_ADD_INT,
- [_BINARY_OP_ADD_INT_r21] = _BINARY_OP_ADD_INT,
- [_BINARY_OP_ADD_INT_r32] = _BINARY_OP_ADD_INT,
- [_BINARY_OP_SUBTRACT_INT_r01] = _BINARY_OP_SUBTRACT_INT,
- [_BINARY_OP_SUBTRACT_INT_r11] = _BINARY_OP_SUBTRACT_INT,
- [_BINARY_OP_SUBTRACT_INT_r21] = _BINARY_OP_SUBTRACT_INT,
- [_BINARY_OP_SUBTRACT_INT_r32] = _BINARY_OP_SUBTRACT_INT,
+ [_BINARY_OP_MULTIPLY_INT_r03] = _BINARY_OP_MULTIPLY_INT,
+ [_BINARY_OP_MULTIPLY_INT_r13] = _BINARY_OP_MULTIPLY_INT,
+ [_BINARY_OP_MULTIPLY_INT_r23] = _BINARY_OP_MULTIPLY_INT,
+ [_BINARY_OP_ADD_INT_r03] = _BINARY_OP_ADD_INT,
+ [_BINARY_OP_ADD_INT_r13] = _BINARY_OP_ADD_INT,
+ [_BINARY_OP_ADD_INT_r23] = _BINARY_OP_ADD_INT,
+ [_BINARY_OP_SUBTRACT_INT_r03] = _BINARY_OP_SUBTRACT_INT,
+ [_BINARY_OP_SUBTRACT_INT_r13] = _BINARY_OP_SUBTRACT_INT,
+ [_BINARY_OP_SUBTRACT_INT_r23] = _BINARY_OP_SUBTRACT_INT,
[_GUARD_NOS_FLOAT_r02] = _GUARD_NOS_FLOAT,
[_GUARD_NOS_FLOAT_r12] = _GUARD_NOS_FLOAT,
[_GUARD_NOS_FLOAT_r22] = _GUARD_NOS_FLOAT,
@@ -3436,42 +3686,27 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {
[_GUARD_TOS_FLOAT_r11] = _GUARD_TOS_FLOAT,
[_GUARD_TOS_FLOAT_r22] = _GUARD_TOS_FLOAT,
[_GUARD_TOS_FLOAT_r33] = _GUARD_TOS_FLOAT,
- [_BINARY_OP_MULTIPLY_FLOAT_r01] = _BINARY_OP_MULTIPLY_FLOAT,
- [_BINARY_OP_MULTIPLY_FLOAT_r11] = _BINARY_OP_MULTIPLY_FLOAT,
- [_BINARY_OP_MULTIPLY_FLOAT_r21] = _BINARY_OP_MULTIPLY_FLOAT,
- [_BINARY_OP_MULTIPLY_FLOAT_r32] = _BINARY_OP_MULTIPLY_FLOAT,
- [_BINARY_OP_ADD_FLOAT_r01] = _BINARY_OP_ADD_FLOAT,
- [_BINARY_OP_ADD_FLOAT_r11] = _BINARY_OP_ADD_FLOAT,
- [_BINARY_OP_ADD_FLOAT_r21] = _BINARY_OP_ADD_FLOAT,
- [_BINARY_OP_ADD_FLOAT_r32] = _BINARY_OP_ADD_FLOAT,
- [_BINARY_OP_SUBTRACT_FLOAT_r01] = _BINARY_OP_SUBTRACT_FLOAT,
- [_BINARY_OP_SUBTRACT_FLOAT_r11] = _BINARY_OP_SUBTRACT_FLOAT,
- [_BINARY_OP_SUBTRACT_FLOAT_r21] = _BINARY_OP_SUBTRACT_FLOAT,
- [_BINARY_OP_SUBTRACT_FLOAT_r32] = _BINARY_OP_SUBTRACT_FLOAT,
- [_BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS_r01] = _BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS,
- [_BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS_r11] = _BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS,
- [_BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS_r21] = _BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS,
- [_BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS_r32] = _BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS,
- [_BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS_r01] = _BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS,
- [_BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS_r11] = _BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS,
- [_BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS_r21] = _BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS,
- [_BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS_r32] = _BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS,
- [_BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS_r01] = _BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS,
- [_BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS_r11] = _BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS,
- [_BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS_r21] = _BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS,
- [_BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS_r32] = _BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS,
- [_BINARY_OP_ADD_UNICODE_r01] = _BINARY_OP_ADD_UNICODE,
- [_BINARY_OP_ADD_UNICODE_r11] = _BINARY_OP_ADD_UNICODE,
- [_BINARY_OP_ADD_UNICODE_r21] = _BINARY_OP_ADD_UNICODE,
- [_BINARY_OP_ADD_UNICODE_r32] = _BINARY_OP_ADD_UNICODE,
- [_BINARY_OP_INPLACE_ADD_UNICODE_r20] = _BINARY_OP_INPLACE_ADD_UNICODE,
+ [_BINARY_OP_MULTIPLY_FLOAT_r03] = _BINARY_OP_MULTIPLY_FLOAT,
+ [_BINARY_OP_MULTIPLY_FLOAT_r13] = _BINARY_OP_MULTIPLY_FLOAT,
+ [_BINARY_OP_MULTIPLY_FLOAT_r23] = _BINARY_OP_MULTIPLY_FLOAT,
+ [_BINARY_OP_ADD_FLOAT_r03] = _BINARY_OP_ADD_FLOAT,
+ [_BINARY_OP_ADD_FLOAT_r13] = _BINARY_OP_ADD_FLOAT,
+ [_BINARY_OP_ADD_FLOAT_r23] = _BINARY_OP_ADD_FLOAT,
+ [_BINARY_OP_SUBTRACT_FLOAT_r03] = _BINARY_OP_SUBTRACT_FLOAT,
+ [_BINARY_OP_SUBTRACT_FLOAT_r13] = _BINARY_OP_SUBTRACT_FLOAT,
+ [_BINARY_OP_SUBTRACT_FLOAT_r23] = _BINARY_OP_SUBTRACT_FLOAT,
+ [_BINARY_OP_ADD_UNICODE_r03] = _BINARY_OP_ADD_UNICODE,
+ [_BINARY_OP_ADD_UNICODE_r13] = _BINARY_OP_ADD_UNICODE,
+ [_BINARY_OP_ADD_UNICODE_r23] = _BINARY_OP_ADD_UNICODE,
+ [_BINARY_OP_INPLACE_ADD_UNICODE_r21] = _BINARY_OP_INPLACE_ADD_UNICODE,
[_GUARD_BINARY_OP_EXTEND_r22] = _GUARD_BINARY_OP_EXTEND,
- [_BINARY_OP_EXTEND_r21] = _BINARY_OP_EXTEND,
+ [_BINARY_OP_EXTEND_r23] = _BINARY_OP_EXTEND,
[_BINARY_SLICE_r31] = _BINARY_SLICE,
[_STORE_SLICE_r30] = _STORE_SLICE,
- [_BINARY_OP_SUBSCR_LIST_INT_r21] = _BINARY_OP_SUBSCR_LIST_INT,
+ [_BINARY_OP_SUBSCR_LIST_INT_r23] = _BINARY_OP_SUBSCR_LIST_INT,
[_BINARY_OP_SUBSCR_LIST_SLICE_r21] = _BINARY_OP_SUBSCR_LIST_SLICE,
- [_BINARY_OP_SUBSCR_STR_INT_r21] = _BINARY_OP_SUBSCR_STR_INT,
+ [_BINARY_OP_SUBSCR_STR_INT_r23] = _BINARY_OP_SUBSCR_STR_INT,
+ [_BINARY_OP_SUBSCR_USTR_INT_r23] = _BINARY_OP_SUBSCR_USTR_INT,
[_GUARD_NOS_TUPLE_r02] = _GUARD_NOS_TUPLE,
[_GUARD_NOS_TUPLE_r12] = _GUARD_NOS_TUPLE,
[_GUARD_NOS_TUPLE_r22] = _GUARD_NOS_TUPLE,
@@ -3480,7 +3715,13 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {
[_GUARD_TOS_TUPLE_r11] = _GUARD_TOS_TUPLE,
[_GUARD_TOS_TUPLE_r22] = _GUARD_TOS_TUPLE,
[_GUARD_TOS_TUPLE_r33] = _GUARD_TOS_TUPLE,
- [_BINARY_OP_SUBSCR_TUPLE_INT_r21] = _BINARY_OP_SUBSCR_TUPLE_INT,
+ [_GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r02] = _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS,
+ [_GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r12] = _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS,
+ [_GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r22] = _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS,
+ [_GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r33] = _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS,
+ [_BINARY_OP_SUBSCR_TUPLE_INT_r03] = _BINARY_OP_SUBSCR_TUPLE_INT,
+ [_BINARY_OP_SUBSCR_TUPLE_INT_r13] = _BINARY_OP_SUBSCR_TUPLE_INT,
+ [_BINARY_OP_SUBSCR_TUPLE_INT_r23] = _BINARY_OP_SUBSCR_TUPLE_INT,
[_GUARD_NOS_DICT_r02] = _GUARD_NOS_DICT,
[_GUARD_NOS_DICT_r12] = _GUARD_NOS_DICT,
[_GUARD_NOS_DICT_r22] = _GUARD_NOS_DICT,
@@ -3489,7 +3730,7 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {
[_GUARD_TOS_DICT_r11] = _GUARD_TOS_DICT,
[_GUARD_TOS_DICT_r22] = _GUARD_TOS_DICT,
[_GUARD_TOS_DICT_r33] = _GUARD_TOS_DICT,
- [_BINARY_OP_SUBSCR_DICT_r21] = _BINARY_OP_SUBSCR_DICT,
+ [_BINARY_OP_SUBSCR_DICT_r23] = _BINARY_OP_SUBSCR_DICT,
[_BINARY_OP_SUBSCR_CHECK_FUNC_r23] = _BINARY_OP_SUBSCR_CHECK_FUNC,
[_BINARY_OP_SUBSCR_INIT_CALL_r01] = _BINARY_OP_SUBSCR_INIT_CALL,
[_BINARY_OP_SUBSCR_INIT_CALL_r11] = _BINARY_OP_SUBSCR_INIT_CALL,
@@ -3498,8 +3739,8 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {
[_LIST_APPEND_r10] = _LIST_APPEND,
[_SET_ADD_r10] = _SET_ADD,
[_STORE_SUBSCR_r30] = _STORE_SUBSCR,
- [_STORE_SUBSCR_LIST_INT_r30] = _STORE_SUBSCR_LIST_INT,
- [_STORE_SUBSCR_DICT_r30] = _STORE_SUBSCR_DICT,
+ [_STORE_SUBSCR_LIST_INT_r32] = _STORE_SUBSCR_LIST_INT,
+ [_STORE_SUBSCR_DICT_r31] = _STORE_SUBSCR_DICT,
[_DELETE_SUBSCR_r20] = _DELETE_SUBSCR,
[_CALL_INTRINSIC_1_r11] = _CALL_INTRINSIC_1,
[_CALL_INTRINSIC_2_r21] = _CALL_INTRINSIC_2,
@@ -3526,6 +3767,8 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {
[_STORE_GLOBAL_r10] = _STORE_GLOBAL,
[_DELETE_GLOBAL_r00] = _DELETE_GLOBAL,
[_LOAD_LOCALS_r01] = _LOAD_LOCALS,
+ [_LOAD_LOCALS_r12] = _LOAD_LOCALS,
+ [_LOAD_LOCALS_r23] = _LOAD_LOCALS,
[_LOAD_NAME_r01] = _LOAD_NAME,
[_LOAD_GLOBAL_r00] = _LOAD_GLOBAL,
[_PUSH_NULL_CONDITIONAL_r00] = _PUSH_NULL_CONDITIONAL,
@@ -3573,10 +3816,14 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {
[_CHECK_MANAGED_OBJECT_HAS_VALUES_r11] = _CHECK_MANAGED_OBJECT_HAS_VALUES,
[_CHECK_MANAGED_OBJECT_HAS_VALUES_r22] = _CHECK_MANAGED_OBJECT_HAS_VALUES,
[_CHECK_MANAGED_OBJECT_HAS_VALUES_r33] = _CHECK_MANAGED_OBJECT_HAS_VALUES,
- [_LOAD_ATTR_INSTANCE_VALUE_r11] = _LOAD_ATTR_INSTANCE_VALUE,
- [_LOAD_ATTR_MODULE_r11] = _LOAD_ATTR_MODULE,
- [_LOAD_ATTR_WITH_HINT_r11] = _LOAD_ATTR_WITH_HINT,
- [_LOAD_ATTR_SLOT_r11] = _LOAD_ATTR_SLOT,
+ [_LOAD_ATTR_INSTANCE_VALUE_r02] = _LOAD_ATTR_INSTANCE_VALUE,
+ [_LOAD_ATTR_INSTANCE_VALUE_r12] = _LOAD_ATTR_INSTANCE_VALUE,
+ [_LOAD_ATTR_INSTANCE_VALUE_r23] = _LOAD_ATTR_INSTANCE_VALUE,
+ [_LOAD_ATTR_MODULE_r12] = _LOAD_ATTR_MODULE,
+ [_LOAD_ATTR_WITH_HINT_r12] = _LOAD_ATTR_WITH_HINT,
+ [_LOAD_ATTR_SLOT_r02] = _LOAD_ATTR_SLOT,
+ [_LOAD_ATTR_SLOT_r12] = _LOAD_ATTR_SLOT,
+ [_LOAD_ATTR_SLOT_r23] = _LOAD_ATTR_SLOT,
[_CHECK_ATTR_CLASS_r01] = _CHECK_ATTR_CLASS,
[_CHECK_ATTR_CLASS_r11] = _CHECK_ATTR_CLASS,
[_CHECK_ATTR_CLASS_r22] = _CHECK_ATTR_CLASS,
@@ -3587,24 +3834,33 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {
[_GUARD_DORV_NO_DICT_r11] = _GUARD_DORV_NO_DICT,
[_GUARD_DORV_NO_DICT_r22] = _GUARD_DORV_NO_DICT,
[_GUARD_DORV_NO_DICT_r33] = _GUARD_DORV_NO_DICT,
- [_STORE_ATTR_INSTANCE_VALUE_r20] = _STORE_ATTR_INSTANCE_VALUE,
- [_STORE_ATTR_WITH_HINT_r20] = _STORE_ATTR_WITH_HINT,
- [_STORE_ATTR_SLOT_r20] = _STORE_ATTR_SLOT,
+ [_STORE_ATTR_INSTANCE_VALUE_r21] = _STORE_ATTR_INSTANCE_VALUE,
+ [_STORE_ATTR_INSTANCE_VALUE_NULL_r01] = _STORE_ATTR_INSTANCE_VALUE_NULL,
+ [_STORE_ATTR_INSTANCE_VALUE_NULL_r11] = _STORE_ATTR_INSTANCE_VALUE_NULL,
+ [_STORE_ATTR_INSTANCE_VALUE_NULL_r21] = _STORE_ATTR_INSTANCE_VALUE_NULL,
+ [_STORE_ATTR_INSTANCE_VALUE_NULL_r32] = _STORE_ATTR_INSTANCE_VALUE_NULL,
+ [_STORE_ATTR_WITH_HINT_r21] = _STORE_ATTR_WITH_HINT,
+ [_STORE_ATTR_SLOT_r21] = _STORE_ATTR_SLOT,
+ [_STORE_ATTR_SLOT_NULL_r01] = _STORE_ATTR_SLOT_NULL,
+ [_STORE_ATTR_SLOT_NULL_r11] = _STORE_ATTR_SLOT_NULL,
+ [_STORE_ATTR_SLOT_NULL_r21] = _STORE_ATTR_SLOT_NULL,
+ [_STORE_ATTR_SLOT_NULL_r32] = _STORE_ATTR_SLOT_NULL,
[_COMPARE_OP_r21] = _COMPARE_OP,
- [_COMPARE_OP_FLOAT_r01] = _COMPARE_OP_FLOAT,
- [_COMPARE_OP_FLOAT_r11] = _COMPARE_OP_FLOAT,
- [_COMPARE_OP_FLOAT_r21] = _COMPARE_OP_FLOAT,
- [_COMPARE_OP_FLOAT_r32] = _COMPARE_OP_FLOAT,
- [_COMPARE_OP_INT_r21] = _COMPARE_OP_INT,
- [_COMPARE_OP_STR_r21] = _COMPARE_OP_STR,
- [_IS_OP_r21] = _IS_OP,
- [_CONTAINS_OP_r21] = _CONTAINS_OP,
+ [_COMPARE_OP_FLOAT_r03] = _COMPARE_OP_FLOAT,
+ [_COMPARE_OP_FLOAT_r13] = _COMPARE_OP_FLOAT,
+ [_COMPARE_OP_FLOAT_r23] = _COMPARE_OP_FLOAT,
+ [_COMPARE_OP_INT_r23] = _COMPARE_OP_INT,
+ [_COMPARE_OP_STR_r23] = _COMPARE_OP_STR,
+ [_IS_OP_r03] = _IS_OP,
+ [_IS_OP_r13] = _IS_OP,
+ [_IS_OP_r23] = _IS_OP,
+ [_CONTAINS_OP_r23] = _CONTAINS_OP,
[_GUARD_TOS_ANY_SET_r01] = _GUARD_TOS_ANY_SET,
[_GUARD_TOS_ANY_SET_r11] = _GUARD_TOS_ANY_SET,
[_GUARD_TOS_ANY_SET_r22] = _GUARD_TOS_ANY_SET,
[_GUARD_TOS_ANY_SET_r33] = _GUARD_TOS_ANY_SET,
- [_CONTAINS_OP_SET_r21] = _CONTAINS_OP_SET,
- [_CONTAINS_OP_DICT_r21] = _CONTAINS_OP_DICT,
+ [_CONTAINS_OP_SET_r23] = _CONTAINS_OP_SET,
+ [_CONTAINS_OP_DICT_r23] = _CONTAINS_OP_DICT,
[_CHECK_EG_MATCH_r22] = _CHECK_EG_MATCH,
[_CHECK_EXC_MATCH_r22] = _CHECK_EXC_MATCH,
[_IMPORT_NAME_r21] = _IMPORT_NAME,
@@ -3653,6 +3909,8 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {
[_ITER_NEXT_RANGE_r03] = _ITER_NEXT_RANGE,
[_ITER_NEXT_RANGE_r13] = _ITER_NEXT_RANGE,
[_ITER_NEXT_RANGE_r23] = _ITER_NEXT_RANGE,
+ [_FOR_ITER_GEN_FRAME_r03] = _FOR_ITER_GEN_FRAME,
+ [_FOR_ITER_GEN_FRAME_r13] = _FOR_ITER_GEN_FRAME,
[_FOR_ITER_GEN_FRAME_r23] = _FOR_ITER_GEN_FRAME,
[_INSERT_NULL_r10] = _INSERT_NULL,
[_LOAD_SPECIAL_r00] = _LOAD_SPECIAL,
@@ -3729,12 +3987,15 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {
[_GUARD_CALLABLE_TYPE_1_r13] = _GUARD_CALLABLE_TYPE_1,
[_GUARD_CALLABLE_TYPE_1_r23] = _GUARD_CALLABLE_TYPE_1,
[_GUARD_CALLABLE_TYPE_1_r33] = _GUARD_CALLABLE_TYPE_1,
- [_CALL_TYPE_1_r31] = _CALL_TYPE_1,
+ [_CALL_TYPE_1_r02] = _CALL_TYPE_1,
+ [_CALL_TYPE_1_r12] = _CALL_TYPE_1,
+ [_CALL_TYPE_1_r22] = _CALL_TYPE_1,
+ [_CALL_TYPE_1_r32] = _CALL_TYPE_1,
[_GUARD_CALLABLE_STR_1_r03] = _GUARD_CALLABLE_STR_1,
[_GUARD_CALLABLE_STR_1_r13] = _GUARD_CALLABLE_STR_1,
[_GUARD_CALLABLE_STR_1_r23] = _GUARD_CALLABLE_STR_1,
[_GUARD_CALLABLE_STR_1_r33] = _GUARD_CALLABLE_STR_1,
- [_CALL_STR_1_r31] = _CALL_STR_1,
+ [_CALL_STR_1_r32] = _CALL_STR_1,
[_GUARD_CALLABLE_TUPLE_1_r03] = _GUARD_CALLABLE_TUPLE_1,
[_GUARD_CALLABLE_TUPLE_1_r13] = _GUARD_CALLABLE_TUPLE_1,
[_GUARD_CALLABLE_TUPLE_1_r23] = _GUARD_CALLABLE_TUPLE_1,
@@ -3744,7 +4005,7 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {
[_CREATE_INIT_FRAME_r01] = _CREATE_INIT_FRAME,
[_EXIT_INIT_CHECK_r10] = _EXIT_INIT_CHECK,
[_CALL_BUILTIN_CLASS_r01] = _CALL_BUILTIN_CLASS,
- [_CALL_BUILTIN_O_r01] = _CALL_BUILTIN_O,
+ [_CALL_BUILTIN_O_r03] = _CALL_BUILTIN_O,
[_CALL_BUILTIN_FAST_r01] = _CALL_BUILTIN_FAST,
[_CALL_BUILTIN_FAST_WITH_KEYWORDS_r01] = _CALL_BUILTIN_FAST_WITH_KEYWORDS,
[_GUARD_CALLABLE_LEN_r03] = _GUARD_CALLABLE_LEN,
@@ -3761,8 +4022,11 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {
[_GUARD_CALLABLE_LIST_APPEND_r13] = _GUARD_CALLABLE_LIST_APPEND,
[_GUARD_CALLABLE_LIST_APPEND_r23] = _GUARD_CALLABLE_LIST_APPEND,
[_GUARD_CALLABLE_LIST_APPEND_r33] = _GUARD_CALLABLE_LIST_APPEND,
- [_CALL_LIST_APPEND_r30] = _CALL_LIST_APPEND,
- [_CALL_METHOD_DESCRIPTOR_O_r01] = _CALL_METHOD_DESCRIPTOR_O,
+ [_CALL_LIST_APPEND_r03] = _CALL_LIST_APPEND,
+ [_CALL_LIST_APPEND_r13] = _CALL_LIST_APPEND,
+ [_CALL_LIST_APPEND_r23] = _CALL_LIST_APPEND,
+ [_CALL_LIST_APPEND_r33] = _CALL_LIST_APPEND,
+ [_CALL_METHOD_DESCRIPTOR_O_r03] = _CALL_METHOD_DESCRIPTOR_O,
[_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS_r01] = _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS,
[_CALL_METHOD_DESCRIPTOR_NOARGS_r01] = _CALL_METHOD_DESCRIPTOR_NOARGS,
[_CALL_METHOD_DESCRIPTOR_FAST_r01] = _CALL_METHOD_DESCRIPTOR_FAST,
@@ -3774,6 +4038,16 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {
[_CHECK_IS_NOT_PY_CALLABLE_KW_r11] = _CHECK_IS_NOT_PY_CALLABLE_KW,
[_CALL_KW_NON_PY_r11] = _CALL_KW_NON_PY,
[_MAKE_CALLARGS_A_TUPLE_r33] = _MAKE_CALLARGS_A_TUPLE,
+ [_CHECK_IS_PY_CALLABLE_EX_r03] = _CHECK_IS_PY_CALLABLE_EX,
+ [_CHECK_IS_PY_CALLABLE_EX_r13] = _CHECK_IS_PY_CALLABLE_EX,
+ [_CHECK_IS_PY_CALLABLE_EX_r23] = _CHECK_IS_PY_CALLABLE_EX,
+ [_CHECK_IS_PY_CALLABLE_EX_r33] = _CHECK_IS_PY_CALLABLE_EX,
+ [_PY_FRAME_EX_r31] = _PY_FRAME_EX,
+ [_CHECK_IS_NOT_PY_CALLABLE_EX_r03] = _CHECK_IS_NOT_PY_CALLABLE_EX,
+ [_CHECK_IS_NOT_PY_CALLABLE_EX_r13] = _CHECK_IS_NOT_PY_CALLABLE_EX,
+ [_CHECK_IS_NOT_PY_CALLABLE_EX_r23] = _CHECK_IS_NOT_PY_CALLABLE_EX,
+ [_CHECK_IS_NOT_PY_CALLABLE_EX_r33] = _CHECK_IS_NOT_PY_CALLABLE_EX,
+ [_CALL_FUNCTION_EX_NON_PY_GENERAL_r31] = _CALL_FUNCTION_EX_NON_PY_GENERAL,
[_MAKE_FUNCTION_r11] = _MAKE_FUNCTION,
[_SET_FUNCTION_ATTRIBUTE_r01] = _SET_FUNCTION_ATTRIBUTE,
[_SET_FUNCTION_ATTRIBUTE_r11] = _SET_FUNCTION_ATTRIBUTE,
@@ -3795,7 +4069,7 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {
[_COPY_3_r23] = _COPY_3,
[_COPY_3_r33] = _COPY_3,
[_COPY_r01] = _COPY,
- [_BINARY_OP_r21] = _BINARY_OP,
+ [_BINARY_OP_r23] = _BINARY_OP,
[_SWAP_2_r02] = _SWAP_2,
[_SWAP_2_r12] = _SWAP_2,
[_SWAP_2_r22] = _SWAP_2,
@@ -3813,6 +4087,46 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {
[_GUARD_IS_FALSE_POP_r10] = _GUARD_IS_FALSE_POP,
[_GUARD_IS_FALSE_POP_r21] = _GUARD_IS_FALSE_POP,
[_GUARD_IS_FALSE_POP_r32] = _GUARD_IS_FALSE_POP,
+ [_GUARD_BIT_IS_SET_POP_4_r00] = _GUARD_BIT_IS_SET_POP_4,
+ [_GUARD_BIT_IS_SET_POP_4_r10] = _GUARD_BIT_IS_SET_POP_4,
+ [_GUARD_BIT_IS_SET_POP_4_r21] = _GUARD_BIT_IS_SET_POP_4,
+ [_GUARD_BIT_IS_SET_POP_4_r32] = _GUARD_BIT_IS_SET_POP_4,
+ [_GUARD_BIT_IS_SET_POP_5_r00] = _GUARD_BIT_IS_SET_POP_5,
+ [_GUARD_BIT_IS_SET_POP_5_r10] = _GUARD_BIT_IS_SET_POP_5,
+ [_GUARD_BIT_IS_SET_POP_5_r21] = _GUARD_BIT_IS_SET_POP_5,
+ [_GUARD_BIT_IS_SET_POP_5_r32] = _GUARD_BIT_IS_SET_POP_5,
+ [_GUARD_BIT_IS_SET_POP_6_r00] = _GUARD_BIT_IS_SET_POP_6,
+ [_GUARD_BIT_IS_SET_POP_6_r10] = _GUARD_BIT_IS_SET_POP_6,
+ [_GUARD_BIT_IS_SET_POP_6_r21] = _GUARD_BIT_IS_SET_POP_6,
+ [_GUARD_BIT_IS_SET_POP_6_r32] = _GUARD_BIT_IS_SET_POP_6,
+ [_GUARD_BIT_IS_SET_POP_7_r00] = _GUARD_BIT_IS_SET_POP_7,
+ [_GUARD_BIT_IS_SET_POP_7_r10] = _GUARD_BIT_IS_SET_POP_7,
+ [_GUARD_BIT_IS_SET_POP_7_r21] = _GUARD_BIT_IS_SET_POP_7,
+ [_GUARD_BIT_IS_SET_POP_7_r32] = _GUARD_BIT_IS_SET_POP_7,
+ [_GUARD_BIT_IS_SET_POP_r00] = _GUARD_BIT_IS_SET_POP,
+ [_GUARD_BIT_IS_SET_POP_r10] = _GUARD_BIT_IS_SET_POP,
+ [_GUARD_BIT_IS_SET_POP_r21] = _GUARD_BIT_IS_SET_POP,
+ [_GUARD_BIT_IS_SET_POP_r32] = _GUARD_BIT_IS_SET_POP,
+ [_GUARD_BIT_IS_UNSET_POP_4_r00] = _GUARD_BIT_IS_UNSET_POP_4,
+ [_GUARD_BIT_IS_UNSET_POP_4_r10] = _GUARD_BIT_IS_UNSET_POP_4,
+ [_GUARD_BIT_IS_UNSET_POP_4_r21] = _GUARD_BIT_IS_UNSET_POP_4,
+ [_GUARD_BIT_IS_UNSET_POP_4_r32] = _GUARD_BIT_IS_UNSET_POP_4,
+ [_GUARD_BIT_IS_UNSET_POP_5_r00] = _GUARD_BIT_IS_UNSET_POP_5,
+ [_GUARD_BIT_IS_UNSET_POP_5_r10] = _GUARD_BIT_IS_UNSET_POP_5,
+ [_GUARD_BIT_IS_UNSET_POP_5_r21] = _GUARD_BIT_IS_UNSET_POP_5,
+ [_GUARD_BIT_IS_UNSET_POP_5_r32] = _GUARD_BIT_IS_UNSET_POP_5,
+ [_GUARD_BIT_IS_UNSET_POP_6_r00] = _GUARD_BIT_IS_UNSET_POP_6,
+ [_GUARD_BIT_IS_UNSET_POP_6_r10] = _GUARD_BIT_IS_UNSET_POP_6,
+ [_GUARD_BIT_IS_UNSET_POP_6_r21] = _GUARD_BIT_IS_UNSET_POP_6,
+ [_GUARD_BIT_IS_UNSET_POP_6_r32] = _GUARD_BIT_IS_UNSET_POP_6,
+ [_GUARD_BIT_IS_UNSET_POP_7_r00] = _GUARD_BIT_IS_UNSET_POP_7,
+ [_GUARD_BIT_IS_UNSET_POP_7_r10] = _GUARD_BIT_IS_UNSET_POP_7,
+ [_GUARD_BIT_IS_UNSET_POP_7_r21] = _GUARD_BIT_IS_UNSET_POP_7,
+ [_GUARD_BIT_IS_UNSET_POP_7_r32] = _GUARD_BIT_IS_UNSET_POP_7,
+ [_GUARD_BIT_IS_UNSET_POP_r00] = _GUARD_BIT_IS_UNSET_POP,
+ [_GUARD_BIT_IS_UNSET_POP_r10] = _GUARD_BIT_IS_UNSET_POP,
+ [_GUARD_BIT_IS_UNSET_POP_r21] = _GUARD_BIT_IS_UNSET_POP,
+ [_GUARD_BIT_IS_UNSET_POP_r32] = _GUARD_BIT_IS_UNSET_POP,
[_GUARD_IS_NONE_POP_r00] = _GUARD_IS_NONE_POP,
[_GUARD_IS_NONE_POP_r10] = _GUARD_IS_NONE_POP,
[_GUARD_IS_NONE_POP_r21] = _GUARD_IS_NONE_POP,
@@ -3857,6 +4171,23 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {
[_POP_TWO_LOAD_CONST_INLINE_BORROW_r21] = _POP_TWO_LOAD_CONST_INLINE_BORROW,
[_POP_CALL_LOAD_CONST_INLINE_BORROW_r21] = _POP_CALL_LOAD_CONST_INLINE_BORROW,
[_POP_CALL_ONE_LOAD_CONST_INLINE_BORROW_r31] = _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW,
+ [_INSERT_1_LOAD_CONST_INLINE_r02] = _INSERT_1_LOAD_CONST_INLINE,
+ [_INSERT_1_LOAD_CONST_INLINE_r12] = _INSERT_1_LOAD_CONST_INLINE,
+ [_INSERT_1_LOAD_CONST_INLINE_r23] = _INSERT_1_LOAD_CONST_INLINE,
+ [_INSERT_1_LOAD_CONST_INLINE_BORROW_r02] = _INSERT_1_LOAD_CONST_INLINE_BORROW,
+ [_INSERT_1_LOAD_CONST_INLINE_BORROW_r12] = _INSERT_1_LOAD_CONST_INLINE_BORROW,
+ [_INSERT_1_LOAD_CONST_INLINE_BORROW_r23] = _INSERT_1_LOAD_CONST_INLINE_BORROW,
+ [_INSERT_2_LOAD_CONST_INLINE_BORROW_r03] = _INSERT_2_LOAD_CONST_INLINE_BORROW,
+ [_INSERT_2_LOAD_CONST_INLINE_BORROW_r13] = _INSERT_2_LOAD_CONST_INLINE_BORROW,
+ [_INSERT_2_LOAD_CONST_INLINE_BORROW_r23] = _INSERT_2_LOAD_CONST_INLINE_BORROW,
+ [_SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r02] = _SHUFFLE_2_LOAD_CONST_INLINE_BORROW,
+ [_SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r12] = _SHUFFLE_2_LOAD_CONST_INLINE_BORROW,
+ [_SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r22] = _SHUFFLE_2_LOAD_CONST_INLINE_BORROW,
+ [_SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r32] = _SHUFFLE_2_LOAD_CONST_INLINE_BORROW,
+ [_SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03] = _SHUFFLE_3_LOAD_CONST_INLINE_BORROW,
+ [_SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13] = _SHUFFLE_3_LOAD_CONST_INLINE_BORROW,
+ [_SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23] = _SHUFFLE_3_LOAD_CONST_INLINE_BORROW,
+ [_SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33] = _SHUFFLE_3_LOAD_CONST_INLINE_BORROW,
[_POP_CALL_TWO_LOAD_CONST_INLINE_BORROW_r31] = _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW,
[_LOAD_CONST_UNDER_INLINE_r02] = _LOAD_CONST_UNDER_INLINE,
[_LOAD_CONST_UNDER_INLINE_r12] = _LOAD_CONST_UNDER_INLINE,
@@ -3935,78 +4266,60 @@ const uint16_t _PyUop_SpillsAndReloads[4][4] = {
const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
[_BINARY_OP] = "_BINARY_OP",
- [_BINARY_OP_r21] = "_BINARY_OP_r21",
+ [_BINARY_OP_r23] = "_BINARY_OP_r23",
[_BINARY_OP_ADD_FLOAT] = "_BINARY_OP_ADD_FLOAT",
- [_BINARY_OP_ADD_FLOAT_r01] = "_BINARY_OP_ADD_FLOAT_r01",
- [_BINARY_OP_ADD_FLOAT_r11] = "_BINARY_OP_ADD_FLOAT_r11",
- [_BINARY_OP_ADD_FLOAT_r21] = "_BINARY_OP_ADD_FLOAT_r21",
- [_BINARY_OP_ADD_FLOAT_r32] = "_BINARY_OP_ADD_FLOAT_r32",
- [_BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS] = "_BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS",
- [_BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS_r01] = "_BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS_r01",
- [_BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS_r11] = "_BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS_r11",
- [_BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS_r21] = "_BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS_r21",
- [_BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS_r32] = "_BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS_r32",
+ [_BINARY_OP_ADD_FLOAT_r03] = "_BINARY_OP_ADD_FLOAT_r03",
+ [_BINARY_OP_ADD_FLOAT_r13] = "_BINARY_OP_ADD_FLOAT_r13",
+ [_BINARY_OP_ADD_FLOAT_r23] = "_BINARY_OP_ADD_FLOAT_r23",
[_BINARY_OP_ADD_INT] = "_BINARY_OP_ADD_INT",
- [_BINARY_OP_ADD_INT_r01] = "_BINARY_OP_ADD_INT_r01",
- [_BINARY_OP_ADD_INT_r11] = "_BINARY_OP_ADD_INT_r11",
- [_BINARY_OP_ADD_INT_r21] = "_BINARY_OP_ADD_INT_r21",
- [_BINARY_OP_ADD_INT_r32] = "_BINARY_OP_ADD_INT_r32",
+ [_BINARY_OP_ADD_INT_r03] = "_BINARY_OP_ADD_INT_r03",
+ [_BINARY_OP_ADD_INT_r13] = "_BINARY_OP_ADD_INT_r13",
+ [_BINARY_OP_ADD_INT_r23] = "_BINARY_OP_ADD_INT_r23",
[_BINARY_OP_ADD_UNICODE] = "_BINARY_OP_ADD_UNICODE",
- [_BINARY_OP_ADD_UNICODE_r01] = "_BINARY_OP_ADD_UNICODE_r01",
- [_BINARY_OP_ADD_UNICODE_r11] = "_BINARY_OP_ADD_UNICODE_r11",
- [_BINARY_OP_ADD_UNICODE_r21] = "_BINARY_OP_ADD_UNICODE_r21",
- [_BINARY_OP_ADD_UNICODE_r32] = "_BINARY_OP_ADD_UNICODE_r32",
+ [_BINARY_OP_ADD_UNICODE_r03] = "_BINARY_OP_ADD_UNICODE_r03",
+ [_BINARY_OP_ADD_UNICODE_r13] = "_BINARY_OP_ADD_UNICODE_r13",
+ [_BINARY_OP_ADD_UNICODE_r23] = "_BINARY_OP_ADD_UNICODE_r23",
[_BINARY_OP_EXTEND] = "_BINARY_OP_EXTEND",
- [_BINARY_OP_EXTEND_r21] = "_BINARY_OP_EXTEND_r21",
+ [_BINARY_OP_EXTEND_r23] = "_BINARY_OP_EXTEND_r23",
[_BINARY_OP_INPLACE_ADD_UNICODE] = "_BINARY_OP_INPLACE_ADD_UNICODE",
- [_BINARY_OP_INPLACE_ADD_UNICODE_r20] = "_BINARY_OP_INPLACE_ADD_UNICODE_r20",
+ [_BINARY_OP_INPLACE_ADD_UNICODE_r21] = "_BINARY_OP_INPLACE_ADD_UNICODE_r21",
[_BINARY_OP_MULTIPLY_FLOAT] = "_BINARY_OP_MULTIPLY_FLOAT",
- [_BINARY_OP_MULTIPLY_FLOAT_r01] = "_BINARY_OP_MULTIPLY_FLOAT_r01",
- [_BINARY_OP_MULTIPLY_FLOAT_r11] = "_BINARY_OP_MULTIPLY_FLOAT_r11",
- [_BINARY_OP_MULTIPLY_FLOAT_r21] = "_BINARY_OP_MULTIPLY_FLOAT_r21",
- [_BINARY_OP_MULTIPLY_FLOAT_r32] = "_BINARY_OP_MULTIPLY_FLOAT_r32",
- [_BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS] = "_BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS",
- [_BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS_r01] = "_BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS_r01",
- [_BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS_r11] = "_BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS_r11",
- [_BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS_r21] = "_BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS_r21",
- [_BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS_r32] = "_BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS_r32",
+ [_BINARY_OP_MULTIPLY_FLOAT_r03] = "_BINARY_OP_MULTIPLY_FLOAT_r03",
+ [_BINARY_OP_MULTIPLY_FLOAT_r13] = "_BINARY_OP_MULTIPLY_FLOAT_r13",
+ [_BINARY_OP_MULTIPLY_FLOAT_r23] = "_BINARY_OP_MULTIPLY_FLOAT_r23",
[_BINARY_OP_MULTIPLY_INT] = "_BINARY_OP_MULTIPLY_INT",
- [_BINARY_OP_MULTIPLY_INT_r01] = "_BINARY_OP_MULTIPLY_INT_r01",
- [_BINARY_OP_MULTIPLY_INT_r11] = "_BINARY_OP_MULTIPLY_INT_r11",
- [_BINARY_OP_MULTIPLY_INT_r21] = "_BINARY_OP_MULTIPLY_INT_r21",
- [_BINARY_OP_MULTIPLY_INT_r32] = "_BINARY_OP_MULTIPLY_INT_r32",
+ [_BINARY_OP_MULTIPLY_INT_r03] = "_BINARY_OP_MULTIPLY_INT_r03",
+ [_BINARY_OP_MULTIPLY_INT_r13] = "_BINARY_OP_MULTIPLY_INT_r13",
+ [_BINARY_OP_MULTIPLY_INT_r23] = "_BINARY_OP_MULTIPLY_INT_r23",
[_BINARY_OP_SUBSCR_CHECK_FUNC] = "_BINARY_OP_SUBSCR_CHECK_FUNC",
[_BINARY_OP_SUBSCR_CHECK_FUNC_r23] = "_BINARY_OP_SUBSCR_CHECK_FUNC_r23",
[_BINARY_OP_SUBSCR_DICT] = "_BINARY_OP_SUBSCR_DICT",
- [_BINARY_OP_SUBSCR_DICT_r21] = "_BINARY_OP_SUBSCR_DICT_r21",
+ [_BINARY_OP_SUBSCR_DICT_r23] = "_BINARY_OP_SUBSCR_DICT_r23",
[_BINARY_OP_SUBSCR_INIT_CALL] = "_BINARY_OP_SUBSCR_INIT_CALL",
[_BINARY_OP_SUBSCR_INIT_CALL_r01] = "_BINARY_OP_SUBSCR_INIT_CALL_r01",
[_BINARY_OP_SUBSCR_INIT_CALL_r11] = "_BINARY_OP_SUBSCR_INIT_CALL_r11",
[_BINARY_OP_SUBSCR_INIT_CALL_r21] = "_BINARY_OP_SUBSCR_INIT_CALL_r21",
[_BINARY_OP_SUBSCR_INIT_CALL_r31] = "_BINARY_OP_SUBSCR_INIT_CALL_r31",
[_BINARY_OP_SUBSCR_LIST_INT] = "_BINARY_OP_SUBSCR_LIST_INT",
- [_BINARY_OP_SUBSCR_LIST_INT_r21] = "_BINARY_OP_SUBSCR_LIST_INT_r21",
+ [_BINARY_OP_SUBSCR_LIST_INT_r23] = "_BINARY_OP_SUBSCR_LIST_INT_r23",
[_BINARY_OP_SUBSCR_LIST_SLICE] = "_BINARY_OP_SUBSCR_LIST_SLICE",
[_BINARY_OP_SUBSCR_LIST_SLICE_r21] = "_BINARY_OP_SUBSCR_LIST_SLICE_r21",
[_BINARY_OP_SUBSCR_STR_INT] = "_BINARY_OP_SUBSCR_STR_INT",
- [_BINARY_OP_SUBSCR_STR_INT_r21] = "_BINARY_OP_SUBSCR_STR_INT_r21",
+ [_BINARY_OP_SUBSCR_STR_INT_r23] = "_BINARY_OP_SUBSCR_STR_INT_r23",
[_BINARY_OP_SUBSCR_TUPLE_INT] = "_BINARY_OP_SUBSCR_TUPLE_INT",
- [_BINARY_OP_SUBSCR_TUPLE_INT_r21] = "_BINARY_OP_SUBSCR_TUPLE_INT_r21",
+ [_BINARY_OP_SUBSCR_TUPLE_INT_r03] = "_BINARY_OP_SUBSCR_TUPLE_INT_r03",
+ [_BINARY_OP_SUBSCR_TUPLE_INT_r13] = "_BINARY_OP_SUBSCR_TUPLE_INT_r13",
+ [_BINARY_OP_SUBSCR_TUPLE_INT_r23] = "_BINARY_OP_SUBSCR_TUPLE_INT_r23",
+ [_BINARY_OP_SUBSCR_USTR_INT] = "_BINARY_OP_SUBSCR_USTR_INT",
+ [_BINARY_OP_SUBSCR_USTR_INT_r23] = "_BINARY_OP_SUBSCR_USTR_INT_r23",
[_BINARY_OP_SUBTRACT_FLOAT] = "_BINARY_OP_SUBTRACT_FLOAT",
- [_BINARY_OP_SUBTRACT_FLOAT_r01] = "_BINARY_OP_SUBTRACT_FLOAT_r01",
- [_BINARY_OP_SUBTRACT_FLOAT_r11] = "_BINARY_OP_SUBTRACT_FLOAT_r11",
- [_BINARY_OP_SUBTRACT_FLOAT_r21] = "_BINARY_OP_SUBTRACT_FLOAT_r21",
- [_BINARY_OP_SUBTRACT_FLOAT_r32] = "_BINARY_OP_SUBTRACT_FLOAT_r32",
- [_BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS] = "_BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS",
- [_BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS_r01] = "_BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS_r01",
- [_BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS_r11] = "_BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS_r11",
- [_BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS_r21] = "_BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS_r21",
- [_BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS_r32] = "_BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS_r32",
+ [_BINARY_OP_SUBTRACT_FLOAT_r03] = "_BINARY_OP_SUBTRACT_FLOAT_r03",
+ [_BINARY_OP_SUBTRACT_FLOAT_r13] = "_BINARY_OP_SUBTRACT_FLOAT_r13",
+ [_BINARY_OP_SUBTRACT_FLOAT_r23] = "_BINARY_OP_SUBTRACT_FLOAT_r23",
[_BINARY_OP_SUBTRACT_INT] = "_BINARY_OP_SUBTRACT_INT",
- [_BINARY_OP_SUBTRACT_INT_r01] = "_BINARY_OP_SUBTRACT_INT_r01",
- [_BINARY_OP_SUBTRACT_INT_r11] = "_BINARY_OP_SUBTRACT_INT_r11",
- [_BINARY_OP_SUBTRACT_INT_r21] = "_BINARY_OP_SUBTRACT_INT_r21",
- [_BINARY_OP_SUBTRACT_INT_r32] = "_BINARY_OP_SUBTRACT_INT_r32",
+ [_BINARY_OP_SUBTRACT_INT_r03] = "_BINARY_OP_SUBTRACT_INT_r03",
+ [_BINARY_OP_SUBTRACT_INT_r13] = "_BINARY_OP_SUBTRACT_INT_r13",
+ [_BINARY_OP_SUBTRACT_INT_r23] = "_BINARY_OP_SUBTRACT_INT_r23",
[_BINARY_SLICE] = "_BINARY_SLICE",
[_BINARY_SLICE_r31] = "_BINARY_SLICE_r31",
[_BUILD_INTERPOLATION] = "_BUILD_INTERPOLATION",
@@ -4032,7 +4345,9 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
[_CALL_BUILTIN_FAST_WITH_KEYWORDS] = "_CALL_BUILTIN_FAST_WITH_KEYWORDS",
[_CALL_BUILTIN_FAST_WITH_KEYWORDS_r01] = "_CALL_BUILTIN_FAST_WITH_KEYWORDS_r01",
[_CALL_BUILTIN_O] = "_CALL_BUILTIN_O",
- [_CALL_BUILTIN_O_r01] = "_CALL_BUILTIN_O_r01",
+ [_CALL_BUILTIN_O_r03] = "_CALL_BUILTIN_O_r03",
+ [_CALL_FUNCTION_EX_NON_PY_GENERAL] = "_CALL_FUNCTION_EX_NON_PY_GENERAL",
+ [_CALL_FUNCTION_EX_NON_PY_GENERAL_r31] = "_CALL_FUNCTION_EX_NON_PY_GENERAL_r31",
[_CALL_INTRINSIC_1] = "_CALL_INTRINSIC_1",
[_CALL_INTRINSIC_1_r11] = "_CALL_INTRINSIC_1_r11",
[_CALL_INTRINSIC_2] = "_CALL_INTRINSIC_2",
@@ -4044,7 +4359,10 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
[_CALL_LEN] = "_CALL_LEN",
[_CALL_LEN_r33] = "_CALL_LEN_r33",
[_CALL_LIST_APPEND] = "_CALL_LIST_APPEND",
- [_CALL_LIST_APPEND_r30] = "_CALL_LIST_APPEND_r30",
+ [_CALL_LIST_APPEND_r03] = "_CALL_LIST_APPEND_r03",
+ [_CALL_LIST_APPEND_r13] = "_CALL_LIST_APPEND_r13",
+ [_CALL_LIST_APPEND_r23] = "_CALL_LIST_APPEND_r23",
+ [_CALL_LIST_APPEND_r33] = "_CALL_LIST_APPEND_r33",
[_CALL_METHOD_DESCRIPTOR_FAST] = "_CALL_METHOD_DESCRIPTOR_FAST",
[_CALL_METHOD_DESCRIPTOR_FAST_r01] = "_CALL_METHOD_DESCRIPTOR_FAST_r01",
[_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = "_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS",
@@ -4052,15 +4370,18 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
[_CALL_METHOD_DESCRIPTOR_NOARGS] = "_CALL_METHOD_DESCRIPTOR_NOARGS",
[_CALL_METHOD_DESCRIPTOR_NOARGS_r01] = "_CALL_METHOD_DESCRIPTOR_NOARGS_r01",
[_CALL_METHOD_DESCRIPTOR_O] = "_CALL_METHOD_DESCRIPTOR_O",
- [_CALL_METHOD_DESCRIPTOR_O_r01] = "_CALL_METHOD_DESCRIPTOR_O_r01",
+ [_CALL_METHOD_DESCRIPTOR_O_r03] = "_CALL_METHOD_DESCRIPTOR_O_r03",
[_CALL_NON_PY_GENERAL] = "_CALL_NON_PY_GENERAL",
[_CALL_NON_PY_GENERAL_r01] = "_CALL_NON_PY_GENERAL_r01",
[_CALL_STR_1] = "_CALL_STR_1",
- [_CALL_STR_1_r31] = "_CALL_STR_1_r31",
+ [_CALL_STR_1_r32] = "_CALL_STR_1_r32",
[_CALL_TUPLE_1] = "_CALL_TUPLE_1",
[_CALL_TUPLE_1_r32] = "_CALL_TUPLE_1_r32",
[_CALL_TYPE_1] = "_CALL_TYPE_1",
- [_CALL_TYPE_1_r31] = "_CALL_TYPE_1_r31",
+ [_CALL_TYPE_1_r02] = "_CALL_TYPE_1_r02",
+ [_CALL_TYPE_1_r12] = "_CALL_TYPE_1_r12",
+ [_CALL_TYPE_1_r22] = "_CALL_TYPE_1_r22",
+ [_CALL_TYPE_1_r32] = "_CALL_TYPE_1_r32",
[_CHECK_AND_ALLOCATE_OBJECT] = "_CHECK_AND_ALLOCATE_OBJECT",
[_CHECK_AND_ALLOCATE_OBJECT_r00] = "_CHECK_AND_ALLOCATE_OBJECT_r00",
[_CHECK_ATTR_CLASS] = "_CHECK_ATTR_CLASS",
@@ -4092,8 +4413,18 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
[_CHECK_FUNCTION_VERSION_KW_r11] = "_CHECK_FUNCTION_VERSION_KW_r11",
[_CHECK_IS_NOT_PY_CALLABLE] = "_CHECK_IS_NOT_PY_CALLABLE",
[_CHECK_IS_NOT_PY_CALLABLE_r00] = "_CHECK_IS_NOT_PY_CALLABLE_r00",
+ [_CHECK_IS_NOT_PY_CALLABLE_EX] = "_CHECK_IS_NOT_PY_CALLABLE_EX",
+ [_CHECK_IS_NOT_PY_CALLABLE_EX_r03] = "_CHECK_IS_NOT_PY_CALLABLE_EX_r03",
+ [_CHECK_IS_NOT_PY_CALLABLE_EX_r13] = "_CHECK_IS_NOT_PY_CALLABLE_EX_r13",
+ [_CHECK_IS_NOT_PY_CALLABLE_EX_r23] = "_CHECK_IS_NOT_PY_CALLABLE_EX_r23",
+ [_CHECK_IS_NOT_PY_CALLABLE_EX_r33] = "_CHECK_IS_NOT_PY_CALLABLE_EX_r33",
[_CHECK_IS_NOT_PY_CALLABLE_KW] = "_CHECK_IS_NOT_PY_CALLABLE_KW",
[_CHECK_IS_NOT_PY_CALLABLE_KW_r11] = "_CHECK_IS_NOT_PY_CALLABLE_KW_r11",
+ [_CHECK_IS_PY_CALLABLE_EX] = "_CHECK_IS_PY_CALLABLE_EX",
+ [_CHECK_IS_PY_CALLABLE_EX_r03] = "_CHECK_IS_PY_CALLABLE_EX_r03",
+ [_CHECK_IS_PY_CALLABLE_EX_r13] = "_CHECK_IS_PY_CALLABLE_EX_r13",
+ [_CHECK_IS_PY_CALLABLE_EX_r23] = "_CHECK_IS_PY_CALLABLE_EX_r23",
+ [_CHECK_IS_PY_CALLABLE_EX_r33] = "_CHECK_IS_PY_CALLABLE_EX_r33",
[_CHECK_MANAGED_OBJECT_HAS_VALUES] = "_CHECK_MANAGED_OBJECT_HAS_VALUES",
[_CHECK_MANAGED_OBJECT_HAS_VALUES_r01] = "_CHECK_MANAGED_OBJECT_HAS_VALUES_r01",
[_CHECK_MANAGED_OBJECT_HAS_VALUES_r11] = "_CHECK_MANAGED_OBJECT_HAS_VALUES_r11",
@@ -4136,20 +4467,19 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
[_COMPARE_OP] = "_COMPARE_OP",
[_COMPARE_OP_r21] = "_COMPARE_OP_r21",
[_COMPARE_OP_FLOAT] = "_COMPARE_OP_FLOAT",
- [_COMPARE_OP_FLOAT_r01] = "_COMPARE_OP_FLOAT_r01",
- [_COMPARE_OP_FLOAT_r11] = "_COMPARE_OP_FLOAT_r11",
- [_COMPARE_OP_FLOAT_r21] = "_COMPARE_OP_FLOAT_r21",
- [_COMPARE_OP_FLOAT_r32] = "_COMPARE_OP_FLOAT_r32",
+ [_COMPARE_OP_FLOAT_r03] = "_COMPARE_OP_FLOAT_r03",
+ [_COMPARE_OP_FLOAT_r13] = "_COMPARE_OP_FLOAT_r13",
+ [_COMPARE_OP_FLOAT_r23] = "_COMPARE_OP_FLOAT_r23",
[_COMPARE_OP_INT] = "_COMPARE_OP_INT",
- [_COMPARE_OP_INT_r21] = "_COMPARE_OP_INT_r21",
+ [_COMPARE_OP_INT_r23] = "_COMPARE_OP_INT_r23",
[_COMPARE_OP_STR] = "_COMPARE_OP_STR",
- [_COMPARE_OP_STR_r21] = "_COMPARE_OP_STR_r21",
+ [_COMPARE_OP_STR_r23] = "_COMPARE_OP_STR_r23",
[_CONTAINS_OP] = "_CONTAINS_OP",
- [_CONTAINS_OP_r21] = "_CONTAINS_OP_r21",
+ [_CONTAINS_OP_r23] = "_CONTAINS_OP_r23",
[_CONTAINS_OP_DICT] = "_CONTAINS_OP_DICT",
- [_CONTAINS_OP_DICT_r21] = "_CONTAINS_OP_DICT_r21",
+ [_CONTAINS_OP_DICT_r23] = "_CONTAINS_OP_DICT_r23",
[_CONTAINS_OP_SET] = "_CONTAINS_OP_SET",
- [_CONTAINS_OP_SET_r21] = "_CONTAINS_OP_SET_r21",
+ [_CONTAINS_OP_SET_r23] = "_CONTAINS_OP_SET_r23",
[_CONVERT_VALUE] = "_CONVERT_VALUE",
[_CONVERT_VALUE_r11] = "_CONVERT_VALUE_r11",
[_COPY] = "_COPY",
@@ -4227,6 +4557,8 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
[_FORMAT_WITH_SPEC] = "_FORMAT_WITH_SPEC",
[_FORMAT_WITH_SPEC_r21] = "_FORMAT_WITH_SPEC_r21",
[_FOR_ITER_GEN_FRAME] = "_FOR_ITER_GEN_FRAME",
+ [_FOR_ITER_GEN_FRAME_r03] = "_FOR_ITER_GEN_FRAME_r03",
+ [_FOR_ITER_GEN_FRAME_r13] = "_FOR_ITER_GEN_FRAME_r13",
[_FOR_ITER_GEN_FRAME_r23] = "_FOR_ITER_GEN_FRAME_r23",
[_FOR_ITER_TIER_TWO] = "_FOR_ITER_TIER_TWO",
[_FOR_ITER_TIER_TWO_r23] = "_FOR_ITER_TIER_TWO_r23",
@@ -4244,6 +4576,61 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
[_GET_YIELD_FROM_ITER_r11] = "_GET_YIELD_FROM_ITER_r11",
[_GUARD_BINARY_OP_EXTEND] = "_GUARD_BINARY_OP_EXTEND",
[_GUARD_BINARY_OP_EXTEND_r22] = "_GUARD_BINARY_OP_EXTEND_r22",
+ [_GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS] = "_GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS",
+ [_GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r02] = "_GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r02",
+ [_GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r12] = "_GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r12",
+ [_GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r22] = "_GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r22",
+ [_GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r33] = "_GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r33",
+ [_GUARD_BIT_IS_SET_POP] = "_GUARD_BIT_IS_SET_POP",
+ [_GUARD_BIT_IS_SET_POP_r00] = "_GUARD_BIT_IS_SET_POP_r00",
+ [_GUARD_BIT_IS_SET_POP_r10] = "_GUARD_BIT_IS_SET_POP_r10",
+ [_GUARD_BIT_IS_SET_POP_r21] = "_GUARD_BIT_IS_SET_POP_r21",
+ [_GUARD_BIT_IS_SET_POP_r32] = "_GUARD_BIT_IS_SET_POP_r32",
+ [_GUARD_BIT_IS_SET_POP_4] = "_GUARD_BIT_IS_SET_POP_4",
+ [_GUARD_BIT_IS_SET_POP_4_r00] = "_GUARD_BIT_IS_SET_POP_4_r00",
+ [_GUARD_BIT_IS_SET_POP_4_r10] = "_GUARD_BIT_IS_SET_POP_4_r10",
+ [_GUARD_BIT_IS_SET_POP_4_r21] = "_GUARD_BIT_IS_SET_POP_4_r21",
+ [_GUARD_BIT_IS_SET_POP_4_r32] = "_GUARD_BIT_IS_SET_POP_4_r32",
+ [_GUARD_BIT_IS_SET_POP_5] = "_GUARD_BIT_IS_SET_POP_5",
+ [_GUARD_BIT_IS_SET_POP_5_r00] = "_GUARD_BIT_IS_SET_POP_5_r00",
+ [_GUARD_BIT_IS_SET_POP_5_r10] = "_GUARD_BIT_IS_SET_POP_5_r10",
+ [_GUARD_BIT_IS_SET_POP_5_r21] = "_GUARD_BIT_IS_SET_POP_5_r21",
+ [_GUARD_BIT_IS_SET_POP_5_r32] = "_GUARD_BIT_IS_SET_POP_5_r32",
+ [_GUARD_BIT_IS_SET_POP_6] = "_GUARD_BIT_IS_SET_POP_6",
+ [_GUARD_BIT_IS_SET_POP_6_r00] = "_GUARD_BIT_IS_SET_POP_6_r00",
+ [_GUARD_BIT_IS_SET_POP_6_r10] = "_GUARD_BIT_IS_SET_POP_6_r10",
+ [_GUARD_BIT_IS_SET_POP_6_r21] = "_GUARD_BIT_IS_SET_POP_6_r21",
+ [_GUARD_BIT_IS_SET_POP_6_r32] = "_GUARD_BIT_IS_SET_POP_6_r32",
+ [_GUARD_BIT_IS_SET_POP_7] = "_GUARD_BIT_IS_SET_POP_7",
+ [_GUARD_BIT_IS_SET_POP_7_r00] = "_GUARD_BIT_IS_SET_POP_7_r00",
+ [_GUARD_BIT_IS_SET_POP_7_r10] = "_GUARD_BIT_IS_SET_POP_7_r10",
+ [_GUARD_BIT_IS_SET_POP_7_r21] = "_GUARD_BIT_IS_SET_POP_7_r21",
+ [_GUARD_BIT_IS_SET_POP_7_r32] = "_GUARD_BIT_IS_SET_POP_7_r32",
+ [_GUARD_BIT_IS_UNSET_POP] = "_GUARD_BIT_IS_UNSET_POP",
+ [_GUARD_BIT_IS_UNSET_POP_r00] = "_GUARD_BIT_IS_UNSET_POP_r00",
+ [_GUARD_BIT_IS_UNSET_POP_r10] = "_GUARD_BIT_IS_UNSET_POP_r10",
+ [_GUARD_BIT_IS_UNSET_POP_r21] = "_GUARD_BIT_IS_UNSET_POP_r21",
+ [_GUARD_BIT_IS_UNSET_POP_r32] = "_GUARD_BIT_IS_UNSET_POP_r32",
+ [_GUARD_BIT_IS_UNSET_POP_4] = "_GUARD_BIT_IS_UNSET_POP_4",
+ [_GUARD_BIT_IS_UNSET_POP_4_r00] = "_GUARD_BIT_IS_UNSET_POP_4_r00",
+ [_GUARD_BIT_IS_UNSET_POP_4_r10] = "_GUARD_BIT_IS_UNSET_POP_4_r10",
+ [_GUARD_BIT_IS_UNSET_POP_4_r21] = "_GUARD_BIT_IS_UNSET_POP_4_r21",
+ [_GUARD_BIT_IS_UNSET_POP_4_r32] = "_GUARD_BIT_IS_UNSET_POP_4_r32",
+ [_GUARD_BIT_IS_UNSET_POP_5] = "_GUARD_BIT_IS_UNSET_POP_5",
+ [_GUARD_BIT_IS_UNSET_POP_5_r00] = "_GUARD_BIT_IS_UNSET_POP_5_r00",
+ [_GUARD_BIT_IS_UNSET_POP_5_r10] = "_GUARD_BIT_IS_UNSET_POP_5_r10",
+ [_GUARD_BIT_IS_UNSET_POP_5_r21] = "_GUARD_BIT_IS_UNSET_POP_5_r21",
+ [_GUARD_BIT_IS_UNSET_POP_5_r32] = "_GUARD_BIT_IS_UNSET_POP_5_r32",
+ [_GUARD_BIT_IS_UNSET_POP_6] = "_GUARD_BIT_IS_UNSET_POP_6",
+ [_GUARD_BIT_IS_UNSET_POP_6_r00] = "_GUARD_BIT_IS_UNSET_POP_6_r00",
+ [_GUARD_BIT_IS_UNSET_POP_6_r10] = "_GUARD_BIT_IS_UNSET_POP_6_r10",
+ [_GUARD_BIT_IS_UNSET_POP_6_r21] = "_GUARD_BIT_IS_UNSET_POP_6_r21",
+ [_GUARD_BIT_IS_UNSET_POP_6_r32] = "_GUARD_BIT_IS_UNSET_POP_6_r32",
+ [_GUARD_BIT_IS_UNSET_POP_7] = "_GUARD_BIT_IS_UNSET_POP_7",
+ [_GUARD_BIT_IS_UNSET_POP_7_r00] = "_GUARD_BIT_IS_UNSET_POP_7_r00",
+ [_GUARD_BIT_IS_UNSET_POP_7_r10] = "_GUARD_BIT_IS_UNSET_POP_7_r10",
+ [_GUARD_BIT_IS_UNSET_POP_7_r21] = "_GUARD_BIT_IS_UNSET_POP_7_r21",
+ [_GUARD_BIT_IS_UNSET_POP_7_r32] = "_GUARD_BIT_IS_UNSET_POP_7_r32",
[_GUARD_CALLABLE_ISINSTANCE] = "_GUARD_CALLABLE_ISINSTANCE",
[_GUARD_CALLABLE_ISINSTANCE_r03] = "_GUARD_CALLABLE_ISINSTANCE_r03",
[_GUARD_CALLABLE_ISINSTANCE_r13] = "_GUARD_CALLABLE_ISINSTANCE_r13",
@@ -4331,6 +4718,11 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
[_GUARD_KEYS_VERSION_r11] = "_GUARD_KEYS_VERSION_r11",
[_GUARD_KEYS_VERSION_r22] = "_GUARD_KEYS_VERSION_r22",
[_GUARD_KEYS_VERSION_r33] = "_GUARD_KEYS_VERSION_r33",
+ [_GUARD_NOS_COMPACT_ASCII] = "_GUARD_NOS_COMPACT_ASCII",
+ [_GUARD_NOS_COMPACT_ASCII_r02] = "_GUARD_NOS_COMPACT_ASCII_r02",
+ [_GUARD_NOS_COMPACT_ASCII_r12] = "_GUARD_NOS_COMPACT_ASCII_r12",
+ [_GUARD_NOS_COMPACT_ASCII_r22] = "_GUARD_NOS_COMPACT_ASCII_r22",
+ [_GUARD_NOS_COMPACT_ASCII_r33] = "_GUARD_NOS_COMPACT_ASCII_r33",
[_GUARD_NOS_DICT] = "_GUARD_NOS_DICT",
[_GUARD_NOS_DICT_r02] = "_GUARD_NOS_DICT_r02",
[_GUARD_NOS_DICT_r12] = "_GUARD_NOS_DICT_r12",
@@ -4474,12 +4866,26 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
[_INIT_CALL_PY_EXACT_ARGS_3_r01] = "_INIT_CALL_PY_EXACT_ARGS_3_r01",
[_INIT_CALL_PY_EXACT_ARGS_4] = "_INIT_CALL_PY_EXACT_ARGS_4",
[_INIT_CALL_PY_EXACT_ARGS_4_r01] = "_INIT_CALL_PY_EXACT_ARGS_4_r01",
+ [_INSERT_1_LOAD_CONST_INLINE] = "_INSERT_1_LOAD_CONST_INLINE",
+ [_INSERT_1_LOAD_CONST_INLINE_r02] = "_INSERT_1_LOAD_CONST_INLINE_r02",
+ [_INSERT_1_LOAD_CONST_INLINE_r12] = "_INSERT_1_LOAD_CONST_INLINE_r12",
+ [_INSERT_1_LOAD_CONST_INLINE_r23] = "_INSERT_1_LOAD_CONST_INLINE_r23",
+ [_INSERT_1_LOAD_CONST_INLINE_BORROW] = "_INSERT_1_LOAD_CONST_INLINE_BORROW",
+ [_INSERT_1_LOAD_CONST_INLINE_BORROW_r02] = "_INSERT_1_LOAD_CONST_INLINE_BORROW_r02",
+ [_INSERT_1_LOAD_CONST_INLINE_BORROW_r12] = "_INSERT_1_LOAD_CONST_INLINE_BORROW_r12",
+ [_INSERT_1_LOAD_CONST_INLINE_BORROW_r23] = "_INSERT_1_LOAD_CONST_INLINE_BORROW_r23",
+ [_INSERT_2_LOAD_CONST_INLINE_BORROW] = "_INSERT_2_LOAD_CONST_INLINE_BORROW",
+ [_INSERT_2_LOAD_CONST_INLINE_BORROW_r03] = "_INSERT_2_LOAD_CONST_INLINE_BORROW_r03",
+ [_INSERT_2_LOAD_CONST_INLINE_BORROW_r13] = "_INSERT_2_LOAD_CONST_INLINE_BORROW_r13",
+ [_INSERT_2_LOAD_CONST_INLINE_BORROW_r23] = "_INSERT_2_LOAD_CONST_INLINE_BORROW_r23",
[_INSERT_NULL] = "_INSERT_NULL",
[_INSERT_NULL_r10] = "_INSERT_NULL_r10",
[_IS_NONE] = "_IS_NONE",
[_IS_NONE_r11] = "_IS_NONE_r11",
[_IS_OP] = "_IS_OP",
- [_IS_OP_r21] = "_IS_OP_r21",
+ [_IS_OP_r03] = "_IS_OP_r03",
+ [_IS_OP_r13] = "_IS_OP_r13",
+ [_IS_OP_r23] = "_IS_OP_r23",
[_ITER_CHECK_LIST] = "_ITER_CHECK_LIST",
[_ITER_CHECK_LIST_r02] = "_ITER_CHECK_LIST_r02",
[_ITER_CHECK_LIST_r12] = "_ITER_CHECK_LIST_r12",
@@ -4516,7 +4922,9 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
[_LOAD_ATTR_CLASS] = "_LOAD_ATTR_CLASS",
[_LOAD_ATTR_CLASS_r11] = "_LOAD_ATTR_CLASS_r11",
[_LOAD_ATTR_INSTANCE_VALUE] = "_LOAD_ATTR_INSTANCE_VALUE",
- [_LOAD_ATTR_INSTANCE_VALUE_r11] = "_LOAD_ATTR_INSTANCE_VALUE_r11",
+ [_LOAD_ATTR_INSTANCE_VALUE_r02] = "_LOAD_ATTR_INSTANCE_VALUE_r02",
+ [_LOAD_ATTR_INSTANCE_VALUE_r12] = "_LOAD_ATTR_INSTANCE_VALUE_r12",
+ [_LOAD_ATTR_INSTANCE_VALUE_r23] = "_LOAD_ATTR_INSTANCE_VALUE_r23",
[_LOAD_ATTR_METHOD_LAZY_DICT] = "_LOAD_ATTR_METHOD_LAZY_DICT",
[_LOAD_ATTR_METHOD_LAZY_DICT_r02] = "_LOAD_ATTR_METHOD_LAZY_DICT_r02",
[_LOAD_ATTR_METHOD_LAZY_DICT_r12] = "_LOAD_ATTR_METHOD_LAZY_DICT_r12",
@@ -4530,7 +4938,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
[_LOAD_ATTR_METHOD_WITH_VALUES_r12] = "_LOAD_ATTR_METHOD_WITH_VALUES_r12",
[_LOAD_ATTR_METHOD_WITH_VALUES_r23] = "_LOAD_ATTR_METHOD_WITH_VALUES_r23",
[_LOAD_ATTR_MODULE] = "_LOAD_ATTR_MODULE",
- [_LOAD_ATTR_MODULE_r11] = "_LOAD_ATTR_MODULE_r11",
+ [_LOAD_ATTR_MODULE_r12] = "_LOAD_ATTR_MODULE_r12",
[_LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = "_LOAD_ATTR_NONDESCRIPTOR_NO_DICT",
[_LOAD_ATTR_NONDESCRIPTOR_NO_DICT_r11] = "_LOAD_ATTR_NONDESCRIPTOR_NO_DICT_r11",
[_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = "_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES",
@@ -4538,9 +4946,11 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
[_LOAD_ATTR_PROPERTY_FRAME] = "_LOAD_ATTR_PROPERTY_FRAME",
[_LOAD_ATTR_PROPERTY_FRAME_r11] = "_LOAD_ATTR_PROPERTY_FRAME_r11",
[_LOAD_ATTR_SLOT] = "_LOAD_ATTR_SLOT",
- [_LOAD_ATTR_SLOT_r11] = "_LOAD_ATTR_SLOT_r11",
+ [_LOAD_ATTR_SLOT_r02] = "_LOAD_ATTR_SLOT_r02",
+ [_LOAD_ATTR_SLOT_r12] = "_LOAD_ATTR_SLOT_r12",
+ [_LOAD_ATTR_SLOT_r23] = "_LOAD_ATTR_SLOT_r23",
[_LOAD_ATTR_WITH_HINT] = "_LOAD_ATTR_WITH_HINT",
- [_LOAD_ATTR_WITH_HINT_r11] = "_LOAD_ATTR_WITH_HINT_r11",
+ [_LOAD_ATTR_WITH_HINT_r12] = "_LOAD_ATTR_WITH_HINT_r12",
[_LOAD_BUILD_CLASS] = "_LOAD_BUILD_CLASS",
[_LOAD_BUILD_CLASS_r01] = "_LOAD_BUILD_CLASS_r01",
[_LOAD_COMMON_CONSTANT] = "_LOAD_COMMON_CONSTANT",
@@ -4647,6 +5057,8 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
[_LOAD_FAST_BORROW_7_r23] = "_LOAD_FAST_BORROW_7_r23",
[_LOAD_FAST_CHECK] = "_LOAD_FAST_CHECK",
[_LOAD_FAST_CHECK_r01] = "_LOAD_FAST_CHECK_r01",
+ [_LOAD_FAST_CHECK_r12] = "_LOAD_FAST_CHECK_r12",
+ [_LOAD_FAST_CHECK_r23] = "_LOAD_FAST_CHECK_r23",
[_LOAD_FROM_DICT_OR_DEREF] = "_LOAD_FROM_DICT_OR_DEREF",
[_LOAD_FROM_DICT_OR_DEREF_r11] = "_LOAD_FROM_DICT_OR_DEREF_r11",
[_LOAD_GLOBAL] = "_LOAD_GLOBAL",
@@ -4657,6 +5069,8 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
[_LOAD_GLOBAL_MODULE_r01] = "_LOAD_GLOBAL_MODULE_r01",
[_LOAD_LOCALS] = "_LOAD_LOCALS",
[_LOAD_LOCALS_r01] = "_LOAD_LOCALS_r01",
+ [_LOAD_LOCALS_r12] = "_LOAD_LOCALS_r12",
+ [_LOAD_LOCALS_r23] = "_LOAD_LOCALS_r23",
[_LOAD_NAME] = "_LOAD_NAME",
[_LOAD_NAME_r01] = "_LOAD_NAME_r01",
[_LOAD_SMALL_INT] = "_LOAD_SMALL_INT",
@@ -4777,12 +5191,16 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
[_PUSH_NULL_r23] = "_PUSH_NULL_r23",
[_PUSH_NULL_CONDITIONAL] = "_PUSH_NULL_CONDITIONAL",
[_PUSH_NULL_CONDITIONAL_r00] = "_PUSH_NULL_CONDITIONAL_r00",
+ [_PY_FRAME_EX] = "_PY_FRAME_EX",
+ [_PY_FRAME_EX_r31] = "_PY_FRAME_EX_r31",
[_PY_FRAME_GENERAL] = "_PY_FRAME_GENERAL",
[_PY_FRAME_GENERAL_r01] = "_PY_FRAME_GENERAL_r01",
[_PY_FRAME_KW] = "_PY_FRAME_KW",
[_PY_FRAME_KW_r11] = "_PY_FRAME_KW_r11",
[_REPLACE_WITH_TRUE] = "_REPLACE_WITH_TRUE",
- [_REPLACE_WITH_TRUE_r11] = "_REPLACE_WITH_TRUE_r11",
+ [_REPLACE_WITH_TRUE_r02] = "_REPLACE_WITH_TRUE_r02",
+ [_REPLACE_WITH_TRUE_r12] = "_REPLACE_WITH_TRUE_r12",
+ [_REPLACE_WITH_TRUE_r23] = "_REPLACE_WITH_TRUE_r23",
[_RESUME_CHECK] = "_RESUME_CHECK",
[_RESUME_CHECK_r00] = "_RESUME_CHECK_r00",
[_RESUME_CHECK_r11] = "_RESUME_CHECK_r11",
@@ -4815,6 +5233,16 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
[_SET_IP_r33] = "_SET_IP_r33",
[_SET_UPDATE] = "_SET_UPDATE",
[_SET_UPDATE_r10] = "_SET_UPDATE_r10",
+ [_SHUFFLE_2_LOAD_CONST_INLINE_BORROW] = "_SHUFFLE_2_LOAD_CONST_INLINE_BORROW",
+ [_SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r02] = "_SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r02",
+ [_SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r12] = "_SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r12",
+ [_SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r22] = "_SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r22",
+ [_SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r32] = "_SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r32",
+ [_SHUFFLE_3_LOAD_CONST_INLINE_BORROW] = "_SHUFFLE_3_LOAD_CONST_INLINE_BORROW",
+ [_SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03] = "_SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03",
+ [_SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13] = "_SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13",
+ [_SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23] = "_SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23",
+ [_SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33] = "_SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33",
[_SPILL_OR_RELOAD] = "_SPILL_OR_RELOAD",
[_SPILL_OR_RELOAD_r01] = "_SPILL_OR_RELOAD_r01",
[_SPILL_OR_RELOAD_r02] = "_SPILL_OR_RELOAD_r02",
@@ -4833,31 +5261,23 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
[_STORE_ATTR] = "_STORE_ATTR",
[_STORE_ATTR_r20] = "_STORE_ATTR_r20",
[_STORE_ATTR_INSTANCE_VALUE] = "_STORE_ATTR_INSTANCE_VALUE",
- [_STORE_ATTR_INSTANCE_VALUE_r20] = "_STORE_ATTR_INSTANCE_VALUE_r20",
+ [_STORE_ATTR_INSTANCE_VALUE_r21] = "_STORE_ATTR_INSTANCE_VALUE_r21",
+ [_STORE_ATTR_INSTANCE_VALUE_NULL] = "_STORE_ATTR_INSTANCE_VALUE_NULL",
+ [_STORE_ATTR_INSTANCE_VALUE_NULL_r01] = "_STORE_ATTR_INSTANCE_VALUE_NULL_r01",
+ [_STORE_ATTR_INSTANCE_VALUE_NULL_r11] = "_STORE_ATTR_INSTANCE_VALUE_NULL_r11",
+ [_STORE_ATTR_INSTANCE_VALUE_NULL_r21] = "_STORE_ATTR_INSTANCE_VALUE_NULL_r21",
+ [_STORE_ATTR_INSTANCE_VALUE_NULL_r32] = "_STORE_ATTR_INSTANCE_VALUE_NULL_r32",
[_STORE_ATTR_SLOT] = "_STORE_ATTR_SLOT",
- [_STORE_ATTR_SLOT_r20] = "_STORE_ATTR_SLOT_r20",
+ [_STORE_ATTR_SLOT_r21] = "_STORE_ATTR_SLOT_r21",
+ [_STORE_ATTR_SLOT_NULL] = "_STORE_ATTR_SLOT_NULL",
+ [_STORE_ATTR_SLOT_NULL_r01] = "_STORE_ATTR_SLOT_NULL_r01",
+ [_STORE_ATTR_SLOT_NULL_r11] = "_STORE_ATTR_SLOT_NULL_r11",
+ [_STORE_ATTR_SLOT_NULL_r21] = "_STORE_ATTR_SLOT_NULL_r21",
+ [_STORE_ATTR_SLOT_NULL_r32] = "_STORE_ATTR_SLOT_NULL_r32",
[_STORE_ATTR_WITH_HINT] = "_STORE_ATTR_WITH_HINT",
- [_STORE_ATTR_WITH_HINT_r20] = "_STORE_ATTR_WITH_HINT_r20",
+ [_STORE_ATTR_WITH_HINT_r21] = "_STORE_ATTR_WITH_HINT_r21",
[_STORE_DEREF] = "_STORE_DEREF",
[_STORE_DEREF_r10] = "_STORE_DEREF_r10",
- [_STORE_FAST] = "_STORE_FAST",
- [_STORE_FAST_r10] = "_STORE_FAST_r10",
- [_STORE_FAST_0] = "_STORE_FAST_0",
- [_STORE_FAST_0_r10] = "_STORE_FAST_0_r10",
- [_STORE_FAST_1] = "_STORE_FAST_1",
- [_STORE_FAST_1_r10] = "_STORE_FAST_1_r10",
- [_STORE_FAST_2] = "_STORE_FAST_2",
- [_STORE_FAST_2_r10] = "_STORE_FAST_2_r10",
- [_STORE_FAST_3] = "_STORE_FAST_3",
- [_STORE_FAST_3_r10] = "_STORE_FAST_3_r10",
- [_STORE_FAST_4] = "_STORE_FAST_4",
- [_STORE_FAST_4_r10] = "_STORE_FAST_4_r10",
- [_STORE_FAST_5] = "_STORE_FAST_5",
- [_STORE_FAST_5_r10] = "_STORE_FAST_5_r10",
- [_STORE_FAST_6] = "_STORE_FAST_6",
- [_STORE_FAST_6_r10] = "_STORE_FAST_6_r10",
- [_STORE_FAST_7] = "_STORE_FAST_7",
- [_STORE_FAST_7_r10] = "_STORE_FAST_7_r10",
[_STORE_GLOBAL] = "_STORE_GLOBAL",
[_STORE_GLOBAL_r10] = "_STORE_GLOBAL_r10",
[_STORE_NAME] = "_STORE_NAME",
@@ -4867,9 +5287,9 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
[_STORE_SUBSCR] = "_STORE_SUBSCR",
[_STORE_SUBSCR_r30] = "_STORE_SUBSCR_r30",
[_STORE_SUBSCR_DICT] = "_STORE_SUBSCR_DICT",
- [_STORE_SUBSCR_DICT_r30] = "_STORE_SUBSCR_DICT_r30",
+ [_STORE_SUBSCR_DICT_r31] = "_STORE_SUBSCR_DICT_r31",
[_STORE_SUBSCR_LIST_INT] = "_STORE_SUBSCR_LIST_INT",
- [_STORE_SUBSCR_LIST_INT_r30] = "_STORE_SUBSCR_LIST_INT_r30",
+ [_STORE_SUBSCR_LIST_INT_r32] = "_STORE_SUBSCR_LIST_INT_r32",
[_SWAP] = "_SWAP",
[_SWAP_r11] = "_SWAP_r11",
[_SWAP_2] = "_SWAP_2",
@@ -4882,6 +5302,51 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
[_SWAP_3_r13] = "_SWAP_3_r13",
[_SWAP_3_r23] = "_SWAP_3_r23",
[_SWAP_3_r33] = "_SWAP_3_r33",
+ [_SWAP_FAST] = "_SWAP_FAST",
+ [_SWAP_FAST_r01] = "_SWAP_FAST_r01",
+ [_SWAP_FAST_r11] = "_SWAP_FAST_r11",
+ [_SWAP_FAST_r22] = "_SWAP_FAST_r22",
+ [_SWAP_FAST_r33] = "_SWAP_FAST_r33",
+ [_SWAP_FAST_0] = "_SWAP_FAST_0",
+ [_SWAP_FAST_0_r01] = "_SWAP_FAST_0_r01",
+ [_SWAP_FAST_0_r11] = "_SWAP_FAST_0_r11",
+ [_SWAP_FAST_0_r22] = "_SWAP_FAST_0_r22",
+ [_SWAP_FAST_0_r33] = "_SWAP_FAST_0_r33",
+ [_SWAP_FAST_1] = "_SWAP_FAST_1",
+ [_SWAP_FAST_1_r01] = "_SWAP_FAST_1_r01",
+ [_SWAP_FAST_1_r11] = "_SWAP_FAST_1_r11",
+ [_SWAP_FAST_1_r22] = "_SWAP_FAST_1_r22",
+ [_SWAP_FAST_1_r33] = "_SWAP_FAST_1_r33",
+ [_SWAP_FAST_2] = "_SWAP_FAST_2",
+ [_SWAP_FAST_2_r01] = "_SWAP_FAST_2_r01",
+ [_SWAP_FAST_2_r11] = "_SWAP_FAST_2_r11",
+ [_SWAP_FAST_2_r22] = "_SWAP_FAST_2_r22",
+ [_SWAP_FAST_2_r33] = "_SWAP_FAST_2_r33",
+ [_SWAP_FAST_3] = "_SWAP_FAST_3",
+ [_SWAP_FAST_3_r01] = "_SWAP_FAST_3_r01",
+ [_SWAP_FAST_3_r11] = "_SWAP_FAST_3_r11",
+ [_SWAP_FAST_3_r22] = "_SWAP_FAST_3_r22",
+ [_SWAP_FAST_3_r33] = "_SWAP_FAST_3_r33",
+ [_SWAP_FAST_4] = "_SWAP_FAST_4",
+ [_SWAP_FAST_4_r01] = "_SWAP_FAST_4_r01",
+ [_SWAP_FAST_4_r11] = "_SWAP_FAST_4_r11",
+ [_SWAP_FAST_4_r22] = "_SWAP_FAST_4_r22",
+ [_SWAP_FAST_4_r33] = "_SWAP_FAST_4_r33",
+ [_SWAP_FAST_5] = "_SWAP_FAST_5",
+ [_SWAP_FAST_5_r01] = "_SWAP_FAST_5_r01",
+ [_SWAP_FAST_5_r11] = "_SWAP_FAST_5_r11",
+ [_SWAP_FAST_5_r22] = "_SWAP_FAST_5_r22",
+ [_SWAP_FAST_5_r33] = "_SWAP_FAST_5_r33",
+ [_SWAP_FAST_6] = "_SWAP_FAST_6",
+ [_SWAP_FAST_6_r01] = "_SWAP_FAST_6_r01",
+ [_SWAP_FAST_6_r11] = "_SWAP_FAST_6_r11",
+ [_SWAP_FAST_6_r22] = "_SWAP_FAST_6_r22",
+ [_SWAP_FAST_6_r33] = "_SWAP_FAST_6_r33",
+ [_SWAP_FAST_7] = "_SWAP_FAST_7",
+ [_SWAP_FAST_7_r01] = "_SWAP_FAST_7_r01",
+ [_SWAP_FAST_7_r11] = "_SWAP_FAST_7_r11",
+ [_SWAP_FAST_7_r22] = "_SWAP_FAST_7_r22",
+ [_SWAP_FAST_7_r33] = "_SWAP_FAST_7_r33",
[_TIER2_RESUME_CHECK] = "_TIER2_RESUME_CHECK",
[_TIER2_RESUME_CHECK_r00] = "_TIER2_RESUME_CHECK_r00",
[_TIER2_RESUME_CHECK_r11] = "_TIER2_RESUME_CHECK_r11",
@@ -4895,20 +5360,26 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
[_TO_BOOL_BOOL_r22] = "_TO_BOOL_BOOL_r22",
[_TO_BOOL_BOOL_r33] = "_TO_BOOL_BOOL_r33",
[_TO_BOOL_INT] = "_TO_BOOL_INT",
- [_TO_BOOL_INT_r11] = "_TO_BOOL_INT_r11",
+ [_TO_BOOL_INT_r02] = "_TO_BOOL_INT_r02",
+ [_TO_BOOL_INT_r12] = "_TO_BOOL_INT_r12",
+ [_TO_BOOL_INT_r23] = "_TO_BOOL_INT_r23",
[_TO_BOOL_LIST] = "_TO_BOOL_LIST",
- [_TO_BOOL_LIST_r11] = "_TO_BOOL_LIST_r11",
+ [_TO_BOOL_LIST_r02] = "_TO_BOOL_LIST_r02",
+ [_TO_BOOL_LIST_r12] = "_TO_BOOL_LIST_r12",
+ [_TO_BOOL_LIST_r23] = "_TO_BOOL_LIST_r23",
[_TO_BOOL_NONE] = "_TO_BOOL_NONE",
[_TO_BOOL_NONE_r01] = "_TO_BOOL_NONE_r01",
[_TO_BOOL_NONE_r11] = "_TO_BOOL_NONE_r11",
[_TO_BOOL_NONE_r22] = "_TO_BOOL_NONE_r22",
[_TO_BOOL_NONE_r33] = "_TO_BOOL_NONE_r33",
[_TO_BOOL_STR] = "_TO_BOOL_STR",
- [_TO_BOOL_STR_r11] = "_TO_BOOL_STR_r11",
+ [_TO_BOOL_STR_r02] = "_TO_BOOL_STR_r02",
+ [_TO_BOOL_STR_r12] = "_TO_BOOL_STR_r12",
+ [_TO_BOOL_STR_r23] = "_TO_BOOL_STR_r23",
[_UNARY_INVERT] = "_UNARY_INVERT",
- [_UNARY_INVERT_r11] = "_UNARY_INVERT_r11",
+ [_UNARY_INVERT_r12] = "_UNARY_INVERT_r12",
[_UNARY_NEGATIVE] = "_UNARY_NEGATIVE",
- [_UNARY_NEGATIVE_r11] = "_UNARY_NEGATIVE_r11",
+ [_UNARY_NEGATIVE_r12] = "_UNARY_NEGATIVE_r12",
[_UNARY_NOT] = "_UNARY_NOT",
[_UNARY_NOT_r01] = "_UNARY_NOT_r01",
[_UNARY_NOT_r11] = "_UNARY_NOT_r11",
@@ -4992,23 +5463,23 @@ int _PyUop_num_popped(int opcode, int oparg)
return 0;
case _LOAD_SMALL_INT:
return 0;
- case _STORE_FAST_0:
+ case _SWAP_FAST_0:
return 1;
- case _STORE_FAST_1:
+ case _SWAP_FAST_1:
return 1;
- case _STORE_FAST_2:
+ case _SWAP_FAST_2:
return 1;
- case _STORE_FAST_3:
+ case _SWAP_FAST_3:
return 1;
- case _STORE_FAST_4:
+ case _SWAP_FAST_4:
return 1;
- case _STORE_FAST_5:
+ case _SWAP_FAST_5:
return 1;
- case _STORE_FAST_6:
+ case _SWAP_FAST_6:
return 1;
- case _STORE_FAST_7:
+ case _SWAP_FAST_7:
return 1;
- case _STORE_FAST:
+ case _SWAP_FAST:
return 1;
case _POP_TOP:
return 1;
@@ -5050,6 +5521,8 @@ int _PyUop_num_popped(int opcode, int oparg)
return 1;
case _TO_BOOL_NONE:
return 1;
+ case _GUARD_NOS_COMPACT_ASCII:
+ return 0;
case _GUARD_NOS_UNICODE:
return 0;
case _GUARD_TOS_UNICODE:
@@ -5084,12 +5557,6 @@ int _PyUop_num_popped(int opcode, int oparg)
return 2;
case _BINARY_OP_SUBTRACT_FLOAT:
return 2;
- case _BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS:
- return 2;
- case _BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS:
- return 2;
- case _BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS:
- return 2;
case _BINARY_OP_ADD_UNICODE:
return 2;
case _BINARY_OP_INPLACE_ADD_UNICODE:
@@ -5108,10 +5575,14 @@ int _PyUop_num_popped(int opcode, int oparg)
return 2;
case _BINARY_OP_SUBSCR_STR_INT:
return 2;
+ case _BINARY_OP_SUBSCR_USTR_INT:
+ return 2;
case _GUARD_NOS_TUPLE:
return 0;
case _GUARD_TOS_TUPLE:
return 0;
+ case _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS:
+ return 0;
case _BINARY_OP_SUBSCR_TUPLE_INT:
return 2;
case _GUARD_NOS_DICT:
@@ -5264,10 +5735,14 @@ int _PyUop_num_popped(int opcode, int oparg)
return 0;
case _STORE_ATTR_INSTANCE_VALUE:
return 2;
+ case _STORE_ATTR_INSTANCE_VALUE_NULL:
+ return 2;
case _STORE_ATTR_WITH_HINT:
return 2;
case _STORE_ATTR_SLOT:
return 2;
+ case _STORE_ATTR_SLOT_NULL:
+ return 2;
case _COMPARE_OP:
return 2;
case _COMPARE_OP_FLOAT:
@@ -5466,6 +5941,14 @@ int _PyUop_num_popped(int opcode, int oparg)
return 3 + oparg;
case _MAKE_CALLARGS_A_TUPLE:
return 0;
+ case _CHECK_IS_PY_CALLABLE_EX:
+ return 0;
+ case _PY_FRAME_EX:
+ return 4;
+ case _CHECK_IS_NOT_PY_CALLABLE_EX:
+ return 0;
+ case _CALL_FUNCTION_EX_NON_PY_GENERAL:
+ return 4;
case _MAKE_FUNCTION:
return 1;
case _SET_FUNCTION_ATTRIBUTE:
@@ -5500,6 +5983,26 @@ int _PyUop_num_popped(int opcode, int oparg)
return 1;
case _GUARD_IS_FALSE_POP:
return 1;
+ case _GUARD_BIT_IS_SET_POP_4:
+ return 1;
+ case _GUARD_BIT_IS_SET_POP_5:
+ return 1;
+ case _GUARD_BIT_IS_SET_POP_6:
+ return 1;
+ case _GUARD_BIT_IS_SET_POP_7:
+ return 1;
+ case _GUARD_BIT_IS_SET_POP:
+ return 1;
+ case _GUARD_BIT_IS_UNSET_POP_4:
+ return 1;
+ case _GUARD_BIT_IS_UNSET_POP_5:
+ return 1;
+ case _GUARD_BIT_IS_UNSET_POP_6:
+ return 1;
+ case _GUARD_BIT_IS_UNSET_POP_7:
+ return 1;
+ case _GUARD_BIT_IS_UNSET_POP:
+ return 1;
case _GUARD_IS_NONE_POP:
return 1;
case _GUARD_IS_NOT_NONE_POP:
@@ -5538,6 +6041,16 @@ int _PyUop_num_popped(int opcode, int oparg)
return 2;
case _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW:
return 3;
+ case _INSERT_1_LOAD_CONST_INLINE:
+ return 1;
+ case _INSERT_1_LOAD_CONST_INLINE_BORROW:
+ return 1;
+ case _INSERT_2_LOAD_CONST_INLINE_BORROW:
+ return 2;
+ case _SHUFFLE_2_LOAD_CONST_INLINE_BORROW:
+ return 3;
+ case _SHUFFLE_3_LOAD_CONST_INLINE_BORROW:
+ return 3;
case _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW:
return 4;
case _LOAD_CONST_UNDER_INLINE:
diff --git a/Include/longobject.h b/Include/longobject.h
index 19f06977036d05..38673bc18785fa 100644
--- a/Include/longobject.h
+++ b/Include/longobject.h
@@ -166,6 +166,44 @@ PyAPI_FUNC(PyObject *) PyLong_FromString(const char *, char **, int);
PyAPI_FUNC(unsigned long) PyOS_strtoul(const char *, char **, int);
PyAPI_FUNC(long) PyOS_strtol(const char *, char **, int);
+/* --- Import/Export API -------------------------------------------------- */
+
+typedef struct PyLongLayout {
+ uint8_t bits_per_digit;
+ uint8_t digit_size;
+ int8_t digits_order;
+ int8_t digit_endianness;
+} PyLongLayout;
+
+PyAPI_FUNC(const PyLongLayout*) PyLong_GetNativeLayout(void);
+
+typedef struct PyLongExport {
+ int64_t value;
+ uint8_t negative;
+ Py_ssize_t ndigits;
+ const void *digits;
+ // Member used internally, must not be used for other purpose.
+ Py_uintptr_t _reserved;
+} PyLongExport;
+
+PyAPI_FUNC(int) PyLong_Export(
+ PyObject *obj,
+ PyLongExport *export_long);
+PyAPI_FUNC(void) PyLong_FreeExport(
+ PyLongExport *export_long);
+
+
+/* --- PyLongWriter API --------------------------------------------------- */
+
+typedef struct PyLongWriter PyLongWriter;
+
+PyAPI_FUNC(PyLongWriter*) PyLongWriter_Create(
+ int negative,
+ Py_ssize_t ndigits,
+ void **digits);
+PyAPI_FUNC(PyObject*) PyLongWriter_Finish(PyLongWriter *writer);
+PyAPI_FUNC(void) PyLongWriter_Discard(PyLongWriter *writer);
+
#ifndef Py_LIMITED_API
# define Py_CPYTHON_LONGOBJECT_H
# include "cpython/longobject.h"
diff --git a/Include/moduleobject.h b/Include/moduleobject.h
index e83bc395aa4618..d1dde7982ad50d 100644
--- a/Include/moduleobject.h
+++ b/Include/moduleobject.h
@@ -118,11 +118,11 @@ PyAPI_FUNC(int) PyUnstable_Module_SetGIL(PyObject *module, void *gil);
#endif
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= _Py_PACK_VERSION(3, 15)
-PyAPI_FUNC(PyObject *) PyModule_FromSlotsAndSpec(const PyModuleDef_Slot *,
+PyAPI_FUNC(PyObject *) PyModule_FromSlotsAndSpec(const PyModuleDef_Slot *slots,
PyObject *spec);
-PyAPI_FUNC(int) PyModule_Exec(PyObject *mod);
-PyAPI_FUNC(int) PyModule_GetStateSize(PyObject *mod, Py_ssize_t *result);
-PyAPI_FUNC(int) PyModule_GetToken(PyObject *, void **result);
+PyAPI_FUNC(int) PyModule_Exec(PyObject *module);
+PyAPI_FUNC(int) PyModule_GetStateSize(PyObject *module, Py_ssize_t *result);
+PyAPI_FUNC(int) PyModule_GetToken(PyObject *module, void **result);
#endif
#ifndef _Py_OPAQUE_PYOBJECT
diff --git a/Include/opcode_ids.h b/Include/opcode_ids.h
index 0d066c169019a7..c46368444f4c59 100644
--- a/Include/opcode_ids.h
+++ b/Include/opcode_ids.h
@@ -144,75 +144,78 @@ extern "C" {
#define BINARY_OP_SUBSCR_LIST_SLICE 138
#define BINARY_OP_SUBSCR_STR_INT 139
#define BINARY_OP_SUBSCR_TUPLE_INT 140
-#define BINARY_OP_SUBTRACT_FLOAT 141
-#define BINARY_OP_SUBTRACT_INT 142
-#define CALL_ALLOC_AND_ENTER_INIT 143
-#define CALL_BOUND_METHOD_EXACT_ARGS 144
-#define CALL_BOUND_METHOD_GENERAL 145
-#define CALL_BUILTIN_CLASS 146
-#define CALL_BUILTIN_FAST 147
-#define CALL_BUILTIN_FAST_WITH_KEYWORDS 148
-#define CALL_BUILTIN_O 149
-#define CALL_ISINSTANCE 150
-#define CALL_KW_BOUND_METHOD 151
-#define CALL_KW_NON_PY 152
-#define CALL_KW_PY 153
-#define CALL_LEN 154
-#define CALL_LIST_APPEND 155
-#define CALL_METHOD_DESCRIPTOR_FAST 156
-#define CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 157
-#define CALL_METHOD_DESCRIPTOR_NOARGS 158
-#define CALL_METHOD_DESCRIPTOR_O 159
-#define CALL_NON_PY_GENERAL 160
-#define CALL_PY_EXACT_ARGS 161
-#define CALL_PY_GENERAL 162
-#define CALL_STR_1 163
-#define CALL_TUPLE_1 164
-#define CALL_TYPE_1 165
-#define COMPARE_OP_FLOAT 166
-#define COMPARE_OP_INT 167
-#define COMPARE_OP_STR 168
-#define CONTAINS_OP_DICT 169
-#define CONTAINS_OP_SET 170
-#define FOR_ITER_GEN 171
-#define FOR_ITER_LIST 172
-#define FOR_ITER_RANGE 173
-#define FOR_ITER_TUPLE 174
-#define JUMP_BACKWARD_JIT 175
-#define JUMP_BACKWARD_NO_JIT 176
-#define LOAD_ATTR_CLASS 177
-#define LOAD_ATTR_CLASS_WITH_METACLASS_CHECK 178
-#define LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN 179
-#define LOAD_ATTR_INSTANCE_VALUE 180
-#define LOAD_ATTR_METHOD_LAZY_DICT 181
-#define LOAD_ATTR_METHOD_NO_DICT 182
-#define LOAD_ATTR_METHOD_WITH_VALUES 183
-#define LOAD_ATTR_MODULE 184
-#define LOAD_ATTR_NONDESCRIPTOR_NO_DICT 185
-#define LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 186
-#define LOAD_ATTR_PROPERTY 187
-#define LOAD_ATTR_SLOT 188
-#define LOAD_ATTR_WITH_HINT 189
-#define LOAD_GLOBAL_BUILTIN 190
-#define LOAD_GLOBAL_MODULE 191
-#define LOAD_SUPER_ATTR_ATTR 192
-#define LOAD_SUPER_ATTR_METHOD 193
-#define RESUME_CHECK 194
-#define SEND_GEN 195
-#define STORE_ATTR_INSTANCE_VALUE 196
-#define STORE_ATTR_SLOT 197
-#define STORE_ATTR_WITH_HINT 198
-#define STORE_SUBSCR_DICT 199
-#define STORE_SUBSCR_LIST_INT 200
-#define TO_BOOL_ALWAYS_TRUE 201
-#define TO_BOOL_BOOL 202
-#define TO_BOOL_INT 203
-#define TO_BOOL_LIST 204
-#define TO_BOOL_NONE 205
-#define TO_BOOL_STR 206
-#define UNPACK_SEQUENCE_LIST 207
-#define UNPACK_SEQUENCE_TUPLE 208
-#define UNPACK_SEQUENCE_TWO_TUPLE 209
+#define BINARY_OP_SUBSCR_USTR_INT 141
+#define BINARY_OP_SUBTRACT_FLOAT 142
+#define BINARY_OP_SUBTRACT_INT 143
+#define CALL_ALLOC_AND_ENTER_INIT 144
+#define CALL_BOUND_METHOD_EXACT_ARGS 145
+#define CALL_BOUND_METHOD_GENERAL 146
+#define CALL_BUILTIN_CLASS 147
+#define CALL_BUILTIN_FAST 148
+#define CALL_BUILTIN_FAST_WITH_KEYWORDS 149
+#define CALL_BUILTIN_O 150
+#define CALL_EX_NON_PY_GENERAL 151
+#define CALL_EX_PY 152
+#define CALL_ISINSTANCE 153
+#define CALL_KW_BOUND_METHOD 154
+#define CALL_KW_NON_PY 155
+#define CALL_KW_PY 156
+#define CALL_LEN 157
+#define CALL_LIST_APPEND 158
+#define CALL_METHOD_DESCRIPTOR_FAST 159
+#define CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 160
+#define CALL_METHOD_DESCRIPTOR_NOARGS 161
+#define CALL_METHOD_DESCRIPTOR_O 162
+#define CALL_NON_PY_GENERAL 163
+#define CALL_PY_EXACT_ARGS 164
+#define CALL_PY_GENERAL 165
+#define CALL_STR_1 166
+#define CALL_TUPLE_1 167
+#define CALL_TYPE_1 168
+#define COMPARE_OP_FLOAT 169
+#define COMPARE_OP_INT 170
+#define COMPARE_OP_STR 171
+#define CONTAINS_OP_DICT 172
+#define CONTAINS_OP_SET 173
+#define FOR_ITER_GEN 174
+#define FOR_ITER_LIST 175
+#define FOR_ITER_RANGE 176
+#define FOR_ITER_TUPLE 177
+#define JUMP_BACKWARD_JIT 178
+#define JUMP_BACKWARD_NO_JIT 179
+#define LOAD_ATTR_CLASS 180
+#define LOAD_ATTR_CLASS_WITH_METACLASS_CHECK 181
+#define LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN 182
+#define LOAD_ATTR_INSTANCE_VALUE 183
+#define LOAD_ATTR_METHOD_LAZY_DICT 184
+#define LOAD_ATTR_METHOD_NO_DICT 185
+#define LOAD_ATTR_METHOD_WITH_VALUES 186
+#define LOAD_ATTR_MODULE 187
+#define LOAD_ATTR_NONDESCRIPTOR_NO_DICT 188
+#define LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 189
+#define LOAD_ATTR_PROPERTY 190
+#define LOAD_ATTR_SLOT 191
+#define LOAD_ATTR_WITH_HINT 192
+#define LOAD_GLOBAL_BUILTIN 193
+#define LOAD_GLOBAL_MODULE 194
+#define LOAD_SUPER_ATTR_ATTR 195
+#define LOAD_SUPER_ATTR_METHOD 196
+#define RESUME_CHECK 197
+#define SEND_GEN 198
+#define STORE_ATTR_INSTANCE_VALUE 199
+#define STORE_ATTR_SLOT 200
+#define STORE_ATTR_WITH_HINT 201
+#define STORE_SUBSCR_DICT 202
+#define STORE_SUBSCR_LIST_INT 203
+#define TO_BOOL_ALWAYS_TRUE 204
+#define TO_BOOL_BOOL 205
+#define TO_BOOL_INT 206
+#define TO_BOOL_LIST 207
+#define TO_BOOL_NONE 208
+#define TO_BOOL_STR 209
+#define UNPACK_SEQUENCE_LIST 210
+#define UNPACK_SEQUENCE_TUPLE 211
+#define UNPACK_SEQUENCE_TWO_TUPLE 212
#define INSTRUMENTED_END_FOR 233
#define INSTRUMENTED_POP_ITER 234
#define INSTRUMENTED_END_SEND 235
diff --git a/Include/patchlevel.h b/Include/patchlevel.h
index 804aa1a0427ba9..ea42c123116959 100644
--- a/Include/patchlevel.h
+++ b/Include/patchlevel.h
@@ -24,10 +24,10 @@
#define PY_MINOR_VERSION 15
#define PY_MICRO_VERSION 0
#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA
-#define PY_RELEASE_SERIAL 2
+#define PY_RELEASE_SERIAL 5
/* Version as a string */
-#define PY_VERSION "3.15.0a2+"
+#define PY_VERSION "3.15.0a5+"
/*--end constants--*/
diff --git a/InternalDocs/README.md b/InternalDocs/README.md
index 06f67b3cfc124a..3e8ab442315753 100644
--- a/InternalDocs/README.md
+++ b/InternalDocs/README.md
@@ -11,6 +11,11 @@ it is not, please report that through the
[issue tracker](https://github.com/python/cpython/issues).
+General Resources
+---
+
+- [Source Code Structure](structure.md)
+
Compiling Python Source Code
---
@@ -29,8 +34,6 @@ Runtime Objects
- [Frames](frames.md)
-- [String Interning](string_interning.md)
-
Program Execution
---
@@ -48,6 +51,14 @@ Program Execution
- [Stack protection](stack_protection.md)
+Built-in Types
+---
+
+- [String Interning](string_interning.md)
+
+- [List sort algorithm](../Objects/listsort.txt)
+
+
Modules
---
diff --git a/InternalDocs/interpreter.md b/InternalDocs/interpreter.md
index 38e9f6fced6088..75acdf596a7f30 100644
--- a/InternalDocs/interpreter.md
+++ b/InternalDocs/interpreter.md
@@ -226,10 +226,11 @@ Up through 3.10, the call stack was implemented as a singly-linked list of
heap allocation for the stack frame.
Since 3.11, frames are no longer fully-fledged objects. Instead, a leaner internal
-`_PyInterpreterFrame` structure is used, which is allocated using a custom allocator
-function (`_PyThreadState_BumpFramePointer()`), which allocates and initializes a
-frame structure. Usually a frame allocation is just a pointer bump, which improves
-memory locality.
+`_PyInterpreterFrame` structure is used. Most frames are allocated contiguously in a
+per-thread stack (see `_PyThreadState_PushFrame` in [Python/pystate.c](../Python/pystate.c)),
+which improves memory locality and reduces overhead.
+If the current `datastack_chunk` has enough space (`_PyThreadState_HasStackSpace`)
+then the lightweight `_PyFrame_PushUnchecked` can be used instead of `_PyThreadState_PushFrame`.
Sometimes an actual `PyFrameObject` is needed, such as when Python code calls
`sys._getframe()` or an extension module calls
diff --git a/InternalDocs/profiling_binary_format.md b/InternalDocs/profiling_binary_format.md
new file mode 100644
index 00000000000000..7e4592a0d89705
--- /dev/null
+++ b/InternalDocs/profiling_binary_format.md
@@ -0,0 +1,541 @@
+# Profiling Binary Format
+
+The profiling module includes a binary file format for storing sampling
+profiler data. This document describes the format's structure and the
+design decisions behind it.
+
+The implementation is in
+[`Modules/_remote_debugging/binary_io_writer.c`](../Modules/_remote_debugging/binary_io_writer.c)
+and [`Modules/_remote_debugging/binary_io_reader.c`](../Modules/_remote_debugging/binary_io_reader.c),
+with declarations in
+[`Modules/_remote_debugging/binary_io.h`](../Modules/_remote_debugging/binary_io.h).
+
+## Overview
+
+The sampling profiler can generate enormous amounts of data. A typical
+profiling session sampling at 1000 Hz for 60 seconds produces 60,000 samples.
+Each sample contains a full call stack, often 20-50 frames deep, and each
+frame includes a filename, function name, and line number. In a text-based
+format like collapsed stacks, this would mean repeating the same long file
+paths and function names thousands of times.
+
+The binary format addresses this through two key strategies:
+
+1. **Deduplication**: Strings and frames are stored once in lookup tables,
+ then referenced by small integer indices. A 100-character file path that
+ appears in 50,000 samples is stored once, not 50,000 times.
+
+2. **Compact encoding**: Variable-length integers (varints) encode small
+ values in fewer bytes. Since most indices are small (under 128), they
+ typically need only one byte instead of four.
+
+Together with optional zstd compression, these techniques reduce file sizes
+by 10-50x compared to text formats while also enabling faster I/O.
+
+## File Layout
+
+The file consists of five sections:
+
+```
++------------------+ Offset 0
+| Header | 64 bytes (fixed)
++------------------+ Offset 64
+| |
+| Sample Data | Variable size (optionally compressed)
+| |
++------------------+ string_table_offset
+| String Table | Variable size
++------------------+ frame_table_offset
+| Frame Table | Variable size
++------------------+ file_size - 32
+| Footer | 32 bytes (fixed)
++------------------+ file_size
+```
+
+The layout is designed for streaming writes during profiling. The profiler
+cannot know in advance how many unique strings or frames will be encountered,
+so these tables must be built incrementally and written at the end.
+
+The header comes first so readers can quickly validate the file and locate
+the metadata tables. The sample data follows immediately, allowing the writer
+to stream samples directly to disk (or through a compression stream) without
+buffering the entire dataset in memory.
+
+The string and frame tables are placed after sample data because they grow
+as new unique entries are discovered during profiling. By deferring their
+output until finalization, the writer avoids the complexity of reserving
+space or rewriting portions of the file.
+
+The footer at the end contains counts needed to allocate arrays before
+parsing the tables. Placing it at a fixed offset from the end (rather than
+at a variable offset recorded in the header) means readers can locate it
+with a single seek to `file_size - 32`, without first reading the header.
+
+## Header
+
+```
+ Offset Size Type Description
++--------+------+---------+----------------------------------------+
+| 0 | 4 | uint32 | Magic number (0x54414348 = "TACH") |
+| 4 | 4 | uint32 | Format version |
+| 8 | 4 | bytes | Python version (major, minor, micro, |
+| | | | reserved) |
+| 12 | 8 | uint64 | Start timestamp (microseconds) |
+| 20 | 8 | uint64 | Sample interval (microseconds) |
+| 28 | 4 | uint32 | Total sample count |
+| 32 | 4 | uint32 | Thread count |
+| 36 | 8 | uint64 | String table offset |
+| 44 | 8 | uint64 | Frame table offset |
+| 52 | 4 | uint32 | Compression type (0=none, 1=zstd) |
+| 56 | 8 | bytes | Reserved (zero-filled) |
++--------+------+---------+----------------------------------------+
+```
+
+The magic number `0x54414348` ("TACH" for Tachyon) identifies the file format
+and also serves as an **endianness marker**. When read on a system with
+different byte order than the writer, it appears as `0x48434154`. The reader
+uses this to detect cross-endian files and automatically byte-swap all
+multi-byte integer fields.
+
+The Python version field records the major, minor, and micro version numbers
+of the Python interpreter that generated the file. This allows analysis tools
+to detect version mismatches when replaying data collected on a different
+Python version, which may have different internal structures or behaviors.
+
+The header is written as zeros initially, then overwritten with actual values
+during finalization. This requires the output stream to be seekable, which
+is acceptable since the format targets regular files rather than pipes or
+network streams.
+
+## Sample Data
+
+Sample data begins at offset 64 and extends to `string_table_offset`. Samples
+use delta compression to minimize redundancy when consecutive samples from the
+same thread have identical or similar call stacks.
+
+### Stack Encoding Types
+
+Each sample record begins with thread identification, then an encoding byte:
+
+| Code | Name | Description |
+|------|------|-------------|
+| 0x00 | REPEAT | RLE: identical stack repeated N times |
+| 0x01 | FULL | Complete stack (first sample or no match) |
+| 0x02 | SUFFIX | Shares N frames from bottom of previous stack |
+| 0x03 | POP_PUSH | Remove M frames from top, add N new frames |
+
+### Record Formats
+
+**REPEAT (0x00) - Run-Length Encoded Identical Stacks:**
+```
++-----------------+-----------+----------------------------------------+
+| thread_id | 8 bytes | Thread identifier (uint64, fixed) |
+| interpreter_id | 4 bytes | Interpreter ID (uint32, fixed) |
+| encoding | 1 byte | 0x00 (REPEAT) |
+| count | varint | Number of samples in this RLE group |
+| samples | varies | Interleaved: [delta: varint, status: 1]|
+| | | repeated count times |
++-----------------+-----------+----------------------------------------+
+```
+The stack is inherited from this thread's previous sample. Each sample in the
+group gets its own timestamp delta and status byte, stored as interleaved pairs
+(delta1, status1, delta2, status2, ...) rather than separate arrays.
+
+**FULL (0x01) - Complete Stack:**
+```
++-----------------+-----------+----------------------------------------+
+| thread_id | 8 bytes | Thread identifier (uint64, fixed) |
+| interpreter_id | 4 bytes | Interpreter ID (uint32, fixed) |
+| encoding | 1 byte | 0x01 (FULL) |
+| timestamp_delta | varint | Microseconds since thread's last sample|
+| status | 1 byte | Thread state flags |
+| stack_depth | varint | Number of frames in call stack |
+| frame_indices | varint[] | Array of frame table indices |
++-----------------+-----------+----------------------------------------+
+```
+Used for the first sample from a thread, or when delta encoding would not
+provide savings.
+
+**SUFFIX (0x02) - Shared Suffix Match:**
+```
++-----------------+-----------+----------------------------------------+
+| thread_id | 8 bytes | Thread identifier (uint64, fixed) |
+| interpreter_id | 4 bytes | Interpreter ID (uint32, fixed) |
+| encoding | 1 byte | 0x02 (SUFFIX) |
+| timestamp_delta | varint | Microseconds since thread's last sample|
+| status | 1 byte | Thread state flags |
+| shared_count | varint | Frames shared from bottom of prev stack|
+| new_count | varint | New frames at top of stack |
+| new_frames | varint[] | Array of new_count frame indices |
++-----------------+-----------+----------------------------------------+
+```
+Used when a function call added frames to the top of the stack. The shared
+frames from the previous stack are kept, and new frames are prepended.
+
+**POP_PUSH (0x03) - Pop and Push:**
+```
++-----------------+-----------+----------------------------------------+
+| thread_id | 8 bytes | Thread identifier (uint64, fixed) |
+| interpreter_id | 4 bytes | Interpreter ID (uint32, fixed) |
+| encoding | 1 byte | 0x03 (POP_PUSH) |
+| timestamp_delta | varint | Microseconds since thread's last sample|
+| status | 1 byte | Thread state flags |
+| pop_count | varint | Frames to remove from top of prev stack|
+| push_count | varint | New frames to add at top |
+| new_frames | varint[] | Array of push_count frame indices |
++-----------------+-----------+----------------------------------------+
+```
+Used when the code path changed: some frames were popped (function returns)
+and new frames were pushed (different function calls).
+
+### Thread and Interpreter Identification
+
+Thread IDs are 64-bit values that can be large (memory addresses on some
+platforms) and vary unpredictably. Using a fixed 8-byte encoding avoids
+the overhead of varint encoding for large values and simplifies parsing
+since the reader knows exactly where each field begins.
+
+The interpreter ID identifies which Python sub-interpreter the thread
+belongs to, allowing analysis tools to separate activity across interpreters
+in processes using multiple sub-interpreters.
+
+### Status Byte
+
+The status byte is a bitfield encoding thread state at sample time:
+
+| Bit | Flag | Meaning |
+|-----|-----------------------|--------------------------------------------|
+| 0 | THREAD_STATUS_HAS_GIL | Thread holds the GIL (Global Interpreter Lock) |
+| 1 | THREAD_STATUS_ON_CPU | Thread is actively running on a CPU core |
+| 2 | THREAD_STATUS_UNKNOWN | Thread state could not be determined |
+| 3 | THREAD_STATUS_GIL_REQUESTED | Thread is waiting to acquire the GIL |
+| 4 | THREAD_STATUS_HAS_EXCEPTION | Thread has a pending exception |
+
+Multiple flags can be set simultaneously (e.g., a thread can hold the GIL
+while also running on CPU). Analysis tools use these to filter samples or
+visualize thread states over time.
+
+### Timestamp Delta Encoding
+
+Timestamps use delta encoding rather than absolute values. Absolute
+timestamps in microseconds require 8 bytes each, but consecutive samples
+from the same thread are typically separated by the sampling interval
+(e.g., 1000 microseconds), so the delta between them is small and fits
+in 1-2 varint bytes. The writer tracks the previous timestamp for each
+thread separately. The first sample from a thread encodes its delta from
+the profiling start time; subsequent samples encode the delta from that
+thread's previous sample. This per-thread tracking is necessary because
+samples are interleaved across threads in arrival order, not grouped by
+thread.
+
+For REPEAT (RLE) records, timestamp deltas and status bytes are stored as
+interleaved pairs (delta, status, delta, status, ...) - one pair per
+repeated sample - allowing efficient batching while preserving the exact
+timing and state of each sample.
+
+### Frame Indexing
+
+Each frame in a call stack is represented by an index into the frame table
+rather than inline data. This provides massive space savings because call
+stacks are highly repetitive: the same function appears in many samples
+(hot functions), call stacks often share common prefixes (main -> app ->
+handler -> ...), and recursive functions create repeated frame sequences.
+A frame index is typically 1-2 varint bytes. Inline frame data would be
+20-200+ bytes (two strings plus a line number). For a profile with 100,000
+samples averaging 30 frames each, this reduces frame data from potentially
+gigabytes to tens of megabytes.
+
+Frame indices are written innermost-first (the currently executing frame
+has index 0 in the array). This ordering works well with delta compression:
+function calls typically add frames at the top (index 0), while shared
+frames remain at the bottom.
+
+## String Table
+
+The string table stores deduplicated UTF-8 strings (filenames and function
+names). It begins at `string_table_offset` and contains entries in order of
+their assignment during writing:
+
+```
++----------------+
+| length: varint |
+| data: bytes |
++----------------+ (repeated for each string)
+```
+
+Strings are stored in the order they were first encountered during writing.
+The first unique filename gets index 0, the second gets index 1, and so on.
+Length-prefixing (rather than null-termination) allows strings containing
+null bytes and enables readers to allocate exact-sized buffers. The varint
+length encoding means short strings (under 128 bytes) need only one length
+byte.
+
+## Frame Table
+
+The frame table stores deduplicated frame entries with full source position
+information and bytecode opcode:
+
+```
++----------------------------+
+| filename_idx: varint |
+| funcname_idx: varint |
+| lineno: svarint |
+| end_lineno_delta: svarint |
+| column: svarint |
+| end_column_delta: svarint |
+| opcode: u8 |
++----------------------------+ (repeated for each frame)
+```
+
+### Field Definitions
+
+| Field | Type | Description |
+|------------------|---------------|----------------------------------------------------------|
+| filename_idx | varint | Index into string table for file name |
+| funcname_idx | varint | Index into string table for function name |
+| lineno | zigzag varint | Start line number (-1 for synthetic frames) |
+| end_lineno_delta | zigzag varint | Delta from lineno (end_lineno = lineno + delta) |
+| column | zigzag varint | Start column offset in UTF-8 bytes (-1 if not available) |
+| end_column_delta | zigzag varint | Delta from column (end_column = column + delta) |
+| opcode | u8 | Python bytecode opcode (0-254) or 255 for None |
+
+### Delta Encoding
+
+Position end values use delta encoding for efficiency:
+
+- `end_lineno = lineno + end_lineno_delta`
+- `end_column = column + end_column_delta`
+
+Typical values:
+- `end_lineno_delta`: Usually 0 (single-line expressions) → encodes to 1 byte
+- `end_column_delta`: Usually 5-20 (expression width) → encodes to 1 byte
+
+This saves ~1-2 bytes per frame compared to absolute encoding. When the base
+value (lineno or column) is -1 (not available), the delta is stored as 0 and
+the reconstructed value is -1.
+
+### Sentinel Values
+
+- `opcode = 255`: No opcode captured
+- `lineno = -1`: Synthetic frame (no source location)
+- `column = -1`: Column offset not available
+
+### Deduplication
+
+Each unique (filename, funcname, lineno, end_lineno, column, end_column,
+opcode) combination gets one entry. This enables instruction-level profiling
+where multiple bytecode instructions on the same line can be distinguished.
+
+Strings and frames are deduplicated separately because they have different
+cardinalities and reference patterns. A codebase might have hundreds of
+unique source files but thousands of unique functions. Many functions share
+the same filename, so storing the filename index in each frame entry (rather
+than the full string) provides an additional layer of deduplication. A frame
+entry is typically 7-9 bytes rather than two full strings plus location data.
+
+### Size Analysis
+
+Typical frame size with delta encoding:
+- file_idx: 1-2 bytes
+- func_idx: 1-2 bytes
+- lineno: 1-2 bytes
+- end_lineno_delta: 1 byte (usually 0)
+- column: 1 byte (usually < 64)
+- end_column_delta: 1 byte (usually < 64)
+- opcode: 1 byte
+
+**Total: ~7-9 bytes per frame**
+
+Line numbers and columns use signed varint (zigzag encoding) to handle
+sentinel values efficiently. Synthetic frames—generated frames that don't
+correspond directly to Python source code, such as C extension boundaries or
+internal interpreter frames—use -1 to indicate the absence of a source
+location. Zigzag encoding ensures these small negative values encode
+efficiently (−1 becomes 1, which is one byte) rather than requiring the
+maximum varint length.
+
+## Footer
+
+```
+ Offset Size Type Description
++--------+------+---------+----------------------------------------+
+| 0 | 4 | uint32 | String count |
+| 4 | 4 | uint32 | Frame count |
+| 8 | 8 | uint64 | Total file size |
+| 16 | 16 | bytes | Checksum (reserved, currently zeros) |
++--------+------+---------+----------------------------------------+
+```
+
+The string and frame counts allow readers to pre-allocate arrays of the
+correct size before parsing the tables. Without these counts, readers would
+need to either scan the tables twice (once to count, once to parse) or use
+dynamically-growing arrays.
+
+The file size field provides a consistency check: if the actual file size
+does not match, the file may be truncated or corrupted.
+
+The checksum field is reserved for future use. A checksum would allow
+detection of corruption but adds complexity and computation cost. The
+current implementation leaves this as zeros.
+
+## Variable-Length Integer Encoding
+
+The format uses LEB128 (Little Endian Base 128) for unsigned integers and
+zigzag + LEB128 for signed integers. These encodings are widely used
+(Protocol Buffers, DWARF debug info, WebAssembly) and well-understood.
+
+### Unsigned Varint (LEB128)
+
+Each byte stores 7 bits of data. The high bit indicates whether more bytes
+follow:
+
+```
+Value Encoded bytes
+0-127 [0xxxxxxx] (1 byte)
+128-16383 [1xxxxxxx] [0xxxxxxx] (2 bytes)
+16384+ [1xxxxxxx] [1xxxxxxx] ... (3+ bytes)
+```
+
+Most indices in profiling data are small. A profile with 1000 unique frames
+needs at most 2 bytes per frame index. The common case (indices under 128)
+needs only 1 byte.
+
+### Signed Varint (Zigzag)
+
+Standard LEB128 encodes −1 as a very large unsigned value, requiring many
+bytes. Zigzag encoding interleaves positive and negative values:
+
+```
+ 0 -> 0 -1 -> 1 1 -> 2 -2 -> 3 2 -> 4
+```
+
+This ensures small-magnitude values (whether positive or negative) encode
+in few bytes.
+
+## Compression
+
+When compression is enabled, the sample data region contains a zstd stream.
+The string table, frame table, and footer remain uncompressed so readers can
+access metadata without decompressing the entire file. A tool that only needs
+to report "this file contains 50,000 samples of 3 threads" can read the header
+and footer without touching the compressed sample data. This also simplifies
+the format: the header's offset fields point directly to the tables rather
+than to positions within a decompressed stream.
+
+Zstd provides an excellent balance of compression ratio and speed. Profiling
+data compresses very well (often 5-10x) due to repetitive patterns: the same
+small set of frame indices appears repeatedly, and delta-encoded timestamps
+cluster around the sampling interval. Zstd's streaming API allows compression
+without buffering the entire dataset. The writer feeds sample data through
+the compressor incrementally, flushing compressed chunks to disk as they
+become available.
+
+Level 5 compression is used as a default. Lower levels (1-3) are faster but
+compress less; higher levels (6+) compress more but slow down writing. Level
+5 provides good compression with minimal impact on profiling overhead.
+
+## Reading and Writing
+
+### Writing
+
+1. Open the output file and write 64 zero bytes as a placeholder header
+2. Initialize empty string and frame dictionaries for deduplication
+3. For each sample:
+ - Intern any new strings, assigning sequential indices
+ - Intern any new frames, assigning sequential indices
+ - Encode the sample record and write to the buffer
+ - Flush the buffer through compression (if enabled) when full
+4. Flush remaining buffered data and finalize compression
+5. Write the string table (length-prefixed strings in index order)
+6. Write the frame table (varint-encoded entries in index order)
+7. Write the footer with final counts
+8. Seek to offset 0 and write the header with actual values
+
+The writer maintains two dictionaries: one mapping strings to indices, one
+mapping (filename_idx, funcname_idx, lineno) tuples to frame indices. These
+enable O(1) lookup during interning.
+
+### Reading
+
+1. Read the header magic number to detect endianness (set `needs_swap` flag
+ if the magic appears byte-swapped)
+2. Validate version and read remaining header fields (byte-swapping if needed)
+3. Seek to end − 32 and read the footer (byte-swapping counts if needed)
+4. Allocate string array of `string_count` elements
+5. Parse the string table, populating the array
+6. Allocate frame array of `frame_count * 3` uint32 elements
+7. Parse the frame table, populating the array
+8. If compressed, decompress the sample data region
+9. Iterate through samples, resolving indices to strings/frames
+ (byte-swapping thread_id and interpreter_id if needed)
+
+The reader builds lookup arrays rather than dictionaries since it only needs
+index-to-value mapping, not value-to-index.
+
+## Platform Considerations
+
+### Byte Ordering and Cross-Platform Portability
+
+The binary format uses **native byte order** for all multi-byte integer
+fields when writing. However, the reader supports **cross-endian reading**:
+files written on a little-endian system (x86, ARM) can be read on a
+big-endian system (s390x, PowerPC), and vice versa.
+
+The magic number doubles as an endianness marker. When read on a system with
+different byte order, it appears byte-swapped (`0x48434154` instead of
+`0x54414348`). The reader detects this and automatically byte-swaps all
+fixed-width integer fields during parsing.
+
+Writers must use `memcpy()` from properly-sized integer types when writing
+fixed-width integer fields. When the source variable's type differs from the
+field width (e.g., `size_t` written as 4 bytes), explicit casting to the
+correct type (e.g., `uint32_t`) is required before `memcpy()`. On big-endian
+systems, copying from an oversized type would copy the wrong bytes—high-order
+zeros instead of the actual value.
+
+The reader tracks whether byte-swapping is needed via a `needs_swap` flag set
+during header parsing. All fixed-width fields in the header, footer, and
+sample data are conditionally byte-swapped using Python's internal byte-swap
+functions (`_Py_bswap32`, `_Py_bswap64` from `pycore_bitutils.h`).
+
+Variable-length integers (varints) are byte-order independent since they
+encode values one byte at a time using the LEB128 scheme, so they require
+no special handling for cross-endian reading.
+
+### Memory-Mapped I/O
+
+On Unix systems (Linux, macOS), the reader uses `mmap()` to map the file
+into the process address space. The kernel handles paging data in and out
+as needed, no explicit read() calls or buffer management are required,
+multiple readers can share the same physical pages, and sequential access
+patterns benefit from kernel read-ahead.
+
+The implementation uses `madvise()` to hint the access pattern to the kernel:
+`MADV_SEQUENTIAL` indicates the file will be read linearly, enabling
+aggressive read-ahead. `MADV_WILLNEED` requests pre-faulting of pages.
+On Linux, `MAP_POPULATE` pre-faults all pages at mmap time rather than on
+first access, moving page fault overhead from the parsing loop to the
+initial mapping for more predictable performance. For large files (over
+32 MB), `MADV_HUGEPAGE` requests transparent huge pages (2 MB instead of
+4 KB) to reduce TLB pressure when accessing large amounts of data.
+
+On Windows, the implementation falls back to standard file I/O with full
+file buffering. Profiling data files are typically small enough (tens to
+hundreds of megabytes) that this is acceptable.
+
+The writer uses a 512 KB buffer to batch small writes. Each sample record
+is typically tens of bytes; writing these individually would incur excessive
+syscall overhead. The buffer accumulates data until full, then flushes in
+one write() call (or feeds through the compression stream).
+
+## Future Considerations
+
+The format reserves space for future extensions. The 12 reserved bytes in
+the header could hold additional metadata. The 16-byte checksum field in
+the footer is currently unused. The version field allows incompatible
+changes with graceful rejection. New compression types could be added
+(compression_type > 1).
+
+Any changes that alter the meaning of existing fields or the parsing logic
+should increment the version number to prevent older readers from
+misinterpreting new files.
diff --git a/InternalDocs/stackrefs.md b/InternalDocs/stackrefs.md
index 2d8810262d45f7..5774be9c56d363 100644
--- a/InternalDocs/stackrefs.md
+++ b/InternalDocs/stackrefs.md
@@ -64,7 +64,6 @@ these values. Type checks use `PyStackRef_IsTaggedInt` and `PyStackRef_LongCheck
## Free threading considerations
-With `Py_GIL_DISABLED`, `Py_TAG_DEFERRED` is an alias for `Py_TAG_REFCNT`.
Objects that support deferred reference counting can be pushed to the evaluation
stack and stored in local variables without directly incrementing the reference
count because they are only freed during cyclic garbage collection. This avoids
diff --git a/InternalDocs/structure.md b/InternalDocs/structure.md
new file mode 100644
index 00000000000000..75c8476aa0ad98
--- /dev/null
+++ b/InternalDocs/structure.md
@@ -0,0 +1,40 @@
+# CPython source code
+
+This section gives an overview of CPython's code structure and provides
+a summary of file locations for modules and built-ins.
+
+
+## Source code layout
+
+For a Python module, the typical layout is:
+
+* `Lib/.py`
+* `Modules/_.c` (if there's also a C accelerator module)
+* `Lib/test/test_.py`
+* `Doc/library/.rst`
+
+For an extension module, the typical layout is:
+
+* `Modules/module.c`
+* `Lib/test/test_.py`
+* `Doc/library/.rst`
+
+For builtin types, the typical layout is:
+
+* `Objects/object.c`
+* `Lib/test/test_.py`
+* [`Doc/library/stdtypes.rst`](../Doc/library/stdtypes.rst)
+
+For builtin functions, the typical layout is:
+
+* [`Python/bltinmodule.c`](../Python/bltinmodule.c)
+* [`Lib/test/test_builtin.py`](../Lib/test/test_builtin.py)
+* [`Doc/library/functions.rst`](../Doc/library/functions.rst)
+
+Some exceptions to these layouts are:
+
+* built-in type `int` is at [`Objects/longobject.c`](../Objects/longobject.c)
+* built-in type `str` is at [`Objects/unicodeobject.c`](../Objects/unicodeobject.c)
+* built-in module `sys` is at [`Python/sysmodule.c`](../Python/sysmodule.c)
+* built-in module `marshal` is at [`Python/marshal.c`](../Python/marshal.c)
+* Windows-only module `winreg` is at [`PC/winreg.c`](../PC/winreg.c)
diff --git a/Lib/_colorize.py b/Lib/_colorize.py
index 29d7cc67b6e39d..5c4903f14aa86b 100644
--- a/Lib/_colorize.py
+++ b/Lib/_colorize.py
@@ -9,7 +9,7 @@
# types
if False:
- from typing import IO, Self, ClassVar
+ from typing import IO, Literal, Self, ClassVar
_theme: Theme
@@ -74,6 +74,19 @@ class ANSIColors:
setattr(NoColors, attr, "")
+class CursesColors:
+ """Curses color constants for terminal UI theming."""
+ BLACK = 0
+ RED = 1
+ GREEN = 2
+ YELLOW = 3
+ BLUE = 4
+ MAGENTA = 5
+ CYAN = 6
+ WHITE = 7
+ DEFAULT = -1
+
+
#
# Experimental theming support (see gh-133346)
#
@@ -169,7 +182,7 @@ class Argparse(ThemeSection):
label: str = ANSIColors.BOLD_YELLOW
action: str = ANSIColors.BOLD_GREEN
default: str = ANSIColors.GREY
- default_value: str = ANSIColors.YELLOW
+ interpolated_value: str = ANSIColors.YELLOW
reset: str = ANSIColors.RESET
error: str = ANSIColors.BOLD_MAGENTA
warning: str = ANSIColors.BOLD_YELLOW
@@ -187,6 +200,114 @@ class Difflib(ThemeSection):
reset: str = ANSIColors.RESET
+@dataclass(frozen=True, kw_only=True)
+class LiveProfiler(ThemeSection):
+ """Theme section for the live profiling TUI (Tachyon profiler).
+
+ Colors use CursesColors constants (BLACK, RED, GREEN, YELLOW,
+ BLUE, MAGENTA, CYAN, WHITE, DEFAULT).
+ """
+ # Header colors
+ title_fg: int = CursesColors.CYAN
+ title_bg: int = CursesColors.DEFAULT
+
+ # Status display colors
+ pid_fg: int = CursesColors.CYAN
+ uptime_fg: int = CursesColors.GREEN
+ time_fg: int = CursesColors.YELLOW
+ interval_fg: int = CursesColors.MAGENTA
+
+ # Thread view colors
+ thread_all_fg: int = CursesColors.GREEN
+ thread_single_fg: int = CursesColors.MAGENTA
+
+ # Progress bar colors
+ bar_good_fg: int = CursesColors.GREEN
+ bar_bad_fg: int = CursesColors.RED
+
+ # Stats colors
+ on_gil_fg: int = CursesColors.GREEN
+ off_gil_fg: int = CursesColors.RED
+ waiting_gil_fg: int = CursesColors.YELLOW
+ gc_fg: int = CursesColors.MAGENTA
+
+ # Function display colors
+ func_total_fg: int = CursesColors.CYAN
+ func_exec_fg: int = CursesColors.GREEN
+ func_stack_fg: int = CursesColors.YELLOW
+ func_shown_fg: int = CursesColors.MAGENTA
+
+ # Table header colors (for sorted column highlight)
+ sorted_header_fg: int = CursesColors.BLACK
+ sorted_header_bg: int = CursesColors.CYAN
+
+ # Normal header colors (non-sorted columns) - use reverse video style
+ normal_header_fg: int = CursesColors.BLACK
+ normal_header_bg: int = CursesColors.WHITE
+
+ # Data row colors
+ samples_fg: int = CursesColors.CYAN
+ file_fg: int = CursesColors.GREEN
+ func_fg: int = CursesColors.YELLOW
+
+ # Trend indicator colors
+ trend_up_fg: int = CursesColors.GREEN
+ trend_down_fg: int = CursesColors.RED
+
+ # Medal colors for top functions
+ medal_gold_fg: int = CursesColors.RED
+ medal_silver_fg: int = CursesColors.YELLOW
+ medal_bronze_fg: int = CursesColors.GREEN
+
+ # Background style: 'dark' or 'light'
+ background_style: Literal["dark", "light"] = "dark"
+
+
+LiveProfilerLight = LiveProfiler(
+ # Header colors
+ title_fg=CursesColors.BLUE, # Blue is more readable than cyan on light bg
+
+ # Status display colors - darker colors for light backgrounds
+ pid_fg=CursesColors.BLUE,
+ uptime_fg=CursesColors.BLACK,
+ time_fg=CursesColors.BLACK,
+ interval_fg=CursesColors.BLUE,
+
+ # Thread view colors
+ thread_all_fg=CursesColors.BLACK,
+ thread_single_fg=CursesColors.BLUE,
+
+ # Stats colors
+ waiting_gil_fg=CursesColors.RED,
+ gc_fg=CursesColors.BLUE,
+
+ # Function display colors
+ func_total_fg=CursesColors.BLUE,
+ func_exec_fg=CursesColors.BLACK,
+ func_stack_fg=CursesColors.BLACK,
+ func_shown_fg=CursesColors.BLUE,
+
+ # Table header colors (for sorted column highlight)
+ sorted_header_fg=CursesColors.WHITE,
+ sorted_header_bg=CursesColors.BLUE,
+
+ # Normal header colors (non-sorted columns)
+ normal_header_fg=CursesColors.WHITE,
+ normal_header_bg=CursesColors.BLACK,
+
+ # Data row colors - use dark colors readable on white
+ samples_fg=CursesColors.BLACK,
+ file_fg=CursesColors.BLACK,
+ func_fg=CursesColors.BLUE, # Blue is more readable than magenta on light bg
+
+ # Medal colors for top functions
+ medal_silver_fg=CursesColors.BLUE,
+
+ # Background style
+ background_style="light",
+)
+
+
@dataclass(frozen=True, kw_only=True)
class Syntax(ThemeSection):
prompt: str = ANSIColors.BOLD_MAGENTA
@@ -232,6 +353,7 @@ class Theme:
"""
argparse: Argparse = field(default_factory=Argparse)
difflib: Difflib = field(default_factory=Difflib)
+ live_profiler: LiveProfiler = field(default_factory=LiveProfiler)
syntax: Syntax = field(default_factory=Syntax)
traceback: Traceback = field(default_factory=Traceback)
unittest: Unittest = field(default_factory=Unittest)
@@ -241,6 +363,7 @@ def copy_with(
*,
argparse: Argparse | None = None,
difflib: Difflib | None = None,
+ live_profiler: LiveProfiler | None = None,
syntax: Syntax | None = None,
traceback: Traceback | None = None,
unittest: Unittest | None = None,
@@ -253,6 +376,7 @@ def copy_with(
return type(self)(
argparse=argparse or self.argparse,
difflib=difflib or self.difflib,
+ live_profiler=live_profiler or self.live_profiler,
syntax=syntax or self.syntax,
traceback=traceback or self.traceback,
unittest=unittest or self.unittest,
@@ -269,6 +393,7 @@ def no_colors(cls) -> Self:
return cls(
argparse=Argparse.no_colors(),
difflib=Difflib.no_colors(),
+ live_profiler=LiveProfiler.no_colors(),
syntax=Syntax.no_colors(),
traceback=Traceback.no_colors(),
unittest=Unittest.no_colors(),
@@ -338,6 +463,9 @@ def _safe_getenv(k: str, fallback: str | None = None) -> str | None:
default_theme = Theme()
theme_no_color = default_theme.no_colors()
+# Convenience theme with light profiler colors (for white/light terminal backgrounds)
+light_profiler_theme = default_theme.copy_with(live_profiler=LiveProfilerLight)
+
def get_theme(
*,
diff --git a/Lib/_opcode_metadata.py b/Lib/_opcode_metadata.py
index e681cb17e43e04..8f14d81a43ee75 100644
--- a/Lib/_opcode_metadata.py
+++ b/Lib/_opcode_metadata.py
@@ -26,8 +26,10 @@
"BINARY_OP_SUBSCR_LIST_SLICE",
"BINARY_OP_SUBSCR_TUPLE_INT",
"BINARY_OP_SUBSCR_STR_INT",
+ "BINARY_OP_SUBSCR_USTR_INT",
"BINARY_OP_SUBSCR_DICT",
"BINARY_OP_SUBSCR_GETITEM",
+ "BINARY_OP_INPLACE_ADD_UNICODE",
"BINARY_OP_EXTEND",
"BINARY_OP_INPLACE_ADD_UNICODE",
],
@@ -117,6 +119,10 @@
"CALL_KW_PY",
"CALL_KW_NON_PY",
],
+ "CALL_FUNCTION_EX": [
+ "CALL_EX_PY",
+ "CALL_EX_NON_PY_GENERAL",
+ ],
}
_specialized_opmap = {
@@ -125,6 +131,7 @@
'BINARY_OP_ADD_UNICODE': 131,
'BINARY_OP_EXTEND': 132,
'BINARY_OP_INPLACE_ADD_UNICODE': 3,
+ 'BINARY_OP_INPLACE_ADD_UNICODE': 3,
'BINARY_OP_MULTIPLY_FLOAT': 133,
'BINARY_OP_MULTIPLY_INT': 134,
'BINARY_OP_SUBSCR_DICT': 135,
@@ -133,75 +140,78 @@
'BINARY_OP_SUBSCR_LIST_SLICE': 138,
'BINARY_OP_SUBSCR_STR_INT': 139,
'BINARY_OP_SUBSCR_TUPLE_INT': 140,
- 'BINARY_OP_SUBTRACT_FLOAT': 141,
- 'BINARY_OP_SUBTRACT_INT': 142,
- 'CALL_ALLOC_AND_ENTER_INIT': 143,
- 'CALL_BOUND_METHOD_EXACT_ARGS': 144,
- 'CALL_BOUND_METHOD_GENERAL': 145,
- 'CALL_BUILTIN_CLASS': 146,
- 'CALL_BUILTIN_FAST': 147,
- 'CALL_BUILTIN_FAST_WITH_KEYWORDS': 148,
- 'CALL_BUILTIN_O': 149,
- 'CALL_ISINSTANCE': 150,
- 'CALL_KW_BOUND_METHOD': 151,
- 'CALL_KW_NON_PY': 152,
- 'CALL_KW_PY': 153,
- 'CALL_LEN': 154,
- 'CALL_LIST_APPEND': 155,
- 'CALL_METHOD_DESCRIPTOR_FAST': 156,
- 'CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS': 157,
- 'CALL_METHOD_DESCRIPTOR_NOARGS': 158,
- 'CALL_METHOD_DESCRIPTOR_O': 159,
- 'CALL_NON_PY_GENERAL': 160,
- 'CALL_PY_EXACT_ARGS': 161,
- 'CALL_PY_GENERAL': 162,
- 'CALL_STR_1': 163,
- 'CALL_TUPLE_1': 164,
- 'CALL_TYPE_1': 165,
- 'COMPARE_OP_FLOAT': 166,
- 'COMPARE_OP_INT': 167,
- 'COMPARE_OP_STR': 168,
- 'CONTAINS_OP_DICT': 169,
- 'CONTAINS_OP_SET': 170,
- 'FOR_ITER_GEN': 171,
- 'FOR_ITER_LIST': 172,
- 'FOR_ITER_RANGE': 173,
- 'FOR_ITER_TUPLE': 174,
- 'JUMP_BACKWARD_JIT': 175,
- 'JUMP_BACKWARD_NO_JIT': 176,
- 'LOAD_ATTR_CLASS': 177,
- 'LOAD_ATTR_CLASS_WITH_METACLASS_CHECK': 178,
- 'LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN': 179,
- 'LOAD_ATTR_INSTANCE_VALUE': 180,
- 'LOAD_ATTR_METHOD_LAZY_DICT': 181,
- 'LOAD_ATTR_METHOD_NO_DICT': 182,
- 'LOAD_ATTR_METHOD_WITH_VALUES': 183,
- 'LOAD_ATTR_MODULE': 184,
- 'LOAD_ATTR_NONDESCRIPTOR_NO_DICT': 185,
- 'LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES': 186,
- 'LOAD_ATTR_PROPERTY': 187,
- 'LOAD_ATTR_SLOT': 188,
- 'LOAD_ATTR_WITH_HINT': 189,
- 'LOAD_GLOBAL_BUILTIN': 190,
- 'LOAD_GLOBAL_MODULE': 191,
- 'LOAD_SUPER_ATTR_ATTR': 192,
- 'LOAD_SUPER_ATTR_METHOD': 193,
- 'RESUME_CHECK': 194,
- 'SEND_GEN': 195,
- 'STORE_ATTR_INSTANCE_VALUE': 196,
- 'STORE_ATTR_SLOT': 197,
- 'STORE_ATTR_WITH_HINT': 198,
- 'STORE_SUBSCR_DICT': 199,
- 'STORE_SUBSCR_LIST_INT': 200,
- 'TO_BOOL_ALWAYS_TRUE': 201,
- 'TO_BOOL_BOOL': 202,
- 'TO_BOOL_INT': 203,
- 'TO_BOOL_LIST': 204,
- 'TO_BOOL_NONE': 205,
- 'TO_BOOL_STR': 206,
- 'UNPACK_SEQUENCE_LIST': 207,
- 'UNPACK_SEQUENCE_TUPLE': 208,
- 'UNPACK_SEQUENCE_TWO_TUPLE': 209,
+ 'BINARY_OP_SUBSCR_USTR_INT': 141,
+ 'BINARY_OP_SUBTRACT_FLOAT': 142,
+ 'BINARY_OP_SUBTRACT_INT': 143,
+ 'CALL_ALLOC_AND_ENTER_INIT': 144,
+ 'CALL_BOUND_METHOD_EXACT_ARGS': 145,
+ 'CALL_BOUND_METHOD_GENERAL': 146,
+ 'CALL_BUILTIN_CLASS': 147,
+ 'CALL_BUILTIN_FAST': 148,
+ 'CALL_BUILTIN_FAST_WITH_KEYWORDS': 149,
+ 'CALL_BUILTIN_O': 150,
+ 'CALL_EX_NON_PY_GENERAL': 151,
+ 'CALL_EX_PY': 152,
+ 'CALL_ISINSTANCE': 153,
+ 'CALL_KW_BOUND_METHOD': 154,
+ 'CALL_KW_NON_PY': 155,
+ 'CALL_KW_PY': 156,
+ 'CALL_LEN': 157,
+ 'CALL_LIST_APPEND': 158,
+ 'CALL_METHOD_DESCRIPTOR_FAST': 159,
+ 'CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS': 160,
+ 'CALL_METHOD_DESCRIPTOR_NOARGS': 161,
+ 'CALL_METHOD_DESCRIPTOR_O': 162,
+ 'CALL_NON_PY_GENERAL': 163,
+ 'CALL_PY_EXACT_ARGS': 164,
+ 'CALL_PY_GENERAL': 165,
+ 'CALL_STR_1': 166,
+ 'CALL_TUPLE_1': 167,
+ 'CALL_TYPE_1': 168,
+ 'COMPARE_OP_FLOAT': 169,
+ 'COMPARE_OP_INT': 170,
+ 'COMPARE_OP_STR': 171,
+ 'CONTAINS_OP_DICT': 172,
+ 'CONTAINS_OP_SET': 173,
+ 'FOR_ITER_GEN': 174,
+ 'FOR_ITER_LIST': 175,
+ 'FOR_ITER_RANGE': 176,
+ 'FOR_ITER_TUPLE': 177,
+ 'JUMP_BACKWARD_JIT': 178,
+ 'JUMP_BACKWARD_NO_JIT': 179,
+ 'LOAD_ATTR_CLASS': 180,
+ 'LOAD_ATTR_CLASS_WITH_METACLASS_CHECK': 181,
+ 'LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN': 182,
+ 'LOAD_ATTR_INSTANCE_VALUE': 183,
+ 'LOAD_ATTR_METHOD_LAZY_DICT': 184,
+ 'LOAD_ATTR_METHOD_NO_DICT': 185,
+ 'LOAD_ATTR_METHOD_WITH_VALUES': 186,
+ 'LOAD_ATTR_MODULE': 187,
+ 'LOAD_ATTR_NONDESCRIPTOR_NO_DICT': 188,
+ 'LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES': 189,
+ 'LOAD_ATTR_PROPERTY': 190,
+ 'LOAD_ATTR_SLOT': 191,
+ 'LOAD_ATTR_WITH_HINT': 192,
+ 'LOAD_GLOBAL_BUILTIN': 193,
+ 'LOAD_GLOBAL_MODULE': 194,
+ 'LOAD_SUPER_ATTR_ATTR': 195,
+ 'LOAD_SUPER_ATTR_METHOD': 196,
+ 'RESUME_CHECK': 197,
+ 'SEND_GEN': 198,
+ 'STORE_ATTR_INSTANCE_VALUE': 199,
+ 'STORE_ATTR_SLOT': 200,
+ 'STORE_ATTR_WITH_HINT': 201,
+ 'STORE_SUBSCR_DICT': 202,
+ 'STORE_SUBSCR_LIST_INT': 203,
+ 'TO_BOOL_ALWAYS_TRUE': 204,
+ 'TO_BOOL_BOOL': 205,
+ 'TO_BOOL_INT': 206,
+ 'TO_BOOL_LIST': 207,
+ 'TO_BOOL_NONE': 208,
+ 'TO_BOOL_STR': 209,
+ 'UNPACK_SEQUENCE_LIST': 210,
+ 'UNPACK_SEQUENCE_TUPLE': 211,
+ 'UNPACK_SEQUENCE_TWO_TUPLE': 212,
}
opmap = {
diff --git a/Lib/_pyio.py b/Lib/_pyio.py
index 69a088df8fc987..3306c8a274760b 100644
--- a/Lib/_pyio.py
+++ b/Lib/_pyio.py
@@ -949,23 +949,24 @@ def read1(self, size=-1):
return self.read(size)
def write(self, b):
- if self.closed:
- raise ValueError("write to closed file")
if isinstance(b, str):
raise TypeError("can't write str to binary stream")
with memoryview(b) as view:
+ if self.closed:
+ raise ValueError("write to closed file")
+
n = view.nbytes # Size of any bytes-like object
- if n == 0:
- return 0
+ if n == 0:
+ return 0
- with self._lock:
- pos = self._pos
- if pos > len(self._buffer):
- # Pad buffer to pos with null bytes.
- self._buffer.resize(pos)
- self._buffer[pos:pos + n] = b
- self._pos += n
- return n
+ with self._lock:
+ pos = self._pos
+ if pos > len(self._buffer):
+ # Pad buffer to pos with null bytes.
+ self._buffer.resize(pos)
+ self._buffer[pos:pos + n] = view
+ self._pos += n
+ return n
def seek(self, pos, whence=0):
if self.closed:
diff --git a/Lib/_pyrepl/_module_completer.py b/Lib/_pyrepl/_module_completer.py
index cf59e007f4df80..2098d0a54aba31 100644
--- a/Lib/_pyrepl/_module_completer.py
+++ b/Lib/_pyrepl/_module_completer.py
@@ -108,6 +108,18 @@ def _find_modules(self, path: str, prefix: str) -> list[str]:
return []
modules: Iterable[pkgutil.ModuleInfo] = self.global_cache
+ imported_module = sys.modules.get(path.split('.')[0])
+ if imported_module:
+ # Filter modules to those who name and specs match the
+ # imported module to avoid invalid suggestions
+ spec = imported_module.__spec__
+ if spec:
+ modules = [mod for mod in modules
+ if mod.name == spec.name
+ and mod.module_finder.find_spec(mod.name, None) == spec]
+ else:
+ modules = []
+
is_stdlib_import: bool | None = None
for segment in path.split('.'):
modules = [mod_info for mod_info in modules
@@ -196,7 +208,6 @@ def global_cache(self) -> list[pkgutil.ModuleInfo]:
"""Global module cache"""
if not self._global_cache or self._curr_sys_path != sys.path:
self._curr_sys_path = sys.path[:]
- # print('getting packages')
self._global_cache = list(pkgutil.iter_modules())
return self._global_cache
diff --git a/Lib/_pyrepl/reader.py b/Lib/_pyrepl/reader.py
index 0ebd9162eca4bb..9ab92f64d1ef63 100644
--- a/Lib/_pyrepl/reader.py
+++ b/Lib/_pyrepl/reader.py
@@ -619,6 +619,16 @@ def suspend(self) -> SimpleContextManager:
setattr(self, arg, prev_state[arg])
self.prepare()
+ @contextmanager
+ def suspend_colorization(self) -> SimpleContextManager:
+ try:
+ old_can_colorize = self.can_colorize
+ self.can_colorize = False
+ yield
+ finally:
+ self.can_colorize = old_can_colorize
+
+
def finish(self) -> None:
"""Called when a command signals that we're finished."""
pass
diff --git a/Lib/_pyrepl/simple_interact.py b/Lib/_pyrepl/simple_interact.py
index 3b0debf2ba037b..0da9f91baf6cfc 100644
--- a/Lib/_pyrepl/simple_interact.py
+++ b/Lib/_pyrepl/simple_interact.py
@@ -124,7 +124,7 @@ def maybe_run_command(statement: str) -> bool:
command = REPL_COMMANDS[statement]
if callable(command):
# Make sure that history does not change because of commands
- with reader.suspend_history():
+ with reader.suspend_history(), reader.suspend_colorization():
command()
return True
return False
diff --git a/Lib/_pyrepl/unix_console.py b/Lib/_pyrepl/unix_console.py
index 09247de748ee3b..937b5df6ff7d4c 100644
--- a/Lib/_pyrepl/unix_console.py
+++ b/Lib/_pyrepl/unix_console.py
@@ -251,8 +251,9 @@ def refresh(self, screen, c_xy):
if not self.__gone_tall:
while len(self.screen) < min(len(screen), self.height):
self.__hide_cursor()
- self.__move(0, len(self.screen) - 1)
- self.__write("\n")
+ if self.screen:
+ self.__move(0, len(self.screen) - 1)
+ self.__write("\n")
self.posxy = 0, len(self.screen)
self.screen.append("")
else:
@@ -808,7 +809,7 @@ def __tputs(self, fmt, prog=delayprog):
will never do anyone any good."""
# using .get() means that things will blow up
# only if the bps is actually needed (which I'm
- # betting is pretty unlkely)
+ # betting is pretty unlikely)
bps = ratedict.get(self.__svtermstate.ospeed)
while True:
m = prog.search(fmt)
diff --git a/Lib/_pyrepl/windows_console.py b/Lib/_pyrepl/windows_console.py
index f9f5988af0b9ef..303af8a354ff00 100644
--- a/Lib/_pyrepl/windows_console.py
+++ b/Lib/_pyrepl/windows_console.py
@@ -183,8 +183,9 @@ def refresh(self, screen: list[str], c_xy: tuple[int, int]) -> None:
while len(self.screen) < min(len(screen), self.height):
self._hide_cursor()
- self._move_relative(0, len(self.screen) - 1)
- self.__write("\n")
+ if self.screen:
+ self._move_relative(0, len(self.screen) - 1)
+ self.__write("\n")
self.posxy = 0, len(self.screen)
self.screen.append("")
@@ -501,7 +502,7 @@ def clear(self) -> None:
"""Wipe the screen"""
self.__write(CLEAR)
self.posxy = 0, 0
- self.screen = [""]
+ self.screen = []
def finish(self) -> None:
"""Move the cursor to the end of the display and otherwise get
@@ -553,7 +554,7 @@ def getpending(self) -> Event:
e.data += ch
return e
- def wait(self, timeout: float | None) -> bool:
+ def wait_for_event(self, timeout: float | None) -> bool:
"""Wait for an event."""
if timeout is None:
timeout = INFINITE
@@ -566,6 +567,15 @@ def wait(self, timeout: float | None) -> bool:
return False
return True
+ def wait(self, timeout: float | None) -> bool:
+ """
+ Wait for events on the console.
+ """
+ return (
+ not self.event_queue.empty()
+ or self.wait_for_event(timeout)
+ )
+
def repaint(self) -> None:
raise NotImplementedError("No repaint support")
diff --git a/Lib/_sitebuiltins.py b/Lib/_sitebuiltins.py
index c66269a571967f..81b36efc6c285f 100644
--- a/Lib/_sitebuiltins.py
+++ b/Lib/_sitebuiltins.py
@@ -36,7 +36,7 @@ def __init__(self, name, data, files=(), dirs=()):
import os
self.__name = name
self.__data = data
- self.__lines = None
+ self.__lines = []
self.__filenames = [os.path.join(dir, filename)
for dir in dirs
for filename in files]
@@ -65,24 +65,12 @@ def __repr__(self):
return "Type %s() to see the full %s text" % ((self.__name,)*2)
def __call__(self):
+ from _pyrepl.pager import get_pager
self.__setup()
- prompt = 'Hit Return for more, or q (and Return) to quit: '
- lineno = 0
- while 1:
- try:
- for i in range(lineno, lineno + self.MAXLINES):
- print(self.__lines[i])
- except IndexError:
- break
- else:
- lineno += self.MAXLINES
- key = None
- while key is None:
- key = input(prompt)
- if key not in ('', 'q'):
- key = None
- if key == 'q':
- break
+
+ pager = get_pager()
+ text = "\n".join(self.__lines)
+ pager(text, title=self.__name)
class _Helper(object):
diff --git a/Lib/annotationlib.py b/Lib/annotationlib.py
index a5788cdbfae3f5..832d160de7f4e5 100644
--- a/Lib/annotationlib.py
+++ b/Lib/annotationlib.py
@@ -279,7 +279,13 @@ def __eq__(self, other):
# because dictionaries are not hashable.
and self.__globals__ is other.__globals__
and self.__forward_is_class__ == other.__forward_is_class__
- and self.__cell__ == other.__cell__
+ # Two separate cells are always considered unequal in forward refs.
+ and (
+ {name: id(cell) for name, cell in self.__cell__.items()}
+ == {name: id(cell) for name, cell in other.__cell__.items()}
+ if isinstance(self.__cell__, dict) and isinstance(other.__cell__, dict)
+ else self.__cell__ is other.__cell__
+ )
and self.__owner__ == other.__owner__
and (
(tuple(sorted(self.__extra_names__.items())) if self.__extra_names__ else None) ==
@@ -293,7 +299,10 @@ def __hash__(self):
self.__forward_module__,
id(self.__globals__), # dictionaries are not hashable, so hash by identity
self.__forward_is_class__,
- tuple(sorted(self.__cell__.items())) if isinstance(self.__cell__, dict) else self.__cell__,
+ ( # cells are not hashable as well
+ tuple(sorted([(name, id(cell)) for name, cell in self.__cell__.items()]))
+ if isinstance(self.__cell__, dict) else id(self.__cell__),
+ ),
self.__owner__,
tuple(sorted(self.__extra_names__.items())) if self.__extra_names__ else None,
))
@@ -1096,7 +1105,7 @@ def _rewrite_star_unpack(arg):
"""If the given argument annotation expression is a star unpack e.g. `'*Ts'`
rewrite it to a valid expression.
"""
- if arg.startswith("*"):
+ if arg.lstrip().startswith("*"):
return f"({arg},)[0]" # E.g. (*Ts,)[0] or (*tuple[int, int],)[0]
else:
return arg
diff --git a/Lib/argparse.py b/Lib/argparse.py
index ed98aa9e974b2a..0494b545f2f1d3 100644
--- a/Lib/argparse.py
+++ b/Lib/argparse.py
@@ -517,7 +517,27 @@ def _format_text(self, text):
text = text % dict(prog=self._prog)
text_width = max(self._width - self._current_indent, 11)
indent = ' ' * self._current_indent
- return self._fill_text(text, text_width, indent) + '\n\n'
+ text = self._fill_text(text, text_width, indent)
+ text = self._apply_text_markup(text)
+ return text + '\n\n'
+
+ def _apply_text_markup(self, text):
+ """Apply color markup to text.
+
+ Supported markup:
+ `...` - inline code (rendered with prog_extra color)
+
+ When colors are disabled, backticks are preserved as-is.
+ """
+ t = self._theme
+ if not t.reset:
+ return text
+ text = _re.sub(
+ r'`([^`]+)`',
+ rf'{t.prog_extra}\1{t.reset}',
+ text,
+ )
+ return text
def _format_action(self, action):
# determine the required width and the entry label
@@ -668,7 +688,41 @@ def _expand_help(self, action):
params[name] = value.__name__
if params.get('choices') is not None:
params['choices'] = ', '.join(map(str, params['choices']))
- return help_string % params
+
+ t = self._theme
+
+ result = help_string % params
+
+ if not t.reset:
+ return result
+
+ # Match format specifiers like: %s, %d, %(key)s, etc.
+ fmt_spec = r'''
+ %
+ (?:
+ % # %% escape
+ |
+ (?:\((?P[^)]*)\))? # key
+ [-#0\ +]* # flags
+ (?:\*|\d+)? # width
+ (?:\.(?:\*|\d+))? # precision
+ [hlL]? # length modifier
+ [diouxXeEfFgGcrsa] # conversion type
+ )
+ '''
+
+ def colorize(match):
+ spec, key = match.group(0, 'key')
+ if spec == '%%':
+ return '%'
+ if key is not None:
+ # %(key)... - format and colorize
+ formatted = spec % {key: params[key]}
+ return f'{t.interpolated_value}{formatted}{t.reset}'
+ # bare %s etc. - format with full params dict, no colorization
+ return spec % params
+
+ return _re.sub(fmt_spec, colorize, help_string, flags=_re.VERBOSE)
def _iter_indented_subactions(self, action):
try:
@@ -749,8 +803,8 @@ def _get_help_string(self, action):
default_str = _(" (default: %(default)s)")
prefix, suffix = default_str.split("%(default)s")
help += (
- f" {t.default}{prefix.lstrip()}"
- f"{t.default_value}%(default)s"
+ f" {t.default}{prefix.lstrip()}{t.reset}"
+ f"%(default)s"
f"{t.default}{suffix}{t.reset}"
)
return help
diff --git a/Lib/asyncio/__main__.py b/Lib/asyncio/__main__.py
index d078ebfa4cedbe..44667efc522556 100644
--- a/Lib/asyncio/__main__.py
+++ b/Lib/asyncio/__main__.py
@@ -86,16 +86,17 @@ def run(self):
global return_code
try:
- banner = (
- f'asyncio REPL {sys.version} on {sys.platform}\n'
- f'Use "await" directly instead of "asyncio.run()".\n'
- f'Type "help", "copyright", "credits" or "license" '
- f'for more information.\n'
- )
+ if not sys.flags.quiet:
+ banner = (
+ f'asyncio REPL {sys.version} on {sys.platform}\n'
+ f'Use "await" directly instead of "asyncio.run()".\n'
+ f'Type "help", "copyright", "credits" or "license" '
+ f'for more information.\n'
+ )
- console.write(banner)
+ console.write(banner)
- if startup_path := os.getenv("PYTHONSTARTUP"):
+ if not sys.flags.isolated and (startup_path := os.getenv("PYTHONSTARTUP")):
sys.audit("cpython.run_startup", startup_path)
import tokenize
@@ -240,4 +241,5 @@ def interrupt(self) -> None:
break
console.write('exiting asyncio REPL...\n')
+ loop.close()
sys.exit(return_code)
diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py
index 29652295218a22..11858a0274a69f 100644
--- a/Lib/asyncio/futures.py
+++ b/Lib/asyncio/futures.py
@@ -79,6 +79,10 @@ def __init__(self, *, loop=None):
loop object used by the future. If it's not provided, the future uses
the default event loop.
"""
+ if self._loop is not None:
+ raise RuntimeError(f"{self.__class__.__name__} object is already "
+ "initialized")
+
if loop is None:
self._loop = events.get_event_loop()
else:
diff --git a/Lib/asyncio/tools.py b/Lib/asyncio/tools.py
index f9b8a4ee56c5c1..62d6a71557fa37 100644
--- a/Lib/asyncio/tools.py
+++ b/Lib/asyncio/tools.py
@@ -27,10 +27,10 @@ def __init__(
# ─── indexing helpers ───────────────────────────────────────────
def _format_stack_entry(elem: str|FrameInfo) -> str:
if not isinstance(elem, str):
- if elem.lineno == 0 and elem.filename == "":
+ if elem.location.lineno == 0 and elem.filename == "":
return f"{elem.funcname}"
else:
- return f"{elem.funcname} {elem.filename}:{elem.lineno}"
+ return f"{elem.funcname} {elem.filename}:{elem.location.lineno}"
return elem
diff --git a/Lib/base64.py b/Lib/base64.py
index 341bf8eaf1891e..6e9d24f0649320 100644
--- a/Lib/base64.py
+++ b/Lib/base64.py
@@ -26,6 +26,8 @@
]
+_NOT_SPECIFIED = ['NOT SPECIFIED']
+
bytes_types = (bytes, bytearray) # Types acceptable as binary data
def _bytes_from_decode_data(s):
@@ -45,21 +47,24 @@ def _bytes_from_decode_data(s):
# Base64 encoding/decoding uses binascii
-def b64encode(s, altchars=None):
+def b64encode(s, altchars=None, *, wrapcol=0):
"""Encode the bytes-like object s using Base64 and return a bytes object.
Optional altchars should be a byte string of length 2 which specifies an
alternative alphabet for the '+' and '/' characters. This allows an
application to e.g. generate url or filesystem safe Base64 strings.
+
+ If wrapcol is non-zero, insert a newline (b'\\n') character after at most
+ every wrapcol characters.
"""
- encoded = binascii.b2a_base64(s, newline=False)
+ encoded = binascii.b2a_base64(s, wrapcol=wrapcol, newline=False)
if altchars is not None:
assert len(altchars) == 2, repr(altchars)
return encoded.translate(bytes.maketrans(b'+/', altchars))
return encoded
-def b64decode(s, altchars=None, validate=False):
+def b64decode(s, altchars=None, validate=_NOT_SPECIFIED, *, ignorechars=_NOT_SPECIFIED):
"""Decode the Base64 encoded bytes-like object or ASCII string s.
Optional altchars must be a bytes-like object or ASCII string of length 2
@@ -69,20 +74,65 @@ def b64decode(s, altchars=None, validate=False):
The result is returned as a bytes object. A binascii.Error is raised if
s is incorrectly padded.
- If validate is False (the default), characters that are neither in the
- normal base-64 alphabet nor the alternative alphabet are discarded prior
- to the padding check. If validate is True, these non-alphabet characters
- in the input result in a binascii.Error.
+ If ignorechars is specified, it should be a byte string containing
+ characters to ignore from the input. The default value of validate is
+ True if ignorechars is specified, False otherwise.
+
+ If validate is false, characters that are neither in the normal base-64
+ alphabet nor the alternative alphabet are discarded prior to the
+ padding check. If validate is true, these non-alphabet characters in
+ the input result in a binascii.Error if they are not in ignorechars.
For more information about the strict base64 check, see:
https://docs.python.org/3.11/library/binascii.html#binascii.a2b_base64
"""
s = _bytes_from_decode_data(s)
+ if validate is _NOT_SPECIFIED:
+ validate = ignorechars is not _NOT_SPECIFIED
+ if ignorechars is _NOT_SPECIFIED:
+ ignorechars = b''
+ badchar = None
+ badchar_strict = False
if altchars is not None:
altchars = _bytes_from_decode_data(altchars)
- assert len(altchars) == 2, repr(altchars)
+ if len(altchars) != 2:
+ raise ValueError(f'invalid altchars: {altchars!r}')
+ for b in b'+/':
+ if b not in altchars and b in s:
+ if badchar is None:
+ badchar = b
+ if not validate:
+ break
+ if not isinstance(ignorechars, (bytes, bytearray)):
+ ignorechars = memoryview(ignorechars).cast('B')
+ if b not in ignorechars:
+ badchar_strict = True
+ badchar = b
+ break
s = s.translate(bytes.maketrans(altchars, b'+/'))
- return binascii.a2b_base64(s, strict_mode=validate)
+ result = binascii.a2b_base64(s, strict_mode=validate,
+ ignorechars=ignorechars)
+ if badchar is not None:
+ import warnings
+ if badchar_strict:
+ warnings.warn(f'invalid character {chr(badchar)!a} in Base64 data '
+ f'with altchars={altchars!r} and validate=True '
+ f'will be an error in future Python versions',
+ DeprecationWarning, stacklevel=2)
+ else:
+ ignorechars = bytes(ignorechars)
+ if ignorechars:
+ warnings.warn(f'invalid character {chr(badchar)!a} in Base64 data '
+ f'with altchars={altchars!r} '
+ f'and ignorechars={ignorechars!r} '
+ f'will be discarded in future Python versions',
+ FutureWarning, stacklevel=2)
+ else:
+ warnings.warn(f'invalid character {chr(badchar)!a} in Base64 data '
+ f'with altchars={altchars!r} and validate=False '
+ f'will be discarded in future Python versions',
+ FutureWarning, stacklevel=2)
+ return result
def standard_b64encode(s):
@@ -127,8 +177,19 @@ def urlsafe_b64decode(s):
The alphabet uses '-' instead of '+' and '_' instead of '/'.
"""
s = _bytes_from_decode_data(s)
+ badchar = None
+ for b in b'+/':
+ if b in s:
+ badchar = b
+ break
s = s.translate(_urlsafe_decode_translation)
- return b64decode(s)
+ result = binascii.a2b_base64(s, strict_mode=False)
+ if badchar is not None:
+ import warnings
+ warnings.warn(f'invalid character {chr(badchar)!a} in URL-safe Base64 data '
+ f'will be discarded in future Python versions',
+ FutureWarning, stacklevel=2)
+ return result
@@ -327,9 +388,8 @@ def a85encode(b, *, foldspaces=False, wrapcol=0, pad=False, adobe=False):
instead of 4 consecutive spaces (ASCII 0x20) as supported by 'btoa'. This
feature is not supported by the "standard" Adobe encoding.
- wrapcol controls whether the output should have newline (b'\\n') characters
- added to it. If this is non-zero, each output line will be at most this
- many characters long, excluding the trailing newline.
+ If wrapcol is non-zero, insert a newline (b'\\n') character after at most
+ every wrapcol characters.
pad controls whether the input is padded to a multiple of 4 before
encoding. Note that the btoa implementation always pads.
@@ -508,9 +568,9 @@ def b85decode(b):
)
_z85_encode_translation = bytes.maketrans(_b85alphabet, _z85alphabet)
-def z85encode(s):
+def z85encode(s, pad=False):
"""Encode bytes-like object b in z85 format and return a bytes object."""
- return b85encode(s).translate(_z85_encode_translation)
+ return b85encode(s, pad).translate(_z85_encode_translation)
def z85decode(s):
"""Decode the z85-encoded bytes-like object or ASCII string b
@@ -566,11 +626,10 @@ def encodebytes(s):
"""Encode a bytestring into a bytes object containing multiple lines
of base-64 data."""
_input_type_check(s)
- pieces = []
- for i in range(0, len(s), MAXBINSIZE):
- chunk = s[i : i + MAXBINSIZE]
- pieces.append(binascii.b2a_base64(chunk))
- return b"".join(pieces)
+ result = binascii.b2a_base64(s, wrapcol=MAXLINESIZE)
+ if result == b'\n':
+ return b''
+ return result
def decodebytes(s):
diff --git a/Lib/configparser.py b/Lib/configparser.py
index 18af1eadaad111..d435a5c2fe0da2 100644
--- a/Lib/configparser.py
+++ b/Lib/configparser.py
@@ -794,7 +794,8 @@ def read_dict(self, dictionary, source=''):
"""
elements_added = set()
for section, keys in dictionary.items():
- section = str(section)
+ if section is not UNNAMED_SECTION:
+ section = str(section)
try:
self.add_section(section)
except (DuplicateSectionError, ValueError):
diff --git a/Lib/copy.py b/Lib/copy.py
index fff7e93c2a1b89..4c024ab5311d2d 100644
--- a/Lib/copy.py
+++ b/Lib/copy.py
@@ -230,7 +230,7 @@ def _reconstruct(x, memo, func, args,
*, deepcopy=deepcopy):
deep = memo is not None
if deep and args:
- args = (deepcopy(arg, memo) for arg in args)
+ args = [deepcopy(arg, memo) for arg in args]
y = func(*args)
if deep:
memo[id(x)] = y
diff --git a/Lib/ctypes/__init__.py b/Lib/ctypes/__init__.py
index ab5b656e6e5d6c..aec92f3aee2472 100644
--- a/Lib/ctypes/__init__.py
+++ b/Lib/ctypes/__init__.py
@@ -5,12 +5,9 @@
import sysconfig as _sysconfig
import types as _types
-__version__ = "1.1.0"
-
from _ctypes import Union, Structure, Array
from _ctypes import _Pointer
from _ctypes import CFuncPtr as _CFuncPtr
-from _ctypes import __version__ as _ctypes_version
from _ctypes import RTLD_LOCAL, RTLD_GLOBAL
from _ctypes import ArgumentError
from _ctypes import SIZEOF_TIME_T
@@ -18,9 +15,6 @@
from struct import calcsize as _calcsize
-if __version__ != _ctypes_version:
- raise Exception("Version number mismatch", __version__, _ctypes_version)
-
if _os.name == "nt":
from _ctypes import COMError, CopyComPointer, FormatError
@@ -673,3 +667,12 @@ def DllCanUnloadNow():
raise SystemError(f"Unexpected sizeof(time_t): {SIZEOF_TIME_T=}")
_reset_cache()
+
+
+def __getattr__(name):
+ if name == "__version__":
+ from warnings import _deprecated
+
+ _deprecated("__version__", remove=(3, 20))
+ return "1.1.0" # Do not change
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
diff --git a/Lib/dbm/dumb.py b/Lib/dbm/dumb.py
index 1bc239a84fff83..c1c38da5101a57 100644
--- a/Lib/dbm/dumb.py
+++ b/Lib/dbm/dumb.py
@@ -9,7 +9,7 @@
- seems to contain a bug when updating...
- reclaim free space (currently, space once occupied by deleted or expanded
-items is not reused exept if .reorganize() is called)
+items is not reused except if .reorganize() is called)
- support concurrent access (currently, if two processes take turns making
updates, they can mess up the index)
diff --git a/Lib/difflib.py b/Lib/difflib.py
index 4a0600e4ebb01b..7c7e233b013a76 100644
--- a/Lib/difflib.py
+++ b/Lib/difflib.py
@@ -638,15 +638,15 @@ def quick_ratio(self):
# avail[x] is the number of times x appears in 'b' less the
# number of times we've seen it in 'a' so far ... kinda
avail = {}
- availhas, matches = avail.__contains__, 0
+ matches = 0
for elt in self.a:
- if availhas(elt):
+ if elt in avail:
numb = avail[elt]
else:
numb = fullbcount.get(elt, 0)
avail[elt] = numb - 1
if numb > 0:
- matches = matches + 1
+ matches += 1
return _calculate_ratio(matches, len(self.a) + len(self.b))
def real_quick_ratio(self):
@@ -702,10 +702,12 @@ def get_close_matches(word, possibilities, n=3, cutoff=0.6):
s.set_seq2(word)
for x in possibilities:
s.set_seq1(x)
- if s.real_quick_ratio() >= cutoff and \
- s.quick_ratio() >= cutoff and \
- s.ratio() >= cutoff:
- result.append((s.ratio(), x))
+ if s.real_quick_ratio() < cutoff or s.quick_ratio() < cutoff:
+ continue
+
+ ratio = s.ratio()
+ if ratio >= cutoff:
+ result.append((ratio, x))
# Move the best scorers to head of list
result = _nlargest(n, result)
diff --git a/Lib/email/_encoded_words.py b/Lib/email/_encoded_words.py
index 6795a606de037e..05a34a4c105233 100644
--- a/Lib/email/_encoded_words.py
+++ b/Lib/email/_encoded_words.py
@@ -219,7 +219,7 @@ def encode(string, charset='utf-8', encoding=None, lang=''):
"""
if charset == 'unknown-8bit':
- bstring = string.encode('ascii', 'surrogateescape')
+ bstring = string.encode('utf-8', 'surrogateescape')
else:
bstring = string.encode(charset)
if encoding is None:
diff --git a/Lib/email/_header_value_parser.py b/Lib/email/_header_value_parser.py
index 46fef2048babe7..172f9ef9e5f096 100644
--- a/Lib/email/_header_value_parser.py
+++ b/Lib/email/_header_value_parser.py
@@ -101,6 +101,12 @@ def make_quoted_pairs(value):
return str(value).replace('\\', '\\\\').replace('"', '\\"')
+def make_parenthesis_pairs(value):
+ """Escape parenthesis and backslash for use within a comment."""
+ return str(value).replace('\\', '\\\\') \
+ .replace('(', '\\(').replace(')', '\\)')
+
+
def quote_string(value):
escaped = make_quoted_pairs(value)
return f'"{escaped}"'
@@ -943,7 +949,7 @@ def value(self):
return ' '
def startswith_fws(self):
- return True
+ return self and self[0] in WSP
class ValueTerminal(Terminal):
@@ -2963,6 +2969,13 @@ def _refold_parse_tree(parse_tree, *, policy):
[ValueTerminal(make_quoted_pairs(p), 'ptext')
for p in newparts] +
[ValueTerminal('"', 'ptext')])
+ if part.token_type == 'comment':
+ newparts = (
+ [ValueTerminal('(', 'ptext')] +
+ [ValueTerminal(make_parenthesis_pairs(p), 'ptext')
+ if p.token_type == 'ptext' else p
+ for p in newparts] +
+ [ValueTerminal(')', 'ptext')])
if not part.as_ew_allowed:
wrap_as_ew_blocked += 1
newparts.append(end_ew_not_allowed)
diff --git a/Lib/email/base64mime.py b/Lib/email/base64mime.py
index a5a3f737a97b51..5766f9ad655bc3 100644
--- a/Lib/email/base64mime.py
+++ b/Lib/email/base64mime.py
@@ -83,16 +83,15 @@ def body_encode(s, maxlinelen=76, eol=NL):
if not s:
return ""
- encvec = []
- max_unencoded = maxlinelen * 3 // 4
- for i in range(0, len(s), max_unencoded):
- # BAW: should encode() inherit b2a_base64()'s dubious behavior in
- # adding a newline to the encoded string?
- enc = b2a_base64(s[i:i + max_unencoded]).decode("ascii")
- if enc.endswith(NL) and eol != NL:
- enc = enc[:-1] + eol
- encvec.append(enc)
- return EMPTYSTRING.join(encvec)
+ if not eol:
+ return b2a_base64(s, newline=False).decode("ascii")
+
+ # BAW: should encode() inherit b2a_base64()'s dubious behavior in
+ # adding a newline to the encoded string?
+ enc = b2a_base64(s, wrapcol=maxlinelen).decode("ascii")
+ if eol != NL:
+ enc = enc.replace(NL, eol)
+ return enc
def decode(string):
diff --git a/Lib/email/contentmanager.py b/Lib/email/contentmanager.py
index 11d1536db27d79..13fcb9787f1f32 100644
--- a/Lib/email/contentmanager.py
+++ b/Lib/email/contentmanager.py
@@ -129,19 +129,6 @@ def _finalize_set(msg, disposition, filename, cid, params):
msg.set_param(key, value)
-# XXX: This is a cleaned-up version of base64mime.body_encode (including a bug
-# fix in the calculation of unencoded_bytes_per_line). It would be nice to
-# drop both this and quoprimime.body_encode in favor of enhanced binascii
-# routines that accepted a max_line_length parameter.
-def _encode_base64(data, max_line_length):
- encoded_lines = []
- unencoded_bytes_per_line = max_line_length // 4 * 3
- for i in range(0, len(data), unencoded_bytes_per_line):
- thisline = data[i:i+unencoded_bytes_per_line]
- encoded_lines.append(binascii.b2a_base64(thisline).decode('ascii'))
- return ''.join(encoded_lines)
-
-
def _encode_text(string, charset, cte, policy):
# If max_line_length is 0 or None, there is no limit.
maxlen = policy.max_line_length or sys.maxsize
@@ -176,7 +163,7 @@ def normal_body(lines): return b'\n'.join(lines) + b'\n'
data = quoprimime.body_encode(normal_body(lines).decode('latin-1'),
maxlen)
elif cte == 'base64':
- data = _encode_base64(embedded_body(lines), maxlen)
+ data = binascii.b2a_base64(embedded_body(lines), wrapcol=maxlen).decode('ascii')
else:
raise ValueError("Unknown content transfer encoding {}".format(cte))
return cte, data
@@ -234,7 +221,8 @@ def set_bytes_content(msg, data, maintype, subtype, cte='base64',
params=None, headers=None):
_prepare_set(msg, maintype, subtype, headers)
if cte == 'base64':
- data = _encode_base64(data, max_line_length=msg.policy.max_line_length)
+ data = binascii.b2a_base64(data, wrapcol=msg.policy.max_line_length)
+ data = data.decode('ascii')
elif cte == 'quoted-printable':
# XXX: quoprimime.body_encode won't encode newline characters in data,
# so we can't use it. This means max_line_length is ignored. Another
diff --git a/Lib/email/generator.py b/Lib/email/generator.py
index 03524c96559153..cebbc416087fee 100644
--- a/Lib/email/generator.py
+++ b/Lib/email/generator.py
@@ -22,6 +22,7 @@
NLCRE = re.compile(r'\r\n|\r|\n')
fcre = re.compile(r'^From ', re.MULTILINE)
NEWLINE_WITHOUT_FWSP = re.compile(r'\r\n[^ \t]|\r[^ \n\t]|\n[^ \t]')
+NEWLINE_WITHOUT_FWSP_BYTES = re.compile(br'\r\n[^ \t]|\r[^ \n\t]|\n[^ \t]')
class Generator:
@@ -429,7 +430,16 @@ def _write_headers(self, msg):
# This is almost the same as the string version, except for handling
# strings with 8bit bytes.
for h, v in msg.raw_items():
- self._fp.write(self.policy.fold_binary(h, v))
+ folded = self.policy.fold_binary(h, v)
+ if self.policy.verify_generated_headers:
+ linesep = self.policy.linesep.encode()
+ if not folded.endswith(linesep):
+ raise HeaderWriteError(
+ f'folded header does not end with {linesep!r}: {folded!r}')
+ if NEWLINE_WITHOUT_FWSP_BYTES.search(folded.removesuffix(linesep)):
+ raise HeaderWriteError(
+ f'folded header contains newline: {folded!r}')
+ self._fp.write(folded)
# A blank line always separates headers from body
self.write(self._NL)
diff --git a/Lib/enum.py b/Lib/enum.py
index 15dddf6de69268..025e973446d88d 100644
--- a/Lib/enum.py
+++ b/Lib/enum.py
@@ -130,7 +130,7 @@ def show_flag_values(value):
def bin(num, max_bits=None):
"""
Like built-in bin(), except negative values are represented in
- twos-compliment, and the leading bit always indicates sign
+ twos-complement, and the leading bit always indicates sign
(0=positive, 1=negative).
>>> bin(10)
@@ -139,6 +139,7 @@ def bin(num, max_bits=None):
'0b1 0101'
"""
+ num = num.__index__()
ceiling = 2 ** (num).bit_length()
if num >= 0:
s = bltns.bin(num + ceiling).replace('1', '0', 1)
diff --git a/Lib/functools.py b/Lib/functools.py
index 836eb680ccd4d4..59fc2a8fbf6219 100644
--- a/Lib/functools.py
+++ b/Lib/functools.py
@@ -517,7 +517,7 @@ def _unwrap_partialmethod(func):
### LRU Cache function decorator
################################################################################
-_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])
+_CacheInfo = namedtuple("CacheInfo", ("hits", "misses", "maxsize", "currsize"))
def _make_key(args, kwds, typed,
kwd_mark = (object(),),
@@ -539,13 +539,15 @@ def _make_key(args, kwds, typed,
# distinct call from f(y=2, x=1) which will be cached separately.
key = args
if kwds:
+ key = list(key)
key += kwd_mark
for item in kwds.items():
key += item
+ key = tuple(key)
if typed:
- key += tuple(type(v) for v in args)
+ key += tuple([type(v) for v in args])
if kwds:
- key += tuple(type(v) for v in kwds.values())
+ key += tuple([type(v) for v in kwds.values()])
elif len(key) == 1 and type(key[0]) in fasttypes:
return key[0]
return key
@@ -600,6 +602,9 @@ def decorating_function(user_function):
return decorating_function
def _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo):
+ if not callable(user_function):
+ raise TypeError("the first argument must be callable")
+
# Constants shared by all lru cache instances:
sentinel = object() # unique object used to signal cache misses
make_key = _make_key # build a key from the function arguments
diff --git a/Lib/graphlib.py b/Lib/graphlib.py
index 7961c9c5cac2d6..af5245ccbcd3a8 100644
--- a/Lib/graphlib.py
+++ b/Lib/graphlib.py
@@ -199,6 +199,7 @@ def done(self, *nodes):
self._ready_nodes.append(successor)
self._nfinished += 1
+ # See note "On Finding Cycles" at the bottom.
def _find_cycle(self):
n2i = self._node2info
stack = []
@@ -212,8 +213,6 @@ def _find_cycle(self):
while True:
if node in seen:
- # If we have seen already the node and is in the
- # current stack we have found a cycle.
if node in node2stacki:
return stack[node2stacki[node] :] + [node]
# else go on to get next successor
@@ -228,11 +227,15 @@ def _find_cycle(self):
while stack:
try:
node = itstack[-1]()
- break
+ break # resume at top of "while True:"
except StopIteration:
+ # no more successors; pop the stack
+ # and continue looking up
del node2stacki[stack.pop()]
itstack.pop()
else:
+ # stack is empty; look for a fresh node to
+ # start over from (a node not yet in seen)
break
return None
@@ -252,3 +255,55 @@ def static_order(self):
self.done(*node_group)
__class_getitem__ = classmethod(GenericAlias)
+
+
+# On Finding Cycles
+# -----------------
+# There is a (at least one) total order if and only if the graph is
+# acyclic.
+#
+# When it is cyclic, "there's a cycle - somewhere!" isn't very helpful.
+# In theory, it would be most helpful to partition the graph into
+# strongly connected components (SCCs) and display those with more than
+# one node. Then all cycles could easily be identified "by eyeball".
+#
+# That's a lot of work, though, and we can get most of the benefit much
+# more easily just by showing a single specific cycle.
+#
+# Approaches to that are based on breadth first or depth first search
+# (BFS or DFS). BFS is most natural, which can easily be arranged to
+# find a shortest-possible cycle. But memory burden can be high, because
+# every path-in-progress has to keep its own idea of what "the path" is
+# so far.
+#
+# DFS is much easier on RAM, only requiring keeping track of _the_ path
+# from the starting node to the current node at the current recursion
+# level. But there may be any number of nodes, and so there's no bound
+# on recursion depth short of the total number of nodes.
+#
+# So we use an iterative version of DFS, keeping an exploit list
+# (`stack`) of the path so far. A parallel stack (`itstack`) holds the
+# `__next__` method of an iterator over the current level's node's
+# successors, so when backtracking to a shallower level we can just call
+# that to get the node's next successor. This is state that a recursive
+# version would implicitly store in a `for` loop's internals.
+#
+# `seen()` is a set recording which nodes have already been, at some
+# time, pushed on the stack. If a node has been pushed on the stack, DFS
+# will find any cycle it's part of, so there's no need to ever look at
+# it again.
+#
+# Finally, `node2stacki` maps a node to its index on the current stack,
+# for and only for nodes currently _on_ the stack. If a successor to be
+# pushed on the stack is in that dict, the node is already on the path,
+# at that index. The cycle is then `stack[that_index :] + [node]`.
+#
+# As is often the case when removing recursion, the control flow looks a
+# bit off. The "while True:" loop here rarely actually loops - it's only
+# looking to go "up the stack" until finding a level that has another
+# successor to consider, emulating a chain of returns in a recursive
+# version.
+#
+# Worst cases: O(V+E) for time, and O(V) for memory, where V is the
+# number of nodes and E the number of edges (which may be quadratic in
+# V!). It requires care to ensure these bounds are met.
diff --git a/Lib/hmac.py b/Lib/hmac.py
index 9d3fae8b1b1597..e0c040bcd5fe3d 100644
--- a/Lib/hmac.py
+++ b/Lib/hmac.py
@@ -171,6 +171,7 @@ def copy(self):
# Call __new__ directly to avoid the expensive __init__.
other = self.__class__.__new__(self.__class__)
other.digest_size = self.digest_size
+ other.block_size = self.block_size
if self._hmac:
other._hmac = self._hmac.copy()
other._inner = other._outer = None
diff --git a/Lib/http/cookies.py b/Lib/http/cookies.py
index 74349bb63d66e2..917280037d4dbb 100644
--- a/Lib/http/cookies.py
+++ b/Lib/http/cookies.py
@@ -87,9 +87,9 @@
such trickeries do not confuse it.
>>> C = cookies.SimpleCookie()
- >>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=\\012;";')
+ >>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=;";')
>>> print(C)
- Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;"
+ Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=;"
Each element of the Cookie also supports all of the RFC 2109
Cookie attributes. Here's an example which sets the Path
@@ -170,6 +170,15 @@ class CookieError(Exception):
})
_is_legal_key = re.compile('[%s]+' % re.escape(_LegalChars)).fullmatch
+_control_character_re = re.compile(r'[\x00-\x1F\x7F]')
+
+
+def _has_control_character(*val):
+ """Detects control characters within a value.
+ Supports any type, as header values can be any type.
+ """
+ return any(_control_character_re.search(str(v)) for v in val)
+
def _quote(str):
r"""Quote a string for use in a cookie header.
@@ -294,12 +303,16 @@ def __setitem__(self, K, V):
K = K.lower()
if not K in self._reserved:
raise CookieError("Invalid attribute %r" % (K,))
+ if _has_control_character(K, V):
+ raise CookieError(f"Control characters are not allowed in cookies {K!r} {V!r}")
dict.__setitem__(self, K, V)
def setdefault(self, key, val=None):
key = key.lower()
if key not in self._reserved:
raise CookieError("Invalid attribute %r" % (key,))
+ if _has_control_character(key, val):
+ raise CookieError("Control characters are not allowed in cookies %r %r" % (key, val,))
return dict.setdefault(self, key, val)
def __eq__(self, morsel):
@@ -335,6 +348,9 @@ def set(self, key, val, coded_val):
raise CookieError('Attempt to set a reserved key %r' % (key,))
if not _is_legal_key(key):
raise CookieError('Illegal key %r' % (key,))
+ if _has_control_character(key, val, coded_val):
+ raise CookieError(
+ "Control characters are not allowed in cookies %r %r %r" % (key, val, coded_val,))
# It's a good key, so save it.
self._key = key
@@ -488,7 +504,10 @@ def output(self, attrs=None, header="Set-Cookie:", sep="\015\012"):
result = []
items = sorted(self.items())
for key, value in items:
- result.append(value.output(attrs, header))
+ value_output = value.output(attrs, header)
+ if _has_control_character(value_output):
+ raise CookieError("Control characters are not allowed in cookies")
+ result.append(value_output)
return sep.join(result)
__str__ = output
diff --git a/Lib/http/server.py b/Lib/http/server.py
index 160d3eefc7cbdf..9c9cfbce421343 100644
--- a/Lib/http/server.py
+++ b/Lib/http/server.py
@@ -61,8 +61,6 @@
# (Actually, the latter is only true if you know the server configuration
# at the time the request was made!)
-__version__ = "0.6"
-
__all__ = [
"HTTPServer", "ThreadingHTTPServer",
"HTTPSServer", "ThreadingHTTPSServer",
@@ -280,7 +278,7 @@ class BaseHTTPRequestHandler(socketserver.StreamRequestHandler):
# The server software version. You may want to override this.
# The format is multiple whitespace-separated strings,
# where each string is of the form name[/version].
- server_version = "BaseHTTP/" + __version__
+ server_version = "BaseHTTP"
error_message_format = DEFAULT_ERROR_MESSAGE
error_content_type = DEFAULT_ERROR_CONTENT_TYPE
@@ -690,7 +688,7 @@ class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
"""
- server_version = "SimpleHTTP/" + __version__
+ server_version = "SimpleHTTP"
index_pages = ("index.html", "index.htm")
extensions_map = _encodings_map_default = {
'.gz': 'application/gzip',
@@ -1080,5 +1078,14 @@ class HTTPSDualStackServer(DualStackServerMixin, ThreadingHTTPSServer):
)
+def __getattr__(name):
+ if name == "__version__":
+ from warnings import _deprecated
+
+ _deprecated("__version__", remove=(3, 20))
+ return "0.6" # Do not change
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
+
+
if __name__ == '__main__':
_main()
diff --git a/Lib/idlelib/News3.txt b/Lib/idlelib/News3.txt
index 53d83762f99ec5..0f61da8368f211 100644
--- a/Lib/idlelib/News3.txt
+++ b/Lib/idlelib/News3.txt
@@ -1,9 +1,20 @@
+What's New in IDLE 3.15.0
+(since 3.14.0)
+Released on 2026-10-01
+=========================
+
+
+gh-143774: Better explain the operation of Format / Format Paragraph.
+Patch by Terry J. Reedy.
+
+gh-139742: Colorize t-string prefixes for template strings in IDLE,
+as done for f-string prefixes. Patch by Anuradha Agrawal.
+
What's New in IDLE 3.14.0
(since 3.13.0)
Released on 2025-10-07
=========================
-
gh-129873: Simplify displaying the IDLE doc by only copying the text
section of idle.html to idlelib/help.html. Patch by Stan Ulbrych.
diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html
index fc618ab727d1fb..eda16ac5bed118 100644
--- a/Lib/idlelib/help.html
+++ b/Lib/idlelib/help.html
@@ -16,6 +16,12 @@
of global and local namespaces
configuration, browsers, and other dialogs
+
The IDLE application is implemented in the idlelib package.
+
This is an optional module.
+If it is missing from your copy of CPython,
+look for documentation from your distributor (that is,
+whoever provided Python to you).
+If you are the distributor, see Requirements for optional modules.
IDLE has two main window types, the Shell window and the Editor window. It is
@@ -105,14 +111,14 @@
Edit menu (Shell and Editor)Completions in the Editing and navigation section below.
+Completions in the Editing and Navigation section below.
Expand Word
Expand a prefix you have typed to match a full word in the same window;
repeat to get a different expansion.
Show Call Tip
After an unclosed parenthesis for a function, open a small window with
function parameter hints. See Calltips in the
-Editing and navigation section below.
Reformat the current blank-line-delimited paragraph in comment block or
-multiline string or selected line in a string. All lines in the
-paragraph will be formatted to less than N columns, where N defaults to 72.
+
Format Paragraph
Rewrap the text block containing the text insert cursor.
+Avoid code lines. See Format block in the
+Editing and Navigation section below.
Indent Region
Shift selected lines right by the indent width (default 4 spaces).
Reformat Paragraph rewraps a block (‘paragraph’) of contiguous equally
+indented non-blank comments, a similar block of text within a multiline
+string, or a selected subset of either.
+If needed, add a blank line to separate string from code.
+Partial lines in a selection expand to complete lines.
+The resulting lines have the same indent as before
+but have maximum total length of N columns (characters).
+Change the default N of 72 on the Window tab of IDLE Settings.
Within an editor window containing Python code, code context can be toggled
in order to show or hide a pane at the top of the window. When shown, this
pane freezes the opening lines for block code, such as those beginning with
@@ -516,7 +533,7 @@