From 7a10cdec359750b5154490fa9e24475c90d05aab Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Date: Thu, 10 Oct 2024 10:34:55 +0100 Subject: [PATCH 001/170] Pin the doctest workflow to Ubuntu 22.04 (#125236) --- .github/workflows/reusable-docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/reusable-docs.yml b/.github/workflows/reusable-docs.yml index 4b021b3dc32f15..7755cb431bd301 100644 --- a/.github/workflows/reusable-docs.yml +++ b/.github/workflows/reusable-docs.yml @@ -95,7 +95,7 @@ jobs: # Run "doctest" on HEAD as new syntax doesn't exist in the latest stable release doctest: name: 'Doctest' - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 timeout-minutes: 60 steps: - uses: actions/checkout@v4 From 1639d934b9180c278ac9c02be43cbb1beada494a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 10 Oct 2024 12:11:06 +0200 Subject: [PATCH 002/170] gh-125196: Add a free list to PyUnicodeWriter (#125227) --- Include/internal/pycore_freelist_state.h | 2 ++ Objects/object.c | 1 + Objects/unicodeobject.c | 13 +++++++++---- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Include/internal/pycore_freelist_state.h b/Include/internal/pycore_freelist_state.h index 762c583ce94e9a..4e04cf431e0b31 100644 --- a/Include/internal/pycore_freelist_state.h +++ b/Include/internal/pycore_freelist_state.h @@ -20,6 +20,7 @@ extern "C" { # define Py_async_gen_asends_MAXFREELIST 80 # define Py_futureiters_MAXFREELIST 255 # define Py_object_stack_chunks_MAXFREELIST 4 +# define Py_unicode_writers_MAXFREELIST 1 // A generic freelist of either PyObjects or other data structures. struct _Py_freelist { @@ -44,6 +45,7 @@ struct _Py_freelists { struct _Py_freelist async_gen_asends; struct _Py_freelist futureiters; struct _Py_freelist object_stack_chunks; + struct _Py_freelist unicode_writers; }; #ifdef __cplusplus diff --git a/Objects/object.c b/Objects/object.c index 8d809158a6c1da..a97a900890320d 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -862,6 +862,7 @@ _PyObject_ClearFreeLists(struct _Py_freelists *freelists, int is_finalization) // stacks during GC, so emptying the free-list is counterproductive. clear_freelist(&freelists->object_stack_chunks, 1, PyMem_RawFree); } + clear_freelist(&freelists->unicode_writers, is_finalization, PyMem_Free); } /* diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 93c1025b6a3cae..b94a74c2c688a9 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -46,6 +46,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "pycore_codecs.h" // _PyCodec_Lookup() #include "pycore_critical_section.h" // Py_*_CRITICAL_SECTION_SEQUENCE_FAST #include "pycore_format.h" // F_LJUST +#include "pycore_freelist.h" // _Py_FREELIST_FREE(), _Py_FREELIST_POP() #include "pycore_initconfig.h" // _PyStatus_OK() #include "pycore_interp.h" // PyInterpreterState.fs_codec #include "pycore_long.h" // _PyLong_FormatWriter() @@ -13436,9 +13437,13 @@ PyUnicodeWriter_Create(Py_ssize_t length) } const size_t size = sizeof(_PyUnicodeWriter); - PyUnicodeWriter *pub_writer = (PyUnicodeWriter *)PyMem_Malloc(size); + PyUnicodeWriter *pub_writer; + pub_writer = _Py_FREELIST_POP_MEM(unicode_writers); if (pub_writer == NULL) { - return (PyUnicodeWriter *)PyErr_NoMemory(); + pub_writer = (PyUnicodeWriter *)PyMem_Malloc(size); + if (pub_writer == NULL) { + return (PyUnicodeWriter *)PyErr_NoMemory(); + } } _PyUnicodeWriter *writer = (_PyUnicodeWriter *)pub_writer; @@ -13459,7 +13464,7 @@ void PyUnicodeWriter_Discard(PyUnicodeWriter *writer) return; } _PyUnicodeWriter_Dealloc((_PyUnicodeWriter*)writer); - PyMem_Free(writer); + _Py_FREELIST_FREE(unicode_writers, writer, PyMem_Free); } @@ -13881,7 +13886,7 @@ PyUnicodeWriter_Finish(PyUnicodeWriter *writer) { PyObject *str = _PyUnicodeWriter_Finish((_PyUnicodeWriter*)writer); assert(((_PyUnicodeWriter*)writer)->buffer == NULL); - PyMem_Free(writer); + _Py_FREELIST_FREE(unicode_writers, writer, PyMem_Free); return str; } From 82dfdc328779778295075d791ee30a0308fb9af4 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 10 Oct 2024 12:20:53 +0200 Subject: [PATCH 003/170] gh-125196: Use PyUnicodeWriter for repr(tuple) (#125242) --- Objects/tupleobject.c | 50 +++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 47134697918052..f3132e0933ac30 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -232,56 +232,54 @@ tuple_repr(PyObject *self) return res > 0 ? PyUnicode_FromString("(...)") : NULL; } - _PyUnicodeWriter writer; - _PyUnicodeWriter_Init(&writer); - writer.overallocate = 1; + Py_ssize_t prealloc; if (n > 1) { - /* "(" + "1" + ", 2" * (len - 1) + ")" */ - writer.min_length = 1 + 1 + (2 + 1) * (n - 1) + 1; + // "(" + "1" + ", 2" * (len - 1) + ")" + prealloc = 1 + 1 + (2 + 1) * (n - 1) + 1; } else { - /* "(1,)" */ - writer.min_length = 4; + // "(1,)" + prealloc = 4; + } + PyUnicodeWriter *writer = PyUnicodeWriter_Create(prealloc); + if (writer == NULL) { + goto error; } - if (_PyUnicodeWriter_WriteChar(&writer, '(') < 0) + if (PyUnicodeWriter_WriteChar(writer, '(') < 0) { goto error; + } /* Do repr() on each element. */ for (Py_ssize_t i = 0; i < n; ++i) { - PyObject *s; - if (i > 0) { - if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ", 2) < 0) + if (PyUnicodeWriter_WriteChar(writer, ',') < 0) { goto error; + } + if (PyUnicodeWriter_WriteChar(writer, ' ') < 0) { + goto error; + } } - s = PyObject_Repr(v->ob_item[i]); - if (s == NULL) - goto error; - - if (_PyUnicodeWriter_WriteStr(&writer, s) < 0) { - Py_DECREF(s); + if (PyUnicodeWriter_WriteRepr(writer, v->ob_item[i]) < 0) { goto error; } - Py_DECREF(s); } - writer.overallocate = 0; - if (n > 1) { - if (_PyUnicodeWriter_WriteChar(&writer, ')') < 0) + if (n == 1) { + if (PyUnicodeWriter_WriteChar(writer, ',') < 0) { goto error; + } } - else { - if (_PyUnicodeWriter_WriteASCIIString(&writer, ",)", 2) < 0) - goto error; + if (PyUnicodeWriter_WriteChar(writer, ')') < 0) { + goto error; } Py_ReprLeave((PyObject *)v); - return _PyUnicodeWriter_Finish(&writer); + return PyUnicodeWriter_Finish(writer); error: - _PyUnicodeWriter_Dealloc(&writer); + PyUnicodeWriter_Discard(writer); Py_ReprLeave((PyObject *)v); return NULL; } From f9ae5d1cee2f8927a71cd4f1f66f10050a4f658a Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Thu, 10 Oct 2024 11:21:12 +0100 Subject: [PATCH 004/170] gh-71784: [doc] add usage examples for traceback.TracebackException (#125189) Co-authored-by: Alex Waygood --- Doc/library/traceback.rst | 133 +++++++++++++++++++++++++++++++++----- 1 file changed, 118 insertions(+), 15 deletions(-) diff --git a/Doc/library/traceback.rst b/Doc/library/traceback.rst index 401e12be45f418..100a92b73d5497 100644 --- a/Doc/library/traceback.rst +++ b/Doc/library/traceback.rst @@ -8,11 +8,15 @@ -------------- -This module provides a standard interface to extract, format and print stack -traces of Python programs. It exactly mimics the behavior of the Python -interpreter when it prints a stack trace. This is useful when you want to print -stack traces under program control, such as in a "wrapper" around the -interpreter. +This module provides a standard interface to extract, format and print +stack traces of Python programs. It is more flexible than the +interpreter's default traceback display, and therefore makes it +possible to configure certain aspects of the output. Finally, +it contains a utility for capturing enough information about an +exception to print it later, without the need to save a reference +to the actual exception. Since exceptions can be the roots of large +objects graph, this utility can significantly improve +memory management. .. index:: pair: object; traceback @@ -29,7 +33,20 @@ which are assigned to the :attr:`~BaseException.__traceback__` field of Module :mod:`pdb` Interactive source code debugger for Python programs. -The module defines the following functions: +The module's API can be divided into two parts: + +* Module-level functions offering basic functionality, which are useful for interactive + inspection of exceptions and tracebacks. + +* :class:`TracebackException` class and its helper classes + :class:`StackSummary` and :class:`FrameSummary`. These offer both more + flexibility in the output generated and the ability to store the information + necessary for later formatting without holding references to actual exception + and traceback objects. + + +Module-Level Functions +---------------------- .. function:: print_tb(tb, limit=None, file=None) @@ -237,7 +254,6 @@ The module defines the following functions: .. versionadded:: 3.5 -The module also defines the following classes: :class:`!TracebackException` Objects ------------------------------------ @@ -245,12 +261,17 @@ The module also defines the following classes: .. versionadded:: 3.5 :class:`!TracebackException` objects are created from actual exceptions to -capture data for later printing in a lightweight fashion. +capture data for later printing. They offer a more lightweight method of +storing this information by avoiding holding references to +:ref:`traceback` and :ref:`frame` objects +In addition, they expose more options to configure the output compared to +the module-level functions described above. .. class:: TracebackException(exc_type, exc_value, exc_traceback, *, limit=None, lookup_lines=True, capture_locals=False, compact=False, max_group_width=15, max_group_depth=10) - Capture an exception for later rendering. *limit*, *lookup_lines* and - *capture_locals* are as for the :class:`StackSummary` class. + Capture an exception for later rendering. The meaning of *limit*, + *lookup_lines* and *capture_locals* are as for the :class:`StackSummary` + class. If *compact* is true, only data that is required by :class:`!TracebackException`'s :meth:`format` method @@ -509,8 +530,8 @@ in a :ref:`traceback `. .. _traceback-example: -Traceback Examples ------------------- +Examples of Using the Module-Level Functions +-------------------------------------------- This simple example implements a basic read-eval-print loop, similar to (but less useful than) the standard Python interactive interpreter loop. For a more @@ -549,8 +570,7 @@ exception and traceback: try: lumberjack() - except IndexError: - exc = sys.exception() + except IndexError as exc: print("*** print_tb:") traceback.print_tb(exc.__traceback__, limit=1, file=sys.stdout) print("*** print_exception:") @@ -653,5 +673,88 @@ This last example demonstrates the final few formatting functions: [' File "spam.py", line 3, in \n spam.eggs()\n', ' File "eggs.py", line 42, in eggs\n return "bacon"\n'] >>> an_error = IndexError('tuple index out of range') - >>> traceback.format_exception_only(type(an_error), an_error) + >>> traceback.format_exception_only(an_error) ['IndexError: tuple index out of range\n'] + + +Examples of Using :class:`TracebackException` +--------------------------------------------- + +With the helper class, we have more options:: + + >>> import sys + >>> from traceback import TracebackException + >>> + >>> def lumberjack(): + ... bright_side_of_life() + ... + >>> def bright_side_of_life(): + ... t = "bright", "side", "of", "life" + ... return t[5] + ... + >>> try: + ... lumberjack() + ... except IndexError as e: + ... exc = e + ... + >>> try: + ... try: + ... lumberjack() + ... except: + ... 1/0 + ... except Exception as e: + ... chained_exc = e + ... + >>> # limit works as with the module-level functions + >>> TracebackException.from_exception(exc, limit=-2).print() + Traceback (most recent call last): + File "", line 6, in lumberjack + bright_side_of_life() + ~~~~~~~~~~~~~~~~~~~^^ + File "", line 10, in bright_side_of_life + return t[5] + ~^^^ + IndexError: tuple index out of range + + >>> # capture_locals adds local variables in frames + >>> TracebackException.from_exception(exc, limit=-2, capture_locals=True).print() + Traceback (most recent call last): + File "", line 6, in lumberjack + bright_side_of_life() + ~~~~~~~~~~~~~~~~~~~^^ + File "", line 10, in bright_side_of_life + return t[5] + ~^^^ + t = ("bright", "side", "of", "life") + IndexError: tuple index out of range + + >>> # The *chain* kwarg to print() controls whether chained + >>> # exceptions are displayed + >>> TracebackException.from_exception(chained_exc).print() + Traceback (most recent call last): + File "", line 4, in + lumberjack() + ~~~~~~~~~~^^ + File "", line 7, in lumberjack + bright_side_of_life() + ~~~~~~~~~~~~~~~~~~~^^ + File "", line 11, in bright_side_of_life + return t[5] + ~^^^ + IndexError: tuple index out of range + + During handling of the above exception, another exception occurred: + + Traceback (most recent call last): + File "", line 6, in + 1/0 + ~^~ + ZeroDivisionError: division by zero + + >>> TracebackException.from_exception(chained_exc).print(chain=False) + Traceback (most recent call last): + File "", line 6, in + 1/0 + ~^~ + ZeroDivisionError: division by zero + From e4cab488d4445e8444932f3bed1c329c0d9e5038 Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Thu, 10 Oct 2024 21:39:53 +0900 Subject: [PATCH 005/170] gh-124471: Set name for unnamed reusable workflow (#124475) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Co-authored-by: Sviatoslav Sydorenko (Святослав Сидоренко) --- .github/workflows/reusable-change-detection.yml | 4 +--- .github/workflows/reusable-docs.yml | 2 +- .github/workflows/reusable-macos.yml | 2 ++ .github/workflows/reusable-tsan.yml | 2 ++ .github/workflows/reusable-ubuntu.yml | 2 ++ .github/workflows/reusable-wasi.yml | 2 ++ .github/workflows/reusable-windows-msi.yml | 2 +- .github/workflows/reusable-windows.yml | 2 ++ 8 files changed, 13 insertions(+), 5 deletions(-) diff --git a/.github/workflows/reusable-change-detection.yml b/.github/workflows/reusable-change-detection.yml index 6f599f75547ceb..5cd6fb39f1e12f 100644 --- a/.github/workflows/reusable-change-detection.yml +++ b/.github/workflows/reusable-change-detection.yml @@ -1,6 +1,4 @@ ---- - -name: Change detection +name: Reusable change detection on: # yamllint disable-line rule:truthy workflow_call: diff --git a/.github/workflows/reusable-docs.yml b/.github/workflows/reusable-docs.yml index 7755cb431bd301..3809f24dcc977e 100644 --- a/.github/workflows/reusable-docs.yml +++ b/.github/workflows/reusable-docs.yml @@ -1,4 +1,4 @@ -name: Docs +name: Reusable Docs on: workflow_call: diff --git a/.github/workflows/reusable-macos.yml b/.github/workflows/reusable-macos.yml index b4227545887ad1..b3a160fbbf8053 100644 --- a/.github/workflows/reusable-macos.yml +++ b/.github/workflows/reusable-macos.yml @@ -1,3 +1,5 @@ +name: Reusable macOS + on: workflow_call: inputs: diff --git a/.github/workflows/reusable-tsan.yml b/.github/workflows/reusable-tsan.yml index 27f4eacd86fd95..f4c976ca996410 100644 --- a/.github/workflows/reusable-tsan.yml +++ b/.github/workflows/reusable-tsan.yml @@ -1,3 +1,5 @@ +name: Reusable Thread Sanitizer + on: workflow_call: inputs: diff --git a/.github/workflows/reusable-ubuntu.yml b/.github/workflows/reusable-ubuntu.yml index 769f1210de4d3c..0cf40ba8a9b03b 100644 --- a/.github/workflows/reusable-ubuntu.yml +++ b/.github/workflows/reusable-ubuntu.yml @@ -1,3 +1,5 @@ +name: Reusable Ubuntu + on: workflow_call: inputs: diff --git a/.github/workflows/reusable-wasi.yml b/.github/workflows/reusable-wasi.yml index 1b1a68c0badc76..4c8137c958a312 100644 --- a/.github/workflows/reusable-wasi.yml +++ b/.github/workflows/reusable-wasi.yml @@ -1,3 +1,5 @@ +name: Reusable WASI + on: workflow_call: inputs: diff --git a/.github/workflows/reusable-windows-msi.yml b/.github/workflows/reusable-windows-msi.yml index fc34ab7c3eb1f2..abdb1a1982fef8 100644 --- a/.github/workflows/reusable-windows-msi.yml +++ b/.github/workflows/reusable-windows-msi.yml @@ -1,4 +1,4 @@ -name: TestsMSI +name: Reusable Windows MSI on: workflow_call: diff --git a/.github/workflows/reusable-windows.yml b/.github/workflows/reusable-windows.yml index e9c3c8e05a801c..dcfc62d7f5d145 100644 --- a/.github/workflows/reusable-windows.yml +++ b/.github/workflows/reusable-windows.yml @@ -1,3 +1,5 @@ +name: Reusable Windows + on: workflow_call: inputs: From 87d7315ac57250046372b0d9ae4619ba619c8c87 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Thu, 10 Oct 2024 15:42:03 +0300 Subject: [PATCH 006/170] gh-125118: don't copy arbitrary values to _Bool in the struct module (GH-125169) memcopy'ing arbitrary values to _Bool variable triggers undefined behaviour. Avoid this. We assume that `false` is represented by all zero bytes. Credits to Alex Gaynor. Co-authored-by: Sam Gross Co-authored-by: Victor Stinner Co-authored-by: Petr Viktorin --- Lib/test/test_struct.py | 3 +++ .../Library/2024-10-09-07-09-00.gh-issue-125118.J9rQ1S.rst | 1 + Modules/_struct.c | 5 ++--- 3 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-09-07-09-00.gh-issue-125118.J9rQ1S.rst diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py index e3193c7863fbae..04ec3ed0837c82 100644 --- a/Lib/test/test_struct.py +++ b/Lib/test/test_struct.py @@ -540,6 +540,9 @@ def __bool__(self): for c in [b'\x01', b'\x7f', b'\xff', b'\x0f', b'\xf0']: self.assertTrue(struct.unpack('>?', c)[0]) + self.assertTrue(struct.unpack(' Date: Thu, 10 Oct 2024 21:57:13 +0900 Subject: [PATCH 007/170] gh-124153: Simplify PyType_GetBaseByToken (GH-124488) --- Objects/typeobject.c | 123 +++++++++++++++---------------------------- 1 file changed, 43 insertions(+), 80 deletions(-) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 6484e8921f8122..5380633fa1149e 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -5269,11 +5269,10 @@ PyType_GetModuleByDef(PyTypeObject *type, PyModuleDef *def) static PyTypeObject * -get_base_by_token_recursive(PyTypeObject *type, void *token) +get_base_by_token_recursive(PyObject *bases, void *token) { - assert(PyType_GetSlot(type, Py_tp_token) != token); - PyObject *bases = lookup_tp_bases(type); assert(bases != NULL); + PyTypeObject *res = NULL; Py_ssize_t n = PyTuple_GET_SIZE(bases); for (Py_ssize_t i = 0; i < n; i++) { PyTypeObject *base = _PyType_CAST(PyTuple_GET_ITEM(bases, i)); @@ -5281,112 +5280,76 @@ get_base_by_token_recursive(PyTypeObject *type, void *token) continue; } if (((PyHeapTypeObject*)base)->ht_token == token) { - return base; + res = base; + break; } - base = get_base_by_token_recursive(base, token); + base = get_base_by_token_recursive(lookup_tp_bases(base), token); if (base != NULL) { - return base; + res = base; + break; } } - return NULL; + return res; // Prefer to return recursively from one place } -static inline PyTypeObject * -get_base_by_token_from_mro(PyTypeObject *type, void *token) +int +PyType_GetBaseByToken(PyTypeObject *type, void *token, PyTypeObject **result) { - // Bypass lookup_tp_mro() as PyType_IsSubtype() does - PyObject *mro = type->tp_mro; - assert(mro != NULL); - assert(PyTuple_Check(mro)); - // mro_invoke() ensures that the type MRO cannot be empty. - assert(PyTuple_GET_SIZE(mro) >= 1); - // Also, the first item in the MRO is the type itself, which is supposed - // to be already checked by the caller. We skip it in the loop. - assert(PyTuple_GET_ITEM(mro, 0) == (PyObject *)type); - assert(PyType_GetSlot(type, Py_tp_token) != token); - - Py_ssize_t n = PyTuple_GET_SIZE(mro); - for (Py_ssize_t i = 1; i < n; i++) { - PyTypeObject *base = _PyType_CAST(PyTuple_GET_ITEM(mro, i)); - if (!_PyType_HasFeature(base, Py_TPFLAGS_HEAPTYPE)) { - continue; - } - if (((PyHeapTypeObject*)base)->ht_token == token) { - return base; - } + if (result != NULL) { + *result = NULL; } - return NULL; -} -static int -check_base_by_token(PyTypeObject *type, void *token) { - // Chain the branches, which will be optimized exclusive here if (token == NULL) { PyErr_Format(PyExc_SystemError, "PyType_GetBaseByToken called with token=NULL"); return -1; } - else if (!PyType_Check(type)) { + if (!PyType_Check(type)) { PyErr_Format(PyExc_TypeError, "expected a type, got a '%T' object", type); return -1; } - else if (!_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) { - return 0; - } - else if (((PyHeapTypeObject*)type)->ht_token == token) { - return 1; - } - else if (type->tp_mro != NULL) { - // This will not be inlined - return get_base_by_token_from_mro(type, token) ? 1 : 0; - } - else { - return get_base_by_token_recursive(type, token) ? 1 : 0; - } -} -int -PyType_GetBaseByToken(PyTypeObject *type, void *token, PyTypeObject **result) -{ - if (result == NULL) { - // If the `result` is checked only once here, the subsequent - // branches will become trivial to optimize. - return check_base_by_token(type, token); - } - if (token == NULL || !PyType_Check(type)) { - *result = NULL; - return check_base_by_token(type, token); - } - - // Chain the branches, which will be optimized exclusive here - PyTypeObject *base; if (!_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) { // No static type has a heaptype superclass, // which is ensured by type_ready_mro(). - *result = NULL; return 0; } - else if (((PyHeapTypeObject*)type)->ht_token == token) { - *result = (PyTypeObject *)Py_NewRef(type); + if (((PyHeapTypeObject*)type)->ht_token == token) { +found: + if (result != NULL) { + *result = (PyTypeObject *)Py_NewRef(type); + } return 1; } - else if (type->tp_mro != NULL) { - // Expect this to be inlined - base = get_base_by_token_from_mro(type, token); - } - else { - base = get_base_by_token_recursive(type, token); - } - if (base != NULL) { - *result = (PyTypeObject *)Py_NewRef(base); - return 1; - } - else { - *result = NULL; + PyObject *mro = type->tp_mro; // No lookup, following PyType_IsSubtype() + if (mro == NULL) { + PyTypeObject *base; + base = get_base_by_token_recursive(lookup_tp_bases(type), token); + if (base != NULL) { + // Copying the given type can cause a slowdown, + // unlike the overwrite below. + type = base; + goto found; + } return 0; } + // mro_invoke() ensures that the type MRO cannot be empty. + assert(PyTuple_GET_SIZE(mro) >= 1); + // Also, the first item in the MRO is the type itself, which + // we already checked above. We skip it in the loop. + assert(PyTuple_GET_ITEM(mro, 0) == (PyObject *)type); + Py_ssize_t n = PyTuple_GET_SIZE(mro); + for (Py_ssize_t i = 1; i < n; i++) { + PyTypeObject *base = (PyTypeObject *)PyTuple_GET_ITEM(mro, i); + if (_PyType_HasFeature(base, Py_TPFLAGS_HEAPTYPE) + && ((PyHeapTypeObject*)base)->ht_token == token) { + type = base; + goto found; + } + } + return 0; } From c914212474792312bb125211bae5719650fe2f58 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 10 Oct 2024 15:33:00 +0200 Subject: [PATCH 008/170] gh-125196: Use PyUnicodeWriter for JSON encoder (#125249) Replace the private _PyUnicodeWriter with the public PyUnicodeWriter. --- Modules/_json.c | 87 ++++++++++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 38 deletions(-) diff --git a/Modules/_json.c b/Modules/_json.c index 9e29de0f22465f..ce0093ab431d05 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -86,11 +86,11 @@ encoder_dealloc(PyObject *self); static int encoder_clear(PyEncoderObject *self); static int -encoder_listencode_list(PyEncoderObject *s, _PyUnicodeWriter *writer, PyObject *seq, PyObject *newline_indent); +encoder_listencode_list(PyEncoderObject *s, PyUnicodeWriter *writer, PyObject *seq, PyObject *newline_indent); static int -encoder_listencode_obj(PyEncoderObject *s, _PyUnicodeWriter *writer, PyObject *obj, PyObject *newline_indent); +encoder_listencode_obj(PyEncoderObject *s, PyUnicodeWriter *writer, PyObject *obj, PyObject *newline_indent); static int -encoder_listencode_dict(PyEncoderObject *s, _PyUnicodeWriter *writer, PyObject *dct, PyObject *newline_indent); +encoder_listencode_dict(PyEncoderObject *s, PyUnicodeWriter *writer, PyObject *dct, PyObject *newline_indent); static PyObject * _encoded_const(PyObject *obj); static void @@ -1268,38 +1268,39 @@ encoder_call(PyEncoderObject *self, PyObject *args, PyObject *kwds) { /* Python callable interface to encode_listencode_obj */ static char *kwlist[] = {"obj", "_current_indent_level", NULL}; - PyObject *obj, *result; + PyObject *obj; Py_ssize_t indent_level; - _PyUnicodeWriter writer; if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:_iterencode", kwlist, - &obj, &indent_level)) + &obj, &indent_level)) return NULL; - _PyUnicodeWriter_Init(&writer); - writer.overallocate = 1; + PyUnicodeWriter *writer = PyUnicodeWriter_Create(0); + if (writer == NULL) { + return NULL; + } PyObject *newline_indent = NULL; if (self->indent != Py_None) { newline_indent = _create_newline_indent(self->indent, indent_level); if (newline_indent == NULL) { - _PyUnicodeWriter_Dealloc(&writer); + PyUnicodeWriter_Discard(writer); return NULL; } } - if (encoder_listencode_obj(self, &writer, obj, newline_indent)) { - _PyUnicodeWriter_Dealloc(&writer); + if (encoder_listencode_obj(self, writer, obj, newline_indent)) { + PyUnicodeWriter_Discard(writer); Py_XDECREF(newline_indent); return NULL; } Py_XDECREF(newline_indent); - result = PyTuple_New(1); - if (result == NULL || - PyTuple_SetItem(result, 0, _PyUnicodeWriter_Finish(&writer)) < 0) { - Py_XDECREF(result); + PyObject *str = PyUnicodeWriter_Finish(writer); + if (str == NULL) { return NULL; } + PyObject *result = PyTuple_Pack(1, str); + Py_DECREF(str); return result; } @@ -1370,16 +1371,16 @@ encoder_encode_string(PyEncoderObject *s, PyObject *obj) } static int -_steal_accumulate(_PyUnicodeWriter *writer, PyObject *stolen) +_steal_accumulate(PyUnicodeWriter *writer, PyObject *stolen) { /* Append stolen and then decrement its reference count */ - int rval = _PyUnicodeWriter_WriteStr(writer, stolen); + int rval = PyUnicodeWriter_WriteStr(writer, stolen); Py_DECREF(stolen); return rval; } static int -encoder_listencode_obj(PyEncoderObject *s, _PyUnicodeWriter *writer, +encoder_listencode_obj(PyEncoderObject *s, PyUnicodeWriter *writer, PyObject *obj, PyObject *newline_indent) { /* Encode Python object obj to a JSON term */ @@ -1387,13 +1388,13 @@ encoder_listencode_obj(PyEncoderObject *s, _PyUnicodeWriter *writer, int rv; if (obj == Py_None) { - return _PyUnicodeWriter_WriteASCIIString(writer, "null", 4); + return PyUnicodeWriter_WriteUTF8(writer, "null", 4); } else if (obj == Py_True) { - return _PyUnicodeWriter_WriteASCIIString(writer, "true", 4); + return PyUnicodeWriter_WriteUTF8(writer, "true", 4); } else if (obj == Py_False) { - return _PyUnicodeWriter_WriteASCIIString(writer, "false", 5); + return PyUnicodeWriter_WriteUTF8(writer, "false", 5); } else if (PyUnicode_Check(obj)) { PyObject *encoded = encoder_encode_string(s, obj); @@ -1402,6 +1403,10 @@ encoder_listencode_obj(PyEncoderObject *s, _PyUnicodeWriter *writer, return _steal_accumulate(writer, encoded); } else if (PyLong_Check(obj)) { + if (PyLong_CheckExact(obj)) { + // Fast-path for exact integers + return PyUnicodeWriter_WriteRepr(writer, obj); + } PyObject *encoded = PyLong_Type.tp_repr(obj); if (encoded == NULL) return -1; @@ -1478,7 +1483,7 @@ encoder_listencode_obj(PyEncoderObject *s, _PyUnicodeWriter *writer, } static int -encoder_encode_key_value(PyEncoderObject *s, _PyUnicodeWriter *writer, bool *first, +encoder_encode_key_value(PyEncoderObject *s, PyUnicodeWriter *writer, bool *first, PyObject *dct, PyObject *key, PyObject *value, PyObject *newline_indent, PyObject *item_separator) @@ -1518,7 +1523,7 @@ encoder_encode_key_value(PyEncoderObject *s, _PyUnicodeWriter *writer, bool *fir *first = false; } else { - if (_PyUnicodeWriter_WriteStr(writer, item_separator) < 0) { + if (PyUnicodeWriter_WriteStr(writer, item_separator) < 0) { Py_DECREF(keystr); return -1; } @@ -1533,7 +1538,7 @@ encoder_encode_key_value(PyEncoderObject *s, _PyUnicodeWriter *writer, bool *fir if (_steal_accumulate(writer, encoded) < 0) { return -1; } - if (_PyUnicodeWriter_WriteStr(writer, s->key_separator) < 0) { + if (PyUnicodeWriter_WriteStr(writer, s->key_separator) < 0) { return -1; } if (encoder_listencode_obj(s, writer, value, newline_indent) < 0) { @@ -1544,7 +1549,7 @@ encoder_encode_key_value(PyEncoderObject *s, _PyUnicodeWriter *writer, bool *fir } static int -encoder_listencode_dict(PyEncoderObject *s, _PyUnicodeWriter *writer, +encoder_listencode_dict(PyEncoderObject *s, PyUnicodeWriter *writer, PyObject *dct, PyObject *newline_indent) { /* Encode Python dict dct a JSON term */ @@ -1555,8 +1560,10 @@ encoder_listencode_dict(PyEncoderObject *s, _PyUnicodeWriter *writer, PyObject *new_newline_indent = NULL; PyObject *separator_indent = NULL; - if (PyDict_GET_SIZE(dct) == 0) /* Fast path */ - return _PyUnicodeWriter_WriteASCIIString(writer, "{}", 2); + if (PyDict_GET_SIZE(dct) == 0) { + /* Fast path */ + return PyUnicodeWriter_WriteUTF8(writer, "{}", 2); + } if (s->markers != Py_None) { int has_key; @@ -1574,8 +1581,9 @@ encoder_listencode_dict(PyEncoderObject *s, _PyUnicodeWriter *writer, } } - if (_PyUnicodeWriter_WriteChar(writer, '{')) + if (PyUnicodeWriter_WriteChar(writer, '{')) { goto bail; + } PyObject *current_item_separator = s->item_separator; // borrowed reference if (s->indent != Py_None) { @@ -1589,7 +1597,7 @@ encoder_listencode_dict(PyEncoderObject *s, _PyUnicodeWriter *writer, } // update item separator with a borrowed reference current_item_separator = separator_indent; - if (_PyUnicodeWriter_WriteStr(writer, new_newline_indent) < 0) { + if (PyUnicodeWriter_WriteStr(writer, new_newline_indent) < 0) { goto bail; } } @@ -1635,13 +1643,14 @@ encoder_listencode_dict(PyEncoderObject *s, _PyUnicodeWriter *writer, Py_CLEAR(new_newline_indent); Py_CLEAR(separator_indent); - if (_PyUnicodeWriter_WriteStr(writer, newline_indent) < 0) { + if (PyUnicodeWriter_WriteStr(writer, newline_indent) < 0) { goto bail; } } - if (_PyUnicodeWriter_WriteChar(writer, '}')) + if (PyUnicodeWriter_WriteChar(writer, '}')) { goto bail; + } return 0; bail: @@ -1653,7 +1662,7 @@ encoder_listencode_dict(PyEncoderObject *s, _PyUnicodeWriter *writer, } static int -encoder_listencode_list(PyEncoderObject *s, _PyUnicodeWriter *writer, +encoder_listencode_list(PyEncoderObject *s, PyUnicodeWriter *writer, PyObject *seq, PyObject *newline_indent) { PyObject *ident = NULL; @@ -1668,7 +1677,7 @@ encoder_listencode_list(PyEncoderObject *s, _PyUnicodeWriter *writer, return -1; if (PySequence_Fast_GET_SIZE(s_fast) == 0) { Py_DECREF(s_fast); - return _PyUnicodeWriter_WriteASCIIString(writer, "[]", 2); + return PyUnicodeWriter_WriteUTF8(writer, "[]", 2); } if (s->markers != Py_None) { @@ -1687,8 +1696,9 @@ encoder_listencode_list(PyEncoderObject *s, _PyUnicodeWriter *writer, } } - if (_PyUnicodeWriter_WriteChar(writer, '[')) + if (PyUnicodeWriter_WriteChar(writer, '[')) { goto bail; + } PyObject *separator = s->item_separator; // borrowed reference if (s->indent != Py_None) { @@ -1697,7 +1707,7 @@ encoder_listencode_list(PyEncoderObject *s, _PyUnicodeWriter *writer, goto bail; } - if (_PyUnicodeWriter_WriteStr(writer, new_newline_indent) < 0) { + if (PyUnicodeWriter_WriteStr(writer, new_newline_indent) < 0) { goto bail; } @@ -1710,7 +1720,7 @@ encoder_listencode_list(PyEncoderObject *s, _PyUnicodeWriter *writer, for (i = 0; i < PySequence_Fast_GET_SIZE(s_fast); i++) { PyObject *obj = PySequence_Fast_GET_ITEM(s_fast, i); if (i) { - if (_PyUnicodeWriter_WriteStr(writer, separator) < 0) + if (PyUnicodeWriter_WriteStr(writer, separator) < 0) goto bail; } if (encoder_listencode_obj(s, writer, obj, new_newline_indent)) { @@ -1727,13 +1737,14 @@ encoder_listencode_list(PyEncoderObject *s, _PyUnicodeWriter *writer, if (s->indent != Py_None) { Py_CLEAR(new_newline_indent); Py_CLEAR(separator_indent); - if (_PyUnicodeWriter_WriteStr(writer, newline_indent) < 0) { + if (PyUnicodeWriter_WriteStr(writer, newline_indent) < 0) { goto bail; } } - if (_PyUnicodeWriter_WriteChar(writer, ']')) + if (PyUnicodeWriter_WriteChar(writer, ']')) { goto bail; + } Py_DECREF(s_fast); return 0; From 01fc3b34cc6994bc83b6540da3a8573e79dfbb56 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Thu, 10 Oct 2024 16:27:52 +0200 Subject: [PATCH 009/170] gh-124570: ctypes: Run some Structure tests on Union as well (GH-124976) - Move some Structure tests to test_structunion; use a common base test class + two subclasses to run them on Union too - Remove test_union for now as it's redundant Note: `test_simple_structs` & `test_simple_unions` are in the common file because they share `formats`. --- Lib/test/test_ctypes/test_structunion.py | 353 +++++++++++++++++++++++ Lib/test/test_ctypes/test_structures.py | 337 +--------------------- Lib/test/test_ctypes/test_unions.py | 35 --- 3 files changed, 368 insertions(+), 357 deletions(-) create mode 100644 Lib/test/test_ctypes/test_structunion.py delete mode 100644 Lib/test/test_ctypes/test_unions.py diff --git a/Lib/test/test_ctypes/test_structunion.py b/Lib/test/test_ctypes/test_structunion.py new file mode 100644 index 00000000000000..973ac3b2f1919d --- /dev/null +++ b/Lib/test/test_ctypes/test_structunion.py @@ -0,0 +1,353 @@ +"""Common tests for ctypes.Structure and ctypes.Union""" + +import unittest +from ctypes import (Structure, Union, POINTER, sizeof, alignment, + c_char, c_byte, c_ubyte, + c_short, c_ushort, c_int, c_uint, + c_long, c_ulong, c_longlong, c_ulonglong, c_float, c_double) +from ._support import (_CData, PyCStructType, UnionType, + Py_TPFLAGS_DISALLOW_INSTANTIATION, + Py_TPFLAGS_IMMUTABLETYPE) +from struct import calcsize + + +class StructUnionTestBase: + formats = {"c": c_char, + "b": c_byte, + "B": c_ubyte, + "h": c_short, + "H": c_ushort, + "i": c_int, + "I": c_uint, + "l": c_long, + "L": c_ulong, + "q": c_longlong, + "Q": c_ulonglong, + "f": c_float, + "d": c_double, + } + + def test_subclass(self): + class X(self.cls): + _fields_ = [("a", c_int)] + + class Y(X): + _fields_ = [("b", c_int)] + + class Z(X): + pass + + self.assertEqual(sizeof(X), sizeof(c_int)) + self.check_sizeof(Y, + struct_size=sizeof(c_int)*2, + union_size=sizeof(c_int)) + self.assertEqual(sizeof(Z), sizeof(c_int)) + self.assertEqual(X._fields_, [("a", c_int)]) + self.assertEqual(Y._fields_, [("b", c_int)]) + self.assertEqual(Z._fields_, [("a", c_int)]) + + def test_subclass_delayed(self): + class X(self.cls): + pass + self.assertEqual(sizeof(X), 0) + X._fields_ = [("a", c_int)] + + class Y(X): + pass + self.assertEqual(sizeof(Y), sizeof(X)) + Y._fields_ = [("b", c_int)] + + class Z(X): + pass + + self.assertEqual(sizeof(X), sizeof(c_int)) + self.check_sizeof(Y, + struct_size=sizeof(c_int)*2, + union_size=sizeof(c_int)) + self.assertEqual(sizeof(Z), sizeof(c_int)) + self.assertEqual(X._fields_, [("a", c_int)]) + self.assertEqual(Y._fields_, [("b", c_int)]) + self.assertEqual(Z._fields_, [("a", c_int)]) + + def test_inheritance_hierarchy(self): + self.assertEqual(self.cls.mro(), [self.cls, _CData, object]) + self.assertEqual(type(self.metacls), type) + + def test_type_flags(self): + for cls in self.cls, self.metacls: + with self.subTest(cls=cls): + self.assertTrue(cls.__flags__ & Py_TPFLAGS_IMMUTABLETYPE) + self.assertFalse(cls.__flags__ & Py_TPFLAGS_DISALLOW_INSTANTIATION) + + def test_metaclass_details(self): + # Abstract classes (whose metaclass __init__ was not called) can't be + # instantiated directly + NewClass = self.metacls.__new__(self.metacls, 'NewClass', + (self.cls,), {}) + for cls in self.cls, NewClass: + with self.subTest(cls=cls): + with self.assertRaisesRegex(TypeError, "abstract class"): + obj = cls() + + # Cannot call the metaclass __init__ more than once + class T(self.cls): + _fields_ = [("x", c_char), + ("y", c_char)] + with self.assertRaisesRegex(SystemError, "already initialized"): + self.metacls.__init__(T, 'ptr', (), {}) + + def test_alignment(self): + class X(self.cls): + _fields_ = [("x", c_char * 3)] + self.assertEqual(alignment(X), calcsize("s")) + self.assertEqual(sizeof(X), calcsize("3s")) + + class Y(self.cls): + _fields_ = [("x", c_char * 3), + ("y", c_int)] + self.assertEqual(alignment(Y), alignment(c_int)) + self.check_sizeof(Y, + struct_size=calcsize("3s i"), + union_size=max(calcsize("3s"), calcsize("i"))) + + class SI(self.cls): + _fields_ = [("a", X), + ("b", Y)] + self.assertEqual(alignment(SI), max(alignment(Y), alignment(X))) + self.check_sizeof(SI, + struct_size=calcsize("3s0i 3si 0i"), + union_size=max(calcsize("3s"), calcsize("i"))) + + class IS(self.cls): + _fields_ = [("b", Y), + ("a", X)] + + self.assertEqual(alignment(SI), max(alignment(X), alignment(Y))) + self.check_sizeof(IS, + struct_size=calcsize("3si 3s 0i"), + union_size=max(calcsize("3s"), calcsize("i"))) + + class XX(self.cls): + _fields_ = [("a", X), + ("b", X)] + self.assertEqual(alignment(XX), alignment(X)) + self.check_sizeof(XX, + struct_size=calcsize("3s 3s 0s"), + union_size=calcsize("3s")) + + def test_empty(self): + # I had problems with these + # + # Although these are pathological cases: Empty Structures! + class X(self.cls): + _fields_ = [] + + # Is this really the correct alignment, or should it be 0? + self.assertTrue(alignment(X) == 1) + self.assertTrue(sizeof(X) == 0) + + class XX(self.cls): + _fields_ = [("a", X), + ("b", X)] + + self.assertEqual(alignment(XX), 1) + self.assertEqual(sizeof(XX), 0) + + def test_fields(self): + # test the offset and size attributes of Structure/Union fields. + class X(self.cls): + _fields_ = [("x", c_int), + ("y", c_char)] + + self.assertEqual(X.x.offset, 0) + self.assertEqual(X.x.size, sizeof(c_int)) + + if self.cls == Structure: + self.assertEqual(X.y.offset, sizeof(c_int)) + else: + self.assertEqual(X.y.offset, 0) + self.assertEqual(X.y.size, sizeof(c_char)) + + # readonly + self.assertRaises((TypeError, AttributeError), setattr, X.x, "offset", 92) + self.assertRaises((TypeError, AttributeError), setattr, X.x, "size", 92) + + # XXX Should we check nested data types also? + # offset is always relative to the class... + + def test_invalid_field_types(self): + class POINT(self.cls): + pass + self.assertRaises(TypeError, setattr, POINT, "_fields_", [("x", 1), ("y", 2)]) + + def test_invalid_name(self): + # field name must be string + def declare_with_name(name): + class S(self.cls): + _fields_ = [(name, c_int)] + + self.assertRaises(TypeError, declare_with_name, b"x") + + def test_intarray_fields(self): + class SomeInts(self.cls): + _fields_ = [("a", c_int * 4)] + + # can use tuple to initialize array (but not list!) + self.assertEqual(SomeInts((1, 2)).a[:], [1, 2, 0, 0]) + self.assertEqual(SomeInts((1, 2)).a[::], [1, 2, 0, 0]) + self.assertEqual(SomeInts((1, 2)).a[::-1], [0, 0, 2, 1]) + self.assertEqual(SomeInts((1, 2)).a[::2], [1, 0]) + self.assertEqual(SomeInts((1, 2)).a[1:5:6], [2]) + self.assertEqual(SomeInts((1, 2)).a[6:4:-1], []) + self.assertEqual(SomeInts((1, 2, 3, 4)).a[:], [1, 2, 3, 4]) + self.assertEqual(SomeInts((1, 2, 3, 4)).a[::], [1, 2, 3, 4]) + # too long + # XXX Should raise ValueError?, not RuntimeError + self.assertRaises(RuntimeError, SomeInts, (1, 2, 3, 4, 5)) + + def test_huge_field_name(self): + # issue12881: segfault with large structure field names + def create_class(length): + class S(self.cls): + _fields_ = [('x' * length, c_int)] + + for length in [10 ** i for i in range(0, 8)]: + try: + create_class(length) + except MemoryError: + # MemoryErrors are OK, we just don't want to segfault + pass + + def test_abstract_class(self): + class X(self.cls): + _abstract_ = "something" + with self.assertRaisesRegex(TypeError, r"^abstract class$"): + X() + + def test_methods(self): + self.assertIn("in_dll", dir(type(self.cls))) + self.assertIn("from_address", dir(type(self.cls))) + self.assertIn("in_dll", dir(type(self.cls))) + + +class StructureTestCase(unittest.TestCase, StructUnionTestBase): + cls = Structure + metacls = PyCStructType + + def test_metaclass_name(self): + self.assertEqual(self.metacls.__name__, "PyCStructType") + + def check_sizeof(self, cls, *, struct_size, union_size): + self.assertEqual(sizeof(cls), struct_size) + + def test_simple_structs(self): + for code, tp in self.formats.items(): + class X(Structure): + _fields_ = [("x", c_char), + ("y", tp)] + self.assertEqual((sizeof(X), code), + (calcsize("c%c0%c" % (code, code)), code)) + + +class UnionTestCase(unittest.TestCase, StructUnionTestBase): + cls = Union + metacls = UnionType + + def test_metaclass_name(self): + self.assertEqual(self.metacls.__name__, "UnionType") + + def check_sizeof(self, cls, *, struct_size, union_size): + self.assertEqual(sizeof(cls), union_size) + + def test_simple_unions(self): + for code, tp in self.formats.items(): + class X(Union): + _fields_ = [("x", c_char), + ("y", tp)] + self.assertEqual((sizeof(X), code), + (calcsize("%c" % (code)), code)) + + +class PointerMemberTestBase: + def test(self): + # a Structure/Union with a POINTER field + class S(self.cls): + _fields_ = [("array", POINTER(c_int))] + + s = S() + # We can assign arrays of the correct type + s.array = (c_int * 3)(1, 2, 3) + items = [s.array[i] for i in range(3)] + self.assertEqual(items, [1, 2, 3]) + + s.array[0] = 42 + + items = [s.array[i] for i in range(3)] + self.assertEqual(items, [42, 2, 3]) + + s.array[0] = 1 + + items = [s.array[i] for i in range(3)] + self.assertEqual(items, [1, 2, 3]) + +class PointerMemberTestCase_Struct(unittest.TestCase, PointerMemberTestBase): + cls = Structure + + def test_none_to_pointer_fields(self): + class S(self.cls): + _fields_ = [("x", c_int), + ("p", POINTER(c_int))] + + s = S() + s.x = 12345678 + s.p = None + self.assertEqual(s.x, 12345678) + +class PointerMemberTestCase_Union(unittest.TestCase, PointerMemberTestBase): + cls = Union + + def test_none_to_pointer_fields(self): + class S(self.cls): + _fields_ = [("x", c_int), + ("p", POINTER(c_int))] + + s = S() + s.x = 12345678 + s.p = None + self.assertFalse(s.p) # NULL pointers are falsy + + +class TestRecursiveBase: + def test_contains_itself(self): + class Recursive(self.cls): + pass + + try: + Recursive._fields_ = [("next", Recursive)] + except AttributeError as details: + self.assertIn("Structure or union cannot contain itself", + str(details)) + else: + self.fail("Structure or union cannot contain itself") + + + def test_vice_versa(self): + class First(self.cls): + pass + class Second(self.cls): + pass + + First._fields_ = [("second", Second)] + + try: + Second._fields_ = [("first", First)] + except AttributeError as details: + self.assertIn("_fields_ is final", str(details)) + else: + self.fail("AttributeError not raised") + +class TestRecursiveStructure(unittest.TestCase, TestRecursiveBase): + cls = Structure + +class TestRecursiveUnion(unittest.TestCase, TestRecursiveBase): + cls = Union diff --git a/Lib/test/test_ctypes/test_structures.py b/Lib/test/test_ctypes/test_structures.py index 6cc09c8f2b5b59..0ec238e04b74cd 100644 --- a/Lib/test/test_ctypes/test_structures.py +++ b/Lib/test/test_ctypes/test_structures.py @@ -1,209 +1,24 @@ +"""Tests for ctypes.Structure + +Features common with Union should go in test_structunion.py instead. +""" + from platform import architecture as _architecture import struct import sys import unittest -from ctypes import (CDLL, Structure, Union, POINTER, sizeof, byref, alignment, +from ctypes import (CDLL, Structure, Union, POINTER, sizeof, byref, c_void_p, c_char, c_wchar, c_byte, c_ubyte, - c_uint8, c_uint16, c_uint32, - c_short, c_ushort, c_int, c_uint, - c_long, c_ulong, c_longlong, c_ulonglong, c_float, c_double) + c_uint8, c_uint16, c_uint32, c_int, c_uint, + c_long, c_ulong, c_longlong, c_float, c_double) from ctypes.util import find_library -from struct import calcsize from collections import namedtuple from test import support from test.support import import_helper _ctypes_test = import_helper.import_module("_ctypes_test") -from ._support import (_CData, PyCStructType, Py_TPFLAGS_DISALLOW_INSTANTIATION, - Py_TPFLAGS_IMMUTABLETYPE) - - -class SubclassesTest(unittest.TestCase): - def test_subclass(self): - class X(Structure): - _fields_ = [("a", c_int)] - - class Y(X): - _fields_ = [("b", c_int)] - - class Z(X): - pass - - self.assertEqual(sizeof(X), sizeof(c_int)) - self.assertEqual(sizeof(Y), sizeof(c_int)*2) - self.assertEqual(sizeof(Z), sizeof(c_int)) - self.assertEqual(X._fields_, [("a", c_int)]) - self.assertEqual(Y._fields_, [("b", c_int)]) - self.assertEqual(Z._fields_, [("a", c_int)]) - - def test_subclass_delayed(self): - class X(Structure): - pass - self.assertEqual(sizeof(X), 0) - X._fields_ = [("a", c_int)] - - class Y(X): - pass - self.assertEqual(sizeof(Y), sizeof(X)) - Y._fields_ = [("b", c_int)] - - class Z(X): - pass - - self.assertEqual(sizeof(X), sizeof(c_int)) - self.assertEqual(sizeof(Y), sizeof(c_int)*2) - self.assertEqual(sizeof(Z), sizeof(c_int)) - self.assertEqual(X._fields_, [("a", c_int)]) - self.assertEqual(Y._fields_, [("b", c_int)]) - self.assertEqual(Z._fields_, [("a", c_int)]) class StructureTestCase(unittest.TestCase): - formats = {"c": c_char, - "b": c_byte, - "B": c_ubyte, - "h": c_short, - "H": c_ushort, - "i": c_int, - "I": c_uint, - "l": c_long, - "L": c_ulong, - "q": c_longlong, - "Q": c_ulonglong, - "f": c_float, - "d": c_double, - } - - def test_inheritance_hierarchy(self): - self.assertEqual(Structure.mro(), [Structure, _CData, object]) - - self.assertEqual(PyCStructType.__name__, "PyCStructType") - self.assertEqual(type(PyCStructType), type) - - - def test_type_flags(self): - for cls in Structure, PyCStructType: - with self.subTest(cls=cls): - self.assertTrue(Structure.__flags__ & Py_TPFLAGS_IMMUTABLETYPE) - self.assertFalse(Structure.__flags__ & Py_TPFLAGS_DISALLOW_INSTANTIATION) - - def test_metaclass_details(self): - # Abstract classes (whose metaclass __init__ was not called) can't be - # instantiated directly - NewStructure = PyCStructType.__new__(PyCStructType, 'NewStructure', - (Structure,), {}) - for cls in Structure, NewStructure: - with self.subTest(cls=cls): - with self.assertRaisesRegex(TypeError, "abstract class"): - obj = cls() - - # Cannot call the metaclass __init__ more than once - class T(Structure): - _fields_ = [("x", c_char), - ("y", c_char)] - with self.assertRaisesRegex(SystemError, "already initialized"): - PyCStructType.__init__(T, 'ptr', (), {}) - - def test_simple_structs(self): - for code, tp in self.formats.items(): - class X(Structure): - _fields_ = [("x", c_char), - ("y", tp)] - self.assertEqual((sizeof(X), code), - (calcsize("c%c0%c" % (code, code)), code)) - - def test_unions(self): - for code, tp in self.formats.items(): - class X(Union): - _fields_ = [("x", c_char), - ("y", tp)] - self.assertEqual((sizeof(X), code), - (calcsize("%c" % (code)), code)) - - def test_struct_alignment(self): - class X(Structure): - _fields_ = [("x", c_char * 3)] - self.assertEqual(alignment(X), calcsize("s")) - self.assertEqual(sizeof(X), calcsize("3s")) - - class Y(Structure): - _fields_ = [("x", c_char * 3), - ("y", c_int)] - self.assertEqual(alignment(Y), alignment(c_int)) - self.assertEqual(sizeof(Y), calcsize("3si")) - - class SI(Structure): - _fields_ = [("a", X), - ("b", Y)] - self.assertEqual(alignment(SI), max(alignment(Y), alignment(X))) - self.assertEqual(sizeof(SI), calcsize("3s0i 3si 0i")) - - class IS(Structure): - _fields_ = [("b", Y), - ("a", X)] - - self.assertEqual(alignment(SI), max(alignment(X), alignment(Y))) - self.assertEqual(sizeof(IS), calcsize("3si 3s 0i")) - - class XX(Structure): - _fields_ = [("a", X), - ("b", X)] - self.assertEqual(alignment(XX), alignment(X)) - self.assertEqual(sizeof(XX), calcsize("3s 3s 0s")) - - def test_empty(self): - # I had problems with these - # - # Although these are pathological cases: Empty Structures! - class X(Structure): - _fields_ = [] - - class Y(Union): - _fields_ = [] - - # Is this really the correct alignment, or should it be 0? - self.assertTrue(alignment(X) == alignment(Y) == 1) - self.assertTrue(sizeof(X) == sizeof(Y) == 0) - - class XX(Structure): - _fields_ = [("a", X), - ("b", X)] - - self.assertEqual(alignment(XX), 1) - self.assertEqual(sizeof(XX), 0) - - def test_fields(self): - # test the offset and size attributes of Structure/Union fields. - class X(Structure): - _fields_ = [("x", c_int), - ("y", c_char)] - - self.assertEqual(X.x.offset, 0) - self.assertEqual(X.x.size, sizeof(c_int)) - - self.assertEqual(X.y.offset, sizeof(c_int)) - self.assertEqual(X.y.size, sizeof(c_char)) - - # readonly - self.assertRaises((TypeError, AttributeError), setattr, X.x, "offset", 92) - self.assertRaises((TypeError, AttributeError), setattr, X.x, "size", 92) - - class X(Union): - _fields_ = [("x", c_int), - ("y", c_char)] - - self.assertEqual(X.x.offset, 0) - self.assertEqual(X.x.size, sizeof(c_int)) - - self.assertEqual(X.y.offset, 0) - self.assertEqual(X.y.size, sizeof(c_char)) - - # readonly - self.assertRaises((TypeError, AttributeError), setattr, X.x, "offset", 92) - self.assertRaises((TypeError, AttributeError), setattr, X.x, "size", 92) - - # XXX Should we check nested data types also? - # offset is always relative to the class... - def test_packed(self): class X(Structure): _fields_ = [("a", c_byte), @@ -290,36 +105,6 @@ class POINT(Structure): pt = POINT(y=2, x=1) self.assertEqual((pt.x, pt.y), (1, 2)) - def test_invalid_field_types(self): - class POINT(Structure): - pass - self.assertRaises(TypeError, setattr, POINT, "_fields_", [("x", 1), ("y", 2)]) - - def test_invalid_name(self): - # field name must be string - def declare_with_name(name): - class S(Structure): - _fields_ = [(name, c_int)] - - self.assertRaises(TypeError, declare_with_name, b"x") - - def test_intarray_fields(self): - class SomeInts(Structure): - _fields_ = [("a", c_int * 4)] - - # can use tuple to initialize array (but not list!) - self.assertEqual(SomeInts((1, 2)).a[:], [1, 2, 0, 0]) - self.assertEqual(SomeInts((1, 2)).a[::], [1, 2, 0, 0]) - self.assertEqual(SomeInts((1, 2)).a[::-1], [0, 0, 2, 1]) - self.assertEqual(SomeInts((1, 2)).a[::2], [1, 0]) - self.assertEqual(SomeInts((1, 2)).a[1:5:6], [2]) - self.assertEqual(SomeInts((1, 2)).a[6:4:-1], []) - self.assertEqual(SomeInts((1, 2, 3, 4)).a[:], [1, 2, 3, 4]) - self.assertEqual(SomeInts((1, 2, 3, 4)).a[::], [1, 2, 3, 4]) - # too long - # XXX Should raise ValueError?, not RuntimeError - self.assertRaises(RuntimeError, SomeInts, (1, 2, 3, 4, 5)) - def test_nested_initializers(self): # test initializing nested structures class Phone(Structure): @@ -374,37 +159,12 @@ class Person(Structure): self.assertEqual(msg, "(Phone) TypeError: too many initializers") - def test_huge_field_name(self): - # issue12881: segfault with large structure field names - def create_class(length): - class S(Structure): - _fields_ = [('x' * length, c_int)] - - for length in [10 ** i for i in range(0, 8)]: - try: - create_class(length) - except MemoryError: - # MemoryErrors are OK, we just don't want to segfault - pass - def get_except(self, func, *args): try: func(*args) except Exception as detail: return detail.__class__, str(detail) - def test_abstract_class(self): - class X(Structure): - _abstract_ = "something" - # try 'X()' - cls, msg = self.get_except(eval, "X()", locals()) - self.assertEqual((cls, msg), (TypeError, "abstract class")) - - def test_methods(self): - self.assertIn("in_dll", dir(type(Structure))) - self.assertIn("from_address", dir(type(Structure))) - self.assertIn("in_dll", dir(type(Structure))) - def test_positional_args(self): # see also http://bugs.python.org/issue5042 class W(Structure): @@ -507,6 +267,8 @@ class X(Structure): self.assertEqual(s.second, got.second) def _test_issue18060(self, Vector): + # Regression tests for gh-62260 + # The call to atan2() should succeed if the # class fields were correctly cloned in the # subclasses. Otherwise, it will segfault. @@ -698,6 +460,7 @@ class Test3E(Structure): self.assertEqual(result.data[i], float(i+1)) def test_38368(self): + # Regression test for gh-82549 class U(Union): _fields_ = [ ('f1', c_uint8 * 16), @@ -719,9 +482,9 @@ class U(Union): self.assertEqual(f2, [0x4567, 0x0123, 0xcdef, 0x89ab, 0x3210, 0x7654, 0xba98, 0xfedc]) - @unittest.skipIf(True, 'Test disabled for now - see bpo-16575/bpo-16576') + @unittest.skipIf(True, 'Test disabled for now - see gh-60779/gh-60780') def test_union_by_value(self): - # See bpo-16575 + # See gh-60779 # These should mirror the structures in Modules/_ctypes/_ctypes_test.c @@ -800,9 +563,9 @@ class Test5(Structure): self.assertEqual(test5.nested.an_int, 0) self.assertEqual(test5.another_int, 0) - @unittest.skipIf(True, 'Test disabled for now - see bpo-16575/bpo-16576') + @unittest.skipIf(True, 'Test disabled for now - see gh-60779/gh-60780') def test_bitfield_by_value(self): - # See bpo-16576 + # See gh-60780 # These should mirror the structures in Modules/_ctypes/_ctypes_test.c @@ -882,75 +645,5 @@ class Test8(Union): 'a union by value, which is unsupported.') -class PointerMemberTestCase(unittest.TestCase): - - def test(self): - # a Structure with a POINTER field - class S(Structure): - _fields_ = [("array", POINTER(c_int))] - - s = S() - # We can assign arrays of the correct type - s.array = (c_int * 3)(1, 2, 3) - items = [s.array[i] for i in range(3)] - self.assertEqual(items, [1, 2, 3]) - - # The following are bugs, but are included here because the unittests - # also describe the current behaviour. - # - # This fails with SystemError: bad arg to internal function - # or with IndexError (with a patch I have) - - s.array[0] = 42 - - items = [s.array[i] for i in range(3)] - self.assertEqual(items, [42, 2, 3]) - - s.array[0] = 1 - - items = [s.array[i] for i in range(3)] - self.assertEqual(items, [1, 2, 3]) - - def test_none_to_pointer_fields(self): - class S(Structure): - _fields_ = [("x", c_int), - ("p", POINTER(c_int))] - - s = S() - s.x = 12345678 - s.p = None - self.assertEqual(s.x, 12345678) - - -class TestRecursiveStructure(unittest.TestCase): - def test_contains_itself(self): - class Recursive(Structure): - pass - - try: - Recursive._fields_ = [("next", Recursive)] - except AttributeError as details: - self.assertIn("Structure or union cannot contain itself", - str(details)) - else: - self.fail("Structure or union cannot contain itself") - - - def test_vice_versa(self): - class First(Structure): - pass - class Second(Structure): - pass - - First._fields_ = [("second", Second)] - - try: - Second._fields_ = [("first", First)] - except AttributeError as details: - self.assertIn("_fields_ is final", str(details)) - else: - self.fail("AttributeError not raised") - - if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_ctypes/test_unions.py b/Lib/test/test_ctypes/test_unions.py deleted file mode 100644 index e2dff0f22a9213..00000000000000 --- a/Lib/test/test_ctypes/test_unions.py +++ /dev/null @@ -1,35 +0,0 @@ -import unittest -from ctypes import Union, c_char -from ._support import (_CData, UnionType, Py_TPFLAGS_DISALLOW_INSTANTIATION, - Py_TPFLAGS_IMMUTABLETYPE) - - -class ArrayTestCase(unittest.TestCase): - def test_inheritance_hierarchy(self): - self.assertEqual(Union.mro(), [Union, _CData, object]) - - self.assertEqual(UnionType.__name__, "UnionType") - self.assertEqual(type(UnionType), type) - - def test_type_flags(self): - for cls in Union, UnionType: - with self.subTest(cls=Union): - self.assertTrue(Union.__flags__ & Py_TPFLAGS_IMMUTABLETYPE) - self.assertFalse(Union.__flags__ & Py_TPFLAGS_DISALLOW_INSTANTIATION) - - def test_metaclass_details(self): - # Abstract classes (whose metaclass __init__ was not called) can't be - # instantiated directly - NewUnion = UnionType.__new__(UnionType, 'NewUnion', - (Union,), {}) - for cls in Union, NewUnion: - with self.subTest(cls=cls): - with self.assertRaisesRegex(TypeError, "abstract class"): - obj = cls() - - # Cannot call the metaclass __init__ more than once - class T(Union): - _fields_ = [("x", c_char), - ("y", c_char)] - with self.assertRaisesRegex(SystemError, "already initialized"): - UnionType.__init__(T, 'ptr', (), {}) From c9014374c50d6ef64786d3e7d9c7e99053d5c9e2 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 10 Oct 2024 18:19:08 +0100 Subject: [PATCH 010/170] GH-125174: Make immortal objects more robust, following design from PEP 683 (GH-125251) --- .../pycore_global_objects_fini_generated.h | 2 +- Include/internal/pycore_object.h | 34 ++++----------- Include/object.h | 2 +- Include/refcount.h | 42 ++++++++++--------- Lib/test/test_builtin.py | 4 +- ...-10-10-12-04-56.gh-issue-125174._8h6T7.rst | 4 ++ Modules/_asynciomodule.c | 2 +- Objects/bytesobject.c | 6 +-- Objects/dictobject.c | 10 +++-- Objects/object.c | 2 +- Objects/structseq.c | 2 +- Objects/typeobject.c | 8 ++-- Python/bytecodes.c | 4 +- Python/executor_cases.c.h | 4 +- Python/generated_cases.c.h | 4 +- Python/import.c | 2 +- Tools/cases_generator/analyzer.py | 1 - 17 files changed, 61 insertions(+), 72 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-10-10-12-04-56.gh-issue-125174._8h6T7.rst diff --git a/Include/internal/pycore_global_objects_fini_generated.h b/Include/internal/pycore_global_objects_fini_generated.h index 3140a75a47c5ee..de68ef93257234 100644 --- a/Include/internal/pycore_global_objects_fini_generated.h +++ b/Include/internal/pycore_global_objects_fini_generated.h @@ -11,7 +11,7 @@ extern "C" { #ifdef Py_DEBUG static inline void _PyStaticObject_CheckRefcnt(PyObject *obj) { - if (Py_REFCNT(obj) < _Py_IMMORTAL_REFCNT) { + if (!_Py_IsImmortal(obj)) { fprintf(stderr, "Immortal Object has less refcnt than expected.\n"); _PyObject_Dump(obj); } diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index 0af13b1bcda20b..8832692d03c29e 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -16,9 +16,6 @@ extern "C" { #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_uniqueid.h" // _PyType_IncrefSlow - -#define _Py_IMMORTAL_REFCNT_LOOSE ((_Py_IMMORTAL_REFCNT >> 1) + 1) - // This value is added to `ob_ref_shared` for objects that use deferred // reference counting so that they are not immediately deallocated when the // non-deferred reference count drops to zero. @@ -27,25 +24,8 @@ extern "C" { // `ob_ref_shared` are used for flags. #define _Py_REF_DEFERRED (PY_SSIZE_T_MAX / 8) -// gh-121528, gh-118997: Similar to _Py_IsImmortal() but be more loose when -// comparing the reference count to stay compatible with C extensions built -// with the stable ABI 3.11 or older. Such extensions implement INCREF/DECREF -// as refcnt++ and refcnt-- without taking in account immortal objects. For -// example, the reference count of an immortal object can change from -// _Py_IMMORTAL_REFCNT to _Py_IMMORTAL_REFCNT+1 (INCREF) or -// _Py_IMMORTAL_REFCNT-1 (DECREF). -// -// This function should only be used in assertions. Otherwise, _Py_IsImmortal() -// must be used instead. -static inline int _Py_IsImmortalLoose(PyObject *op) -{ -#if defined(Py_GIL_DISABLED) - return _Py_IsImmortal(op); -#else - return (op->ob_refcnt >= _Py_IMMORTAL_REFCNT_LOOSE); -#endif -} -#define _Py_IsImmortalLoose(op) _Py_IsImmortalLoose(_PyObject_CAST(op)) +/* For backwards compatibility -- Do not use this */ +#define _Py_IsImmortalLoose(op) _Py_IsImmortal /* Check if an object is consistent. For example, ensure that the reference @@ -97,7 +77,7 @@ PyAPI_FUNC(int) _PyObject_IsFreed(PyObject *); #else #define _PyObject_HEAD_INIT(type) \ { \ - .ob_refcnt = _Py_IMMORTAL_REFCNT, \ + .ob_refcnt = _Py_IMMORTAL_INITIAL_REFCNT, \ .ob_type = (type) \ } #endif @@ -184,7 +164,7 @@ PyAPI_FUNC(void) _Py_SetImmortalUntracked(PyObject *op); static inline void _Py_SetMortal(PyObject *op, Py_ssize_t refcnt) { if (op) { - assert(_Py_IsImmortalLoose(op)); + assert(_Py_IsImmortal(op)); #ifdef Py_GIL_DISABLED op->ob_tid = _Py_UNOWNED_TID; op->ob_ref_local = 0; @@ -316,7 +296,7 @@ static inline void _Py_INCREF_TYPE(PyTypeObject *type) { if (!_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) { - assert(_Py_IsImmortalLoose(type)); + assert(_Py_IsImmortal(type)); _Py_INCREF_IMMORTAL_STAT_INC(); return; } @@ -357,7 +337,7 @@ static inline void _Py_DECREF_TYPE(PyTypeObject *type) { if (!_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) { - assert(_Py_IsImmortalLoose(type)); + assert(_Py_IsImmortal(type)); _Py_DECREF_IMMORTAL_STAT_INC(); return; } @@ -393,7 +373,7 @@ _PyObject_Init(PyObject *op, PyTypeObject *typeobj) { assert(op != NULL); Py_SET_TYPE(op, typeobj); - assert(_PyType_HasFeature(typeobj, Py_TPFLAGS_HEAPTYPE) || _Py_IsImmortalLoose(typeobj)); + assert(_PyType_HasFeature(typeobj, Py_TPFLAGS_HEAPTYPE) || _Py_IsImmortal(typeobj)); _Py_INCREF_TYPE(typeobj); _Py_NewReference(op); } diff --git a/Include/object.h b/Include/object.h index 418f2196062df7..5be4dedadc20eb 100644 --- a/Include/object.h +++ b/Include/object.h @@ -81,7 +81,7 @@ whose size is determined when the object is allocated. #else #define PyObject_HEAD_INIT(type) \ { \ - { _Py_IMMORTAL_REFCNT }, \ + { _Py_IMMORTAL_INITIAL_REFCNT }, \ (type) \ }, #endif diff --git a/Include/refcount.h b/Include/refcount.h index 9a4e15065ecab8..141cbd34dd72e6 100644 --- a/Include/refcount.h +++ b/Include/refcount.h @@ -21,25 +21,30 @@ cleanup during runtime finalization. #if SIZEOF_VOID_P > 4 /* -In 64+ bit systems, an object will be marked as immortal by setting all of the -lower 32 bits of the reference count field, which is equal to: 0xFFFFFFFF +In 64+ bit systems, any object whose 32 bit reference count is >= 2**31 +will be treated as immortal. Using the lower 32 bits makes the value backwards compatible by allowing C-Extensions without the updated checks in Py_INCREF and Py_DECREF to safely -increase and decrease the objects reference count. The object would lose its -immortality, but the execution would still be correct. +increase and decrease the objects reference count. + +In order to offer sufficient resilience to C extensions using the stable ABI +compiled against 3.11 or earlier, we set the initial value near the +middle of the range (2**31, 2**32). That way the the refcount can be +off by ~1 billion without affecting immortality. Reference count increases will use saturated arithmetic, taking advantage of having all the lower 32 bits set, which will avoid the reference count to go beyond the refcount limit. Immortality checks for reference count decreases will be done by checking the bit sign flag in the lower 32 bits. + */ -#define _Py_IMMORTAL_REFCNT _Py_CAST(Py_ssize_t, UINT_MAX) +#define _Py_IMMORTAL_INITIAL_REFCNT ((Py_ssize_t)(3UL << 30)) #else /* -In 32 bit systems, an object will be marked as immortal by setting all of the -lower 30 bits of the reference count field, which is equal to: 0x3FFFFFFF +In 32 bit systems, an object will be treated as immortal if its reference +count equals or exceeds _Py_IMMORTAL_MINIMUM_REFCNT (2**30). Using the lower 30 bits makes the value backwards compatible by allowing C-Extensions without the updated checks in Py_INCREF and Py_DECREF to safely @@ -47,9 +52,10 @@ increase and decrease the objects reference count. The object would lose its immortality, but the execution would still be correct. Reference count increases and decreases will first go through an immortality -check by comparing the reference count field to the immortality reference count. +check by comparing the reference count field to the minimum immortality refcount. */ -#define _Py_IMMORTAL_REFCNT _Py_CAST(Py_ssize_t, UINT_MAX >> 2) +#define _Py_IMMORTAL_INITIAL_REFCNT ((Py_ssize_t)(3L << 29)) +#define _Py_IMMORTAL_MINIMUM_REFCNT ((Py_ssize_t)(1L << 30)) #endif // Py_GIL_DISABLED builds indicate immortal objects using `ob_ref_local`, which is @@ -90,7 +96,7 @@ PyAPI_FUNC(Py_ssize_t) Py_REFCNT(PyObject *ob); #else uint32_t local = _Py_atomic_load_uint32_relaxed(&ob->ob_ref_local); if (local == _Py_IMMORTAL_REFCNT_LOCAL) { - return _Py_IMMORTAL_REFCNT; + return _Py_IMMORTAL_INITIAL_REFCNT; } Py_ssize_t shared = _Py_atomic_load_ssize_relaxed(&ob->ob_ref_shared); return _Py_STATIC_CAST(Py_ssize_t, local) + @@ -109,9 +115,9 @@ static inline Py_ALWAYS_INLINE int _Py_IsImmortal(PyObject *op) return (_Py_atomic_load_uint32_relaxed(&op->ob_ref_local) == _Py_IMMORTAL_REFCNT_LOCAL); #elif SIZEOF_VOID_P > 4 - return (_Py_CAST(PY_INT32_T, op->ob_refcnt) < 0); + return _Py_CAST(PY_INT32_T, op->ob_refcnt) < 0; #else - return (op->ob_refcnt == _Py_IMMORTAL_REFCNT); + return op->ob_refcnt >= _Py_IMMORTAL_MINIMUM_REFCNT; #endif } #define _Py_IsImmortal(op) _Py_IsImmortal(_PyObject_CAST(op)) @@ -236,7 +242,7 @@ static inline Py_ALWAYS_INLINE void Py_INCREF(PyObject *op) uint32_t new_local = local + 1; if (new_local == 0) { _Py_INCREF_IMMORTAL_STAT_INC(); - // local is equal to _Py_IMMORTAL_REFCNT: do nothing + // local is equal to _Py_IMMORTAL_REFCNT_LOCAL: do nothing return; } if (_Py_IsOwnedByCurrentThread(op)) { @@ -246,18 +252,14 @@ static inline Py_ALWAYS_INLINE void Py_INCREF(PyObject *op) _Py_atomic_add_ssize(&op->ob_ref_shared, (1 << _Py_REF_SHARED_SHIFT)); } #elif SIZEOF_VOID_P > 4 - // Portable saturated add, branching on the carry flag and set low bits PY_UINT32_T cur_refcnt = op->ob_refcnt_split[PY_BIG_ENDIAN]; - PY_UINT32_T new_refcnt = cur_refcnt + 1; - if (new_refcnt == 0) { + if (((int32_t)cur_refcnt) < 0) { + // the object is immortal _Py_INCREF_IMMORTAL_STAT_INC(); - // cur_refcnt is equal to _Py_IMMORTAL_REFCNT: the object is immortal, - // do nothing return; } - op->ob_refcnt_split[PY_BIG_ENDIAN] = new_refcnt; + op->ob_refcnt_split[PY_BIG_ENDIAN] = cur_refcnt + 1; #else - // Explicitly check immortality against the immortal value if (_Py_IsImmortal(op)) { _Py_INCREF_IMMORTAL_STAT_INC(); return; diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index d884f54940b471..eb5906f8944c8e 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -2574,9 +2574,9 @@ def __del__(self): class ImmortalTests(unittest.TestCase): if sys.maxsize < (1 << 32): - IMMORTAL_REFCOUNT = (1 << 30) - 1 + IMMORTAL_REFCOUNT = 3 << 29 else: - IMMORTAL_REFCOUNT = (1 << 32) - 1 + IMMORTAL_REFCOUNT = 3 << 30 IMMORTALS = (None, True, False, Ellipsis, NotImplemented, *range(-5, 257)) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-10-10-12-04-56.gh-issue-125174._8h6T7.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-10-12-04-56.gh-issue-125174._8h6T7.rst new file mode 100644 index 00000000000000..c7eaac32601bb3 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-10-12-04-56.gh-issue-125174._8h6T7.rst @@ -0,0 +1,4 @@ +Make the handling of reference counts of immortal objects more robust. +Immortal objects with reference counts that deviate from their original +reference count by up to a billion (half a billion on 32 bit builds) are +still counted as immortal. diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 870084100a1b85..0a769c46b87ac8 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -1387,7 +1387,7 @@ FutureObj_get_state(FutureObj *fut, void *Py_UNUSED(ignored)) default: assert (0); } - assert(_Py_IsImmortalLoose(ret)); + assert(_Py_IsImmortal(ret)); return ret; } diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index bf58e55e100b3a..dcc1aba76abbed 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -46,7 +46,7 @@ Py_LOCAL_INLINE(Py_ssize_t) _PyBytesWriter_GetSize(_PyBytesWriter *writer, static inline PyObject* bytes_get_empty(void) { PyObject *empty = &EMPTY->ob_base.ob_base; - assert(_Py_IsImmortalLoose(empty)); + assert(_Py_IsImmortal(empty)); return empty; } @@ -119,7 +119,7 @@ PyBytes_FromStringAndSize(const char *str, Py_ssize_t size) } if (size == 1 && str != NULL) { op = CHARACTER(*str & 255); - assert(_Py_IsImmortalLoose(op)); + assert(_Py_IsImmortal(op)); return (PyObject *)op; } if (size == 0) { @@ -155,7 +155,7 @@ PyBytes_FromString(const char *str) } else if (size == 1) { op = CHARACTER(*str & 255); - assert(_Py_IsImmortalLoose(op)); + assert(_Py_IsImmortal(op)); return (PyObject *)op; } diff --git a/Objects/dictobject.c b/Objects/dictobject.c index adfd91d1e4d63b..12722eca6be5e5 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -416,6 +416,8 @@ _PyDict_DebugMallocStats(FILE *out) #define DK_MASK(dk) (DK_SIZE(dk)-1) +#define _Py_DICT_IMMORTAL_INITIAL_REFCNT PY_SSIZE_T_MIN + static void free_keys_object(PyDictKeysObject *keys, bool use_qsbr); /* PyDictKeysObject has refcounts like PyObject does, so we have the @@ -428,7 +430,8 @@ static void free_keys_object(PyDictKeysObject *keys, bool use_qsbr); static inline void dictkeys_incref(PyDictKeysObject *dk) { - if (FT_ATOMIC_LOAD_SSIZE_RELAXED(dk->dk_refcnt) == _Py_IMMORTAL_REFCNT) { + if (FT_ATOMIC_LOAD_SSIZE_RELAXED(dk->dk_refcnt) < 0) { + assert(FT_ATOMIC_LOAD_SSIZE_RELAXED(dk->dk_refcnt) == _Py_DICT_IMMORTAL_INITIAL_REFCNT); return; } #ifdef Py_REF_DEBUG @@ -440,7 +443,8 @@ dictkeys_incref(PyDictKeysObject *dk) static inline void dictkeys_decref(PyInterpreterState *interp, PyDictKeysObject *dk, bool use_qsbr) { - if (FT_ATOMIC_LOAD_SSIZE_RELAXED(dk->dk_refcnt) == _Py_IMMORTAL_REFCNT) { + if (FT_ATOMIC_LOAD_SSIZE_RELAXED(dk->dk_refcnt) < 0) { + assert(FT_ATOMIC_LOAD_SSIZE_RELAXED(dk->dk_refcnt) == _Py_DICT_IMMORTAL_INITIAL_REFCNT); return; } assert(FT_ATOMIC_LOAD_SSIZE(dk->dk_refcnt) > 0); @@ -586,7 +590,7 @@ estimate_log2_keysize(Py_ssize_t n) * (which cannot fail and thus can do no allocation). */ static PyDictKeysObject empty_keys_struct = { - _Py_IMMORTAL_REFCNT, /* dk_refcnt */ + _Py_DICT_IMMORTAL_INITIAL_REFCNT, /* dk_refcnt */ 0, /* dk_log2_size */ 0, /* dk_log2_index_bytes */ DICT_KEYS_UNICODE, /* dk_kind */ diff --git a/Objects/object.c b/Objects/object.c index a97a900890320d..27d06cc081259d 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2453,7 +2453,7 @@ _Py_SetImmortalUntracked(PyObject *op) op->ob_ref_local = _Py_IMMORTAL_REFCNT_LOCAL; op->ob_ref_shared = 0; #else - op->ob_refcnt = _Py_IMMORTAL_REFCNT; + op->ob_refcnt = _Py_IMMORTAL_INITIAL_REFCNT; #endif } diff --git a/Objects/structseq.c b/Objects/structseq.c index 6092742835400b..56a7851b98788d 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -708,7 +708,7 @@ _PyStructSequence_FiniBuiltin(PyInterpreterState *interp, PyTypeObject *type) assert(type->tp_name != NULL); assert(type->tp_base == &PyTuple_Type); assert((type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN)); - assert(_Py_IsImmortalLoose(type)); + assert(_Py_IsImmortal(type)); // Cannot delete a type if it still has subclasses if (_PyType_HasSubclasses(type)) { diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 5380633fa1149e..d90bb5825fd437 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -476,7 +476,7 @@ set_tp_bases(PyTypeObject *self, PyObject *bases, int initial) assert(PyTuple_GET_SIZE(bases) == 1); assert(PyTuple_GET_ITEM(bases, 0) == (PyObject *)self->tp_base); assert(self->tp_base->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN); - assert(_Py_IsImmortalLoose(self->tp_base)); + assert(_Py_IsImmortal(self->tp_base)); } _Py_SetImmortal(bases); } @@ -493,7 +493,7 @@ clear_tp_bases(PyTypeObject *self, int final) Py_CLEAR(self->tp_bases); } else { - assert(_Py_IsImmortalLoose(self->tp_bases)); + assert(_Py_IsImmortal(self->tp_bases)); _Py_ClearImmortal(self->tp_bases); } } @@ -558,7 +558,7 @@ clear_tp_mro(PyTypeObject *self, int final) Py_CLEAR(self->tp_mro); } else { - assert(_Py_IsImmortalLoose(self->tp_mro)); + assert(_Py_IsImmortal(self->tp_mro)); _Py_ClearImmortal(self->tp_mro); } } @@ -5966,7 +5966,7 @@ fini_static_type(PyInterpreterState *interp, PyTypeObject *type, int isbuiltin, int final) { assert(type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN); - assert(_Py_IsImmortalLoose((PyObject *)type)); + assert(_Py_IsImmortal((PyObject *)type)); type_dealloc_common(type); diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 87cca3fc1d373c..34fdfcb05e3c18 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -381,7 +381,7 @@ dummy_func( EXIT_IF(!PyLong_CheckExact(value_o)); STAT_INC(TO_BOOL, hit); if (_PyLong_IsZero((PyLongObject *)value_o)) { - assert(_Py_IsImmortalLoose(value_o)); + assert(_Py_IsImmortal(value_o)); DEAD(value); res = PyStackRef_False; } @@ -412,7 +412,7 @@ dummy_func( EXIT_IF(!PyUnicode_CheckExact(value_o)); STAT_INC(TO_BOOL, hit); if (value_o == &_Py_STR(empty)) { - assert(_Py_IsImmortalLoose(value_o)); + assert(_Py_IsImmortal(value_o)); DEAD(value); res = PyStackRef_False; } diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 57e15f33ca7703..ef110e2e2a794a 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -402,7 +402,7 @@ } STAT_INC(TO_BOOL, hit); if (_PyLong_IsZero((PyLongObject *)value_o)) { - assert(_Py_IsImmortalLoose(value_o)); + assert(_Py_IsImmortal(value_o)); res = PyStackRef_False; } else { @@ -455,7 +455,7 @@ } STAT_INC(TO_BOOL, hit); if (value_o == &_Py_STR(empty)) { - assert(_Py_IsImmortalLoose(value_o)); + assert(_Py_IsImmortal(value_o)); res = PyStackRef_False; } else { diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 7656ce6bb7e313..7023aea369db49 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -7840,7 +7840,7 @@ DEOPT_IF(!PyLong_CheckExact(value_o), TO_BOOL); STAT_INC(TO_BOOL, hit); if (_PyLong_IsZero((PyLongObject *)value_o)) { - assert(_Py_IsImmortalLoose(value_o)); + assert(_Py_IsImmortal(value_o)); res = PyStackRef_False; } else { @@ -7902,7 +7902,7 @@ DEOPT_IF(!PyUnicode_CheckExact(value_o), TO_BOOL); STAT_INC(TO_BOOL, hit); if (value_o == &_Py_STR(empty)) { - assert(_Py_IsImmortalLoose(value_o)); + assert(_Py_IsImmortal(value_o)); res = PyStackRef_False; } else { diff --git a/Python/import.c b/Python/import.c index 460b1fe225c72e..acf849f14562b9 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1051,7 +1051,7 @@ del_cached_def(struct extensions_cache_value *value) However, this decref would be problematic if the module def were dynamically allocated, it were the last ref, and this function were called with an interpreter other than the def's owner. */ - assert(value->def == NULL || _Py_IsImmortalLoose(value->def)); + assert(value->def == NULL || _Py_IsImmortal(value->def)); Py_XDECREF(value->def->m_base.m_copy); value->def->m_base.m_copy = NULL; diff --git a/Tools/cases_generator/analyzer.py b/Tools/cases_generator/analyzer.py index 9c2981a68ac909..60f5d010a7a083 100644 --- a/Tools/cases_generator/analyzer.py +++ b/Tools/cases_generator/analyzer.py @@ -614,7 +614,6 @@ def has_error_without_pop(op: parser.InstDef) -> bool: "_Py_EnterRecursiveCallTstateUnchecked", "_Py_ID", "_Py_IsImmortal", - "_Py_IsImmortalLoose", "_Py_LeaveRecursiveCallPy", "_Py_LeaveRecursiveCallTstate", "_Py_NewRef", From 3b87fb74c907510402678bf1b7c4a94df0e5e65a Mon Sep 17 00:00:00 2001 From: Justin Kunimune Date: Thu, 10 Oct 2024 13:56:05 -0400 Subject: [PATCH 011/170] Note argparse exit code in documentation (GH-119568) Co-authored-by: Savannah Ostrowski --- Doc/library/argparse.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index e9a08984f77c3a..4eb6fad41f11ef 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -541,7 +541,8 @@ exit_on_error ^^^^^^^^^^^^^ Normally, when you pass an invalid argument list to the :meth:`~ArgumentParser.parse_args` -method of an :class:`ArgumentParser`, it will exit with error info. +method of an :class:`ArgumentParser`, it will print a *message* to :data:`sys.stderr` and exit with a status +code of 2. If the user would like to catch errors manually, the feature can be enabled by setting ``exit_on_error`` to ``False``:: From bb594e801b6a84823badbb85b88f0fc8b221d7bf Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 10 Oct 2024 20:41:14 +0200 Subject: [PATCH 012/170] gh-125196: Use PyUnicodeWriter for repr(dict) (#125270) --- Objects/dictobject.c | 72 ++++++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 12722eca6be5e5..b27599d2815c82 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -3200,16 +3200,12 @@ static PyObject * dict_repr_lock_held(PyObject *self) { PyDictObject *mp = (PyDictObject *)self; - Py_ssize_t i; PyObject *key = NULL, *value = NULL; - _PyUnicodeWriter writer; - int first; - ASSERT_DICT_LOCKED(mp); - i = Py_ReprEnter((PyObject *)mp); - if (i != 0) { - return i > 0 ? PyUnicode_FromString("{...}") : NULL; + int res = Py_ReprEnter((PyObject *)mp); + if (res != 0) { + return (res > 0 ? PyUnicode_FromString("{...}") : NULL); } if (mp->ma_used == 0) { @@ -3217,66 +3213,70 @@ dict_repr_lock_held(PyObject *self) return PyUnicode_FromString("{}"); } - _PyUnicodeWriter_Init(&writer); - writer.overallocate = 1; - /* "{" + "1: 2" + ", 3: 4" * (len - 1) + "}" */ - writer.min_length = 1 + 4 + (2 + 4) * (mp->ma_used - 1) + 1; + // "{" + "1: 2" + ", 3: 4" * (len - 1) + "}" + Py_ssize_t prealloc = 1 + 4 + 6 * (mp->ma_used - 1) + 1; + PyUnicodeWriter *writer = PyUnicodeWriter_Create(prealloc); + if (writer == NULL) { + goto error; + } - if (_PyUnicodeWriter_WriteChar(&writer, '{') < 0) + if (PyUnicodeWriter_WriteChar(writer, '{') < 0) { goto error; + } /* Do repr() on each key+value pair, and insert ": " between them. Note that repr may mutate the dict. */ - i = 0; - first = 1; + Py_ssize_t i = 0; + int first = 1; while (_PyDict_Next((PyObject *)mp, &i, &key, &value, NULL)) { - PyObject *s; - int res; - - /* Prevent repr from deleting key or value during key format. */ + // Prevent repr from deleting key or value during key format. Py_INCREF(key); Py_INCREF(value); if (!first) { - if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ", 2) < 0) + // Write ", " + if (PyUnicodeWriter_WriteChar(writer, ',') < 0) { + goto error; + } + if (PyUnicodeWriter_WriteChar(writer, ' ') < 0) { goto error; + } } first = 0; - s = PyObject_Repr(key); - if (s == NULL) - goto error; - res = _PyUnicodeWriter_WriteStr(&writer, s); - Py_DECREF(s); - if (res < 0) + // Write repr(key) + if (PyUnicodeWriter_WriteRepr(writer, key) < 0) { goto error; + } - if (_PyUnicodeWriter_WriteASCIIString(&writer, ": ", 2) < 0) + // Write ": " + if (PyUnicodeWriter_WriteChar(writer, ':') < 0) { goto error; - - s = PyObject_Repr(value); - if (s == NULL) + } + if (PyUnicodeWriter_WriteChar(writer, ' ') < 0) { goto error; - res = _PyUnicodeWriter_WriteStr(&writer, s); - Py_DECREF(s); - if (res < 0) + } + + // Write repr(value) + if (PyUnicodeWriter_WriteRepr(writer, value) < 0) { goto error; + } Py_CLEAR(key); Py_CLEAR(value); } - writer.overallocate = 0; - if (_PyUnicodeWriter_WriteChar(&writer, '}') < 0) + if (PyUnicodeWriter_WriteChar(writer, '}') < 0) { goto error; + } Py_ReprLeave((PyObject *)mp); - return _PyUnicodeWriter_Finish(&writer); + return PyUnicodeWriter_Finish(writer); error: Py_ReprLeave((PyObject *)mp); - _PyUnicodeWriter_Dealloc(&writer); + PyUnicodeWriter_Discard(writer); Py_XDECREF(key); Py_XDECREF(value); return NULL; From 427dcf24de4e06d239745d74d08c4b2e541dca5a Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Thu, 10 Oct 2024 16:21:29 -0400 Subject: [PATCH 013/170] gh-125268: Use static string for "1e309" in AST (#125272) When formatting the AST as a string, infinite values are replaced by 1e309, which evaluates to infinity. The initialization of this string replacement was not thread-safe in the free threading build. --- Include/internal/pycore_global_objects.h | 3 -- .../pycore_global_objects_fini_generated.h | 1 + Include/internal/pycore_global_strings.h | 1 + .../internal/pycore_runtime_init_generated.h | 1 + .../internal/pycore_unicodeobject_generated.h | 4 +++ Parser/asdl_c.py | 2 -- Python/Python-ast.c | 2 -- Python/ast_unparse.c | 29 +++---------------- 8 files changed, 11 insertions(+), 32 deletions(-) diff --git a/Include/internal/pycore_global_objects.h b/Include/internal/pycore_global_objects.h index 913dce6f1ec0fe..e3f7ac707f0c37 100644 --- a/Include/internal/pycore_global_objects.h +++ b/Include/internal/pycore_global_objects.h @@ -66,9 +66,6 @@ struct _Py_static_objects { struct _Py_interp_cached_objects { PyObject *interned_strings; - /* AST */ - PyObject *str_replace_inf; - /* object.__reduce__ */ PyObject *objreduce; PyObject *type_slots_pname; diff --git a/Include/internal/pycore_global_objects_fini_generated.h b/Include/internal/pycore_global_objects_fini_generated.h index de68ef93257234..2fd7d5d13a98b2 100644 --- a/Include/internal/pycore_global_objects_fini_generated.h +++ b/Include/internal/pycore_global_objects_fini_generated.h @@ -562,6 +562,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(json_decoder)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(kwdefaults)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(list_err)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(str_replace_inf)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(type_params)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(utf_8)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(CANCELLED)); diff --git a/Include/internal/pycore_global_strings.h b/Include/internal/pycore_global_strings.h index 1591cb0a3f114f..fc3871570cc49d 100644 --- a/Include/internal/pycore_global_strings.h +++ b/Include/internal/pycore_global_strings.h @@ -48,6 +48,7 @@ struct _Py_global_strings { STRUCT_FOR_STR(json_decoder, "json.decoder") STRUCT_FOR_STR(kwdefaults, ".kwdefaults") STRUCT_FOR_STR(list_err, "list index out of range") + STRUCT_FOR_STR(str_replace_inf, "1e309") STRUCT_FOR_STR(type_params, ".type_params") STRUCT_FOR_STR(utf_8, "utf-8") } literals; diff --git a/Include/internal/pycore_runtime_init_generated.h b/Include/internal/pycore_runtime_init_generated.h index c9d20d0b5aacdb..3b80e265b0ca50 100644 --- a/Include/internal/pycore_runtime_init_generated.h +++ b/Include/internal/pycore_runtime_init_generated.h @@ -557,6 +557,7 @@ extern "C" { INIT_STR(json_decoder, "json.decoder"), \ INIT_STR(kwdefaults, ".kwdefaults"), \ INIT_STR(list_err, "list index out of range"), \ + INIT_STR(str_replace_inf, "1e309"), \ INIT_STR(type_params, ".type_params"), \ INIT_STR(utf_8, "utf-8"), \ } diff --git a/Include/internal/pycore_unicodeobject_generated.h b/Include/internal/pycore_unicodeobject_generated.h index d335373e88ee74..eb2eca06ec4d4f 100644 --- a/Include/internal/pycore_unicodeobject_generated.h +++ b/Include/internal/pycore_unicodeobject_generated.h @@ -2936,6 +2936,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); assert(PyUnicode_GET_LENGTH(string) != 1); + string = &_Py_STR(str_replace_inf); + _PyUnicode_InternStatic(interp, &string); + assert(_PyUnicode_CheckConsistency(string, 1)); + assert(PyUnicode_GET_LENGTH(string) != 1); string = &_Py_STR(anon_null); _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py index f50c28afcfe205..32eac3afafa5d5 100755 --- a/Parser/asdl_c.py +++ b/Parser/asdl_c.py @@ -2242,8 +2242,6 @@ def generate_ast_fini(module_state, f): for s in module_state: f.write(" Py_CLEAR(state->" + s + ');\n') f.write(textwrap.dedent(""" - Py_CLEAR(_Py_INTERP_CACHED_OBJECT(interp, str_replace_inf)); - state->finalized = 1; state->once = (_PyOnceFlag){0}; } diff --git a/Python/Python-ast.c b/Python/Python-ast.c index 89c52b9dc73cac..38d74b48d232f8 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -281,8 +281,6 @@ void _PyAST_Fini(PyInterpreterState *interp) Py_CLEAR(state->vararg); Py_CLEAR(state->withitem_type); - Py_CLEAR(_Py_INTERP_CACHED_OBJECT(interp, str_replace_inf)); - state->finalized = 1; state->once = (_PyOnceFlag){0}; } diff --git a/Python/ast_unparse.c b/Python/ast_unparse.c index 86f7a582b981a3..8017cfc7fcf268 100644 --- a/Python/ast_unparse.c +++ b/Python/ast_unparse.c @@ -2,7 +2,6 @@ #include "pycore_ast.h" // expr_ty #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_runtime.h" // _Py_ID() -#include // DBL_MAX_10_EXP #include /* This limited unparser is used to convert annotations back to strings @@ -13,10 +12,6 @@ _Py_DECLARE_STR(dbl_open_br, "{{"); _Py_DECLARE_STR(dbl_close_br, "}}"); -/* We would statically initialize this if doing so were simple enough. */ -#define _str_replace_inf(interp) \ - _Py_INTERP_CACHED_OBJECT(interp, str_replace_inf) - /* Forward declarations for recursion via helper functions. */ static PyObject * expr_as_unicode(expr_ty e, int level); @@ -78,13 +73,13 @@ append_repr(_PyUnicodeWriter *writer, PyObject *obj) } if ((PyFloat_CheckExact(obj) && isinf(PyFloat_AS_DOUBLE(obj))) || - PyComplex_CheckExact(obj)) + PyComplex_CheckExact(obj)) { - PyInterpreterState *interp = _PyInterpreterState_GET(); + _Py_DECLARE_STR(str_replace_inf, "1e309"); // evaluates to inf PyObject *new_repr = PyUnicode_Replace( repr, &_Py_ID(inf), - _str_replace_inf(interp), + &_Py_STR(str_replace_inf), -1 ); Py_DECREF(repr); @@ -918,20 +913,6 @@ append_ast_expr(_PyUnicodeWriter *writer, expr_ty e, int level) return -1; } -static int -maybe_init_static_strings(void) -{ - PyInterpreterState *interp = _PyInterpreterState_GET(); - if (_str_replace_inf(interp) == NULL) { - PyObject *tmp = PyUnicode_FromFormat("1e%d", 1 + DBL_MAX_10_EXP); - if (tmp == NULL) { - return -1; - } - _str_replace_inf(interp) = tmp; - } - return 0; -} - static PyObject * expr_as_unicode(expr_ty e, int level) { @@ -939,9 +920,7 @@ expr_as_unicode(expr_ty e, int level) _PyUnicodeWriter_Init(&writer); writer.min_length = 256; writer.overallocate = 1; - if (-1 == maybe_init_static_strings() || - -1 == append_ast_expr(&writer, e, level)) - { + if (-1 == append_ast_expr(&writer, e, level)) { _PyUnicodeWriter_Dealloc(&writer); return NULL; } From dd0ee201da34d1d4a631d77b420728f9233f53f9 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Date: Thu, 10 Oct 2024 21:26:01 +0100 Subject: [PATCH 014/170] Doc: Upgrade Sphinx to 8.1 (#125276) --- Doc/conf.py | 31 ++++++++++++++++++++++++------- Doc/requirements.txt | 2 +- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/Doc/conf.py b/Doc/conf.py index 287e0da46eb11c..d7197b17865854 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -11,6 +11,8 @@ import sys import time +import sphinx + sys.path.append(os.path.abspath('tools/extensions')) sys.path.append(os.path.abspath('includes')) @@ -62,7 +64,10 @@ # General substitutions. project = 'Python' -copyright = f"2001-{time.strftime('%Y')}, Python Software Foundation" +if sphinx.version_info[:2] >= (8, 1): + copyright = "2001-%Y, Python Software Foundation" +else: + copyright = f"2001-{time.strftime('%Y')}, Python Software Foundation" # We look for the Include/patchlevel.h file in the current Python source tree # and replace the values accordingly. @@ -361,10 +366,14 @@ } # This 'Last updated on:' timestamp is inserted at the bottom of every page. -html_time = int(os.environ.get('SOURCE_DATE_EPOCH', time.time())) -html_last_updated_fmt = time.strftime( - '%b %d, %Y (%H:%M UTC)', time.gmtime(html_time) -) +html_last_updated_fmt = '%b %d, %Y (%H:%M UTC)' +if sphinx.version_info[:2] >= (8, 1): + html_last_updated_use_utc = True +else: + html_time = int(os.environ.get('SOURCE_DATE_EPOCH', time.time())) + html_last_updated_fmt = time.strftime( + html_last_updated_fmt, time.gmtime(html_time) + ) # Path to find HTML templates. templates_path = ['tools/templates'] @@ -596,13 +605,21 @@ # mapping unique short aliases to a base URL and a prefix. # https://www.sphinx-doc.org/en/master/usage/extensions/extlinks.html extlinks = { - "cve": ("https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-%s", "CVE-%s"), - "cwe": ("https://cwe.mitre.org/data/definitions/%s.html", "CWE-%s"), "pypi": ("https://pypi.org/project/%s/", "%s"), "source": (SOURCE_URI, "%s"), } extlinks_detect_hardcoded_links = True +if sphinx.version_info[:2] < (8, 1): + # Sphinx 8.1 has in-built CVE and CWE roles. + extlinks |= { + "cve": ( + "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-%s", + "CVE-%s", + ), + "cwe": ("https://cwe.mitre.org/data/definitions/%s.html", "CWE-%s"), + } + # Options for c_annotations # ------------------------- diff --git a/Doc/requirements.txt b/Doc/requirements.txt index bf1028020b7af7..5105786ccf283c 100644 --- a/Doc/requirements.txt +++ b/Doc/requirements.txt @@ -6,7 +6,7 @@ # Sphinx version is pinned so that new versions that introduce new warnings # won't suddenly cause build failures. Updating the version is fine as long # as no warnings are raised by doing so. -sphinx~=8.0.0 +sphinx~=8.1.0 blurb From a726ce73ca69b3a5ccc2cbe23061070e686b1150 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Fri, 11 Oct 2024 00:53:45 +0100 Subject: [PATCH 015/170] Add some doctest cleanups for `turtle` and `configparser` (#125288) Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- Doc/library/configparser.rst | 1 + Doc/library/turtle.rst | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/Doc/library/configparser.rst b/Doc/library/configparser.rst index b5c18bbccffb78..3aad6f7b5d2d20 100644 --- a/Doc/library/configparser.rst +++ b/Doc/library/configparser.rst @@ -54,6 +54,7 @@ can be customized by end users easily. import os os.remove("example.ini") + os.remove("override.ini") Quick Start diff --git a/Doc/library/turtle.rst b/Doc/library/turtle.rst index da801d4dc1f5b3..efa4b6f8f1d3f9 100644 --- a/Doc/library/turtle.rst +++ b/Doc/library/turtle.rst @@ -14,6 +14,11 @@ from turtle import * turtle = Turtle() +.. testcleanup:: + + import os + os.remove("my_drawing.ps") + -------------- Introduction From 2f8301cbfbdd2976d254a4a772b4879069dd4298 Mon Sep 17 00:00:00 2001 From: Richard Hansen Date: Thu, 10 Oct 2024 22:39:17 -0400 Subject: [PATCH 016/170] gh-124872: Rename blurb file to reference the correct issue (#125285) --- ....7tinr0.rst => 2024-10-10-02-56-24.gh-issue-124872.0mDDOq.rst} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Misc/NEWS.d/next/Documentation/{2024-09-29-18-14-52.gh-issue-119333.7tinr0.rst => 2024-10-10-02-56-24.gh-issue-124872.0mDDOq.rst} (100%) diff --git a/Misc/NEWS.d/next/Documentation/2024-09-29-18-14-52.gh-issue-119333.7tinr0.rst b/Misc/NEWS.d/next/Documentation/2024-10-10-02-56-24.gh-issue-124872.0mDDOq.rst similarity index 100% rename from Misc/NEWS.d/next/Documentation/2024-09-29-18-14-52.gh-issue-119333.7tinr0.rst rename to Misc/NEWS.d/next/Documentation/2024-10-10-02-56-24.gh-issue-124872.0mDDOq.rst From c1913effeed4e4da4d5310a40ab518945001ffba Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Thu, 10 Oct 2024 23:30:27 -0700 Subject: [PATCH 017/170] gh-125296: Fix strange fragment identifier for `name or flags` in argparse docs (#125297) --- Doc/library/argparse.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index 4eb6fad41f11ef..d337de87ca8f39 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -602,7 +602,7 @@ The add_argument() method The following sections describe how each of these are used. -.. _name_or_flags: +.. _`name or flags`: name or flags ^^^^^^^^^^^^^ From b12e99261e656585ffbaa395af7c5dbaee5ad1ad Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Fri, 11 Oct 2024 03:56:01 -0400 Subject: [PATCH 018/170] gh-125221: Fix free-threading data race in `object.__reduce_ex__` (#125267) --- ...-10-10-14-47-13.gh-issue-125221.nfSQzT.rst | 2 ++ Objects/object.c | 8 ++++++++ Objects/typeobject.c | 20 +++++-------------- 3 files changed, 15 insertions(+), 15 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-10-10-14-47-13.gh-issue-125221.nfSQzT.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-10-10-14-47-13.gh-issue-125221.nfSQzT.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-10-14-47-13.gh-issue-125221.nfSQzT.rst new file mode 100644 index 00000000000000..c79650c3a64feb --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-10-14-47-13.gh-issue-125221.nfSQzT.rst @@ -0,0 +1,2 @@ +Fix possible race condition when calling :meth:`~object.__reduce_ex__` for the +first time in the free threading build. diff --git a/Objects/object.c b/Objects/object.c index 27d06cc081259d..4a4c5bf7d7f08a 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2372,6 +2372,14 @@ _PyTypes_InitTypes(PyInterpreterState *interp) } } + // Cache __reduce__ from PyBaseObject_Type object + PyObject *baseobj_dict = _PyType_GetDict(&PyBaseObject_Type); + PyObject *baseobj_reduce = PyDict_GetItemWithError(baseobj_dict, &_Py_ID(__reduce__)); + if (baseobj_reduce == NULL && PyErr_Occurred()) { + return _PyStatus_ERR("Can't get __reduce__ from base object"); + } + _Py_INTERP_CACHED_OBJECT(interp, objreduce) = baseobj_reduce; + // Must be after static types are initialized if (_Py_initialize_generic(interp) < 0) { return _PyStatus_ERR("Can't initialize generic types"); diff --git a/Objects/typeobject.c b/Objects/typeobject.c index d90bb5825fd437..6ca4406ec0ea2d 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -7359,18 +7359,7 @@ static PyObject * object___reduce_ex___impl(PyObject *self, int protocol) /*[clinic end generated code: output=2e157766f6b50094 input=f326b43fb8a4c5ff]*/ { -#define objreduce \ - (_Py_INTERP_CACHED_OBJECT(_PyInterpreterState_GET(), objreduce)) - PyObject *reduce, *res; - - if (objreduce == NULL) { - PyObject *dict = lookup_tp_dict(&PyBaseObject_Type); - objreduce = PyDict_GetItemWithError(dict, &_Py_ID(__reduce__)); - if (objreduce == NULL && PyErr_Occurred()) { - return NULL; - } - } - + PyObject *reduce; if (PyObject_GetOptionalAttr(self, &_Py_ID(__reduce__), &reduce) < 0) { return NULL; } @@ -7384,10 +7373,12 @@ object___reduce_ex___impl(PyObject *self, int protocol) Py_DECREF(reduce); return NULL; } - override = (clsreduce != objreduce); + + PyInterpreterState *interp = _PyInterpreterState_GET(); + override = (clsreduce != _Py_INTERP_CACHED_OBJECT(interp, objreduce)); Py_DECREF(clsreduce); if (override) { - res = _PyObject_CallNoArgs(reduce); + PyObject *res = _PyObject_CallNoArgs(reduce); Py_DECREF(reduce); return res; } @@ -7396,7 +7387,6 @@ object___reduce_ex___impl(PyObject *self, int protocol) } return _common_reduce(self, protocol); -#undef objreduce } static PyObject * From 0135848059162ad81478a7776fec622d68a36524 Mon Sep 17 00:00:00 2001 From: Jan Kaliszewski Date: Fri, 11 Oct 2024 10:15:46 +0200 Subject: [PATCH 019/170] gh-125058: update `_thread` docs regarding interruptibility of `lock.acquire()` (#125141) --- Doc/library/_thread.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Doc/library/_thread.rst b/Doc/library/_thread.rst index 5fd604c05380ac..6a66fc4c64bc45 100644 --- a/Doc/library/_thread.rst +++ b/Doc/library/_thread.rst @@ -219,9 +219,11 @@ In addition to these methods, lock objects can also be used via the * Calling :func:`sys.exit` or raising the :exc:`SystemExit` exception is equivalent to calling :func:`_thread.exit`. -* It is not possible to interrupt the :meth:`~threading.Lock.acquire` method on - a lock --- the :exc:`KeyboardInterrupt` exception will happen after the lock - has been acquired. +* It is platform-dependent whether the :meth:`~threading.Lock.acquire` method + on a lock can be interrupted (so that the :exc:`KeyboardInterrupt` exception + will happen immediately, rather than only after the lock has been acquired or + the operation has timed out). It can be interrupted on POSIX, but not on + Windows. * When the main thread exits, it is system defined whether the other threads survive. On most systems, they are killed without executing From 18c74497681e0107d7cde53e63ea42feb38f2176 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 11 Oct 2024 11:43:29 +0300 Subject: [PATCH 020/170] gh-61011: Fix inheritance of nested mutually exclusive groups in argparse (GH-125210) Previously, all nested mutually exclusive groups lost their connection to the group containing them and were displayed as belonging directly to the parser. Co-authored-by: Danica J. Sutherland --- Lib/argparse.py | 6 +++- Lib/test/test_argparse.py | 29 +++++++++++++++++++ Misc/ACKS | 1 + ...4-10-09-21-42-43.gh-issue-61011.pQXZb1.rst | 4 +++ 4 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-09-21-42-43.gh-issue-61011.pQXZb1.rst diff --git a/Lib/argparse.py b/Lib/argparse.py index d1f8fa2ace8611..2d8a7ef343a4ef 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -1521,7 +1521,11 @@ def _add_container_actions(self, container): # NOTE: if add_mutually_exclusive_group ever gains title= and # description= then this code will need to be expanded as above for group in container._mutually_exclusive_groups: - mutex_group = self.add_mutually_exclusive_group( + if group._container is container: + cont = self + else: + cont = title_group_map[group._container.title] + mutex_group = cont.add_mutually_exclusive_group( required=group.required) # map the actions to their new mutex group diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index c9e79eb18a08fb..1ebbc21bc1755b 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -2942,6 +2942,35 @@ def test_groups_parents(self): def test_wrong_type_parents(self): self.assertRaises(TypeError, ErrorRaisingArgumentParser, parents=[1]) + def test_mutex_groups_parents(self): + parent = ErrorRaisingArgumentParser(add_help=False) + g = parent.add_argument_group(title='g', description='gd') + g.add_argument('-w') + g.add_argument('-x') + m = g.add_mutually_exclusive_group() + m.add_argument('-y') + m.add_argument('-z') + parser = ErrorRaisingArgumentParser(prog='PROG', parents=[parent]) + + self.assertRaises(ArgumentParserError, parser.parse_args, + ['-y', 'Y', '-z', 'Z']) + + parser_help = parser.format_help() + self.assertEqual(parser_help, textwrap.dedent('''\ + usage: PROG [-h] [-w W] [-x X] [-y Y | -z Z] + + options: + -h, --help show this help message and exit + + g: + gd + + -w W + -x X + -y Y + -z Z + ''')) + # ============================== # Mutually exclusive group tests # ============================== diff --git a/Misc/ACKS b/Misc/ACKS index d94cbacf888468..a1769d9601a2ea 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1814,6 +1814,7 @@ Reuben Sumner Eryk Sun Sanjay Sundaresan Marek Šuppa +Danica J. Sutherland Hisao Suzuki Kalle Svensson Andrew Svetlov diff --git a/Misc/NEWS.d/next/Library/2024-10-09-21-42-43.gh-issue-61011.pQXZb1.rst b/Misc/NEWS.d/next/Library/2024-10-09-21-42-43.gh-issue-61011.pQXZb1.rst new file mode 100644 index 00000000000000..20f9c0b9c78b12 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-09-21-42-43.gh-issue-61011.pQXZb1.rst @@ -0,0 +1,4 @@ +Fix inheritance of nested mutually exclusive groups from parent parser in +:class:`argparse.ArgumentParser`. Previously, all nested mutually exclusive +groups lost their connection to the group containing them and were displayed +as belonging directly to the parser. From b3aa1b5fe260382788a2df416599325ad680a5ee Mon Sep 17 00:00:00 2001 From: Y5 <124019959+y5c4l3@users.noreply.github.com> Date: Fri, 11 Oct 2024 09:08:03 +0000 Subject: [PATCH 021/170] gh-125235: Keep `_tkinter` TCL paths pointing to base installation on Windows (#125250) Signed-off-by: y5c4l3 --- .../next/Library/2024-10-10-18-33-31.gh-issue-125235.0kOB5I.rst | 2 ++ Modules/_tkinter.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-10-18-33-31.gh-issue-125235.0kOB5I.rst diff --git a/Misc/NEWS.d/next/Library/2024-10-10-18-33-31.gh-issue-125235.0kOB5I.rst b/Misc/NEWS.d/next/Library/2024-10-10-18-33-31.gh-issue-125235.0kOB5I.rst new file mode 100644 index 00000000000000..f64d15917da1fc --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-10-18-33-31.gh-issue-125235.0kOB5I.rst @@ -0,0 +1,2 @@ +Keep :mod:`tkinter` TCL paths in venv pointing to base installation on +Windows. diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index 4f05cab375ed6b..b0b70ccb8cc3d3 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -143,7 +143,7 @@ _get_tcl_lib_path(void) struct stat stat_buf; int stat_return_value; - PyObject *prefix = PySys_GetObject("prefix"); // borrowed reference + PyObject *prefix = PySys_GetObject("base_prefix"); // borrowed reference if (prefix == NULL) { return NULL; } From 2115d76acc14effb3dbb9fedcf21048b2ad62c5e Mon Sep 17 00:00:00 2001 From: sobolevn Date: Fri, 11 Oct 2024 17:39:18 +0300 Subject: [PATCH 022/170] gh-124787: Fix `TypeAliasType` and incorrect `type_params` (#124795) Co-authored-by: Jelle Zijlstra --- Lib/test/test_type_aliases.py | 44 ++++++++- ...-09-30-20-46-32.gh-issue-124787.3FnJnP.rst | 4 + Objects/typevarobject.c | 97 ++++++++++++++++--- 3 files changed, 133 insertions(+), 12 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-09-30-20-46-32.gh-issue-124787.3FnJnP.rst diff --git a/Lib/test/test_type_aliases.py b/Lib/test/test_type_aliases.py index ebb65d8c6cf81b..230bbe646baf28 100644 --- a/Lib/test/test_type_aliases.py +++ b/Lib/test/test_type_aliases.py @@ -4,7 +4,9 @@ from test.support import check_syntax_error, run_code from test.typinganndata import mod_generics_cache -from typing import Callable, TypeAliasType, TypeVar, get_args +from typing import ( + Callable, TypeAliasType, TypeVar, TypeVarTuple, ParamSpec, get_args, +) class TypeParamsInvalidTest(unittest.TestCase): @@ -225,6 +227,46 @@ def test_not_generic(self): ): TA[int] + def test_type_params_order_with_defaults(self): + HasNoDefaultT = TypeVar("HasNoDefaultT") + WithDefaultT = TypeVar("WithDefaultT", default=int) + + HasNoDefaultP = ParamSpec("HasNoDefaultP") + WithDefaultP = ParamSpec("WithDefaultP", default=HasNoDefaultP) + + HasNoDefaultTT = TypeVarTuple("HasNoDefaultTT") + WithDefaultTT = TypeVarTuple("WithDefaultTT", default=HasNoDefaultTT) + + for type_params in [ + (HasNoDefaultT, WithDefaultT), + (HasNoDefaultP, WithDefaultP), + (HasNoDefaultTT, WithDefaultTT), + ]: + with self.subTest(type_params=type_params): + TypeAliasType("A", int, type_params=type_params) # ok + + msg = "follows default type parameter" + for type_params in [ + (WithDefaultT, HasNoDefaultT), + (WithDefaultP, HasNoDefaultP), + (WithDefaultTT, HasNoDefaultTT), + (WithDefaultT, HasNoDefaultP), # different types + ]: + with self.subTest(type_params=type_params): + with self.assertRaisesRegex(TypeError, msg): + TypeAliasType("A", int, type_params=type_params) + + def test_expects_type_like(self): + T = TypeVar("T") + + msg = "Expected a type param" + with self.assertRaisesRegex(TypeError, msg): + TypeAliasType("A", int, type_params=(1,)) + with self.assertRaisesRegex(TypeError, msg): + TypeAliasType("A", int, type_params=(1, 2)) + with self.assertRaisesRegex(TypeError, msg): + TypeAliasType("A", int, type_params=(T, 2)) + def test_keywords(self): TA = TypeAliasType(name="TA", value=int) self.assertEqual(TA.__name__, "TA") diff --git a/Misc/NEWS.d/next/Library/2024-09-30-20-46-32.gh-issue-124787.3FnJnP.rst b/Misc/NEWS.d/next/Library/2024-09-30-20-46-32.gh-issue-124787.3FnJnP.rst new file mode 100644 index 00000000000000..d9d1bbcf5a2fe4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-09-30-20-46-32.gh-issue-124787.3FnJnP.rst @@ -0,0 +1,4 @@ +Fix :class:`typing.TypeAliasType` with incorrect ``type_params`` argument. +Now it raises a :exc:`TypeError` when a type parameter without a default +follows one with a default, and when an entry in the ``type_params`` tuple +is not a type parameter object. diff --git a/Objects/typevarobject.c b/Objects/typevarobject.c index 51d93ed8b5ba8c..91cc37c9a72636 100644 --- a/Objects/typevarobject.c +++ b/Objects/typevarobject.c @@ -1799,6 +1799,24 @@ _Py_make_typevartuple(PyThreadState *Py_UNUSED(ignored), PyObject *v) return (PyObject *)typevartuple_alloc(v, NULL, NULL); } +static PyObject * +get_type_param_default(PyThreadState *ts, PyObject *typeparam) { + // Does not modify refcount of existing objects. + if (Py_IS_TYPE(typeparam, ts->interp->cached_objects.typevar_type)) { + return typevar_default((typevarobject *)typeparam, NULL); + } + else if (Py_IS_TYPE(typeparam, ts->interp->cached_objects.paramspec_type)) { + return paramspec_default((paramspecobject *)typeparam, NULL); + } + else if (Py_IS_TYPE(typeparam, ts->interp->cached_objects.typevartuple_type)) { + return typevartuple_default((typevartupleobject *)typeparam, NULL); + } + else { + PyErr_Format(PyExc_TypeError, "Expected a type param, got %R", typeparam); + return NULL; + } +} + static void typealias_dealloc(PyObject *self) { @@ -1906,25 +1924,75 @@ static PyGetSetDef typealias_getset[] = { {0} }; -static typealiasobject * -typealias_alloc(PyObject *name, PyObject *type_params, PyObject *compute_value, - PyObject *value, PyObject *module) -{ - typealiasobject *ta = PyObject_GC_New(typealiasobject, &_PyTypeAlias_Type); - if (ta == NULL) { +static PyObject * +typealias_check_type_params(PyObject *type_params, int *err) { + // Can return type_params or NULL without exception set. + // Does not change the reference count of type_params, + // sets `*err` to 1 when error happens and sets an exception, + // otherwise `*err` is set to 0. + *err = 0; + if (type_params == NULL) { return NULL; } - ta->name = Py_NewRef(name); + + assert(PyTuple_Check(type_params)); + Py_ssize_t length = PyTuple_GET_SIZE(type_params); + if (!length) { // 0-length tuples are the same as `NULL`. + return NULL; + } + + PyThreadState *ts = _PyThreadState_GET(); + int default_seen = 0; + for (Py_ssize_t index = 0; index < length; index++) { + PyObject *type_param = PyTuple_GET_ITEM(type_params, index); + PyObject *dflt = get_type_param_default(ts, type_param); + if (dflt == NULL) { + *err = 1; + return NULL; + } + if (dflt == &_Py_NoDefaultStruct) { + if (default_seen) { + *err = 1; + PyErr_Format(PyExc_TypeError, + "non-default type parameter '%R' " + "follows default type parameter", + type_param); + return NULL; + } + } else { + default_seen = 1; + Py_DECREF(dflt); + } + } + + return type_params; +} + +static PyObject * +typelias_convert_type_params(PyObject *type_params) +{ if ( type_params == NULL || Py_IsNone(type_params) || (PyTuple_Check(type_params) && PyTuple_GET_SIZE(type_params) == 0) ) { - ta->type_params = NULL; + return NULL; } else { - ta->type_params = Py_NewRef(type_params); + return type_params; } +} + +static typealiasobject * +typealias_alloc(PyObject *name, PyObject *type_params, PyObject *compute_value, + PyObject *value, PyObject *module) +{ + typealiasobject *ta = PyObject_GC_New(typealiasobject, &_PyTypeAlias_Type); + if (ta == NULL) { + return NULL; + } + ta->name = Py_NewRef(name); + ta->type_params = Py_XNewRef(type_params); ta->compute_value = Py_XNewRef(compute_value); ta->value = Py_XNewRef(value); ta->module = Py_XNewRef(module); @@ -2002,11 +2070,18 @@ typealias_new_impl(PyTypeObject *type, PyObject *name, PyObject *value, PyErr_SetString(PyExc_TypeError, "type_params must be a tuple"); return NULL; } + + int err = 0; + PyObject *checked_params = typealias_check_type_params(type_params, &err); + if (err) { + return NULL; + } + PyObject *module = caller(); if (module == NULL) { return NULL; } - PyObject *ta = (PyObject *)typealias_alloc(name, type_params, NULL, value, + PyObject *ta = (PyObject *)typealias_alloc(name, checked_params, NULL, value, module); Py_DECREF(module); return ta; @@ -2072,7 +2147,7 @@ _Py_make_typealias(PyThreadState* unused, PyObject *args) assert(PyTuple_GET_SIZE(args) == 3); PyObject *name = PyTuple_GET_ITEM(args, 0); assert(PyUnicode_Check(name)); - PyObject *type_params = PyTuple_GET_ITEM(args, 1); + PyObject *type_params = typelias_convert_type_params(PyTuple_GET_ITEM(args, 1)); PyObject *compute_value = PyTuple_GET_ITEM(args, 2); assert(PyFunction_Check(compute_value)); return (PyObject *)typealias_alloc(name, type_params, compute_value, NULL, NULL); From 08f6bf717118963815d9a3e60578104470fdf3e1 Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Sat, 12 Oct 2024 00:27:26 +0900 Subject: [PATCH 023/170] gh-124612: Update autoconf container image (#125320) --- Tools/build/regen-configure.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tools/build/regen-configure.sh b/Tools/build/regen-configure.sh index efc80c8527885c..1a24b07c3ff707 100755 --- a/Tools/build/regen-configure.sh +++ b/Tools/build/regen-configure.sh @@ -5,7 +5,7 @@ set -e -x # The check_generated_files job of .github/workflows/build.yml must kept in # sync with this script. Use the same container image than the job so the job # doesn't need to run autoreconf in a container. -IMAGE="ghcr.io/python/autoconf:2024.10.06.11200919239" +IMAGE="ghcr.io/python/autoconf:2024.10.11.11293396815" AUTORECONF="autoreconf -ivf -Werror" WORK_DIR="/src" From a00221e5a70e54a281ba0e2cff8d85cd37ae305f Mon Sep 17 00:00:00 2001 From: AN Long Date: Sat, 12 Oct 2024 01:55:36 +0800 Subject: [PATCH 024/170] gh-116738: Make `_csv` module thread-safe (#118344) --- Modules/_csv.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/Modules/_csv.c b/Modules/_csv.c index 913560ce4a0ee3..1a4dc3f1f55ace 100644 --- a/Modules/_csv.c +++ b/Modules/_csv.c @@ -14,6 +14,7 @@ module instead. #endif #include "Python.h" +#include "pycore_pyatomic_ft_wrappers.h" #include // offsetof() #include @@ -34,7 +35,7 @@ typedef struct { PyTypeObject *dialect_type; PyTypeObject *reader_type; PyTypeObject *writer_type; - long field_limit; /* max parsed field size */ + Py_ssize_t field_limit; /* max parsed field size */ PyObject *str_write; } _csvstate; @@ -706,10 +707,11 @@ parse_grow_buff(ReaderObj *self) static int parse_add_char(ReaderObj *self, _csvstate *module_state, Py_UCS4 c) { - if (self->field_len >= module_state->field_limit) { + Py_ssize_t field_limit = FT_ATOMIC_LOAD_SSIZE_RELAXED(module_state->field_limit); + if (self->field_len >= field_limit) { PyErr_Format(module_state->error_obj, - "field larger than field limit (%ld)", - module_state->field_limit); + "field larger than field limit (%zd)", + field_limit); return -1; } if (self->field_len == self->field_size && !parse_grow_buff(self)) @@ -1659,20 +1661,20 @@ _csv_field_size_limit_impl(PyObject *module, PyObject *new_limit) /*[clinic end generated code: output=f2799ecd908e250b input=cec70e9226406435]*/ { _csvstate *module_state = get_csv_state(module); - long old_limit = module_state->field_limit; + Py_ssize_t old_limit = FT_ATOMIC_LOAD_SSIZE_RELAXED(module_state->field_limit); if (new_limit != NULL) { if (!PyLong_CheckExact(new_limit)) { PyErr_Format(PyExc_TypeError, "limit must be an integer"); return NULL; } - module_state->field_limit = PyLong_AsLong(new_limit); - if (module_state->field_limit == -1 && PyErr_Occurred()) { - module_state->field_limit = old_limit; + Py_ssize_t new_limit_value = PyLong_AsSsize_t(new_limit); + if (new_limit_value == -1 && PyErr_Occurred()) { return NULL; } + FT_ATOMIC_STORE_SSIZE_RELAXED(module_state->field_limit, new_limit_value); } - return PyLong_FromLong(old_limit); + return PyLong_FromSsize_t(old_limit); } static PyType_Slot error_slots[] = { From cc2938a18967c9d462ebb18bc09f73e4364aa7d2 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Fri, 11 Oct 2024 12:41:59 -0700 Subject: [PATCH 025/170] gh-124917: Allow keyword args to os.path.exists/lexists on Windows (#124918) --- Lib/test/test_genericpath.py | 4 + ...-10-02-21-11-18.gh-issue-124917.Lnwh5b.rst | 2 + Modules/clinic/posixmodule.c.h | 78 ++++++++++++++++--- Modules/posixmodule.c | 6 +- 4 files changed, 77 insertions(+), 13 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-02-21-11-18.gh-issue-124917.Lnwh5b.rst diff --git a/Lib/test/test_genericpath.py b/Lib/test/test_genericpath.py index bf04b3fecf7057..6d2593cb4cf228 100644 --- a/Lib/test/test_genericpath.py +++ b/Lib/test/test_genericpath.py @@ -156,6 +156,10 @@ def test_exists(self): self.assertIs(self.pathmodule.lexists(filename + '\x00'), False) self.assertIs(self.pathmodule.lexists(bfilename + b'\x00'), False) + # Keyword arguments are accepted + self.assertIs(self.pathmodule.exists(path=filename), True) + self.assertIs(self.pathmodule.lexists(path=filename), True) + @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()") @unittest.skipIf(is_emscripten, "Emscripten pipe fds have no stat") def test_exists_fd(self): diff --git a/Misc/NEWS.d/next/Library/2024-10-02-21-11-18.gh-issue-124917.Lnwh5b.rst b/Misc/NEWS.d/next/Library/2024-10-02-21-11-18.gh-issue-124917.Lnwh5b.rst new file mode 100644 index 00000000000000..f208793859bbf8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-02-21-11-18.gh-issue-124917.Lnwh5b.rst @@ -0,0 +1,2 @@ +Allow calling :func:`os.path.exists` and :func:`os.path.lexists` with +keyword arguments on Windows. Fixes a regression in 3.13.0. diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index 749fe54598cc39..d9d919ea75d853 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -2015,25 +2015,55 @@ os__path_splitroot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py #if defined(MS_WINDOWS) PyDoc_STRVAR(os__path_exists__doc__, -"_path_exists($module, path, /)\n" +"_path_exists($module, /, path)\n" "--\n" "\n" "Test whether a path exists. Returns False for broken symbolic links."); #define OS__PATH_EXISTS_METHODDEF \ - {"_path_exists", (PyCFunction)os__path_exists, METH_O, os__path_exists__doc__}, + {"_path_exists", _PyCFunction_CAST(os__path_exists), METH_FASTCALL|METH_KEYWORDS, os__path_exists__doc__}, static int os__path_exists_impl(PyObject *module, path_t *path); static PyObject * -os__path_exists(PyObject *module, PyObject *arg) +os__path_exists(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"path", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_path_exists", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; path_t path = PATH_T_INITIALIZE_P("_path_exists", "path", 0, 0, 1, 1); int _return_value; - if (!path_converter(arg, &path)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!path_converter(args[0], &path)) { goto exit; } _return_value = os__path_exists_impl(module, &path); @@ -2054,25 +2084,55 @@ os__path_exists(PyObject *module, PyObject *arg) #if defined(MS_WINDOWS) PyDoc_STRVAR(os__path_lexists__doc__, -"_path_lexists($module, path, /)\n" +"_path_lexists($module, /, path)\n" "--\n" "\n" "Test whether a path exists. Returns True for broken symbolic links."); #define OS__PATH_LEXISTS_METHODDEF \ - {"_path_lexists", (PyCFunction)os__path_lexists, METH_O, os__path_lexists__doc__}, + {"_path_lexists", _PyCFunction_CAST(os__path_lexists), METH_FASTCALL|METH_KEYWORDS, os__path_lexists__doc__}, static int os__path_lexists_impl(PyObject *module, path_t *path); static PyObject * -os__path_lexists(PyObject *module, PyObject *arg) +os__path_lexists(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"path", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_path_lexists", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; path_t path = PATH_T_INITIALIZE_P("_path_lexists", "path", 0, 0, 1, 1); int _return_value; - if (!path_converter(arg, &path)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!path_converter(args[0], &path)) { goto exit; } _return_value = os__path_lexists_impl(module, &path); @@ -12837,4 +12897,4 @@ os__create_environ(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF #define OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF #endif /* !defined(OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF) */ -/*[clinic end generated code: output=b93bbaaa8eb5b0ce input=a9049054013a1b77]*/ +/*[clinic end generated code: output=18d75b737513dae6 input=a9049054013a1b77]*/ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 334350285f3b6f..c0af78ba075e85 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -5391,7 +5391,6 @@ _testFileType(path_t *path, int testedType) os._path_exists -> bool path: path_t(allow_fd=True, suppress_value_error=True) - / Test whether a path exists. Returns False for broken symbolic links. @@ -5399,7 +5398,7 @@ Test whether a path exists. Returns False for broken symbolic links. static int os__path_exists_impl(PyObject *module, path_t *path) -/*[clinic end generated code: output=8da13acf666e16ba input=29198507a6082a57]*/ +/*[clinic end generated code: output=8da13acf666e16ba input=142beabfc66783eb]*/ { return _testFileExists(path, TRUE); } @@ -5409,7 +5408,6 @@ os__path_exists_impl(PyObject *module, path_t *path) os._path_lexists -> bool path: path_t(allow_fd=True, suppress_value_error=True) - / Test whether a path exists. Returns True for broken symbolic links. @@ -5417,7 +5415,7 @@ Test whether a path exists. Returns True for broken symbolic links. static int os__path_lexists_impl(PyObject *module, path_t *path) -/*[clinic end generated code: output=e7240ed5fc45bff3 input=03d9fed8bc6ce96f]*/ +/*[clinic end generated code: output=e7240ed5fc45bff3 input=208205112a3cc1ed]*/ { return _testFileExists(path, FALSE); } From 76b29d271b3132bf8e13bc724f10be8c630057ba Mon Sep 17 00:00:00 2001 From: Rafael Fontenelle Date: Fri, 11 Oct 2024 17:00:31 -0300 Subject: [PATCH 026/170] Fix typo in ``Doclibrary/functions.rst`` (#125327) --- Doc/library/functions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 7f8df704a33327..0638df04c6ff40 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -686,7 +686,7 @@ are always available. They are listed here in alphabetical order. The *closure* argument specifies a closure--a tuple of cellvars. It's only valid when the *object* is a code object containing :term:`free (closure) variables `. - The length of the tuple must exactly match the length of the code object'S + The length of the tuple must exactly match the length of the code object's :attr:`~codeobject.co_freevars` attribute. .. audit-event:: exec code_object exec From 89515be596a0ca05fd9ab4ddf76c8013dd093545 Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Fri, 11 Oct 2024 21:18:37 +0100 Subject: [PATCH 027/170] gh-119786: Move garbage collection doc from devguide to InternalDocs (#125282) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Carol Willing carolcode@willingconsulting.com Co-Authored-By: Ezio Melotti ezio.melotti@gmail.com Co-Authored-By: Hugo van Kemenade hugovk@users.noreply.github.com Co-Authored-By: Itamar Ostricher itamarost@gmail.com Co-Authored-By: Jesús Cea jcea@jcea.es Co-Authored-By: Joannah Nanjekye 33177550+nanjekyejoannah@users.noreply.github.com Co-Authored-By: Ned Batchelder ned@nedbatchelder.com Co-Authored-By: Pablo Galindo Salgado Pablogsal@gmail.com Co-Authored-By: Pamela Fox pamela.fox@gmail.com Co-Authored-By: Sam Gross colesbury@gmail.com Co-Authored-By: Stefan Pochmann 609905+pochmann@users.noreply.github.com Co-Authored-By: T. Wouters thomas@python.org Co-Authored-By: q-ata 24601033+q-ata@users.noreply.github.com Co-Authored-By: slateny 46876382+slateny@users.noreply.github.com Co-Authored-By: Борис Верховский boris.verk@gmail.com Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Co-authored-by: Jacob Coffee --- InternalDocs/README.md | 2 + InternalDocs/garbage_collector.md | 596 ++++++++++++++++++ .../images/python-cyclic-gc-1-new-page.png | Bin 0 -> 4415 bytes .../images/python-cyclic-gc-2-new-page.png | Bin 0 -> 4337 bytes .../images/python-cyclic-gc-3-new-page.png | Bin 0 -> 4876 bytes .../images/python-cyclic-gc-4-new-page.png | Bin 0 -> 4863 bytes .../images/python-cyclic-gc-5-new-page.png | Bin 0 -> 5712 bytes 7 files changed, 598 insertions(+) create mode 100644 InternalDocs/garbage_collector.md create mode 100644 InternalDocs/images/python-cyclic-gc-1-new-page.png create mode 100644 InternalDocs/images/python-cyclic-gc-2-new-page.png create mode 100644 InternalDocs/images/python-cyclic-gc-3-new-page.png create mode 100644 InternalDocs/images/python-cyclic-gc-4-new-page.png create mode 100644 InternalDocs/images/python-cyclic-gc-5-new-page.png diff --git a/InternalDocs/README.md b/InternalDocs/README.md index 8956ecafed2039..805e2f97937e1e 100644 --- a/InternalDocs/README.md +++ b/InternalDocs/README.md @@ -22,4 +22,6 @@ it is not, please report that through the [The Source Code Locations Table](locations.md) +[Garbage collector design](garbage_collector.md) + [Exception Handling](exception_handling.md) diff --git a/InternalDocs/garbage_collector.md b/InternalDocs/garbage_collector.md new file mode 100644 index 00000000000000..fd0246fa1a60e2 --- /dev/null +++ b/InternalDocs/garbage_collector.md @@ -0,0 +1,596 @@ + +Garbage collector design +======================== + +Abstract +======== + +The main garbage collection algorithm used by CPython is reference counting. The basic idea is +that CPython counts how many different places there are that have a reference to an +object. Such a place could be another object, or a global (or static) C variable, or +a local variable in some C function. When an object’s reference count becomes zero, +the object is deallocated. If it contains references to other objects, their +reference counts are decremented. Those other objects may be deallocated in turn, if +this decrement makes their reference count become zero, and so on. The reference +count field can be examined using the ``sys.getrefcount()`` function (notice that the +value returned by this function is always 1 more as the function also has a reference +to the object when called): + +```pycon + >>> x = object() + >>> sys.getrefcount(x) + 2 + >>> y = x + >>> sys.getrefcount(x) + 3 + >>> del y + >>> sys.getrefcount(x) + 2 +``` + +The main problem with the reference counting scheme is that it does not handle reference +cycles. For instance, consider this code: + +```pycon + >>> container = [] + >>> container.append(container) + >>> sys.getrefcount(container) + 3 + >>> del container +``` + +In this example, ``container`` holds a reference to itself, so even when we remove +our reference to it (the variable "container") the reference count never falls to 0 +because it still has its own internal reference. Therefore it would never be +cleaned just by simple reference counting. For this reason some additional machinery +is needed to clean these reference cycles between objects once they become +unreachable. This is the cyclic garbage collector, usually called just Garbage +Collector (GC), even though reference counting is also a form of garbage collection. + +Starting in version 3.13, CPython contains two GC implementations: + +- The default build implementation relies on the + [global interpreter lock](https://docs.python.org/3/glossary.html#term-global-interpreter-lock) + for thread safety. +- The free-threaded build implementation pauses other executing threads when + performing a collection for thread safety. + +Both implementations use the same basic algorithms, but operate on different +data structures. The the section on +[Differences between GC implementations](#Differences-between-GC-implementations) +for the details. + + +Memory layout and object structure +================================== + +The garbage collector requires additional fields in Python objects to support +garbage collection. These extra fields are different in the default and the +free-threaded builds. + + +GC for the default build +------------------------ + +Normally the C structure supporting a regular Python object looks as follows: + +``` + object -----> +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ \ + | ob_refcnt | | + +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PyObject_HEAD + | *ob_type | | + +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / + | ... | +``` + +In order to support the garbage collector, the memory layout of objects is altered +to accommodate extra information **before** the normal layout: + +``` + +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ \ + | *_gc_next | | + +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PyGC_Head + | *_gc_prev | | + object -----> +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / + | ob_refcnt | \ + +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PyObject_HEAD + | *ob_type | | + +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / + | ... | +``` + + +In this way the object can be treated as a normal python object and when the extra +information associated to the GC is needed the previous fields can be accessed by a +simple type cast from the original object: `((PyGC_Head *)(the_object)-1)`. + +As is explained later in the +[Optimization: reusing fields to save memory](#optimization-reusing-fields-to-save-memory) +section, these two extra fields are normally used to keep doubly linked lists of all the +objects tracked by the garbage collector (these lists are the GC generations, more on +that in the [Optimization: generations](#Optimization-generations) section), but +they are also reused to fulfill other purposes when the full doubly linked list +structure is not needed as a memory optimization. + +Doubly linked lists are used because they efficiently support the most frequently required operations. In +general, the collection of all objects tracked by GC is partitioned into disjoint sets, each in its own +doubly linked list. Between collections, objects are partitioned into "generations", reflecting how +often they've survived collection attempts. During collections, the generation(s) being collected +are further partitioned into, for example, sets of reachable and unreachable objects. Doubly linked lists +support moving an object from one partition to another, adding a new object, removing an object +entirely (objects tracked by GC are most often reclaimed by the refcounting system when GC +isn't running at all!), and merging partitions, all with a small constant number of pointer updates. +With care, they also support iterating over a partition while objects are being added to - and +removed from - it, which is frequently required while GC is running. + +GC for the free-threaded build +------------------------------ + +In the free-threaded build, Python objects contain a 1-byte field +``ob_gc_bits`` that is used to track garbage collection related state. The +field exists in all objects, including ones that do not support cyclic +garbage collection. The field is used to identify objects that are tracked +by the collector, ensure that finalizers are called only once per object, +and, during garbage collection, differentiate reachable vs. unreachable objects. + +``` + object -----> +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ \ + | ob_tid | | + +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | + | pad | ob_mutex | ob_gc_bits | ob_ref_local | | + +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PyObject_HEAD + | ob_ref_shared | | + +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | + | *ob_type | | + +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / + | ... | +``` + +Note that not all fields are to scale. ``pad`` is two bytes, ``ob_mutex`` and +``ob_gc_bits`` are each one byte, and ``ob_ref_local`` is four bytes. The +other fields, ``ob_tid``, ``ob_ref_shared``, and ``ob_type``, are all +pointer-sized (that is, eight bytes on a 64-bit platform). + + +The garbage collector also temporarily repurposes the ``ob_tid`` (thread ID) +and ``ob_ref_local`` (local reference count) fields for other purposes during +collections. + + +C APIs +------ + +Specific APIs are offered to allocate, deallocate, initialize, track, and untrack +objects with GC support. These APIs can be found in the +[Garbage Collector C API documentation](https://docs.python.org/3/c-api/gcsupport.html). + +Apart from this object structure, the type object for objects supporting garbage +collection must include the ``Py_TPFLAGS_HAVE_GC`` in its ``tp_flags`` slot and +provide an implementation of the ``tp_traverse`` handler. Unless it can be proven +that the objects cannot form reference cycles with only objects of its type or unless +the type is immutable, a ``tp_clear`` implementation must also be provided. + + +Identifying reference cycles +============================ + +The algorithm that CPython uses to detect those reference cycles is +implemented in the ``gc`` module. The garbage collector **only focuses** +on cleaning container objects (that is, objects that can contain a reference +to one or more objects). These can be arrays, dictionaries, lists, custom +class instances, classes in extension modules, etc. One could think that +cycles are uncommon but the truth is that many internal references needed by +the interpreter create cycles everywhere. Some notable examples: + +- Exceptions contain traceback objects that contain a list of frames that + contain the exception itself. +- Module-level functions reference the module's dict (which is needed to resolve globals), + which in turn contains entries for the module-level functions. +- Instances have references to their class which itself references its module, and the module + contains references to everything that is inside (and maybe other modules) + and this can lead back to the original instance. +- When representing data structures like graphs, it is very typical for them to + have internal links to themselves. + +To correctly dispose of these objects once they become unreachable, they need +to be identified first. To understand how the algorithm works, let’s take +the case of a circular linked list which has one link referenced by a +variable ``A``, and one self-referencing object which is completely +unreachable: + +```pycon + >>> import gc + + >>> class Link: + ... def __init__(self, next_link=None): + ... self.next_link = next_link + + >>> link_3 = Link() + >>> link_2 = Link(link_3) + >>> link_1 = Link(link_2) + >>> link_3.next_link = link_1 + >>> A = link_1 + >>> del link_1, link_2, link_3 + + >>> link_4 = Link() + >>> link_4.next_link = link_4 + >>> del link_4 + + # Collect the unreachable Link object (and its .__dict__ dict). + >>> gc.collect() + 2 +``` + +The GC starts with a set of candidate objects it wants to scan. In the +default build, these "objects to scan" might be all container objects or a +smaller subset (or "generation"). In the free-threaded build, the collector +always scans all container objects. + +The objective is to identify all the unreachable objects. The collector does +this by identifying reachable objects; the remaining objects must be +unreachable. The first step is to identify all of the "to scan" objects that +are **directly** reachable from outside the set of candidate objects. These +objects have a refcount larger than the number of incoming references from +within the candidate set. + +Every object that supports garbage collection will have an extra reference +count field initialized to the reference count (``gc_ref`` in the figures) +of that object when the algorithm starts. This is because the algorithm needs +to modify the reference count to do the computations and in this way the +interpreter will not modify the real reference count field. + +![gc-image1](images/python-cyclic-gc-1-new-page.png) + +The GC then iterates over all containers in the first list and decrements by one the +`gc_ref` field of any other object that container is referencing. Doing +this makes use of the ``tp_traverse`` slot in the container class (implemented +using the C API or inherited by a superclass) to know what objects are referenced by +each container. After all the objects have been scanned, only the objects that have +references from outside the “objects to scan” list will have ``gc_ref > 0``. + +![gc-image2](images/python-cyclic-gc-2-new-page.png) + +Notice that having ``gc_ref == 0`` does not imply that the object is unreachable. +This is because another object that is reachable from the outside (``gc_ref > 0``) +can still have references to it. For instance, the ``link_2`` object in our example +ended having ``gc_ref == 0`` but is referenced still by the ``link_1`` object that +is reachable from the outside. To obtain the set of objects that are really +unreachable, the garbage collector re-scans the container objects using the +``tp_traverse`` slot; this time with a different traverse function that marks objects with +``gc_ref == 0`` as "tentatively unreachable" and then moves them to the +tentatively unreachable list. The following image depicts the state of the lists in a +moment when the GC processed the ``link_3`` and ``link_4`` objects but has not +processed ``link_1`` and ``link_2`` yet. + +![gc-image3](images/python-cyclic-gc-3-new-page.png) + +Then the GC scans the next ``link_1`` object. Because it has ``gc_ref == 1``, +the gc does not do anything special because it knows it has to be reachable (and is +already in what will become the reachable list): + +![gc-image4](images/python-cyclic-gc-4-new-page.png) + +When the GC encounters an object which is reachable (``gc_ref > 0``), it traverses +its references using the ``tp_traverse`` slot to find all the objects that are +reachable from it, moving them to the end of the list of reachable objects (where +they started originally) and setting its ``gc_ref`` field to 1. This is what happens +to ``link_2`` and ``link_3`` below as they are reachable from ``link_1``. From the +state in the previous image and after examining the objects referred to by ``link_1`` +the GC knows that ``link_3`` is reachable after all, so it is moved back to the +original list and its ``gc_ref`` field is set to 1 so that if the GC visits it again, +it will know that it's reachable. To avoid visiting an object twice, the GC marks all +objects that have already been visited once (by unsetting the ``PREV_MASK_COLLECTING`` +flag) so that if an object that has already been processed is referenced by some other +object, the GC does not process it twice. + +![gc-image5](images/python-cyclic-gc-5-new-page.png) + +Notice that an object that was marked as "tentatively unreachable" and was later +moved back to the reachable list will be visited again by the garbage collector +as now all the references that that object has need to be processed as well. This +process is really a breadth first search over the object graph. Once all the objects +are scanned, the GC knows that all container objects in the tentatively unreachable +list are really unreachable and can thus be garbage collected. + +Pragmatically, it's important to note that no recursion is required by any of this, +and neither does it in any other way require additional memory proportional to the +number of objects, number of pointers, or the lengths of pointer chains. Apart from +``O(1)`` storage for internal C needs, the objects themselves contain all the storage +the GC algorithms require. + +Why moving unreachable objects is better +---------------------------------------- + +It sounds logical to move the unreachable objects under the premise that most objects +are usually reachable, until you think about it: the reason it pays isn't actually +obvious. + +Suppose we create objects A, B, C in that order. They appear in the young generation +in the same order. If B points to A, and C to B, and C is reachable from outside, +then the adjusted refcounts after the first step of the algorithm runs will be 0, 0, +and 1 respectively because the only reachable object from the outside is C. + +When the next step of the algorithm finds A, A is moved to the unreachable list. The +same for B when it's first encountered. Then C is traversed, B is moved *back* to +the reachable list. B is eventually traversed, and then A is moved back to the reachable +list. + +So instead of not moving at all, the reachable objects B and A are each moved twice. +Why is this a win? A straightforward algorithm to move the reachable objects instead +would move A, B, and C once each. The key is that this dance leaves the objects in +order C, B, A - it's reversed from the original order. On all *subsequent* scans, +none of them will move. Since most objects aren't in cycles, this can save an +unbounded number of moves across an unbounded number of later collections. The only +time the cost can be higher is the first time the chain is scanned. + +Destroying unreachable objects +============================== + +Once the GC knows the list of unreachable objects, a very delicate process starts +with the objective of completely destroying these objects. Roughly, the process +follows these steps in order: + +1. Handle and clear weak references (if any). Weak references to unreachable objects + are set to ``None``. If the weak reference has an associated callback, the callback + is enqueued to be called once the clearing of weak references is finished. We only + invoke callbacks for weak references that are themselves reachable. If both the weak + reference and the pointed-to object are unreachable we do not execute the callback. + This is partly for historical reasons: the callback could resurrect an unreachable + object and support for weak references predates support for object resurrection. + Ignoring the weak reference's callback is fine because both the object and the weakref + are going away, so it's legitimate to say the weak reference is going away first. +2. If an object has legacy finalizers (``tp_del`` slot) move it to the + ``gc.garbage`` list. +3. Call the finalizers (``tp_finalize`` slot) and mark the objects as already + finalized to avoid calling finalizers twice if the objects are resurrected or + if other finalizers have removed the object first. +4. Deal with resurrected objects. If some objects have been resurrected, the GC + finds the new subset of objects that are still unreachable by running the cycle + detection algorithm again and continues with them. +5. Call the ``tp_clear`` slot of every object so all internal links are broken and + the reference counts fall to 0, triggering the destruction of all unreachable + objects. + +Optimization: generations +========================= + +In order to limit the time each garbage collection takes, the GC +implementation for the default build uses a popular optimization: +generations. The main idea behind this concept is the assumption that most +objects have a very short lifespan and can thus be collected soon after their +creation. This has proven to be very close to the reality of many Python +programs as many temporary objects are created and destroyed very quickly. + +To take advantage of this fact, all container objects are segregated into +three spaces/generations. Every new +object starts in the first generation (generation 0). The previous algorithm is +executed only over the objects of a particular generation and if an object +survives a collection of its generation it will be moved to the next one +(generation 1), where it will be surveyed for collection less often. If +the same object survives another GC round in this new generation (generation 1) +it will be moved to the last generation (generation 2) where it will be +surveyed the least often. + +The GC implementation for the free-threaded build does not use multiple +generations. Every collection operates on the entire heap. + +In order to decide when to run, the collector keeps track of the number of object +allocations and deallocations since the last collection. When the number of +allocations minus the number of deallocations exceeds ``threshold_0``, +collection starts. Initially only generation 0 is examined. If generation 0 has +been examined more than ``threshold_1`` times since generation 1 has been +examined, then generation 1 is examined as well. With generation 2, +things are a bit more complicated; see +[Collecting the oldest generation](#Collecting-the-oldest-generation) for +more information. These thresholds can be examined using the +[`gc.get_threshold()`](https://docs.python.org/3/library/gc.html#gc.get_threshold) +function: + +```pycon + >>> import gc + >>> gc.get_threshold() + (700, 10, 10) +``` + +The content of these generations can be examined using the +``gc.get_objects(generation=NUM)`` function and collections can be triggered +specifically in a generation by calling ``gc.collect(generation=NUM)``. + +```pycon + >>> import gc + >>> class MyObj: + ... pass + ... + + # Move everything to the last generation so it's easier to inspect + # the younger generations. + + >>> gc.collect() + 0 + + # Create a reference cycle. + + >>> x = MyObj() + >>> x.self = x + + # Initially the object is in the youngest generation. + + >>> gc.get_objects(generation=0) + [..., <__main__.MyObj object at 0x7fbcc12a3400>, ...] + + # After a collection of the youngest generation the object + # moves to the next generation. + + >>> gc.collect(generation=0) + 0 + >>> gc.get_objects(generation=0) + [] + >>> gc.get_objects(generation=1) + [..., <__main__.MyObj object at 0x7fbcc12a3400>, ...] +``` + +Collecting the oldest generation +-------------------------------- + +In addition to the various configurable thresholds, the GC only triggers a full +collection of the oldest generation if the ratio ``long_lived_pending / long_lived_total`` +is above a given value (hardwired to 25%). The reason is that, while "non-full" +collections (that is, collections of the young and middle generations) will always +examine roughly the same number of objects (determined by the aforementioned +thresholds) the cost of a full collection is proportional to the total +number of long-lived objects, which is virtually unbounded. Indeed, it has +been remarked that doing a full collection every of object +creations entails a dramatic performance degradation in workloads which consist +of creating and storing lots of long-lived objects (for example, building a large list +of GC-tracked objects would show quadratic performance, instead of linear as +expected). Using the above ratio, instead, yields amortized linear performance +in the total number of objects (the effect of which can be summarized thusly: +"each full garbage collection is more and more costly as the number of objects +grows, but we do fewer and fewer of them"). + +Optimization: reusing fields to save memory +=========================================== + +In order to save memory, the two linked list pointers in every object with GC +support are reused for several purposes. This is a common optimization known +as "fat pointers" or "tagged pointers": pointers that carry additional data, +"folded" into the pointer, meaning stored inline in the data representing the +address, taking advantage of certain properties of memory addressing. This is +possible as most architectures align certain types of data +to the size of the data, often a word or multiple thereof. This discrepancy +leaves a few of the least significant bits of the pointer unused, which can be +used for tags or to keep other information – most often as a bit field (each +bit a separate tag) – as long as code that uses the pointer masks out these +bits before accessing memory. For example, on a 32-bit architecture (for both +addresses and word size), a word is 32 bits = 4 bytes, so word-aligned +addresses are always a multiple of 4, hence end in ``00``, leaving the last 2 bits +available; while on a 64-bit architecture, a word is 64 bits = 8 bytes, so +word-aligned addresses end in ``000``, leaving the last 3 bits available. + +The CPython GC makes use of two fat pointers that correspond to the extra fields +of ``PyGC_Head`` discussed in the `Memory layout and object structure`_ section: + +> [!WARNING] +> Because the presence of extra information, "tagged" or "fat" pointers cannot be +> dereferenced directly and the extra information must be stripped off before +> obtaining the real memory address. Special care needs to be taken with +> functions that directly manipulate the linked lists, as these functions +> normally assume the pointers inside the lists are in a consistent state. + + +- The ``_gc_prev`` field is normally used as the "previous" pointer to maintain the + doubly linked list but its lowest two bits are used to keep the flags + ``PREV_MASK_COLLECTING`` and ``_PyGC_PREV_MASK_FINALIZED``. Between collections, + the only flag that can be present is ``_PyGC_PREV_MASK_FINALIZED`` that indicates + if an object has been already finalized. During collections ``_gc_prev`` is + temporarily used for storing a copy of the reference count (``gc_ref``), in + addition to two flags, and the GC linked list becomes a singly linked list until + ``_gc_prev`` is restored. + +- The ``_gc_next`` field is used as the "next" pointer to maintain the doubly linked + list but during collection its lowest bit is used to keep the + ``NEXT_MASK_UNREACHABLE`` flag that indicates if an object is tentatively + unreachable during the cycle detection algorithm. This is a drawback to using only + doubly linked lists to implement partitions: while most needed operations are + constant-time, there is no efficient way to determine which partition an object is + currently in. Instead, when that's needed, ad hoc tricks (like the + ``NEXT_MASK_UNREACHABLE`` flag) are employed. + +Optimization: delay tracking containers +======================================= + +Certain types of containers cannot participate in a reference cycle, and so do +not need to be tracked by the garbage collector. Untracking these objects +reduces the cost of garbage collection. However, determining which objects may +be untracked is not free, and the costs must be weighed against the benefits +for garbage collection. There are two possible strategies for when to untrack +a container: + +1. When the container is created. +2. When the container is examined by the garbage collector. + +As a general rule, instances of atomic types aren't tracked and instances of +non-atomic types (containers, user-defined objects...) are. However, some +type-specific optimizations can be present in order to suppress the garbage +collector footprint of simple instances. Some examples of native types that +benefit from delayed tracking: + +- Tuples containing only immutable objects (integers, strings etc, + and recursively, tuples of immutable objects) do not need to be tracked. The + interpreter creates a large number of tuples, many of which will not survive + until garbage collection. It is therefore not worthwhile to untrack eligible + tuples at creation time. Instead, all tuples except the empty tuple are tracked + when created. During garbage collection it is determined whether any surviving + tuples can be untracked. A tuple can be untracked if all of its contents are + already not tracked. Tuples are examined for untracking in all garbage collection + cycles. It may take more than one cycle to untrack a tuple. + +- Dictionaries containing only immutable objects also do not need to be tracked. + Dictionaries are untracked when created. If a tracked item is inserted into a + dictionary (either as a key or value), the dictionary becomes tracked. During a + full garbage collection (all generations), the collector will untrack any dictionaries + whose contents are not tracked. + +The garbage collector module provides the Python function ``is_tracked(obj)``, which returns +the current tracking status of the object. Subsequent garbage collections may change the +tracking status of the object. + +```pycon + >>> gc.is_tracked(0) + False + >>> gc.is_tracked("a") + False + >>> gc.is_tracked([]) + True + >>> gc.is_tracked({}) + False + >>> gc.is_tracked({"a": 1}) + False + >>> gc.is_tracked({"a": []}) + True +``` + +Differences between GC implementations +====================================== + +This section summarizes the differences between the GC implementation in the +default build and the implementation in the free-threaded build. + +The default build implementation makes extensive use of the ``PyGC_Head`` data +structure, while the free-threaded build implementation does not use that +data structure. + +- The default build implementation stores all tracked objects in a doubly + linked list using ``PyGC_Head``. The free-threaded build implementation + instead relies on the embedded mimalloc memory allocator to scan the heap + for tracked objects. +- The default build implementation uses ``PyGC_Head`` for the unreachable + object list. The free-threaded build implementation repurposes the + ``ob_tid`` field to store a unreachable objects linked list. +- The default build implementation stores flags in the ``_gc_prev`` field of + ``PyGC_Head``. The free-threaded build implementation stores these flags + in ``ob_gc_bits``. + + +The default build implementation relies on the +[global interpreter lock](https://docs.python.org/3/glossary.html#term-global-interpreter-lock) +for thread safety. The free-threaded build implementation has two "stop the +world" pauses, in which all other executing threads are temporarily paused so +that the GC can safely access reference counts and object attributes. + +The default build implementation is a generational collector. The +free-threaded build is non-generational; each collection scans the entire +heap. + +- Keeping track of object generations is simple and inexpensive in the default + build. The free-threaded build relies on mimalloc for finding tracked + objects; identifying "young" objects without scanning the entire heap would + be more difficult. + + +> [!NOTE] +> **Document history** +> +> Pablo Galindo Salgado - Original author +> +> Irit Katriel - Convert to Markdown diff --git a/InternalDocs/images/python-cyclic-gc-1-new-page.png b/InternalDocs/images/python-cyclic-gc-1-new-page.png new file mode 100644 index 0000000000000000000000000000000000000000..2ddac50f4b5575888d8d19cd9b6f2e3863132776 GIT binary patch literal 4415 zcmZ`-cUV)~vfn9?Pz*(Sks?SF4DHY{v_R-ZsUjdq5iyj2R83TRQ>ubMBya=-k*@S2 z3Mdj0L~1}mA_z$D@Zve|-FwgdzW2whS$p=LHM3{dH*0Xq9R2J5_h(<=`5s@q#(=Bn-Jf z-S2tM!qOTyM=GQ_F{MtvGeD=0kzPv=j*Bz!5MIOG|JTF)DzhYW(esjJ z8f05Ovk=8t?*$Q51LL3qw;pW~)XD##-`3zt|49Z~^5l;x(40MO)Z%!tAv7mko!A0n zmG#6YS#c$AIH392w1k_$~Q!)rSP0RDWQ!sH=4h`Nb>*26BS5k7PBYnJF~ zbT4h4YeC+M?a%Iny|4wBj~)hRJUqkjTZ&4xuGN!2BhK(*%O4{t+91coptKo@;$BTd z8tby(2ExM#R#22;W_ASN3no4_?B;Et>+u|1uR`eH#BUM!{+2a9O!2SDGaL z+x{Le<&h{En)7esAe?j22{GF+P z8UCG4tAF_PcUmjyag17G>?K%Ygo#Mdu;kiXRH~!owO1KUka-VjL$^T~iu-|^u@FXV z*t)x+@Ra1!*_1hMv}rjUt#m~jP)}G?nl@feRtmFl^L;= z$w$i9gtOE2uM7y16@5beh=!|xal#WO^1>CK3c3wRQPDQmnCt>Q7sNH$b#l;) zb)+(&o){N*nz=H6uIKq_vQ?(XgJ1~pri#cb=ka%tsO0yaD6c9ES|SKSB*m4xoHb>m z$_9BqP2~1b(B(d}1jpSZTH$@p%HrR&7YP!UPvAn@1#CgiS#>w|7F~|cuC?9XU99#x z$Ghr;dli0#a>^~k9QBm<6${xGj~lH05#tcZbhGmK?PS*qcRgf-H#pL+UL?|%V(#{G z2t*ZTug-}8@;so^DG_%kkv4?~h09NmYa(`53@k#7>4#RGi|03&*kkMp#~^v#%ugi8 zVN|f|WyD79+FkpDyJhG7UTz1r=5@BeD6gcRA-165an3iQxUae=c-m{u@q88<9TY1d zVULl6)!4o>M8jSY;fHcTREPMUfU3z8isR+49X@S`b$x;2*nBH&sw~D3yFabBtx!&T z+E|`(IYttvd@BxUOacm%qfsZRSw2l^cFZ~a`1)#@SN?VQEc|w^)J*8LlYu5Lv^VlP zD=zu+Q#4av36X_j0`^}w(C@vtH|w!vEkl%u@A=ABGz3vElJN@3$n|>t$FF`S#v{ia z(KvSA2ym1#Gm*+KapVLNWJVh6T%OAQw)M!2x74+-Nzuug{(c4)v7ziD;r_=Ur9o2p zZ93zl?Pq4T;F-FG znp{`A*bDVz|?V`}Lei!y3+2TSH}ph&!A zqox-2Aik@nulVg@6stEGr=~R$?}brw=3a8WNqbPFO#abgyQu-3IQMDXl5LMrx2?>w z)?K8J3+ExnBJ%-ipr2LO2uOYI@cit($04`Xa2K(v*0-i}Pt7t3V{@BE7$I|S@&<2& zd3&{qlKEddrbr;%za?J$9saHoq;8Wr-4UulLT9nhTbY z9SN)Jx0p)gW9q~zR1dP;uG321FcX!EgNsl#2wYVGTmi;w*G;8S@_jPOULQ%ByN90T zt9Rem1pENF0O;*+?-P1v^bW21RVGh8NssFpsG8X7E>Aj{EEzI%ZF}l-r}W7r-L!yw z%9fH7%f{C(EZ-YX;q zyHp$UHq+e_sIbgZM)L_y^y8AW%r(cWs&mP= zVDI9!p>wm5%dMV>s5WdZ`n@cLWuBbf>QJh4_KdtaFUl7?q=9jqn8{tN$VwNCSn8Ln zltHvz0N@b_Ua7XLt zzuuy7V$k}qZN^HneP)UTI&xm_ht zoVnB^x#18saQk(B+R-HN+#ek^h&34t(t)<>88N$x}nsZE#MGvQXeL9`VO$Vv~|fgxZUxG(+O(b+i^Jc6irFph_OD& zd5tV7qf*%xa&Q@f(S5)cdK_qf5sA_H*fm-&^kEp}TZ~mE+U?bY8x46b;`4`*QnFEw zgo?@Lqp?+|#0Ke!Pi@Ot(`BCypCHD?uhaYHVYUA6^WbU$H4*;p$GIae8b=*K&ArG* zzuLN{vNw|*EfNDmmePc}z6MdUOq3I7@^q51Pg9KnWuP|fuI`fmx^2fv>X|_XHTKLlue~_{KBZ$4PXp$#_#s+x*UPa zwMM%4Ar|Wf!v}}16|3E($eVS;^&qlVXGwajZC^~edaw{D+i3G!azPsw71~7cTNguU-QSiIGhDAhI#41P8wN=Z;8Jr4N3QG@%5e zw&Ao_myO|hIm%$EP}6Zdnq#vbKKmlFw;r|_9Vx^~+XpqF^JuLQ&{(2<$>%zO6NMT{P!G%_z@~aqz z3x2?YHLXaGd`21UD+LSO~EC;)9T#smRQaXX?+8EXbl_n_`chHawo* zh`N#(Wmj6bLNPy8zn9OV?$`Otm}3mGgnKGwXcTtr>t8!<{yDh&!1A~;V(01A0b6ZS z%8L5%dPPL@JPl8E6>p&odBe@s0;PdMm+Q7y>9pQ#l!xNmCyxQ$zj_0}aj;22_vQ!)t#z_Gs7bqTm{2b&`T*6Y zNj@A55xJ+s;$|r~0#kRv9SD;v;Tw^yLI!$7$|sdlZE_QTej6*58y4Ocn~ZSoGh93r zxI~>_MtOq!+0=_w1qQU8o=a`$(Hi2Z%9yCq*MfwjS@FiVqN7E$2FY>(vb2pl79&H$ zRp^$04WfI8rg1q-ZEN*_5aE^^G0%quH=3@ggc+|Z|0+&)VWzSdcZrU^T+!6V+<@Y4 ziRaf)y;OshyGpX>?w`s_cZ6uQ+R7Tf9P4S>FMY;~rXy}EUzBnDu7vDU$vR2C;%eK literal 0 HcmV?d00001 diff --git a/InternalDocs/images/python-cyclic-gc-2-new-page.png b/InternalDocs/images/python-cyclic-gc-2-new-page.png new file mode 100644 index 0000000000000000000000000000000000000000..159aeeb05024a3247381e1c3aec2b986035b5e44 GIT binary patch literal 4337 zcmai2c|26z|GzV1UlU^N*_SX`LzplkQPwOGiO9~_w~?}rl$3;wY$aRPjEpP|m2?rJ zmR-!@|}8q%k%v4d;R`+pL1U4-uLI6d*1h+^LgL&^H!%h*@V~t0N^w?GqC{x zC`fM)v(O8`)bGhCG@A?yWf?=9IGv3e#VmmljFh{G#RiPKn)u5jej&5;;o z8)=E~t&T2Aeq=+&9f}n5;8Aw~cqzZYcC67;rB*^zaJuDiizk4>< zkypd{HI5{l{iu!+E4ww&`yu@rH~L6v^a0C;#QkF4Q8Ax;&#ka-P(%4D9neZqraj+Q zW0Mc($GG5_SwfG4WBmty56JNFpLpyhNPcn$X?uy;M@}@U!ax)}3Z!MI`Sv4OtRaBY zOKGTOycVtl^4GCKM=8d^Gzh@KG{)<**a#`QVs!s_I|OBVLg&h$_bYccI@^USK;QI@ zd{wgimy)Z7W=4co$(u;qI_4%JwEkb%D*3{KgJxcywn!H<+|zNG?mKzNDcLe!&^$%3 zbh=Gh8vM8f$r==tNaG%SfCeTlAm_1i;K!>l-8AMisw(HkL@@@pmpSR<2!nOo1qx70 z+&{qM^LrWpi3}vK&;R20O0#ItLBWci>v~K$1fHzCy<>yikak+MfMlIAIU;)cV0?G3 zGt+ILk?>Rwl2sis&_T?*$^N%$e`5WP_upD2$%1@;@LN!8 zhKD=e$kgd(u-nvjv3b;Ra-v<;yJVMx>~rI>Lw_%G@U(d2njA8A!S?RSB!#}b^UJRd zf3|QVVi~X-D9gN{&PI`YNZWBW@4cPOY(y*vc0X#E$`9_Wh1x+aUHzim88=Qp&}Sl2 zsHhN5G=1r+%8V%x+}yN#n$&;ILl*qE)_-*8CC@|kpH^L?Gx7j@@#hD*bnzkNP^t5D zrKjPOR`iJ*Ay4PAXxQ_Ut*4u9$6?M@-@vJmd`QUlH1gbR(e^NlHgt+iK;Qd}fq z9}=u|!6ri)!vvINzVwvCZEWfy7Gt4Pk&OLTA3l^+Go!@{!%P(iz`jB$p43%N^n>FA z0p31Wb)V-AtuRsw!*(S&Ng`x_Ql6gTSc&IhlM67i&OF(?C$cV7;%f>r`!>`?>f3`b zE-`KkT+nSNPeVD1J{?tNo-}`|-Vmup+Y2PrbjxRUe|lgn>{p|& zdgvus6?CDdb7E-AtLGC7dU%jaxk}`<9G_<3Bq#X+4=JZXq#$YYTihij><63F6`3xJ z$Tq`YvN%)-K0-hC2ieB5KHLA+_WO=OL*#H1yA+gUvcE|XQvEl7bHk2Wz#AGf$lz~X(ebpht!FA-G%PP zXCf`aP1-Z;K-S5tVb&c{S?^!z?r^DH3@9BTY72*W&Of>rD$?Vqb~mnE7Y)PlTw%bi zYKc7K80#80cq7o(N}R8R#B*s{t`>R>~q{WFM91BD}6(_0CSe9 zQY!U@qJi_r==;?s#;T%t05$IUI=AQ6aY}5Nh}UrV=LFXuK^yXp+}rmnx81a-S7GP^ zgqDL&sL4v)-3HgiExZE9?8+_wlW>7ZSBVJAxI4AK6qI({mfPW2I{^UCn0ytq6HI#AuHG>9V2f&L`;r@dQn?sE zpXpv^A)kEDU{Gp7q)<4^IxS7F0U_gRF`V(P4o>vO$t`@Yc03h4TiEXWv7X6ih_9Tz zNcx2_Z*qZde$IB;;dAb7=3durk>_Yxo#eXRr95HM+4cDuvH3cO}C9oW9>YXC# zlHO`24BX0H2FbT_+41q4NYjWFUs~9}tGafYN`A@wh(-!}Tp$?|dMwaQZp}0&KVGF; z3=%W*?E9dEd9opOC^T^YgH!u}UOn+yO>zQTQ`)Z1ewa4t zH8Qh5D5h^~+n5hSUT9A+#N}N~7)8{##WyVpm5XqHNg}`|#ShO!oArG8xT1_1{Gj@R z^S<`TX3)N)9&H+kNnTw`tYOZ$Avry@O!p@?O64_ie#YxpdJV)(Thh8M9!N{R zV_33YhC8ZART#JVcFW?#DN`Jja#h*%^1CNLVI^cNkU8o(DWTW)oln~w2zkV{G)zU{ zGI^CMUdn`Be*O5wLN7nZuu~+|;@oJ;zH8+=vqE3z9;L1*ExpI9}&va*iwfp#1wAGRCS@cn6sruI%E+egyACipOqeFPO&jPVT)Wk{Our zU-~AT_fmgT~-chP>VgCCMMsy~E3Yp9#qXJ&cnyM4) z{yYkENC_`0h-jr^dW6WBX!boNI_7+{L%2Y_1I<|{(OQpmAjne|-gqqm^6U zN8qP3HeHJOOy?Wr-}?Lr*5R4&a=e5Kb*4si>|Zvf`DdwKUr>Mamy2DX!O(n_59y}a1%DtW@5GEg!`_iv3d{*&|RO_WoiAM3A(Rjn~R#&T3 zed;2t2z3-A%Bqo6%hdERe9PCxn>>9);S?MF+!)1J5zifewCZ~?M9-Cn2TnhJ&>e96 z!l3!x6s#t4UKdu-JG=$MDc!td$mLlqqB~f{g+6n_v8dR7`}xH7t8(Q+1!#OC8@d@` zN8GW$1sfhsidbpt@@fUE)3({}qCz9RGgiOHGNQ{74FU?INh&SYZ$q?>Tvu|<;(?4EBJIyTKq;GWM4jJ}#1Lo-yg*&Xha^Jsk} zfsRiqQ4;lF4=ibuB)zj+%?0wke>0yp1?z@-=j{YB|EVMiN3Y*Bg^;*{#~M zkQBDPRjUD;q{3O09OCPSf&|_LvQQ!!V;Y8a=AAXYx&-IKfH|-mX}qZyd0^_T7)r7z8UaBAyYKJ-@ss0Wt`kSe~+jlY17oB%%{>_Vx!- z2O~jt-yO#?+W6k?vUw~6=#1mU6U`?)Wki`RiF-+pI=u+?qk&FJ-kT+#)vlvO?V^e}-zAd-rILnC+_S|gFq8e+tJ&n|HZU>X)^NSG6c*b}kTvC~@ zxOxV%6AHHH(_PfR%<8}W?B?wXx`o+gAnO&SGd#rK@4Wc2$xPgXD(E>AAhq$V=vbBl z!$W6vO@sO?e@P99c~-}|P=Yt9r)(WWo1%pV$T7c literal 0 HcmV?d00001 diff --git a/InternalDocs/images/python-cyclic-gc-3-new-page.png b/InternalDocs/images/python-cyclic-gc-3-new-page.png new file mode 100644 index 0000000000000000000000000000000000000000..29fab0498e5b106f813e08aa2799602269cd74d1 GIT binary patch literal 4876 zcma)AcT`i$w?1hgARUw{9f{J5KxmO50qIqw$(14qh(JsbDTxXJq)U?;L_n&b6afQr z0YPa&q)JgiiPEkRq)6li@9)05)_d!%_5L{Lo3-cLduH~WS!ebaZ*7TYXBA=v0D#@p z#K;x^z!XON?GeTcF!q0ZnE@=I1^lB3#Xj=55SyDZAlKN{sm-} zJ!`}HQU+LYVz}2x);DtOQ-JVC`l|Pn?_Z53u?fOgU7U=cA}lNEgk!9c(^U93WCfNv zx5BQ@1(V>Y2c^0vdAZ%QVT=KDCOE<=jBo@;lEdFo`Ft5eAy5C)cWR6mQXmbdR6c>I z-?t+no<$G6!9ftS7>WN=Nm21(6Aj*m6v zG2hDuqamMe-%5tDQD8b8dg`&H6ie9asgw+x+5!_BlEW}_gTQl;hm;}s%kGopIO?=# zF@vj5VuK~bsY{3vhSbY47T^5G_%RVAx!d<@5$0>fkJNDgJ$jn1HS;Ici|%-LlOM*v zEyFvn|JUOFULzy9Bz|8;a*bH>u~!>IB84v;#f9V zNQ%3rHTl<*-On9WbJe)WsuNK4gh_|ykptC^{lKxjz{d#lN+Lk+sa14+%!tlN>;K5^ z;nw{-kAJpx{wVd-3!z6;5{PvYSHck}5l`TR43srigzkDc_A5_*TL^<{I$?Oy`Zcr&|kzYj#A( zNYIw8U}&K&?%gcy@XecV)vS0>1ox_js6DRptTcsb*YtCYN%1pw{{I8*!c-w9pD#8H zZU>Z-R?SFdv?z&q7R3SEV*}~cgJ(h1l|Fvh9te3{#}ZyTGq=8WUF4$}kqR zh=Ll1VI$~A(QqJyoiUcrzmk6tg{p#$F+T=e;)eff_YqI;$IA7vaTK85e-adGoA);q^dHQ|Y~0^jk8QZk|`$x&Eo zg;gSU-CnNQsgP?f5(*4XyO^(+IBw&Xcy7A_MJ7DIdKyk?0|t-Q%|5NSb#zpu(|q_f?BK_{umQ}r1r-xiD$by9ao*7+s?1p9L5{XI8wJk zOP(zk%r;AGf==55*XTzT$mwePpJkTOQ{)@5P5DQ5y|{`->u+f+*v5}!q3h&TMwvR) z#`HxMv#+ExIQ+g6XmjBv53%vig52PWZr^_5pYpnQpZ2V$+m6n zVCrIA-#H9c9(XxjfJ(N?m5|j3Q5;kKz};tlv_Y8IiUW3%?&;xw`Qm+gzfr9qDh>CaRVzuCj?JGXjg)+ zQE?gCedj;DHk)Rr-kD7^PHS7ypFq%v9LG>1A_k`xwbVTaGqyDF#*gqQg6tG0wWpT+ zel1cbrUHwVf8&v)#0lA>Br37dME9IqL>|Ls{4`P9%O7~vQG}={QV$pR)I;PtJBA~j zpZW!vC-MAxE3_854r-8*yxQFQ2&ps*&GfRa29wn&ycWo(X9?GIQKP{5&oGgnJ@^y4 zfKe4vlPQ-aqLp6E@S^4Sd=w6doG@+5q*qq3P&6lNZdHdEAzfcWL~a#^%`;I82YoME zX3xmYT)qM4xwLv6F}vjzGAK86+o;QH(wGcze#ZR*&VYTW=WT*Wm z*`k=Y-13EYW$S>D{f(Xbmts4jb{EmPzg#2eKRaBe^qBW}+bptH$M1^7Q;9|67%twV z5o>ni4J10fubgm7uK300>Hwy2a?wxq5<$w>RFv8r0tG37sK%6b@p`|r?*^0?xT}w* z;;kl4%3QyW%{(_ifuaI^a7BXQai3Hu7&+#ha}&*Jomd6uAW0LzX0b@ag32gf+Aam`T{eZkZZ zK_R7gh{t&V>E8K0Eb__s&?27(*UwH{{b4M=9ne2RtrqhA*A#%ICCvzqEX~o~lb0N& z+KK?Wbn9eiS9A^YsU9PixDNma6xU-ec^`^z&VVz1^x1-{li%RKU4eP8-H z?~rbODeZoA-Qx3U<%mA}cCL{9eyf83uM6Xofn2BymRjV*ueN>PyL$aatIe}?pK4?o zzf4=e*-43IAK!@}r#^AioBgn)I2a~GT4J7-w1a)(;hs<)jFtydQ5LtQH}m|@6USm( zILul(Xelj*Gf$FM$~3Spx_q|AD)tuudikP;sL_K_$x+ueY(gBj%8;8PTrBJOr<*at z?ao`6dqua@OZ@6zZCoq^gth$5}!nij!AJ@`(Hq0S#r z$Ic#l9XD9Vm}D7hpWdi_ZEAr}*5XqOgZH*agrrwoPWOhjs!-+81RK(eso{s4_GS;#ngx?sTjvB1d}_M zpnJf?>gBqgi&55BzMTCQg&ba9X?C;}LVGB(_DAhT`}myjEa>M`**rqpuob*2G}YT` zFRr7I62VF7?@j6x$vQy$_&fj-LvgZY(m2M*JG@{9mVjMx4PznqWshGgr&~jnDNv6``*I|Iul@n~?MxN9aV^=i(&%0_wtzmuYk@qT`;WTj;JF}j&zcd? zy{d`QNi~<9VW)Y;N>SqY=0F90Je5FRPopTok}nzAC8qWW1kJ5FrqtXsP8_5l&wFd@ zg)&nN`3ca)w3PTjbHNxxi_n_w&5^4B?O2=PPO9Q4udl?Bz&2nblw?PO4x8}VvKoEn z3h{dB!p9mU4ifJl2tWWyo%T)y>+`SgN3v-HPAMjWU)>6HdI$Ca(o+BOZaeW$0>Lod zikCVGA{ceIS|Wq$PctDWIeq!WlbUN$9n3-jRez=TF7kYlb9_X~cOa9FJM=`Q#+KZ3J$p-~2#B_2$*`y`1PX&zkmIi}m3f*%3A`Fr@6Ot?Hy51)D z#)zl_X72l|$P}g=6A$pW?|mQgZF2~Thm*~N7tH$29jAK5WvS|GYMrs})ctM?z8fnO zYuRs;e{sAtBmH|Qy$X>Y#7^@7c_o-Y@iq5RD_O}4PJQJWlIIf3fSBy=gI<8VwXruG zfc``^QO@~5g~|&gN5y+DH9EvOoqh|YT3{8((RK$nd>69SlA5)e(gl00a|yLs9Go$Q z8y}a@S+4q4{8_GbUU^FIExhiWw7Wu5BkS=wyKqXNGj>fo5niY}0zxOWP#64j*k@Z% zd6UO^-g&HsA-J!AmoLG z>sl(Gvt8hF!0Y?MW}B&y`<92S&obG&NeIW8G(aJXOjezuXW`(E(Olo_b(d zF$;pZjt-W#q&!IADK;bCeHX~!nMWD64y0`uVwCzK=P|OmuvqxgiwfkE2sshViRpSJxM!2BN33vB1Ghrxmfy7kFsq{_ZVu*~ z*}I?DtL6eOtPrak+Ds=_=W_c0Xc~vltxR?_e*J*X`4MEi?8;$^RIH-6O9VWOyD(8B zK@4DSoq99iE;d#vXn|v8e>TPSEpQ~r=vNz9FZJS(DV%Z(yc*bZ@lB*!#}&!F?`{P5 z%V=2m6_R(m&`s*c?X)<#XgiXDFbvjeKpC?vm30ZQ_h~QbUubCoLb^=80+QJ#Mt5DJsz~qyZn7m+C#ZWkHH&RY`Hg2ikKXapFy2~KYn6zhDBSgSmsi22X& zG1HeqSiPTROyGM{Y`T2Z6N^Ke1@``O^)hY5y;)ZDd{-x!bU|BW%lY7dHT;chvQpWX zWy(2vEi#&gG!j&9&8R)azzutD|JJKxd548NL%2AEs0;sAvkv~Gg1yMbPsd0lh#$wM zbO>MWjj6s{zcO^*e?E7seEpSJ=SO|gLJy~PN5=$4@U30Ty}znFqaPB=e&S;#)XIwD z=^lbK1_hOXduZ1m6yPup(-*PFjO9{;S{?(mC5IWarm}j=>y)|Xr zBRmxB_gC4T?QcQhw_5X$ymF`tRQxRt90EgZAV2>l*7sDPT7U=so}n|zV9q&Vy#By= zBRoUA833p%tEej|YbvNJ+p8)gG?Wo4XHF|CBb1ei4-yVltA8B=gS`BFZvNj6Ke|;L Q7!H8xIZLBjLyz141yIB0(EtDd literal 0 HcmV?d00001 diff --git a/InternalDocs/images/python-cyclic-gc-4-new-page.png b/InternalDocs/images/python-cyclic-gc-4-new-page.png new file mode 100644 index 0000000000000000000000000000000000000000..51a2b1065ea64eaf009a96ce6fecd3132424ea0f GIT binary patch literal 4863 zcma)AXIN8Nw?0WE)W8S|NY{Xl^r8ZRK$LC)DN+R-YA{j_C}1ENg@{5B5k^!X6k+HJ z0Y+jdA{`}y6oCY000}}2NNACA<9Fw4KkoC~ALqRL+2^di)_T|8d+oJTF526`MC3#O z0D#%qS~>v$n9gqx3h`fnHRg9eJ_twHdR*tD?LQvt9*h~k0rop*V+rgL)B9ThK=QPm z82#6q+FnvrGKR}ilyOU0y zY+V+9bjatnv44;l36k}t$h^E*-KqRb^RdToT1q``4)%zjQR5@b*weiPHH>@Y2F`{^8;(ZxEGL1ZeRPC@)!%C-*AK#zFskKZ|H-ou3>c?44}EH&+LWMIAxb5(i}$3dChM z?u`r63*AJGT^zoUyxq_U-b}OlaGjeKUYaILw>LQa;PyuE-~eVFB5Cj|pcSV_hC9{R zrZX|;%nd_<=}yW;yfjjo{*e~b&$5dKBMQ>>c#A`4_{#5~Hbhbm1z|;gfsPkE(Cp=_ zk%1sAGMBPQpRPc8s9I+*h1G#i=+wBs56x%t-%kFgum5!NKYc~<1%B}QzjWli$aH>T z=_`abF1^Toj?c~vu<{jUk%78dBc8c~a^hud4DDfEv(XjQ_CW@946;K;FMHEb+L=q}txm9*+-at9*R-lvs|Z zDHpH4%Qk@THrX_p3Q|K`Wiyuc^EP;cUcKBv zYl`&7?`qmp-_L}Sch=%nQNFutI?RL5YVxx*P>D)qbAkjCm>VU(6tzwRaOtku0sHy! z{xKK+KY#%gOV>#JS+b*s*S`1zqw(V9w%vzOi3R&TMd>iSwxY`c@&?e^fknEfqf{;LTXW)tP| zTBuxr1;d+}9+pp~U+>quWkWXE_t46k#U`xF0WJ`-gq{tLgi05AI5#H1N_{_WKPOGv z695vnvpvMKRZtu-_M(EO#nhV>Bwi=Nv~sq(#DvU|YoY^v+Kr~?mI{`z%PvF3x} zV^$V9tY3NK>V`e}l7l6Js(>bHv;C%}6PkVeDC+c#;?esytg)++)_>&HGAkJIgqU&_ zr=$+l{K@F}3b{Yh@@ukWs}5P1$X2{COfY{af$)mG3r?l;$jSzYV zn2x(ZHa|)CcJTiwVQj{-e!D4#k{>kEABM^$L89KGNhuW<@VjL1!Bi7~ou%BB&>>nu zg;88#@?CTe)e+lu3_!GbrQTY-SPf9r;C^@7j)C0ZWOH<*d!0?TMf}61%YkHbUApHV zRfL4mG@svsfhUU7BJtcbyjgr;-En$pOy;RT2{H|Crzj7?t!Q8SV^_cUF#WorB!Ux( zeE0H#5+eBFF9C4!fKt;_Fz%XR#n(2ko8j4z+>OpzYm_pK(xB@*y>+_ioihqSeETWDiZgv{QiSDCMe+=L>a_6u_$7ps2}+1dF<>5_VTb)u6hXuVi{iu^ z@$wKH+Rc3YtADtNa~PD{);cJU&7gvE?bBOzgt-u&AI4bLUtuwg4ueg$$b-475Tw1p zEo)F5hJ1aw2=G>9y-yYLrpai4xo60wB3ORcA@sq!mbn6~P=a=EaLIcidKRIf$=$cf z9?z6!k?r)|yq>9|@~gk-_$CU`y@1>YTkFMHCInK#bB(i=V6GxN8&<2Jcl`ve48UR_ z8yxF*vg7D^lQ|^`WBq@yo(k#WQXX`KYokM;nWqpQzol1LxDrL5Ae*1}@ zqY5$OEo>=k_I%yWnM}GLr?Nj{QfE%{vcp|0~DGD^%qpU zm(TGTya+dzeXL7Eek0p_WT8R*_&WrJchMD-A>YI5V}@iKf$`&w0bTcu!}7=Z3u5PT zoiPH-kU#zA2=Bn%n}>t2 zb{fGm9K1NuZ$a>!#2)rZapaw2j4r6j$>vwzqKB_;(2DXc*iLaBx9{v16g6KPz~i+8CD(>WRG04|)W1HoEBY9_yaJ=C<~f~q4z|GK6d zk48(2LcGS>(ee6Y`9W=riL73?GbCl|a(?~zn&@~{1~CS*0G3HsV9*C!2f}Y8%k{b@ zBqWe6RC@I9obQ}zW49Y2d-d%~3M|cc9F#r$o&~pYL|)#4QWPbp&bumw7;2*%JBxpU zgy?Dmy!nJ{*RH&dG9j|JUklUKYQ_GvCs%x_*<1eFyFSI+3U1k5-Mcm#CP1!I^Y~ch zJ;nNL$*tMjY_x{@Py?j{HO#~JQ5sI*abR-G*i~xC=tdpK{pHQ%Fc;)VXsRr4ZvKD> zy$>%Q!Sp%+it{2D6<+EeRzD_8uZx3W`wZ=c=+Sul7ZFR2`&hlG%p`?EfEFo+RL{K` zTb&GeLs&~R&S5?72+AOHoAZYx8dDW*rhNAESQ)gT(OESQIswZO%T~?2pgO}9FKZn6 zo)KUks!ZEllSXX>Kd*6~?+ZdXloox$9;0U_{+b*78_s;ITq4O-L3J!sb6r%!QuVq1KM1U=m5FS>Wb9}noiWkq~c-baijNv(*p@K z7=5{Gq1vJpJE__C;o$5qvFof0hD$5WS9%Y4SsQU+2Noh#k1H^jjDKgo=|3o?V}t`( zX-$q2Xw0Mfk@8_w{6i39YwsH&3d}+uA7mO~0vNT&v6Qh^Ky8fizv(71LMD{S@OO@jO$IB3FA`v@1IO znTTKbi8B?~sOY9Hg3_fMM^gTzoX81y!*aB(_#A>Z_%ZYsQdSmmR2d(mM-pjQFt`&^ zQ2DaBeW7B+6Z4ZDTlRr%MdhXJa0^m|GJQW>O0(*CumHpq>O{Rf+_<8JWB*JO9}bzOTiQ}Y7t=6%Ev4DBm(@i&h!DtSmhr3Owd;4 z%_iao)5Ov`wK$3&g&Qw|QTeCTs|4c!yU;RTU$}HhJ0|V^UG#2RXsyC?-HjXb1p{`4 z!yR7M06wM89~b1fGrKvY5#!FGjl%F@V`)#|6#W2K%#F&{Oyry9>n%PpM+6zKD(%L|6(d26|LCG|-`)5adrs-6C+dNE&?gAwXDFrvLfw!J?xy+E7}mlV~c zk`%TDKFfCBiga>3^Gy8FCn&3sVDvcN7bnsE>~e~29F{nJQmNstLW$PVPT8!PyBV5D ze(p5<(wRpb&A%XGvl;s{*W<>}960{>W=N+LJ;77G5LUI`ET~^)mP#i2wurLC6f0{L z=+q%&xRR;~a??UgQ5~qm7#cQr0{_V{hbH(7{_#~qYmlI2RdpVzjY3Z59;z@Er zbb9?zjC^#_`k!mz_K&?pPMFNzbeG$m03Bpxe8R9h>okcC#Q0~LS1Qk~4(`Yf#Mn({ z%yqv%>fduEt4{{?+vy5zy}YXP!56)mOC9&tEoXP?*-kZC^07vdI!bm=z7-H@_0DY- zcL=HCB?I*qB>u{XMp8J}d^xFEf)pjzU+ojQ4Z{<(7I*mmvV2+tL*~}ng=WUF?+A>s z0yo6WB;R^l0VQZ;1n;vk6pW+1II(h)@Oj!l&Yrvgd!(t%P(nleLq6UIGn#*#_i_T? zWjf%iv*v7>uBNYj@OgF~uEuuwYBBEJ4-*!rJn_{+6gOO|UJxj5=7EKLFcdDjU6D@D zl3*Sn%YYS60GY0U;`o@?iEmO3@jCS5o%L|;i`xWcfYCkhdN8digsRYY&s|5Wr3JHx zSImFGAc`|DL$IA|5YmL~rZ_7ofy5e9Kr634Taxip*QFOxlxd59fNbzuO z+f#zHRHdas%p)1B2%{38=M)X||NouRD08~fs7FgmDk5z2UoYP`HR`qa3;?wz!G=EmDUuNZx%pi$CZIprNv1WZM zCJrK@$M^$aB^X5e!=r+6k7v5MIKuk}6h;GTad*3@eCGDXuFmH0_iY#aFe4>U%`A{$0@ko)B3wL z`e#ayX0qka>ACrcM#OG}z3vxcpx@0mym2_!vc=gPt&llWuU50>WOKW@(d!`95t-~- zyC8I+rUK`*P2O#)ju=CxP=0qxM|x%Z$lPOR5FjL6g*{N)SNp0ANMvs zUV9RccxLc;?>f@1$~0rl&0%X|UA&dT1h`plJI{|Ce<0u%rM literal 0 HcmV?d00001 diff --git a/InternalDocs/images/python-cyclic-gc-5-new-page.png b/InternalDocs/images/python-cyclic-gc-5-new-page.png new file mode 100644 index 0000000000000000000000000000000000000000..fe67a6896fe4b07c03291ca8b21781fde8785757 GIT binary patch literal 5712 zcmZ{oc|25W{Ksd(U>H&MeTi&kD-6RRYgw`{4T`ZO6oaB+CgB#@ibBH?ne3G1rjSZx zJ@y(GNf>)HBujpC@9*CG+g`sv&iOp&`99z0oaghL=e(ZtzHMh?&dn*p34uVkEiF#l zLm)7aSsr9(o*-sHPcJfsUr3MiX71YkS z46$;&&OfOq;KkV&VAeD?n6jEu#b}*Z-deqM^y;-f+eey7Npi>dh~_sRV&$;Or(ty# ze+x-XsESiz@uTdi-t6t>$w z?tqJflHqqz=fsXi>wp3X)|aM<0RvPBaoE)TL;G*cej%#ZWR?J^yBrn?$}oiwFoo4I zy9ZeRiDl4llWn9qz{hKd0HiE7*%L(=Sj$wrCK|Z07epI#mLCA%?Z=F3hX(xC6KHE1K*+6MMs3EA3G_fVf7p{ zopk@Yk-5&Z$QnEt$r3I1N%5~5!x`=WJ}!~~(=Vv|pTcyOB=FBD|Ic8VvHxrm^6`VB z>*F={09~pb0|!-A_;9C18CZZ;pi_TQx8`}uCsq83$p#z&*?isjtt#SQ%+;dOS2DFwE<5o-+B=AxsXVWaCp= z>uK#VnD~V+CSO=Mbe)xQgOOnL!)eyumioLPa)XO4*Ac+bNI0^4{AAaeT%wP*3ye}- zu%LvEOXTVjINl_9aZWghyCAVQ9Ky+Tg86L7f8;NFnA85JOaBU; z3P&d$GPYng-N!*D8fBhJF*BxE!KQM)Fm`Z?2Rv@YrHYL+$Bs2d)WaA^C{EQ;0PqJ^ zE~qmCol;&$OM%Xa&AH|HYAynoIbQdDM=wRGiIpCOaaFHzy;dTF?JvXqF(rm)X%ciz zgEvW~FY~8$IW&86O?U)tO3w-Tq^i_N2!#o8$t9#;n*$E5wE5IP{+%ZV(AxBoaIc&mHr&Em0-=x)oWFQeB*m-=|q-OvgM*1<0eb6?4 zo|Rro&R?#a!o&L4s&*?Zc0X^bD&|M-^Ohj}i)YTpY4%7q!E^6MNCKLquTHwJ z}eWu5d}US28D?~qLlHJ)ZF6RE|R!%`wp#f%FnG3piiS#QU56_MC1|Hs1uSEH`7QG~=s;SL4?8@2ZHAE9Y(MErPitJDJ_t(^F24pmdi^G*yy>7k1HP;Lg|#G zVmRiSK8T4nqks2UP3j@n9P8yy{;_pR5?NPY7rFXnZ}Mw!r#Y08E)d)+_Ye=^UyG;8;o%muPF(SRyRID8m(z8 z$%=%a6D$|Jc`{WN-=Ab=TF6BYj*Iv5@|h?aoC^P%ZYh6Q5<*BxDNStAkgiQ6%jsn; z43n`B?5w;uN}-rrR$(N6#|amW_a{5G)2(_Kz?|{Ot-H~veS;#3@d$0tIAkJ{~2Vz3@gi9(ZmU^{1ER9l+K3i-@yi%yla|zcZc~=i&FwoAB+n4 zw=6qr%{$K})dX_{S;s&rZ_Jc&!v|9c!fg-B)~5$kLG4x-Lbs0D(3ab}cMjH;3f10B zYMJN8IIQ3!w?hDA&&o(*a!JmKMX5D7t@LE~mf*qaiLPe_!R=ilJQ~L*`S|lu^z%92 z&4)G;UL7-{c%J|D>%;7EDio*hWlQ7%pXlDq%k8U?WNAtl+{DTS5yvlio_D8i@?z(0 zh&M{U;dnf0wV7WpioWyAnTONlGo2;^QLcDl?qzIpgZ$B;r{v}FR|kP_6axu$5P9wQ z`C>iR;W`CV^$90M&WaN%E`-g~O1`Iuz%Y$3>zs{~?BWx<^(jeT$yFM9PtFIP(Lcn# zR+z*hb#`jfC58ob-sM+z?s=86m5mVQKkK(Cg8QP+K~v^ue{ECAqpL3p4k$fex407? zF7=h=F!#pqdryz)32_M@M-=BM>9KItk-5T&$$H)SzZlP>^4{{udc^H@9C);>vKb?i zV%-($3Kx*T!Cv+Zf2PZ%kUv))BI>LEGtjJQ&Ut4(V@72b4u#h871(rK!uSlidkFxLm` zXMOZoW>>!>o^Sd_oMg%K+>Rf;1F4kVHvbL7KC=KPUEtYbh{jT4$y5p$cfA!Ss(cW3 z$`~6CcR;emUYMGkr@mp6K8NE(||!$-fpFm?WiRI|*PvIber#KT}&&dSB8 zNAulb_tW(4rOsBZnT4m|>KgWa&dqEjmi@X|UaX9TZ?_#R34@Vk*X$kgL~}inTBOx} ze=PO(-B?)DzNLk)F&Zi^0V8m>DL2Y|)p45L|9G(2grFL-%kgGMxKu+J9r+o&7XI0j zcY-}6sFosQliv)SRyST*#Dr_UMgkoT^3SV6cT_=_2q@$JVG*y;1GhsTphp2p{gxEq zlAV_QUBYwoGoyf(!CxEkQyD6L?qQQwZjlTqjj~V?dMaM-X@~E2MDkC)i_Ie+|4jw= zsHdrEfd{s77Qfb|m^gY=*?Pzc{r0yvu^a?n-J{Jb3Qty!H;Ohd8lfykfNMCRb4VFY z0qm~3?YP*D2Ur&*x05Zekd{_?0=bf*M(cA-&>aDrguolooRGx)7u3e(HxR60B!Zb6$wJIiCd_@55hyfgfL zdQ4m2RaHyuxwA;VmRh8`@wjgHg{c&ceh7i6iEo6`1zu#SIclVys@w-XRpfGZb72kv zp;e03rHPH>MSH-#X%VxIB`W4i>#Nw9)AqQ$C2qPdiZelwCt>Y+`jeG+8MLaGCcY^twGpkw`gmPh zEp7G%$wmp!+B_be#6zcgy&C%?E%w=K$%BPB)TN*O2kDaydcoBjW331M@wpRINIq1#+HfGkO z<_?VTl5I%ZMRm651X8Ox5j{m`D8nh-J?%%5Ap7pvdkM?;AQ(S38QtZ^=@*dwD?m8= z^kUl$FHXAi_VWm+ZNsSh)L27dYW?UvU+qzZLMX1H_=lXZs^wOslx5J%LmHOjVl{i) zXrQuwG(p2NUR>di4&%u`#;Z;^(ss2+C{*#^skD##>VjSof4q8~;(PpGfzqD0YB`F=+QB)vGaF0-SA9(v2m zD7)v%!zd0)X~7LYu?QzickxFz^{mHK4O-X&%1yp;=HD{l4fM9qP!_7@rE*x@id4Pr zi~S}No$u&z;|BF)LW@*PTqxH>%LjLPsqjbfoYKb##ZC%a7=~koIYM zmop%$v>&!H6j>ts>Fro#j5h2piQNFh+hXu41F>}BO1;FV0y1*BV+8w|&LD6jir zy*q@`a7%17vnRQ1U@I=&Qi)>W?v#xcrA~ZoyOiM%yzP@lu-zQ~IfD(-gHFUg!K=F% z=G4B$4$2xTfDWBTlW@W#^wjFh-*^+2-S65>^U?bpXLYksU(;ZeEF51c&PZ-IGU?cP z*hJAvNswxe(}6Tl-j-=WEfvohUnv}&Wv8gK4D$vIt?K}H%dTk4JC8ysU_W-Kmw)h4 zuTDO{+s_JYsKKjPmL}U$#KsX#-$7+(mM~BM;Sg7m%9PI1^+dhVqsL8BUqJ&N3<997 zy2<4P@O>ugy9e`?kjkLdd!;*#Ds^|K%T}?{itlqZDf)f$HMOl)nkTMwteuvk_!&)A zoi2|S4%^-*tvcO-L<$vtDzy?9O1BRKsp;_wnkDT9QI*yGY=kLPwPXW~8zNuZ?je0Y z5|S}gY@jM$kG^$CrIXZ^@=?Y+z6KIqg>dE2f;`oEzb-BJY^d_$<;ms-Vx`H&H{kK! z#Y5Rv%1V)4VfVY1hfwNT z<%(24Jfird_~p8}*k?aLcISR( zfzGM#J5P2=RWy~~xPcaud|-@NBe2KYrVfhtTwezL=fu_epP{7nBmfqLFxC36^5HbD9{^+0UkD5UyMIH=sPI4l(<6B?wq-}UIHOP zz%^XE3oF_^2M<+yRIVcz-16yE!62_qYSrLwN zA{pp^6;dgKOq`t_{xbXrhFmoz0-hro7$hD~PcqIdzPZ?A3cNfF&X|dNDPR2&$diC( z2jvi4a^)@v2u3{hhc%N8(CaRU#;*y}*Dq&1D|{Wd|0L&FU4NowN}Xq4nq06 zh0RUVXHjD^m8I-Nd4Ss49k~m)mT)cIE`IidI$@YSt2QR^A@(&gNXfW>gTCd41;HmdEn~#_NihACS>I&lmmz4Qi;myqczM4#*1lG3RG~EIHVNI_Y z_;0ig=AO_+DVApk+=!PYw~QeXDwlQ8!DFJ3uGtwTOM`>epL+F3@@EWRrRp*P)Q$jn z0+0Ha_56+h{u6%vONICVFL=NStYO~X7=$JXW!#ln`Zt>VTmFWl{Y3|ef%~pM z3N_a7Ojdi8VCqWny+FXDeZufefoQ0yYpJSft7Ulni@p(`R@Nn d2oCiP^t=B5CtNi{nllq1mZmnRtBk#G{s-d0T~Yu5 literal 0 HcmV?d00001 From 21ac0a7f4cf6d11da728b33ed5e8cfa65a5a8ae7 Mon Sep 17 00:00:00 2001 From: Victorien <65306057+Viicos@users.noreply.github.com> Date: Sat, 12 Oct 2024 01:05:13 +0200 Subject: [PATCH 028/170] gh-116938: Clarify documentation of `dict` and `dict.update` regarding the positional argument they accept (#125213) Co-authored-by: Alex Waygood --- Doc/library/stdtypes.rst | 25 +++++++++++++------------ Lib/_collections_abc.py | 2 +- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 833c71c4ce4b9a..a6e2e3b8928ebe 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -4505,14 +4505,14 @@ can be used interchangeably to index the same dictionary entry. ``dict([('foo', 100), ('bar', 200)])``, ``dict(foo=100, bar=200)`` If no positional argument is given, an empty dictionary is created. - If a positional argument is given and it is a mapping object, a dictionary - is created with the same key-value pairs as the mapping object. Otherwise, - the positional argument must be an :term:`iterable` object. Each item in - the iterable must itself be an iterable with exactly two objects. The - first object of each item becomes a key in the new dictionary, and the - second object the corresponding value. If a key occurs more than once, the - last value for that key becomes the corresponding value in the new - dictionary. + If a positional argument is given and it defines a ``keys()`` method, a + dictionary is created by calling :meth:`~object.__getitem__` on the argument with + each returned key from the method. Otherwise, the positional argument must be an + :term:`iterable` object. Each item in the iterable must itself be an iterable + with exactly two elements. The first element of each item becomes a key in the + new dictionary, and the second element the corresponding value. If a key occurs + more than once, the last value for that key becomes the corresponding value in + the new dictionary. If keyword arguments are given, the keyword arguments and their values are added to the dictionary created from the positional argument. If a key @@ -4669,10 +4669,11 @@ can be used interchangeably to index the same dictionary entry. Update the dictionary with the key/value pairs from *other*, overwriting existing keys. Return ``None``. - :meth:`update` accepts either another dictionary object or an iterable of - key/value pairs (as tuples or other iterables of length two). If keyword - arguments are specified, the dictionary is then updated with those - key/value pairs: ``d.update(red=1, blue=2)``. + :meth:`update` accepts either another object with a ``keys()`` method (in + which case :meth:`~object.__getitem__` is called with every key returned from + the method). or an iterable of key/value pairs (as tuples or other iterables + of length two). If keyword arguments are specified, the dictionary is then + updated with those key/value pairs: ``d.update(red=1, blue=2)``. .. method:: values() diff --git a/Lib/_collections_abc.py b/Lib/_collections_abc.py index c2edf6c8856c21..06667b7434ccef 100644 --- a/Lib/_collections_abc.py +++ b/Lib/_collections_abc.py @@ -962,7 +962,7 @@ def clear(self): def update(self, other=(), /, **kwds): ''' D.update([E, ]**F) -> None. Update D from mapping/iterable E and F. - If E present and has a .keys() method, does: for k in E: D[k] = E[k] + If E present and has a .keys() method, does: for k in E.keys(): D[k] = E[k] If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v In either case, this is followed by: for k, v in F.items(): D[k] = v ''' From 979c0df7c0adfb744159a5fc184043dc733d8534 Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Sat, 12 Oct 2024 00:31:06 +0100 Subject: [PATCH 029/170] gh-124309: fix staggered race on eager tasks (#124847) This patch is entirely by Thomas and Peter Co-authored-by: Thomas Grainger Co-authored-by: Peter Bierma --- Lib/asyncio/staggered.py | 17 +++++-- .../test_asyncio/test_eager_task_factory.py | 46 +++++++++++++++++++ Lib/test/test_asyncio/test_staggered.py | 27 +++++++++++ ...-10-01-13-46-58.gh-issue-124390.dK1Zcm.rst | 1 + 4 files changed, 88 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-01-13-46-58.gh-issue-124390.dK1Zcm.rst diff --git a/Lib/asyncio/staggered.py b/Lib/asyncio/staggered.py index 326c6f708944af..0f4df8855a80b9 100644 --- a/Lib/asyncio/staggered.py +++ b/Lib/asyncio/staggered.py @@ -69,7 +69,11 @@ async def staggered_race(coro_fns, delay, *, loop=None): exceptions = [] running_tasks = [] - async def run_one_coro(previous_failed) -> None: + async def run_one_coro(ok_to_start, previous_failed) -> None: + # in eager tasks this waits for the calling task to append this task + # to running_tasks, in regular tasks this wait is a no-op that does + # not yield a future. See gh-124309. + await ok_to_start.wait() # Wait for the previous task to finish, or for delay seconds if previous_failed is not None: with contextlib.suppress(exceptions_mod.TimeoutError): @@ -85,8 +89,12 @@ async def run_one_coro(previous_failed) -> None: return # Start task that will run the next coroutine this_failed = locks.Event() - next_task = loop.create_task(run_one_coro(this_failed)) + next_ok_to_start = locks.Event() + next_task = loop.create_task(run_one_coro(next_ok_to_start, this_failed)) running_tasks.append(next_task) + # next_task has been appended to running_tasks so next_task is ok to + # start. + next_ok_to_start.set() assert len(running_tasks) == this_index + 2 # Prepare place to put this coroutine's exceptions if not won exceptions.append(None) @@ -116,8 +124,11 @@ async def run_one_coro(previous_failed) -> None: if i != this_index: t.cancel() - first_task = loop.create_task(run_one_coro(None)) + ok_to_start = locks.Event() + first_task = loop.create_task(run_one_coro(ok_to_start, None)) running_tasks.append(first_task) + # first_task has been appended to running_tasks so first_task is ok to start. + ok_to_start.set() try: # Wait for a growing list of tasks to all finish: poor man's version of # curio's TaskGroup or trio's nursery diff --git a/Lib/test/test_asyncio/test_eager_task_factory.py b/Lib/test/test_asyncio/test_eager_task_factory.py index 0777f39b572486..31d2a00dbb8c9c 100644 --- a/Lib/test/test_asyncio/test_eager_task_factory.py +++ b/Lib/test/test_asyncio/test_eager_task_factory.py @@ -213,6 +213,52 @@ async def run(): self.run_coro(run()) + def test_staggered_race_with_eager_tasks(self): + # See https://github.com/python/cpython/issues/124309 + + async def fail(): + await asyncio.sleep(0) + raise ValueError("no good") + + async def run(): + winner, index, excs = await asyncio.staggered.staggered_race( + [ + lambda: asyncio.sleep(2, result="sleep2"), + lambda: asyncio.sleep(1, result="sleep1"), + lambda: fail() + ], + delay=0.25 + ) + self.assertEqual(winner, 'sleep1') + self.assertEqual(index, 1) + self.assertIsNone(excs[index]) + self.assertIsInstance(excs[0], asyncio.CancelledError) + self.assertIsInstance(excs[2], ValueError) + + self.run_coro(run()) + + def test_staggered_race_with_eager_tasks_no_delay(self): + # See https://github.com/python/cpython/issues/124309 + async def fail(): + raise ValueError("no good") + + async def run(): + winner, index, excs = await asyncio.staggered.staggered_race( + [ + lambda: fail(), + lambda: asyncio.sleep(1, result="sleep1"), + lambda: asyncio.sleep(0, result="sleep0"), + ], + delay=None + ) + self.assertEqual(winner, 'sleep1') + self.assertEqual(index, 1) + self.assertIsNone(excs[index]) + self.assertIsInstance(excs[0], ValueError) + self.assertEqual(len(excs), 2) + + self.run_coro(run()) + class PyEagerTaskFactoryLoopTests(EagerTaskFactoryLoopTests, test_utils.TestCase): Task = tasks._PyTask diff --git a/Lib/test/test_asyncio/test_staggered.py b/Lib/test/test_asyncio/test_staggered.py index e6e32f7dbbbcba..74941f704c4890 100644 --- a/Lib/test/test_asyncio/test_staggered.py +++ b/Lib/test/test_asyncio/test_staggered.py @@ -95,3 +95,30 @@ async def coro(index): self.assertEqual(len(excs), 2) self.assertIsInstance(excs[0], ValueError) self.assertIsInstance(excs[1], ValueError) + + + async def test_multiple_winners(self): + event = asyncio.Event() + + async def coro(index): + await event.wait() + return index + + async def do_set(): + event.set() + await asyncio.Event().wait() + + winner, index, excs = await staggered_race( + [ + lambda: coro(0), + lambda: coro(1), + do_set, + ], + delay=0.1, + ) + self.assertIs(winner, 0) + self.assertIs(index, 0) + self.assertEqual(len(excs), 3) + self.assertIsNone(excs[0], None) + self.assertIsInstance(excs[1], asyncio.CancelledError) + self.assertIsInstance(excs[2], asyncio.CancelledError) diff --git a/Misc/NEWS.d/next/Library/2024-10-01-13-46-58.gh-issue-124390.dK1Zcm.rst b/Misc/NEWS.d/next/Library/2024-10-01-13-46-58.gh-issue-124390.dK1Zcm.rst new file mode 100644 index 00000000000000..89610fa44bf743 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-01-13-46-58.gh-issue-124390.dK1Zcm.rst @@ -0,0 +1 @@ +Fixed :exc:`AssertionError` when using :func:`!asyncio.staggered.staggered_race` with :attr:`asyncio.eager_task_factory`. From 5a074aab845f82f4a150c27b905dae05c337d381 Mon Sep 17 00:00:00 2001 From: Rafael Fontenelle Date: Fri, 11 Oct 2024 21:40:33 -0300 Subject: [PATCH 030/170] Doc: Fix a typo in "Function Examples" in the control-flow tutorial (#125338) --- Doc/tutorial/controlflow.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index fd765e58ff2485..9b73ac475c78d5 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -832,7 +832,7 @@ parameters as there is a ``/`` in the function definition:: File "", line 1, in TypeError: pos_only_arg() got some positional-only arguments passed as keyword arguments: 'arg' -The third function ``kwd_only_args`` only allows keyword arguments as indicated +The third function ``kwd_only_arg`` only allows keyword arguments as indicated by a ``*`` in the function definition:: >>> kwd_only_arg(3) From 5d8739e956cd20d3860133b384518a3c5c74e5ae Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Sat, 12 Oct 2024 12:40:34 +0530 Subject: [PATCH 031/170] gh-111924: use atomics for interp id refcounting (#125321) --- Include/internal/pycore_interp.h | 6 ++-- Python/pystate.c | 54 ++++---------------------------- 2 files changed, 8 insertions(+), 52 deletions(-) diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index d7e584094f7839..36cd71e5a007d5 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -102,9 +102,8 @@ struct _is { PyInterpreterState *next; int64_t id; - int64_t id_refcount; + Py_ssize_t id_refcount; int requires_idref; - PyThread_type_lock id_mutex; #define _PyInterpreterState_WHENCE_NOTSET -1 #define _PyInterpreterState_WHENCE_UNKNOWN 0 @@ -318,8 +317,7 @@ _PyInterpreterState_SetFinalizing(PyInterpreterState *interp, PyThreadState *tst PyAPI_FUNC(int64_t) _PyInterpreterState_ObjectToID(PyObject *); PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_LookUpID(int64_t); PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_LookUpIDObject(PyObject *); -PyAPI_FUNC(int) _PyInterpreterState_IDInitref(PyInterpreterState *); -PyAPI_FUNC(int) _PyInterpreterState_IDIncref(PyInterpreterState *); +PyAPI_FUNC(void) _PyInterpreterState_IDIncref(PyInterpreterState *); PyAPI_FUNC(void) _PyInterpreterState_IDDecref(PyInterpreterState *); PyAPI_FUNC(int) _PyInterpreterState_IsReady(PyInterpreterState *interp); diff --git a/Python/pystate.c b/Python/pystate.c index 45e79ade7b6035..5d94b7714bd607 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -523,12 +523,6 @@ _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime) _PyTypes_AfterFork(); - /* bpo-42540: id_mutex is freed by _PyInterpreterState_Delete, which does - * not force the default allocator. */ - if (_PyThread_at_fork_reinit(&runtime->interpreters.main->id_mutex) < 0) { - return _PyStatus_ERR("Failed to reinitialize runtime locks"); - } - PyStatus status = gilstate_tss_reinit(runtime); if (_PyStatus_EXCEPTION(status)) { return status; @@ -629,6 +623,8 @@ init_interpreter(PyInterpreterState *interp, assert(id > 0 || (id == 0 && interp == runtime->interpreters.main)); interp->id = id; + interp->id_refcount = 0; + assert(runtime->interpreters.head == interp); assert(next != NULL || (interp == runtime->interpreters.main)); interp->next = next; @@ -989,10 +985,6 @@ PyInterpreterState_Delete(PyInterpreterState *interp) } HEAD_UNLOCK(runtime); - if (interp->id_mutex != NULL) { - PyThread_free_lock(interp->id_mutex); - } - _Py_qsbr_fini(interp); _PyObject_FiniState(interp); @@ -1031,9 +1023,6 @@ _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime) // the "current" tstate to be set? PyInterpreterState_Clear(interp); // XXX must activate? zapthreads(interp); - if (interp->id_mutex != NULL) { - PyThread_free_lock(interp->id_mutex); - } PyInterpreterState *prev_interp = interp; interp = interp->next; free_interpreter(prev_interp); @@ -1247,9 +1236,6 @@ PyInterpreterState_GetID(PyInterpreterState *interp) PyObject * _PyInterpreterState_GetIDObject(PyInterpreterState *interp) { - if (_PyInterpreterState_IDInitref(interp) != 0) { - return NULL; - }; int64_t interpid = interp->id; if (interpid < 0) { return NULL; @@ -1259,50 +1245,22 @@ _PyInterpreterState_GetIDObject(PyInterpreterState *interp) } -int -_PyInterpreterState_IDInitref(PyInterpreterState *interp) -{ - if (interp->id_mutex != NULL) { - return 0; - } - interp->id_mutex = PyThread_allocate_lock(); - if (interp->id_mutex == NULL) { - PyErr_SetString(PyExc_RuntimeError, - "failed to create init interpreter ID mutex"); - return -1; - } - interp->id_refcount = 0; - return 0; -} - -int +void _PyInterpreterState_IDIncref(PyInterpreterState *interp) { - if (_PyInterpreterState_IDInitref(interp) < 0) { - return -1; - } - - PyThread_acquire_lock(interp->id_mutex, WAIT_LOCK); - interp->id_refcount += 1; - PyThread_release_lock(interp->id_mutex); - return 0; + _Py_atomic_add_ssize(&interp->id_refcount, 1); } void _PyInterpreterState_IDDecref(PyInterpreterState *interp) { - assert(interp->id_mutex != NULL); _PyRuntimeState *runtime = interp->runtime; - PyThread_acquire_lock(interp->id_mutex, WAIT_LOCK); - assert(interp->id_refcount != 0); - interp->id_refcount -= 1; - int64_t refcount = interp->id_refcount; - PyThread_release_lock(interp->id_mutex); + Py_ssize_t refcount = _Py_atomic_add_ssize(&interp->id_refcount, -1); - if (refcount == 0 && interp->requires_idref) { + if (refcount == 1 && interp->requires_idref) { PyThreadState *tstate = _PyThreadState_NewBound(interp, _PyThreadState_WHENCE_FINI); From 4a943c3251d1b3fdf50cfb9264ae74e5bc845c3c Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 12 Oct 2024 09:28:34 +0200 Subject: [PATCH 032/170] gh-125196: Use PyUnicodeWriter in parser (#125271) Replace the private _PyUnicodeWriter API with the public PyUnicodeWriter API in _PyPegen_concatenate_strings(). --- Parser/action_helpers.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Parser/action_helpers.c b/Parser/action_helpers.c index 24b817c6f8ff27..cb21777f566189 100644 --- a/Parser/action_helpers.c +++ b/Parser/action_helpers.c @@ -1615,7 +1615,6 @@ _PyPegen_concatenate_strings(Parser *p, asdl_expr_seq *strings, } /* build folded list */ - _PyUnicodeWriter writer; current_pos = 0; for (i = 0; i < n_flattened_elements; i++) { expr_ty elem = asdl_seq_GET(flattened, i); @@ -1635,14 +1634,17 @@ _PyPegen_concatenate_strings(Parser *p, asdl_expr_seq *strings, "abc" u"abc" -> "abcabc" */ PyObject *kind = elem->v.Constant.kind; - _PyUnicodeWriter_Init(&writer); + PyUnicodeWriter *writer = PyUnicodeWriter_Create(0); + if (writer == NULL) { + return NULL; + } expr_ty last_elem = elem; for (j = i; j < n_flattened_elements; j++) { expr_ty current_elem = asdl_seq_GET(flattened, j); if (current_elem->kind == Constant_kind) { - if (_PyUnicodeWriter_WriteStr( - &writer, current_elem->v.Constant.value)) { - _PyUnicodeWriter_Dealloc(&writer); + if (PyUnicodeWriter_WriteStr(writer, + current_elem->v.Constant.value)) { + PyUnicodeWriter_Discard(writer); return NULL; } last_elem = current_elem; @@ -1652,9 +1654,8 @@ _PyPegen_concatenate_strings(Parser *p, asdl_expr_seq *strings, } i = j - 1; - PyObject *concat_str = _PyUnicodeWriter_Finish(&writer); + PyObject *concat_str = PyUnicodeWriter_Finish(writer); if (concat_str == NULL) { - _PyUnicodeWriter_Dealloc(&writer); return NULL; } if (_PyArena_AddPyObject(p->arena, concat_str) < 0) { From eb2d268ac7480b5e2b4ffb9a644cad7ac75ae954 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 12 Oct 2024 13:10:50 +0300 Subject: [PATCH 033/170] gh-65865: Raise early errors for invalid help strings in argparse (GH-124899) --- Lib/argparse.py | 31 ++++++++++++++----- Lib/test/test_argparse.py | 31 +++++++++++++++++++ ...4-10-02-16-35-07.gh-issue-65865.S2D4wq.rst | 3 ++ 3 files changed, 58 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-02-16-35-07.gh-issue-65865.S2D4wq.rst diff --git a/Lib/argparse.py b/Lib/argparse.py index 2d8a7ef343a4ef..208c1827f9aca7 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -588,17 +588,20 @@ def _format_args(self, action, default_metavar): return result def _expand_help(self, action): + help_string = self._get_help_string(action) + if '%' not in help_string: + return help_string params = dict(vars(action), prog=self._prog) for name in list(params): - if params[name] is SUPPRESS: + value = params[name] + if value is SUPPRESS: del params[name] - for name in list(params): - if hasattr(params[name], '__name__'): - params[name] = params[name].__name__ + elif hasattr(value, '__name__'): + params[name] = value.__name__ if params.get('choices') is not None: choices_str = ', '.join([str(c) for c in params['choices']]) params['choices'] = choices_str - return self._get_help_string(action) % params + return help_string % params def _iter_indented_subactions(self, action): try: @@ -1180,9 +1183,13 @@ def add_parser(self, name, *, deprecated=False, **kwargs): help = kwargs.pop('help') choice_action = self._ChoicesPseudoAction(name, aliases, help) self._choices_actions.append(choice_action) + else: + choice_action = None # create the parser and add it to the map parser = self._parser_class(**kwargs) + if choice_action is not None: + parser._check_help(choice_action) self._name_parser_map[name] = parser # make parser available under aliases also @@ -1449,11 +1456,12 @@ def add_argument(self, *args, **kwargs): # raise an error if the metavar does not match the type if hasattr(self, "_get_formatter"): + formatter = self._get_formatter() try: - self._get_formatter()._format_args(action, None) + formatter._format_args(action, None) except TypeError: raise ValueError("length of metavar tuple does not match nargs") - + self._check_help(action) return self._add_action(action) def add_argument_group(self, *args, **kwargs): @@ -1635,6 +1643,14 @@ def _handle_conflict_resolve(self, action, conflicting_actions): if not action.option_strings: action.container._remove_action(action) + def _check_help(self, action): + if action.help and hasattr(self, "_get_formatter"): + formatter = self._get_formatter() + try: + formatter._expand_help(action) + except (ValueError, TypeError, KeyError) as exc: + raise ValueError('badly formed help string') from exc + class _ArgumentGroup(_ActionsContainer): @@ -1852,6 +1868,7 @@ def add_subparsers(self, **kwargs): # create the parsers action and add it to the positionals list parsers_class = self._pop_action_class(kwargs, 'parsers') action = parsers_class(option_strings=[], **kwargs) + self._check_help(action) self._subparsers._add_action(action) # return the created parsers action diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 1ebbc21bc1755b..000b810454f584 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -2623,6 +2623,29 @@ def test_parser_command_help(self): --foo foo help ''')) + def assert_bad_help(self, context_type, func, *args, **kwargs): + with self.assertRaisesRegex(ValueError, 'badly formed help string') as cm: + func(*args, **kwargs) + self.assertIsInstance(cm.exception.__context__, context_type) + + def test_invalid_subparsers_help(self): + parser = ErrorRaisingArgumentParser(prog='PROG') + self.assert_bad_help(ValueError, parser.add_subparsers, help='%Y-%m-%d') + parser = ErrorRaisingArgumentParser(prog='PROG') + self.assert_bad_help(KeyError, parser.add_subparsers, help='%(spam)s') + parser = ErrorRaisingArgumentParser(prog='PROG') + self.assert_bad_help(TypeError, parser.add_subparsers, help='%(prog)d') + + def test_invalid_subparser_help(self): + parser = ErrorRaisingArgumentParser(prog='PROG') + subparsers = parser.add_subparsers() + self.assert_bad_help(ValueError, subparsers.add_parser, '1', + help='%Y-%m-%d') + self.assert_bad_help(KeyError, subparsers.add_parser, '1', + help='%(spam)s') + self.assert_bad_help(TypeError, subparsers.add_parser, '1', + help='%(prog)d') + def test_subparser_title_help(self): parser = ErrorRaisingArgumentParser(prog='PROG', description='main description') @@ -5375,6 +5398,14 @@ def test_invalid_action(self): self.assertValueError('--foo', action="store-true", errmsg='unknown action') + def test_invalid_help(self): + self.assertValueError('--foo', help='%Y-%m-%d', + errmsg='badly formed help string') + self.assertValueError('--foo', help='%(spam)s', + errmsg='badly formed help string') + self.assertValueError('--foo', help='%(prog)d', + errmsg='badly formed help string') + def test_multiple_dest(self): parser = argparse.ArgumentParser() parser.add_argument(dest='foo') diff --git a/Misc/NEWS.d/next/Library/2024-10-02-16-35-07.gh-issue-65865.S2D4wq.rst b/Misc/NEWS.d/next/Library/2024-10-02-16-35-07.gh-issue-65865.S2D4wq.rst new file mode 100644 index 00000000000000..106a8b81140520 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-02-16-35-07.gh-issue-65865.S2D4wq.rst @@ -0,0 +1,3 @@ +:mod:`argparse` now raises early error for invalid ``help`` arguments to +:meth:`~argparse.ArgumentParser.add_argument`, +:meth:`~argparse.ArgumentParser.add_subparsers` and :meth:`!add_parser`. From a6c0c64de0ade400df7995f1e9480b6fc0f863aa Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 12 Oct 2024 14:46:28 +0300 Subject: [PATCH 034/170] gh-59330: Improve error message for dest= for positionals (GH-125215) Also improve the documentation. Specify how dest and metavar are derived from add_argument() positional arguments. Co-authored-by: Simon Law --- Doc/library/argparse.rst | 19 +++++++++++++++++++ Lib/argparse.py | 3 ++- Lib/test/test_argparse.py | 3 ++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index d337de87ca8f39..19f832051a9ee8 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -636,6 +636,25 @@ be positional:: usage: PROG [-h] [-f FOO] bar PROG: error: the following arguments are required: bar +By default, argparse automatically handles the internal naming and +display names of arguments, simplifying the process without requiring +additional configuration. +As such, you do not need to specify the dest_ and metavar_ parameters. +The dest_ parameter defaults to the argument name with underscores ``_`` +replacing hyphens ``-`` . The metavar_ parameter defaults to the +upper-cased name. For example:: + + >>> parser = argparse.ArgumentParser(prog='PROG') + >>> parser.add_argument('--foo-bar') + >>> parser.parse_args(['--foo-bar', 'FOO-BAR'] + Namespace(foo_bar='FOO-BAR') + >>> parser.print_help() + usage: [-h] [--foo-bar FOO-BAR] + + optional arguments: + -h, --help show this help message and exit + --foo-bar FOO-BAR + .. _action: diff --git a/Lib/argparse.py b/Lib/argparse.py index 208c1827f9aca7..64dbd7149e769c 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -1424,7 +1424,8 @@ def add_argument(self, *args, **kwargs): chars = self.prefix_chars if not args or len(args) == 1 and args[0][0] not in chars: if args and 'dest' in kwargs: - raise ValueError('dest supplied twice for positional argument') + raise ValueError('dest supplied twice for positional argument,' + ' did you mean metavar?') kwargs = self._get_positional_kwargs(*args, **kwargs) # otherwise, we're adding an optional argument diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 000b810454f584..61ddb5f16cc44f 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -5411,7 +5411,8 @@ def test_multiple_dest(self): parser.add_argument(dest='foo') with self.assertRaises(ValueError) as cm: parser.add_argument('bar', dest='baz') - self.assertIn('dest supplied twice for positional argument', + self.assertIn('dest supplied twice for positional argument,' + ' did you mean metavar?', str(cm.exception)) def test_no_argument_actions(self): From 07c2d15977738165e9dc4248e7edda7c75ecc14b Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 12 Oct 2024 14:53:00 +0300 Subject: [PATCH 035/170] gh-85935: Explicitly document the case nargs=0 in argparse (GH-125302) --- Doc/library/argparse.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index 19f832051a9ee8..d58c75eef3e739 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -751,6 +751,9 @@ how the command-line arguments should be handled. The supplied actions are: .. versionadded:: 3.8 +Only actions that consume command-line arguments (e.g. ``'store'``, +``'append'`` or ``'extend'``) can be used with positional arguments. + You may also specify an arbitrary action by passing an Action subclass or other object that implements the same interface. The ``BooleanOptionalAction`` is available in ``argparse`` and adds support for boolean actions such as @@ -878,6 +881,8 @@ See also :ref:`specifying-ambiguous-arguments`. The supported values are: If the ``nargs`` keyword argument is not provided, the number of arguments consumed is determined by the action_. Generally this means a single command-line argument will be consumed and a single item (not a list) will be produced. +Actions that do not consume command-line arguments (e.g. +``'store_const'``) set ``nargs=0``. .. _const: From 63cf4e914f879ee28a75c02e867baa7c6047ea2b Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 12 Oct 2024 15:15:37 +0300 Subject: [PATCH 036/170] gh-125254: Fix error report about ambiguous option in argparse (GH-125273) This was a regression introduced in gh-58573. It was only tested for the case when the ambiguous option is the last argument in the command line. --- Lib/argparse.py | 2 +- Lib/test/test_argparse.py | 14 ++++++++++++-- .../2024-10-10-19-57-35.gh-issue-125254.RtZxXS.rst | 1 + 3 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-10-19-57-35.gh-issue-125254.RtZxXS.rst diff --git a/Lib/argparse.py b/Lib/argparse.py index 64dbd7149e769c..cbecb3b753c2b9 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -2019,7 +2019,7 @@ def consume_optional(start_index): if len(option_tuples) > 1: options = ', '.join([option_string for action, option_string, sep, explicit_arg in option_tuples]) - args = {'option': arg_string, 'matches': options} + args = {'option': arg_strings[start_index], 'matches': options} msg = _('ambiguous option: %(option)s could match %(matches)s') raise ArgumentError(None, msg % args) diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 61ddb5f16cc44f..1fc97de78f7f89 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -6730,9 +6730,19 @@ def test_conflicting_mutually_exclusive_args_zero_or_more_with_metavar2(self): def test_ambiguous_option(self): self.parser.add_argument('--foobaz') self.parser.add_argument('--fooble', action='store_true') + self.parser.add_argument('--foogle') self.assertRaisesRegex(argparse.ArgumentError, - "ambiguous option: --foob could match --foobaz, --fooble", - self.parser.parse_args, ['--foob']) + "ambiguous option: --foob could match --foobaz, --fooble", + self.parser.parse_args, ['--foob']) + self.assertRaisesRegex(argparse.ArgumentError, + "ambiguous option: --foob=1 could match --foobaz, --fooble$", + self.parser.parse_args, ['--foob=1']) + self.assertRaisesRegex(argparse.ArgumentError, + "ambiguous option: --foob could match --foobaz, --fooble$", + self.parser.parse_args, ['--foob', '1', '--foogle', '2']) + self.assertRaisesRegex(argparse.ArgumentError, + "ambiguous option: --foob=1 could match --foobaz, --fooble$", + self.parser.parse_args, ['--foob=1', '--foogle', '2']) def test_os_error(self): self.parser.add_argument('file') diff --git a/Misc/NEWS.d/next/Library/2024-10-10-19-57-35.gh-issue-125254.RtZxXS.rst b/Misc/NEWS.d/next/Library/2024-10-10-19-57-35.gh-issue-125254.RtZxXS.rst new file mode 100644 index 00000000000000..abe37fefedc3be --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-10-19-57-35.gh-issue-125254.RtZxXS.rst @@ -0,0 +1 @@ +Fix a bug where ArgumentError includes the incorrect ambiguous option in :mod:`argparse`. From 9944ad388c457325456152257b977410c4ec3593 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 12 Oct 2024 16:04:17 +0300 Subject: [PATCH 037/170] gh-85935: Check for nargs=0 for positional arguments in argparse (GH-124839) Raise ValueError in add_argument() if either explicit nargs=0 or action that does not consume arguments (like 'store_const' or 'store_true') is specified for positional argument. --- Lib/argparse.py | 10 +++++++++- Lib/test/test_argparse.py | 7 +++++-- .../2024-10-01-13-11-53.gh-issue-85935.CTwJUy.rst | 4 ++++ 3 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-01-13-11-53.gh-issue-85935.CTwJUy.rst diff --git a/Lib/argparse.py b/Lib/argparse.py index cbecb3b753c2b9..550415dc93478b 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -1441,11 +1441,17 @@ def add_argument(self, *args, **kwargs): kwargs['default'] = self.argument_default # create the action object, and add it to the parser + action_name = kwargs.get('action') action_class = self._pop_action_class(kwargs) if not callable(action_class): raise ValueError('unknown action "%s"' % (action_class,)) action = action_class(**kwargs) + # raise an error if action for positional argument does not + # consume arguments + if not action.option_strings and action.nargs == 0: + raise ValueError(f'action {action_name!r} is not valid for positional arguments') + # raise an error if the action type is not callable type_func = self._registry_get('type', action.type, action.type) if not callable(type_func): @@ -1554,7 +1560,9 @@ def _get_positional_kwargs(self, dest, **kwargs): # mark positional arguments as required if at least one is # always required nargs = kwargs.get('nargs') - if nargs not in [OPTIONAL, ZERO_OR_MORE, REMAINDER, SUPPRESS, 0]: + if nargs == 0: + raise ValueError('nargs for positionals must be != 0') + if nargs not in [OPTIONAL, ZERO_OR_MORE, REMAINDER, SUPPRESS]: kwargs['required'] = True # return the keyword arguments with no option strings diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 1fc97de78f7f89..f52a4b6bdd8aca 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -5424,8 +5424,11 @@ def test_no_argument_actions(self): with self.subTest(attrs=attrs): self.assertTypeError('-x', action=action, **attrs) self.assertTypeError('x', action=action, **attrs) + self.assertValueError('x', action=action, + errmsg=f"action '{action}' is not valid for positional arguments") self.assertTypeError('-x', action=action, nargs=0) - self.assertTypeError('x', action=action, nargs=0) + self.assertValueError('x', action=action, nargs=0, + errmsg='nargs for positionals must be != 0') def test_no_argument_no_const_actions(self): # options with zero arguments @@ -5445,7 +5448,7 @@ def test_more_than_one_argument_actions(self): self.assertValueError('-x', nargs=0, action=action, errmsg=f'nargs for {action_name} actions must be != 0') self.assertValueError('spam', nargs=0, action=action, - errmsg=f'nargs for {action_name} actions must be != 0') + errmsg='nargs for positionals must be != 0') # const is disallowed with non-optional arguments for nargs in [1, '*', '+']: diff --git a/Misc/NEWS.d/next/Library/2024-10-01-13-11-53.gh-issue-85935.CTwJUy.rst b/Misc/NEWS.d/next/Library/2024-10-01-13-11-53.gh-issue-85935.CTwJUy.rst new file mode 100644 index 00000000000000..553f206bf26337 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-01-13-11-53.gh-issue-85935.CTwJUy.rst @@ -0,0 +1,4 @@ +:meth:`argparse.ArgumentParser.add_argument` now raises an exception if +an :ref:`action` that does not consume arguments (like 'store_const' or +'store_true') or explicit ``nargs=0`` are specified for positional +arguments. From dcd58c50844dae0d83517e88518a677914ea594b Mon Sep 17 00:00:00 2001 From: "Bernhard M. Wiedemann" Date: Sat, 12 Oct 2024 19:18:48 +0200 Subject: [PATCH 038/170] gh-125260: Change the default ``gzip.compress()`` mtime to 0 (#125261) This follows GNU gzip, which defaults to using 0 as the mtime for compressing stdin, where no file mtime is involved. This makes the output of gzip.compress() deterministic by default, greatly helping reproducible builds. Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- Doc/library/gzip.rst | 9 +++++++-- Lib/gzip.py | 6 +++--- Lib/test/test_gzip.py | 11 +++++++++++ .../2024-10-11-04-04-38.gh-issue-125260.PeZ0Mb.rst | 2 ++ 4 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-11-04-04-38.gh-issue-125260.PeZ0Mb.rst diff --git a/Doc/library/gzip.rst b/Doc/library/gzip.rst index 6b6e158f6eba2c..f24e73517e5767 100644 --- a/Doc/library/gzip.rst +++ b/Doc/library/gzip.rst @@ -184,11 +184,12 @@ The module defines the following items: attribute instead. -.. function:: compress(data, compresslevel=9, *, mtime=None) +.. function:: compress(data, compresslevel=9, *, mtime=0) Compress the *data*, returning a :class:`bytes` object containing the compressed data. *compresslevel* and *mtime* have the same meaning as in - the :class:`GzipFile` constructor above. + the :class:`GzipFile` constructor above, + but *mtime* defaults to 0 for reproducible output. .. versionadded:: 3.2 .. versionchanged:: 3.8 @@ -203,6 +204,10 @@ The module defines the following items: .. versionchanged:: 3.13 The gzip header OS byte is guaranteed to be set to 255 when this function is used as was the case in 3.10 and earlier. + .. versionchanged:: 3.14 + The *mtime* parameter now defaults to 0 for reproducible output. + For the previous behaviour of using the current time, + pass ``None`` to *mtime*. .. function:: decompress(data) diff --git a/Lib/gzip.py b/Lib/gzip.py index ba753ce3050dd8..1a3c82ce7e0711 100644 --- a/Lib/gzip.py +++ b/Lib/gzip.py @@ -580,12 +580,12 @@ def _rewind(self): self._new_member = True -def compress(data, compresslevel=_COMPRESS_LEVEL_BEST, *, mtime=None): +def compress(data, compresslevel=_COMPRESS_LEVEL_BEST, *, mtime=0): """Compress data in one shot and return the compressed string. compresslevel sets the compression level in range of 0-9. - mtime can be used to set the modification time. The modification time is - set to the current time by default. + mtime can be used to set the modification time. + The modification time is set to 0 by default, for reproducibility. """ # Wbits=31 automatically includes a gzip header and trailer. gzip_data = zlib.compress(data, level=compresslevel, wbits=31) diff --git a/Lib/test/test_gzip.py b/Lib/test/test_gzip.py index ae384c3849d49e..bf6e1703db8451 100644 --- a/Lib/test/test_gzip.py +++ b/Lib/test/test_gzip.py @@ -713,6 +713,17 @@ def test_compress_mtime(self): f.read(1) # to set mtime attribute self.assertEqual(f.mtime, mtime) + def test_compress_mtime_default(self): + # test for gh-125260 + datac = gzip.compress(data1, mtime=0) + datac2 = gzip.compress(data1) + self.assertEqual(datac, datac2) + datac3 = gzip.compress(data1, mtime=None) + self.assertNotEqual(datac, datac3) + with gzip.GzipFile(fileobj=io.BytesIO(datac3), mode="rb") as f: + f.read(1) # to set mtime attribute + self.assertGreater(f.mtime, 1) + def test_compress_correct_level(self): for mtime in (0, 42): with self.subTest(mtime=mtime): diff --git a/Misc/NEWS.d/next/Library/2024-10-11-04-04-38.gh-issue-125260.PeZ0Mb.rst b/Misc/NEWS.d/next/Library/2024-10-11-04-04-38.gh-issue-125260.PeZ0Mb.rst new file mode 100644 index 00000000000000..fab524ea0185c2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-11-04-04-38.gh-issue-125260.PeZ0Mb.rst @@ -0,0 +1,2 @@ +The :func:`gzip.compress` *mtime* parameter now defaults to 0 for reproducible output. +Patch by Bernhard M. Wiedemann and Adam Turner. From c05f9dde8a12dfd63d3ade93da616042df2dc925 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 12 Oct 2024 20:46:21 +0300 Subject: [PATCH 039/170] gh-53203: Fix strptime() for %c and %x formats on many locales (GH-124946) In some locales (like French or Hebrew) the full or abbreviated names of the default month and weekday used in __calc_date_time can be part of other name or constant part of the %c format. The month name can also match %m with constant suffix (like in Japanese). So the code failed to correctly distinguish formats %a, %A, %b, %B and %m. Cycle all month and all days of the week to find the variable part and distinguish %a from %A and %b from %B or %m. Fixed locales for the following languges: Arabic, Bislama, Breton, Bodo, Kashubian, Chuvash, Estonian, French, Irish, Ge'ez, Gurajati, Manx Gaelic, Hebrew, Hindi, Chhattisgarhi, Haitian Kreyol, Japanese, Kannada, Korean, Marathi, Malay, Norwegian, Nynorsk, Punjabi, Rajasthani, Tok Pisin, Yoruba, Yue Chinese, Yau/Nungon and Chinese. Co-authored-by: Eli Bendersky --- Lib/_strptime.py | 127 +++++++++++++++--- Lib/test/test_strptime.py | 36 +++-- ...4-10-03-20-45-57.gh-issue-53203.3Sk4Ia.rst | 5 + 3 files changed, 134 insertions(+), 34 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-03-20-45-57.gh-issue-53203.3Sk4Ia.rst diff --git a/Lib/_strptime.py b/Lib/_strptime.py index a3f8bb544d518d..89adc174e5ad30 100644 --- a/Lib/_strptime.py +++ b/Lib/_strptime.py @@ -28,6 +28,18 @@ def _getlang(): # Figure out what the current language is set to. return locale.getlocale(locale.LC_TIME) +def _findall(haystack, needle): + # Find all positions of needle in haystack. + if not needle: + return + i = 0 + while True: + i = haystack.find(needle, i) + if i < 0: + break + yield i + i += len(needle) + class LocaleTime(object): """Stores and handles locale-specific information related to time. @@ -102,7 +114,8 @@ def __calc_am_pm(self): am_pm = [] for hour in (1, 22): time_tuple = time.struct_time((1999,3,17,hour,44,55,2,76,0)) - am_pm.append(time.strftime("%p", time_tuple).lower()) + # br_FR has AM/PM info (' ',' '). + am_pm.append(time.strftime("%p", time_tuple).lower().strip()) self.am_pm = am_pm def __calc_date_time(self): @@ -114,42 +127,114 @@ def __calc_date_time(self): # values within the format string is very important; it eliminates # possible ambiguity for what something represents. time_tuple = time.struct_time((1999,3,17,22,44,55,2,76,0)) - date_time = [None, None, None] - date_time[0] = time.strftime("%c", time_tuple).lower() - date_time[1] = time.strftime("%x", time_tuple).lower() - date_time[2] = time.strftime("%X", time_tuple).lower() - replacement_pairs = [('%', '%%'), (self.f_weekday[2], '%A'), - (self.f_month[3], '%B'), (self.a_weekday[2], '%a'), - (self.a_month[3], '%b'), (self.am_pm[1], '%p'), + time_tuple2 = time.struct_time((1999,1,3,1,1,1,6,3,0)) + replacement_pairs = [ ('1999', '%Y'), ('99', '%y'), ('22', '%H'), ('44', '%M'), ('55', '%S'), ('76', '%j'), ('17', '%d'), ('03', '%m'), ('3', '%m'), # '3' needed for when no leading zero. ('2', '%w'), ('10', '%I')] - replacement_pairs.extend([(tz, "%Z") for tz_values in self.timezone - for tz in tz_values]) - for offset,directive in ((0,'%c'), (1,'%x'), (2,'%X')): - current_format = date_time[offset] - for old, new in replacement_pairs: + date_time = [] + for directive in ('%c', '%x', '%X'): + current_format = time.strftime(directive, time_tuple).lower() + current_format = current_format.replace('%', '%%') + # The month and the day of the week formats are treated specially + # because of a possible ambiguity in some locales where the full + # and abbreviated names are equal or names of different types + # are equal. See doc of __find_month_format for more details. + lst, fmt = self.__find_weekday_format(directive) + if lst: + current_format = current_format.replace(lst[2], fmt, 1) + lst, fmt = self.__find_month_format(directive) + if lst: + current_format = current_format.replace(lst[3], fmt, 1) + if self.am_pm[1]: # Must deal with possible lack of locale info # manifesting itself as the empty string (e.g., Swedish's # lack of AM/PM info) or a platform returning a tuple of empty # strings (e.g., MacOS 9 having timezone as ('','')). - if old: - current_format = current_format.replace(old, new) + current_format = current_format.replace(self.am_pm[1], '%p') + for tz_values in self.timezone: + for tz in tz_values: + if tz: + current_format = current_format.replace(tz, "%Z") + for old, new in replacement_pairs: + current_format = current_format.replace(old, new) # If %W is used, then Sunday, 2005-01-03 will fall on week 0 since # 2005-01-03 occurs before the first Monday of the year. Otherwise # %U is used. - time_tuple = time.struct_time((1999,1,3,1,1,1,6,3,0)) - if '00' in time.strftime(directive, time_tuple): + if '00' in time.strftime(directive, time_tuple2): U_W = '%W' else: U_W = '%U' - date_time[offset] = current_format.replace('11', U_W) + current_format = current_format.replace('11', U_W) + date_time.append(current_format) self.LC_date_time = date_time[0] self.LC_date = date_time[1] self.LC_time = date_time[2] + def __find_month_format(self, directive): + """Find the month format appropriate for the current locale. + + In some locales (for example French and Hebrew), the default month + used in __calc_date_time has the same name in full and abbreviated + form. Also, the month name can by accident match other part of the + representation: the day of the week name (for example in Morisyen) + or the month number (for example in Japanese). Thus, cycle months + of the year and find all positions that match the month name for + each month, If no common positions are found, the representation + does not use the month name. + """ + full_indices = abbr_indices = None + for m in range(1, 13): + time_tuple = time.struct_time((1999, m, 17, 22, 44, 55, 2, 76, 0)) + datetime = time.strftime(directive, time_tuple).lower() + indices = set(_findall(datetime, self.f_month[m])) + if full_indices is None: + full_indices = indices + else: + full_indices &= indices + indices = set(_findall(datetime, self.a_month[m])) + if abbr_indices is None: + abbr_indices = indices + else: + abbr_indices &= indices + if not full_indices and not abbr_indices: + return None, None + if full_indices: + return self.f_month, '%B' + if abbr_indices: + return self.a_month, '%b' + return None, None + + def __find_weekday_format(self, directive): + """Find the day of the week format appropriate for the current locale. + + Similar to __find_month_format(). + """ + full_indices = abbr_indices = None + for wd in range(7): + time_tuple = time.struct_time((1999, 3, 17, 22, 44, 55, wd, 76, 0)) + datetime = time.strftime(directive, time_tuple).lower() + indices = set(_findall(datetime, self.f_weekday[wd])) + if full_indices is None: + full_indices = indices + else: + full_indices &= indices + if self.f_weekday[wd] != self.a_weekday[wd]: + indices = set(_findall(datetime, self.a_weekday[wd])) + if abbr_indices is None: + abbr_indices = indices + else: + abbr_indices &= indices + if not full_indices and not abbr_indices: + return None, None + if full_indices: + return self.f_weekday, '%A' + if abbr_indices: + return self.a_weekday, '%a' + return None, None + def __calc_timezone(self): # Set self.timezone by using time.tzname. # Do not worry about possibility of time.tzname[0] == time.tzname[1] @@ -187,7 +272,7 @@ def __init__(self, locale_time=None): 'd': r"(?P3[0-1]|[1-2]\d|0[1-9]|[1-9]| [1-9])", 'f': r"(?P[0-9]{1,6})", 'H': r"(?P2[0-3]|[0-1]\d|\d)", - 'I': r"(?P1[0-2]|0[1-9]|[1-9])", + 'I': r"(?P1[0-2]|0[1-9]|[1-9]| [1-9])", 'G': r"(?P\d\d\d\d)", 'j': r"(?P36[0-6]|3[0-5]\d|[1-2]\d\d|0[1-9]\d|00[1-9]|[1-9]\d|0[1-9]|[1-9])", 'm': r"(?P1[0-2]|0[1-9]|[1-9])", @@ -349,8 +434,8 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"): _regex_cache[format] = format_regex found = format_regex.match(data_string) if not found: - raise ValueError("time data %r does not match format %r" % - (data_string, format)) + raise ValueError("time data %r does not match format %r :: /%s/" % + (data_string, format, format_regex.pattern)) if len(data_string) != found.end(): raise ValueError("unconverted data remains: %s" % data_string[found.end():]) diff --git a/Lib/test/test_strptime.py b/Lib/test/test_strptime.py index 37f6b08db28b3e..79f48dfe44abde 100644 --- a/Lib/test/test_strptime.py +++ b/Lib/test/test_strptime.py @@ -5,6 +5,7 @@ import locale import re import os +import platform import sys from test import support from test.support import warnings_helper @@ -13,6 +14,13 @@ import _strptime +libc_ver = platform.libc_ver() +if libc_ver[0] == 'glibc': + glibc_ver = tuple(map(int, libc_ver[1].split('.'))) +else: + glibc_ver = None + + class getlang_Tests(unittest.TestCase): """Test _getlang""" def test_basic(self): @@ -478,16 +486,16 @@ def test_bad_timezone(self): # * Year is not included: ha_NG. # * Use non-Gregorian calendar: lo_LA, thai, th_TH. # - # BUG: Generates invalid regexp for br_FR, csb_PL, Arabic. - # BUG: Generates regexp that does not match the current date and time - # for fa_IR, gez_ER, gez_ET, lzh_TW, my_MM, or_IN, shn_MM, yo_NG. # BUG: Generates regexp that does not match the current date and time - # for fa_IR, gez_ER, gez_ET, lzh_TW, my_MM, or_IN, shn_MM, yo_NG, - # fr_FR, ja_JP, he_IL, ko_KR, zh_CN, etc. - @run_with_locales('LC_TIME', 'C', 'en_US', 'de_DE', - 'eu_ES', 'mfe_MU') + # for az_IR, fa_IR, lzh_TW, my_MM, or_IN, shn_MM. + @run_with_locales('LC_TIME', 'C', 'en_US', 'fr_FR', 'de_DE', 'ja_JP', + 'he_IL', 'eu_ES', 'ar_AE', 'mfe_MU', 'yo_NG', + 'csb_PL', 'br_FR', 'gez_ET', 'brx_IN') def test_date_time_locale(self): # Test %c directive + loc = locale.getlocale(locale.LC_TIME)[0] + if glibc_ver and glibc_ver < (2, 31) and loc == 'br_FR': + self.skipTest('%c in locale br_FR does not include time') now = time.time() self.roundtrip('%c', slice(0, 6), time.localtime(now)) # 1 hour 20 minutes 30 seconds ago @@ -505,7 +513,9 @@ def test_date_time_locale(self): # NB: Dates before 1969 do not roundtrip on some locales: # bo_CN, bo_IN, dz_BT, eu_ES, eu_FR. - @run_with_locales('LC_TIME', 'C', 'en_US', 'de_DE', 'ja_JP') + @run_with_locales('LC_TIME', 'C', 'en_US', 'fr_FR', 'de_DE', 'ja_JP', + 'he_IL', 'ar_AE', 'mfe_MU', 'yo_NG', + 'csb_PL', 'br_FR', 'gez_ET', 'brx_IN') def test_date_time_locale2(self): # Test %c directive self.roundtrip('%c', slice(0, 6), (1900, 1, 1, 0, 0, 0, 0, 1, 0)) @@ -513,10 +523,9 @@ def test_date_time_locale2(self): # NB: Does not roundtrip because use non-Gregorian calendar: # lo_LA, thai, th_TH. # BUG: Generates regexp that does not match the current date - # for az_IR, fa_IR, lzh_TW, my_MM, or_IN, shn_MM, - # Arabic, ja_JP, ko_KR, zh_CN, etc. - @run_with_locales('LC_TIME', 'C', 'en_US', 'fr_FR', 'de_DE', - 'he_IL', 'eu_ES') + # for az_IR, fa_IR, lzh_TW, my_MM, or_IN, shn_MM. + @run_with_locales('LC_TIME', 'C', 'en_US', 'fr_FR', 'de_DE', 'ja_JP', + 'he_IL', 'eu_ES', 'ar_AE') def test_date_locale(self): # Test %x directive now = time.time() @@ -535,7 +544,8 @@ def test_date_locale(self): support.is_emscripten or support.is_wasi, "musl libc issue on Emscripten, bpo-46390" ) - @run_with_locales('LC_TIME', 'en_US', 'fr_FR', 'de_DE', 'ja_JP') + @run_with_locales('LC_TIME', 'en_US', 'fr_FR', 'de_DE', 'ja_JP', + 'eu_ES', 'ar_AE') def test_date_locale2(self): # Test %x directive self.roundtrip('%x', slice(0, 3), (1900, 1, 1, 0, 0, 0, 0, 1, 0)) diff --git a/Misc/NEWS.d/next/Library/2024-10-03-20-45-57.gh-issue-53203.3Sk4Ia.rst b/Misc/NEWS.d/next/Library/2024-10-03-20-45-57.gh-issue-53203.3Sk4Ia.rst new file mode 100644 index 00000000000000..6895cffcf545fd --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-03-20-45-57.gh-issue-53203.3Sk4Ia.rst @@ -0,0 +1,5 @@ +Fix :func:`time.strptime` for ``%c`` and ``%x`` formats in many locales: +Arabic, Bislama, Breton, Bodo, Kashubian, Chuvash, Estonian, French, Irish, +Ge'ez, Gurajati, Manx Gaelic, Hebrew, Hindi, Chhattisgarhi, Haitian Kreyol, +Japanese, Kannada, Korean, Marathi, Malay, Norwegian, Nynorsk, Punjabi, +Rajasthani, Tok Pisin, Yoruba, Yue Chinese, Yau/Nungon and Chinese. From 62d5a53a0b2a5262a86984cfe9817aeb653ebfca Mon Sep 17 00:00:00 2001 From: Richard Hansen Date: Sat, 12 Oct 2024 15:33:00 -0400 Subject: [PATCH 040/170] gh-124872: Move PyThreadState to first argument for consistency (#124774) --- Python/context.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Python/context.c b/Python/context.c index 36e2677c398f59..9b742136b0726d 100644 --- a/Python/context.c +++ b/Python/context.c @@ -112,7 +112,8 @@ context_event_name(PyContextEvent event) { Py_UNREACHABLE(); } -static void notify_context_watchers(PyContextEvent event, PyContext *ctx, PyThreadState *ts) +static void +notify_context_watchers(PyThreadState *ts, PyContextEvent event, PyContext *ctx) { assert(Py_REFCNT(ctx) > 0); PyInterpreterState *interp = ts->interp; @@ -192,7 +193,7 @@ _PyContext_Enter(PyThreadState *ts, PyObject *octx) ts->context = Py_NewRef(ctx); ts->context_ver++; - notify_context_watchers(Py_CONTEXT_EVENT_ENTER, ctx, ts); + notify_context_watchers(ts, Py_CONTEXT_EVENT_ENTER, ctx); return 0; } @@ -226,7 +227,7 @@ _PyContext_Exit(PyThreadState *ts, PyObject *octx) return -1; } - notify_context_watchers(Py_CONTEXT_EVENT_EXIT, ctx, ts); + notify_context_watchers(ts, Py_CONTEXT_EVENT_EXIT, ctx); Py_SETREF(ts->context, (PyObject *)ctx->ctx_prev); ts->context_ver++; From 4a2282b0679bbf7b7fbd36aae1b1565145238961 Mon Sep 17 00:00:00 2001 From: Stephen Rosen Date: Sat, 12 Oct 2024 15:21:55 -0500 Subject: [PATCH 041/170] Prefer "similar" over "equivalent" in tutorial (#125343) In the datastructures tutorial doc, some operations are described as "equivalent to" others. This has led to some user-confusion -- at least in the Discourse forums -- about cases in which the operations differ. This change doesn't systematically eliminate the word "equivalent" from the tutorial. It just substitutes "similar to" in several cases in which "equivalent to" could mislead users into expecting exact equivalence. --- Doc/tutorial/datastructures.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/tutorial/datastructures.rst b/Doc/tutorial/datastructures.rst index 73f17adeea72de..31941bc112a135 100644 --- a/Doc/tutorial/datastructures.rst +++ b/Doc/tutorial/datastructures.rst @@ -19,13 +19,13 @@ objects: .. method:: list.append(x) :noindex: - Add an item to the end of the list. Equivalent to ``a[len(a):] = [x]``. + Add an item to the end of the list. Similar to ``a[len(a):] = [x]``. .. method:: list.extend(iterable) :noindex: - Extend the list by appending all the items from the iterable. Equivalent to + Extend the list by appending all the items from the iterable. Similar to ``a[len(a):] = iterable``. @@ -56,7 +56,7 @@ objects: .. method:: list.clear() :noindex: - Remove all items from the list. Equivalent to ``del a[:]``. + Remove all items from the list. Similar to ``del a[:]``. .. method:: list.index(x[, start[, end]]) @@ -93,7 +93,7 @@ objects: .. method:: list.copy() :noindex: - Return a shallow copy of the list. Equivalent to ``a[:]``. + Return a shallow copy of the list. Similar to ``a[:]``. An example that uses most of the list methods:: From fa52b82c91a8e1a0971bd5fef656473ec93f41e3 Mon Sep 17 00:00:00 2001 From: "Ghorban M. Tavakoly" <58617996+galmyk@users.noreply.github.com> Date: Sun, 13 Oct 2024 00:08:13 +0330 Subject: [PATCH 042/170] gh-125289: Update sample code in asyncio-task.rst (GH-125292) * Update sample code in asyncio-task.rst This will change **coroutines** sample code in the **Awaitables** section and make the example clearer. * Update Doc/library/asyncio-task.rst Revert the added print Co-authored-by: Carol Willing * Update Doc/library/asyncio-task.rst Co-authored-by: Carol Willing --------- Co-authored-by: Carol Willing --- Doc/library/asyncio-task.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index 4716a3f9c8ac79..f27e858cf420f4 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -158,7 +158,7 @@ other coroutines:: # Nothing happens if we just call "nested()". # A coroutine object is created but not awaited, # so it *won't run at all*. - nested() + nested() # will raise a "RuntimeWarning". # Let's do it differently now and await it: print(await nested()) # will print "42". From 330c527299a5380f39c658bfa9321706cabc445d Mon Sep 17 00:00:00 2001 From: Richard Hansen Date: Sat, 12 Oct 2024 16:57:27 -0400 Subject: [PATCH 043/170] gh-124872: Change PyContext_WatchCallback to take PyObject (#124737) The PyContext struct is not intended to be public, and users of the API don't need anything more specific than PyObject. Also see gh-78943. --- Doc/c-api/contextvars.rst | 2 +- Include/cpython/context.h | 2 +- Modules/_testcapi/watchers.c | 10 +++++----- Python/context.c | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Doc/c-api/contextvars.rst b/Doc/c-api/contextvars.rst index 59e74ba1ac7022..8eba54a80dc80d 100644 --- a/Doc/c-api/contextvars.rst +++ b/Doc/c-api/contextvars.rst @@ -136,7 +136,7 @@ Context object management functions: .. versionadded:: 3.14 -.. c:type:: int (*PyContext_WatchCallback)(PyContextEvent event, PyContext* ctx) +.. c:type:: int (*PyContext_WatchCallback)(PyContextEvent event, PyObject *obj) Context object watcher callback function. The object passed to the callback is event-specific; see :c:type:`PyContextEvent` for details. diff --git a/Include/cpython/context.h b/Include/cpython/context.h index d722b4d93134f7..3c9be7873b9399 100644 --- a/Include/cpython/context.h +++ b/Include/cpython/context.h @@ -52,7 +52,7 @@ typedef enum { * if the callback returns with an exception set, it must return -1. Otherwise * it should return 0 */ -typedef int (*PyContext_WatchCallback)(PyContextEvent, PyContext *); +typedef int (*PyContext_WatchCallback)(PyContextEvent, PyObject *); /* * Register a per-interpreter callback that will be invoked for context object diff --git a/Modules/_testcapi/watchers.c b/Modules/_testcapi/watchers.c index 689863d098ad8a..b4233d07134aea 100644 --- a/Modules/_testcapi/watchers.c +++ b/Modules/_testcapi/watchers.c @@ -630,7 +630,7 @@ static int num_context_object_enter_events[NUM_CONTEXT_WATCHERS] = {0, 0}; static int num_context_object_exit_events[NUM_CONTEXT_WATCHERS] = {0, 0}; static int -handle_context_watcher_event(int which_watcher, PyContextEvent event, PyContext *ctx) { +handle_context_watcher_event(int which_watcher, PyContextEvent event, PyObject *ctx) { if (event == Py_CONTEXT_EVENT_ENTER) { num_context_object_enter_events[which_watcher]++; } @@ -644,22 +644,22 @@ handle_context_watcher_event(int which_watcher, PyContextEvent event, PyContext } static int -first_context_watcher_callback(PyContextEvent event, PyContext *ctx) { +first_context_watcher_callback(PyContextEvent event, PyObject *ctx) { return handle_context_watcher_event(0, event, ctx); } static int -second_context_watcher_callback(PyContextEvent event, PyContext *ctx) { +second_context_watcher_callback(PyContextEvent event, PyObject *ctx) { return handle_context_watcher_event(1, event, ctx); } static int -noop_context_event_handler(PyContextEvent event, PyContext *ctx) { +noop_context_event_handler(PyContextEvent event, PyObject *ctx) { return 0; } static int -error_context_event_handler(PyContextEvent event, PyContext *ctx) { +error_context_event_handler(PyContextEvent event, PyObject *ctx) { PyErr_SetString(PyExc_RuntimeError, "boom!"); return -1; } diff --git a/Python/context.c b/Python/context.c index 9b742136b0726d..8bc487a33c890b 100644 --- a/Python/context.c +++ b/Python/context.c @@ -113,7 +113,7 @@ context_event_name(PyContextEvent event) { } static void -notify_context_watchers(PyThreadState *ts, PyContextEvent event, PyContext *ctx) +notify_context_watchers(PyThreadState *ts, PyContextEvent event, PyObject *ctx) { assert(Py_REFCNT(ctx) > 0); PyInterpreterState *interp = ts->interp; @@ -193,7 +193,7 @@ _PyContext_Enter(PyThreadState *ts, PyObject *octx) ts->context = Py_NewRef(ctx); ts->context_ver++; - notify_context_watchers(ts, Py_CONTEXT_EVENT_ENTER, ctx); + notify_context_watchers(ts, Py_CONTEXT_EVENT_ENTER, octx); return 0; } @@ -227,7 +227,7 @@ _PyContext_Exit(PyThreadState *ts, PyObject *octx) return -1; } - notify_context_watchers(ts, Py_CONTEXT_EVENT_EXIT, ctx); + notify_context_watchers(ts, Py_CONTEXT_EVENT_EXIT, octx); Py_SETREF(ts->context, (PyObject *)ctx->ctx_prev); ts->context_ver++; From a8fa4ad9e9f7aa0cba8b23af2c583d17bb1d1847 Mon Sep 17 00:00:00 2001 From: Ruoyu Zhong Date: Sun, 13 Oct 2024 08:53:28 +0800 Subject: [PATCH 044/170] Doc: Fix suggested usage of `-X gil=0` in the glossary (#125366) Currently, the "global interpreter lock" entry in the glossary mentions that `-X gil 0` can be used to disable the GIL [1]. However, this is invalid; the correct usage should be `-X gil=0`. $ python -X gil 0 -c 'print("Hello, world")' Fatal Python error: config_read_gil: PYTHON_GIL / -X gil must be "0" or "1" Python runtime state: preinitialized $ python -X gil=0 -c 'print("Hello, world")' Hello, world [1]: https://docs.python.org/3/using/cmdline.html#cmdoption-X Signed-off-by: Ruoyu Zhong --- Doc/glossary.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/glossary.rst b/Doc/glossary.rst index 1d407732eef576..f67f3ecad0bc40 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -617,7 +617,7 @@ Glossary As of Python 3.13, the GIL can be disabled using the :option:`--disable-gil` build configuration. After building Python with this option, code must be - run with :option:`-X gil 0 <-X>` or after setting the :envvar:`PYTHON_GIL=0 ` + run with :option:`-X gil=0 <-X>` or after setting the :envvar:`PYTHON_GIL=0 ` environment variable. This feature enables improved performance for multi-threaded applications and makes it easier to use multi-core CPUs efficiently. For more details, see :pep:`703`. From 82bcaf15890cf85b76b4f62d2dd1710bb49c3ed1 Mon Sep 17 00:00:00 2001 From: Andrew Athan <24279435+aathan@users.noreply.github.com> Date: Sun, 13 Oct 2024 00:22:05 -0700 Subject: [PATCH 045/170] Trivial change: Update comments in activate about what running hash -r does (GH-125385) Update comments about what running hash -r does The old comment said "hash -r" forgets "past commands." However, the documentation for "hash" states that it forgets past locations. The old comment was, in my opinion, confusing. This is because it could be interpreted to mean it does something to the command history (HISTORY/HISTFILE etc) vs the cache of locations. --- Lib/venv/scripts/common/activate | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Lib/venv/scripts/common/activate b/Lib/venv/scripts/common/activate index cbd4873f012246..4593799b7e9b0e 100644 --- a/Lib/venv/scripts/common/activate +++ b/Lib/venv/scripts/common/activate @@ -14,8 +14,9 @@ deactivate () { unset _OLD_VIRTUAL_PYTHONHOME fi - # Call hash to forget past commands. Without forgetting - # past commands the $PATH changes we made may not be respected + # Call hash to forget past locations. Without forgetting + # past locations the $PATH changes we made may not be respected. + # See "man bash" for more details. hash is usually a builtin of your shell hash -r 2> /dev/null if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then From 4197a796ecf3a751ad7245b8d4f980d6d444b614 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sun, 13 Oct 2024 09:38:47 +0200 Subject: [PATCH 046/170] gh-86673: Loosen test_ttk.test_identify() requirements (#125335) In aeca373b3 (PR gh-12011, issue gh-71500), test_identify() was changed to expect different results on Darwin. Ned's fix was later adjusted by e52f9bee8. This workaround is only needed for some variants of Tk/Tcl on macOS, so we now allow both the workaround and the generic results for these tests. --- Lib/test/test_ttk/test_widgets.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_ttk/test_widgets.py b/Lib/test/test_ttk/test_widgets.py index 88740b18864006..10bec33be617a1 100644 --- a/Lib/test/test_ttk/test_widgets.py +++ b/Lib/test/test_ttk/test_widgets.py @@ -336,7 +336,8 @@ class EntryTest(AbstractWidgetTest, unittest.TestCase): 'show', 'state', 'style', 'takefocus', 'textvariable', 'validate', 'validatecommand', 'width', 'xscrollcommand', ) - IDENTIFY_AS = 'Entry.field' if sys.platform == 'darwin' else 'textarea' + # bpo-27313: macOS Tk/Tcl may or may not report 'Entry.field'. + IDENTIFY_AS = {'Entry.field', 'textarea'} def setUp(self): super().setUp() @@ -373,8 +374,7 @@ def test_identify(self): self.entry.pack() self.entry.update() - # bpo-27313: macOS Cocoa widget differs from X, allow either - self.assertEqual(self.entry.identify(5, 5), self.IDENTIFY_AS) + self.assertIn(self.entry.identify(5, 5), self.IDENTIFY_AS) self.assertEqual(self.entry.identify(-1, -1), "") self.assertRaises(tkinter.TclError, self.entry.identify, None, 5) @@ -461,7 +461,7 @@ class ComboboxTest(EntryTest, unittest.TestCase): 'validate', 'validatecommand', 'values', 'width', 'xscrollcommand', ) - IDENTIFY_AS = 'Combobox.button' if sys.platform == 'darwin' else 'textarea' + IDENTIFY_AS = {'Combobox.button', 'textarea'} def setUp(self): super().setUp() @@ -1204,7 +1204,7 @@ class SpinboxTest(EntryTest, unittest.TestCase): 'takefocus', 'textvariable', 'to', 'validate', 'validatecommand', 'values', 'width', 'wrap', 'xscrollcommand', ) - IDENTIFY_AS = 'Spinbox.field' if sys.platform == 'darwin' else 'textarea' + IDENTIFY_AS = {'Spinbox.field', 'textarea'} def setUp(self): super().setUp() From ce740d46246b28bb675ba9d62214b59be9b8411e Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sun, 13 Oct 2024 10:22:31 +0200 Subject: [PATCH 047/170] gh-61698: Use launchctl to detect macOS window manager in tests (#118390) --- Lib/test/support/__init__.py | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 72ce5dacd1be4c..d768bead7120c7 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -253,22 +253,16 @@ class USEROBJECTFLAGS(ctypes.Structure): # process not running under the same user id as the current console # user. To avoid that, raise an exception if the window manager # connection is not available. - from ctypes import cdll, c_int, pointer, Structure - from ctypes.util import find_library - - app_services = cdll.LoadLibrary(find_library("ApplicationServices")) - - if app_services.CGMainDisplayID() == 0: - reason = "gui tests cannot run without OS X window manager" + import subprocess + try: + rc = subprocess.run(["launchctl", "managername"], + capture_output=True, check=True) + managername = rc.stdout.decode("utf-8").strip() + except subprocess.CalledProcessError: + reason = "unable to detect macOS launchd job manager" else: - class ProcessSerialNumber(Structure): - _fields_ = [("highLongOfPSN", c_int), - ("lowLongOfPSN", c_int)] - psn = ProcessSerialNumber() - psn_p = pointer(psn) - if ( (app_services.GetCurrentProcess(psn_p) < 0) or - (app_services.SetFrontProcess(psn_p) < 0) ): - reason = "cannot run without OS X gui process" + if managername != "Aqua": + reason = f"{managername=} -- can only run in a macOS GUI session" # check on every platform whether tkinter can actually do anything if not reason: From 283ea5f3b2b6a18605b8598a979afe263b0f21ce Mon Sep 17 00:00:00 2001 From: Wulian Date: Sun, 13 Oct 2024 19:10:59 +0800 Subject: [PATCH 048/170] gh-125383: Update `fib` function comment for accuracy (#125386) `Doc/tutorial/controlflow.rst`: fix comment for `fib` function --- Doc/tutorial/controlflow.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index 9b73ac475c78d5..b830ce94ba4f47 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -461,8 +461,8 @@ Defining Functions We can create a function that writes the Fibonacci series to an arbitrary boundary:: - >>> def fib(n): # write Fibonacci series up to n - ... """Print a Fibonacci series up to n.""" + >>> def fib(n): # write Fibonacci series less than n + ... """Print a Fibonacci series less than n.""" ... a, b = 0, 1 ... while a < n: ... print(a, end=' ') From 022c50d190e14affb952a244c4eb6e4a644ad0c9 Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Sun, 13 Oct 2024 20:59:07 +0530 Subject: [PATCH 049/170] fix comment in _PyMutex_TryUnlock (#125319) --- Include/internal/pycore_lock.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Include/internal/pycore_lock.h b/Include/internal/pycore_lock.h index e6da083b807ce5..cd7deda00c7bee 100644 --- a/Include/internal/pycore_lock.h +++ b/Include/internal/pycore_lock.h @@ -64,8 +64,8 @@ PyMutex_LockFlags(PyMutex *m, _PyLockFlags flags) } } -// Unlock a mutex, returns 0 if the mutex is not locked (used for improved -// error messages). +// Unlock a mutex, returns -1 if the mutex is not locked (used for improved +// error messages) otherwise returns 0. extern int _PyMutex_TryUnlock(PyMutex *m); From 08489325d1cd94eba97c5f5f8cac49521fd0b0d7 Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Sun, 13 Oct 2024 20:59:41 +0530 Subject: [PATCH 050/170] gh-125161: return non zero value in pthread_self on wasi (#125303) --- Python/thread_pthread_stubs.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Python/thread_pthread_stubs.h b/Python/thread_pthread_stubs.h index 4741e594e52e65..458f8fc5951720 100644 --- a/Python/thread_pthread_stubs.h +++ b/Python/thread_pthread_stubs.h @@ -1,5 +1,9 @@ #include "cpython/pthread_stubs.h" +typedef struct py_stub_tls_entry py_tls_entry; + +#define py_tls_entries (_PyRuntime.threads.stubs.tls_entries) + // mutex int pthread_mutex_init(pthread_mutex_t *restrict mutex, @@ -105,7 +109,7 @@ pthread_join(pthread_t thread, void** value_ptr) PyAPI_FUNC(pthread_t) pthread_self(void) { - return 0; + return (pthread_t)(uintptr_t)&py_tls_entries; } int @@ -134,10 +138,6 @@ pthread_attr_destroy(pthread_attr_t *attr) } -typedef struct py_stub_tls_entry py_tls_entry; - -#define py_tls_entries (_PyRuntime.threads.stubs.tls_entries) - int pthread_key_create(pthread_key_t *key, void (*destr_function)(void *)) { From cd0f9d111a040ad863c680e9f464419640c8c3fd Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Sun, 13 Oct 2024 21:05:05 +0530 Subject: [PATCH 051/170] gh-89967: make WeakKeyDictionary and WeakValueDictionary thread safe (#125325) Make `WeakKeyDictionary` and `WeakValueDictionary` thread safe by copying the underlying the dict before iterating over it. --- Lib/_weakrefset.py | 25 --- Lib/weakref.py | 198 +++++------------- ...4-10-11-16-19-46.gh-issue-89967.vhWUOR.rst | 1 + 3 files changed, 50 insertions(+), 174 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-11-16-19-46.gh-issue-89967.vhWUOR.rst diff --git a/Lib/_weakrefset.py b/Lib/_weakrefset.py index 2071755d71dfc8..d1c7fcaeec9821 100644 --- a/Lib/_weakrefset.py +++ b/Lib/_weakrefset.py @@ -8,31 +8,6 @@ __all__ = ['WeakSet'] -class _IterationGuard: - # This context manager registers itself in the current iterators of the - # weak container, such as to delay all removals until the context manager - # exits. - # This technique should be relatively thread-safe (since sets are). - - def __init__(self, weakcontainer): - # Don't create cycles - self.weakcontainer = ref(weakcontainer) - - def __enter__(self): - w = self.weakcontainer() - if w is not None: - w._iterating.add(self) - return self - - def __exit__(self, e, t, b): - w = self.weakcontainer() - if w is not None: - s = w._iterating - s.remove(self) - if not s: - w._commit_removals() - - class WeakSet: def __init__(self, data=None): self.data = set() diff --git a/Lib/weakref.py b/Lib/weakref.py index 25b70927e29c31..94e4278143c987 100644 --- a/Lib/weakref.py +++ b/Lib/weakref.py @@ -19,7 +19,7 @@ ReferenceType, _remove_dead_weakref) -from _weakrefset import WeakSet, _IterationGuard +from _weakrefset import WeakSet import _collections_abc # Import after _weakref to avoid circular import. import sys @@ -105,34 +105,14 @@ def __init__(self, other=(), /, **kw): def remove(wr, selfref=ref(self), _atomic_removal=_remove_dead_weakref): self = selfref() if self is not None: - if self._iterating: - self._pending_removals.append(wr.key) - else: - # Atomic removal is necessary since this function - # can be called asynchronously by the GC - _atomic_removal(self.data, wr.key) + # Atomic removal is necessary since this function + # can be called asynchronously by the GC + _atomic_removal(self.data, wr.key) self._remove = remove - # A list of keys to be removed - self._pending_removals = [] - self._iterating = set() self.data = {} self.update(other, **kw) - def _commit_removals(self, _atomic_removal=_remove_dead_weakref): - pop = self._pending_removals.pop - d = self.data - # We shouldn't encounter any KeyError, because this method should - # always be called *before* mutating the dict. - while True: - try: - key = pop() - except IndexError: - return - _atomic_removal(d, key) - def __getitem__(self, key): - if self._pending_removals: - self._commit_removals() o = self.data[key]() if o is None: raise KeyError(key) @@ -140,18 +120,12 @@ def __getitem__(self, key): return o def __delitem__(self, key): - if self._pending_removals: - self._commit_removals() del self.data[key] def __len__(self): - if self._pending_removals: - self._commit_removals() return len(self.data) def __contains__(self, key): - if self._pending_removals: - self._commit_removals() try: o = self.data[key]() except KeyError: @@ -162,38 +136,28 @@ def __repr__(self): return "<%s at %#x>" % (self.__class__.__name__, id(self)) def __setitem__(self, key, value): - if self._pending_removals: - self._commit_removals() self.data[key] = KeyedRef(value, self._remove, key) def copy(self): - if self._pending_removals: - self._commit_removals() new = WeakValueDictionary() - with _IterationGuard(self): - for key, wr in self.data.items(): - o = wr() - if o is not None: - new[key] = o + for key, wr in self.data.copy().items(): + o = wr() + if o is not None: + new[key] = o return new __copy__ = copy def __deepcopy__(self, memo): from copy import deepcopy - if self._pending_removals: - self._commit_removals() new = self.__class__() - with _IterationGuard(self): - for key, wr in self.data.items(): - o = wr() - if o is not None: - new[deepcopy(key, memo)] = o + for key, wr in self.data.copy().items(): + o = wr() + if o is not None: + new[deepcopy(key, memo)] = o return new def get(self, key, default=None): - if self._pending_removals: - self._commit_removals() try: wr = self.data[key] except KeyError: @@ -207,21 +171,15 @@ def get(self, key, default=None): return o def items(self): - if self._pending_removals: - self._commit_removals() - with _IterationGuard(self): - for k, wr in self.data.items(): - v = wr() - if v is not None: - yield k, v + for k, wr in self.data.copy().items(): + v = wr() + if v is not None: + yield k, v def keys(self): - if self._pending_removals: - self._commit_removals() - with _IterationGuard(self): - for k, wr in self.data.items(): - if wr() is not None: - yield k + for k, wr in self.data.copy().items(): + if wr() is not None: + yield k __iter__ = keys @@ -235,23 +193,15 @@ def itervaluerefs(self): keep the values around longer than needed. """ - if self._pending_removals: - self._commit_removals() - with _IterationGuard(self): - yield from self.data.values() + yield from self.data.copy().values() def values(self): - if self._pending_removals: - self._commit_removals() - with _IterationGuard(self): - for wr in self.data.values(): - obj = wr() - if obj is not None: - yield obj + for wr in self.data.copy().values(): + obj = wr() + if obj is not None: + yield obj def popitem(self): - if self._pending_removals: - self._commit_removals() while True: key, wr = self.data.popitem() o = wr() @@ -259,8 +209,6 @@ def popitem(self): return key, o def pop(self, key, *args): - if self._pending_removals: - self._commit_removals() try: o = self.data.pop(key)() except KeyError: @@ -279,16 +227,12 @@ def setdefault(self, key, default=None): except KeyError: o = None if o is None: - if self._pending_removals: - self._commit_removals() self.data[key] = KeyedRef(default, self._remove, key) return default else: return o def update(self, other=None, /, **kwargs): - if self._pending_removals: - self._commit_removals() d = self.data if other is not None: if not hasattr(other, "items"): @@ -308,9 +252,7 @@ def valuerefs(self): keep the values around longer than needed. """ - if self._pending_removals: - self._commit_removals() - return list(self.data.values()) + return list(self.data.copy().values()) def __ior__(self, other): self.update(other) @@ -369,57 +311,22 @@ def __init__(self, dict=None): def remove(k, selfref=ref(self)): self = selfref() if self is not None: - if self._iterating: - self._pending_removals.append(k) - else: - try: - del self.data[k] - except KeyError: - pass + try: + del self.data[k] + except KeyError: + pass self._remove = remove - # A list of dead weakrefs (keys to be removed) - self._pending_removals = [] - self._iterating = set() - self._dirty_len = False if dict is not None: self.update(dict) - def _commit_removals(self): - # NOTE: We don't need to call this method before mutating the dict, - # because a dead weakref never compares equal to a live weakref, - # even if they happened to refer to equal objects. - # However, it means keys may already have been removed. - pop = self._pending_removals.pop - d = self.data - while True: - try: - key = pop() - except IndexError: - return - - try: - del d[key] - except KeyError: - pass - - def _scrub_removals(self): - d = self.data - self._pending_removals = [k for k in self._pending_removals if k in d] - self._dirty_len = False - def __delitem__(self, key): - self._dirty_len = True del self.data[ref(key)] def __getitem__(self, key): return self.data[ref(key)] def __len__(self): - if self._dirty_len and self._pending_removals: - # self._pending_removals may still contain keys which were - # explicitly removed, we have to scrub them (see issue #21173). - self._scrub_removals() - return len(self.data) - len(self._pending_removals) + return len(self.data) def __repr__(self): return "<%s at %#x>" % (self.__class__.__name__, id(self)) @@ -429,11 +336,10 @@ def __setitem__(self, key, value): def copy(self): new = WeakKeyDictionary() - with _IterationGuard(self): - for key, value in self.data.items(): - o = key() - if o is not None: - new[o] = value + for key, value in self.data.copy().items(): + o = key() + if o is not None: + new[o] = value return new __copy__ = copy @@ -441,11 +347,10 @@ def copy(self): def __deepcopy__(self, memo): from copy import deepcopy new = self.__class__() - with _IterationGuard(self): - for key, value in self.data.items(): - o = key() - if o is not None: - new[o] = deepcopy(value, memo) + for key, value in self.data.copy().items(): + o = key() + if o is not None: + new[o] = deepcopy(value, memo) return new def get(self, key, default=None): @@ -459,26 +364,23 @@ def __contains__(self, key): return wr in self.data def items(self): - with _IterationGuard(self): - for wr, value in self.data.items(): - key = wr() - if key is not None: - yield key, value + for wr, value in self.data.copy().items(): + key = wr() + if key is not None: + yield key, value def keys(self): - with _IterationGuard(self): - for wr in self.data: - obj = wr() - if obj is not None: - yield obj + for wr in self.data.copy(): + obj = wr() + if obj is not None: + yield obj __iter__ = keys def values(self): - with _IterationGuard(self): - for wr, value in self.data.items(): - if wr() is not None: - yield value + for wr, value in self.data.copy().items(): + if wr() is not None: + yield value def keyrefs(self): """Return a list of weak references to the keys. @@ -493,7 +395,6 @@ def keyrefs(self): return list(self.data) def popitem(self): - self._dirty_len = True while True: key, value = self.data.popitem() o = key() @@ -501,7 +402,6 @@ def popitem(self): return o, value def pop(self, key, *args): - self._dirty_len = True return self.data.pop(ref(key), *args) def setdefault(self, key, default=None): diff --git a/Misc/NEWS.d/next/Library/2024-10-11-16-19-46.gh-issue-89967.vhWUOR.rst b/Misc/NEWS.d/next/Library/2024-10-11-16-19-46.gh-issue-89967.vhWUOR.rst new file mode 100644 index 00000000000000..d0860457c8e813 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-11-16-19-46.gh-issue-89967.vhWUOR.rst @@ -0,0 +1 @@ +Make :class:`~weakref.WeakKeyDictionary` and :class:`~weakref.WeakValueDictionary` safe against concurrent mutations from other threads. Patch by Kumar Aditya. From 6c386b703d19aaec9a34fd1e843a4d0a144ad14b Mon Sep 17 00:00:00 2001 From: partev Date: Sun, 13 Oct 2024 12:46:15 -0400 Subject: [PATCH 052/170] gh-125403: fix console formatting in Chapter 12 of the tutorial (#125404) --- Doc/tutorial/venv.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Doc/tutorial/venv.rst b/Doc/tutorial/venv.rst index 91e4ce18acef1d..f362e1943b666f 100644 --- a/Doc/tutorial/venv.rst +++ b/Doc/tutorial/venv.rst @@ -76,7 +76,7 @@ virtual environment you're using, and modify the environment so that running ``python`` will get you that particular version and installation of Python. For example: -.. code-block:: bash +.. code-block:: console $ source ~/envs/tutorial-env/bin/activate (tutorial-env) $ python @@ -108,7 +108,7 @@ complete documentation for ``pip``.) You can install the latest version of a package by specifying a package's name: -.. code-block:: bash +.. code-block:: console (tutorial-env) $ python -m pip install novas Collecting novas @@ -120,7 +120,7 @@ You can install the latest version of a package by specifying a package's name: You can also install a specific version of a package by giving the package name followed by ``==`` and the version number: -.. code-block:: bash +.. code-block:: console (tutorial-env) $ python -m pip install requests==2.6.0 Collecting requests==2.6.0 @@ -133,7 +133,7 @@ version is already installed and do nothing. You can supply a different version number to get that version, or you can run ``python -m pip install --upgrade`` to upgrade the package to the latest version: -.. code-block:: bash +.. code-block:: console (tutorial-env) $ python -m pip install --upgrade requests Collecting requests @@ -148,7 +148,7 @@ remove the packages from the virtual environment. ``python -m pip show`` will display information about a particular package: -.. code-block:: bash +.. code-block:: console (tutorial-env) $ python -m pip show requests --- @@ -166,7 +166,7 @@ remove the packages from the virtual environment. ``python -m pip list`` will display all of the packages installed in the virtual environment: -.. code-block:: bash +.. code-block:: console (tutorial-env) $ python -m pip list novas (3.1.1.3) @@ -179,7 +179,7 @@ the virtual environment: but the output uses the format that ``python -m pip install`` expects. A common convention is to put this list in a ``requirements.txt`` file: -.. code-block:: bash +.. code-block:: console (tutorial-env) $ python -m pip freeze > requirements.txt (tutorial-env) $ cat requirements.txt @@ -191,7 +191,7 @@ The ``requirements.txt`` can then be committed to version control and shipped as part of an application. Users can then install all the necessary packages with ``install -r``: -.. code-block:: bash +.. code-block:: console (tutorial-env) $ python -m pip install -r requirements.txt Collecting novas==3.1.1.3 (from -r requirements.txt (line 1)) From e79bbd147fd58e825572f1aa93c5398953289fb2 Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Sun, 13 Oct 2024 22:29:27 +0530 Subject: [PATCH 053/170] add Kumar Aditya as codeowner for weakref (#125405) --- .github/CODEOWNERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 7e9c3caf23f079..221008717b29b1 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -280,3 +280,5 @@ Lib/test/test_configparser.py @jaraco # Doc sections Doc/reference/ @willingc + +**/*weakref* @kumaraditya303 \ No newline at end of file From c6d7b644c2425b397cfb641f336bea70eb8a329a Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Sun, 13 Oct 2024 20:38:42 +0300 Subject: [PATCH 054/170] gh-101291: Add versionadded directives for PyUnstable_Long_* (#125384) --- Doc/c-api/long.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Doc/c-api/long.rst b/Doc/c-api/long.rst index e0ae0f77a01db9..02ef8aa7846468 100644 --- a/Doc/c-api/long.rst +++ b/Doc/c-api/long.rst @@ -608,6 +608,9 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. Exactly what values are considered compact is an implementation detail and is subject to change. + .. versionadded:: 3.12 + + .. c:function:: Py_ssize_t PyUnstable_Long_CompactValue(const PyLongObject* op) If *op* is compact, as determined by :c:func:`PyUnstable_Long_IsCompact`, @@ -615,3 +618,5 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. Otherwise, the return value is undefined. + .. versionadded:: 3.12 + From cb8e5995d89d9b90e83cf43310ec50e177484e70 Mon Sep 17 00:00:00 2001 From: Barney Gale Date: Sun, 13 Oct 2024 18:46:10 +0100 Subject: [PATCH 055/170] GH-125069: Fix inconsistent joining in `WindowsPath(PosixPath(...))` (#125156) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `PurePath.__init__()` incorrectly uses the `_raw_paths` of a given `PurePath` object with a different flavour, even though the procedure to join path segments can differ between flavours. This change makes the `_raw_paths`-enabled deferred joining apply _only_ when the path flavours match. Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> --- Lib/pathlib/_local.py | 4 ++-- Lib/test/test_pathlib/test_pathlib.py | 9 +++++++++ .../2024-10-08-21-17-16.gh-issue-125069.0RP0Mx.rst | 4 ++++ 3 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-08-21-17-16.gh-issue-125069.0RP0Mx.rst diff --git a/Lib/pathlib/_local.py b/Lib/pathlib/_local.py index 1c02e4168d3a9e..a78997179820b1 100644 --- a/Lib/pathlib/_local.py +++ b/Lib/pathlib/_local.py @@ -119,9 +119,9 @@ def __init__(self, *args): paths = [] for arg in args: if isinstance(arg, PurePath): - if arg.parser is ntpath and self.parser is posixpath: + if arg.parser is not self.parser: # GH-103631: Convert separators for backwards compatibility. - paths.extend(path.replace('\\', '/') for path in arg._raw_paths) + paths.append(arg.as_posix()) else: paths.extend(arg._raw_paths) else: diff --git a/Lib/test/test_pathlib/test_pathlib.py b/Lib/test/test_pathlib/test_pathlib.py index b47b4a194cfaa9..c7104bfda90f6c 100644 --- a/Lib/test/test_pathlib/test_pathlib.py +++ b/Lib/test/test_pathlib/test_pathlib.py @@ -131,6 +131,15 @@ def test_constructor_nested(self): self.assertEqual(P(P('a'), P('b'), P('c')), P(FakePath("a/b/c"))) self.assertEqual(P(P('./a:b')), P('./a:b')) + @needs_windows + def test_constructor_nested_foreign_flavour(self): + # See GH-125069. + p1 = pathlib.PurePosixPath('b/c:\\d') + p2 = pathlib.PurePosixPath('b/', 'c:\\d') + self.assertEqual(p1, p2) + self.assertEqual(self.cls(p1), self.cls('b/c:/d')) + self.assertEqual(self.cls(p2), self.cls('b/c:/d')) + def _check_parse_path(self, raw_path, *expected): sep = self.parser.sep actual = self.cls._parse_path(raw_path.replace('/', sep)) diff --git a/Misc/NEWS.d/next/Library/2024-10-08-21-17-16.gh-issue-125069.0RP0Mx.rst b/Misc/NEWS.d/next/Library/2024-10-08-21-17-16.gh-issue-125069.0RP0Mx.rst new file mode 100644 index 00000000000000..9f1fd871e1d0b5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-08-21-17-16.gh-issue-125069.0RP0Mx.rst @@ -0,0 +1,4 @@ +Fix an issue where providing a :class:`pathlib.PurePath` object as an +initializer argument to a second :class:`~pathlib.PurePath` object with a +different :attr:`~pathlib.PurePath.parser` resulted in arguments to the +former object's initializer being joined by the latter object's parser. From f1d33dbddd3496b062e1fbe024fb6d7b023a35f5 Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Sun, 13 Oct 2024 16:17:51 -0400 Subject: [PATCH 056/170] gh-125243: Fix ZoneInfo data race in free threading build (#125281) Lock `ZoneInfoType` to protect accesses to `ZONEINFO_STRONG_CACHE`. Refactor the `tp_new` handler to use Argument Clinic so that we can just use `@critical_section` annotations on the relevant functions. Also use `PyDict_SetDefaultRef` instead of `PyDict_SetDefault` when inserting into the `TIMEDELTA_CACHE`. --- ...-10-10-20-39-57.gh-issue-125243.eUbbtu.rst | 2 + Modules/_zoneinfo.c | 44 +++++++------ Modules/clinic/_zoneinfo.c.h | 61 ++++++++++++++++++- 3 files changed, 87 insertions(+), 20 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-10-20-39-57.gh-issue-125243.eUbbtu.rst diff --git a/Misc/NEWS.d/next/Library/2024-10-10-20-39-57.gh-issue-125243.eUbbtu.rst b/Misc/NEWS.d/next/Library/2024-10-10-20-39-57.gh-issue-125243.eUbbtu.rst new file mode 100644 index 00000000000000..49f84d9711819f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-10-20-39-57.gh-issue-125243.eUbbtu.rst @@ -0,0 +1,2 @@ +Fix data race when creating :class:`zoneinfo.ZoneInfo` objects in the free +threading build. diff --git a/Modules/_zoneinfo.c b/Modules/_zoneinfo.c index 902ece795b575b..c5292575c22f23 100644 --- a/Modules/_zoneinfo.c +++ b/Modules/_zoneinfo.c @@ -3,6 +3,7 @@ #endif #include "Python.h" +#include "pycore_critical_section.h" // _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED() #include "pycore_long.h" // _PyLong_GetOne() #include "pycore_pyerrors.h" // _PyErr_ChainExceptions1() @@ -298,15 +299,20 @@ get_weak_cache(zoneinfo_state *state, PyTypeObject *type) } } +/*[clinic input] +@critical_section +@classmethod +zoneinfo.ZoneInfo.__new__ + + key: object + +Create a new ZoneInfo instance. +[clinic start generated code]*/ + static PyObject * -zoneinfo_new(PyTypeObject *type, PyObject *args, PyObject *kw) +zoneinfo_ZoneInfo_impl(PyTypeObject *type, PyObject *key) +/*[clinic end generated code: output=95e61dab86bb95c3 input=ef73d7a83bf8790e]*/ { - PyObject *key = NULL; - static char *kwlist[] = {"key", NULL}; - if (PyArg_ParseTupleAndKeywords(args, kw, "O", kwlist, &key) == 0) { - return NULL; - } - zoneinfo_state *state = zoneinfo_get_state_by_self(type); PyObject *instance = zone_from_strong_cache(state, type, key); if (instance != NULL || PyErr_Occurred()) { @@ -467,6 +473,7 @@ zoneinfo_ZoneInfo_no_cache_impl(PyTypeObject *type, PyTypeObject *cls, } /*[clinic input] +@critical_section @classmethod zoneinfo.ZoneInfo.clear_cache @@ -481,7 +488,7 @@ Clear the ZoneInfo cache. static PyObject * zoneinfo_ZoneInfo_clear_cache_impl(PyTypeObject *type, PyTypeObject *cls, PyObject *only_keys) -/*[clinic end generated code: output=114d9b7c8a22e660 input=e32ca3bb396788ba]*/ +/*[clinic end generated code: output=114d9b7c8a22e660 input=35944715df26d24e]*/ { zoneinfo_state *state = zoneinfo_get_state_by_cls(cls); PyObject *weak_cache = get_weak_cache(state, type); @@ -816,14 +823,10 @@ zoneinfo_ZoneInfo__unpickle_impl(PyTypeObject *type, PyTypeObject *cls, /*[clinic end generated code: output=556712fc709deecb input=6ac8c73eed3de316]*/ { if (from_cache) { - PyObject *val_args = PyTuple_Pack(1, key); - if (val_args == NULL) { - return NULL; - } - - PyObject *rv = zoneinfo_new(type, val_args, NULL); - - Py_DECREF(val_args); + PyObject *rv; + Py_BEGIN_CRITICAL_SECTION(type); + rv = zoneinfo_ZoneInfo_impl(type, key); + Py_END_CRITICAL_SECTION(); return rv; } else { @@ -858,8 +861,7 @@ load_timedelta(zoneinfo_state *state, long seconds) 0, seconds, 0, 1, PyDateTimeAPI->DeltaType); if (tmp != NULL) { - rv = PyDict_SetDefault(state->TIMEDELTA_CACHE, pyoffset, tmp); - Py_XINCREF(rv); + PyDict_SetDefaultRef(state->TIMEDELTA_CACHE, pyoffset, tmp, &rv); Py_DECREF(tmp); } } @@ -2368,6 +2370,7 @@ strong_cache_free(StrongCacheNode *root) static void remove_from_strong_cache(zoneinfo_state *state, StrongCacheNode *node) { + _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(state->ZoneInfoType); if (state->ZONEINFO_STRONG_CACHE == node) { state->ZONEINFO_STRONG_CACHE = node->next; } @@ -2422,6 +2425,7 @@ eject_from_strong_cache(zoneinfo_state *state, const PyTypeObject *const type, return 0; } + _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(state->ZoneInfoType); StrongCacheNode *cache = state->ZONEINFO_STRONG_CACHE; StrongCacheNode *node = find_in_strong_cache(cache, key); if (node != NULL) { @@ -2478,6 +2482,7 @@ zone_from_strong_cache(zoneinfo_state *state, const PyTypeObject *const type, return NULL; // Strong cache currently only implemented for base class } + _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(state->ZoneInfoType); StrongCacheNode *cache = state->ZONEINFO_STRONG_CACHE; StrongCacheNode *node = find_in_strong_cache(cache, key); @@ -2504,6 +2509,7 @@ update_strong_cache(zoneinfo_state *state, const PyTypeObject *const type, return; } + _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(state->ZoneInfoType); StrongCacheNode *new_node = strong_cache_node_new(key, zone); if (new_node == NULL) { return; @@ -2631,7 +2637,7 @@ static PyType_Slot zoneinfo_slots[] = { {Py_tp_getattro, PyObject_GenericGetAttr}, {Py_tp_methods, zoneinfo_methods}, {Py_tp_members, zoneinfo_members}, - {Py_tp_new, zoneinfo_new}, + {Py_tp_new, zoneinfo_ZoneInfo}, {Py_tp_dealloc, zoneinfo_dealloc}, {Py_tp_traverse, zoneinfo_traverse}, {Py_tp_clear, zoneinfo_clear}, diff --git a/Modules/clinic/_zoneinfo.c.h b/Modules/clinic/_zoneinfo.c.h index 9905b6425e2f79..bde88b5c4fa65b 100644 --- a/Modules/clinic/_zoneinfo.c.h +++ b/Modules/clinic/_zoneinfo.c.h @@ -6,8 +6,65 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_critical_section.h"// Py_BEGIN_CRITICAL_SECTION() #include "pycore_modsupport.h" // _PyArg_UnpackKeywords() +PyDoc_STRVAR(zoneinfo_ZoneInfo__doc__, +"ZoneInfo(key)\n" +"--\n" +"\n" +"Create a new ZoneInfo instance."); + +static PyObject * +zoneinfo_ZoneInfo_impl(PyTypeObject *type, PyObject *key); + +static PyObject * +zoneinfo_ZoneInfo(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"key", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "ZoneInfo", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + PyObject *key; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); + if (!fastargs) { + goto exit; + } + key = fastargs[0]; + Py_BEGIN_CRITICAL_SECTION(type); + return_value = zoneinfo_ZoneInfo_impl(type, key); + Py_END_CRITICAL_SECTION(); + +exit: + return return_value; +} + PyDoc_STRVAR(zoneinfo_ZoneInfo_from_file__doc__, "from_file($type, file_obj, /, key=None)\n" "--\n" @@ -182,7 +239,9 @@ zoneinfo_ZoneInfo_clear_cache(PyTypeObject *type, PyTypeObject *cls, PyObject *c } only_keys = args[0]; skip_optional_kwonly: + Py_BEGIN_CRITICAL_SECTION(type); return_value = zoneinfo_ZoneInfo_clear_cache_impl(type, cls, only_keys); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -372,4 +431,4 @@ zoneinfo_ZoneInfo__unpickle(PyTypeObject *type, PyTypeObject *cls, PyObject *con exit: return return_value; } -/*[clinic end generated code: output=2a15f32fdd2ab6cd input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b4fdc0b30247110a input=a9049054013a1b77]*/ From cfc27bc50fe165330f2295f9ac0ad56ca5b0f31c Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Mon, 14 Oct 2024 07:44:48 +0300 Subject: [PATCH 057/170] gh-123133: clarify p=0 case for "f" and "e" formatting types (GH-125426) Co-authored-by: Serhiy Storchaka --- Doc/library/string.rst | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Doc/library/string.rst b/Doc/library/string.rst index 57a1f920523035..49aeb28d57c8d1 100644 --- a/Doc/library/string.rst +++ b/Doc/library/string.rst @@ -509,9 +509,8 @@ The available presentation types for :class:`float` and | | significant digits. With no precision given, uses a | | | precision of ``6`` digits after the decimal point for | | | :class:`float`, and shows all coefficient digits | - | | for :class:`~decimal.Decimal`. If no digits follow the | - | | decimal point, the decimal point is also removed unless | - | | the ``#`` option is used. | + | | for :class:`~decimal.Decimal`. If ``p=0``, the decimal | + | | point is omitted unless the ``#`` option is used. | +---------+----------------------------------------------------------+ | ``'E'`` | Scientific notation. Same as ``'e'`` except it uses | | | an upper case 'E' as the separator character. | @@ -522,9 +521,8 @@ The available presentation types for :class:`float` and | | precision given, uses a precision of ``6`` digits after | | | the decimal point for :class:`float`, and uses a | | | precision large enough to show all coefficient digits | - | | for :class:`~decimal.Decimal`. If no digits follow the | - | | decimal point, the decimal point is also removed unless | - | | the ``#`` option is used. | + | | for :class:`~decimal.Decimal`. If ``p=0``, the decimal | + | | point is omitted unless the ``#`` option is used. | +---------+----------------------------------------------------------+ | ``'F'`` | Fixed-point notation. Same as ``'f'``, but converts | | | ``nan`` to ``NAN`` and ``inf`` to ``INF``. | From 66b3922b97388c328c9bd8df050eef11c0261fae Mon Sep 17 00:00:00 2001 From: rindeal Date: Mon, 14 Oct 2024 06:36:53 +0000 Subject: [PATCH 058/170] gh-86357: argparse: use str() consistently and explicitly to print choices (GH-117766) Signed-off-by: Jan Chren ~rindeal --- Lib/argparse.py | 12 +++---- Lib/test/test_argparse.py | 31 ++++++++++++++++++- ...-04-19-05-58-50.gh-issue-117766.J3xepp.rst | 1 + 3 files changed, 36 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-04-19-05-58-50.gh-issue-117766.J3xepp.rst diff --git a/Lib/argparse.py b/Lib/argparse.py index 550415dc93478b..fa9f5211257e96 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -547,8 +547,7 @@ def _metavar_formatter(self, action, default_metavar): if action.metavar is not None: result = action.metavar elif action.choices is not None: - choice_strs = [str(choice) for choice in action.choices] - result = '{%s}' % ','.join(choice_strs) + result = '{%s}' % ','.join(map(str, action.choices)) else: result = default_metavar @@ -599,8 +598,7 @@ def _expand_help(self, action): elif hasattr(value, '__name__'): params[name] = value.__name__ if params.get('choices') is not None: - choices_str = ', '.join([str(c) for c in params['choices']]) - params['choices'] = choices_str + params['choices'] = ', '.join(map(str, params['choices'])) return help_string % params def _iter_indented_subactions(self, action): @@ -717,7 +715,7 @@ def _get_action_name(argument): elif argument.dest not in (None, SUPPRESS): return argument.dest elif argument.choices: - return '{' + ','.join(argument.choices) + '}' + return '{%s}' % ','.join(map(str, argument.choices)) else: return None @@ -2607,8 +2605,8 @@ def _check_value(self, action, value): if isinstance(choices, str): choices = iter(choices) if value not in choices: - args = {'value': value, - 'choices': ', '.join(map(repr, action.choices))} + args = {'value': str(value), + 'choices': ', '.join(map(str, action.choices))} msg = _('invalid choice: %(value)r (choose from %(choices)s)') raise ArgumentError(action, msg % args) diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index f52a4b6bdd8aca..78692fd3474782 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -16,6 +16,7 @@ import argparse import warnings +from enum import StrEnum from test.support import captured_stderr from test.support import import_helper from test.support import os_helper @@ -985,6 +986,34 @@ class TestDisallowLongAbbreviationAllowsShortGroupingPrefix(ParserTestCase): ] +class TestStrEnumChoices(TestCase): + class Color(StrEnum): + RED = "red" + GREEN = "green" + BLUE = "blue" + + def test_parse_enum_value(self): + parser = argparse.ArgumentParser() + parser.add_argument('--color', choices=self.Color) + args = parser.parse_args(['--color', 'red']) + self.assertEqual(args.color, self.Color.RED) + + def test_help_message_contains_enum_choices(self): + parser = argparse.ArgumentParser() + parser.add_argument('--color', choices=self.Color, help='Choose a color') + self.assertIn('[--color {red,green,blue}]', parser.format_usage()) + self.assertIn(' --color {red,green,blue}', parser.format_help()) + + def test_invalid_enum_value_raises_error(self): + parser = argparse.ArgumentParser(exit_on_error=False) + parser.add_argument('--color', choices=self.Color) + self.assertRaisesRegex( + argparse.ArgumentError, + r"invalid choice: 'yellow' \(choose from red, green, blue\)", + parser.parse_args, + ['--color', 'yellow'], + ) + # ================ # Positional tests # ================ @@ -2485,7 +2514,7 @@ def test_wrong_argument_subparsers_no_destination_error(self): parser.parse_args(('baz',)) self.assertRegex( excinfo.exception.stderr, - r"error: argument {foo,bar}: invalid choice: 'baz' \(choose from 'foo', 'bar'\)\n$" + r"error: argument {foo,bar}: invalid choice: 'baz' \(choose from foo, bar\)\n$" ) def test_optional_subparsers(self): diff --git a/Misc/NEWS.d/next/Library/2024-04-19-05-58-50.gh-issue-117766.J3xepp.rst b/Misc/NEWS.d/next/Library/2024-04-19-05-58-50.gh-issue-117766.J3xepp.rst new file mode 100644 index 00000000000000..d090f931f0238d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-04-19-05-58-50.gh-issue-117766.J3xepp.rst @@ -0,0 +1 @@ +Always use :func:`str` to print ``choices`` in :mod:`argparse`. From b52c7306ea4470f9d7548655c2a1b89a07ff5504 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 14 Oct 2024 10:54:59 +0300 Subject: [PATCH 059/170] gh-121797: Add class method Fraction.from_number() (GH-121800) It is an alternative constructor which only accepts a single numeric argument. Unlike to Fraction.from_float() and Fraction.from_decimal() it accepts any real numbers supported by the standard constructor (int, float, Decimal, Rational numbers, objects with as_integer_ratio()). Unlike to the standard constructor, it does not accept strings. --- Doc/library/fractions.rst | 10 ++++ Doc/whatsnew/3.14.rst | 4 ++ Lib/fractions.py | 25 +++++++++- Lib/test/test_fractions.py | 49 ++++++++++++++++--- ...-07-15-19-34-56.gh-issue-121797.qDqj59.rst | 2 + 5 files changed, 82 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-07-15-19-34-56.gh-issue-121797.qDqj59.rst diff --git a/Doc/library/fractions.rst b/Doc/library/fractions.rst index 2ee154952549ac..fc7f9a6301a915 100644 --- a/Doc/library/fractions.rst +++ b/Doc/library/fractions.rst @@ -166,6 +166,16 @@ another rational number, or from a string. instance. + .. classmethod:: from_number(number) + + Alternative constructor which only accepts instances of + :class:`numbers.Integral`, :class:`numbers.Rational`, + :class:`float` or :class:`decimal.Decimal`, and objects with + the :meth:`!as_integer_ratio` method, but not strings. + + .. versionadded:: 3.14 + + .. method:: limit_denominator(max_denominator=1000000) Finds and returns the closest :class:`Fraction` to ``self`` that has diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index c62a3ca5872eef..b22d1bd1e99d4e 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -263,6 +263,10 @@ fractions :meth:`!as_integer_ratio` method to a :class:`~fractions.Fraction`. (Contributed by Serhiy Storchaka in :gh:`82017`.) +* Add alternative :class:`~fractions.Fraction` constructor + :meth:`Fraction.from_number() `. + (Contributed by Serhiy Storchaka in :gh:`121797`.) + functools --------- diff --git a/Lib/fractions.py b/Lib/fractions.py index 34fd0803d1b1ab..f0cbc8c2e6c012 100644 --- a/Lib/fractions.py +++ b/Lib/fractions.py @@ -279,7 +279,8 @@ def __new__(cls, numerator=0, denominator=None): numerator = -numerator else: - raise TypeError("argument should be a string or a number") + raise TypeError("argument should be a string or a Rational " + "instance or have the as_integer_ratio() method") elif type(numerator) is int is type(denominator): pass # *very* normal case @@ -305,6 +306,28 @@ def __new__(cls, numerator=0, denominator=None): self._denominator = denominator return self + @classmethod + def from_number(cls, number): + """Converts a finite real number to a rational number, exactly. + + Beware that Fraction.from_number(0.3) != Fraction(3, 10). + + """ + if type(number) is int: + return cls._from_coprime_ints(number, 1) + + elif isinstance(number, numbers.Rational): + return cls._from_coprime_ints(number.numerator, number.denominator) + + elif (isinstance(number, float) or + (not isinstance(number, type) and + hasattr(number, 'as_integer_ratio'))): + return cls._from_coprime_ints(*number.as_integer_ratio()) + + else: + raise TypeError("argument should be a Rational instance or " + "have the as_integer_ratio() method") + @classmethod def from_float(cls, f): """Converts a finite float to a rational number, exactly. diff --git a/Lib/test/test_fractions.py b/Lib/test/test_fractions.py index 4907f4093f52c9..98dccbec9566ac 100644 --- a/Lib/test/test_fractions.py +++ b/Lib/test/test_fractions.py @@ -283,6 +283,13 @@ def __repr__(self): class RectComplex(Rect, complex): pass +class Ratio: + def __init__(self, ratio): + self._ratio = ratio + def as_integer_ratio(self): + return self._ratio + + class FractionTest(unittest.TestCase): def assertTypedEquals(self, expected, actual): @@ -355,14 +362,9 @@ def testInitFromDecimal(self): self.assertRaises(OverflowError, F, Decimal('-inf')) def testInitFromIntegerRatio(self): - class Ratio: - def __init__(self, ratio): - self._ratio = ratio - def as_integer_ratio(self): - return self._ratio - self.assertEqual((7, 3), _components(F(Ratio((7, 3))))) - errmsg = "argument should be a string or a number" + errmsg = (r"argument should be a string or a Rational instance or " + r"have the as_integer_ratio\(\) method") # the type also has an "as_integer_ratio" attribute. self.assertRaisesRegex(TypeError, errmsg, F, Ratio) # bad ratio @@ -388,6 +390,8 @@ class B(metaclass=M): pass self.assertRaisesRegex(TypeError, errmsg, F, B) self.assertRaisesRegex(TypeError, errmsg, F, B()) + self.assertRaises(TypeError, F.from_number, B) + self.assertRaises(TypeError, F.from_number, B()) def testFromString(self): self.assertEqual((5, 1), _components(F("5"))) @@ -594,6 +598,37 @@ def testFromDecimal(self): ValueError, "cannot convert NaN to integer ratio", F.from_decimal, Decimal("snan")) + def testFromNumber(self, cls=F): + def check(arg, numerator, denominator): + f = cls.from_number(arg) + self.assertIs(type(f), cls) + self.assertEqual(f.numerator, numerator) + self.assertEqual(f.denominator, denominator) + + check(10, 10, 1) + check(2.5, 5, 2) + check(Decimal('2.5'), 5, 2) + check(F(22, 7), 22, 7) + check(DummyFraction(22, 7), 22, 7) + check(Rat(22, 7), 22, 7) + check(Ratio((22, 7)), 22, 7) + self.assertRaises(TypeError, cls.from_number, 3+4j) + self.assertRaises(TypeError, cls.from_number, '5/2') + self.assertRaises(TypeError, cls.from_number, []) + self.assertRaises(OverflowError, cls.from_number, float('inf')) + self.assertRaises(OverflowError, cls.from_number, Decimal('inf')) + + # as_integer_ratio not defined in a class + class A: + pass + a = A() + a.as_integer_ratio = lambda: (9, 5) + check(a, 9, 5) + + def testFromNumber_subclass(self): + self.testFromNumber(DummyFraction) + + def test_is_integer(self): self.assertTrue(F(1, 1).is_integer()) self.assertTrue(F(-1, 1).is_integer()) diff --git a/Misc/NEWS.d/next/Library/2024-07-15-19-34-56.gh-issue-121797.qDqj59.rst b/Misc/NEWS.d/next/Library/2024-07-15-19-34-56.gh-issue-121797.qDqj59.rst new file mode 100644 index 00000000000000..9525379587f6cd --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-07-15-19-34-56.gh-issue-121797.qDqj59.rst @@ -0,0 +1,2 @@ +Add alternative :class:`~fractions.Fraction` constructor +:meth:`Fraction.from_number() `. From 4b358ee647809019813f106eb901f466a3846d98 Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Mon, 14 Oct 2024 16:17:51 +0800 Subject: [PATCH 060/170] gh-125323: Remove some unsafe Py_DECREFs in bytecodes.c, replacing them with PyStackRef_CLOSEs (GH-125324) --- Include/internal/pycore_stackref.h | 3 ++ Python/bytecodes.c | 40 +++++++++++----------- Python/executor_cases.c.h | 40 +++++++++++----------- Python/generated_cases.c.h | 40 +++++++++++----------- Tools/cases_generator/analyzer.py | 1 + Tools/cases_generator/generators_common.py | 1 + 6 files changed, 65 insertions(+), 60 deletions(-) diff --git a/Include/internal/pycore_stackref.h b/Include/internal/pycore_stackref.h index 7d1eb11aa5ecb8..0e6410466b924b 100644 --- a/Include/internal/pycore_stackref.h +++ b/Include/internal/pycore_stackref.h @@ -153,6 +153,8 @@ PyStackRef_AsStrongReference(_PyStackRef stackref) return PyStackRef_FromPyObjectSteal(PyStackRef_AsPyObjectSteal(stackref)); } +#define PyStackRef_CLOSE_SPECIALIZED(stackref, dealloc) PyStackRef_CLOSE(stackref) + #else // Py_GIL_DISABLED @@ -177,6 +179,7 @@ static const _PyStackRef PyStackRef_NULL = { .bits = 0 }; #define PyStackRef_DUP(stackref) PyStackRef_FromPyObjectSteal(Py_NewRef(PyStackRef_AsPyObjectBorrow(stackref))) +#define PyStackRef_CLOSE_SPECIALIZED(stackref, dealloc) _Py_DECREF_SPECIALIZED(PyStackRef_AsPyObjectBorrow(stackref), dealloc) #endif // Py_GIL_DISABLED diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 34fdfcb05e3c18..299608f252c546 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -474,8 +474,8 @@ dummy_func( STAT_INC(BINARY_OP, hit); PyObject *res_o = _PyLong_Multiply((PyLongObject *)left_o, (PyLongObject *)right_o); - _Py_DECREF_SPECIALIZED(right_o, (destructor)PyObject_Free); - _Py_DECREF_SPECIALIZED(left_o, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(right, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(left, (destructor)PyObject_Free); INPUTS_DEAD(); ERROR_IF(res_o == NULL, error); res = PyStackRef_FromPyObjectSteal(res_o); @@ -487,8 +487,8 @@ dummy_func( STAT_INC(BINARY_OP, hit); PyObject *res_o = _PyLong_Add((PyLongObject *)left_o, (PyLongObject *)right_o); - _Py_DECREF_SPECIALIZED(right_o, (destructor)PyObject_Free); - _Py_DECREF_SPECIALIZED(left_o, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(right, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(left, (destructor)PyObject_Free); INPUTS_DEAD(); ERROR_IF(res_o == NULL, error); res = PyStackRef_FromPyObjectSteal(res_o); @@ -500,8 +500,8 @@ dummy_func( STAT_INC(BINARY_OP, hit); PyObject *res_o = _PyLong_Subtract((PyLongObject *)left_o, (PyLongObject *)right_o); - _Py_DECREF_SPECIALIZED(right_o, (destructor)PyObject_Free); - _Py_DECREF_SPECIALIZED(left_o, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(right, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(left, (destructor)PyObject_Free); INPUTS_DEAD(); ERROR_IF(res_o == NULL, error); res = PyStackRef_FromPyObjectSteal(res_o); @@ -594,8 +594,8 @@ dummy_func( STAT_INC(BINARY_OP, hit); PyObject *res_o = PyUnicode_Concat(left_o, right_o); - _Py_DECREF_SPECIALIZED(left_o, _PyUnicode_ExactDealloc); - _Py_DECREF_SPECIALIZED(right_o, _PyUnicode_ExactDealloc); + PyStackRef_CLOSE_SPECIALIZED(left, _PyUnicode_ExactDealloc); + PyStackRef_CLOSE_SPECIALIZED(right, _PyUnicode_ExactDealloc); INPUTS_DEAD(); ERROR_IF(res_o == NULL, error); res = PyStackRef_FromPyObjectSteal(res_o); @@ -636,12 +636,12 @@ dummy_func( * that the string is safe to mutate. */ assert(Py_REFCNT(left_o) >= 2); - _Py_DECREF_NO_DEALLOC(left_o); + PyStackRef_CLOSE(left); DEAD(left); PyObject *temp = PyStackRef_AsPyObjectBorrow(*target_local); PyUnicode_Append(&temp, right_o); *target_local = PyStackRef_FromPyObjectSteal(temp); - _Py_DECREF_SPECIALIZED(right_o, _PyUnicode_ExactDealloc); + PyStackRef_CLOSE_SPECIALIZED(right, _PyUnicode_ExactDealloc); DEAD(right); ERROR_IF(PyStackRef_IsNull(*target_local), error); #if TIER_ONE @@ -755,7 +755,7 @@ dummy_func( PyObject *res_o = PyList_GET_ITEM(list, index); assert(res_o != NULL); Py_INCREF(res_o); - _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(sub_st, (destructor)PyObject_Free); DEAD(sub_st); PyStackRef_CLOSE(list_st); res = PyStackRef_FromPyObjectSteal(res_o); @@ -775,7 +775,7 @@ dummy_func( DEOPT_IF(Py_ARRAY_LENGTH(_Py_SINGLETON(strings).ascii) <= c); STAT_INC(BINARY_SUBSCR, hit); PyObject *res_o = (PyObject*)&_Py_SINGLETON(strings).ascii[c]; - _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(sub_st, (destructor)PyObject_Free); DEAD(sub_st); PyStackRef_CLOSE(str_st); res = PyStackRef_FromPyObjectSteal(res_o); @@ -796,7 +796,7 @@ dummy_func( PyObject *res_o = PyTuple_GET_ITEM(tuple, index); assert(res_o != NULL); Py_INCREF(res_o); - _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(sub_st, (destructor)PyObject_Free); DEAD(sub_st); PyStackRef_CLOSE(tuple_st); res = PyStackRef_FromPyObjectSteal(res_o); @@ -908,7 +908,7 @@ dummy_func( PyList_SET_ITEM(list, index, PyStackRef_AsPyObjectSteal(value)); assert(old_value != NULL); Py_DECREF(old_value); - _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(sub_st, (destructor)PyObject_Free); DEAD(sub_st); PyStackRef_CLOSE(list_st); } @@ -2398,9 +2398,9 @@ dummy_func( double dright = PyFloat_AS_DOUBLE(right_o); // 1 if NaN, 2 if <, 4 if >, 8 if ==; this matches low four bits of the oparg int sign_ish = COMPARISON_BIT(dleft, dright); - _Py_DECREF_SPECIALIZED(left_o, _PyFloat_ExactDealloc); + PyStackRef_CLOSE_SPECIALIZED(left, _PyFloat_ExactDealloc); DEAD(left); - _Py_DECREF_SPECIALIZED(right_o, _PyFloat_ExactDealloc); + PyStackRef_CLOSE_SPECIALIZED(right, _PyFloat_ExactDealloc); DEAD(right); res = (sign_ish & oparg) ? PyStackRef_True : PyStackRef_False; // It's always a bool, so we don't care about oparg & 16. @@ -2420,9 +2420,9 @@ dummy_func( Py_ssize_t iright = _PyLong_CompactValue((PyLongObject *)right_o); // 2 if <, 4 if >, 8 if ==; this matches the low 4 bits of the oparg int sign_ish = COMPARISON_BIT(ileft, iright); - _Py_DECREF_SPECIALIZED(left_o, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(left, (destructor)PyObject_Free); DEAD(left); - _Py_DECREF_SPECIALIZED(right_o, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(right, (destructor)PyObject_Free); DEAD(right); res = (sign_ish & oparg) ? PyStackRef_True : PyStackRef_False; // It's always a bool, so we don't care about oparg & 16. @@ -2436,9 +2436,9 @@ dummy_func( STAT_INC(COMPARE_OP, hit); int eq = _PyUnicode_Equal(left_o, right_o); assert((oparg >> 5) == Py_EQ || (oparg >> 5) == Py_NE); - _Py_DECREF_SPECIALIZED(left_o, _PyUnicode_ExactDealloc); + PyStackRef_CLOSE_SPECIALIZED(left, _PyUnicode_ExactDealloc); DEAD(left); - _Py_DECREF_SPECIALIZED(right_o, _PyUnicode_ExactDealloc); + PyStackRef_CLOSE_SPECIALIZED(right, _PyUnicode_ExactDealloc); DEAD(right); assert(eq == 0 || eq == 1); assert((oparg & 0xf) == COMPARISON_NOT_EQUALS || (oparg & 0xf) == COMPARISON_EQUALS); diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index ef110e2e2a794a..5532c04e497a75 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -541,8 +541,8 @@ PyObject *right_o = PyStackRef_AsPyObjectBorrow(right); STAT_INC(BINARY_OP, hit); PyObject *res_o = _PyLong_Multiply((PyLongObject *)left_o, (PyLongObject *)right_o); - _Py_DECREF_SPECIALIZED(right_o, (destructor)PyObject_Free); - _Py_DECREF_SPECIALIZED(left_o, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(right, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(left, (destructor)PyObject_Free); if (res_o == NULL) JUMP_TO_ERROR(); res = PyStackRef_FromPyObjectSteal(res_o); stack_pointer[-2] = res; @@ -561,8 +561,8 @@ PyObject *right_o = PyStackRef_AsPyObjectBorrow(right); STAT_INC(BINARY_OP, hit); PyObject *res_o = _PyLong_Add((PyLongObject *)left_o, (PyLongObject *)right_o); - _Py_DECREF_SPECIALIZED(right_o, (destructor)PyObject_Free); - _Py_DECREF_SPECIALIZED(left_o, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(right, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(left, (destructor)PyObject_Free); if (res_o == NULL) JUMP_TO_ERROR(); res = PyStackRef_FromPyObjectSteal(res_o); stack_pointer[-2] = res; @@ -581,8 +581,8 @@ PyObject *right_o = PyStackRef_AsPyObjectBorrow(right); STAT_INC(BINARY_OP, hit); PyObject *res_o = _PyLong_Subtract((PyLongObject *)left_o, (PyLongObject *)right_o); - _Py_DECREF_SPECIALIZED(right_o, (destructor)PyObject_Free); - _Py_DECREF_SPECIALIZED(left_o, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(right, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(left, (destructor)PyObject_Free); if (res_o == NULL) JUMP_TO_ERROR(); res = PyStackRef_FromPyObjectSteal(res_o); stack_pointer[-2] = res; @@ -722,8 +722,8 @@ PyObject *right_o = PyStackRef_AsPyObjectBorrow(right); STAT_INC(BINARY_OP, hit); PyObject *res_o = PyUnicode_Concat(left_o, right_o); - _Py_DECREF_SPECIALIZED(left_o, _PyUnicode_ExactDealloc); - _Py_DECREF_SPECIALIZED(right_o, _PyUnicode_ExactDealloc); + PyStackRef_CLOSE_SPECIALIZED(left, _PyUnicode_ExactDealloc); + PyStackRef_CLOSE_SPECIALIZED(right, _PyUnicode_ExactDealloc); if (res_o == NULL) JUMP_TO_ERROR(); res = PyStackRef_FromPyObjectSteal(res_o); stack_pointer[-2] = res; @@ -764,11 +764,11 @@ * that the string is safe to mutate. */ assert(Py_REFCNT(left_o) >= 2); - _Py_DECREF_NO_DEALLOC(left_o); + PyStackRef_CLOSE(left); PyObject *temp = PyStackRef_AsPyObjectBorrow(*target_local); PyUnicode_Append(&temp, right_o); *target_local = PyStackRef_FromPyObjectSteal(temp); - _Py_DECREF_SPECIALIZED(right_o, _PyUnicode_ExactDealloc); + PyStackRef_CLOSE_SPECIALIZED(right, _PyUnicode_ExactDealloc); if (PyStackRef_IsNull(*target_local)) JUMP_TO_ERROR(); #if TIER_ONE // The STORE_FAST is already done. This is done here in tier one, @@ -904,7 +904,7 @@ PyObject *res_o = PyList_GET_ITEM(list, index); assert(res_o != NULL); Py_INCREF(res_o); - _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(sub_st, (destructor)PyObject_Free); PyStackRef_CLOSE(list_st); res = PyStackRef_FromPyObjectSteal(res_o); stack_pointer[-2] = res; @@ -946,7 +946,7 @@ } STAT_INC(BINARY_SUBSCR, hit); PyObject *res_o = (PyObject*)&_Py_SINGLETON(strings).ascii[c]; - _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(sub_st, (destructor)PyObject_Free); PyStackRef_CLOSE(str_st); res = PyStackRef_FromPyObjectSteal(res_o); stack_pointer[-2] = res; @@ -985,7 +985,7 @@ PyObject *res_o = PyTuple_GET_ITEM(tuple, index); assert(res_o != NULL); Py_INCREF(res_o); - _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(sub_st, (destructor)PyObject_Free); PyStackRef_CLOSE(tuple_st); res = PyStackRef_FromPyObjectSteal(res_o); stack_pointer[-2] = res; @@ -1160,7 +1160,7 @@ PyList_SET_ITEM(list, index, PyStackRef_AsPyObjectSteal(value)); assert(old_value != NULL); Py_DECREF(old_value); - _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(sub_st, (destructor)PyObject_Free); PyStackRef_CLOSE(list_st); stack_pointer += -3; assert(WITHIN_STACK_BOUNDS()); @@ -2912,8 +2912,8 @@ double dright = PyFloat_AS_DOUBLE(right_o); // 1 if NaN, 2 if <, 4 if >, 8 if ==; this matches low four bits of the oparg int sign_ish = COMPARISON_BIT(dleft, dright); - _Py_DECREF_SPECIALIZED(left_o, _PyFloat_ExactDealloc); - _Py_DECREF_SPECIALIZED(right_o, _PyFloat_ExactDealloc); + PyStackRef_CLOSE_SPECIALIZED(left, _PyFloat_ExactDealloc); + PyStackRef_CLOSE_SPECIALIZED(right, _PyFloat_ExactDealloc); res = (sign_ish & oparg) ? PyStackRef_True : PyStackRef_False; // It's always a bool, so we don't care about oparg & 16. stack_pointer[-2] = res; @@ -2946,8 +2946,8 @@ Py_ssize_t iright = _PyLong_CompactValue((PyLongObject *)right_o); // 2 if <, 4 if >, 8 if ==; this matches the low 4 bits of the oparg int sign_ish = COMPARISON_BIT(ileft, iright); - _Py_DECREF_SPECIALIZED(left_o, (destructor)PyObject_Free); - _Py_DECREF_SPECIALIZED(right_o, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(left, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(right, (destructor)PyObject_Free); res = (sign_ish & oparg) ? PyStackRef_True : PyStackRef_False; // It's always a bool, so we don't care about oparg & 16. stack_pointer[-2] = res; @@ -2968,8 +2968,8 @@ STAT_INC(COMPARE_OP, hit); int eq = _PyUnicode_Equal(left_o, right_o); assert((oparg >> 5) == Py_EQ || (oparg >> 5) == Py_NE); - _Py_DECREF_SPECIALIZED(left_o, _PyUnicode_ExactDealloc); - _Py_DECREF_SPECIALIZED(right_o, _PyUnicode_ExactDealloc); + PyStackRef_CLOSE_SPECIALIZED(left, _PyUnicode_ExactDealloc); + PyStackRef_CLOSE_SPECIALIZED(right, _PyUnicode_ExactDealloc); assert(eq == 0 || eq == 1); assert((oparg & 0xf) == COMPARISON_NOT_EQUALS || (oparg & 0xf) == COMPARISON_EQUALS); assert(COMPARISON_NOT_EQUALS + 1 == COMPARISON_EQUALS); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 7023aea369db49..0eeb566a0adadc 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -118,8 +118,8 @@ PyObject *right_o = PyStackRef_AsPyObjectBorrow(right); STAT_INC(BINARY_OP, hit); PyObject *res_o = _PyLong_Add((PyLongObject *)left_o, (PyLongObject *)right_o); - _Py_DECREF_SPECIALIZED(right_o, (destructor)PyObject_Free); - _Py_DECREF_SPECIALIZED(left_o, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(right, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(left, (destructor)PyObject_Free); if (res_o == NULL) goto pop_2_error; res = PyStackRef_FromPyObjectSteal(res_o); } @@ -153,8 +153,8 @@ PyObject *right_o = PyStackRef_AsPyObjectBorrow(right); STAT_INC(BINARY_OP, hit); PyObject *res_o = PyUnicode_Concat(left_o, right_o); - _Py_DECREF_SPECIALIZED(left_o, _PyUnicode_ExactDealloc); - _Py_DECREF_SPECIALIZED(right_o, _PyUnicode_ExactDealloc); + PyStackRef_CLOSE_SPECIALIZED(left, _PyUnicode_ExactDealloc); + PyStackRef_CLOSE_SPECIALIZED(right, _PyUnicode_ExactDealloc); if (res_o == NULL) goto pop_2_error; res = PyStackRef_FromPyObjectSteal(res_o); } @@ -207,11 +207,11 @@ * that the string is safe to mutate. */ assert(Py_REFCNT(left_o) >= 2); - _Py_DECREF_NO_DEALLOC(left_o); + PyStackRef_CLOSE(left); PyObject *temp = PyStackRef_AsPyObjectBorrow(*target_local); PyUnicode_Append(&temp, right_o); *target_local = PyStackRef_FromPyObjectSteal(temp); - _Py_DECREF_SPECIALIZED(right_o, _PyUnicode_ExactDealloc); + PyStackRef_CLOSE_SPECIALIZED(right, _PyUnicode_ExactDealloc); if (PyStackRef_IsNull(*target_local)) goto pop_2_error; #if TIER_ONE // The STORE_FAST is already done. This is done here in tier one, @@ -285,8 +285,8 @@ PyObject *right_o = PyStackRef_AsPyObjectBorrow(right); STAT_INC(BINARY_OP, hit); PyObject *res_o = _PyLong_Multiply((PyLongObject *)left_o, (PyLongObject *)right_o); - _Py_DECREF_SPECIALIZED(right_o, (destructor)PyObject_Free); - _Py_DECREF_SPECIALIZED(left_o, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(right, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(left, (destructor)PyObject_Free); if (res_o == NULL) goto pop_2_error; res = PyStackRef_FromPyObjectSteal(res_o); } @@ -356,8 +356,8 @@ PyObject *right_o = PyStackRef_AsPyObjectBorrow(right); STAT_INC(BINARY_OP, hit); PyObject *res_o = _PyLong_Subtract((PyLongObject *)left_o, (PyLongObject *)right_o); - _Py_DECREF_SPECIALIZED(right_o, (destructor)PyObject_Free); - _Py_DECREF_SPECIALIZED(left_o, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(right, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(left, (destructor)PyObject_Free); if (res_o == NULL) goto pop_2_error; res = PyStackRef_FromPyObjectSteal(res_o); } @@ -582,7 +582,7 @@ PyObject *res_o = PyList_GET_ITEM(list, index); assert(res_o != NULL); Py_INCREF(res_o); - _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(sub_st, (destructor)PyObject_Free); PyStackRef_CLOSE(list_st); res = PyStackRef_FromPyObjectSteal(res_o); stack_pointer[-2] = res; @@ -614,7 +614,7 @@ DEOPT_IF(Py_ARRAY_LENGTH(_Py_SINGLETON(strings).ascii) <= c, BINARY_SUBSCR); STAT_INC(BINARY_SUBSCR, hit); PyObject *res_o = (PyObject*)&_Py_SINGLETON(strings).ascii[c]; - _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(sub_st, (destructor)PyObject_Free); PyStackRef_CLOSE(str_st); res = PyStackRef_FromPyObjectSteal(res_o); stack_pointer[-2] = res; @@ -646,7 +646,7 @@ PyObject *res_o = PyTuple_GET_ITEM(tuple, index); assert(res_o != NULL); Py_INCREF(res_o); - _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(sub_st, (destructor)PyObject_Free); PyStackRef_CLOSE(tuple_st); res = PyStackRef_FromPyObjectSteal(res_o); stack_pointer[-2] = res; @@ -3284,8 +3284,8 @@ double dright = PyFloat_AS_DOUBLE(right_o); // 1 if NaN, 2 if <, 4 if >, 8 if ==; this matches low four bits of the oparg int sign_ish = COMPARISON_BIT(dleft, dright); - _Py_DECREF_SPECIALIZED(left_o, _PyFloat_ExactDealloc); - _Py_DECREF_SPECIALIZED(right_o, _PyFloat_ExactDealloc); + PyStackRef_CLOSE_SPECIALIZED(left, _PyFloat_ExactDealloc); + PyStackRef_CLOSE_SPECIALIZED(right, _PyFloat_ExactDealloc); res = (sign_ish & oparg) ? PyStackRef_True : PyStackRef_False; // It's always a bool, so we don't care about oparg & 16. } @@ -3326,8 +3326,8 @@ Py_ssize_t iright = _PyLong_CompactValue((PyLongObject *)right_o); // 2 if <, 4 if >, 8 if ==; this matches the low 4 bits of the oparg int sign_ish = COMPARISON_BIT(ileft, iright); - _Py_DECREF_SPECIALIZED(left_o, (destructor)PyObject_Free); - _Py_DECREF_SPECIALIZED(right_o, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(left, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(right, (destructor)PyObject_Free); res = (sign_ish & oparg) ? PyStackRef_True : PyStackRef_False; // It's always a bool, so we don't care about oparg & 16. } @@ -3362,8 +3362,8 @@ STAT_INC(COMPARE_OP, hit); int eq = _PyUnicode_Equal(left_o, right_o); assert((oparg >> 5) == Py_EQ || (oparg >> 5) == Py_NE); - _Py_DECREF_SPECIALIZED(left_o, _PyUnicode_ExactDealloc); - _Py_DECREF_SPECIALIZED(right_o, _PyUnicode_ExactDealloc); + PyStackRef_CLOSE_SPECIALIZED(left, _PyUnicode_ExactDealloc); + PyStackRef_CLOSE_SPECIALIZED(right, _PyUnicode_ExactDealloc); assert(eq == 0 || eq == 1); assert((oparg & 0xf) == COMPARISON_NOT_EQUALS || (oparg & 0xf) == COMPARISON_EQUALS); assert(COMPARISON_NOT_EQUALS + 1 == COMPARISON_EQUALS); @@ -7720,7 +7720,7 @@ PyList_SET_ITEM(list, index, PyStackRef_AsPyObjectSteal(value)); assert(old_value != NULL); Py_DECREF(old_value); - _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); + PyStackRef_CLOSE_SPECIALIZED(sub_st, (destructor)PyObject_Free); PyStackRef_CLOSE(list_st); stack_pointer += -3; assert(WITHIN_STACK_BOUNDS()); diff --git a/Tools/cases_generator/analyzer.py b/Tools/cases_generator/analyzer.py index 60f5d010a7a083..19fdeac65cf2df 100644 --- a/Tools/cases_generator/analyzer.py +++ b/Tools/cases_generator/analyzer.py @@ -540,6 +540,7 @@ def has_error_without_pop(op: parser.InstDef) -> bool: "PyStackRef_AsPyObjectSteal", "PyStackRef_CLEAR", "PyStackRef_CLOSE", + "PyStackRef_CLOSE_SPECIALIZED", "PyStackRef_DUP", "PyStackRef_False", "PyStackRef_FromPyObjectImmortal", diff --git a/Tools/cases_generator/generators_common.py b/Tools/cases_generator/generators_common.py index 0bfa1a3b56fbc2..7e032c21d2485c 100644 --- a/Tools/cases_generator/generators_common.py +++ b/Tools/cases_generator/generators_common.py @@ -116,6 +116,7 @@ def __init__(self, out: CWriter): "SAVE_STACK": self.save_stack, "RELOAD_STACK": self.reload_stack, "PyStackRef_CLOSE": self.stackref_close, + "PyStackRef_CLOSE_SPECIALIZED": self.stackref_close, "PyStackRef_AsPyObjectSteal": self.stackref_steal, "DISPATCH": self.dispatch } From 5217328f93f599755bd70418952392c54f705a71 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 14 Oct 2024 11:24:01 +0300 Subject: [PATCH 061/170] gh-121798: Add class method Decimal.from_number() (GH-121801) It is an alternate constructor which only accepts a single numeric argument. Unlike to Decimal.from_float() it accepts also Decimal. Unlike to the standard constructor, it does not accept strings and tuples. --- Doc/library/decimal.rst | 17 +++++++ Doc/whatsnew/3.14.rst | 6 +++ Lib/_pydecimal.py | 15 ++++++ Lib/test/test_decimal.py | 23 ++++++++++ ...-07-15-19-25-25.gh-issue-121798.GmuBDu.rst | 2 + Modules/_decimal/_decimal.c | 46 +++++++++++++++++++ Modules/_decimal/docstrings.h | 13 ++++++ 7 files changed, 122 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2024-07-15-19-25-25.gh-issue-121798.GmuBDu.rst diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst index 916f17cadfaa7e..c9a3e448cad063 100644 --- a/Doc/library/decimal.rst +++ b/Doc/library/decimal.rst @@ -598,6 +598,23 @@ Decimal objects .. versionadded:: 3.1 + .. classmethod:: from_number(number) + + Alternative constructor that only accepts instances of + :class:`float`, :class:`int` or :class:`Decimal`, but not strings + or tuples. + + .. doctest:: + + >>> Decimal.from_number(314) + Decimal('314') + >>> Decimal.from_number(0.1) + Decimal('0.1000000000000000055511151231257827021181583404541015625') + >>> Decimal.from_number(Decimal('3.14')) + Decimal('3.14') + + .. versionadded:: 3.14 + .. method:: fma(other, third, context=None) Fused multiply-add. Return self*other+third with no rounding of the diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index b22d1bd1e99d4e..25e69a59bdec62 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -239,6 +239,12 @@ ctypes to help match a non-default ABI. (Contributed by Petr Viktorin in :gh:`97702`.) +decimal +------- + +* Add alternative :class:`~decimal.Decimal` constructor + :meth:`Decimal.from_number() `. + (Contributed by Serhiy Storchaka in :gh:`121798`.) dis --- diff --git a/Lib/_pydecimal.py b/Lib/_pydecimal.py index 75df3db262470b..5b60570c6c592a 100644 --- a/Lib/_pydecimal.py +++ b/Lib/_pydecimal.py @@ -582,6 +582,21 @@ def __new__(cls, value="0", context=None): raise TypeError("Cannot convert %r to Decimal" % value) + @classmethod + def from_number(cls, number): + """Converts a real number to a decimal number, exactly. + + >>> Decimal.from_number(314) # int + Decimal('314') + >>> Decimal.from_number(0.1) # float + Decimal('0.1000000000000000055511151231257827021181583404541015625') + >>> Decimal.from_number(Decimal('3.14')) # another decimal instance + Decimal('3.14') + """ + if isinstance(number, (int, Decimal, float)): + return cls(number) + raise TypeError("Cannot convert %r to Decimal" % number) + @classmethod def from_float(cls, f): """Converts a float to a decimal number, exactly. diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index d1e7e69e7e951b..bc6c6427740949 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -812,6 +812,29 @@ def test_explicit_context_create_from_float(self): x = random.expovariate(0.01) * (random.random() * 2.0 - 1.0) self.assertEqual(x, float(nc.create_decimal(x))) # roundtrip + def test_from_number(self, cls=None): + Decimal = self.decimal.Decimal + if cls is None: + cls = Decimal + + def check(arg, expected): + d = cls.from_number(arg) + self.assertIs(type(d), cls) + self.assertEqual(d, expected) + + check(314, Decimal(314)) + check(3.14, Decimal.from_float(3.14)) + check(Decimal('3.14'), Decimal('3.14')) + self.assertRaises(TypeError, cls.from_number, 3+4j) + self.assertRaises(TypeError, cls.from_number, '314') + self.assertRaises(TypeError, cls.from_number, (0, (3, 1, 4), 0)) + self.assertRaises(TypeError, cls.from_number, object()) + + def test_from_number_subclass(self, cls=None): + class DecimalSubclass(self.decimal.Decimal): + pass + self.test_from_number(DecimalSubclass) + def test_unicode_digits(self): Decimal = self.decimal.Decimal diff --git a/Misc/NEWS.d/next/Library/2024-07-15-19-25-25.gh-issue-121798.GmuBDu.rst b/Misc/NEWS.d/next/Library/2024-07-15-19-25-25.gh-issue-121798.GmuBDu.rst new file mode 100644 index 00000000000000..5706e4bffeb4a1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-07-15-19-25-25.gh-issue-121798.GmuBDu.rst @@ -0,0 +1,2 @@ +Add alternative :class:`~decimal.Decimal` constructor +:meth:`Decimal.from_number() `. diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index a33c9793b5ad17..c564813036e504 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -2857,6 +2857,51 @@ dec_from_float(PyObject *type, PyObject *pyfloat) return result; } +/* 'v' can have any numeric type accepted by the Decimal constructor. Attempt + an exact conversion. If the result does not meet the restrictions + for an mpd_t, fail with InvalidOperation. */ +static PyObject * +PyDecType_FromNumberExact(PyTypeObject *type, PyObject *v, PyObject *context) +{ + decimal_state *state = get_module_state_by_def(type); + assert(v != NULL); + if (PyDec_Check(state, v)) { + return PyDecType_FromDecimalExact(type, v, context); + } + else if (PyLong_Check(v)) { + return PyDecType_FromLongExact(type, v, context); + } + else if (PyFloat_Check(v)) { + if (dec_addstatus(context, MPD_Float_operation)) { + return NULL; + } + return PyDecType_FromFloatExact(type, v, context); + } + else { + PyErr_Format(PyExc_TypeError, + "conversion from %s to Decimal is not supported", + Py_TYPE(v)->tp_name); + return NULL; + } +} + +/* class method */ +static PyObject * +dec_from_number(PyObject *type, PyObject *number) +{ + PyObject *context; + PyObject *result; + + decimal_state *state = get_module_state_by_def((PyTypeObject *)type); + CURRENT_CONTEXT(state, context); + result = PyDecType_FromNumberExact(state->PyDec_Type, number, context); + if (type != (PyObject *)state->PyDec_Type && result != NULL) { + Py_SETREF(result, PyObject_CallFunctionObjArgs(type, result, NULL)); + } + + return result; +} + /* create_decimal_from_float */ static PyObject * ctx_from_float(PyObject *context, PyObject *v) @@ -5052,6 +5097,7 @@ static PyMethodDef dec_methods [] = /* Miscellaneous */ { "from_float", dec_from_float, METH_O|METH_CLASS, doc_from_float }, + { "from_number", dec_from_number, METH_O|METH_CLASS, doc_from_number }, { "as_tuple", PyDec_AsTuple, METH_NOARGS, doc_as_tuple }, { "as_integer_ratio", dec_as_integer_ratio, METH_NOARGS, doc_as_integer_ratio }, diff --git a/Modules/_decimal/docstrings.h b/Modules/_decimal/docstrings.h index a1823cdd32b74c..b34bff83d3f4e9 100644 --- a/Modules/_decimal/docstrings.h +++ b/Modules/_decimal/docstrings.h @@ -189,6 +189,19 @@ Decimal.from_float(0.1) is not the same as Decimal('0.1').\n\ \n\ \n"); +PyDoc_STRVAR(doc_from_number, +"from_number($type, number, /)\n--\n\n\ +Class method that converts a real number to a decimal number, exactly.\n\ +\n\ + >>> Decimal.from_number(314) # int\n\ + Decimal('314')\n\ + >>> Decimal.from_number(0.1) # float\n\ + Decimal('0.1000000000000000055511151231257827021181583404541015625')\n\ + >>> Decimal.from_number(Decimal('3.14')) # another decimal instance\n\ + Decimal('3.14')\n\ +\n\ +\n"); + PyDoc_STRVAR(doc_fma, "fma($self, /, other, third, context=None)\n--\n\n\ Fused multiply-add. Return self*other+third with no rounding of the\n\ From 67f6e08147bc005e460d82fcce85bf5d56009cf5 Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Mon, 14 Oct 2024 14:06:31 +0530 Subject: [PATCH 062/170] gh-125139: use `_PyRecursiveMutex` in `_thread.RLock` (#125144) --- Include/internal/pycore_lock.h | 3 +- Modules/_threadmodule.c | 151 +++++++-------------------------- Python/lock.c | 31 ++++++- 3 files changed, 63 insertions(+), 122 deletions(-) diff --git a/Include/internal/pycore_lock.h b/Include/internal/pycore_lock.h index cd7deda00c7bee..57cbce8f126aca 100644 --- a/Include/internal/pycore_lock.h +++ b/Include/internal/pycore_lock.h @@ -160,8 +160,9 @@ typedef struct { PyAPI_FUNC(int) _PyRecursiveMutex_IsLockedByCurrentThread(_PyRecursiveMutex *m); PyAPI_FUNC(void) _PyRecursiveMutex_Lock(_PyRecursiveMutex *m); +extern PyLockStatus _PyRecursiveMutex_LockTimed(_PyRecursiveMutex *m, PyTime_t timeout, _PyLockFlags flags); PyAPI_FUNC(void) _PyRecursiveMutex_Unlock(_PyRecursiveMutex *m); - +extern int _PyRecursiveMutex_TryUnlock(_PyRecursiveMutex *m); // A readers-writer (RW) lock. The lock supports multiple concurrent readers or // a single writer. The lock is write-preferring: if a writer is waiting while diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index 9617f9cafe76ff..d4408aa9e42d9d 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -726,11 +726,6 @@ lock_dealloc(PyObject *op) Py_DECREF(tp); } -static inline PyLockStatus -acquire_timed(PyThread_type_lock lock, PyTime_t timeout) -{ - return PyThread_acquire_lock_timed_with_retries(lock, timeout); -} static int lock_acquire_parse_args(PyObject *args, PyObject *kwds, @@ -973,10 +968,7 @@ static PyType_Spec lock_type_spec = { typedef struct { PyObject_HEAD - PyThread_type_lock rlock_lock; - PyThread_ident_t rlock_owner; - unsigned long rlock_count; - PyObject *in_weakreflist; + _PyRecursiveMutex lock; } rlockobject; static int @@ -992,59 +984,26 @@ rlock_dealloc(PyObject *op) { rlockobject *self = (rlockobject*)op; PyObject_GC_UnTrack(self); - if (self->in_weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) self); - /* self->rlock_lock can be NULL if PyThread_allocate_lock() failed - in rlock_new() */ - if (self->rlock_lock != NULL) { - /* Unlock the lock so it's safe to free it */ - if (self->rlock_count > 0) - PyThread_release_lock(self->rlock_lock); - - PyThread_free_lock(self->rlock_lock); - } + PyObject_ClearWeakRefs((PyObject *) self); PyTypeObject *tp = Py_TYPE(self); tp->tp_free(self); Py_DECREF(tp); } -static bool -rlock_is_owned_by(rlockobject *self, PyThread_ident_t tid) -{ - PyThread_ident_t owner_tid = - _Py_atomic_load_ullong_relaxed(&self->rlock_owner); - return owner_tid == tid && self->rlock_count > 0; -} static PyObject * rlock_acquire(PyObject *op, PyObject *args, PyObject *kwds) { rlockobject *self = (rlockobject*)op; PyTime_t timeout; - PyThread_ident_t tid; - PyLockStatus r = PY_LOCK_ACQUIRED; - if (lock_acquire_parse_args(args, kwds, &timeout) < 0) + if (lock_acquire_parse_args(args, kwds, &timeout) < 0) { return NULL; - - tid = PyThread_get_thread_ident_ex(); - if (rlock_is_owned_by(self, tid)) { - unsigned long count = self->rlock_count + 1; - if (count <= self->rlock_count) { - PyErr_SetString(PyExc_OverflowError, - "Internal lock count overflowed"); - return NULL; - } - self->rlock_count = count; - Py_RETURN_TRUE; - } - r = acquire_timed(self->rlock_lock, timeout); - if (r == PY_LOCK_ACQUIRED) { - assert(self->rlock_count == 0); - _Py_atomic_store_ullong_relaxed(&self->rlock_owner, tid); - self->rlock_count = 1; } - else if (r == PY_LOCK_INTR) { + + PyLockStatus r = _PyRecursiveMutex_LockTimed(&self->lock, timeout, + _PY_LOCK_HANDLE_SIGNALS | _PY_LOCK_DETACH); + if (r == PY_LOCK_INTR) { return NULL; } @@ -1078,17 +1037,12 @@ static PyObject * rlock_release(PyObject *op, PyObject *Py_UNUSED(ignored)) { rlockobject *self = (rlockobject*)op; - PyThread_ident_t tid = PyThread_get_thread_ident_ex(); - if (!rlock_is_owned_by(self, tid)) { + if (_PyRecursiveMutex_TryUnlock(&self->lock) < 0) { PyErr_SetString(PyExc_RuntimeError, "cannot release un-acquired lock"); return NULL; } - if (--self->rlock_count == 0) { - _Py_atomic_store_ullong_relaxed(&self->rlock_owner, 0); - PyThread_release_lock(self->rlock_lock); - } Py_RETURN_NONE; } @@ -1116,25 +1070,15 @@ rlock_acquire_restore(PyObject *op, PyObject *args) { rlockobject *self = (rlockobject*)op; PyThread_ident_t owner; - unsigned long count; - int r = 1; + Py_ssize_t count; - if (!PyArg_ParseTuple(args, "(k" Py_PARSE_THREAD_IDENT_T "):_acquire_restore", + if (!PyArg_ParseTuple(args, "(n" Py_PARSE_THREAD_IDENT_T "):_acquire_restore", &count, &owner)) return NULL; - if (!PyThread_acquire_lock(self->rlock_lock, 0)) { - Py_BEGIN_ALLOW_THREADS - r = PyThread_acquire_lock(self->rlock_lock, 1); - Py_END_ALLOW_THREADS - } - if (!r) { - PyErr_SetString(ThreadError, "couldn't acquire lock"); - return NULL; - } - assert(self->rlock_count == 0); - _Py_atomic_store_ullong_relaxed(&self->rlock_owner, owner); - self->rlock_count = count; + _PyRecursiveMutex_Lock(&self->lock); + _Py_atomic_store_ullong_relaxed(&self->lock.thread, owner); + self->lock.level = (size_t)count - 1; Py_RETURN_NONE; } @@ -1148,21 +1092,18 @@ static PyObject * rlock_release_save(PyObject *op, PyObject *Py_UNUSED(ignored)) { rlockobject *self = (rlockobject*)op; - PyThread_ident_t owner; - unsigned long count; - if (self->rlock_count == 0) { + if (!_PyRecursiveMutex_IsLockedByCurrentThread(&self->lock)) { PyErr_SetString(PyExc_RuntimeError, "cannot release un-acquired lock"); return NULL; } - owner = self->rlock_owner; - count = self->rlock_count; - self->rlock_count = 0; - _Py_atomic_store_ullong_relaxed(&self->rlock_owner, 0); - PyThread_release_lock(self->rlock_lock); - return Py_BuildValue("k" Py_PARSE_THREAD_IDENT_T, count, owner); + PyThread_ident_t owner = self->lock.thread; + Py_ssize_t count = self->lock.level + 1; + self->lock.level = 0; // ensure the unlock releases the lock + _PyRecursiveMutex_Unlock(&self->lock); + return Py_BuildValue("n" Py_PARSE_THREAD_IDENT_T, count, owner); } PyDoc_STRVAR(rlock_release_save_doc, @@ -1175,10 +1116,10 @@ static PyObject * rlock_recursion_count(PyObject *op, PyObject *Py_UNUSED(ignored)) { rlockobject *self = (rlockobject*)op; - PyThread_ident_t tid = PyThread_get_thread_ident_ex(); - PyThread_ident_t owner = - _Py_atomic_load_ullong_relaxed(&self->rlock_owner); - return PyLong_FromUnsignedLong(owner == tid ? self->rlock_count : 0UL); + if (_PyRecursiveMutex_IsLockedByCurrentThread(&self->lock)) { + return PyLong_FromSize_t(self->lock.level + 1); + } + return PyLong_FromLong(0); } PyDoc_STRVAR(rlock_recursion_count_doc, @@ -1191,12 +1132,8 @@ static PyObject * rlock_is_owned(PyObject *op, PyObject *Py_UNUSED(ignored)) { rlockobject *self = (rlockobject*)op; - PyThread_ident_t tid = PyThread_get_thread_ident_ex(); - - if (rlock_is_owned_by(self, tid)) { - Py_RETURN_TRUE; - } - Py_RETURN_FALSE; + long owned = _PyRecursiveMutex_IsLockedByCurrentThread(&self->lock); + return PyBool_FromLong(owned); } PyDoc_STRVAR(rlock_is_owned_doc, @@ -1212,16 +1149,7 @@ rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (self == NULL) { return NULL; } - self->in_weakreflist = NULL; - self->rlock_owner = 0; - self->rlock_count = 0; - - self->rlock_lock = PyThread_allocate_lock(); - if (self->rlock_lock == NULL) { - Py_DECREF(self); - PyErr_SetString(ThreadError, "can't allocate lock"); - return NULL; - } + self->lock = (_PyRecursiveMutex){0}; return (PyObject *) self; } @@ -1229,13 +1157,13 @@ static PyObject * rlock_repr(PyObject *op) { rlockobject *self = (rlockobject*)op; - PyThread_ident_t owner = - _Py_atomic_load_ullong_relaxed(&self->rlock_owner); + PyThread_ident_t owner = self->lock.thread; + size_t count = self->lock.level + 1; return PyUnicode_FromFormat( - "<%s %s object owner=%" PY_FORMAT_THREAD_IDENT_T " count=%lu at %p>", - self->rlock_count ? "locked" : "unlocked", + "<%s %s object owner=%" PY_FORMAT_THREAD_IDENT_T " count=%zu at %p>", + owner ? "locked" : "unlocked", Py_TYPE(self)->tp_name, owner, - self->rlock_count, self); + count, self); } @@ -1243,14 +1171,7 @@ rlock_repr(PyObject *op) static PyObject * rlock__at_fork_reinit(rlockobject *self, PyObject *Py_UNUSED(args)) { - if (_PyThread_at_fork_reinit(&self->rlock_lock) < 0) { - PyErr_SetString(ThreadError, "failed to reinitialize lock at fork"); - return NULL; - } - - self->rlock_owner = 0; - self->rlock_count = 0; - + self->lock = (_PyRecursiveMutex){0}; Py_RETURN_NONE; } #endif /* HAVE_FORK */ @@ -1281,18 +1202,12 @@ static PyMethodDef rlock_methods[] = { }; -static PyMemberDef rlock_type_members[] = { - {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(rlockobject, in_weakreflist), Py_READONLY}, - {NULL}, -}; - static PyType_Slot rlock_type_slots[] = { {Py_tp_dealloc, rlock_dealloc}, {Py_tp_repr, rlock_repr}, {Py_tp_methods, rlock_methods}, {Py_tp_alloc, PyType_GenericAlloc}, {Py_tp_new, rlock_new}, - {Py_tp_members, rlock_type_members}, {Py_tp_traverse, rlock_traverse}, {0, 0}, }; @@ -1301,7 +1216,7 @@ static PyType_Spec rlock_type_spec = { .name = "_thread.RLock", .basicsize = sizeof(rlockobject), .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE), + Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_MANAGED_WEAKREF), .slots = rlock_type_slots, }; diff --git a/Python/lock.c b/Python/lock.c index 57675fe1873fa2..554c51d7780322 100644 --- a/Python/lock.c +++ b/Python/lock.c @@ -377,21 +377,46 @@ _PyRecursiveMutex_Lock(_PyRecursiveMutex *m) assert(m->level == 0); } +PyLockStatus +_PyRecursiveMutex_LockTimed(_PyRecursiveMutex *m, PyTime_t timeout, _PyLockFlags flags) +{ + PyThread_ident_t thread = PyThread_get_thread_ident_ex(); + if (recursive_mutex_is_owned_by(m, thread)) { + m->level++; + return PY_LOCK_ACQUIRED; + } + PyLockStatus s = _PyMutex_LockTimed(&m->mutex, timeout, flags); + if (s == PY_LOCK_ACQUIRED) { + _Py_atomic_store_ullong_relaxed(&m->thread, thread); + assert(m->level == 0); + } + return s; +} + void _PyRecursiveMutex_Unlock(_PyRecursiveMutex *m) +{ + if (_PyRecursiveMutex_TryUnlock(m) < 0) { + Py_FatalError("unlocking a recursive mutex that is not " + "owned by the current thread"); + } +} + +int +_PyRecursiveMutex_TryUnlock(_PyRecursiveMutex *m) { PyThread_ident_t thread = PyThread_get_thread_ident_ex(); if (!recursive_mutex_is_owned_by(m, thread)) { - Py_FatalError("unlocking a recursive mutex that is not owned by the" - " current thread"); + return -1; } if (m->level > 0) { m->level--; - return; + return 0; } assert(m->level == 0); _Py_atomic_store_ullong_relaxed(&m->thread, 0); PyMutex_Unlock(&m->mutex); + return 0; } #define _Py_WRITE_LOCKED 1 From 06ca33020e1168459fc6c3e0df93664daf801339 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 14 Oct 2024 14:18:57 +0100 Subject: [PATCH 063/170] GH-125323: Convert DECREF_INPUTS_AND_REUSE_FLOAT into a function that takes PyStackRefs. (GH-125439) --- Include/internal/pycore_ceval.h | 2 ++ Include/internal/pycore_opcode_metadata.h | 6 ++-- Include/internal/pycore_stackref.h | 7 +++++ Include/internal/pycore_uop_metadata.h | 6 ++-- Objects/floatobject.c | 35 +++++++++++++++++++++++ Python/bytecodes.c | 12 ++++---- Python/ceval_macros.h | 20 ------------- Python/executor_cases.c.h | 12 ++++---- Python/generated_cases.c.h | 12 ++++---- Tools/cases_generator/analyzer.py | 1 + 10 files changed, 69 insertions(+), 44 deletions(-) diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 594fbb1c8e443b..cff2b1f7114793 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -316,6 +316,8 @@ _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(PyObject *) _PyFloat_FromDouble_ConsumeInputs(_PyStackRef left, _PyStackRef right, double value); + #ifdef __cplusplus } diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index 8fec45b1e8d5c3..c18423476d3962 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -1015,13 +1015,13 @@ extern const struct opcode_metadata _PyOpcode_opcode_metadata[266]; #ifdef NEED_OPCODE_METADATA const struct opcode_metadata _PyOpcode_opcode_metadata[266] = { [BINARY_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, - [BINARY_OP_ADD_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG }, + [BINARY_OP_ADD_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG }, [BINARY_OP_ADD_INT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG }, [BINARY_OP_ADD_UNICODE] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG }, [BINARY_OP_INPLACE_ADD_UNICODE] = { true, INSTR_FMT_IXC, HAS_LOCAL_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG }, - [BINARY_OP_MULTIPLY_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG }, + [BINARY_OP_MULTIPLY_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG }, [BINARY_OP_MULTIPLY_INT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG }, - [BINARY_OP_SUBTRACT_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG }, + [BINARY_OP_SUBTRACT_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG }, [BINARY_OP_SUBTRACT_INT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG }, [BINARY_SLICE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [BINARY_SUBSCR] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, diff --git a/Include/internal/pycore_stackref.h b/Include/internal/pycore_stackref.h index 0e6410466b924b..588e57f6cd97e0 100644 --- a/Include/internal/pycore_stackref.h +++ b/Include/internal/pycore_stackref.h @@ -76,6 +76,13 @@ PyStackRef_AsPyObjectBorrow(_PyStackRef stackref) #define PyStackRef_IsDeferred(ref) (((ref).bits & Py_TAG_BITS) == Py_TAG_DEFERRED) +static inline PyObject * +PyStackRef_NotDeferred_AsPyObject(_PyStackRef stackref) +{ + assert(!PyStackRef_IsDeferred(stackref)); + return (PyObject *)stackref.bits; +} + static inline PyObject * PyStackRef_AsPyObjectSteal(_PyStackRef stackref) { diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index fd41e9a5fe862b..2f0a7fb2f6e549 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -69,9 +69,9 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = { [_GUARD_BOTH_FLOAT] = HAS_EXIT_FLAG, [_GUARD_NOS_FLOAT] = HAS_EXIT_FLAG, [_GUARD_TOS_FLOAT] = HAS_EXIT_FLAG, - [_BINARY_OP_MULTIPLY_FLOAT] = HAS_PURE_FLAG, - [_BINARY_OP_ADD_FLOAT] = HAS_PURE_FLAG, - [_BINARY_OP_SUBTRACT_FLOAT] = HAS_PURE_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, [_GUARD_BOTH_UNICODE] = HAS_EXIT_FLAG, [_BINARY_OP_ADD_UNICODE] = HAS_ERROR_FLAG | HAS_PURE_FLAG, [_BINARY_OP_INPLACE_ADD_UNICODE] = HAS_LOCAL_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG, diff --git a/Objects/floatobject.c b/Objects/floatobject.c index a48a210adee3b9..d66863febe8c86 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -134,6 +134,41 @@ PyFloat_FromDouble(double fval) return (PyObject *) op; } +#ifdef Py_GIL_DISABLED + +PyObject *_PyFloat_FromDouble_ConsumeInputs(_PyStackRef left, _PyStackRef right, double value) +{ + PyStackRef_CLOSE(left); + PyStackRef_CLOSE(right); + return PyFloat_FromDouble(value); +} + +#else // Py_GIL_DISABLED + +PyObject *_PyFloat_FromDouble_ConsumeInputs(_PyStackRef left, _PyStackRef right, double value) +{ + PyObject *left_o = PyStackRef_AsPyObjectSteal(left); + PyObject *right_o = PyStackRef_AsPyObjectSteal(right); + if (Py_REFCNT(left_o) == 1) { + ((PyFloatObject *)left_o)->ob_fval = value; + _Py_DECREF_SPECIALIZED(right_o, _PyFloat_ExactDealloc); + return left_o; + } + else if (Py_REFCNT(right_o) == 1) { + ((PyFloatObject *)right_o)->ob_fval = value; + _Py_DECREF_NO_DEALLOC(left_o); + return right_o; + } + else { + PyObject *result = PyFloat_FromDouble(value); + _Py_DECREF_NO_DEALLOC(left_o); + _Py_DECREF_NO_DEALLOC(right_o); + return result; + } +} + +#endif // Py_GIL_DISABLED + static PyObject * float_from_string_inner(const char *s, Py_ssize_t len, void *obj) { diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 299608f252c546..b22916aeaa248b 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -539,9 +539,9 @@ dummy_func( double dres = ((PyFloatObject *)left_o)->ob_fval * ((PyFloatObject *)right_o)->ob_fval; - PyObject *res_o; - DECREF_INPUTS_AND_REUSE_FLOAT(left_o, right_o, dres, res_o); + PyObject *res_o = _PyFloat_FromDouble_ConsumeInputs(left, right, dres); INPUTS_DEAD(); + ERROR_IF(res_o == NULL, error); res = PyStackRef_FromPyObjectSteal(res_o); } @@ -553,9 +553,9 @@ dummy_func( double dres = ((PyFloatObject *)left_o)->ob_fval + ((PyFloatObject *)right_o)->ob_fval; - PyObject *res_o; - DECREF_INPUTS_AND_REUSE_FLOAT(left_o, right_o, dres, res_o); + PyObject *res_o = _PyFloat_FromDouble_ConsumeInputs(left, right, dres); INPUTS_DEAD(); + ERROR_IF(res_o == NULL, error); res = PyStackRef_FromPyObjectSteal(res_o); } @@ -567,9 +567,9 @@ dummy_func( double dres = ((PyFloatObject *)left_o)->ob_fval - ((PyFloatObject *)right_o)->ob_fval; - PyObject *res_o; - DECREF_INPUTS_AND_REUSE_FLOAT(left_o, right_o, dres, res_o); + PyObject *res_o = _PyFloat_FromDouble_ConsumeInputs(left, right, dres); INPUTS_DEAD(); + ERROR_IF(res_o == NULL, error); res = PyStackRef_FromPyObjectSteal(res_o); } diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h index e0e9cc156ed62f..6674c4ccf9f693 100644 --- a/Python/ceval_macros.h +++ b/Python/ceval_macros.h @@ -327,26 +327,6 @@ GETITEM(PyObject *v, Py_ssize_t i) { " in enclosing scope" #define NAME_ERROR_MSG "name '%.200s' is not defined" -#define DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dval, result) \ -do { \ - if (Py_REFCNT(left) == 1) { \ - ((PyFloatObject *)left)->ob_fval = (dval); \ - _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc);\ - result = (left); \ - } \ - else if (Py_REFCNT(right) == 1) {\ - ((PyFloatObject *)right)->ob_fval = (dval); \ - _Py_DECREF_NO_DEALLOC(left); \ - result = (right); \ - }\ - else { \ - result = PyFloat_FromDouble(dval); \ - if ((result) == NULL) GOTO_ERROR(error); \ - _Py_DECREF_NO_DEALLOC(left); \ - _Py_DECREF_NO_DEALLOC(right); \ - } \ -} while (0) - // If a trace function sets a new f_lineno and // *then* raises, we use the destination when searching // for an exception handler, displaying the traceback, and so on diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 5532c04e497a75..0ed361a2ee7fb0 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -643,8 +643,8 @@ double dres = ((PyFloatObject *)left_o)->ob_fval * ((PyFloatObject *)right_o)->ob_fval; - PyObject *res_o; - DECREF_INPUTS_AND_REUSE_FLOAT(left_o, right_o, dres, res_o); + PyObject *res_o = _PyFloat_FromDouble_ConsumeInputs(left, right, dres); + if (res_o == NULL) JUMP_TO_ERROR(); res = PyStackRef_FromPyObjectSteal(res_o); stack_pointer[-2] = res; stack_pointer += -1; @@ -664,8 +664,8 @@ double dres = ((PyFloatObject *)left_o)->ob_fval + ((PyFloatObject *)right_o)->ob_fval; - PyObject *res_o; - DECREF_INPUTS_AND_REUSE_FLOAT(left_o, right_o, dres, res_o); + PyObject *res_o = _PyFloat_FromDouble_ConsumeInputs(left, right, dres); + if (res_o == NULL) JUMP_TO_ERROR(); res = PyStackRef_FromPyObjectSteal(res_o); stack_pointer[-2] = res; stack_pointer += -1; @@ -685,8 +685,8 @@ double dres = ((PyFloatObject *)left_o)->ob_fval - ((PyFloatObject *)right_o)->ob_fval; - PyObject *res_o; - DECREF_INPUTS_AND_REUSE_FLOAT(left_o, right_o, dres, res_o); + PyObject *res_o = _PyFloat_FromDouble_ConsumeInputs(left, right, dres); + if (res_o == NULL) JUMP_TO_ERROR(); res = PyStackRef_FromPyObjectSteal(res_o); stack_pointer[-2] = res; stack_pointer += -1; diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 0eeb566a0adadc..7bd1b7dd5aba27 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -84,8 +84,8 @@ double dres = ((PyFloatObject *)left_o)->ob_fval + ((PyFloatObject *)right_o)->ob_fval; - PyObject *res_o; - DECREF_INPUTS_AND_REUSE_FLOAT(left_o, right_o, dres, res_o); + PyObject *res_o = _PyFloat_FromDouble_ConsumeInputs(left, right, dres); + if (res_o == NULL) goto pop_2_error; res = PyStackRef_FromPyObjectSteal(res_o); } stack_pointer[-2] = res; @@ -251,8 +251,8 @@ double dres = ((PyFloatObject *)left_o)->ob_fval * ((PyFloatObject *)right_o)->ob_fval; - PyObject *res_o; - DECREF_INPUTS_AND_REUSE_FLOAT(left_o, right_o, dres, res_o); + PyObject *res_o = _PyFloat_FromDouble_ConsumeInputs(left, right, dres); + if (res_o == NULL) goto pop_2_error; res = PyStackRef_FromPyObjectSteal(res_o); } stack_pointer[-2] = res; @@ -322,8 +322,8 @@ double dres = ((PyFloatObject *)left_o)->ob_fval - ((PyFloatObject *)right_o)->ob_fval; - PyObject *res_o; - DECREF_INPUTS_AND_REUSE_FLOAT(left_o, right_o, dres, res_o); + PyObject *res_o = _PyFloat_FromDouble_ConsumeInputs(left, right, dres); + if (res_o == NULL) goto pop_2_error; res = PyStackRef_FromPyObjectSteal(res_o); } stack_pointer[-2] = res; diff --git a/Tools/cases_generator/analyzer.py b/Tools/cases_generator/analyzer.py index 19fdeac65cf2df..381ad3a4e2082c 100644 --- a/Tools/cases_generator/analyzer.py +++ b/Tools/cases_generator/analyzer.py @@ -575,6 +575,7 @@ def has_error_without_pop(op: parser.InstDef) -> bool: "_PyDictValues_AddToInsertionOrder", "_PyErr_Occurred", "_PyEval_FrameClearAndPop", + "_PyFloat_FromDouble_ConsumeInputs", "_PyFrame_GetCode", "_PyFrame_IsIncomplete", "_PyFrame_PushUnchecked", From 5f4e5b598cab86d5fd5727d423c9728221889ed0 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 14 Oct 2024 16:29:20 +0300 Subject: [PATCH 064/170] gh-53203: Fix strptime() for %c, %x and %X formats on many locales (GH-125406) Fixed most locales that use non-ASCII digits, like Persian, Burmese, Odia and Shan. --- Lib/_strptime.py | 68 ++++++++++++------- Lib/test/test_strptime.py | 34 ++++++---- Lib/test/test_time.py | 2 +- ...4-10-13-20-21-35.gh-issue-53203.Rz1c8A.rst | 2 + 4 files changed, 66 insertions(+), 40 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-13-20-21-35.gh-issue-53203.Rz1c8A.rst diff --git a/Lib/_strptime.py b/Lib/_strptime.py index 89adc174e5ad30..5f4d2475c0169b 100644 --- a/Lib/_strptime.py +++ b/Lib/_strptime.py @@ -15,6 +15,7 @@ import locale import calendar from re import compile as re_compile +from re import sub as re_sub from re import IGNORECASE from re import escape as re_escape from datetime import (date as datetime_date, @@ -129,11 +130,23 @@ def __calc_date_time(self): time_tuple = time.struct_time((1999,3,17,22,44,55,2,76,0)) time_tuple2 = time.struct_time((1999,1,3,1,1,1,6,3,0)) replacement_pairs = [ - ('1999', '%Y'), ('99', '%y'), ('22', '%H'), - ('44', '%M'), ('55', '%S'), ('76', '%j'), - ('17', '%d'), ('03', '%m'), ('3', '%m'), - # '3' needed for when no leading zero. - ('2', '%w'), ('10', '%I')] + ('1999', '%Y'), ('99', '%y'), ('22', '%H'), + ('44', '%M'), ('55', '%S'), ('76', '%j'), + ('17', '%d'), ('03', '%m'), ('3', '%m'), + # '3' needed for when no leading zero. + ('2', '%w'), ('10', '%I'), + # Non-ASCII digits + ('\u0661\u0669\u0669\u0669', '%Y'), + ('\u0669\u0669', '%Oy'), + ('\u0662\u0662', '%OH'), + ('\u0664\u0664', '%OM'), + ('\u0665\u0665', '%OS'), + ('\u0661\u0667', '%Od'), + ('\u0660\u0663', '%Om'), + ('\u0663', '%Om'), + ('\u0662', '%Ow'), + ('\u0661\u0660', '%OI'), + ] date_time = [] for directive in ('%c', '%x', '%X'): current_format = time.strftime(directive, time_tuple).lower() @@ -158,6 +171,10 @@ def __calc_date_time(self): for tz in tz_values: if tz: current_format = current_format.replace(tz, "%Z") + # Transform all non-ASCII digits to digits in range U+0660 to U+0669. + current_format = re_sub(r'\d(?3[0-1]|[1-2]\d|0[1-9]|[1-9]| [1-9])", 'f': r"(?P[0-9]{1,6})", @@ -296,11 +313,15 @@ def __init__(self, locale_time=None): 'Z': self.__seqToRE((tz for tz_names in self.locale_time.timezone for tz in tz_names), 'Z'), - '%': '%'}) - base.__setitem__('W', base.__getitem__('U').replace('U', 'W')) - base.__setitem__('c', self.pattern(self.locale_time.LC_date_time)) - base.__setitem__('x', self.pattern(self.locale_time.LC_date)) + '%': '%'} + for d in 'dmyHIMS': + mapping['O' + d] = r'(?P<%s>\d\d|\d| \d)' % d + mapping['Ow'] = r'(?P\d)' + mapping['W'] = mapping['U'].replace('U', 'W') + base.__init__(mapping) base.__setitem__('X', self.pattern(self.locale_time.LC_time)) + base.__setitem__('x', self.pattern(self.locale_time.LC_date)) + base.__setitem__('c', self.pattern(self.locale_time.LC_date_time)) def __seqToRE(self, to_convert, directive): """Convert a list to a regex string for matching a directive. @@ -328,28 +349,25 @@ def pattern(self, format): regex syntax are escaped. """ - processed_format = '' # The sub() call escapes all characters that might be misconstrued # as regex syntax. Cannot use re.escape since we have to deal with # format directives (%m, etc.). - regex_chars = re_compile(r"([\\.^$*+?\(\){}\[\]|])") - format = regex_chars.sub(r"\\\1", format) - whitespace_replacement = re_compile(r'\s+') - format = whitespace_replacement.sub(r'\\s+', format) + format = re_sub(r"([\\.^$*+?\(\){}\[\]|])", r"\\\1", format) + format = re_sub(r'\s+', r'\\s+', format) + format = re_sub(r"'", "['\u02bc]", format) # needed for br_FR year_in_format = False day_of_month_in_format = False - while '%' in format: - directive_index = format.index('%')+1 - format_char = format[directive_index] - processed_format = "%s%s%s" % (processed_format, - format[:directive_index-1], - self[format_char]) - format = format[directive_index+1:] + def repl(m): + format_char = m[1] match format_char: case 'Y' | 'y' | 'G': + nonlocal year_in_format year_in_format = True case 'd': + nonlocal day_of_month_in_format day_of_month_in_format = True + return self[format_char] + format = re_sub(r'%(O?.)', repl, format) if day_of_month_in_format and not year_in_format: import warnings warnings.warn("""\ @@ -360,7 +378,7 @@ def pattern(self, format): See https://github.com/python/cpython/issues/70647.""", DeprecationWarning, skip_file_prefixes=(os.path.dirname(__file__),)) - return "%s%s" % (processed_format, format) + return format def compile(self, format): """Return a compiled re object for the format string.""" @@ -434,8 +452,8 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"): _regex_cache[format] = format_regex found = format_regex.match(data_string) if not found: - raise ValueError("time data %r does not match format %r :: /%s/" % - (data_string, format, format_regex.pattern)) + raise ValueError("time data %r does not match format %r" % + (data_string, format)) if len(data_string) != found.end(): raise ValueError("unconverted data remains: %s" % data_string[found.end():]) diff --git a/Lib/test/test_strptime.py b/Lib/test/test_strptime.py index 79f48dfe44abde..12366b053a2fc1 100644 --- a/Lib/test/test_strptime.py +++ b/Lib/test/test_strptime.py @@ -292,7 +292,7 @@ def test_strptime_exception_context(self): # additional check for IndexError branch (issue #19545) with self.assertRaises(ValueError) as e: _strptime._strptime_time('19', '%Y %') - self.assertIs(e.exception.__suppress_context__, True) + self.assertIsNone(e.exception.__context__) def test_unconverteddata(self): # Check ValueError is raised when there is unconverted data @@ -485,12 +485,14 @@ def test_bad_timezone(self): # id_ID, ms_MY. # * Year is not included: ha_NG. # * Use non-Gregorian calendar: lo_LA, thai, th_TH. + # On Windows: ar_IN, ar_SA, fa_IR, ps_AF. # # BUG: Generates regexp that does not match the current date and time - # for az_IR, fa_IR, lzh_TW, my_MM, or_IN, shn_MM. + # for lzh_TW. @run_with_locales('LC_TIME', 'C', 'en_US', 'fr_FR', 'de_DE', 'ja_JP', 'he_IL', 'eu_ES', 'ar_AE', 'mfe_MU', 'yo_NG', - 'csb_PL', 'br_FR', 'gez_ET', 'brx_IN') + 'csb_PL', 'br_FR', 'gez_ET', 'brx_IN', + 'my_MM', 'or_IN', 'shn_MM', 'az_IR') def test_date_time_locale(self): # Test %c directive loc = locale.getlocale(locale.LC_TIME)[0] @@ -512,20 +514,23 @@ def test_date_time_locale(self): self.roundtrip('%c', slice(0, 6), time.localtime(now - 366*24*3600)) # NB: Dates before 1969 do not roundtrip on some locales: - # bo_CN, bo_IN, dz_BT, eu_ES, eu_FR. + # az_IR, bo_CN, bo_IN, dz_BT, eu_ES, eu_FR, fa_IR, or_IN. @run_with_locales('LC_TIME', 'C', 'en_US', 'fr_FR', 'de_DE', 'ja_JP', 'he_IL', 'ar_AE', 'mfe_MU', 'yo_NG', - 'csb_PL', 'br_FR', 'gez_ET', 'brx_IN') + 'csb_PL', 'br_FR', 'gez_ET', 'brx_IN', + 'my_MM', 'shn_MM') def test_date_time_locale2(self): # Test %c directive self.roundtrip('%c', slice(0, 6), (1900, 1, 1, 0, 0, 0, 0, 1, 0)) + self.roundtrip('%c', slice(0, 6), (1800, 1, 1, 0, 0, 0, 0, 1, 0)) # NB: Does not roundtrip because use non-Gregorian calendar: - # lo_LA, thai, th_TH. + # lo_LA, thai, th_TH. On Windows: ar_IN, ar_SA, fa_IR, ps_AF. # BUG: Generates regexp that does not match the current date - # for az_IR, fa_IR, lzh_TW, my_MM, or_IN, shn_MM. + # for lzh_TW. @run_with_locales('LC_TIME', 'C', 'en_US', 'fr_FR', 'de_DE', 'ja_JP', - 'he_IL', 'eu_ES', 'ar_AE') + 'he_IL', 'eu_ES', 'ar_AE', + 'az_IR', 'my_MM', 'or_IN', 'shn_MM') def test_date_locale(self): # Test %x directive now = time.time() @@ -545,10 +550,11 @@ def test_date_locale(self): "musl libc issue on Emscripten, bpo-46390" ) @run_with_locales('LC_TIME', 'en_US', 'fr_FR', 'de_DE', 'ja_JP', - 'eu_ES', 'ar_AE') + 'eu_ES', 'ar_AE', 'my_MM', 'shn_MM') def test_date_locale2(self): # Test %x directive self.roundtrip('%x', slice(0, 3), (1900, 1, 1, 0, 0, 0, 0, 1, 0)) + self.roundtrip('%x', slice(0, 3), (1800, 1, 1, 0, 0, 0, 0, 1, 0)) # NB: Does not roundtrip in some locales due to the ambiguity of # the time representation (bugs in locales?): @@ -556,11 +562,11 @@ def test_date_locale2(self): # norwegian, nynorsk. # * Hours are in 12-hour notation without AM/PM indication: hy_AM, # ms_MY, sm_WS. - # BUG: Generates regexp that does not match the current time for - # aa_DJ, aa_ER, aa_ET, am_ET, az_IR, byn_ER, fa_IR, gez_ER, gez_ET, - # lzh_TW, my_MM, om_ET, om_KE, or_IN, shn_MM, sid_ET, so_DJ, so_ET, - # so_SO, ti_ER, ti_ET, tig_ER, wal_ET. - @run_with_locales('LC_TIME', 'C', 'en_US', 'fr_FR', 'de_DE', 'ja_JP') + # BUG: Generates regexp that does not match the current time for lzh_TW. + @run_with_locales('LC_TIME', 'C', 'en_US', 'fr_FR', 'de_DE', 'ja_JP', + 'aa_ET', 'am_ET', 'az_IR', 'byn_ER', 'fa_IR', 'gez_ET', + 'my_MM', 'om_ET', 'or_IN', 'shn_MM', 'sid_ET', 'so_SO', + 'ti_ET', 'tig_ER', 'wal_ET') def test_time_locale(self): # Test %X directive now = time.time() diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py index 5b5779231f06ce..27c0f51acc58ab 100644 --- a/Lib/test/test_time.py +++ b/Lib/test/test_time.py @@ -298,7 +298,7 @@ def test_strptime_exception_context(self): # additional check for IndexError branch (issue #19545) with self.assertRaises(ValueError) as e: time.strptime('19', '%Y %') - self.assertIs(e.exception.__suppress_context__, True) + self.assertIsNone(e.exception.__context__) def test_strptime_leap_year(self): # GH-70647: warns if parsing a format with a day and no year. diff --git a/Misc/NEWS.d/next/Library/2024-10-13-20-21-35.gh-issue-53203.Rz1c8A.rst b/Misc/NEWS.d/next/Library/2024-10-13-20-21-35.gh-issue-53203.Rz1c8A.rst new file mode 100644 index 00000000000000..cdfa8c191e8242 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-13-20-21-35.gh-issue-53203.Rz1c8A.rst @@ -0,0 +1,2 @@ +Fix :func:`time.strptime` for ``%c``, ``%x`` and ``%X`` formats in many +locales that use non-ASCII digits, like Persian, Burmese, Odia and Shan. From 6a08a753b702ac63c9b6ac58dd204d1fe9662e9d Mon Sep 17 00:00:00 2001 From: Wulian Date: Mon, 14 Oct 2024 21:53:50 +0800 Subject: [PATCH 065/170] gh-124960: Fixed `barry_as_FLUFL` future flag does not work in new REPL (#124999) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Nice Zombies Co-authored-by: Łukasz Langa --- Lib/_pyrepl/console.py | 10 +++++-- Lib/codeop.py | 7 +++-- Lib/test/test_pyrepl/test_interact.py | 27 ++++++++++++++++++- ...-10-05-15-49-53.gh-issue-124960.Bol9hT.rst | 1 + 4 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-05-15-49-53.gh-issue-124960.Bol9hT.rst diff --git a/Lib/_pyrepl/console.py b/Lib/_pyrepl/console.py index 3e72a56807f6fb..03266c4dfc2dd8 100644 --- a/Lib/_pyrepl/console.py +++ b/Lib/_pyrepl/console.py @@ -174,7 +174,13 @@ def _excepthook(self, typ, value, tb): def runsource(self, source, filename="", symbol="single"): try: - tree = ast.parse(source) + tree = self.compile.compiler( + source, + filename, + "exec", + ast.PyCF_ONLY_AST, + incomplete_input=False, + ) except (SyntaxError, OverflowError, ValueError): self.showsyntaxerror(filename, source=source) return False @@ -185,7 +191,7 @@ def runsource(self, source, filename="", symbol="single"): the_symbol = symbol if stmt is last_stmt else "exec" item = wrapper([stmt]) try: - code = self.compile.compiler(item, filename, the_symbol, dont_inherit=True) + code = self.compile.compiler(item, filename, the_symbol) except SyntaxError as e: if e.args[0] == "'await' outside function": python = os.path.basename(sys.executable) diff --git a/Lib/codeop.py b/Lib/codeop.py index a0276b52d484e3..adf000ba29f88c 100644 --- a/Lib/codeop.py +++ b/Lib/codeop.py @@ -44,6 +44,7 @@ # Caveat emptor: These flags are undocumented on purpose and depending # on their effect outside the standard library is **unsupported**. PyCF_DONT_IMPLY_DEDENT = 0x200 +PyCF_ONLY_AST = 0x400 PyCF_ALLOW_INCOMPLETE_INPUT = 0x4000 def _maybe_compile(compiler, source, filename, symbol): @@ -109,12 +110,14 @@ class Compile: def __init__(self): self.flags = PyCF_DONT_IMPLY_DEDENT | PyCF_ALLOW_INCOMPLETE_INPUT - def __call__(self, source, filename, symbol, **kwargs): - flags = self.flags + def __call__(self, source, filename, symbol, flags=0, **kwargs): + flags |= self.flags if kwargs.get('incomplete_input', True) is False: flags &= ~PyCF_DONT_IMPLY_DEDENT flags &= ~PyCF_ALLOW_INCOMPLETE_INPUT codeob = compile(source, filename, symbol, flags, True) + if flags & PyCF_ONLY_AST: + return codeob # this is an ast.Module in this case for feature in _features: if codeob.co_flags & feature.compiler_flag: self.flags |= feature.compiler_flag diff --git a/Lib/test/test_pyrepl/test_interact.py b/Lib/test/test_pyrepl/test_interact.py index b7adaffbac0e22..0c6df4e5dae869 100644 --- a/Lib/test/test_pyrepl/test_interact.py +++ b/Lib/test/test_pyrepl/test_interact.py @@ -119,13 +119,38 @@ def test_runsource_shows_syntax_error_for_failed_compilation(self): def test_no_active_future(self): console = InteractiveColoredConsole() - source = "x: int = 1; print(__annotate__(1))" + source = dedent("""\ + x: int = 1 + print(__annotate__(1)) + """) f = io.StringIO() with contextlib.redirect_stdout(f): result = console.runsource(source) self.assertFalse(result) self.assertEqual(f.getvalue(), "{'x': }\n") + def test_future_annotations(self): + console = InteractiveColoredConsole() + source = dedent("""\ + from __future__ import annotations + def g(x: int): ... + print(g.__annotations__) + """) + f = io.StringIO() + with contextlib.redirect_stdout(f): + result = console.runsource(source) + self.assertFalse(result) + self.assertEqual(f.getvalue(), "{'x': 'int'}\n") + + def test_future_barry_as_flufl(self): + console = InteractiveColoredConsole() + f = io.StringIO() + with contextlib.redirect_stdout(f): + result = console.runsource("from __future__ import barry_as_FLUFL\n") + result = console.runsource("""print("black" <> 'blue')\n""") + self.assertFalse(result) + self.assertEqual(f.getvalue(), "True\n") + class TestMoreLines(unittest.TestCase): def test_invalid_syntax_single_line(self): diff --git a/Misc/NEWS.d/next/Library/2024-10-05-15-49-53.gh-issue-124960.Bol9hT.rst b/Misc/NEWS.d/next/Library/2024-10-05-15-49-53.gh-issue-124960.Bol9hT.rst new file mode 100644 index 00000000000000..332d6bb54d80c7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-05-15-49-53.gh-issue-124960.Bol9hT.rst @@ -0,0 +1 @@ +Fix support for the ``barry_as_FLUFL`` future flag in the new REPL. From c77121e9f19702b1ab280299394e38e8f15c0fd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Mon, 14 Oct 2024 16:23:05 +0200 Subject: [PATCH 066/170] gh-111178: fix USAN failures for `partialobject` (#124733) --- Modules/_functoolsmodule.c | 59 ++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index 4ab3adc0fe44cc..802b1cf792c555 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -144,10 +144,13 @@ typedef struct { vectorcallfunc vectorcall; } partialobject; +// cast a PyObject pointer PTR to a partialobject pointer (no type checks) +#define _PyPartialObject_CAST(PTR) ((partialobject *)(PTR)) + static void partial_setvectorcall(partialobject *pto); static struct PyModuleDef _functools_module; static PyObject * -partial_call(partialobject *pto, PyObject *args, PyObject *kwargs); +partial_call(PyObject *pto, PyObject *args, PyObject *kwargs); static inline _functools_state * get_functools_state_by_type(PyTypeObject *type) @@ -307,8 +310,9 @@ partial_new(PyTypeObject *type, PyObject *args, PyObject *kw) } static int -partial_clear(partialobject *pto) +partial_clear(PyObject *self) { + partialobject *pto = _PyPartialObject_CAST(self); Py_CLEAR(pto->fn); Py_CLEAR(pto->args); Py_CLEAR(pto->kw); @@ -317,8 +321,9 @@ partial_clear(partialobject *pto) } static int -partial_traverse(partialobject *pto, visitproc visit, void *arg) +partial_traverse(PyObject *self, visitproc visit, void *arg) { + partialobject *pto = _PyPartialObject_CAST(self); Py_VISIT(Py_TYPE(pto)); Py_VISIT(pto->fn); Py_VISIT(pto->args); @@ -328,16 +333,16 @@ partial_traverse(partialobject *pto, visitproc visit, void *arg) } static void -partial_dealloc(partialobject *pto) +partial_dealloc(PyObject *self) { - PyTypeObject *tp = Py_TYPE(pto); + PyTypeObject *tp = Py_TYPE(self); /* bpo-31095: UnTrack is needed before calling any callbacks */ - PyObject_GC_UnTrack(pto); - if (pto->weakreflist != NULL) { - PyObject_ClearWeakRefs((PyObject *) pto); + PyObject_GC_UnTrack(self); + if (_PyPartialObject_CAST(self)->weakreflist != NULL) { + PyObject_ClearWeakRefs(self); } - (void)partial_clear(pto); - tp->tp_free(pto); + (void)partial_clear(self); + tp->tp_free(self); Py_DECREF(tp); } @@ -360,14 +365,14 @@ partial_vectorcall_fallback(PyThreadState *tstate, partialobject *pto, { pto->vectorcall = NULL; Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); - return _PyObject_MakeTpCall(tstate, (PyObject *)pto, - args, nargs, kwnames); + return _PyObject_MakeTpCall(tstate, (PyObject *)pto, args, nargs, kwnames); } static PyObject * -partial_vectorcall(partialobject *pto, PyObject *const *args, +partial_vectorcall(PyObject *self, PyObject *const *args, size_t nargsf, PyObject *kwnames) { + partialobject *pto = _PyPartialObject_CAST(self);; PyThreadState *tstate = _PyThreadState_GET(); Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); @@ -468,15 +473,16 @@ partial_setvectorcall(partialobject *pto) * but that is unlikely (why use partial without arguments?), * so we don't optimize that */ else { - pto->vectorcall = (vectorcallfunc)partial_vectorcall; + pto->vectorcall = partial_vectorcall; } } // Not converted to argument clinic, because of `*args, **kwargs` arguments. static PyObject * -partial_call(partialobject *pto, PyObject *args, PyObject *kwargs) +partial_call(PyObject *self, PyObject *args, PyObject *kwargs) { + partialobject *pto = _PyPartialObject_CAST(self); assert(PyCallable_Check(pto->fn)); assert(PyTuple_Check(pto->args)); assert(PyDict_Check(pto->kw)); @@ -587,8 +593,9 @@ static PyGetSetDef partial_getsetlist[] = { }; static PyObject * -partial_repr(partialobject *pto) +partial_repr(PyObject *self) { + partialobject *pto = _PyPartialObject_CAST(self); PyObject *result = NULL; PyObject *arglist; PyObject *mod; @@ -597,7 +604,7 @@ partial_repr(partialobject *pto) PyObject *key, *value; int status; - status = Py_ReprEnter((PyObject *)pto); + status = Py_ReprEnter(self); if (status != 0) { if (status < 0) return NULL; @@ -608,7 +615,7 @@ partial_repr(partialobject *pto) if (arglist == NULL) goto done; /* Pack positional arguments */ - assert (PyTuple_Check(pto->args)); + assert(PyTuple_Check(pto->args)); n = PyTuple_GET_SIZE(pto->args); for (i = 0; i < n; i++) { Py_SETREF(arglist, PyUnicode_FromFormat("%U, %R", arglist, @@ -643,11 +650,11 @@ partial_repr(partialobject *pto) Py_DECREF(arglist); done: - Py_ReprLeave((PyObject *)pto); + Py_ReprLeave(self); return result; error: Py_DECREF(arglist); - Py_ReprLeave((PyObject *)pto); + Py_ReprLeave(self); return NULL; } @@ -659,16 +666,18 @@ partial_repr(partialobject *pto) */ static PyObject * -partial_reduce(partialobject *pto, PyObject *unused) +partial_reduce(PyObject *self, PyObject *Py_UNUSED(args)) { + partialobject *pto = _PyPartialObject_CAST(self); return Py_BuildValue("O(O)(OOOO)", Py_TYPE(pto), pto->fn, pto->fn, pto->args, pto->kw, pto->dict ? pto->dict : Py_None); } static PyObject * -partial_setstate(partialobject *pto, PyObject *state) +partial_setstate(PyObject *self, PyObject *state) { + partialobject *pto = _PyPartialObject_CAST(self); PyObject *fn, *fnargs, *kw, *dict; if (!PyTuple_Check(state)) { @@ -730,8 +739,8 @@ partial_setstate(partialobject *pto, PyObject *state) } static PyMethodDef partial_methods[] = { - {"__reduce__", (PyCFunction)partial_reduce, METH_NOARGS}, - {"__setstate__", (PyCFunction)partial_setstate, METH_O}, + {"__reduce__", partial_reduce, METH_NOARGS}, + {"__setstate__", partial_setstate, METH_O}, {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, {NULL, NULL} /* sentinel */ @@ -749,7 +758,7 @@ static PyType_Slot partial_type_slots[] = { {Py_tp_methods, partial_methods}, {Py_tp_members, partial_memberlist}, {Py_tp_getset, partial_getsetlist}, - {Py_tp_descr_get, (descrgetfunc)partial_descr_get}, + {Py_tp_descr_get, partial_descr_get}, {Py_tp_new, partial_new}, {Py_tp_free, PyObject_GC_Del}, {0, 0} From 45df264f3ffbc0893cbfd257131d3abe21043786 Mon Sep 17 00:00:00 2001 From: Mikhail Efimov Date: Mon, 14 Oct 2024 17:53:08 +0300 Subject: [PATCH 067/170] gh-112088: aclocal version is updated to 1.16.5 in docs (#125457) --- Doc/using/configure.rst | 4 ++-- Doc/whatsnew/3.13.rst | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/using/configure.rst b/Doc/using/configure.rst index 4976418ba33cf8..10cdf2376229ff 100644 --- a/Doc/using/configure.rst +++ b/Doc/using/configure.rst @@ -29,7 +29,7 @@ Features and minimum versions required to build CPython: * Tcl/Tk 8.5.12 for the :mod:`tkinter` module. -* Autoconf 2.71 and aclocal 1.16.4 are required to regenerate the +* Autoconf 2.71 and aclocal 1.16.5 are required to regenerate the :file:`configure` script. .. versionchanged:: 3.1 @@ -56,7 +56,7 @@ Features and minimum versions required to build CPython: Tcl/Tk version 8.5.12 is now required for the :mod:`tkinter` module. .. versionchanged:: 3.13 - Autoconf 2.71, aclocal 1.16.4 and SQLite 3.15.2 are now required. + Autoconf 2.71, aclocal 1.16.5 and SQLite 3.15.2 are now required. See also :pep:`7` "Style Guide for C Code" and :pep:`11` "CPython platform support". diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index a2897097aaba57..f9e74a9b8ff9c6 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -2495,9 +2495,9 @@ Build Changes * Building CPython now requires a compiler with support for the C11 atomic library, GCC built-in atomic functions, or MSVC interlocked intrinsics. -* Autoconf 2.71 and aclocal 1.16.4 are now required to regenerate +* Autoconf 2.71 and aclocal 1.16.5 are now required to regenerate the :file:`configure` script. - (Contributed by Christian Heimes in :gh:`89886`.) + (Contributed by Christian Heimes in :gh:`89886` and by Victor Stinner in :gh:`112090`.) * SQLite 3.15.2 or newer is required to build the :mod:`sqlite3` extension module. From d5dbbf4372cd3dbf3eead1cc70ddc4261c061fd9 Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Mon, 14 Oct 2024 16:19:56 +0100 Subject: [PATCH 068/170] gh-124958: fix asyncio.TaskGroup and _PyFuture refcycles (#124959) --- Lib/asyncio/futures.py | 6 +- Lib/asyncio/taskgroups.py | 41 +++++++-- Lib/test/test_asyncio/test_futures.py | 22 +++++ Lib/test/test_asyncio/test_taskgroups.py | 92 ++++++++++++++++++- ...-10-04-08-46-00.gh-issue-124958.rea9-x.rst | 1 + 5 files changed, 147 insertions(+), 15 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-04-08-46-00.gh-issue-124958.rea9-x.rst diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py index 5f6fa2348726cf..c95fce035cd548 100644 --- a/Lib/asyncio/futures.py +++ b/Lib/asyncio/futures.py @@ -190,8 +190,7 @@ def result(self): the future is done and has an exception set, this exception is raised. """ if self._state == _CANCELLED: - exc = self._make_cancelled_error() - raise exc + raise self._make_cancelled_error() if self._state != _FINISHED: raise exceptions.InvalidStateError('Result is not ready.') self.__log_traceback = False @@ -208,8 +207,7 @@ def exception(self): InvalidStateError. """ if self._state == _CANCELLED: - exc = self._make_cancelled_error() - raise exc + raise self._make_cancelled_error() if self._state != _FINISHED: raise exceptions.InvalidStateError('Exception is not set.') self.__log_traceback = False diff --git a/Lib/asyncio/taskgroups.py b/Lib/asyncio/taskgroups.py index f2ee9648c43876..9fa772ca9d02cc 100644 --- a/Lib/asyncio/taskgroups.py +++ b/Lib/asyncio/taskgroups.py @@ -66,6 +66,20 @@ async def __aenter__(self): return self async def __aexit__(self, et, exc, tb): + tb = None + try: + return await self._aexit(et, exc) + finally: + # Exceptions are heavy objects that can have object + # cycles (bad for GC); let's not keep a reference to + # a bunch of them. It would be nicer to use a try/finally + # in __aexit__ directly but that introduced some diff noise + self._parent_task = None + self._errors = None + self._base_error = None + exc = None + + async def _aexit(self, et, exc): self._exiting = True if (exc is not None and @@ -122,7 +136,10 @@ async def __aexit__(self, et, exc, tb): assert not self._tasks if self._base_error is not None: - raise self._base_error + try: + raise self._base_error + finally: + exc = None if self._parent_cancel_requested: # If this flag is set we *must* call uncancel(). @@ -133,8 +150,14 @@ async def __aexit__(self, et, exc, tb): # Propagate CancelledError if there is one, except if there # are other errors -- those have priority. - if propagate_cancellation_error is not None and not self._errors: - raise propagate_cancellation_error + try: + if propagate_cancellation_error is not None and not self._errors: + try: + raise propagate_cancellation_error + finally: + exc = None + finally: + propagate_cancellation_error = None if et is not None and not issubclass(et, exceptions.CancelledError): self._errors.append(exc) @@ -146,14 +169,14 @@ async def __aexit__(self, et, exc, tb): if self._parent_task.cancelling(): self._parent_task.uncancel() self._parent_task.cancel() - # Exceptions are heavy objects that can have object - # cycles (bad for GC); let's not keep a reference to - # a bunch of them. try: - me = BaseExceptionGroup('unhandled errors in a TaskGroup', self._errors) - raise me from None + raise BaseExceptionGroup( + 'unhandled errors in a TaskGroup', + self._errors, + ) from None finally: - self._errors = None + exc = None + def create_task(self, coro, *, name=None, context=None): """Create a new task in this group and return it. diff --git a/Lib/test/test_asyncio/test_futures.py b/Lib/test/test_asyncio/test_futures.py index 458b70451a306a..c566b28adb2408 100644 --- a/Lib/test/test_asyncio/test_futures.py +++ b/Lib/test/test_asyncio/test_futures.py @@ -659,6 +659,28 @@ def __del__(self): fut = self._new_future(loop=self.loop) fut.set_result(Evil()) + def test_future_cancelled_result_refcycles(self): + f = self._new_future(loop=self.loop) + f.cancel() + exc = None + try: + f.result() + except asyncio.CancelledError as e: + exc = e + self.assertIsNotNone(exc) + self.assertListEqual(gc.get_referrers(exc), []) + + def test_future_cancelled_exception_refcycles(self): + f = self._new_future(loop=self.loop) + f.cancel() + exc = None + try: + f.exception() + except asyncio.CancelledError as e: + exc = e + self.assertIsNotNone(exc) + self.assertListEqual(gc.get_referrers(exc), []) + @unittest.skipUnless(hasattr(futures, '_CFuture'), 'requires the C _asyncio module') diff --git a/Lib/test/test_asyncio/test_taskgroups.py b/Lib/test/test_asyncio/test_taskgroups.py index 4852536defc93d..138f59ebf57ef7 100644 --- a/Lib/test/test_asyncio/test_taskgroups.py +++ b/Lib/test/test_asyncio/test_taskgroups.py @@ -1,7 +1,7 @@ # Adapted with permission from the EdgeDB project; # license: PSFL. - +import gc import asyncio import contextvars import contextlib @@ -11,7 +11,6 @@ from test.test_asyncio.utils import await_without_task - # To prevent a warning "test altered the execution environment" def tearDownModule(): asyncio.set_event_loop_policy(None) @@ -899,6 +898,95 @@ async def outer(): await outer() + async def test_exception_refcycles_direct(self): + """Test that TaskGroup doesn't keep a reference to the raised ExceptionGroup""" + tg = asyncio.TaskGroup() + exc = None + + class _Done(Exception): + pass + + try: + async with tg: + raise _Done + except ExceptionGroup as e: + exc = e + + self.assertIsNotNone(exc) + self.assertListEqual(gc.get_referrers(exc), []) + + + async def test_exception_refcycles_errors(self): + """Test that TaskGroup deletes self._errors, and __aexit__ args""" + tg = asyncio.TaskGroup() + exc = None + + class _Done(Exception): + pass + + try: + async with tg: + raise _Done + except* _Done as excs: + exc = excs.exceptions[0] + + self.assertIsInstance(exc, _Done) + self.assertListEqual(gc.get_referrers(exc), []) + + + async def test_exception_refcycles_parent_task(self): + """Test that TaskGroup deletes self._parent_task""" + tg = asyncio.TaskGroup() + exc = None + + class _Done(Exception): + pass + + async def coro_fn(): + async with tg: + raise _Done + + try: + async with asyncio.TaskGroup() as tg2: + tg2.create_task(coro_fn()) + except* _Done as excs: + exc = excs.exceptions[0].exceptions[0] + + self.assertIsInstance(exc, _Done) + self.assertListEqual(gc.get_referrers(exc), []) + + async def test_exception_refcycles_propagate_cancellation_error(self): + """Test that TaskGroup deletes propagate_cancellation_error""" + tg = asyncio.TaskGroup() + exc = None + + try: + async with asyncio.timeout(-1): + async with tg: + await asyncio.sleep(0) + except TimeoutError as e: + exc = e.__cause__ + + self.assertIsInstance(exc, asyncio.CancelledError) + self.assertListEqual(gc.get_referrers(exc), []) + + async def test_exception_refcycles_base_error(self): + """Test that TaskGroup deletes self._base_error""" + class MyKeyboardInterrupt(KeyboardInterrupt): + pass + + tg = asyncio.TaskGroup() + exc = None + + try: + async with tg: + raise MyKeyboardInterrupt + except MyKeyboardInterrupt as e: + exc = e + + self.assertIsNotNone(exc) + self.assertListEqual(gc.get_referrers(exc), []) + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2024-10-04-08-46-00.gh-issue-124958.rea9-x.rst b/Misc/NEWS.d/next/Library/2024-10-04-08-46-00.gh-issue-124958.rea9-x.rst new file mode 100644 index 00000000000000..534d5bb8c898da --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-04-08-46-00.gh-issue-124958.rea9-x.rst @@ -0,0 +1 @@ +Fix refcycles in exceptions raised from :class:`asyncio.TaskGroup` and the python implementation of :class:`asyncio.Future` From 5dac0dceda9097d46a0b5a6ad7c927e002c6c7a5 Mon Sep 17 00:00:00 2001 From: Paul Hoffman Date: Mon, 14 Oct 2024 08:26:57 -0700 Subject: [PATCH 069/170] gh-125461: Remove Python 2 from identifiers in doc (GH-125462) Remove Python 2 from identifiers in doc --- Doc/reference/lexical_analysis.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Doc/reference/lexical_analysis.rst b/Doc/reference/lexical_analysis.rst index ae5408ee386bbd..f7167032ad7df9 100644 --- a/Doc/reference/lexical_analysis.rst +++ b/Doc/reference/lexical_analysis.rst @@ -284,11 +284,10 @@ UAX-31, with elaboration and changes as defined below; see also :pep:`3131` for further details. Within the ASCII range (U+0001..U+007F), the valid characters for identifiers -are the same as in Python 2.x: the uppercase and lowercase letters ``A`` through +include the uppercase and lowercase letters ``A`` through ``Z``, the underscore ``_`` and, except for the first character, the digits ``0`` through ``9``. - -Python 3.0 introduces additional characters from outside the ASCII range (see +Python 3.0 introduced additional characters from outside the ASCII range (see :pep:`3131`). For these characters, the classification uses the version of the Unicode Character Database as included in the :mod:`unicodedata` module. From 187580d95c8339a3b6e2b012f98d86101c346cfa Mon Sep 17 00:00:00 2001 From: Mikhail Efimov Date: Mon, 14 Oct 2024 20:24:54 +0300 Subject: [PATCH 070/170] gh-119786: [doc] broken link and typo fix in interpreter_definition.md (#125455) --- InternalDocs/README.md | 2 ++ Tools/cases_generator/interpreter_definition.md | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/InternalDocs/README.md b/InternalDocs/README.md index 805e2f97937e1e..0a6ecf899458ed 100644 --- a/InternalDocs/README.md +++ b/InternalDocs/README.md @@ -11,6 +11,8 @@ The core dev team attempts to keep this documentation up to date. If it is not, please report that through the [issue tracker](https://github.com/python/cpython/issues). +Index: +----- [Guide to the parser](parser.md) diff --git a/Tools/cases_generator/interpreter_definition.md b/Tools/cases_generator/interpreter_definition.md index ba09931c541646..6cf36f343d5fa7 100644 --- a/Tools/cases_generator/interpreter_definition.md +++ b/Tools/cases_generator/interpreter_definition.md @@ -74,7 +74,7 @@ We update it as the need arises. ### Syntax Each op definition has a kind, a name, a stack and instruction stream effect, -and a piece of C code describing its semantics:: +and a piece of C code describing its semantics: ``` file: @@ -245,7 +245,8 @@ The same is true for all members of a pseudo instruction ## Examples -(Another source of examples can be found in the [tests](test_generator.py).) +(Another source of examples can be found in the +[tests](https://github.com/python/cpython/blob/main/Lib/test/test_generated_cases.py).) Some examples: From e99650b80ace3893c2a80b3f2a4aca99cb305191 Mon Sep 17 00:00:00 2001 From: Kirill Podoprigora Date: Mon, 14 Oct 2024 20:59:13 +0300 Subject: [PATCH 071/170] =?UTF-8?q?gh-125472:=20Revert=20"gh-124958:=20fix?= =?UTF-8?q?=20asyncio.TaskGroup=20and=20=5FPyFuture=20refcycles=20(#12?= =?UTF-8?q?=E2=80=A6=20(#125476)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Revert "gh-124958: fix asyncio.TaskGroup and _PyFuture refcycles (#124959)" This reverts commit d5dbbf4372cd3dbf3eead1cc70ddc4261c061fd9. --- Lib/asyncio/futures.py | 6 +- Lib/asyncio/taskgroups.py | 41 ++------- Lib/test/test_asyncio/test_futures.py | 22 ----- Lib/test/test_asyncio/test_taskgroups.py | 92 +------------------ ...-10-04-08-46-00.gh-issue-124958.rea9-x.rst | 1 - 5 files changed, 15 insertions(+), 147 deletions(-) delete mode 100644 Misc/NEWS.d/next/Library/2024-10-04-08-46-00.gh-issue-124958.rea9-x.rst diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py index c95fce035cd548..5f6fa2348726cf 100644 --- a/Lib/asyncio/futures.py +++ b/Lib/asyncio/futures.py @@ -190,7 +190,8 @@ def result(self): the future is done and has an exception set, this exception is raised. """ if self._state == _CANCELLED: - raise self._make_cancelled_error() + exc = self._make_cancelled_error() + raise exc if self._state != _FINISHED: raise exceptions.InvalidStateError('Result is not ready.') self.__log_traceback = False @@ -207,7 +208,8 @@ def exception(self): InvalidStateError. """ if self._state == _CANCELLED: - raise self._make_cancelled_error() + exc = self._make_cancelled_error() + raise exc if self._state != _FINISHED: raise exceptions.InvalidStateError('Exception is not set.') self.__log_traceback = False diff --git a/Lib/asyncio/taskgroups.py b/Lib/asyncio/taskgroups.py index 9fa772ca9d02cc..f2ee9648c43876 100644 --- a/Lib/asyncio/taskgroups.py +++ b/Lib/asyncio/taskgroups.py @@ -66,20 +66,6 @@ async def __aenter__(self): return self async def __aexit__(self, et, exc, tb): - tb = None - try: - return await self._aexit(et, exc) - finally: - # Exceptions are heavy objects that can have object - # cycles (bad for GC); let's not keep a reference to - # a bunch of them. It would be nicer to use a try/finally - # in __aexit__ directly but that introduced some diff noise - self._parent_task = None - self._errors = None - self._base_error = None - exc = None - - async def _aexit(self, et, exc): self._exiting = True if (exc is not None and @@ -136,10 +122,7 @@ async def _aexit(self, et, exc): assert not self._tasks if self._base_error is not None: - try: - raise self._base_error - finally: - exc = None + raise self._base_error if self._parent_cancel_requested: # If this flag is set we *must* call uncancel(). @@ -150,14 +133,8 @@ async def _aexit(self, et, exc): # Propagate CancelledError if there is one, except if there # are other errors -- those have priority. - try: - if propagate_cancellation_error is not None and not self._errors: - try: - raise propagate_cancellation_error - finally: - exc = None - finally: - propagate_cancellation_error = None + if propagate_cancellation_error is not None and not self._errors: + raise propagate_cancellation_error if et is not None and not issubclass(et, exceptions.CancelledError): self._errors.append(exc) @@ -169,14 +146,14 @@ async def _aexit(self, et, exc): if self._parent_task.cancelling(): self._parent_task.uncancel() self._parent_task.cancel() + # Exceptions are heavy objects that can have object + # cycles (bad for GC); let's not keep a reference to + # a bunch of them. try: - raise BaseExceptionGroup( - 'unhandled errors in a TaskGroup', - self._errors, - ) from None + me = BaseExceptionGroup('unhandled errors in a TaskGroup', self._errors) + raise me from None finally: - exc = None - + self._errors = None def create_task(self, coro, *, name=None, context=None): """Create a new task in this group and return it. diff --git a/Lib/test/test_asyncio/test_futures.py b/Lib/test/test_asyncio/test_futures.py index c566b28adb2408..458b70451a306a 100644 --- a/Lib/test/test_asyncio/test_futures.py +++ b/Lib/test/test_asyncio/test_futures.py @@ -659,28 +659,6 @@ def __del__(self): fut = self._new_future(loop=self.loop) fut.set_result(Evil()) - def test_future_cancelled_result_refcycles(self): - f = self._new_future(loop=self.loop) - f.cancel() - exc = None - try: - f.result() - except asyncio.CancelledError as e: - exc = e - self.assertIsNotNone(exc) - self.assertListEqual(gc.get_referrers(exc), []) - - def test_future_cancelled_exception_refcycles(self): - f = self._new_future(loop=self.loop) - f.cancel() - exc = None - try: - f.exception() - except asyncio.CancelledError as e: - exc = e - self.assertIsNotNone(exc) - self.assertListEqual(gc.get_referrers(exc), []) - @unittest.skipUnless(hasattr(futures, '_CFuture'), 'requires the C _asyncio module') diff --git a/Lib/test/test_asyncio/test_taskgroups.py b/Lib/test/test_asyncio/test_taskgroups.py index 138f59ebf57ef7..4852536defc93d 100644 --- a/Lib/test/test_asyncio/test_taskgroups.py +++ b/Lib/test/test_asyncio/test_taskgroups.py @@ -1,7 +1,7 @@ # Adapted with permission from the EdgeDB project; # license: PSFL. -import gc + import asyncio import contextvars import contextlib @@ -11,6 +11,7 @@ from test.test_asyncio.utils import await_without_task + # To prevent a warning "test altered the execution environment" def tearDownModule(): asyncio.set_event_loop_policy(None) @@ -898,95 +899,6 @@ async def outer(): await outer() - async def test_exception_refcycles_direct(self): - """Test that TaskGroup doesn't keep a reference to the raised ExceptionGroup""" - tg = asyncio.TaskGroup() - exc = None - - class _Done(Exception): - pass - - try: - async with tg: - raise _Done - except ExceptionGroup as e: - exc = e - - self.assertIsNotNone(exc) - self.assertListEqual(gc.get_referrers(exc), []) - - - async def test_exception_refcycles_errors(self): - """Test that TaskGroup deletes self._errors, and __aexit__ args""" - tg = asyncio.TaskGroup() - exc = None - - class _Done(Exception): - pass - - try: - async with tg: - raise _Done - except* _Done as excs: - exc = excs.exceptions[0] - - self.assertIsInstance(exc, _Done) - self.assertListEqual(gc.get_referrers(exc), []) - - - async def test_exception_refcycles_parent_task(self): - """Test that TaskGroup deletes self._parent_task""" - tg = asyncio.TaskGroup() - exc = None - - class _Done(Exception): - pass - - async def coro_fn(): - async with tg: - raise _Done - - try: - async with asyncio.TaskGroup() as tg2: - tg2.create_task(coro_fn()) - except* _Done as excs: - exc = excs.exceptions[0].exceptions[0] - - self.assertIsInstance(exc, _Done) - self.assertListEqual(gc.get_referrers(exc), []) - - async def test_exception_refcycles_propagate_cancellation_error(self): - """Test that TaskGroup deletes propagate_cancellation_error""" - tg = asyncio.TaskGroup() - exc = None - - try: - async with asyncio.timeout(-1): - async with tg: - await asyncio.sleep(0) - except TimeoutError as e: - exc = e.__cause__ - - self.assertIsInstance(exc, asyncio.CancelledError) - self.assertListEqual(gc.get_referrers(exc), []) - - async def test_exception_refcycles_base_error(self): - """Test that TaskGroup deletes self._base_error""" - class MyKeyboardInterrupt(KeyboardInterrupt): - pass - - tg = asyncio.TaskGroup() - exc = None - - try: - async with tg: - raise MyKeyboardInterrupt - except MyKeyboardInterrupt as e: - exc = e - - self.assertIsNotNone(exc) - self.assertListEqual(gc.get_referrers(exc), []) - if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2024-10-04-08-46-00.gh-issue-124958.rea9-x.rst b/Misc/NEWS.d/next/Library/2024-10-04-08-46-00.gh-issue-124958.rea9-x.rst deleted file mode 100644 index 534d5bb8c898da..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-04-08-46-00.gh-issue-124958.rea9-x.rst +++ /dev/null @@ -1 +0,0 @@ -Fix refcycles in exceptions raised from :class:`asyncio.TaskGroup` and the python implementation of :class:`asyncio.Future` From 843d28f59d2616d052d9d45f31823976da07f0f3 Mon Sep 17 00:00:00 2001 From: Richard Hansen Date: Mon, 14 Oct 2024 15:28:41 -0400 Subject: [PATCH 072/170] gh-124872: Replace enter/exit events with "switched" (#124776) Users want to know when the current context switches to a different context object. Right now this happens when and only when a context is entered or exited, so the enter and exit events are synonymous with "switched". However, if the changes proposed for gh-99633 are implemented, the current context will also switch for reasons other than context enter or exit. Since users actually care about context switches and not enter or exit, replace the enter and exit events with a single switched event. The former exit event was emitted just before exiting the context. The new switched event is emitted after the context is exited to match the semantics users expect of an event with a past-tense name. If users need the ability to clean up before the switch takes effect, another event type can be added in the future. It is not added here because YAGNI. I skipped 0 in the enum as a matter of practice. Skipping 0 makes it easier to troubleshoot when code forgets to set zeroed memory, and it aligns with best practices for other tools (e.g., https://protobuf.dev/programming-guides/dos-donts/#unspecified-enum). --- Doc/c-api/contextvars.rst | 14 ++--- Include/cpython/context.h | 17 ++---- Lib/test/test_capi/test_watchers.py | 89 ++++++++++++++-------------- Modules/_testcapi/watchers.c | 79 ++++++++++++------------ Python/context.c | 31 ++++++---- Tools/c-analyzer/cpython/ignored.tsv | 4 +- 6 files changed, 117 insertions(+), 117 deletions(-) diff --git a/Doc/c-api/contextvars.rst b/Doc/c-api/contextvars.rst index 8eba54a80dc80d..b7c6550ff34aac 100644 --- a/Doc/c-api/contextvars.rst +++ b/Doc/c-api/contextvars.rst @@ -123,16 +123,10 @@ Context object management functions: Enumeration of possible context object watcher events: - - ``Py_CONTEXT_EVENT_ENTER``: A context has been entered, causing the - :term:`current context` to switch to it. The object passed to the watch - callback is the now-current :class:`contextvars.Context` object. Each - enter event will eventually have a corresponding exit event for the same - context object after any subsequently entered contexts have themselves been - exited. - - ``Py_CONTEXT_EVENT_EXIT``: A context is about to be exited, which will - cause the :term:`current context` to switch back to what it was before the - context was entered. The object passed to the watch callback is the - still-current :class:`contextvars.Context` object. + - ``Py_CONTEXT_SWITCHED``: The :term:`current context` has switched to a + different context. The object passed to the watch callback is the + now-current :class:`contextvars.Context` object, or None if no context is + current. .. versionadded:: 3.14 diff --git a/Include/cpython/context.h b/Include/cpython/context.h index 3c9be7873b9399..3a7a4b459c09ad 100644 --- a/Include/cpython/context.h +++ b/Include/cpython/context.h @@ -29,20 +29,11 @@ PyAPI_FUNC(int) PyContext_Exit(PyObject *); typedef enum { /* - * A context has been entered, causing the "current context" to switch to - * it. The object passed to the watch callback is the now-current - * contextvars.Context object. Each enter event will eventually have a - * corresponding exit event for the same context object after any - * subsequently entered contexts have themselves been exited. + * The current context has switched to a different context. The object + * passed to the watch callback is the now-current contextvars.Context + * object, or None if no context is current. */ - Py_CONTEXT_EVENT_ENTER, - /* - * A context is about to be exited, which will cause the "current context" - * to switch back to what it was before the context was entered. The - * object passed to the watch callback is the still-current - * contextvars.Context object. - */ - Py_CONTEXT_EVENT_EXIT, + Py_CONTEXT_SWITCHED = 1, } PyContextEvent; /* diff --git a/Lib/test/test_capi/test_watchers.py b/Lib/test/test_capi/test_watchers.py index f21d2627c6094b..4680d6765de122 100644 --- a/Lib/test/test_capi/test_watchers.py +++ b/Lib/test/test_capi/test_watchers.py @@ -577,68 +577,62 @@ class TestContextObjectWatchers(unittest.TestCase): def context_watcher(self, which_watcher): wid = _testcapi.add_context_watcher(which_watcher) try: - yield wid + switches = _testcapi.get_context_switches(which_watcher) + except ValueError: + switches = None + try: + yield switches finally: _testcapi.clear_context_watcher(wid) - def assert_event_counts(self, exp_enter_0, exp_exit_0, - exp_enter_1, exp_exit_1): - self.assertEqual( - exp_enter_0, _testcapi.get_context_watcher_num_enter_events(0)) - self.assertEqual( - exp_exit_0, _testcapi.get_context_watcher_num_exit_events(0)) - self.assertEqual( - exp_enter_1, _testcapi.get_context_watcher_num_enter_events(1)) - self.assertEqual( - exp_exit_1, _testcapi.get_context_watcher_num_exit_events(1)) + def assert_event_counts(self, want_0, want_1): + self.assertEqual(len(_testcapi.get_context_switches(0)), want_0) + self.assertEqual(len(_testcapi.get_context_switches(1)), want_1) def test_context_object_events_dispatched(self): # verify that all counts are zero before any watchers are registered - self.assert_event_counts(0, 0, 0, 0) + self.assert_event_counts(0, 0) # verify that all counts remain zero when a context object is # entered and exited with no watchers registered ctx = contextvars.copy_context() - ctx.run(self.assert_event_counts, 0, 0, 0, 0) - self.assert_event_counts(0, 0, 0, 0) + ctx.run(self.assert_event_counts, 0, 0) + self.assert_event_counts(0, 0) # verify counts are as expected when first watcher is registered with self.context_watcher(0): - self.assert_event_counts(0, 0, 0, 0) - ctx.run(self.assert_event_counts, 1, 0, 0, 0) - self.assert_event_counts(1, 1, 0, 0) + self.assert_event_counts(0, 0) + ctx.run(self.assert_event_counts, 1, 0) + self.assert_event_counts(2, 0) # again with second watcher registered with self.context_watcher(1): - self.assert_event_counts(1, 1, 0, 0) - ctx.run(self.assert_event_counts, 2, 1, 1, 0) - self.assert_event_counts(2, 2, 1, 1) + self.assert_event_counts(2, 0) + ctx.run(self.assert_event_counts, 3, 1) + self.assert_event_counts(4, 2) # verify counts are reset and don't change after both watchers are cleared - ctx.run(self.assert_event_counts, 0, 0, 0, 0) - self.assert_event_counts(0, 0, 0, 0) - - def test_enter_error(self): - with self.context_watcher(2): - with catch_unraisable_exception() as cm: - ctx = contextvars.copy_context() - ctx.run(int, 0) - self.assertEqual( - cm.unraisable.err_msg, - "Exception ignored in " - f"Py_CONTEXT_EVENT_EXIT watcher callback for {ctx!r}" - ) - self.assertEqual(str(cm.unraisable.exc_value), "boom!") - - def test_exit_error(self): - ctx = contextvars.copy_context() - def _in_context(stack): - stack.enter_context(self.context_watcher(2)) - - with catch_unraisable_exception() as cm: - with ExitStack() as stack: - ctx.run(_in_context, stack) - self.assertEqual(str(cm.unraisable.exc_value), "boom!") + ctx.run(self.assert_event_counts, 0, 0) + self.assert_event_counts(0, 0) + + def test_callback_error(self): + ctx_outer = contextvars.copy_context() + ctx_inner = contextvars.copy_context() + unraisables = [] + + def _in_outer(): + with self.context_watcher(2): + with catch_unraisable_exception() as cm: + ctx_inner.run(lambda: unraisables.append(cm.unraisable)) + unraisables.append(cm.unraisable) + + ctx_outer.run(_in_outer) + self.assertEqual([x.err_msg for x in unraisables], + ["Exception ignored in Py_CONTEXT_SWITCHED " + f"watcher callback for {ctx!r}" + for ctx in [ctx_inner, ctx_outer]]) + self.assertEqual([str(x.exc_value) for x in unraisables], + ["boom!", "boom!"]) def test_clear_out_of_range_watcher_id(self): with self.assertRaisesRegex(ValueError, r"Invalid context watcher ID -1"): @@ -654,5 +648,12 @@ def test_allocate_too_many_watchers(self): with self.assertRaisesRegex(RuntimeError, r"no more context watcher IDs available"): _testcapi.allocate_too_many_context_watchers() + def test_exit_base_context(self): + ctx = contextvars.Context() + _testcapi.clear_context_stack() + with self.context_watcher(0) as switches: + ctx.run(lambda: None) + self.assertEqual(switches, [ctx, None]) + if __name__ == "__main__": unittest.main() diff --git a/Modules/_testcapi/watchers.c b/Modules/_testcapi/watchers.c index b4233d07134aea..321d3aeffb6ad1 100644 --- a/Modules/_testcapi/watchers.c +++ b/Modules/_testcapi/watchers.c @@ -626,16 +626,12 @@ allocate_too_many_func_watchers(PyObject *self, PyObject *args) // Test contexct object watchers #define NUM_CONTEXT_WATCHERS 2 static int context_watcher_ids[NUM_CONTEXT_WATCHERS] = {-1, -1}; -static int num_context_object_enter_events[NUM_CONTEXT_WATCHERS] = {0, 0}; -static int num_context_object_exit_events[NUM_CONTEXT_WATCHERS] = {0, 0}; +static PyObject *context_switches[NUM_CONTEXT_WATCHERS]; static int handle_context_watcher_event(int which_watcher, PyContextEvent event, PyObject *ctx) { - if (event == Py_CONTEXT_EVENT_ENTER) { - num_context_object_enter_events[which_watcher]++; - } - else if (event == Py_CONTEXT_EVENT_EXIT) { - num_context_object_exit_events[which_watcher]++; + if (event == Py_CONTEXT_SWITCHED) { + PyList_Append(context_switches[which_watcher], ctx); } else { return -1; @@ -667,31 +663,28 @@ error_context_event_handler(PyContextEvent event, PyObject *ctx) { static PyObject * add_context_watcher(PyObject *self, PyObject *which_watcher) { - int watcher_id; + static const PyContext_WatchCallback callbacks[] = { + &first_context_watcher_callback, + &second_context_watcher_callback, + &error_context_event_handler, + }; assert(PyLong_Check(which_watcher)); long which_l = PyLong_AsLong(which_watcher); - if (which_l == 0) { - watcher_id = PyContext_AddWatcher(first_context_watcher_callback); - context_watcher_ids[0] = watcher_id; - num_context_object_enter_events[0] = 0; - num_context_object_exit_events[0] = 0; - } - else if (which_l == 1) { - watcher_id = PyContext_AddWatcher(second_context_watcher_callback); - context_watcher_ids[1] = watcher_id; - num_context_object_enter_events[1] = 0; - num_context_object_exit_events[1] = 0; - } - else if (which_l == 2) { - watcher_id = PyContext_AddWatcher(error_context_event_handler); - } - else { + if (which_l < 0 || which_l >= (long)Py_ARRAY_LENGTH(callbacks)) { PyErr_Format(PyExc_ValueError, "invalid watcher %d", which_l); return NULL; } + int watcher_id = PyContext_AddWatcher(callbacks[which_l]); if (watcher_id < 0) { return NULL; } + if (which_l >= 0 && which_l < NUM_CONTEXT_WATCHERS) { + context_watcher_ids[which_l] = watcher_id; + Py_XSETREF(context_switches[which_l], PyList_New(0)); + if (context_switches[which_l] == NULL) { + return NULL; + } + } return PyLong_FromLong(watcher_id); } @@ -708,8 +701,7 @@ clear_context_watcher(PyObject *self, PyObject *watcher_id) for (int i = 0; i < NUM_CONTEXT_WATCHERS; i++) { if (watcher_id_l == context_watcher_ids[i]) { context_watcher_ids[i] = -1; - num_context_object_enter_events[i] = 0; - num_context_object_exit_events[i] = 0; + Py_CLEAR(context_switches[i]); } } } @@ -717,21 +709,34 @@ clear_context_watcher(PyObject *self, PyObject *watcher_id) } static PyObject * -get_context_watcher_num_enter_events(PyObject *self, PyObject *watcher_id) +clear_context_stack(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args)) { - assert(PyLong_Check(watcher_id)); - long watcher_id_l = PyLong_AsLong(watcher_id); - assert(watcher_id_l >= 0 && watcher_id_l < NUM_CONTEXT_WATCHERS); - return PyLong_FromLong(num_context_object_enter_events[watcher_id_l]); + PyThreadState *tstate = PyThreadState_Get(); + if (tstate->context == NULL) { + Py_RETURN_NONE; + } + if (((PyContext *)tstate->context)->ctx_prev != NULL) { + PyErr_SetString(PyExc_RuntimeError, + "must first exit all non-base contexts"); + return NULL; + } + Py_CLEAR(tstate->context); + Py_RETURN_NONE; } static PyObject * -get_context_watcher_num_exit_events(PyObject *self, PyObject *watcher_id) +get_context_switches(PyObject *Py_UNUSED(self), PyObject *watcher_id) { assert(PyLong_Check(watcher_id)); long watcher_id_l = PyLong_AsLong(watcher_id); - assert(watcher_id_l >= 0 && watcher_id_l < NUM_CONTEXT_WATCHERS); - return PyLong_FromLong(num_context_object_exit_events[watcher_id_l]); + if (watcher_id_l < 0 || watcher_id_l >= NUM_CONTEXT_WATCHERS) { + PyErr_Format(PyExc_ValueError, "invalid watcher %ld", watcher_id_l); + return NULL; + } + if (context_switches[watcher_id_l] == NULL) { + return PyList_New(0); + } + return Py_NewRef(context_switches[watcher_id_l]); } static PyObject * @@ -835,10 +840,8 @@ static PyMethodDef test_methods[] = { // Code object watchers. {"add_context_watcher", add_context_watcher, METH_O, NULL}, {"clear_context_watcher", clear_context_watcher, METH_O, NULL}, - {"get_context_watcher_num_enter_events", - get_context_watcher_num_enter_events, METH_O, NULL}, - {"get_context_watcher_num_exit_events", - get_context_watcher_num_exit_events, METH_O, NULL}, + {"clear_context_stack", clear_context_stack, METH_NOARGS, NULL}, + {"get_context_switches", get_context_switches, METH_O, NULL}, {"allocate_too_many_context_watchers", (PyCFunction) allocate_too_many_context_watchers, METH_NOARGS, NULL}, {NULL}, diff --git a/Python/context.c b/Python/context.c index 8bc487a33c890b..95aa82206270f9 100644 --- a/Python/context.c +++ b/Python/context.c @@ -102,10 +102,8 @@ PyContext_CopyCurrent(void) static const char * context_event_name(PyContextEvent event) { switch (event) { - case Py_CONTEXT_EVENT_ENTER: - return "Py_CONTEXT_EVENT_ENTER"; - case Py_CONTEXT_EVENT_EXIT: - return "Py_CONTEXT_EVENT_EXIT"; + case Py_CONTEXT_SWITCHED: + return "Py_CONTEXT_SWITCHED"; default: return "?"; } @@ -115,6 +113,13 @@ context_event_name(PyContextEvent event) { static void notify_context_watchers(PyThreadState *ts, PyContextEvent event, PyObject *ctx) { + if (ctx == NULL) { + // This will happen after exiting the last context in the stack, which + // can occur if context_get was never called before entering a context + // (e.g., called `contextvars.Context().run()` on a fresh thread, as + // PyContext_Enter doesn't call context_get). + ctx = Py_None; + } assert(Py_REFCNT(ctx) > 0); PyInterpreterState *interp = ts->interp; assert(interp->_initialized); @@ -175,6 +180,16 @@ PyContext_ClearWatcher(int watcher_id) } +static inline void +context_switched(PyThreadState *ts) +{ + ts->context_ver++; + // ts->context is used instead of context_get() because context_get() might + // throw if ts->context is NULL. + notify_context_watchers(ts, Py_CONTEXT_SWITCHED, ts->context); +} + + static int _PyContext_Enter(PyThreadState *ts, PyObject *octx) { @@ -191,9 +206,7 @@ _PyContext_Enter(PyThreadState *ts, PyObject *octx) ctx->ctx_entered = 1; ts->context = Py_NewRef(ctx); - ts->context_ver++; - - notify_context_watchers(ts, Py_CONTEXT_EVENT_ENTER, octx); + context_switched(ts); return 0; } @@ -227,13 +240,11 @@ _PyContext_Exit(PyThreadState *ts, PyObject *octx) return -1; } - notify_context_watchers(ts, Py_CONTEXT_EVENT_EXIT, octx); Py_SETREF(ts->context, (PyObject *)ctx->ctx_prev); - ts->context_ver++; ctx->ctx_prev = NULL; ctx->ctx_entered = 0; - + context_switched(ts); return 0; } diff --git a/Tools/c-analyzer/cpython/ignored.tsv b/Tools/c-analyzer/cpython/ignored.tsv index e6c599a2ac4a46..2605825d3d0078 100644 --- a/Tools/c-analyzer/cpython/ignored.tsv +++ b/Tools/c-analyzer/cpython/ignored.tsv @@ -455,8 +455,8 @@ Modules/_testcapi/watchers.c - pyfunc_watchers - Modules/_testcapi/watchers.c - func_watcher_ids - Modules/_testcapi/watchers.c - func_watcher_callbacks - Modules/_testcapi/watchers.c - context_watcher_ids - -Modules/_testcapi/watchers.c - num_context_object_enter_events - -Modules/_testcapi/watchers.c - num_context_object_exit_events - +Modules/_testcapi/watchers.c - context_switches - +Modules/_testcapi/watchers.c add_context_watcher callbacks - Modules/_testcapimodule.c - BasicStaticTypes - Modules/_testcapimodule.c - num_basic_static_types_used - Modules/_testcapimodule.c - ContainerNoGC_members - From 0c8c665581ede95fe119f902b070e395614b78ed Mon Sep 17 00:00:00 2001 From: sobolevn Date: Mon, 14 Oct 2024 23:46:17 +0300 Subject: [PATCH 073/170] gh-125470: Fix warning in `Python/generated_cases.c.h` (#125471) Co-authored-by: Kirill Podoprigora --- Python/bytecodes.c | 2 ++ Python/executor_cases.c.h | 2 ++ Python/generated_cases.c.h | 2 ++ 3 files changed, 6 insertions(+) diff --git a/Python/bytecodes.c b/Python/bytecodes.c index b22916aeaa248b..e6525657cabc2b 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -611,7 +611,9 @@ dummy_func( // specializations, but there is no output. // At the end we just skip over the STORE_FAST. op(_BINARY_OP_INPLACE_ADD_UNICODE, (left, right --)) { + #ifndef NDEBUG PyObject *left_o = PyStackRef_AsPyObjectBorrow(left); + #endif PyObject *right_o = PyStackRef_AsPyObjectBorrow(right); int next_oparg; diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 0ed361a2ee7fb0..15a6c7bc1a7966 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -737,7 +737,9 @@ _PyStackRef left; right = stack_pointer[-1]; left = stack_pointer[-2]; + #ifndef NDEBUG PyObject *left_o = PyStackRef_AsPyObjectBorrow(left); + #endif PyObject *right_o = PyStackRef_AsPyObjectBorrow(right); int next_oparg; #if TIER_ONE diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 7bd1b7dd5aba27..a9290986c24f45 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -183,7 +183,9 @@ /* Skip 1 cache entry */ // _BINARY_OP_INPLACE_ADD_UNICODE { + #ifndef NDEBUG PyObject *left_o = PyStackRef_AsPyObjectBorrow(left); + #endif PyObject *right_o = PyStackRef_AsPyObjectBorrow(right); int next_oparg; #if TIER_ONE From 3fea1d000ef0a74062fd3fe218ad94618b08d9f2 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Mon, 14 Oct 2024 17:11:58 -0400 Subject: [PATCH 074/170] Fix idlelib typos (#125484) Propagate fixes in Doc/library/idle.rst to help.html. Change 'interruptable' to 'interruptible' in run.py. The latter was reported by ember91 in PR 125473. --- Lib/idlelib/help.html | 21 ++++++++++++--------- Lib/idlelib/run.py | 12 ++++++------ 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html index 827d230b54e159..2a4adc6a4d395f 100644 --- a/Lib/idlelib/help.html +++ b/Lib/idlelib/help.html @@ -5,7 +5,7 @@ - IDLE — Python 3.13.0a2 documentation + IDLE — Python 3.14.0a0 documentation @@ -18,7 +18,7 @@ @@ -26,6 +26,7 @@ + @@ -45,6 +46,8 @@ + + @@ -184,7 +187,7 @@

Navigation

  • - 3.13.0a2 Documentation » + 3.14.0a0 Documentation »
  • @@ -554,7 +557,7 @@

    Key bindingsControl key on Windows and -Unix and the Command key on macOS. (And all such dicussions +Unix and the Command key on macOS. (And all such discussions assume that the keys have not been re-bound to something else.)

    @@ -694,7 +697,7 @@

    Shell window -
  • C-c attemps to interrupt statement execution (but may fail).

  • +
  • C-c attempts to interrupt statement execution (but may fail).

  • C-d closes Shell if typed at a >>> prompt.

  • Alt-p and Alt-n (C-p and C-n on macOS) retrieve to the current prompt the previous or next previously @@ -1136,7 +1139,7 @@

    Navigation

  • - 3.13.0a2 Documentation » + 3.14.0a0 Documentation »
  • @@ -1180,7 +1183,7 @@

    Navigation



    - Last updated on Jan 17, 2024 (06:57 UTC). + Last updated on Oct 14, 2024 (20:27 UTC). Found a bug?
    diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index 8f98e73258e778..a30db99a619a93 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -108,11 +108,11 @@ def handle_tk_events(tcl=tcl): # Thread shared globals: Establish a queue between a subthread (which handles # the socket) and the main thread (which runs user code), plus global -# completion, exit and interruptable (the main thread) flags: +# completion, exit and interruptible (the main thread) flags: exit_now = False quitting = False -interruptable = False +interruptible = False def main(del_exitfunc=False): """Start the Python execution server in a subprocess @@ -582,14 +582,14 @@ def __init__(self, rpchandler): self.locals = {} def runcode(self, code): - global interruptable + global interruptible try: self.user_exc_info = None - interruptable = True + interruptible = True try: exec(code, self.locals) finally: - interruptable = False + interruptible = False except SystemExit as e: if e.args: # SystemExit called with an argument. ob = e.args[0] @@ -615,7 +615,7 @@ def runcode(self, code): flush_stdout() def interrupt_the_server(self): - if interruptable: + if interruptible: thread.interrupt_main() def start_the_debugger(self, gui_adap_oid): From 2a5cdb251674ce8d9a824c102f7cd846d944cfa4 Mon Sep 17 00:00:00 2001 From: edson duarte Date: Mon, 14 Oct 2024 19:02:58 -0300 Subject: [PATCH 075/170] gh-85453: Improve variable mark up for datetime.rst (#120702) Variables and literals are marked up using backticks. --- Doc/library/datetime.rst | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index f0b465bc9ce39c..2f81080d525f86 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -180,19 +180,19 @@ Objects of the :class:`date` type are always naive. An object of type :class:`.time` or :class:`.datetime` may be aware or naive. -A :class:`.datetime` object *d* is aware if both of the following hold: +A :class:`.datetime` object ``d`` is aware if both of the following hold: 1. ``d.tzinfo`` is not ``None`` 2. ``d.tzinfo.utcoffset(d)`` does not return ``None`` -Otherwise, *d* is naive. +Otherwise, ``d`` is naive. -A :class:`.time` object *t* is aware if both of the following hold: +A :class:`.time` object ``t`` is aware if both of the following hold: 1. ``t.tzinfo`` is not ``None`` 2. ``t.tzinfo.utcoffset(None)`` does not return ``None``. -Otherwise, *t* is naive. +Otherwise, ``t`` is naive. The distinction between aware and naive doesn't apply to :class:`timedelta` objects. @@ -358,8 +358,8 @@ Supported operations: +--------------------------------+-----------------------------------------------+ | ``q, r = divmod(t1, t2)`` | Computes the quotient and the remainder: | | | ``q = t1 // t2`` (3) and ``r = t1 % t2``. | -| | q is an integer and r is a :class:`timedelta` | -| | object. | +| | ``q`` is an integer and ``r`` is a | +| | :class:`timedelta` object. | +--------------------------------+-----------------------------------------------+ | ``+t1`` | Returns a :class:`timedelta` object with the | | | same value. (2) | @@ -526,7 +526,7 @@ Other constructors, all class methods: January 1 of year 1 has ordinal 1. :exc:`ValueError` is raised unless ``1 <= ordinal <= - date.max.toordinal()``. For any date *d*, + date.max.toordinal()``. For any date ``d``, ``date.fromordinal(d.toordinal()) == d``. @@ -730,7 +730,7 @@ Instance methods: .. method:: date.toordinal() Return the proleptic Gregorian ordinal of the date, where January 1 of year 1 - has ordinal 1. For any :class:`date` object *d*, + has ordinal 1. For any :class:`date` object ``d``, ``date.fromordinal(d.toordinal()) == d``. @@ -782,7 +782,7 @@ Instance methods: .. method:: date.__str__() - For a date *d*, ``str(d)`` is equivalent to ``d.isoformat()``. + For a date ``d``, ``str(d)`` is equivalent to ``d.isoformat()``. .. method:: date.ctime() @@ -1063,7 +1063,7 @@ Other constructors, all class methods: is used. If the *date* argument is a :class:`.datetime` object, its time components and :attr:`.tzinfo` attributes are ignored. - For any :class:`.datetime` object *d*, + For any :class:`.datetime` object ``d``, ``d == datetime.combine(d.date(), d.time(), d.tzinfo)``. .. versionchanged:: 3.6 @@ -1270,11 +1270,11 @@ Supported operations: If both are naive, or both are aware and have the same :attr:`~.datetime.tzinfo` attribute, the :attr:`~.datetime.tzinfo` attributes are ignored, and the result is a :class:`timedelta` - object *t* such that ``datetime2 + t == datetime1``. No time zone adjustments + object ``t`` such that ``datetime2 + t == datetime1``. No time zone adjustments are done in this case. If both are aware and have different :attr:`~.datetime.tzinfo` attributes, ``a-b`` acts - as if *a* and *b* were first converted to naive UTC datetimes. The + as if ``a`` and ``b`` were first converted to naive UTC datetimes. The result is ``(a.replace(tzinfo=None) - a.utcoffset()) - (b.replace(tzinfo=None) - b.utcoffset())`` except that the implementation never overflows. @@ -1454,11 +1454,11 @@ Instance methods: .. method:: datetime.utctimetuple() - If :class:`.datetime` instance *d* is naive, this is the same as + If :class:`.datetime` instance ``d`` is naive, this is the same as ``d.timetuple()`` except that :attr:`~.time.struct_time.tm_isdst` is forced to 0 regardless of what ``d.dst()`` returns. DST is never in effect for a UTC time. - If *d* is aware, *d* is normalized to UTC time, by subtracting + If ``d`` is aware, ``d`` is normalized to UTC time, by subtracting ``d.utcoffset()``, and a :class:`time.struct_time` for the normalized time is returned. :attr:`!tm_isdst` is forced to 0. Note that an :exc:`OverflowError` may be raised if ``d.year`` was @@ -1606,7 +1606,7 @@ Instance methods: .. method:: datetime.__str__() - For a :class:`.datetime` instance *d*, ``str(d)`` is equivalent to + For a :class:`.datetime` instance ``d``, ``str(d)`` is equivalent to ``d.isoformat(' ')``. @@ -1853,7 +1853,7 @@ Instance attributes (read-only): .. versionadded:: 3.6 :class:`.time` objects support equality and order comparisons, -where *a* is considered less than *b* when *a* precedes *b* in time. +where ``a`` is considered less than ``b`` when ``a`` precedes ``b`` in time. Naive and aware :class:`!time` objects are never equal. Order comparison between naive and aware :class:`!time` objects raises @@ -2000,7 +2000,7 @@ Instance methods: .. method:: time.__str__() - For a time *t*, ``str(t)`` is equivalent to ``t.isoformat()``. + For a time ``t``, ``str(t)`` is equivalent to ``t.isoformat()``. .. method:: time.strftime(format) From 1bffd7a2a738506a4ad50c6c3c2c32926cce6d14 Mon Sep 17 00:00:00 2001 From: Steven Jin Date: Mon, 14 Oct 2024 18:36:38 -0400 Subject: [PATCH 076/170] gh-124944: Add socket.SO_ORIGINAL_DST (#124945) --- .../Library/2024-10-03-17-13-22.gh-issue-124944.YyLAzf.rst | 1 + Modules/socketmodule.c | 3 +++ Modules/socketmodule.h | 4 ++++ configure | 6 ++++++ configure.ac | 2 +- pyconfig.h.in | 3 +++ 6 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-03-17-13-22.gh-issue-124944.YyLAzf.rst diff --git a/Misc/NEWS.d/next/Library/2024-10-03-17-13-22.gh-issue-124944.YyLAzf.rst b/Misc/NEWS.d/next/Library/2024-10-03-17-13-22.gh-issue-124944.YyLAzf.rst new file mode 100644 index 00000000000000..66af712c5ae5a8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-03-17-13-22.gh-issue-124944.YyLAzf.rst @@ -0,0 +1 @@ +Add ``SO_ORIGINAL_DST`` to the :mod:`socket` module. diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 0829d2358129d2..744e5e0c0b2b54 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -7921,6 +7921,9 @@ socket_exec(PyObject *m) #ifdef SO_OOBINLINE ADD_INT_MACRO(m, SO_OOBINLINE); #endif +#ifdef SO_ORIGINAL_DST + ADD_INT_MACRO(m, SO_ORIGINAL_DST); +#endif #ifndef __GNU__ #ifdef SO_REUSEPORT ADD_INT_MACRO(m, SO_REUSEPORT); diff --git a/Modules/socketmodule.h b/Modules/socketmodule.h index a77c620c2ef630..e1d96377728eb9 100644 --- a/Modules/socketmodule.h +++ b/Modules/socketmodule.h @@ -172,6 +172,10 @@ typedef int socklen_t; # undef AF_VSOCK #endif +#ifdef HAVE_LINUX_NETFILTER_IPV4_H +# include +#endif + #ifdef HAVE_SOCKADDR_ALG # include diff --git a/configure b/configure index 0cc73e4e66552d..c5bec6a1b0d7c2 100755 --- a/configure +++ b/configure @@ -11092,6 +11092,12 @@ if test "x$ac_cv_header_linux_memfd_h" = xyes then : printf "%s\n" "#define HAVE_LINUX_MEMFD_H 1" >>confdefs.h +fi +ac_fn_c_check_header_compile "$LINENO" "linux/netfilter_ipv4.h" "ac_cv_header_linux_netfilter_ipv4_h" "$ac_includes_default" +if test "x$ac_cv_header_linux_netfilter_ipv4_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_NETFILTER_IPV4_H 1" >>confdefs.h + fi ac_fn_c_check_header_compile "$LINENO" "linux/random.h" "ac_cv_header_linux_random_h" "$ac_includes_default" if test "x$ac_cv_header_linux_random_h" = xyes diff --git a/configure.ac b/configure.ac index 1864e94ace9243..d4b7942190207a 100644 --- a/configure.ac +++ b/configure.ac @@ -3013,7 +3013,7 @@ AC_DEFINE([STDC_HEADERS], [1], AC_CHECK_HEADERS([ \ alloca.h asm/types.h bluetooth.h conio.h direct.h dlfcn.h endian.h errno.h fcntl.h grp.h \ io.h langinfo.h libintl.h libutil.h linux/auxvec.h sys/auxv.h linux/fs.h linux/limits.h linux/memfd.h \ - linux/random.h linux/soundcard.h \ + linux/netfilter_ipv4.h linux/random.h linux/soundcard.h \ linux/tipc.h linux/wait.h netdb.h net/ethernet.h netinet/in.h netpacket/packet.h poll.h process.h pthread.h pty.h \ sched.h setjmp.h shadow.h signal.h spawn.h stropts.h sys/audioio.h sys/bsdtty.h sys/devpoll.h \ sys/endian.h sys/epoll.h sys/event.h sys/eventfd.h sys/file.h sys/ioctl.h sys/kern_control.h \ diff --git a/pyconfig.h.in b/pyconfig.h.in index 7f02603e26f5d0..1947d8ee14f83e 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -739,6 +739,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_MEMFD_H +/* Define to 1 if you have the header file. */ +#undef HAVE_LINUX_NETFILTER_IPV4_H + /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_NETLINK_H From 0b28ea4a35dc7c68c97127f7aad8f0175d77c520 Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Mon, 14 Oct 2024 23:45:58 +0100 Subject: [PATCH 077/170] gh-124958: Revert "gh-125472: Revert "gh-124958: fix asyncio.TaskGroup and _PyFuture refcycles ... (#125486) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Revert "gh-125472: Revert "gh-124958: fix asyncio.TaskGroup and _PyFuture refcycles (#12… (#125476)" This reverts commit e99650b80ace3893c2a80b3f2a4aca99cb305191. * fix incompatability with gh-124392 --- Lib/asyncio/futures.py | 6 +- Lib/asyncio/taskgroups.py | 41 +++++-- Lib/test/test_asyncio/test_futures.py | 22 ++++ Lib/test/test_asyncio/test_taskgroups.py | 102 +++++++++++++++++- ...-10-04-08-46-00.gh-issue-124958.rea9-x.rst | 1 + 5 files changed, 157 insertions(+), 15 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-04-08-46-00.gh-issue-124958.rea9-x.rst diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py index 5f6fa2348726cf..c95fce035cd548 100644 --- a/Lib/asyncio/futures.py +++ b/Lib/asyncio/futures.py @@ -190,8 +190,7 @@ def result(self): the future is done and has an exception set, this exception is raised. """ if self._state == _CANCELLED: - exc = self._make_cancelled_error() - raise exc + raise self._make_cancelled_error() if self._state != _FINISHED: raise exceptions.InvalidStateError('Result is not ready.') self.__log_traceback = False @@ -208,8 +207,7 @@ def exception(self): InvalidStateError. """ if self._state == _CANCELLED: - exc = self._make_cancelled_error() - raise exc + raise self._make_cancelled_error() if self._state != _FINISHED: raise exceptions.InvalidStateError('Exception is not set.') self.__log_traceback = False diff --git a/Lib/asyncio/taskgroups.py b/Lib/asyncio/taskgroups.py index f2ee9648c43876..9fa772ca9d02cc 100644 --- a/Lib/asyncio/taskgroups.py +++ b/Lib/asyncio/taskgroups.py @@ -66,6 +66,20 @@ async def __aenter__(self): return self async def __aexit__(self, et, exc, tb): + tb = None + try: + return await self._aexit(et, exc) + finally: + # Exceptions are heavy objects that can have object + # cycles (bad for GC); let's not keep a reference to + # a bunch of them. It would be nicer to use a try/finally + # in __aexit__ directly but that introduced some diff noise + self._parent_task = None + self._errors = None + self._base_error = None + exc = None + + async def _aexit(self, et, exc): self._exiting = True if (exc is not None and @@ -122,7 +136,10 @@ async def __aexit__(self, et, exc, tb): assert not self._tasks if self._base_error is not None: - raise self._base_error + try: + raise self._base_error + finally: + exc = None if self._parent_cancel_requested: # If this flag is set we *must* call uncancel(). @@ -133,8 +150,14 @@ async def __aexit__(self, et, exc, tb): # Propagate CancelledError if there is one, except if there # are other errors -- those have priority. - if propagate_cancellation_error is not None and not self._errors: - raise propagate_cancellation_error + try: + if propagate_cancellation_error is not None and not self._errors: + try: + raise propagate_cancellation_error + finally: + exc = None + finally: + propagate_cancellation_error = None if et is not None and not issubclass(et, exceptions.CancelledError): self._errors.append(exc) @@ -146,14 +169,14 @@ async def __aexit__(self, et, exc, tb): if self._parent_task.cancelling(): self._parent_task.uncancel() self._parent_task.cancel() - # Exceptions are heavy objects that can have object - # cycles (bad for GC); let's not keep a reference to - # a bunch of them. try: - me = BaseExceptionGroup('unhandled errors in a TaskGroup', self._errors) - raise me from None + raise BaseExceptionGroup( + 'unhandled errors in a TaskGroup', + self._errors, + ) from None finally: - self._errors = None + exc = None + def create_task(self, coro, *, name=None, context=None): """Create a new task in this group and return it. diff --git a/Lib/test/test_asyncio/test_futures.py b/Lib/test/test_asyncio/test_futures.py index 458b70451a306a..c566b28adb2408 100644 --- a/Lib/test/test_asyncio/test_futures.py +++ b/Lib/test/test_asyncio/test_futures.py @@ -659,6 +659,28 @@ def __del__(self): fut = self._new_future(loop=self.loop) fut.set_result(Evil()) + def test_future_cancelled_result_refcycles(self): + f = self._new_future(loop=self.loop) + f.cancel() + exc = None + try: + f.result() + except asyncio.CancelledError as e: + exc = e + self.assertIsNotNone(exc) + self.assertListEqual(gc.get_referrers(exc), []) + + def test_future_cancelled_exception_refcycles(self): + f = self._new_future(loop=self.loop) + f.cancel() + exc = None + try: + f.exception() + except asyncio.CancelledError as e: + exc = e + self.assertIsNotNone(exc) + self.assertListEqual(gc.get_referrers(exc), []) + @unittest.skipUnless(hasattr(futures, '_CFuture'), 'requires the C _asyncio module') diff --git a/Lib/test/test_asyncio/test_taskgroups.py b/Lib/test/test_asyncio/test_taskgroups.py index 4852536defc93d..1b4de96a572fb9 100644 --- a/Lib/test/test_asyncio/test_taskgroups.py +++ b/Lib/test/test_asyncio/test_taskgroups.py @@ -1,7 +1,8 @@ # Adapted with permission from the EdgeDB project; # license: PSFL. - +import sys +import gc import asyncio import contextvars import contextlib @@ -11,7 +12,6 @@ from test.test_asyncio.utils import await_without_task - # To prevent a warning "test altered the execution environment" def tearDownModule(): asyncio.set_event_loop_policy(None) @@ -29,6 +29,15 @@ def get_error_types(eg): return {type(exc) for exc in eg.exceptions} +def no_other_refs(): + # due to gh-124392 coroutines now refer to their locals + coro = asyncio.current_task().get_coro() + frame = sys._getframe(1) + while coro.cr_frame != frame: + coro = coro.cr_await + return [coro] + + class TestTaskGroup(unittest.IsolatedAsyncioTestCase): async def test_taskgroup_01(self): @@ -899,6 +908,95 @@ async def outer(): await outer() + async def test_exception_refcycles_direct(self): + """Test that TaskGroup doesn't keep a reference to the raised ExceptionGroup""" + tg = asyncio.TaskGroup() + exc = None + + class _Done(Exception): + pass + + try: + async with tg: + raise _Done + except ExceptionGroup as e: + exc = e + + self.assertIsNotNone(exc) + self.assertListEqual(gc.get_referrers(exc), no_other_refs()) + + + async def test_exception_refcycles_errors(self): + """Test that TaskGroup deletes self._errors, and __aexit__ args""" + tg = asyncio.TaskGroup() + exc = None + + class _Done(Exception): + pass + + try: + async with tg: + raise _Done + except* _Done as excs: + exc = excs.exceptions[0] + + self.assertIsInstance(exc, _Done) + self.assertListEqual(gc.get_referrers(exc), no_other_refs()) + + + async def test_exception_refcycles_parent_task(self): + """Test that TaskGroup deletes self._parent_task""" + tg = asyncio.TaskGroup() + exc = None + + class _Done(Exception): + pass + + async def coro_fn(): + async with tg: + raise _Done + + try: + async with asyncio.TaskGroup() as tg2: + tg2.create_task(coro_fn()) + except* _Done as excs: + exc = excs.exceptions[0].exceptions[0] + + self.assertIsInstance(exc, _Done) + self.assertListEqual(gc.get_referrers(exc), no_other_refs()) + + async def test_exception_refcycles_propagate_cancellation_error(self): + """Test that TaskGroup deletes propagate_cancellation_error""" + tg = asyncio.TaskGroup() + exc = None + + try: + async with asyncio.timeout(-1): + async with tg: + await asyncio.sleep(0) + except TimeoutError as e: + exc = e.__cause__ + + self.assertIsInstance(exc, asyncio.CancelledError) + self.assertListEqual(gc.get_referrers(exc), no_other_refs()) + + async def test_exception_refcycles_base_error(self): + """Test that TaskGroup deletes self._base_error""" + class MyKeyboardInterrupt(KeyboardInterrupt): + pass + + tg = asyncio.TaskGroup() + exc = None + + try: + async with tg: + raise MyKeyboardInterrupt + except MyKeyboardInterrupt as e: + exc = e + + self.assertIsNotNone(exc) + self.assertListEqual(gc.get_referrers(exc), no_other_refs()) + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2024-10-04-08-46-00.gh-issue-124958.rea9-x.rst b/Misc/NEWS.d/next/Library/2024-10-04-08-46-00.gh-issue-124958.rea9-x.rst new file mode 100644 index 00000000000000..534d5bb8c898da --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-04-08-46-00.gh-issue-124958.rea9-x.rst @@ -0,0 +1 @@ +Fix refcycles in exceptions raised from :class:`asyncio.TaskGroup` and the python implementation of :class:`asyncio.Future` From 8d42e2d915c3096e7eac1c649751d1da567bb7c3 Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Mon, 14 Oct 2024 20:09:48 -0400 Subject: [PATCH 078/170] gh-125269: Use `AC_LINK_IF_ELSE` to detect if `-latomic` is needed (#125416) We previously used `AC_RUN_IF_ELSE` with a short test program to detect if `-latomic` is needed, but that requires choosing a specific default value when cross-compiling because the test program is not run. Some cross compilation targets like `wasm32-emscripten` do not support `-latomic`, while other cross compilation targets, like `arm-linux-gnueabi` require it. --- .../2024-10-13-21-11-30.gh-issue-125269.BC-fdo.rst | 2 ++ configure | 12 +++--------- configure.ac | 7 +++---- 3 files changed, 8 insertions(+), 13 deletions(-) create mode 100644 Misc/NEWS.d/next/Build/2024-10-13-21-11-30.gh-issue-125269.BC-fdo.rst diff --git a/Misc/NEWS.d/next/Build/2024-10-13-21-11-30.gh-issue-125269.BC-fdo.rst b/Misc/NEWS.d/next/Build/2024-10-13-21-11-30.gh-issue-125269.BC-fdo.rst new file mode 100644 index 00000000000000..24f5469e8a664b --- /dev/null +++ b/Misc/NEWS.d/next/Build/2024-10-13-21-11-30.gh-issue-125269.BC-fdo.rst @@ -0,0 +1,2 @@ +Fix detection of whether ``-latomic`` is needed when cross-compiling CPython +using the configure script. diff --git a/configure b/configure index c5bec6a1b0d7c2..be119f108a060b 100755 --- a/configure +++ b/configure @@ -28999,10 +28999,6 @@ printf %s "checking whether libatomic is needed by ... " >&6; } if test ${ac_cv_libatomic_needed+y} then : printf %s "(cached) " >&6 -else $as_nop - if test "$cross_compiling" = yes -then : - ac_cv_libatomic_needed=no else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -29044,16 +29040,14 @@ int main() } _ACEOF -if ac_fn_c_try_run "$LINENO" +if ac_fn_c_try_link "$LINENO" then : ac_cv_libatomic_needed=no else $as_nop ac_cv_libatomic_needed=yes fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libatomic_needed" >&5 printf "%s\n" "$ac_cv_libatomic_needed" >&6; } diff --git a/configure.ac b/configure.ac index d4b7942190207a..582851695e400f 100644 --- a/configure.ac +++ b/configure.ac @@ -7497,7 +7497,7 @@ CPPFLAGS="${BASECPPFLAGS} -I. -I${srcdir}/Include ${CPPFLAGS}" AC_CACHE_CHECK([whether libatomic is needed by ], [ac_cv_libatomic_needed], -[AC_RUN_IFELSE([AC_LANG_SOURCE([[ +[AC_LINK_IFELSE([AC_LANG_SOURCE([[ // pyatomic.h needs uint64_t and Py_ssize_t types #include // int64_t, intptr_t #ifdef HAVE_SYS_TYPES_H @@ -7534,9 +7534,8 @@ int main() return 0; // all good } ]])], - [ac_cv_libatomic_needed=no], dnl build succeeded - [ac_cv_libatomic_needed=yes], dnl build failed - [ac_cv_libatomic_needed=no]) dnl cross compilation + [ac_cv_libatomic_needed=no], dnl build and link succeeded + [ac_cv_libatomic_needed=yes]) dnl build and link failed ]) AS_VAR_IF([ac_cv_libatomic_needed], [yes], From a2fe9ff11d6104074c19bf328a104caa99becc11 Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Tue, 15 Oct 2024 09:29:08 +0200 Subject: [PATCH 079/170] Doc: Update CVE URL (#125489) --- Doc/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/conf.py b/Doc/conf.py index d7197b17865854..839beaad08bebd 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -614,7 +614,7 @@ # Sphinx 8.1 has in-built CVE and CWE roles. extlinks |= { "cve": ( - "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-%s", + "https://www.cve.org/CVERecord?id=CVE-%s", "CVE-%s", ), "cwe": ("https://cwe.mitre.org/data/definitions/%s.html", "CWE-%s"), From 66064c342c6fb54b443aae8ccf8db74bb9d8bc50 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 15 Oct 2024 10:39:15 +0300 Subject: [PATCH 080/170] gh-123299: Copyedit "What's New in Python 3.14" (#125438) --- .../c-api-pending-removal-in-3.14.rst | 2 +- .../c-api-pending-removal-in-3.15.rst | 2 +- .../c-api-pending-removal-in-future.rst | 2 +- Doc/deprecations/index.rst | 2 +- Doc/deprecations/pending-removal-in-3.13.rst | 2 +- Doc/deprecations/pending-removal-in-3.14.rst | 2 +- Doc/deprecations/pending-removal-in-3.15.rst | 4 +- Doc/deprecations/pending-removal-in-3.16.rst | 29 +++-- .../pending-removal-in-future.rst | 2 +- Doc/whatsnew/3.14.rst | 110 +++++++++--------- 10 files changed, 79 insertions(+), 78 deletions(-) diff --git a/Doc/deprecations/c-api-pending-removal-in-3.14.rst b/Doc/deprecations/c-api-pending-removal-in-3.14.rst index d16da66c29abe7..9e10bf2691e5c8 100644 --- a/Doc/deprecations/c-api-pending-removal-in-3.14.rst +++ b/Doc/deprecations/c-api-pending-removal-in-3.14.rst @@ -1,4 +1,4 @@ -Pending Removal in Python 3.14 +Pending removal in Python 3.14 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * The ``ma_version_tag`` field in :c:type:`PyDictObject` for extension modules diff --git a/Doc/deprecations/c-api-pending-removal-in-3.15.rst b/Doc/deprecations/c-api-pending-removal-in-3.15.rst index e3974415e0cc89..1bb49e5b4874f2 100644 --- a/Doc/deprecations/c-api-pending-removal-in-3.15.rst +++ b/Doc/deprecations/c-api-pending-removal-in-3.15.rst @@ -1,4 +1,4 @@ -Pending Removal in Python 3.15 +Pending removal in Python 3.15 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * The bundled copy of ``libmpdecimal``. diff --git a/Doc/deprecations/c-api-pending-removal-in-future.rst b/Doc/deprecations/c-api-pending-removal-in-future.rst index 0c3ae52b87ff74..8fc1c80c35d092 100644 --- a/Doc/deprecations/c-api-pending-removal-in-future.rst +++ b/Doc/deprecations/c-api-pending-removal-in-future.rst @@ -1,4 +1,4 @@ -Pending Removal in Future Versions +Pending removal in future versions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The following APIs are deprecated and will be removed, diff --git a/Doc/deprecations/index.rst b/Doc/deprecations/index.rst index a9efb0bc744335..bac6e3f18d4594 100644 --- a/Doc/deprecations/index.rst +++ b/Doc/deprecations/index.rst @@ -7,7 +7,7 @@ Deprecations .. include:: pending-removal-in-future.rst -C API Deprecations +C API deprecations ------------------ .. include:: c-api-pending-removal-in-3.15.rst diff --git a/Doc/deprecations/pending-removal-in-3.13.rst b/Doc/deprecations/pending-removal-in-3.13.rst index 89790497816e83..2fd2f12cc6a2c4 100644 --- a/Doc/deprecations/pending-removal-in-3.13.rst +++ b/Doc/deprecations/pending-removal-in-3.13.rst @@ -1,4 +1,4 @@ -Pending Removal in Python 3.13 +Pending removal in Python 3.13 ------------------------------ Modules (see :pep:`594`): diff --git a/Doc/deprecations/pending-removal-in-3.14.rst b/Doc/deprecations/pending-removal-in-3.14.rst index de30f4695059ed..b8791b8d6c387e 100644 --- a/Doc/deprecations/pending-removal-in-3.14.rst +++ b/Doc/deprecations/pending-removal-in-3.14.rst @@ -1,4 +1,4 @@ -Pending Removal in Python 3.14 +Pending removal in Python 3.14 ------------------------------ * The import system: diff --git a/Doc/deprecations/pending-removal-in-3.15.rst b/Doc/deprecations/pending-removal-in-3.15.rst index a55fb6bea3fdaa..17029b8d4773bd 100644 --- a/Doc/deprecations/pending-removal-in-3.15.rst +++ b/Doc/deprecations/pending-removal-in-3.15.rst @@ -1,4 +1,4 @@ -Pending Removal in Python 3.15 +Pending removal in Python 3.15 ------------------------------ * The import system: @@ -63,7 +63,7 @@ Pending Removal in Python 3.15 * The undocumented keyword argument syntax for creating :class:`~typing.NamedTuple` classes - (e.g. ``Point = NamedTuple("Point", x=int, y=int)``) + (for example, ``Point = NamedTuple("Point", x=int, y=int)``) has been deprecated since Python 3.13. Use the class-based syntax or the functional syntax instead. diff --git a/Doc/deprecations/pending-removal-in-3.16.rst b/Doc/deprecations/pending-removal-in-3.16.rst index fc2ef33de5e5cc..fac500d34742ca 100644 --- a/Doc/deprecations/pending-removal-in-3.16.rst +++ b/Doc/deprecations/pending-removal-in-3.16.rst @@ -1,15 +1,6 @@ -Pending Removal in Python 3.16 +Pending removal in Python 3.16 ------------------------------ -* :mod:`builtins`: - - * Bitwise inversion on boolean types, ``~True`` or ``~False`` - has been deprecated since Python 3.12, - as it produces surprising and unintuitive results (``-2`` and ``-1``). - Use ``not x`` instead for the logical negation of a Boolean. - In the rare case that you need the bitwise inversion of - the underlying integer, convert to ``int`` explicitly (``~int(x)``). - * :mod:`array`: * The ``'u'`` format code (:c:type:`wchar_t`) @@ -20,11 +11,19 @@ Pending Removal in Python 3.16 * :mod:`asyncio`: - * :mod:`asyncio`: - :func:`!asyncio.iscoroutinefunction` is deprecated - and will be removed in Python 3.16, - use :func:`inspect.iscoroutinefunction` instead. - (Contributed by Jiahao Li and Kumar Aditya in :gh:`122875`.) + * :func:`!asyncio.iscoroutinefunction` is deprecated + and will be removed in Python 3.16, + use :func:`inspect.iscoroutinefunction` instead. + (Contributed by Jiahao Li and Kumar Aditya in :gh:`122875`.) + +* :mod:`builtins`: + + * Bitwise inversion on boolean types, ``~True`` or ``~False`` + has been deprecated since Python 3.12, + as it produces surprising and unintuitive results (``-2`` and ``-1``). + Use ``not x`` instead for the logical negation of a Boolean. + In the rare case that you need the bitwise inversion of + the underlying integer, convert to ``int`` explicitly (``~int(x)``). * :mod:`shutil`: diff --git a/Doc/deprecations/pending-removal-in-future.rst b/Doc/deprecations/pending-removal-in-future.rst index 3f9cf6f208221a..f916797c07a068 100644 --- a/Doc/deprecations/pending-removal-in-future.rst +++ b/Doc/deprecations/pending-removal-in-future.rst @@ -1,4 +1,4 @@ -Pending Removal in Future Versions +Pending removal in future versions ---------------------------------- The following APIs will be removed in the future, diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index 25e69a59bdec62..b106578fe9e8b0 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -1,6 +1,6 @@ **************************** - What's New In Python 3.14 + What's new in Python 3.14 **************************** :Editor: TBD @@ -56,7 +56,7 @@ For full details, see the :ref:`changelog `. so it's worth checking back even after reading earlier versions. -Summary -- Release highlights +Summary -- release highlights ============================= .. This section singles out the most important changes in Python 3.14. @@ -67,12 +67,12 @@ Summary -- Release highlights -New Features +New features ============ -.. _whatsnew-314-pep649: +.. _whatsnew314-pep649: -PEP 649: Deferred Evaluation of Annotations +PEP 649: deferred evaluation of annotations ------------------------------------------- The :term:`annotations ` on functions, classes, and modules are no @@ -150,12 +150,12 @@ In Python 3.7, :pep:`563` introduced the ``from __future__ import annotations`` directive, which turns all annotations into strings. This directive is now considered deprecated and it is expected to be removed in a future version of Python. However, this removal will not happen until after Python 3.13, the last version of -Python without deferred evaluation of annotations, reaches its end of life. +Python without deferred evaluation of annotations, reaches its end of life in 2029. In Python 3.14, the behavior of code using ``from __future__ import annotations`` is unchanged. -Improved Error Messages +Improved error messages ----------------------- * When unpacking assignment fails due to incorrect number of variables, the @@ -172,16 +172,16 @@ Improved Error Messages ValueError: too many values to unpack (expected 3, got 4) -Other Language Changes +Other language changes ====================== * Incorrect usage of :keyword:`await` and asynchronous comprehensions is now detected even if the code is optimized away by the :option:`-O` - command line option. For example, ``python -O -c 'assert await 1'`` + command-line option. For example, ``python -O -c 'assert await 1'`` now produces a :exc:`SyntaxError`. (Contributed by Jelle Zijlstra in :gh:`121637`.) * Writes to ``__debug__`` are now detected even if the code is optimized - away by the :option:`-O` command line option. For example, + away by the :option:`-O` command-line option. For example, ``python -O -c 'assert (__debug__ := 1)'`` now produces a :exc:`SyntaxError`. (Contributed by Irit Katriel in :gh:`122245`.) @@ -191,7 +191,7 @@ Other Language Changes (Contributed by Serhiy Storchaka in :gh:`84978`.) -New Modules +New modules =========== * :mod:`annotationlib`: For introspecting :term:`annotations `. @@ -199,7 +199,7 @@ New Modules (Contributed by Jelle Zijlstra in :gh:`119180`.) -Improved Modules +Improved modules ================ argparse @@ -214,7 +214,7 @@ ast --- * Add :func:`ast.compare` for comparing two ASTs. - (Contributed by Batuhan Taskaya and Jeremy Hylton in :issue:`15987`.) + (Contributed by Batuhan Taskaya and Jeremy Hylton in :gh:`60191`.) * Add support for :func:`copy.replace` for AST nodes. (Contributed by Bénédikt Tran in :gh:`121141`.) @@ -246,6 +246,12 @@ decimal :meth:`Decimal.from_number() `. (Contributed by Serhiy Storchaka in :gh:`121798`.) +datetime +-------- + +* Add :meth:`datetime.time.strptime` and :meth:`datetime.date.strptime`. + (Contributed by Wannes Boeykens in :gh:`41431`.) + dis --- @@ -254,9 +260,10 @@ dis This feature is added to the following interfaces via the *show_positions* keyword argument: - - :class:`dis.Bytecode`, - - :func:`dis.dis`, :func:`dis.distb`, and - - :func:`dis.disassemble`. + - :class:`dis.Bytecode` + - :func:`dis.dis` + - :func:`dis.distb` + - :func:`dis.disassemble` This feature is also exposed via :option:`dis --show-positions`. (Contributed by Bénédikt Tran in :gh:`123165`.) @@ -310,7 +317,8 @@ json of the error. (Contributed by Serhiy Storchaka in :gh:`122163`.) -* Enable the :mod:`json` module to work as a script using the :option:`-m` switch: ``python -m json``. +* Enable the :mod:`json` module to work as a script using the :option:`-m` + switch: :program:`python -m json`. See the :ref:`JSON command-line interface ` documentation. (Contributed by Trey Hunner in :gh:`122873`.) @@ -325,12 +333,6 @@ operator (Contributed by Raymond Hettinger and Nico Mexis in :gh:`115808`.) -datetime --------- - -* Add :meth:`datetime.time.strptime` and :meth:`datetime.date.strptime`. - (Contributed by Wannes Boeykens in :gh:`41431`.) - os -- @@ -357,11 +359,11 @@ pathlib pdb --- -* Hard-coded breakpoints (:func:`breakpoint` and :func:`pdb.set_trace`) now +* Hardcoded breakpoints (:func:`breakpoint` and :func:`pdb.set_trace`) now reuse the most recent :class:`~pdb.Pdb` instance that calls :meth:`~pdb.Pdb.set_trace`, instead of creating a new one each time. As a result, all the instance specific data like :pdbcmd:`display` and - :pdbcmd:`commands` are preserved across hard-coded breakpoints. + :pdbcmd:`commands` are preserved across hardcoded breakpoints. (Contributed by Tian Gao in :gh:`121450`.) * Add a new argument *mode* to :class:`pdb.Pdb`. Disable the ``restart`` @@ -391,9 +393,9 @@ symtable * Expose the following :class:`symtable.Symbol` methods: - * :meth:`~symtable.Symbol.is_free_class` - * :meth:`~symtable.Symbol.is_comp_iter` * :meth:`~symtable.Symbol.is_comp_cell` + * :meth:`~symtable.Symbol.is_comp_iter` + * :meth:`~symtable.Symbol.is_free_class` (Contributed by Bénédikt Tran in :gh:`120029`.) @@ -472,11 +474,11 @@ ast * Remove the following classes. They were all deprecated since Python 3.8, and have emitted deprecation warnings since Python 3.12: - * :class:`!ast.Num` - * :class:`!ast.Str` * :class:`!ast.Bytes` - * :class:`!ast.NameConstant` * :class:`!ast.Ellipsis` + * :class:`!ast.NameConstant` + * :class:`!ast.Num` + * :class:`!ast.Str` Use :class:`ast.Constant` instead. As a consequence of these removals, user-defined ``visit_Num``, ``visit_Str``, ``visit_Bytes``, @@ -501,16 +503,16 @@ asyncio * Remove the following classes and functions. They were all deprecated and emitted deprecation warnings since Python 3.12: + * :func:`!asyncio.get_child_watcher` + * :func:`!asyncio.set_child_watcher` + * :meth:`!asyncio.AbstractEventLoopPolicy.get_child_watcher` + * :meth:`!asyncio.AbstractEventLoopPolicy.set_child_watcher` * :class:`!asyncio.AbstractChildWatcher` - * :class:`!asyncio.SafeChildWatcher` - * :class:`!asyncio.MultiLoopChildWatcher` * :class:`!asyncio.FastChildWatcher` - * :class:`!asyncio.ThreadedChildWatcher` + * :class:`!asyncio.MultiLoopChildWatcher` * :class:`!asyncio.PidfdChildWatcher` - * :meth:`!asyncio.AbstractEventLoopPolicy.get_child_watcher` - * :meth:`!asyncio.AbstractEventLoopPolicy.set_child_watcher` - * :func:`!asyncio.get_child_watcher` - * :func:`!asyncio.set_child_watcher` + * :class:`!asyncio.SafeChildWatcher` + * :class:`!asyncio.ThreadedChildWatcher` (Contributed by Kumar Aditya in :gh:`120804`.) @@ -623,14 +625,14 @@ Changes in the Python API (Contributed by Serhiy Storchaka in :gh:`69998`.) -Build Changes +Build changes ============= -C API Changes +C API changes ============= -New Features +New features ------------ * Add :c:func:`PyLong_GetSign` function to get the sign of :class:`int` objects. @@ -640,17 +642,17 @@ New Features object: * :c:func:`PyUnicodeWriter_Create` + * :c:func:`PyUnicodeWriter_DecodeUTF8Stateful` * :c:func:`PyUnicodeWriter_Discard` * :c:func:`PyUnicodeWriter_Finish` + * :c:func:`PyUnicodeWriter_Format` * :c:func:`PyUnicodeWriter_WriteChar` - * :c:func:`PyUnicodeWriter_WriteUTF8` - * :c:func:`PyUnicodeWriter_WriteUCS4` - * :c:func:`PyUnicodeWriter_WriteWideChar` - * :c:func:`PyUnicodeWriter_WriteStr` * :c:func:`PyUnicodeWriter_WriteRepr` + * :c:func:`PyUnicodeWriter_WriteStr` * :c:func:`PyUnicodeWriter_WriteSubstring` - * :c:func:`PyUnicodeWriter_Format` - * :c:func:`PyUnicodeWriter_DecodeUTF8Stateful` + * :c:func:`PyUnicodeWriter_WriteUCS4` + * :c:func:`PyUnicodeWriter_WriteUTF8` + * :c:func:`PyUnicodeWriter_WriteWideChar` (Contributed by Victor Stinner in :gh:`119182`.) @@ -671,14 +673,14 @@ New Features * Add new functions to convert C ```` numbers from/to Python :class:`int`: - * :c:func:`PyLong_FromInt32` - * :c:func:`PyLong_FromInt64` - * :c:func:`PyLong_FromUInt32` - * :c:func:`PyLong_FromUInt64` * :c:func:`PyLong_AsInt32` * :c:func:`PyLong_AsInt64` * :c:func:`PyLong_AsUInt32` * :c:func:`PyLong_AsUInt64` + * :c:func:`PyLong_FromInt32` + * :c:func:`PyLong_FromInt64` + * :c:func:`PyLong_FromUInt32` + * :c:func:`PyLong_FromUInt64` (Contributed by Victor Stinner in :gh:`120389`.) @@ -701,20 +703,20 @@ New Features * Add functions to configure the Python initialization (:pep:`741`): + * :c:func:`Py_InitializeFromInitConfig` + * :c:func:`PyInitConfig_AddModule` * :c:func:`PyInitConfig_Create` * :c:func:`PyInitConfig_Free` + * :c:func:`PyInitConfig_FreeStrList` * :c:func:`PyInitConfig_GetError` * :c:func:`PyInitConfig_GetExitCode` - * :c:func:`PyInitConfig_HasOption` * :c:func:`PyInitConfig_GetInt` * :c:func:`PyInitConfig_GetStr` * :c:func:`PyInitConfig_GetStrList` - * :c:func:`PyInitConfig_FreeStrList` + * :c:func:`PyInitConfig_HasOption` * :c:func:`PyInitConfig_SetInt` * :c:func:`PyInitConfig_SetStr` * :c:func:`PyInitConfig_SetStrList` - * :c:func:`PyInitConfig_AddModule` - * :c:func:`Py_InitializeFromInitConfig` (Contributed by Victor Stinner in :gh:`107954`.) From 92af191a6a5f266b71373f5374ca0c9c522d62d9 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 15 Oct 2024 11:05:40 +0300 Subject: [PATCH 081/170] gh-53203: Fix strptime() tests for %X on glibc < 2.29 (#125469) --- Lib/test/test_strptime.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_strptime.py b/Lib/test/test_strptime.py index 12366b053a2fc1..09f6f656bfcb0d 100644 --- a/Lib/test/test_strptime.py +++ b/Lib/test/test_strptime.py @@ -569,12 +569,20 @@ def test_date_locale2(self): 'ti_ET', 'tig_ER', 'wal_ET') def test_time_locale(self): # Test %X directive + loc = locale.getlocale(locale.LC_TIME)[0] + pos = slice(3, 6) + if glibc_ver and glibc_ver < (2, 29) and loc in { + 'aa_ET', 'am_ET', 'byn_ER', 'gez_ET', 'om_ET', + 'sid_ET', 'so_SO', 'ti_ET', 'tig_ER', 'wal_ET'}: + # Hours are in 12-hour notation without AM/PM indication. + # Ignore hours. + pos = slice(4, 6) now = time.time() - self.roundtrip('%X', slice(3, 6), time.localtime(now)) + self.roundtrip('%X', pos, time.localtime(now)) # 1 hour 20 minutes 30 seconds ago - self.roundtrip('%X', slice(3, 6), time.localtime(now - 4830)) + self.roundtrip('%X', pos, time.localtime(now - 4830)) # 12 hours ago - self.roundtrip('%X', slice(3, 6), time.localtime(now - 12*3600)) + self.roundtrip('%X', pos, time.localtime(now - 12*3600)) def test_percent(self): # Make sure % signs are handled properly From 546dddca43a2a69dbe33d230e9e540636b403270 Mon Sep 17 00:00:00 2001 From: "RUANG (Roy James)" Date: Tue, 15 Oct 2024 17:21:16 +0800 Subject: [PATCH 082/170] gh-125234: Make PyInitConfig_Free(NULL) a no-op (#125266) --- Doc/c-api/init_config.rst | 2 ++ Programs/_testembed.c | 1 + Python/initconfig.c | 3 +++ 3 files changed, 6 insertions(+) diff --git a/Doc/c-api/init_config.rst b/Doc/c-api/init_config.rst index 6f8962afc7af0d..66e845df2e6aa5 100644 --- a/Doc/c-api/init_config.rst +++ b/Doc/c-api/init_config.rst @@ -1621,6 +1621,8 @@ Create Config Free memory of the initialization configuration *config*. + If *config* is ``NULL``, no operation is performed. + Error Handling -------------- diff --git a/Programs/_testembed.c b/Programs/_testembed.c index ab619e32429d63..0fb45b2265e3c6 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -1896,6 +1896,7 @@ static int test_initconfig_api(void) goto error; } PyInitConfig_Free(config); + PyInitConfig_Free(NULL); dump_config(); Py_Finalize(); diff --git a/Python/initconfig.c b/Python/initconfig.c index 58ac5e7d7eaeff..c142438b02bfd9 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -3457,6 +3457,9 @@ PyInitConfig_Create(void) void PyInitConfig_Free(PyInitConfig *config) { + if (config == NULL) { + return; + } free(config->err_msg); free(config); } From aa18fd55d575a04e3aa782fedcd08dced26676e0 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 15 Oct 2024 11:47:36 +0200 Subject: [PATCH 083/170] gh-125196: Use PyUnicodeWriter in HAMT (#125458) --- Python/hamt.c | 81 ++++++++++++++++++++------------------------------- 1 file changed, 31 insertions(+), 50 deletions(-) diff --git a/Python/hamt.c b/Python/hamt.c index a8fbb00b807934..cfd211f4541446 100644 --- a/Python/hamt.c +++ b/Python/hamt.c @@ -349,7 +349,7 @@ hamt_node_find(PyHamtNode *node, #ifdef Py_DEBUG static int hamt_node_dump(PyHamtNode *node, - _PyUnicodeWriter *writer, int level); + PyUnicodeWriter *writer, int level); #endif static PyHamtNode * @@ -444,7 +444,7 @@ hamt_bitindex(uint32_t bitmap, uint32_t bit) #ifdef Py_DEBUG static int -_hamt_dump_ident(_PyUnicodeWriter *writer, int level) +_hamt_dump_ident(PyUnicodeWriter *writer, int level) { /* Write `' ' * level` to the `writer` */ PyObject *str = NULL; @@ -467,7 +467,7 @@ _hamt_dump_ident(_PyUnicodeWriter *writer, int level) goto error; } - ret = _PyUnicodeWriter_WriteStr(writer, res); + ret = PyUnicodeWriter_WriteStr(writer, res); error: Py_XDECREF(res); @@ -476,29 +476,6 @@ _hamt_dump_ident(_PyUnicodeWriter *writer, int level) return ret; } -static int -_hamt_dump_format(_PyUnicodeWriter *writer, const char *format, ...) -{ - /* A convenient helper combining _PyUnicodeWriter_WriteStr and - PyUnicode_FromFormatV. - */ - PyObject* msg; - int ret; - - va_list vargs; - va_start(vargs, format); - msg = PyUnicode_FromFormatV(format, vargs); - va_end(vargs); - - if (msg == NULL) { - return -1; - } - - ret = _PyUnicodeWriter_WriteStr(writer, msg); - Py_DECREF(msg); - return ret; -} - #endif /* Py_DEBUG */ /////////////////////////////////// Bitmap Node @@ -1154,7 +1131,7 @@ hamt_node_bitmap_dealloc(PyHamtNode_Bitmap *self) #ifdef Py_DEBUG static int hamt_node_bitmap_dump(PyHamtNode_Bitmap *node, - _PyUnicodeWriter *writer, int level) + PyUnicodeWriter *writer, int level) { /* Debug build: __dump__() method implementation for Bitmap nodes. */ @@ -1166,8 +1143,8 @@ hamt_node_bitmap_dump(PyHamtNode_Bitmap *node, goto error; } - if (_hamt_dump_format(writer, "BitmapNode(size=%zd count=%zd ", - Py_SIZE(node), Py_SIZE(node) / 2)) + if (PyUnicodeWriter_Format(writer, "BitmapNode(size=%zd count=%zd ", + Py_SIZE(node), Py_SIZE(node) / 2) < 0) { goto error; } @@ -1181,7 +1158,9 @@ hamt_node_bitmap_dump(PyHamtNode_Bitmap *node, if (tmp2 == NULL) { goto error; } - if (_hamt_dump_format(writer, "bitmap=%S id=%p):\n", tmp2, node)) { + if (PyUnicodeWriter_Format(writer, "bitmap=%S id=%p):\n", + tmp2, node) < 0) + { Py_DECREF(tmp2); goto error; } @@ -1196,7 +1175,7 @@ hamt_node_bitmap_dump(PyHamtNode_Bitmap *node, } if (key_or_null == NULL) { - if (_hamt_dump_format(writer, "NULL:\n")) { + if (PyUnicodeWriter_WriteUTF8(writer, "NULL:\n", -1) < 0) { goto error; } @@ -1207,14 +1186,14 @@ hamt_node_bitmap_dump(PyHamtNode_Bitmap *node, } } else { - if (_hamt_dump_format(writer, "%R: %R", key_or_null, - val_or_node)) + if (PyUnicodeWriter_Format(writer, "%R: %R", + key_or_null, val_or_node) < 0) { goto error; } } - if (_hamt_dump_format(writer, "\n")) { + if (PyUnicodeWriter_WriteUTF8(writer, "\n", 1) < 0) { goto error; } } @@ -1548,7 +1527,7 @@ hamt_node_collision_dealloc(PyHamtNode_Collision *self) #ifdef Py_DEBUG static int hamt_node_collision_dump(PyHamtNode_Collision *node, - _PyUnicodeWriter *writer, int level) + PyUnicodeWriter *writer, int level) { /* Debug build: __dump__() method implementation for Collision nodes. */ @@ -1558,8 +1537,8 @@ hamt_node_collision_dump(PyHamtNode_Collision *node, goto error; } - if (_hamt_dump_format(writer, "CollisionNode(size=%zd id=%p):\n", - Py_SIZE(node), node)) + if (PyUnicodeWriter_Format(writer, "CollisionNode(size=%zd id=%p):\n", + Py_SIZE(node), node) < 0) { goto error; } @@ -1572,7 +1551,7 @@ hamt_node_collision_dump(PyHamtNode_Collision *node, goto error; } - if (_hamt_dump_format(writer, "%R: %R\n", key, val)) { + if (PyUnicodeWriter_Format(writer, "%R: %R\n", key, val) < 0) { goto error; } } @@ -1924,7 +1903,7 @@ hamt_node_array_dealloc(PyHamtNode_Array *self) #ifdef Py_DEBUG static int hamt_node_array_dump(PyHamtNode_Array *node, - _PyUnicodeWriter *writer, int level) + PyUnicodeWriter *writer, int level) { /* Debug build: __dump__() method implementation for Array nodes. */ @@ -1934,7 +1913,7 @@ hamt_node_array_dump(PyHamtNode_Array *node, goto error; } - if (_hamt_dump_format(writer, "ArrayNode(id=%p):\n", node)) { + if (PyUnicodeWriter_Format(writer, "ArrayNode(id=%p):\n", node) < 0) { goto error; } @@ -1947,7 +1926,7 @@ hamt_node_array_dump(PyHamtNode_Array *node, goto error; } - if (_hamt_dump_format(writer, "%zd::\n", i)) { + if (PyUnicodeWriter_Format(writer, "%zd::\n", i) < 0) { goto error; } @@ -1955,7 +1934,7 @@ hamt_node_array_dump(PyHamtNode_Array *node, goto error; } - if (_hamt_dump_format(writer, "\n")) { + if (PyUnicodeWriter_WriteUTF8(writer, "\n", 1) < 0) { goto error; } } @@ -2071,7 +2050,7 @@ hamt_node_find(PyHamtNode *node, #ifdef Py_DEBUG static int hamt_node_dump(PyHamtNode *node, - _PyUnicodeWriter *writer, int level) + PyUnicodeWriter *writer, int level) { /* Debug build: __dump__() method implementation for a node. @@ -2440,22 +2419,24 @@ _PyHamt_New(void) static PyObject * hamt_dump(PyHamtObject *self) { - _PyUnicodeWriter writer; - - _PyUnicodeWriter_Init(&writer); + PyUnicodeWriter *writer = PyUnicodeWriter_Create(0); + if (writer == NULL) { + return NULL; + } - if (_hamt_dump_format(&writer, "HAMT(len=%zd):\n", self->h_count)) { + if (PyUnicodeWriter_Format(writer, "HAMT(len=%zd):\n", + self->h_count) < 0) { goto error; } - if (hamt_node_dump(self->h_root, &writer, 0)) { + if (hamt_node_dump(self->h_root, writer, 0)) { goto error; } - return _PyUnicodeWriter_Finish(&writer); + return PyUnicodeWriter_Finish(writer); error: - _PyUnicodeWriter_Dealloc(&writer); + PyUnicodeWriter_Discard(writer); return NULL; } #endif /* Py_DEBUG */ From fcef3fc9a593e2aa868d23cf2d91c57d8bf60ac6 Mon Sep 17 00:00:00 2001 From: foreignmeloman Date: Tue, 15 Oct 2024 14:26:19 +0400 Subject: [PATCH 084/170] =?UTF-8?q?gh-119535:=20Support=20=F0=9D=9C=8Bthon?= =?UTF-8?q?=20in=20Python=203.14=20venvs=20(#125035)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Lib/venv/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/venv/__init__.py b/Lib/venv/__init__.py index a00fa690fa0b88..a5d348ba4cf121 100644 --- a/Lib/venv/__init__.py +++ b/Lib/venv/__init__.py @@ -306,7 +306,7 @@ def setup_python(self, context): suffixes = ['python', 'python3', f'python3.{sys.version_info[1]}'] if sys.version_info[:2] == (3, 14): - suffixes.append('python𝜋') + suffixes.append('𝜋thon') for suffix in suffixes: path = os.path.join(binpath, suffix) if not os.path.exists(path): From cc5a225cdc2a5d4e035dd08d59cef39182c10a6c Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Tue, 15 Oct 2024 13:29:43 +0200 Subject: [PATCH 085/170] gh-125041: test_zlib: For s390x HW acceleration, only skip checking the compressed bytes (#125042) --- Lib/test/support/__init__.py | 6 ++--- Lib/test/test_zlib.py | 25 ++++++++++++------- ...-10-07-14-13-38.gh-issue-125041.PKLWDf.rst | 3 +++ 3 files changed, 22 insertions(+), 12 deletions(-) create mode 100644 Misc/NEWS.d/next/Tests/2024-10-07-14-13-38.gh-issue-125041.PKLWDf.rst diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index d768bead7120c7..f05be2b6bdf496 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -2625,9 +2625,9 @@ def exceeds_recursion_limit(): return get_c_recursion_limit() * 3 -#Windows doesn't have os.uname() but it doesn't support s390x. -skip_on_s390x = unittest.skipIf(hasattr(os, 'uname') and os.uname().machine == 's390x', - 'skipped on s390x') +# Windows doesn't have os.uname() but it doesn't support s390x. +is_s390x = hasattr(os, 'uname') and os.uname().machine == 's390x' +skip_on_s390x = unittest.skipIf(is_s390x, 'skipped on s390x') Py_TRACE_REFS = hasattr(sys, 'getobjects') diff --git a/Lib/test/test_zlib.py b/Lib/test/test_zlib.py index ef02c64f886f8a..8b4bb8750f8f5c 100644 --- a/Lib/test/test_zlib.py +++ b/Lib/test/test_zlib.py @@ -6,7 +6,7 @@ import pickle import random import sys -from test.support import bigmemtest, _1G, _4G, skip_on_s390x +from test.support import bigmemtest, _1G, _4G, is_s390x zlib = import_helper.import_module('zlib') @@ -33,8 +33,9 @@ def _zlib_runtime_version_tuple(zlib_version=zlib.ZLIB_RUNTIME_VERSION): ZLIB_RUNTIME_VERSION_TUPLE = _zlib_runtime_version_tuple() -# bpo-46623: On s390x, when a hardware accelerator is used, using different -# ways to compress data with zlib can produce different compressed data. +# bpo-46623: When a hardware accelerator is used (currently only on s390x), +# using different ways to compress data with zlib can produce different +# compressed data. # Simplified test_pair() code: # # def func1(data): @@ -57,8 +58,10 @@ def _zlib_runtime_version_tuple(zlib_version=zlib.ZLIB_RUNTIME_VERSION): # # zlib.decompress(func1(data)) == zlib.decompress(func2(data)) == data # -# Make the assumption that s390x always has an accelerator to simplify the skip -# condition. +# To simplify the skip condition, make the assumption that s390x always has an +# accelerator, and nothing else has it. +HW_ACCELERATED = is_s390x + class VersionTestCase(unittest.TestCase): @@ -223,12 +226,14 @@ def test_keywords(self): bufsize=zlib.DEF_BUF_SIZE), HAMLET_SCENE) - @skip_on_s390x def test_speech128(self): # compress more data data = HAMLET_SCENE * 128 x = zlib.compress(data) - self.assertEqual(zlib.compress(bytearray(data)), x) + # With hardware acceleration, the compressed bytes + # might not be identical. + if not HW_ACCELERATED: + self.assertEqual(zlib.compress(bytearray(data)), x) for ob in x, bytearray(x): self.assertEqual(zlib.decompress(ob), data) @@ -275,7 +280,6 @@ def test_64bit_compress(self, size): class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase): # Test compression object - @skip_on_s390x def test_pair(self): # straightforward compress/decompress objects datasrc = HAMLET_SCENE * 128 @@ -286,7 +290,10 @@ def test_pair(self): x1 = co.compress(data) x2 = co.flush() self.assertRaises(zlib.error, co.flush) # second flush should not work - self.assertEqual(x1 + x2, datazip) + # With hardware acceleration, the compressed bytes might not + # be identical. + if not HW_ACCELERATED: + self.assertEqual(x1 + x2, datazip) for v1, v2 in ((x1, x2), (bytearray(x1), bytearray(x2))): dco = zlib.decompressobj() y1 = dco.decompress(v1 + v2) diff --git a/Misc/NEWS.d/next/Tests/2024-10-07-14-13-38.gh-issue-125041.PKLWDf.rst b/Misc/NEWS.d/next/Tests/2024-10-07-14-13-38.gh-issue-125041.PKLWDf.rst new file mode 100644 index 00000000000000..c7181eb9c1f3a9 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2024-10-07-14-13-38.gh-issue-125041.PKLWDf.rst @@ -0,0 +1,3 @@ +Re-enable skipped tests for :mod:`zlib` on the s390x architecture: only skip +checks of the compressed bytes, which can be different between zlib's +software implementation and the hardware-accelerated implementation. From c8a1818fb01937b66b93728c11d68c9f9af688a5 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Tue, 15 Oct 2024 16:12:32 +0300 Subject: [PATCH 086/170] gh-125517: Fix unreachable code warnings in `_testembed.c` (#125518) --- Doc/c-api/init_config.rst | 16 ++++++++++------ Programs/_testembed.c | 20 ++++++++++++-------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/Doc/c-api/init_config.rst b/Doc/c-api/init_config.rst index 66e845df2e6aa5..6194d7446c73e4 100644 --- a/Doc/c-api/init_config.rst +++ b/Doc/c-api/init_config.rst @@ -1825,14 +1825,18 @@ return ``-1`` on error: PyInitConfig_Free(config); return 0; - // Display the error message - const char *err_msg; error: - (void)PyInitConfig_GetError(config, &err_msg); - printf("PYTHON INIT ERROR: %s\n", err_msg); - PyInitConfig_Free(config); + { + // Display the error message + // This uncommon braces style is used, because you cannot make + // goto targets point to variable declarations. + const char *err_msg; + (void)PyInitConfig_GetError(config, &err_msg); + printf("PYTHON INIT ERROR: %s\n", err_msg); + PyInitConfig_Free(config); - return -1; + return -1; + } } diff --git a/Programs/_testembed.c b/Programs/_testembed.c index 0fb45b2265e3c6..d15dd519dbf6af 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -1902,11 +1902,13 @@ static int test_initconfig_api(void) Py_Finalize(); return 0; - const char *err_msg; error: - (void)PyInitConfig_GetError(config, &err_msg); - printf("Python init failed: %s\n", err_msg); - exit(1); + { + const char *err_msg; + (void)PyInitConfig_GetError(config, &err_msg); + printf("Python init failed: %s\n", err_msg); + exit(1); + } } @@ -2050,11 +2052,13 @@ static int test_initconfig_module(void) Py_Finalize(); return 0; - const char *err_msg; error: - (void)PyInitConfig_GetError(config, &err_msg); - printf("Python init failed: %s\n", err_msg); - exit(1); + { + const char *err_msg; + (void)PyInitConfig_GetError(config, &err_msg); + printf("Python init failed: %s\n", err_msg); + exit(1); + } } From 55c4f4c30b49734ce35dc88139b8b4fdc94c66fd Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Tue, 15 Oct 2024 15:11:02 +0100 Subject: [PATCH 087/170] gh-125514: fix bug in test_traceback utility. Specify exception types in except: clauses (#125516) --- Lib/test/test_traceback.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index 455fea034198a6..77ef0c5b3c480d 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -150,7 +150,7 @@ def test_no_caret_with_no_debug_ranges_flag_python_traceback(self): import traceback try: x = 1 / 0 - except: + except ZeroDivisionError: traceback.print_exc() """) try: @@ -550,9 +550,10 @@ class PurePythonExceptionFormattingMixin: def get_exception(self, callable, slice_start=0, slice_end=-1): try: callable() - self.fail("No exception thrown.") - except: + except BaseException: return traceback.format_exc().splitlines()[slice_start:slice_end] + else: + self.fail("No exception thrown.") callable_line = get_exception.__code__.co_firstlineno + 2 @@ -2237,7 +2238,7 @@ def test_context_suppression(self): try: try: raise Exception - except: + except Exception: raise ZeroDivisionError from None except ZeroDivisionError as _: e = _ @@ -2589,9 +2590,9 @@ def exc(): try: try: raise EG("eg1", [ValueError(1), TypeError(2)]) - except: + except EG: raise EG("eg2", [ValueError(3), TypeError(4)]) - except: + except EG: raise ImportError(5) expected = ( @@ -2641,7 +2642,7 @@ def exc(): except Exception as e: exc = e raise EG("eg", [VE(1), exc, VE(4)]) - except: + except EG: raise EG("top", [VE(5)]) expected = (f' + Exception Group Traceback (most recent call last):\n' @@ -3454,7 +3455,7 @@ def test_long_context_chain(self): def f(): try: 1/0 - except: + except ZeroDivisionError: f() try: @@ -3558,7 +3559,7 @@ def test_comparison_params_variations(self): def raise_exc(): try: raise ValueError('bad value') - except: + except ValueError: raise def raise_with_locals(): From d3c82b9ccedd77fc302f5ab8ab0220b3372f574c Mon Sep 17 00:00:00 2001 From: Kirill Podoprigora Date: Tue, 15 Oct 2024 17:42:16 +0300 Subject: [PATCH 088/170] gh-125512: Revert "gh-124872: Replace enter/exit events with "switched" (#124776)" (#125513) --- Doc/c-api/contextvars.rst | 14 +++-- Include/cpython/context.h | 17 ++++-- Lib/test/test_capi/test_watchers.py | 89 ++++++++++++++-------------- Modules/_testcapi/watchers.c | 79 ++++++++++++------------ Python/context.c | 31 ++++------ Tools/c-analyzer/cpython/ignored.tsv | 4 +- 6 files changed, 117 insertions(+), 117 deletions(-) diff --git a/Doc/c-api/contextvars.rst b/Doc/c-api/contextvars.rst index b7c6550ff34aac..8eba54a80dc80d 100644 --- a/Doc/c-api/contextvars.rst +++ b/Doc/c-api/contextvars.rst @@ -123,10 +123,16 @@ Context object management functions: Enumeration of possible context object watcher events: - - ``Py_CONTEXT_SWITCHED``: The :term:`current context` has switched to a - different context. The object passed to the watch callback is the - now-current :class:`contextvars.Context` object, or None if no context is - current. + - ``Py_CONTEXT_EVENT_ENTER``: A context has been entered, causing the + :term:`current context` to switch to it. The object passed to the watch + callback is the now-current :class:`contextvars.Context` object. Each + enter event will eventually have a corresponding exit event for the same + context object after any subsequently entered contexts have themselves been + exited. + - ``Py_CONTEXT_EVENT_EXIT``: A context is about to be exited, which will + cause the :term:`current context` to switch back to what it was before the + context was entered. The object passed to the watch callback is the + still-current :class:`contextvars.Context` object. .. versionadded:: 3.14 diff --git a/Include/cpython/context.h b/Include/cpython/context.h index 3a7a4b459c09ad..3c9be7873b9399 100644 --- a/Include/cpython/context.h +++ b/Include/cpython/context.h @@ -29,11 +29,20 @@ PyAPI_FUNC(int) PyContext_Exit(PyObject *); typedef enum { /* - * The current context has switched to a different context. The object - * passed to the watch callback is the now-current contextvars.Context - * object, or None if no context is current. + * A context has been entered, causing the "current context" to switch to + * it. The object passed to the watch callback is the now-current + * contextvars.Context object. Each enter event will eventually have a + * corresponding exit event for the same context object after any + * subsequently entered contexts have themselves been exited. */ - Py_CONTEXT_SWITCHED = 1, + Py_CONTEXT_EVENT_ENTER, + /* + * A context is about to be exited, which will cause the "current context" + * to switch back to what it was before the context was entered. The + * object passed to the watch callback is the still-current + * contextvars.Context object. + */ + Py_CONTEXT_EVENT_EXIT, } PyContextEvent; /* diff --git a/Lib/test/test_capi/test_watchers.py b/Lib/test/test_capi/test_watchers.py index 4680d6765de122..f21d2627c6094b 100644 --- a/Lib/test/test_capi/test_watchers.py +++ b/Lib/test/test_capi/test_watchers.py @@ -577,62 +577,68 @@ class TestContextObjectWatchers(unittest.TestCase): def context_watcher(self, which_watcher): wid = _testcapi.add_context_watcher(which_watcher) try: - switches = _testcapi.get_context_switches(which_watcher) - except ValueError: - switches = None - try: - yield switches + yield wid finally: _testcapi.clear_context_watcher(wid) - def assert_event_counts(self, want_0, want_1): - self.assertEqual(len(_testcapi.get_context_switches(0)), want_0) - self.assertEqual(len(_testcapi.get_context_switches(1)), want_1) + def assert_event_counts(self, exp_enter_0, exp_exit_0, + exp_enter_1, exp_exit_1): + self.assertEqual( + exp_enter_0, _testcapi.get_context_watcher_num_enter_events(0)) + self.assertEqual( + exp_exit_0, _testcapi.get_context_watcher_num_exit_events(0)) + self.assertEqual( + exp_enter_1, _testcapi.get_context_watcher_num_enter_events(1)) + self.assertEqual( + exp_exit_1, _testcapi.get_context_watcher_num_exit_events(1)) def test_context_object_events_dispatched(self): # verify that all counts are zero before any watchers are registered - self.assert_event_counts(0, 0) + self.assert_event_counts(0, 0, 0, 0) # verify that all counts remain zero when a context object is # entered and exited with no watchers registered ctx = contextvars.copy_context() - ctx.run(self.assert_event_counts, 0, 0) - self.assert_event_counts(0, 0) + ctx.run(self.assert_event_counts, 0, 0, 0, 0) + self.assert_event_counts(0, 0, 0, 0) # verify counts are as expected when first watcher is registered with self.context_watcher(0): - self.assert_event_counts(0, 0) - ctx.run(self.assert_event_counts, 1, 0) - self.assert_event_counts(2, 0) + self.assert_event_counts(0, 0, 0, 0) + ctx.run(self.assert_event_counts, 1, 0, 0, 0) + self.assert_event_counts(1, 1, 0, 0) # again with second watcher registered with self.context_watcher(1): - self.assert_event_counts(2, 0) - ctx.run(self.assert_event_counts, 3, 1) - self.assert_event_counts(4, 2) + self.assert_event_counts(1, 1, 0, 0) + ctx.run(self.assert_event_counts, 2, 1, 1, 0) + self.assert_event_counts(2, 2, 1, 1) # verify counts are reset and don't change after both watchers are cleared - ctx.run(self.assert_event_counts, 0, 0) - self.assert_event_counts(0, 0) - - def test_callback_error(self): - ctx_outer = contextvars.copy_context() - ctx_inner = contextvars.copy_context() - unraisables = [] - - def _in_outer(): - with self.context_watcher(2): - with catch_unraisable_exception() as cm: - ctx_inner.run(lambda: unraisables.append(cm.unraisable)) - unraisables.append(cm.unraisable) - - ctx_outer.run(_in_outer) - self.assertEqual([x.err_msg for x in unraisables], - ["Exception ignored in Py_CONTEXT_SWITCHED " - f"watcher callback for {ctx!r}" - for ctx in [ctx_inner, ctx_outer]]) - self.assertEqual([str(x.exc_value) for x in unraisables], - ["boom!", "boom!"]) + ctx.run(self.assert_event_counts, 0, 0, 0, 0) + self.assert_event_counts(0, 0, 0, 0) + + def test_enter_error(self): + with self.context_watcher(2): + with catch_unraisable_exception() as cm: + ctx = contextvars.copy_context() + ctx.run(int, 0) + self.assertEqual( + cm.unraisable.err_msg, + "Exception ignored in " + f"Py_CONTEXT_EVENT_EXIT watcher callback for {ctx!r}" + ) + self.assertEqual(str(cm.unraisable.exc_value), "boom!") + + def test_exit_error(self): + ctx = contextvars.copy_context() + def _in_context(stack): + stack.enter_context(self.context_watcher(2)) + + with catch_unraisable_exception() as cm: + with ExitStack() as stack: + ctx.run(_in_context, stack) + self.assertEqual(str(cm.unraisable.exc_value), "boom!") def test_clear_out_of_range_watcher_id(self): with self.assertRaisesRegex(ValueError, r"Invalid context watcher ID -1"): @@ -648,12 +654,5 @@ def test_allocate_too_many_watchers(self): with self.assertRaisesRegex(RuntimeError, r"no more context watcher IDs available"): _testcapi.allocate_too_many_context_watchers() - def test_exit_base_context(self): - ctx = contextvars.Context() - _testcapi.clear_context_stack() - with self.context_watcher(0) as switches: - ctx.run(lambda: None) - self.assertEqual(switches, [ctx, None]) - if __name__ == "__main__": unittest.main() diff --git a/Modules/_testcapi/watchers.c b/Modules/_testcapi/watchers.c index 321d3aeffb6ad1..b4233d07134aea 100644 --- a/Modules/_testcapi/watchers.c +++ b/Modules/_testcapi/watchers.c @@ -626,12 +626,16 @@ allocate_too_many_func_watchers(PyObject *self, PyObject *args) // Test contexct object watchers #define NUM_CONTEXT_WATCHERS 2 static int context_watcher_ids[NUM_CONTEXT_WATCHERS] = {-1, -1}; -static PyObject *context_switches[NUM_CONTEXT_WATCHERS]; +static int num_context_object_enter_events[NUM_CONTEXT_WATCHERS] = {0, 0}; +static int num_context_object_exit_events[NUM_CONTEXT_WATCHERS] = {0, 0}; static int handle_context_watcher_event(int which_watcher, PyContextEvent event, PyObject *ctx) { - if (event == Py_CONTEXT_SWITCHED) { - PyList_Append(context_switches[which_watcher], ctx); + if (event == Py_CONTEXT_EVENT_ENTER) { + num_context_object_enter_events[which_watcher]++; + } + else if (event == Py_CONTEXT_EVENT_EXIT) { + num_context_object_exit_events[which_watcher]++; } else { return -1; @@ -663,28 +667,31 @@ error_context_event_handler(PyContextEvent event, PyObject *ctx) { static PyObject * add_context_watcher(PyObject *self, PyObject *which_watcher) { - static const PyContext_WatchCallback callbacks[] = { - &first_context_watcher_callback, - &second_context_watcher_callback, - &error_context_event_handler, - }; + int watcher_id; assert(PyLong_Check(which_watcher)); long which_l = PyLong_AsLong(which_watcher); - if (which_l < 0 || which_l >= (long)Py_ARRAY_LENGTH(callbacks)) { + if (which_l == 0) { + watcher_id = PyContext_AddWatcher(first_context_watcher_callback); + context_watcher_ids[0] = watcher_id; + num_context_object_enter_events[0] = 0; + num_context_object_exit_events[0] = 0; + } + else if (which_l == 1) { + watcher_id = PyContext_AddWatcher(second_context_watcher_callback); + context_watcher_ids[1] = watcher_id; + num_context_object_enter_events[1] = 0; + num_context_object_exit_events[1] = 0; + } + else if (which_l == 2) { + watcher_id = PyContext_AddWatcher(error_context_event_handler); + } + else { PyErr_Format(PyExc_ValueError, "invalid watcher %d", which_l); return NULL; } - int watcher_id = PyContext_AddWatcher(callbacks[which_l]); if (watcher_id < 0) { return NULL; } - if (which_l >= 0 && which_l < NUM_CONTEXT_WATCHERS) { - context_watcher_ids[which_l] = watcher_id; - Py_XSETREF(context_switches[which_l], PyList_New(0)); - if (context_switches[which_l] == NULL) { - return NULL; - } - } return PyLong_FromLong(watcher_id); } @@ -701,7 +708,8 @@ clear_context_watcher(PyObject *self, PyObject *watcher_id) for (int i = 0; i < NUM_CONTEXT_WATCHERS; i++) { if (watcher_id_l == context_watcher_ids[i]) { context_watcher_ids[i] = -1; - Py_CLEAR(context_switches[i]); + num_context_object_enter_events[i] = 0; + num_context_object_exit_events[i] = 0; } } } @@ -709,34 +717,21 @@ clear_context_watcher(PyObject *self, PyObject *watcher_id) } static PyObject * -clear_context_stack(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args)) +get_context_watcher_num_enter_events(PyObject *self, PyObject *watcher_id) { - PyThreadState *tstate = PyThreadState_Get(); - if (tstate->context == NULL) { - Py_RETURN_NONE; - } - if (((PyContext *)tstate->context)->ctx_prev != NULL) { - PyErr_SetString(PyExc_RuntimeError, - "must first exit all non-base contexts"); - return NULL; - } - Py_CLEAR(tstate->context); - Py_RETURN_NONE; + assert(PyLong_Check(watcher_id)); + long watcher_id_l = PyLong_AsLong(watcher_id); + assert(watcher_id_l >= 0 && watcher_id_l < NUM_CONTEXT_WATCHERS); + return PyLong_FromLong(num_context_object_enter_events[watcher_id_l]); } static PyObject * -get_context_switches(PyObject *Py_UNUSED(self), PyObject *watcher_id) +get_context_watcher_num_exit_events(PyObject *self, PyObject *watcher_id) { assert(PyLong_Check(watcher_id)); long watcher_id_l = PyLong_AsLong(watcher_id); - if (watcher_id_l < 0 || watcher_id_l >= NUM_CONTEXT_WATCHERS) { - PyErr_Format(PyExc_ValueError, "invalid watcher %ld", watcher_id_l); - return NULL; - } - if (context_switches[watcher_id_l] == NULL) { - return PyList_New(0); - } - return Py_NewRef(context_switches[watcher_id_l]); + assert(watcher_id_l >= 0 && watcher_id_l < NUM_CONTEXT_WATCHERS); + return PyLong_FromLong(num_context_object_exit_events[watcher_id_l]); } static PyObject * @@ -840,8 +835,10 @@ static PyMethodDef test_methods[] = { // Code object watchers. {"add_context_watcher", add_context_watcher, METH_O, NULL}, {"clear_context_watcher", clear_context_watcher, METH_O, NULL}, - {"clear_context_stack", clear_context_stack, METH_NOARGS, NULL}, - {"get_context_switches", get_context_switches, METH_O, NULL}, + {"get_context_watcher_num_enter_events", + get_context_watcher_num_enter_events, METH_O, NULL}, + {"get_context_watcher_num_exit_events", + get_context_watcher_num_exit_events, METH_O, NULL}, {"allocate_too_many_context_watchers", (PyCFunction) allocate_too_many_context_watchers, METH_NOARGS, NULL}, {NULL}, diff --git a/Python/context.c b/Python/context.c index 95aa82206270f9..8bc487a33c890b 100644 --- a/Python/context.c +++ b/Python/context.c @@ -102,8 +102,10 @@ PyContext_CopyCurrent(void) static const char * context_event_name(PyContextEvent event) { switch (event) { - case Py_CONTEXT_SWITCHED: - return "Py_CONTEXT_SWITCHED"; + case Py_CONTEXT_EVENT_ENTER: + return "Py_CONTEXT_EVENT_ENTER"; + case Py_CONTEXT_EVENT_EXIT: + return "Py_CONTEXT_EVENT_EXIT"; default: return "?"; } @@ -113,13 +115,6 @@ context_event_name(PyContextEvent event) { static void notify_context_watchers(PyThreadState *ts, PyContextEvent event, PyObject *ctx) { - if (ctx == NULL) { - // This will happen after exiting the last context in the stack, which - // can occur if context_get was never called before entering a context - // (e.g., called `contextvars.Context().run()` on a fresh thread, as - // PyContext_Enter doesn't call context_get). - ctx = Py_None; - } assert(Py_REFCNT(ctx) > 0); PyInterpreterState *interp = ts->interp; assert(interp->_initialized); @@ -180,16 +175,6 @@ PyContext_ClearWatcher(int watcher_id) } -static inline void -context_switched(PyThreadState *ts) -{ - ts->context_ver++; - // ts->context is used instead of context_get() because context_get() might - // throw if ts->context is NULL. - notify_context_watchers(ts, Py_CONTEXT_SWITCHED, ts->context); -} - - static int _PyContext_Enter(PyThreadState *ts, PyObject *octx) { @@ -206,7 +191,9 @@ _PyContext_Enter(PyThreadState *ts, PyObject *octx) ctx->ctx_entered = 1; ts->context = Py_NewRef(ctx); - context_switched(ts); + ts->context_ver++; + + notify_context_watchers(ts, Py_CONTEXT_EVENT_ENTER, octx); return 0; } @@ -240,11 +227,13 @@ _PyContext_Exit(PyThreadState *ts, PyObject *octx) return -1; } + notify_context_watchers(ts, Py_CONTEXT_EVENT_EXIT, octx); Py_SETREF(ts->context, (PyObject *)ctx->ctx_prev); + ts->context_ver++; ctx->ctx_prev = NULL; ctx->ctx_entered = 0; - context_switched(ts); + return 0; } diff --git a/Tools/c-analyzer/cpython/ignored.tsv b/Tools/c-analyzer/cpython/ignored.tsv index 2605825d3d0078..e6c599a2ac4a46 100644 --- a/Tools/c-analyzer/cpython/ignored.tsv +++ b/Tools/c-analyzer/cpython/ignored.tsv @@ -455,8 +455,8 @@ Modules/_testcapi/watchers.c - pyfunc_watchers - Modules/_testcapi/watchers.c - func_watcher_ids - Modules/_testcapi/watchers.c - func_watcher_callbacks - Modules/_testcapi/watchers.c - context_watcher_ids - -Modules/_testcapi/watchers.c - context_switches - -Modules/_testcapi/watchers.c add_context_watcher callbacks - +Modules/_testcapi/watchers.c - num_context_object_enter_events - +Modules/_testcapi/watchers.c - num_context_object_exit_events - Modules/_testcapimodule.c - BasicStaticTypes - Modules/_testcapimodule.c - num_basic_static_types_used - Modules/_testcapimodule.c - ContainerNoGC_members - From 703227dd021491ceb9343f69fa48f4b6a05adbb3 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Tue, 15 Oct 2024 07:51:37 -0700 Subject: [PATCH 089/170] gh-125422: Don't set the caller's f_trace if it's botframe (#125427) --- Lib/bdb.py | 5 +++-- Lib/test/test_bdb.py | 13 +++++++++++++ Lib/test/test_pdb.py | 14 ++++++++++++++ .../2024-10-14-04-44-12.gh-issue-125422.MlVuC6.rst | 1 + 4 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-14-04-44-12.gh-issue-125422.MlVuC6.rst diff --git a/Lib/bdb.py b/Lib/bdb.py index 666f9714eb9b7a..9755d61dd2696c 100644 --- a/Lib/bdb.py +++ b/Lib/bdb.py @@ -350,9 +350,10 @@ def _set_caller_tracefunc(self, current_frame): # Issue #13183: pdb skips frames after hitting a breakpoint and running # step commands. # Restore the trace function in the caller (that may not have been set - # for performance reasons) when returning from the current frame. + # for performance reasons) when returning from the current frame, unless + # the caller is the botframe. caller_frame = current_frame.f_back - if caller_frame and not caller_frame.f_trace: + if caller_frame and not caller_frame.f_trace and caller_frame is not self.botframe: caller_frame.f_trace = self.trace_dispatch # Derived classes and clients can call the following methods diff --git a/Lib/test/test_bdb.py b/Lib/test/test_bdb.py index 10c58c04dfd25e..f15dae13eb384e 100644 --- a/Lib/test/test_bdb.py +++ b/Lib/test/test_bdb.py @@ -1217,6 +1217,19 @@ def main(): with TracerRun(self) as tracer: tracer.runcall(tfunc_import) + def test_next_to_botframe(self): + # gh-125422 + # Check that next command won't go to the bottom frame. + code = """ + lno = 2 + """ + self.expect_set = [ + ('line', 2, ''), ('step', ), + ('return', 2, ''), ('next', ), + ] + with TracerRun(self) as tracer: + tracer.run(compile(textwrap.dedent(code), '', 'exec')) + class TestRegressions(unittest.TestCase): def test_format_stack_entry_no_lineno(self): diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 46eb00261042bc..3dc65fdfc03409 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -3393,6 +3393,20 @@ def test_issue26053(self): self.assertRegex(res, "Restarting .* with arguments:\na b c") self.assertRegex(res, "Restarting .* with arguments:\nd e f") + def test_step_into_botframe(self): + # gh-125422 + # pdb should not be able to step into the botframe (bdb.py) + script = "x = 1" + commands = """ + step + step + step + quit + """ + stdout, _ = self.run_pdb_script(script, commands) + self.assertIn("The program finished", stdout) + self.assertNotIn("bdb.py", stdout) + def test_pdbrc_basic(self): script = textwrap.dedent(""" a = 1 diff --git a/Misc/NEWS.d/next/Library/2024-10-14-04-44-12.gh-issue-125422.MlVuC6.rst b/Misc/NEWS.d/next/Library/2024-10-14-04-44-12.gh-issue-125422.MlVuC6.rst new file mode 100644 index 00000000000000..c890ecec8beaf8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-14-04-44-12.gh-issue-125422.MlVuC6.rst @@ -0,0 +1 @@ +Fixed the bug where :mod:`pdb` and :mod:`bdb` can step into the bottom caller frame. From b903fc38d8ec74f61fb5ca8a3f5fd025915bceac Mon Sep 17 00:00:00 2001 From: Mikhail Efimov Date: Tue, 15 Oct 2024 18:38:19 +0300 Subject: [PATCH 090/170] gh-119786: fix typo in compiler.md (#125456) --- InternalDocs/compiler.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/InternalDocs/compiler.md b/InternalDocs/compiler.md index f27e73b274511f..acef6def563154 100644 --- a/InternalDocs/compiler.md +++ b/InternalDocs/compiler.md @@ -515,7 +515,7 @@ Important files Creates C structs corresponding to the ASDL types. Also contains code for marshalling AST nodes (core ASDL types have marshalling code in [Python/asdl.c](https://github.com/python/cpython/blob/main/Python/asdl.c)). - "File automatically generated by + File automatically generated by [Parser/asdl_c.py](https://github.com/python/cpython/blob/main/Parser/asdl_c.py). This file must be committed separately after every grammar change is committed since the ``__version__`` value is set to the latest @@ -572,7 +572,7 @@ Important files * [Include/internal/pycore_ast.h](https://github.com/python/cpython/blob/main/Include/internal/pycore_ast.h) : Contains the actual definitions of the C structs as generated by [Python/Python-ast.c](https://github.com/python/cpython/blob/main/Python/Python-ast.c) - "Automatically generated by + Automatically generated by [Parser/asdl_c.py](https://github.com/python/cpython/blob/main/Parser/asdl_c.py). * [Include/internal/pycore_asdl.h](https://github.com/python/cpython/blob/main/Include/internal/pycore_asdl.h) From c6e8ff86b2bf8cf597622d416f8befae940366fa Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 15 Oct 2024 17:42:55 +0200 Subject: [PATCH 091/170] gh-125451: Skip concurrent.futures test_processes_terminate() (#125533) The test hangs randomly. It tries to serialize local lock and a local function which are not possible. --- Lib/test/test_concurrent_futures/test_shutdown.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Lib/test/test_concurrent_futures/test_shutdown.py b/Lib/test/test_concurrent_futures/test_shutdown.py index 7a4065afd46fc8..ba3618614a9bf9 100644 --- a/Lib/test/test_concurrent_futures/test_shutdown.py +++ b/Lib/test/test_concurrent_futures/test_shutdown.py @@ -253,6 +253,9 @@ def test_cancel_futures_wait_false(self): class ProcessPoolShutdownTest(ExecutorShutdownTest): + # gh-125451: 'lock' cannot be serialized, the test is broken + # and hangs randomly + @unittest.skipIf(True, "broken test") def test_processes_terminate(self): def acquire_lock(lock): lock.acquire() From bb9604b62ae7f043594ffea9287f9213067cc7fb Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Tue, 15 Oct 2024 08:45:23 -0700 Subject: [PATCH 092/170] gh-100141: Allow pdb to deal with empty file (#125425) --- Lib/pdb.py | 3 +-- Lib/test/test_pdb.py | 10 ++++++++++ .../2024-10-14-02-27-03.gh-issue-100141.NuAcwa.rst | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-14-02-27-03.gh-issue-100141.NuAcwa.rst diff --git a/Lib/pdb.py b/Lib/pdb.py index d9aed24bfcd8e7..2b36b1e3fa7cbe 100644 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -429,8 +429,7 @@ def user_call(self, frame, argument_list): def user_line(self, frame): """This function is called when we stop or break at this line.""" if self._wait_for_mainpyfile: - if (self.mainpyfile != self.canonic(frame.f_code.co_filename) - or frame.f_lineno <= 0): + if (self.mainpyfile != self.canonic(frame.f_code.co_filename)): return self._wait_for_mainpyfile = False self.bp_commands(frame) diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 3dc65fdfc03409..474d31f1ae03d9 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -3999,6 +3999,16 @@ def _create_fake_frozen_module(): # verify that pdb found the source of the "frozen" function self.assertIn('x = "Sentinel string for gh-93696"', stdout, "Sentinel statement not found") + def test_empty_file(self): + script = '' + commands = 'q\n' + # We check that pdb stopped at line 0, but anything reasonable + # is acceptable here, as long as it does not halt + stdout, _ = self.run_pdb_script(script, commands) + self.assertIn('main.py(0)', stdout) + stdout, _ = self.run_pdb_module(script, commands) + self.assertIn('__main__.py(0)', stdout) + def test_non_utf8_encoding(self): script_dir = os.path.join(os.path.dirname(__file__), 'encoded_modules') for filename in os.listdir(script_dir): diff --git a/Misc/NEWS.d/next/Library/2024-10-14-02-27-03.gh-issue-100141.NuAcwa.rst b/Misc/NEWS.d/next/Library/2024-10-14-02-27-03.gh-issue-100141.NuAcwa.rst new file mode 100644 index 00000000000000..c366b0ad4040d3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-14-02-27-03.gh-issue-100141.NuAcwa.rst @@ -0,0 +1 @@ +Fixed the bug where :mod:`pdb` will be stuck in an infinite loop when debugging an empty file. From c9826c11db25e81b1a90c837f84074879f1b1126 Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Tue, 15 Oct 2024 08:48:28 -0700 Subject: [PATCH 093/170] gh-89819: Add argument_default and conflict_handler to add_argument_group() docs (GH-125379) --- Doc/library/argparse.rst | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index d58c75eef3e739..51ab8e29ff96d5 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -1808,7 +1808,8 @@ FileType objects Argument groups ^^^^^^^^^^^^^^^ -.. method:: ArgumentParser.add_argument_group(title=None, description=None) +.. method:: ArgumentParser.add_argument_group(title=None, description=None, *, \ + [argument_default], [conflict_handler]) By default, :class:`ArgumentParser` groups command-line arguments into "positional arguments" and "options" when displaying help @@ -1853,6 +1854,11 @@ Argument groups --bar BAR bar help + The optional, keyword-only parameters argument_default_ and conflict_handler_ + allow for finer-grained control of the behavior of the argument group. These + parameters have the same meaning as in the :class:`ArgumentParser` constructor, + but apply specifically to the argument group rather than the entire parser. + Note that any arguments not in your user-defined groups will end up back in the usual "positional arguments" and "optional arguments" sections. From e97910cdb76c1f1dadfc4721b828611e4f4b6449 Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Tue, 15 Oct 2024 17:00:04 +0100 Subject: [PATCH 094/170] gh-125522 : add explicit exception types to bare excepts in tests (#125523) --- Lib/test/test_cmd_line_script.py | 2 +- Lib/test/test_coroutines.py | 2 +- Lib/test/test_file.py | 2 +- Lib/test/test_listcomps.py | 4 ++-- Lib/test/test_logging.py | 2 +- Lib/test/test_pdb.py | 4 ++-- Lib/test/test_peepholer.py | 2 +- Lib/test/test_raise.py | 28 +++++++++++++-------------- Lib/test/test_sys_setprofile.py | 14 +++++++------- Lib/test/test_unittest/test_result.py | 14 +++++++------- Lib/test/test_with.py | 2 +- 11 files changed, 38 insertions(+), 38 deletions(-) diff --git a/Lib/test/test_cmd_line_script.py b/Lib/test/test_cmd_line_script.py index 3a5a8abf81e43d..f30107225ff612 100644 --- a/Lib/test/test_cmd_line_script.py +++ b/Lib/test/test_cmd_line_script.py @@ -543,7 +543,7 @@ def test_pep_409_verbiage(self): script = textwrap.dedent("""\ try: raise ValueError - except: + except ValueError: raise NameError from None """) with os_helper.temp_dir() as script_dir: diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py index a677301c62becc..e6d65e7d90abb1 100644 --- a/Lib/test/test_coroutines.py +++ b/Lib/test/test_coroutines.py @@ -1185,7 +1185,7 @@ async def f(): async def g(): try: raise KeyError - except: + except KeyError: return await f() _, result = run_async(g()) diff --git a/Lib/test/test_file.py b/Lib/test/test_file.py index 9df55278693531..1206032a93566e 100644 --- a/Lib/test/test_file.py +++ b/Lib/test/test_file.py @@ -126,7 +126,7 @@ def testMethods(self): # it must also return None if an exception was given try: 1/0 - except: + except ZeroDivisionError: self.assertEqual(self.f.__exit__(*sys.exc_info()), None) def testReadWhenWriting(self): diff --git a/Lib/test/test_listcomps.py b/Lib/test/test_listcomps.py index 45644d6c092782..cffdeeacc5d73b 100644 --- a/Lib/test/test_listcomps.py +++ b/Lib/test/test_listcomps.py @@ -609,7 +609,7 @@ def test_comp_in_try_except(self): result = snapshot = None try: result = [{func}(value) for value in value] - except: + except ValueError: snapshot = value raise """ @@ -643,7 +643,7 @@ def test_exception_in_post_comp_call(self): value = [1, None] try: [v for v in value].sort() - except: + except TypeError: pass """ self._check_in_scopes(code, {"value": [1, None]}) diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index d4ceb7c8dc0b41..e72f222e1c7eeb 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -4877,7 +4877,7 @@ def test_formatting(self): r.addHandler(h) try: raise RuntimeError('deliberate mistake') - except: + except RuntimeError: logging.exception('failed', stack_info=True) r.removeHandler(h) h.close() diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 474d31f1ae03d9..084b7cd4cad219 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -1081,7 +1081,7 @@ def test_convenience_variables(): ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() ... try: ... raise Exception('test') - ... except: + ... except Exception: ... pass ... return 1 @@ -1153,7 +1153,7 @@ def test_convenience_variables(): Exception('test') (Pdb) next > (5)util_function() - -> except: + -> except Exception: (Pdb) $_exception *** KeyError: '_exception' (Pdb) return diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py index dd3eaeb39e7fe3..b143f3d27a1537 100644 --- a/Lib/test/test_peepholer.py +++ b/Lib/test/test_peepholer.py @@ -766,7 +766,7 @@ def test_load_fast_unknown_after_error_2(self): def f(): try: 1 / 0 - except: + except ZeroDivisionError: print(a, b, c, d, e, f, g) a = b = c = d = e = f = g = 1 self.assertInBytecode(f, 'LOAD_FAST_CHECK') diff --git a/Lib/test/test_raise.py b/Lib/test/test_raise.py index 6d26a61bee4292..dcf0753bc828f3 100644 --- a/Lib/test/test_raise.py +++ b/Lib/test/test_raise.py @@ -48,7 +48,7 @@ def test_except_reraise(self): def reraise(): try: raise TypeError("foo") - except: + except TypeError: try: raise KeyError("caught") except KeyError: @@ -60,7 +60,7 @@ def test_finally_reraise(self): def reraise(): try: raise TypeError("foo") - except: + except TypeError: try: raise KeyError("caught") finally: @@ -73,7 +73,7 @@ def nested_reraise(): def reraise(): try: raise TypeError("foo") - except: + except TypeError: nested_reraise() self.assertRaises(TypeError, reraise) @@ -81,7 +81,7 @@ def test_raise_from_None(self): try: try: raise TypeError("foo") - except: + except TypeError: raise ValueError() from None except ValueError as e: self.assertIsInstance(e.__context__, TypeError) @@ -91,7 +91,7 @@ def test_with_reraise1(self): def reraise(): try: raise TypeError("foo") - except: + except TypeError: with Context(): pass raise @@ -101,7 +101,7 @@ def test_with_reraise2(self): def reraise(): try: raise TypeError("foo") - except: + except TypeError: with Context(): raise KeyError("caught") raise @@ -111,7 +111,7 @@ def test_yield_reraise(self): def reraise(): try: raise TypeError("foo") - except: + except TypeError: yield 1 raise g = reraise() @@ -314,7 +314,7 @@ def test_instance_context_instance_raise(self): try: try: raise context - except: + except IndexError: raise OSError() except OSError as e: self.assertIs(e.__context__, context) @@ -326,7 +326,7 @@ def test_class_context_instance_raise(self): try: try: raise context - except: + except IndexError: raise OSError() except OSError as e: self.assertIsNot(e.__context__, context) @@ -339,7 +339,7 @@ def test_class_context_class_raise(self): try: try: raise context - except: + except IndexError: raise OSError except OSError as e: self.assertIsNot(e.__context__, context) @@ -351,7 +351,7 @@ def test_c_exception_context(self): try: try: 1/0 - except: + except ZeroDivisionError: raise OSError except OSError as e: self.assertIsInstance(e.__context__, ZeroDivisionError) @@ -362,7 +362,7 @@ def test_c_exception_raise(self): try: try: 1/0 - except: + except ZeroDivisionError: xyzzy except NameError as e: self.assertIsInstance(e.__context__, ZeroDivisionError) @@ -459,7 +459,7 @@ def f(): try: try: raise ValueError - except: + except ValueError: del g raise KeyError except Exception as e: @@ -475,7 +475,7 @@ class C: def __del__(self): try: 1/0 - except: + except ZeroDivisionError: raise def f(): diff --git a/Lib/test/test_sys_setprofile.py b/Lib/test/test_sys_setprofile.py index b2e8e8a15b67ea..311a4d2cafe88d 100644 --- a/Lib/test/test_sys_setprofile.py +++ b/Lib/test/test_sys_setprofile.py @@ -124,7 +124,7 @@ def f(p): def test_caught_exception(self): def f(p): try: 1/0 - except: pass + except ZeroDivisionError: pass f_ident = ident(f) self.check_events(f, [(1, 'call', f_ident), (1, 'return', f_ident), @@ -133,7 +133,7 @@ def f(p): def test_caught_nested_exception(self): def f(p): try: 1/0 - except: pass + except ZeroDivisionError: pass f_ident = ident(f) self.check_events(f, [(1, 'call', f_ident), (1, 'return', f_ident), @@ -156,9 +156,9 @@ def f(p): def g(p): try: f(p) - except: + except ZeroDivisionError: try: f(p) - except: pass + except ZeroDivisionError: pass f_ident = ident(f) g_ident = ident(g) self.check_events(g, [(1, 'call', g_ident), @@ -187,7 +187,7 @@ def g(p): def test_raise_twice(self): def f(p): try: 1/0 - except: 1/0 + except ZeroDivisionError: 1/0 f_ident = ident(f) self.check_events(f, [(1, 'call', f_ident), (1, 'return', f_ident), @@ -196,7 +196,7 @@ def f(p): def test_raise_reraise(self): def f(p): try: 1/0 - except: raise + except ZeroDivisionError: raise f_ident = ident(f) self.check_events(f, [(1, 'call', f_ident), (1, 'return', f_ident), @@ -320,7 +320,7 @@ def f(p): def test_caught_exception(self): def f(p): try: 1/0 - except: pass + except ZeroDivisionError: pass f_ident = ident(f) self.check_events(f, [(1, 'call', f_ident), (1, 'return', f_ident), diff --git a/Lib/test/test_unittest/test_result.py b/Lib/test/test_unittest/test_result.py index 15e3f62ef66a4b..4e5ec54e9c892a 100644 --- a/Lib/test/test_unittest/test_result.py +++ b/Lib/test/test_unittest/test_result.py @@ -186,7 +186,7 @@ def test_1(self): test = Foo('test_1') try: test.fail("foo") - except: + except AssertionError: exc_info_tuple = sys.exc_info() result = unittest.TestResult() @@ -214,7 +214,7 @@ def test_1(self): def get_exc_info(): try: test.fail("foo") - except: + except AssertionError: return sys.exc_info() exc_info_tuple = get_exc_info() @@ -241,9 +241,9 @@ def get_exc_info(): try: try: test.fail("foo") - except: + except AssertionError: raise ValueError(42) - except: + except ValueError: return sys.exc_info() exc_info_tuple = get_exc_info() @@ -271,7 +271,7 @@ def get_exc_info(): loop.__cause__ = loop loop.__context__ = loop raise loop - except: + except Exception: return sys.exc_info() exc_info_tuple = get_exc_info() @@ -300,7 +300,7 @@ def get_exc_info(): ex1.__cause__ = ex2 ex2.__context__ = ex1 raise C - except: + except Exception: return sys.exc_info() exc_info_tuple = get_exc_info() @@ -345,7 +345,7 @@ def test_1(self): test = Foo('test_1') try: raise TypeError() - except: + except TypeError: exc_info_tuple = sys.exc_info() result = unittest.TestResult() diff --git a/Lib/test/test_with.py b/Lib/test/test_with.py index 839cdec68d573e..e3e2de09496728 100644 --- a/Lib/test/test_with.py +++ b/Lib/test/test_with.py @@ -719,7 +719,7 @@ def testExceptionInExprList(self): try: with self.Dummy() as a, self.InitRaises(): pass - except: + except RuntimeError: pass self.assertTrue(a.enter_called) self.assertTrue(a.exit_called) From 54c6fcbefd33a8d8bf8c004cf1aad3be3d37b933 Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Tue, 15 Oct 2024 12:09:35 -0400 Subject: [PATCH 095/170] gh-124375: Avoid calling `_PyMem_ProcessDelayed` on other thread states (#124459) This fixes a crash when running the PyO3 test suite on the free-threaded build. The `qsbr` field is initialized after the `PyThreadState` is added to the interpreter's linked list -- it might still be NULL. Instead, we "steal" the queue of to-be-freed memory blocks. This is always initialized (possibly empty) and protected by the stop the world pause. --- ...4-10-15-15-29-41.gh-issue-124375.wNrWVa.rst | 1 + Python/gc_free_threading.c | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-10-15-15-29-41.gh-issue-124375.wNrWVa.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-10-15-15-29-41.gh-issue-124375.wNrWVa.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-15-15-29-41.gh-issue-124375.wNrWVa.rst new file mode 100644 index 00000000000000..4bd17a6e683bc7 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-15-15-29-41.gh-issue-124375.wNrWVa.rst @@ -0,0 +1 @@ +Fix a crash in the free threading build when the GC runs concurrently with a new thread starting. diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c index 38564d9d9b0058..3814cd46e2b440 100644 --- a/Python/gc_free_threading.c +++ b/Python/gc_free_threading.c @@ -420,18 +420,24 @@ merge_queued_objects(_PyThreadStateImpl *tstate, struct collection_state *state) static void process_delayed_frees(PyInterpreterState *interp) { - // In STW status, we can observe the latest write sequence by - // advancing the write sequence immediately. + // While we are in a "stop the world" pause, we can observe the latest + // write sequence by advancing the write sequence immediately. _Py_qsbr_advance(&interp->qsbr); _PyThreadStateImpl *current_tstate = (_PyThreadStateImpl *)_PyThreadState_GET(); _Py_qsbr_quiescent_state(current_tstate->qsbr); + + // Merge the queues from other threads into our own queue so that we can + // process all of the pending delayed free requests at once. HEAD_LOCK(&_PyRuntime); - PyThreadState *tstate = interp->threads.head; - while (tstate != NULL) { - _PyMem_ProcessDelayed(tstate); - tstate = (PyThreadState *)tstate->next; + for (PyThreadState *p = interp->threads.head; p != NULL; p = p->next) { + _PyThreadStateImpl *other = (_PyThreadStateImpl *)p; + if (other != current_tstate) { + llist_concat(¤t_tstate->mem_free_queue, &other->mem_free_queue); + } } HEAD_UNLOCK(&_PyRuntime); + + _PyMem_ProcessDelayed((PyThreadState *)current_tstate); } // Subtract an incoming reference from the computed "gc_refs" refcount. From aac89b54c5ee03c4d64fbdfbb6ea3001e26aa83a Mon Sep 17 00:00:00 2001 From: Mikhail Efimov Date: Tue, 15 Oct 2024 19:17:10 +0300 Subject: [PATCH 096/170] gh-125206: Bug in ctypes with old libffi is fixed (#125322) Workaround for old libffi versions is added. Module ctypes now supports C11 double complex only with libffi >= 3.3.0. Co-authored-by: Sergey B Kirpichev --- Lib/test/test_ctypes/test_libc.py | 2 +- ...-10-11-18-03-05.gh-issue-125206.pWRRK6.rst | 2 + Modules/_ctypes/_ctypes.c | 2 +- Modules/_ctypes/_ctypes_test.c | 6 +- Modules/_ctypes/callproc.c | 4 +- Modules/_ctypes/cfield.c | 8 +-- Modules/_ctypes/ctypes.h | 6 +- configure | 64 +++++++++++++++++++ configure.ac | 40 ++++++++++++ pyconfig.h.in | 3 + 10 files changed, 121 insertions(+), 16 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-11-18-03-05.gh-issue-125206.pWRRK6.rst diff --git a/Lib/test/test_ctypes/test_libc.py b/Lib/test/test_ctypes/test_libc.py index cab3cc9f46003a..df7dbc0ae264a0 100644 --- a/Lib/test/test_ctypes/test_libc.py +++ b/Lib/test/test_ctypes/test_libc.py @@ -23,7 +23,7 @@ def test_sqrt(self): self.assertEqual(lib.my_sqrt(2.0), math.sqrt(2.0)) @unittest.skipUnless(hasattr(ctypes, "c_double_complex"), - "requires C11 complex type") + "requires C11 complex type and libffi >= 3.3.0") def test_csqrt(self): lib.my_csqrt.argtypes = ctypes.c_double_complex, lib.my_csqrt.restype = ctypes.c_double_complex diff --git a/Misc/NEWS.d/next/Library/2024-10-11-18-03-05.gh-issue-125206.pWRRK6.rst b/Misc/NEWS.d/next/Library/2024-10-11-18-03-05.gh-issue-125206.pWRRK6.rst new file mode 100644 index 00000000000000..ef7975ebcb376b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-11-18-03-05.gh-issue-125206.pWRRK6.rst @@ -0,0 +1,2 @@ +Workaround for old libffi versions is added. Module ctypes supports +:c:expr:`double complex` only with libffi >= 3.3.0. Patch by Mikhail Efimov. diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 8435ee4090b9e5..d6a5b75a03d3fe 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -1747,7 +1747,7 @@ class _ctypes.c_void_p "PyObject *" "clinic_state_sub()->PyCSimpleType_Type" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=dd4d9646c56f43a9]*/ -#if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE) +#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX) static const char SIMPLE_TYPE_CHARS[] = "cbBhHiIlLdCEFfuzZqQPXOv?g"; #else static const char SIMPLE_TYPE_CHARS[] = "cbBhHiIlLdfuzZqQPXOv?g"; diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c index 5142bb81cf685c..7bac592fd38fb9 100644 --- a/Modules/_ctypes/_ctypes_test.c +++ b/Modules/_ctypes/_ctypes_test.c @@ -13,9 +13,7 @@ #include -#include // FFI_TARGET_HAS_COMPLEX_TYPE - -#if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE) +#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX) # include "../_complex.h" // csqrt() # undef I // for _ctypes_test_generated.c.h #endif @@ -449,7 +447,7 @@ EXPORT(double) my_sqrt(double a) return sqrt(a); } -#if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE) +#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX) EXPORT(double complex) my_csqrt(double complex a) { return csqrt(a); diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index fd89d9c67b3fc0..5ac9cf16681645 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -105,7 +105,7 @@ module _ctypes #include "pycore_global_objects.h"// _Py_ID() #include "pycore_traceback.h" // _PyTraceback_Add() -#if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE) +#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX) #include "../_complex.h" // complex #endif @@ -655,7 +655,7 @@ union result { double d; float f; void *p; -#if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE) +#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX) double complex C; float complex E; long double complex F; diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index 53a946e750b866..3220852c8398e0 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -14,7 +14,7 @@ #include #include "ctypes.h" -#if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE) +#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX) # include "../_complex.h" // complex #endif @@ -972,7 +972,7 @@ d_get(void *ptr, Py_ssize_t size) return PyFloat_FromDouble(val); } -#if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE) +#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX) static PyObject * C_set(void *ptr, PyObject *value, Py_ssize_t size) { @@ -1545,7 +1545,7 @@ static struct fielddesc formattable[] = { { 'B', B_set, B_get, NULL}, { 'c', c_set, c_get, NULL}, { 'd', d_set, d_get, NULL, d_set_sw, d_get_sw}, -#if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE) +#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX) { 'C', C_set, C_get, NULL}, { 'E', E_set, E_get, NULL}, { 'F', F_set, F_get, NULL}, @@ -1600,7 +1600,7 @@ _ctypes_init_fielddesc(void) case 'B': fd->pffi_type = &ffi_type_uchar; break; case 'c': fd->pffi_type = &ffi_type_schar; break; case 'd': fd->pffi_type = &ffi_type_double; break; -#if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE) +#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX) case 'C': fd->pffi_type = &ffi_type_complex_double; break; case 'E': fd->pffi_type = &ffi_type_complex_float; break; case 'F': fd->pffi_type = &ffi_type_complex_longdouble; break; diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h index 738dcd1aaf8a01..7e0804054cded4 100644 --- a/Modules/_ctypes/ctypes.h +++ b/Modules/_ctypes/ctypes.h @@ -2,12 +2,10 @@ # include #endif -#include // FFI_TARGET_HAS_COMPLEX_TYPE - #include "pycore_moduleobject.h" // _PyModule_GetState() #include "pycore_typeobject.h" // _PyType_GetModuleState() -#if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE) +#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX) # include "../_complex.h" // complex #endif @@ -388,7 +386,7 @@ struct tagPyCArgObject { double d; float f; void *p; -#if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE) +#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX) double complex C; float complex E; long double complex F; diff --git a/configure b/configure index be119f108a060b..17c70d25f9e70c 100755 --- a/configure +++ b/configure @@ -15050,6 +15050,70 @@ LIBS=$save_LIBS +fi + +# Check for libffi with real complex double support. +# This is a workaround, since FFI_TARGET_HAS_COMPLEX_TYPE was defined in libffi v3.2.1, +# but real support was provided only in libffi v3.3.0. +# See https://github.com/python/cpython/issues/125206 for more details. +# +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking libffi has complex type support" >&5 +printf %s "checking libffi has complex type support... " >&6; } +if test ${ac_cv_ffi_complex_double_supported+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_save_cc="$CC" +CC="$CC -lffi" +if test "$cross_compiling" = yes +then : + ac_cv_ffi_complex_double_supported=no +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +int z_is_expected(double complex z) +{ + const double complex expected = CMPLX(1.25, -0.5); + return z == expected; +} +int main(void) +{ + double complex z = 1.25 - 0.5 * I; + ffi_type *args[1] = {&ffi_type_complex_double}; + void *values[1] = {&z}; + ffi_cif cif; + if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_sint, args) != FFI_OK) + { + return 2; + } + ffi_arg rc; + ffi_call(&cif, FFI_FN(z_is_expected), &rc, values); + return !rc; +} + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_ffi_complex_double_supported=yes +else $as_nop + ac_cv_ffi_complex_double_supported=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +CC="$ac_save_cc" +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_ffi_complex_double_supported" >&5 +printf "%s\n" "$ac_cv_ffi_complex_double_supported" >&6; } +if test "$ac_cv_ffi_complex_double_supported" = "yes"; then + +printf "%s\n" "#define Py_FFI_SUPPORT_C_COMPLEX 1" >>confdefs.h + fi # Check for use of the system libmpdec library diff --git a/configure.ac b/configure.ac index 582851695e400f..56daa8b0f79bc0 100644 --- a/configure.ac +++ b/configure.ac @@ -4089,6 +4089,46 @@ AS_VAR_IF([have_libffi], [yes], [ ]) ]) +# Check for libffi with real complex double support. +# This is a workaround, since FFI_TARGET_HAS_COMPLEX_TYPE was defined in libffi v3.2.1, +# but real support was provided only in libffi v3.3.0. +# See https://github.com/python/cpython/issues/125206 for more details. +# +AC_CACHE_CHECK([libffi has complex type support], [ac_cv_ffi_complex_double_supported], +[ac_save_cc="$CC" +CC="$CC -lffi" +AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include +#include +int z_is_expected(double complex z) +{ + const double complex expected = CMPLX(1.25, -0.5); + return z == expected; +} +int main(void) +{ + double complex z = 1.25 - 0.5 * I; + ffi_type *args[1] = {&ffi_type_complex_double}; + void *values[1] = {&z}; + ffi_cif cif; + if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_sint, args) != FFI_OK) + { + return 2; + } + ffi_arg rc; + ffi_call(&cif, FFI_FN(z_is_expected), &rc, values); + return !rc; +} +]])], [ac_cv_ffi_complex_double_supported=yes], +[ac_cv_ffi_complex_double_supported=no], +[ac_cv_ffi_complex_double_supported=no]) +CC="$ac_save_cc"]) +if test "$ac_cv_ffi_complex_double_supported" = "yes"; then + AC_DEFINE([Py_FFI_SUPPORT_C_COMPLEX], [1], + [Defined if _Complex C type can be used with libffi.]) +fi + # Check for use of the system libmpdec library AC_MSG_CHECKING([for --with-system-libmpdec]) AC_ARG_WITH( diff --git a/pyconfig.h.in b/pyconfig.h.in index 1947d8ee14f83e..fb9ab1e78dc7e1 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -1685,6 +1685,9 @@ /* Defined if Python is built as a shared library. */ #undef Py_ENABLE_SHARED +/* Defined if _Complex C type can be used with libffi. */ +#undef Py_FFI_SUPPORT_C_COMPLEX + /* Define if you want to disable the GIL */ #undef Py_GIL_DISABLED From 206de4155b01f6285c5551d2224391fa1fa0ac14 Mon Sep 17 00:00:00 2001 From: Neil Schemenauer Date: Tue, 15 Oct 2024 11:47:20 -0700 Subject: [PATCH 097/170] gh-92953: Improve nextpool/prevpool comment. (gh-125545) The meaning of these links depends on which list the pool is part of. They are only the same size class if on the "usedpools" list. --- Include/internal/pycore_obmalloc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Include/internal/pycore_obmalloc.h b/Include/internal/pycore_obmalloc.h index 9140d8f08f0af1..a7ba8f340737aa 100644 --- a/Include/internal/pycore_obmalloc.h +++ b/Include/internal/pycore_obmalloc.h @@ -255,8 +255,8 @@ struct pool_header { union { pymem_block *_padding; uint count; } ref; /* number of allocated blocks */ pymem_block *freeblock; /* pool's free list head */ - struct pool_header *nextpool; /* next pool of this size class */ - struct pool_header *prevpool; /* previous pool "" */ + struct pool_header *nextpool; /* see "Pool table" for meaning */ + struct pool_header *prevpool; /* " */ uint arenaindex; /* index into arenas of base adr */ uint szidx; /* block size class index */ uint nextoffset; /* bytes to virgin block */ From 3ea488aac44887a7cdb30be69580c81a0ca6afe2 Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Tue, 15 Oct 2024 15:06:41 -0400 Subject: [PATCH 098/170] gh-124218: Use per-thread refcounts for code objects (#125216) Use per-thread refcounting for the reference from function objects to their corresponding code object. This can be a source of contention when frequently creating nested functions. Deferred refcounting alone isn't a great fit here because these references are on the heap and may be modified by other libraries. --- Include/cpython/code.h | 1 + Include/cpython/object.h | 2 +- Include/internal/pycore_object.h | 84 +++++++++++++++++++----------- Include/internal/pycore_uniqueid.h | 6 +-- Objects/codeobject.c | 6 ++- Objects/funcobject.c | 8 +-- Objects/typeobject.c | 4 +- Python/gc_free_threading.c | 13 ++--- Python/pylifecycle.c | 2 +- Python/pystate.c | 2 +- Python/uniqueid.c | 67 +++++++++++++++--------- 11 files changed, 119 insertions(+), 76 deletions(-) diff --git a/Include/cpython/code.h b/Include/cpython/code.h index 03622698113ee7..af9149b9c38e62 100644 --- a/Include/cpython/code.h +++ b/Include/cpython/code.h @@ -132,6 +132,7 @@ typedef struct { _PyCoCached *_co_cached; /* cached co_* attributes */ \ uintptr_t _co_instrumentation_version; /* current instrumentation version */ \ _PyCoMonitoringData *_co_monitoring; /* Monitoring data */ \ + Py_ssize_t _co_unique_id; /* ID used for per-thread refcounting */ \ int _co_firsttraceable; /* index of first traceable instruction */ \ /* Scratch space for extra data relating to the code object. \ Type is a void* to keep the format private in codeobject.c to force \ diff --git a/Include/cpython/object.h b/Include/cpython/object.h index 9d092749b90096..f0f61796cd3ec8 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -272,7 +272,7 @@ typedef struct _heaptypeobject { void *ht_token; // Storage for the "Py_tp_token" slot struct _specialization_cache _spec_cache; // For use by the specializer. #ifdef Py_GIL_DISABLED - Py_ssize_t unique_id; // ID used for thread-local refcounting + Py_ssize_t unique_id; // ID used for per-thread refcounting #endif /* here are optional user slots, followed by the members. */ } PyHeapTypeObject; diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index 8832692d03c29e..ad1a7d7e120519 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -14,7 +14,7 @@ extern "C" { #include "pycore_interp.h" // PyInterpreterState.gc #include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_STORE_PTR_RELAXED #include "pycore_pystate.h" // _PyInterpreterState_GET() -#include "pycore_uniqueid.h" // _PyType_IncrefSlow +#include "pycore_uniqueid.h" // _PyObject_ThreadIncrefSlow() // This value is added to `ob_ref_shared` for objects that use deferred // reference counting so that they are not immediately deallocated when the @@ -291,7 +291,31 @@ extern bool _PyRefchain_IsTraced(PyInterpreterState *interp, PyObject *obj); #ifndef Py_GIL_DISABLED # define _Py_INCREF_TYPE Py_INCREF # define _Py_DECREF_TYPE Py_DECREF +# define _Py_INCREF_CODE Py_INCREF +# define _Py_DECREF_CODE Py_DECREF #else +static inline void +_Py_THREAD_INCREF_OBJECT(PyObject *obj, Py_ssize_t unique_id) +{ + _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)_PyThreadState_GET(); + + // Unsigned comparison so that `unique_id=-1`, which indicates that + // per-thread refcounting has been disabled on this object, is handled by + // the "else". + if ((size_t)unique_id < (size_t)tstate->refcounts.size) { +# ifdef Py_REF_DEBUG + _Py_INCREF_IncRefTotal(); +# endif + _Py_INCREF_STAT_INC(); + tstate->refcounts.values[unique_id]++; + } + else { + // The slow path resizes the per-thread refcount array if necessary. + // It handles the unique_id=-1 case to keep the inlinable function smaller. + _PyObject_ThreadIncrefSlow(obj, unique_id); + } +} + static inline void _Py_INCREF_TYPE(PyTypeObject *type) { @@ -308,29 +332,38 @@ _Py_INCREF_TYPE(PyTypeObject *type) # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Warray-bounds" #endif + _Py_THREAD_INCREF_OBJECT((PyObject *)type, ((PyHeapTypeObject *)type)->unique_id); +#if defined(__GNUC__) && __GNUC__ >= 11 +# pragma GCC diagnostic pop +#endif +} + +static inline void +_Py_INCREF_CODE(PyCodeObject *co) +{ + _Py_THREAD_INCREF_OBJECT((PyObject *)co, co->_co_unique_id); +} +static inline void +_Py_THREAD_DECREF_OBJECT(PyObject *obj, Py_ssize_t unique_id) +{ _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)_PyThreadState_GET(); - PyHeapTypeObject *ht = (PyHeapTypeObject *)type; // Unsigned comparison so that `unique_id=-1`, which indicates that - // per-thread refcounting has been disabled on this type, is handled by + // per-thread refcounting has been disabled on this object, is handled by // the "else". - if ((size_t)ht->unique_id < (size_t)tstate->refcounts.size) { + if ((size_t)unique_id < (size_t)tstate->refcounts.size) { # ifdef Py_REF_DEBUG - _Py_INCREF_IncRefTotal(); + _Py_DECREF_DecRefTotal(); # endif - _Py_INCREF_STAT_INC(); - tstate->refcounts.values[ht->unique_id]++; + _Py_DECREF_STAT_INC(); + tstate->refcounts.values[unique_id]--; } else { - // The slow path resizes the thread-local refcount array if necessary. - // It handles the unique_id=-1 case to keep the inlinable function smaller. - _PyType_IncrefSlow(ht); + // Directly decref the object if the id is not assigned or if + // per-thread refcounting has been disabled on this object. + Py_DECREF(obj); } - -#if defined(__GNUC__) && __GNUC__ >= 11 -# pragma GCC diagnostic pop -#endif } static inline void @@ -341,25 +374,14 @@ _Py_DECREF_TYPE(PyTypeObject *type) _Py_DECREF_IMMORTAL_STAT_INC(); return; } - - _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)_PyThreadState_GET(); PyHeapTypeObject *ht = (PyHeapTypeObject *)type; + _Py_THREAD_DECREF_OBJECT((PyObject *)type, ht->unique_id); +} - // Unsigned comparison so that `unique_id=-1`, which indicates that - // per-thread refcounting has been disabled on this type, is handled by - // the "else". - if ((size_t)ht->unique_id < (size_t)tstate->refcounts.size) { -# ifdef Py_REF_DEBUG - _Py_DECREF_DecRefTotal(); -# endif - _Py_DECREF_STAT_INC(); - tstate->refcounts.values[ht->unique_id]--; - } - else { - // Directly decref the type if the type id is not assigned or if - // per-thread refcounting has been disabled on this type. - Py_DECREF(type); - } +static inline void +_Py_DECREF_CODE(PyCodeObject *co) +{ + _Py_THREAD_DECREF_OBJECT((PyObject *)co, co->_co_unique_id); } #endif diff --git a/Include/internal/pycore_uniqueid.h b/Include/internal/pycore_uniqueid.h index 8f3b4418408cf8..ad5dd38ea08483 100644 --- a/Include/internal/pycore_uniqueid.h +++ b/Include/internal/pycore_uniqueid.h @@ -49,7 +49,7 @@ struct _Py_unique_id_pool { extern Py_ssize_t _PyObject_AssignUniqueId(PyObject *obj); // Releases the allocated id back to the pool. -extern void _PyObject_ReleaseUniqueId(Py_ssize_t unique_id); +extern void _PyObject_DisablePerThreadRefcounting(PyObject *obj); // Merges the per-thread reference counts into the corresponding objects. extern void _PyObject_MergePerThreadRefcounts(_PyThreadStateImpl *tstate); @@ -61,8 +61,8 @@ extern void _PyObject_FinalizePerThreadRefcounts(_PyThreadStateImpl *tstate); // Frees the interpreter's pool of type ids. extern void _PyObject_FinalizeUniqueIdPool(PyInterpreterState *interp); -// Increfs the type, resizing the per-thread refcount array if necessary. -PyAPI_FUNC(void) _PyType_IncrefSlow(PyHeapTypeObject *type); +// Increfs the object, resizing the thread-local refcount array if necessary. +PyAPI_FUNC(void) _PyObject_ThreadIncrefSlow(PyObject *obj, Py_ssize_t unique_id); #endif /* Py_GIL_DISABLED */ diff --git a/Objects/codeobject.c b/Objects/codeobject.c index de80f6cca2904f..9419cfc0048541 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -14,6 +14,7 @@ #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_setobject.h" // _PySet_NextEntry() #include "pycore_tuple.h" // _PyTuple_ITEMS() +#include "pycore_uniqueid.h" // _PyObject_AssignUniqueId() #include "clinic/codeobject.c.h" static const char * @@ -676,7 +677,7 @@ _PyCode_New(struct _PyCodeConstructor *con) } init_code(co, con); #ifdef Py_GIL_DISABLED - _PyObject_SetDeferredRefcount((PyObject *)co); + co->_co_unique_id = _PyObject_AssignUniqueId((PyObject *)co); _PyObject_GC_TRACK(co); #endif Py_XDECREF(replacement_locations); @@ -1864,6 +1865,9 @@ code_dealloc(PyCodeObject *co) Py_XDECREF(co->co_qualname); Py_XDECREF(co->co_linetable); Py_XDECREF(co->co_exceptiontable); +#ifdef Py_GIL_DISABLED + assert(co->_co_unique_id == -1); +#endif if (co->_co_cached != NULL) { Py_XDECREF(co->_co_cached->_co_code); Py_XDECREF(co->_co_cached->_co_cellvars); diff --git a/Objects/funcobject.c b/Objects/funcobject.c index 855d1a2eeca819..6119a96b4aae76 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -116,7 +116,8 @@ _PyFunction_FromConstructor(PyFrameConstructor *constr) op->func_builtins = Py_NewRef(constr->fc_builtins); op->func_name = Py_NewRef(constr->fc_name); op->func_qualname = Py_NewRef(constr->fc_qualname); - op->func_code = Py_NewRef(constr->fc_code); + _Py_INCREF_CODE((PyCodeObject *)constr->fc_code); + op->func_code = constr->fc_code; op->func_defaults = Py_XNewRef(constr->fc_defaults); op->func_kwdefaults = Py_XNewRef(constr->fc_kwdefaults); op->func_closure = Py_XNewRef(constr->fc_closure); @@ -146,7 +147,8 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname PyThreadState *tstate = _PyThreadState_GET(); - PyCodeObject *code_obj = (PyCodeObject *)Py_NewRef(code); + PyCodeObject *code_obj = (PyCodeObject *)code; + _Py_INCREF_CODE(code_obj); assert(code_obj->co_name != NULL); PyObject *name = Py_NewRef(code_obj->co_name); @@ -1094,7 +1096,7 @@ func_dealloc(PyObject *self) } (void)func_clear((PyObject*)op); // These aren't cleared by func_clear(). - Py_DECREF(op->func_code); + _Py_DECREF_CODE((PyCodeObject *)op->func_code); Py_DECREF(op->func_name); Py_DECREF(op->func_qualname); PyObject_GC_Del(op); diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 6ca4406ec0ea2d..4d843824e1eb00 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -5025,7 +5025,7 @@ PyType_FromMetaclass( type->tp_dictoffset = dictoffset; #ifdef Py_GIL_DISABLED - // Assign a type id to enable thread-local refcounting + // Assign a unique id to enable per-thread refcounting res->unique_id = _PyObject_AssignUniqueId((PyObject *)res); #endif @@ -6043,7 +6043,7 @@ type_dealloc(PyObject *self) Py_XDECREF(et->ht_module); PyMem_Free(et->_ht_tpname); #ifdef Py_GIL_DISABLED - _PyObject_ReleaseUniqueId(et->unique_id); + assert(et->unique_id == -1); #endif et->ht_token = NULL; Py_TYPE(type)->tp_free((PyObject *)type); diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c index 3814cd46e2b440..8558d4555a9a3a 100644 --- a/Python/gc_free_threading.c +++ b/Python/gc_free_threading.c @@ -15,7 +15,7 @@ #include "pycore_tstate.h" // _PyThreadStateImpl #include "pycore_weakref.h" // _PyWeakref_ClearRef() #include "pydtrace.h" -#include "pycore_uniqueid.h" // _PyType_MergeThreadLocalRefcounts +#include "pycore_uniqueid.h" // _PyObject_MergeThreadLocalRefcounts() #ifdef Py_GIL_DISABLED @@ -215,15 +215,10 @@ disable_deferred_refcounting(PyObject *op) op->ob_gc_bits &= ~_PyGC_BITS_DEFERRED; op->ob_ref_shared -= _Py_REF_SHARED(_Py_REF_DEFERRED, 0); merge_refcount(op, 0); - } - // Heap types also use per-thread refcounting -- disable it here. - if (PyType_Check(op)) { - if (PyType_HasFeature((PyTypeObject *)op, Py_TPFLAGS_HEAPTYPE)) { - PyHeapTypeObject *ht = (PyHeapTypeObject *)op; - _PyObject_ReleaseUniqueId(ht->unique_id); - ht->unique_id = -1; - } + // Heap types and code objects also use per-thread refcounting, which + // should also be disabled when we turn off deferred refcounting. + _PyObject_DisablePerThreadRefcounting(op); } // Generators and frame objects may contain deferred references to other diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index ebeee4f41d795d..5fb9c4f7c719fe 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -28,7 +28,7 @@ #include "pycore_sliceobject.h" // _PySlice_Fini() #include "pycore_sysmodule.h" // _PySys_ClearAuditHooks() #include "pycore_traceback.h" // _Py_DumpTracebackThreads() -#include "pycore_uniqueid.h" // _PyType_FinalizeIdPool() +#include "pycore_uniqueid.h" // _PyObject_FinalizeUniqueIdPool() #include "pycore_typeobject.h" // _PyTypes_InitTypes() #include "pycore_typevarobject.h" // _Py_clear_generic_types() #include "pycore_unicodeobject.h" // _PyUnicode_InitTypes() diff --git a/Python/pystate.c b/Python/pystate.c index 5d94b7714bd607..e3812cba41d9c2 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -20,7 +20,7 @@ #include "pycore_runtime_init.h" // _PyRuntimeState_INIT #include "pycore_sysmodule.h" // _PySys_Audit() #include "pycore_obmalloc.h" // _PyMem_obmalloc_state_on_heap() -#include "pycore_uniqueid.h" // _PyType_FinalizeThreadLocalRefcounts() +#include "pycore_uniqueid.h" // _PyObject_FinalizePerThreadRefcounts() /* -------------------------------------------------------------------------- CAUTION diff --git a/Python/uniqueid.c b/Python/uniqueid.c index 9a9ee2f39467b0..0cbb35c6cd2f8b 100644 --- a/Python/uniqueid.c +++ b/Python/uniqueid.c @@ -98,36 +98,60 @@ _PyObject_AssignUniqueId(PyObject *obj) return unique_id; } -void -_PyObject_ReleaseUniqueId(Py_ssize_t unique_id) +static void +release_unique_id(Py_ssize_t unique_id) { PyInterpreterState *interp = _PyInterpreterState_GET(); struct _Py_unique_id_pool *pool = &interp->unique_ids; - if (unique_id < 0) { - // The id is not assigned - return; - } - LOCK_POOL(pool); + assert(unique_id >= 0 && unique_id < pool->size); _Py_unique_id_entry *entry = &pool->table[unique_id]; entry->next = pool->freelist; pool->freelist = entry; UNLOCK_POOL(pool); } +static Py_ssize_t +clear_unique_id(PyObject *obj) +{ + Py_ssize_t id = -1; + if (PyType_Check(obj)) { + if (PyType_HasFeature((PyTypeObject *)obj, Py_TPFLAGS_HEAPTYPE)) { + PyHeapTypeObject *ht = (PyHeapTypeObject *)obj; + id = ht->unique_id; + ht->unique_id = -1; + } + } + else if (PyCode_Check(obj)) { + PyCodeObject *co = (PyCodeObject *)obj; + id = co->_co_unique_id; + co->_co_unique_id = -1; + } + return id; +} + +void +_PyObject_DisablePerThreadRefcounting(PyObject *obj) +{ + Py_ssize_t id = clear_unique_id(obj); + if (id >= 0) { + release_unique_id(id); + } +} + void -_PyType_IncrefSlow(PyHeapTypeObject *type) +_PyObject_ThreadIncrefSlow(PyObject *obj, Py_ssize_t unique_id) { _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)_PyThreadState_GET(); - if (type->unique_id < 0 || resize_local_refcounts(tstate) < 0) { - // just incref the type directly. - Py_INCREF(type); + if (unique_id < 0 || resize_local_refcounts(tstate) < 0) { + // just incref the object directly. + Py_INCREF(obj); return; } - assert(type->unique_id < tstate->refcounts.size); - tstate->refcounts.values[type->unique_id]++; + assert(unique_id < tstate->refcounts.size); + tstate->refcounts.values[unique_id]++; #ifdef Py_REF_DEBUG _Py_IncRefTotal((PyThreadState *)tstate); #endif @@ -179,20 +203,15 @@ _PyObject_FinalizeUniqueIdPool(PyInterpreterState *interp) pool->freelist = next; } - // Now everything non-NULL is a type. Set the type's id to -1 in case it - // outlives the interpreter. + // Now everything non-NULL is a object. Clear their unique ids as the + // object outlives the interpreter. for (Py_ssize_t i = 0; i < pool->size; i++) { PyObject *obj = pool->table[i].obj; pool->table[i].obj = NULL; - if (obj == NULL) { - continue; - } - if (PyType_Check(obj)) { - assert(PyType_HasFeature((PyTypeObject *)obj, Py_TPFLAGS_HEAPTYPE)); - ((PyHeapTypeObject *)obj)->unique_id = -1; - } - else { - Py_UNREACHABLE(); + if (obj != NULL) { + Py_ssize_t id = clear_unique_id(obj); + (void)id; + assert(id == i); } } PyMem_Free(pool->table); From 9c2bb7d551a695f35db953a671a2ddca89426bef Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Tue, 15 Oct 2024 12:30:28 -0700 Subject: [PATCH 099/170] gh-125115: Pass unknown pdb command line args to script instead of fail (#125424) Co-authored-by: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> --- Lib/pdb.py | 30 +++++++++++++++---- Lib/test/test_pdb.py | 21 ++++++++++++- ...-10-14-02-07-44.gh-issue-125115.IOf3ON.rst | 1 + 3 files changed, 45 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-14-02-07-44.gh-issue-125115.IOf3ON.rst diff --git a/Lib/pdb.py b/Lib/pdb.py index 2b36b1e3fa7cbe..3e5e6088fdcc7e 100644 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -82,6 +82,7 @@ import inspect import textwrap import tokenize +import itertools import traceback import linecache import _colorize @@ -2433,8 +2434,6 @@ def main(): parser.add_argument('-c', '--command', action='append', default=[], metavar='command', dest='commands', help='pdb commands to execute as if given in a .pdbrc file') parser.add_argument('-m', metavar='module', dest='module') - parser.add_argument('args', nargs='*', - help="when -m is not specified, the first arg is the script to debug") if len(sys.argv) == 1: # If no arguments were given (python -m pdb), print the whole help message. @@ -2442,21 +2441,40 @@ def main(): parser.print_help() sys.exit(2) - opts = parser.parse_args() + opts, args = parser.parse_known_args() + + if opts.module: + # If a module is being debugged, we consider the arguments after "-m module" to + # be potential arguments to the module itself. We need to parse the arguments + # before "-m" to check if there is any invalid argument. + # e.g. "python -m pdb -m foo --spam" means passing "--spam" to "foo" + # "python -m pdb --spam -m foo" means passing "--spam" to "pdb" and is invalid + idx = sys.argv.index('-m') + args_to_pdb = sys.argv[1:idx] + # This will raise an error if there are invalid arguments + parser.parse_args(args_to_pdb) + else: + # If a script is being debugged, then pdb expects the script name as the first argument. + # Anything before the script is considered an argument to pdb itself, which would + # be invalid because it's not parsed by argparse. + invalid_args = list(itertools.takewhile(lambda a: a.startswith('-'), args)) + if invalid_args: + parser.error(f"unrecognized arguments: {' '.join(invalid_args)}") + sys.exit(2) if opts.module: file = opts.module target = _ModuleTarget(file) else: - if not opts.args: + if not args: parser.error("no module or script to run") - file = opts.args.pop(0) + file = args.pop(0) if file.endswith('.pyz'): target = _ZipTarget(file) else: target = _ScriptTarget(file) - sys.argv[:] = [file] + opts.args # Hide "pdb.py" and pdb options from argument list + sys.argv[:] = [file] + args # Hide "pdb.py" and pdb options from argument list # Note on saving/restoring sys.argv: it's a good idea when sys.argv was # modified by the script being debugged. It's a bad idea when it was diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 084b7cd4cad219..456effc010954a 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -3089,6 +3089,7 @@ def _run_pdb(self, pdb_args, commands, def run_pdb_script(self, script, commands, expected_returncode=0, extra_env=None, + script_args=None, pdbrc=None, remove_home=False): """Run 'script' lines with pdb and the pdb 'commands'.""" @@ -3106,7 +3107,9 @@ def run_pdb_script(self, script, commands, if remove_home: homesave = os.environ.pop('HOME', None) try: - stdout, stderr = self._run_pdb([filename], commands, expected_returncode, extra_env) + if script_args is None: + script_args = [] + stdout, stderr = self._run_pdb([filename] + script_args, commands, expected_returncode, extra_env) finally: if homesave is not None: os.environ['HOME'] = homesave @@ -3559,6 +3562,22 @@ def test_run_module_with_args(self): stdout, _ = self._run_pdb(["-m", "calendar", "1"], commands) self.assertIn("December", stdout) + stdout, _ = self._run_pdb(["-m", "calendar", "--type", "text"], commands) + self.assertIn("December", stdout) + + def test_run_script_with_args(self): + script = """ + import sys + print(sys.argv[1:]) + """ + commands = """ + continue + quit + """ + + stdout, stderr = self.run_pdb_script(script, commands, script_args=["--bar", "foo"]) + self.assertIn("['--bar', 'foo']", stdout) + def test_breakpoint(self): script = """ if __name__ == '__main__': diff --git a/Misc/NEWS.d/next/Library/2024-10-14-02-07-44.gh-issue-125115.IOf3ON.rst b/Misc/NEWS.d/next/Library/2024-10-14-02-07-44.gh-issue-125115.IOf3ON.rst new file mode 100644 index 00000000000000..3583d537a6ec61 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-14-02-07-44.gh-issue-125115.IOf3ON.rst @@ -0,0 +1 @@ +Fixed a bug in :mod:`pdb` where arguments starting with ``-`` can't be passed to the debugged script. From 8cdaca8b25e3354530d66cbccc622e0e914e8e8a Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 15 Oct 2024 22:29:35 +0300 Subject: [PATCH 100/170] Python 3.14.0a1 --- Doc/c-api/init.rst | 6 +- Doc/c-api/long.rst | 2 +- Doc/c-api/unicode.rst | 2 +- Doc/library/ast.rst | 2 +- Doc/library/ctypes.rst | 2 +- Doc/library/dis.rst | 4 +- Doc/library/pathlib.rst | 4 +- Doc/library/symtable.rst | 8 +- Include/patchlevel.h | 4 +- Lib/pydoc_data/topics.py | 1669 +++-- Misc/NEWS.d/3.14.0a1.rst | 6604 +++++++++++++++++ ...-05-11-15-11-30.gh-issue-118943.VI_MnY.rst | 3 - ...-05-13-15-57-58.gh-issue-118836.7yN1iB.rst | 2 - ...-05-17-19-53-27.gh-issue-119132.wepPgM.rst | 2 - ...-05-19-22-54-55.gh-issue-115119.DwMwev.rst | 1 - ...-05-22-13-18-02.gh-issue-119400.WEt83v.rst | 2 - ...-05-29-17-40-50.gh-issue-119729.k0xJ5U.rst | 5 - ...-06-02-13-23-26.gh-issue-113565.8xBlId.rst | 2 - ...-06-09-15-54-22.gh-issue-120291.IpfHzE.rst | 1 - ...-06-11-00-38-05.gh-issue-120326.JHSDF1.rst | 2 - ...-06-18-15-28-25.gh-issue-118943.aie7nn.rst | 3 - ...-06-18-15-32-36.gh-issue-120688.tjIPLD.rst | 3 - ...-06-19-21-05-15.gh-issue-120602.UyDARz.rst | 2 - ...-06-21-09-24-03.gh-issue-120671.Z8sBQB.rst | 1 - ...-06-27-18-03-20.gh-issue-121082.w3AfRx.rst | 1 - ...-07-02-12-42-25.gh-issue-120831.i3eIjg.rst | 1 - ...-07-02-20-16-09.gh-issue-121103.TMef9j.rst | 3 - ...-07-08-01-11-54.gh-issue-121467.3qWRQj.rst | 1 - ...-07-08-14-01-17.gh-issue-121487.ekHmpR.rst | 1 - ...-07-14-01-29-47.gh-issue-121731.RMPGP3.rst | 1 - ...-07-16-12-29-54.gh-issue-120371.E7x858.rst | 2 - ...-07-18-07-53-07.gh-issue-120522.dg3o5A.rst | 2 - ...-07-19-10-14-31.gh-issue-121996.IEb2sz.rst | 2 - ...-08-02-12-59-15.gh-issue-118943.vZQtET.rst | 1 - ...-08-07-00-20-18.gh-issue-116622.U9cxHM.rst | 2 - ...-08-12-15-48-49.gh-issue-122578.YJ3xEa.rst | 1 - ...-08-14-19-17-34.gh-issue-121634.eOMfHG.rst | 1 - ...-08-24-19-09-31.gh-issue-123297.fdtXoe.rst | 2 - ...-09-04-12-01-43.gh-issue-123418.ynzspB.rst | 1 - ...-09-13-17-48-37.gh-issue-124043.Bruxpq.rst | 2 - ...-09-16-09-42-05.gh-issue-124102.Ow254j.rst | 2 - ...-09-23-11-27-25.gh-issue-123990.d6HrYC.rst | 1 - ...-10-13-21-11-30.gh-issue-125269.BC-fdo.rst | 2 - .../2018-06-30-21-48-16.bpo-34008.2Wjtm0.rst | 2 - ...2-08-05-19-41-20.gh-issue-87135.SCNBYj.rst | 15 - ...2-10-01-09-56-27.gh-issue-97588.Gvg54o.rst | 2 - ...-03-10-14-55-51.gh-issue-116560.x2mZaO.rst | 1 - ...-04-10-16-48-04.gh-issue-117511.RZtBRK.rst | 1 - ...-05-08-20-13-00.gh-issue-118789.m88uUa.rst | 2 - ...-05-08-21-57-50.gh-issue-118789.Ni4UQx.rst | 2 - ...-05-08-23-14-06.gh-issue-116984.5sgcDo.rst | 3 - ...-05-10-15-43-14.gh-issue-118771.5KVglT.rst | 3 - ...-05-20-10-35-22.gh-issue-111389.a6axBk.rst | 2 - ...-05-21-11-35-11.gh-issue-119247.U6n6mh.rst | 4 - ...-05-21-18-28-44.gh-issue-119333.OTsYVX.rst | 2 - ...-05-21-19-41-41.gh-issue-119344.QKvzQb.rst | 1 - ...-05-22-17-50-48.gh-issue-119336.ff3qnS.rst | 1 - ...-05-29-09-21-37.gh-issue-119613.J2xfrC.rst | 2 - ...-05-29-21-05-59.gh-issue-119585.Sn7JL3.rst | 5 - ...-05-30-12-51-21.gh-issue-119775.CBq9IG.rst | 2 - ...-06-04-10-58-20.gh-issue-119613.qOr9GF.rst | 2 - ...-06-07-22-12-30.gh-issue-119182.yt8Ar7.rst | 16 - ...-06-08-08-33-40.gh-issue-119771.Oip2dL.rst | 2 - ...4-06-11-21-38-32.gh-issue-70278.WDE4zM.rst | 4 - ...-06-16-22-58-47.gh-issue-120600.TJdf0w.rst | 2 - ...-06-19-17-27-22.gh-issue-120389.GSZeHF.rst | 13 - ...-06-19-21-27-42.gh-issue-120642.UlKClN.rst | 10 - ...-06-21-16-41-21.gh-issue-120858.Z5_-Mn.rst | 3 - ...-06-26-11-29-01.gh-issue-120642.H7P9qK.rst | 3 - ...-07-02-11-03-40.gh-issue-112136.f3fiY8.rst | 3 - ...-07-04-13-23-27.gh-issue-113601.K3RLqp.rst | 2 - ...-07-04-15-41-10.gh-issue-113993.cLSiWV.rst | 12 - ...-07-21-17-40-07.gh-issue-121489.SUMFCr.rst | 1 - ...-07-30-23-48-26.gh-issue-116622.yTTtil.rst | 3 - ...4-07-09-15-55-20.gh-issue-89364.yYYroI.rst | 3 - ...-07-12-13-40-59.gh-issue-121645.96QvD3.rst | 2 - ...-07-27-00-28-35.gh-issue-105201.0-xUWq.rst | 2 - ...-08-06-14-23-11.gh-issue-122728.l-fQ-v.rst | 2 - ...-08-09-13-12-20.gh-issue-122854.-1OgvU.rst | 2 - ...-08-26-13-01-20.gh-issue-100554.0ku85o.rst | 4 - ...-08-29-15-05-19.gh-issue-123465.eqwNWq.rst | 4 - ...-08-29-15-55-55.gh-issue-107954.pr2O50.rst | 8 - ...-08-30-14-02-17.gh-issue-107954.TPvj4u.rst | 18 - ...-09-10-16-54-27.gh-issue-123909.CTGxDR.rst | 3 - ...-09-12-16-16-24.gh-issue-123880.2-8vcj.rst | 2 - ...-09-16-16-21-39.gh-issue-124127.LB8DBU.rst | 3 - ...-09-17-05-23-35.gh-issue-124153.L8TWmx.rst | 2 - ...-09-18-18-40-30.gh-issue-124160.Zy-VKi.rst | 2 - ...-09-24-20-34-21.gh-issue-124296.S4QoS1.rst | 3 - ...-09-25-11-44-02.gh-issue-124502.qWuDjT.rst | 2 - ...-10-03-14-06-08.gh-issue-123961.uwJQTY.rst | 3 - .../2018-10-09-15-14-53.bpo-24766.c_C1Wc.rst | 1 - ...2-07-22-15-56-35.gh-issue-95144.FZYWX-.rst | 2 - ...3-10-14-23-05-40.gh-issue-84978.Z0t6dg.rst | 1 - ...-01-15-18-11-48.gh-issue-113190.OwQX64.rst | 1 - ...-01-15-21-51-26.gh-issue-114091.VOtSJl.rst | 1 - ...-03-19-22-21-22.gh-issue-116022.iyHENN.rst | 1 - ...-03-25-15-07-01.gh-issue-117195.OWakgD.rst | 2 - ...-04-08-13-49-02.gh-issue-117558.9lSEpR.rst | 2 - ...-04-27-18-36-46.gh-issue-115801.SVeHSy.rst | 1 - ...-05-01-05-09-16.gh-issue-117139.t41w_D.rst | 5 - ...-05-07-16-57-56.gh-issue-118561.wNMKVd.rst | 2 - ...-05-08-09-44-15.gh-issue-118767.iFF5F5.rst | 2 - ...-05-09-02-37-25.gh-issue-118750.7aLfT-.rst | 1 - ...-05-09-19-47-12.gh-issue-117657.Vn0Yey.rst | 1 - ...-05-10-19-54-18.gh-issue-118921.O4ztZG.rst | 1 - ...-05-11-21-44-17.gh-issue-118844.q2H_km.rst | 1 - ...-05-15-12-15-58.gh-issue-119057.P3G9G2.rst | 4 - ...-05-16-23-02-03.gh-issue-119049.qpd_S-.rst | 2 - ...-05-20-10-10-51.gh-issue-119180.35xqpu.rst | 2 - ...-05-20-14-57-39.gh-issue-118692.Qadm7F.rst | 1 - ...-05-21-09-46-51.gh-issue-119011.WOe3bu.rst | 2 - ...-05-21-11-27-14.gh-issue-119213.nxjxrt.rst | 3 - ...-05-21-12-17-02.gh-issue-119180.UNDUb9.rst | 2 - ...-05-22-06-22-47.gh-issue-119180.vZMiXm.rst | 1 - ...-05-22-12-49-03.gh-issue-119372.PXig1R.rst | 2 - ...-05-23-06-34-14.gh-issue-119395.z-Hsqb.rst | 2 - ...-05-23-06-34-45.gh-issue-119311.2DBwKR.rst | 2 - ...-05-23-20-17-37.gh-issue-119258.wZFIpt.rst | 3 - ...-05-24-21-04-00.gh-issue-119525.zLFLf1.rst | 2 - ...-05-24-21-16-52.gh-issue-119369.qBThho.rst | 2 - ...-05-25-12-52-25.gh-issue-119560.wSlm8q.rst | 3 - ...-05-25-13-51-48.gh-issue-111999.L0q1gh.rst | 1 - ...-05-25-16-45-27.gh-issue-119548.pqF9Y6.rst | 1 - ...-05-27-19-13-49.gh-issue-109218.-sdDg0.rst | 3 - ...-05-28-22-49-56.gh-issue-119689.VwLFD5.rst | 1 - ...-05-29-18-53-43.gh-issue-119740.zP2JNM.rst | 2 - ...-05-30-04-11-36.gh-issue-118934.fbDqve.rst | 1 - ...-05-30-23-01-00.gh-issue-119821.jPGfvt.rst | 2 - ...-05-31-08-23-41.gh-issue-119180.KL4VxZ.rst | 3 - ...-05-31-12-06-11.gh-issue-119842.tCGVsv.rst | 1 - ...-06-02-06-12-35.gh-issue-119879.Jit951.rst | 1 - ...-06-03-13-25-04.gh-issue-119724.EH1dkA.rst | 3 - ...-06-03-13-48-44.gh-issue-119933.Kc0HG5.rst | 4 - ...-06-05-08-39-40.gh-issue-120080.DJFK11.rst | 2 - ...-06-05-10-32-44.gh-issue-120097.9S2klk.rst | 2 - ...4-06-05-18-29-18.gh-issue-93691.6OautB.rst | 1 - ...-06-07-16-09-04.gh-issue-120225.kuYf9t.rst | 1 - ...-06-07-22-54-15.gh-issue-119726.D9EE-o.rst | 1 - ...-06-09-19-13-38.gh-issue-119666.S0G4rZ.rst | 1 - ...-06-10-10-42-48.gh-issue-120298.napREA.rst | 2 - ...-06-10-15-07-16.gh-issue-120198.WW_pjO.rst | 1 - ...4-06-10-22-30-26.gh-issue-93691.68WOTS.rst | 2 - ...-06-11-12-47-54.gh-issue-120346.hhn_6X.rst | 2 - ...-06-11-17-56-12.gh-issue-120221.si9hM9.rst | 2 - ...-06-12-13-47-25.gh-issue-120397.n-I_cc.rst | 2 - ...-06-12-18-23-15.gh-issue-120380.edtqjq.rst | 3 - ...-06-12-18-50-29.gh-issue-120367.LmXx2y.rst | 2 - ...-06-13-12-17-52.gh-issue-120384.w1UBGl.rst | 3 - ...-06-14-07-52-00.gh-issue-120485.yy4K4b.rst | 1 - ...-06-14-22-02-25.gh-issue-113993.MiA0vX.rst | 5 - ...-06-17-12-20-20.gh-issue-120507.94lz2J.rst | 3 - ...-06-18-21-34-30.gh-issue-120367.zDwffP.rst | 1 - ...-06-18-22-41-05.gh-issue-120722.rS7tkE.rst | 2 - ...-06-19-01-58-54.gh-issue-120437.nCkIoI.rst | 1 - ...-06-19-11-10-50.gh-issue-119462.DpcqSe.rst | 4 - ...-06-19-19-54-35.gh-issue-120754.uF29sj.rst | 1 - ...4-06-19-21-34-21.gh-issue-98442.cqhjkN.rst | 2 - ...-06-24-08-39-23.gh-issue-116017.-Bw2UY.rst | 3 - ...-06-25-16-26-44.gh-issue-119726.WqvHxB.rst | 2 - ...-06-26-13-42-36.gh-issue-113433.xKAtLB.rst | 2 - ...-06-26-14-09-31.gh-issue-120838.nFeTL9.rst | 2 - ...-06-28-10-02-58.gh-issue-121115.EeSLfc.rst | 3 - ...-06-28-18-34-49.gh-issue-119726.Fjv_Ab.rst | 2 - ...-06-28-23-17-22.gh-issue-121381.i2xL7P.rst | 2 - ...-06-29-10-46-14.gh-issue-121130.Rj66Xs.rst | 2 - ...-06-30-03-48-10.gh-issue-121149.lLBMKe.rst | 2 - ...-07-04-23-38-30.gh-issue-121368.m3EF9E.rst | 3 - ...-07-05-11-29-27.gh-issue-121288.lYKYYP.rst | 5 - ...-07-08-02-24-55.gh-issue-121439.jDHod3.rst | 1 - ...-07-08-10-31-08.gh-issue-121012.M5hHk-.rst | 2 - ...-07-08-17-15-14.gh-issue-121497.I8hMDC.rst | 2 - ...-07-09-13-53-18.gh-issue-121499.rpp7il.rst | 2 - ...-07-10-02-02-32.gh-issue-121562.8beIMi.rst | 2 - ...-07-10-15-43-54.gh-issue-117482.5WYaXR.rst | 2 - ...-07-12-18-18-44.gh-issue-121297.67VE7b.rst | 4 - ...-07-13-12-27-31.gh-issue-121657.wgOYLw.rst | 2 - ...-07-15-16-26-32.gh-issue-121794.fhBtiQ.rst | 2 - ...-07-15-20-41-06.gh-issue-121814.oR2ixR.rst | 1 - ...-07-16-15-11-51.gh-issue-121795.xkIHrI.rst | 1 - ...-07-16-18-23-22.gh-issue-121860.-FTauD.rst | 1 - ...4-07-19-09-38-01.gh-issue-99108.qzM6gl.rst | 10 - ...-07-19-15-28-05.gh-issue-122026.sta2Ca.rst | 2 - ...-07-21-01-23-54.gh-issue-122029.gKv-e2.rst | 1 - ...-07-23-11-57-36.gh-issue-122160.HSnrAP.rst | 1 - ...-07-23-23-59-04.gh-issue-122208.z8KHsY.rst | 1 - ...-07-24-17-11-51.gh-issue-122234.VxsP_F.rst | 4 - ...-07-24-22-39-07.gh-issue-122245.LVa9v8.rst | 4 - ...-07-26-14-05-51.gh-issue-122300.SVIF-l.rst | 2 - ...-07-30-11-41-35.gh-issue-122445.Rq0bjS.rst | 1 - ...-08-05-19-04-06.gh-issue-116622.3LWUzE.rst | 1 - ...-08-18-18-25-54.gh-issue-123123.0ZcaEB.rst | 2 - ...-08-20-11-09-16.gh-issue-123048.2TISpv.rst | 2 - ...-08-20-12-29-52.gh-issue-123142.3PXiNb.rst | 2 - ...-08-21-15-22-53.gh-issue-121804.r5K3PS.rst | 2 - ...-08-23-13-08-27.gh-issue-123229.aHm-dw.rst | 2 - ...-08-23-15-59-54.gh-issue-123177.OLcaC5.rst | 2 - ...-08-25-10-54-22.gh-issue-122982.KLD91q.rst | 1 - ...-08-26-00-58-26.gh-issue-123321.ApxcnE.rst | 2 - ...-08-27-13-16-40.gh-issue-123344.56Or78.rst | 1 - ...-09-23-23-06-19.gh-issue-124285.mahGTg.rst | 2 - ...-10-03-22-26-39.gh-issue-124871.tAMF47.rst | 2 - ...-07-13-09-51-44.gh-issue-121609.jWsE5t.rst | 1 - ...-07-15-20-03-29.gh-issue-121295.w53ucI.rst | 2 - ...-07-18-21-19-04.gh-issue-121999.8IBbTK.rst | 2 - ...-07-25-01-45-21.gh-issue-122239.7zh-sW.rst | 3 - ...-07-26-13-56-32.gh-issue-120906.qBh2I9.rst | 1 - ...-07-29-10-55-46.gh-issue-116090.p1MhU0.rst | 2 - ...-07-29-19-20-25.gh-issue-122417.NVgs0a.rst | 4 - ...-08-01-19-13-58.gh-issue-122527.eztso6.rst | 4 - ...-08-05-19-28-12.gh-issue-122697.17MvYl.rst | 2 - ...-08-08-16-02-28.gh-issue-118093.m6Mrvy.rst | 1 - ...-08-10-12-44-03.gh-issue-122888.TUyu9r.rst | 2 - ...-08-12-11-19-37.gh-issue-122907.q68096.rst | 3 - ...-08-12-11-45-47.gh-issue-122821.WnAzTK.rst | 3 - ...-08-14-11-38-56.gh-issue-118093.3BywDP.rst | 5 - ...-08-15-19-28-43.gh-issue-123022.m3EF9E.rst | 2 - ...-08-17-17-26-25.gh-issue-123083.9xWLJ-.rst | 1 - ...-08-19-15-13-13.gh-issue-118093.dLZ8qS.rst | 3 - ...-08-21-08-53-00.gh-issue-115776.9A7Dv_.rst | 2 - ...-08-23-11-26-54.gh-issue-122298.ZMyln4.rst | 3 - ...-08-23-18-31-10.gh-issue-123275.DprIrj.rst | 1 - ...-08-23-21-20-34.gh-issue-123271.xeVViR.rst | 1 - ...-08-25-18-27-49.gh-issue-123177.yLuyqE.rst | 2 - ...-08-27-21-44-14.gh-issue-116017.ZY3yBY.rst | 2 - ...-08-28-22-42-51.gh-issue-123440.yOFB0N.rst | 1 - ...-08-29-13-18-18.gh-issue-123446.KWDrgq.rst | 2 - ...-08-29-19-46-07.gh-issue-123484.rjUn_F.rst | 2 - ...-09-01-00-02-05.gh-issue-123545.8nQNbL.rst | 1 - ...-09-01-12-08-39.gh-issue-123562.aJPKVu.rst | 2 - ...-09-02-17-32-15.gh-issue-119034.HYh5Vj.rst | 2 - ...-09-02-20-36-45.gh-issue-123339.QcmpSs.rst | 3 - ...-09-02-20-39-10.gh-issue-123614.26TMHp.rst | 2 - ...-09-03-13-34-35.gh-issue-123572.uuqoYV.rst | 2 - ...-09-06-14-13-01.gh-issue-119310.WQxyDF.rst | 3 - ...-09-06-19-23-44.gh-issue-120221.giJEDT.rst | 2 - ...4-09-10-13-27-16.gh-issue-77894.ZC-Olu.rst | 4 - ...-09-10-20-25-00.gh-issue-123923.A7uxqa.rst | 4 - ...-09-11-15-48-36.gh-issue-123958.5VW2r0.rst | 1 - ...-09-12-21-53-26.gh-issue-124022.fQzUiW.rst | 1 - ...-09-13-02-25-06.gh-issue-124027.to_9DY.rst | 2 - ...-09-17-22-06-01.gh-issue-124188.aFqNAB.rst | 2 - ...-09-19-13-17-31.gh-issue-122878.4iFpsB.rst | 1 - ...-09-19-16-57-34.gh-issue-119726.DseseK.rst | 2 - ...4-09-23-13-25-27.gh-issue-65961.LDqXV2.rst | 1 - ...-09-23-15-23-14.gh-issue-123856.yrgJ9m.rst | 2 - ...-09-25-11-53-22.gh-issue-124442.EXC1Ve.rst | 2 - ...-09-25-14-45-56.gh-issue-124513.ywiXtr.rst | 2 - ...-09-26-12-19-13.gh-issue-124547.P_SHfU.rst | 3 - ...-09-26-13-25-01.gh-issue-119180.k_JCX0.rst | 2 - ...-09-26-17-55-34.gh-issue-116510.dhn8w8.rst | 3 - ...-09-26-18-21-06.gh-issue-116510.FacUWO.rst | 5 - ...-09-27-17-18-53.gh-issue-124642.OCjhBJ.rst | 1 - ...-09-30-16-39-37.gh-issue-118093.J2A3gz.rst | 2 - ...-10-03-14-39-41.gh-issue-123378.dCxANf.rst | 3 - ...-10-05-23-53-06.gh-issue-125008.ETANpd.rst | 2 - ...-10-07-23-33-18.gh-issue-125039.MKTyNI.rst | 1 - ...-10-10-12-04-56.gh-issue-125174._8h6T7.rst | 4 - ...-10-10-14-47-13.gh-issue-125221.nfSQzT.rst | 2 - ...-10-15-15-29-41.gh-issue-124375.wNrWVa.rst | 1 - .../2018-07-04-20-35-25.bpo-34008.bqecIb.rst | 8 - ...-06-03-22-06-26.gh-issue-119574.Ik9kOO.rst | 1 - ...-06-05-12-36-18.gh-issue-120012.f14DbQ.rst | 3 - ...-07-14-11-48-10.gh-issue-121749.nxHoTk.rst | 1 - ...-07-14-12-25-53.gh-issue-117765.YFMOUv.rst | 1 - ...-07-19-12-22-48.gh-issue-121277.wF_zKd.rst | 2 - ...4-08-01-17-18-21.gh-issue-70870.fZnBM9.rst | 3 - ...-09-11-16-52-08.gh-issue-123976.jhOfNR.rst | 1 - ...-09-19-19-33-25.gh-issue-116622.M65UZ6.rst | 1 - ...-09-24-11-52-36.gh-issue-124457.yrCjSV.rst | 2 - ...-09-27-16-47-48.gh-issue-124720.nVSTVb.rst | 2 - ...-10-07-00-31-17.gh-issue-125018.yKnymn.rst | 4 - ...-10-10-02-56-24.gh-issue-124872.0mDDOq.rst | 3 - ...-06-05-14-54-24.gh-issue-120104.j_thj4.rst | 1 - ...-06-16-21-42-45.gh-issue-120083.nczuyv.rst | 1 - ...4-07-16-16-57-03.gh-issue-78889.U7ghFD.rst | 2 - ...-07-30-18-02-55.gh-issue-122482.TerE0g.rst | 2 - ...-09-21-23-12-18.gh-issue-112938.OeiDru.rst | 1 - ...-10-04-15-34-34.gh-issue-122392.V8K3w2.rst | 2 - .../2018-12-04-07-36-27.bpo-14074.fMLKCu.rst | 2 - ...9-08-27-01-16-50.gh-issue-67693.4NIAiy.rst | 2 - .../2020-03-28-21-00-54.bpo-15987.aBL8XS.rst | 2 - .../2020-12-22-18-08-12.bpo-41843.q9Nh2r.rst | 2 - .../2021-08-24-19-37-46.bpo-44864.KzxaDh.rst | 1 - .../2022-03-10-16-47-57.bpo-45767.ywmyo1.rst | 3 - ...-03-30-18-19-53.gh-issue-103134.bHrn91.rst | 6 - ...3-04-10-00-04-37.gh-issue-87106.UyBnPQ.rst | 3 - ...-04-24-05-34-23.gh-issue-103194.GwBwWL.rst | 4 - ...3-04-26-22-24-17.gh-issue-92081.V8xMot.rst | 1 - ...-04-28-09-54-15.gh-issue-103956.EyLDPS.rst | 1 - ...-06-16-14-52-00.gh-issue-102450.MfeR6A.rst | 2 - ...-06-17-09-07-06.gh-issue-105623.5G06od.rst | 2 - ...-09-19-17-56-24.gh-issue-109109.WJvvX2.rst | 5 - ...-12-12-15-19-58.gh-issue-108172.KyDPuG.rst | 1 - ...-12-14-13-43-27.gh-issue-113008.jWYn8T.rst | 1 - ...-01-12-08-51-03.gh-issue-113978.MqTgB0.rst | 1 - ...-01-14-11-43-31.gh-issue-113878.dmEIN3.rst | 9 - ...-01-18-21-44-23.gh-issue-114264.DBKn29.rst | 1 - ...-02-22-10-12-59.gh-issue-115808.F2g2Ku.rst | 1 - ...-02-27-10-22-15.gh-issue-115937.0cVNur.rst | 3 - ...-03-19-21-41-31.gh-issue-106531.Mgd--6.rst | 6 - ...-04-19-05-58-50.gh-issue-117766.J3xepp.rst | 1 - ...-04-19-14-59-53.gh-issue-118033.amS4Gw.rst | 2 - ...-04-24-16-23-04.gh-issue-110190.TGd5qx.rst | 2 - ...-04-28-19-51-00.gh-issue-118263.Gaap3S.rst | 1 - ...-05-01-22-24-05.gh-issue-110863.GjYBbq.rst | 2 - ...-05-06-17-39-52.gh-issue-118673.sTXBit.rst | 1 - ...-05-07-17-38-53.gh-issue-118714.XXKpVZ.rst | 2 - ...-05-08-09-21-49.gh-issue-118772.c16E8X.rst | 2 - ...-05-08-18-33-07.gh-issue-118507.OCQsAY.rst | 2 - ...4-05-08-18-59-19.gh-issue-78707._Lz1sw.rst | 3 - ...-05-08-19-47-34.gh-issue-101357.e4R_9x.rst | 5 - ...4-05-08-20-41-48.gh-issue-74033.YebHZj.rst | 1 - ...-05-08-21-13-56.gh-issue-118760.mdmH3T.rst | 1 - ...-05-08-21-30-33.gh-issue-118760.XvyMHn.rst | 1 - ...-05-08-23-16-50.gh-issue-118798.Q_ybqP.rst | 2 - ...-05-09-00-52-30.gh-issue-118803.Wv3AvU.rst | 3 - ...-05-09-01-05-52.gh-issue-118805.N7dm07.rst | 3 - ...-05-09-02-43-37.gh-issue-101588.30bNAr.rst | 2 - ...-05-09-08-46-12.gh-issue-118851.aPAoJw.rst | 2 - ...-05-09-11-50-26.gh-issue-118824.-jBJQC.rst | 3 - ...-05-09-12-33-25.gh-issue-118827.JrzHz1.rst | 3 - ...-05-09-21-36-11.gh-issue-118868.uckxxP.rst | 2 - ...-05-10-05-24-32.gh-issue-118895.wUm5r2.rst | 2 - ...-05-10-22-36-01.gh-issue-118928.IW7Ukv.rst | 2 - ...-05-10-22-59-01.gh-issue-118924.9nyvSH.rst | 2 - ...4-05-11-20-23-45.gh-issue-82805.F9bz4J.rst | 5 - ...4-05-12-21-38-42.gh-issue-58933.0kgU2l.rst | 1 - ...4-05-15-01-36-08.gh-issue-73991.CGknDf.rst | 1 - ...-05-16-17-31-46.gh-issue-118643.hAWH4C.rst | 2 - ...-05-17-17-32-12.gh-issue-119113.kEv1Ll.rst | 2 - ...-05-19-12-25-36.gh-issue-119105.VcR4ig.rst | 1 - ...-05-19-13-05-59.gh-issue-119121.P1gnh1.rst | 2 - ...-05-19-18-49-04.gh-issue-119174.5GTv7d.rst | 3 - ...-05-20-13-48-37.gh-issue-119189.dhJVs5.rst | 3 - ...-05-20-20-30-57.gh-issue-111201.DAA5lC.rst | 1 - ...-05-21-19-10-30.gh-issue-115225.eRmfJH.rst | 1 - ...-05-21-20-13-23.gh-issue-118911.iG8nMq.rst | 5 - ...-05-21-23-39-22.gh-issue-118830.YTqvEo.rst | 1 - ...-05-22-21-20-43.gh-issue-118894.xHdxR_.rst | 1 - ...-05-23-11-52-36.gh-issue-117398.2FG1Mk.rst | 3 - ...-05-23-15-48-17.gh-issue-119461.82KqUW.rst | 1 - ...-05-23-22-29-59.gh-issue-119443.KAGz6S.rst | 2 - ...-05-24-04-05-37.gh-issue-119105.aDSRFn.rst | 1 - ...4-05-24-11-47-08.gh-issue-69214.Grl6zF.rst | 3 - ...-05-24-14-32-24.gh-issue-119506.-nMNqq.rst | 1 - ...-05-24-21-54-55.gh-issue-113892.JKDFqq.rst | 3 - ...-05-25-00-54-26.gh-issue-119127.LpPvag.rst | 2 - ...-05-25-07-25-07.gh-issue-117865.1A0Xpi.rst | 2 - ...-05-25-10-40-38.gh-issue-118908.XcZiq4.rst | 2 - ...-05-25-20-15-26.gh-issue-119555.mvHbEL.rst | 2 - ...-05-25-20-20-42.gh-issue-119562.DyplWc.rst | 3 - ...-05-26-21-28-11.gh-issue-119588.wlLBK5.rst | 1 - ...-05-26-22-22-51.gh-issue-119594.fnQNM8.rst | 1 - ...4-05-28-00-56-59.gh-issue-89727._bxoL3.rst | 3 - ...-05-28-12-15-03.gh-issue-119118.FMKz1F.rst | 2 - ...4-05-29-12-42-40.gh-issue-93963.cb1oJS.rst | 2 - ...4-05-29-20-42-17.gh-issue-89727.5lPTTW.rst | 3 - ...-05-29-21-50-05.gh-issue-119577.S3BlKJ.rst | 4 - ...4-05-30-21-37-05.gh-issue-89727.D6S9ig.rst | 2 - ...-05-31-12-57-31.gh-issue-119770.NCtels.rst | 1 - ...-05-31-13-56-21.gh-issue-119838.H6XHlE.rst | 3 - ...-05-31-21-17-43.gh-issue-119824.CQlxWV.rst | 1 - ...-06-01-16-58-43.gh-issue-117398.kR0RW7.rst | 2 - ...4-06-02-13-35-11.gh-issue-81936.ETeW9x.rst | 3 - ...-06-02-15-09-17.gh-issue-118835.KUAuz6.rst | 1 - ...-06-03-11-18-16.gh-issue-117142.kWTXQo.rst | 2 - ...4-06-04-08-57-02.gh-issue-65454.o9j4wF.rst | 1 - ...-06-04-12-23-01.gh-issue-119819.WKKrYh.rst | 2 - ...-06-04-14-54-46.gh-issue-120029._1YdTf.rst | 2 - ...-06-04-18-53-10.gh-issue-120057.RSD9_Z.rst | 4 - ...-06-04-19-03-25.gh-issue-112672.K2XfZH.rst | 1 - ...-06-04-19-49-16.gh-issue-120056.5aqozw.rst | 3 - ...-06-05-08-02-46.gh-issue-120108.4U9BL8.rst | 2 - ...-06-05-11-03-10.gh-issue-120029.QBsw47.rst | 4 - ...-06-05-11-39-21.gh-issue-119933.ooJXQV.rst | 3 - ...-06-05-16-30-28.gh-issue-120121.9dz8i7.rst | 1 - ...-06-06-12-07-57.gh-issue-119698.rRrprk.rst | 2 - ...-06-06-17-24-43.gh-issue-120161.DahNXV.rst | 2 - ...-06-07-02-00-31.gh-issue-120157.HnWcF9.rst | 1 - ...-06-07-10-10-32.gh-issue-117983.NeMR9n.rst | 2 - ...4-06-07-11-23-31.gh-issue-71587.IjFajE.rst | 2 - ...-06-07-13-21-11.gh-issue-120211.Rws_gf.rst | 1 - ...-06-08-03-29-01.gh-issue-120254.h682ke.rst | 1 - ...-06-08-09-45-31.gh-issue-120244.8o9Dzr.rst | 1 - ...-06-08-14-36-40.gh-issue-120268.MNpd1q.rst | 2 - ...-06-08-15-15-29.gh-issue-114053.WQLAFG.rst | 4 - ...-06-08-15-46-35.gh-issue-114053.Ub2XgJ.rst | 4 - ...4-06-08-17-41-11.gh-issue-82017.WpSTGi.rst | 2 - ...-06-09-19-53-11.gh-issue-120289.s4HXR0.rst | 2 - ...-06-10-14-00-40.gh-issue-119600.jJMf4C.rst | 2 - ...-06-11-07-17-25.gh-issue-119180.iH-2zy.rst | 4 - ...-06-11-16-34-41.gh-issue-120343.hdiXeU.rst | 1 - ...4-06-12-10-00-31.gh-issue-90425.5CfkKG.rst | 2 - ...-06-12-11-54-05.gh-issue-120381.O-BNLs.rst | 2 - ...-06-12-15-07-58.gh-issue-120388.VuTQMT.rst | 3 - ...-06-14-20-05-25.gh-issue-120495.OxgZKB.rst | 1 - ...-06-15-12-04-46.gh-issue-120541.d3cc5y.rst | 2 - ...-06-15-23-38-36.gh-issue-120284.HwsAtY.rst | 2 - ...-06-16-21-33-56.gh-issue-120606.kugbwR.rst | 1 - ...-06-17-20-04-13.gh-issue-120633.kZC5wt.rst | 1 - ...-06-18-14-45-38.gh-issue-118710.5GZZPX.rst | 1 - ...-06-18-19-18-10.gh-issue-120683.xmRez7.rst | 4 - ...-06-19-13-20-01.gh-issue-111259.Wki5PV.rst | 3 - ...-06-19-15-06-58.gh-issue-120732.OvYV9b.rst | 2 - ...-06-19-15-43-04.gh-issue-120743.CMMl2P.rst | 3 - ...4-06-19-19-53-42.gh-issue-41431.gnkUc5.rst | 2 - ...-06-19-23-08-25.gh-issue-120780.0Omopb.rst | 1 - ...-06-20-01-31-24.gh-issue-120769.PfiMrc.rst | 1 - ...-06-21-06-37-46.gh-issue-120713.WBbQx4.rst | 2 - ...-06-21-12-00-16.gh-issue-120782.LOE8tj.rst | 1 - ...-06-21-14-32-56.gh-issue-120811.eBmVTV.rst | 1 - ...-06-22-17-01-56.gh-issue-120678.Ik8dCg.rst | 3 - ...-06-22-22-23-56.gh-issue-101830.1BAoxH.rst | 2 - ...-06-22-22-52-24.gh-issue-120888.sd8I3N.rst | 1 - ...4-06-23-07-23-08.gh-issue-61103.ca_U_l.rst | 5 - ...-06-23-11-21-27.gh-issue-120910.t0QXdB.rst | 2 - ...-06-23-17-50-40.gh-issue-119614.vwPGLB.rst | 2 - ...-06-26-03-04-24.gh-issue-121018.clVSc4.rst | 3 - ...-06-26-10-13-40.gh-issue-121025.M-XXlV.rst | 2 - ...-06-26-17-00-39.gh-issue-117784.inCtAV.rst | 1 - ...-06-27-12-27-52.gh-issue-121027.D4K1OX.rst | 1 - ...-06-27-13-47-14.gh-issue-121027.jh55EC.rst | 2 - ...4-06-29-05-08-59.gh-issue-87744.rpF6Jw.rst | 1 - ...-06-29-15-21-12.gh-issue-121141.4evD6q.rst | 1 - ...-06-29-15-23-26.gh-issue-121151.HeLEvq.rst | 2 - ...-06-29-19-30-15.gh-issue-121163.SJKDFq.rst | 2 - ...-07-01-11-23-18.gh-issue-121210.cD0zfn.rst | 2 - ...-07-02-11-34-06.gh-issue-121245.sSkDAr.rst | 2 - ...-07-03-07-25-21.gh-issue-121332.Iz6FEq.rst | 4 - ...-07-03-10-11-53.gh-issue-121313.D7gARW.rst | 1 - ...-07-03-14-23-04.gh-issue-119004.L5MoUu.rst | 2 - ...4-07-04-17-36-03.gh-issue-59110.IlI9Fz.rst | 2 - ...-07-06-12-37-10.gh-issue-121423.vnxrl4.rst | 2 - ...-07-06-16-08-39.gh-issue-119169.o0YymL.rst | 1 - ...-07-06-23-39-38.gh-issue-121450.vGqb3c.rst | 4 - ...-07-08-03-45-34.gh-issue-121474.NsvrUN.rst | 2 - ...-07-09-12-23-32.gh-issue-121486.Iultjh.rst | 3 - ...-07-10-08-13-34.gh-issue-121249.W9Gd09.rst | 3 - ...-07-13-06-23-24.gh-issue-121245.RfOgf4.rst | 3 - ...4-07-14-06-24-02.gh-issue-57141.C3jhDh.rst | 2 - ...-07-14-11-18-28.gh-issue-120930.Kuo4L0.rst | 2 - ...-07-15-19-25-25.gh-issue-121798.GmuBDu.rst | 2 - ...-07-15-19-34-56.gh-issue-121797.qDqj59.rst | 2 - ...-07-16-20-49-07.gh-issue-121804.gYN-In.rst | 2 - ...-07-17-09-23-03.gh-issue-121889.6se9jS.rst | 1 - ...-07-17-09-44-35.gh-issue-119698.WlygzR.rst | 3 - ...-07-17-12-55-22.gh-issue-121268.41RmjR.rst | 1 - ...4-07-21-02-00-46.gh-issue-73991.pLxdtJ.rst | 1 - ...-07-21-10-45-24.gh-issue-122081.dNrYMq.rst | 2 - ...-07-21-18-03-30.gh-issue-122088.vi2bP-.rst | 3 - ...-07-22-08-14-04.gh-issue-113785.6B_KNB.rst | 1 - ...-07-22-08-57-28.gh-issue-120754.Eo5puP.rst | 1 - ...4-07-23-09-14-44.gh-issue-82951.-F5p5A.rst | 3 - ...-07-23-10-59-38.gh-issue-121723.iJEf7e.rst | 3 - ...-07-23-12-38-14.gh-issue-122145.sTO8nX.rst | 3 - ...-07-23-13-07-12.gh-issue-122129.PwbC8q.rst | 1 - ...-07-23-15-11-13.gh-issue-122163.4wRUuM.rst | 2 - ...-07-23-15-30-23.gh-issue-122170.Z9gi3Y.rst | 2 - ...-07-23-17-13-10.gh-issue-119180.5PZELo.rst | 2 - ...-07-23-22-26-00.gh-issue-119180.B2IVT8.rst | 7 - ...-07-24-08-48-22.gh-issue-122213.o3pdgA.rst | 2 - ...-07-25-15-41-14.gh-issue-105733.o3koJA.rst | 2 - ...-07-26-21-21-13.gh-issue-122332.fvw88r.rst | 2 - ...-07-27-16-10-41.gh-issue-121650.nf6oc9.rst | 5 - ...-07-29-10-24-48.gh-issue-122311.xChV1b.rst | 1 - ...-07-29-16-47-08.gh-issue-122400.fM0YSv.rst | 3 - ...-07-30-04-27-55.gh-issue-122272.6Wwa1V.rst | 2 - ...4-07-30-14-46-16.gh-issue-87320.-Yk1wb.rst | 3 - ...-07-30-15-57-07.gh-issue-122459.AYIoeN.rst | 2 - ...-07-30-21-29-30.gh-issue-122334.LeoE1x.rst | 1 - ...4-07-31-14-55-41.gh-issue-82378.eZvYmR.rst | 2 - ...-07-31-15-08-42.gh-issue-116622.aKxIQA.rst | 2 - ...-07-31-20-43-21.gh-issue-122478.sCU2Le.rst | 3 - ...-08-03-06-51-08.gh-issue-122637.gpas8J.rst | 1 - ...-08-04-14-07-18.gh-issue-118814.uiyks1.rst | 1 - ...-08-06-07-24-00.gh-issue-118974.qamsCQ.rst | 2 - ...-08-06-10-36-55.gh-issue-118761.q_x_1A.rst | 2 - ...-08-06-18-07-19.gh-issue-122744.kCzNDI.rst | 1 - ...-08-07-11-57-41.gh-issue-122311.LDExnJ.rst | 5 - ...-08-07-14-12-19.gh-issue-105376.QbGPdE.rst | 3 - ...-08-07-17-41-16.gh-issue-116263.EcXir0.rst | 2 - ...-08-10-10-21-44.gh-issue-122858.ZC1rJD.rst | 2 - ...-08-10-14-16-59.gh-issue-122873.XlHaUn.rst | 3 - ...-08-11-14-08-04.gh-issue-122905.7tDsxA.rst | 1 - ...-08-11-14-23-07.gh-issue-122903.xktZta.rst | 2 - ...-08-14-10-41-11.gh-issue-122981.BHV0Z9.rst | 2 - ...-08-15-09-45-34.gh-issue-121735._1q0qf.rst | 3 - ...-08-16-16-53-52.gh-issue-123049.izx_fH.rst | 2 - ...-08-16-19-13-21.gh-issue-123067.Nx9O4R.rst | 1 - ...-08-17-08-17-20.gh-issue-123085.7Io2yH.rst | 3 - ...-08-18-08-25-32.gh-issue-123084.rf8izX.rst | 4 - ...-08-19-17-37-18.gh-issue-122909.kP12SK.rst | 3 - ...-08-20-14-22-49.gh-issue-123165.vOZZOA.rst | 1 - ...4-08-20-18-02-27.gh-issue-85110.8_iDQy.rst | 2 - ...-08-22-09-37-48.gh-issue-123213.owmXnP.rst | 3 - ...-08-22-11-25-19.gh-issue-122546.BSmeE7.rst | 2 - ...-08-22-20-10-13.gh-issue-123243.Kifj1L.rst | 1 - ...-08-23-15-49-10.gh-issue-116810.QLBUU8.rst | 4 - ...4-08-23-22-01-30.gh-issue-76960.vsANPu.rst | 5 - ...-08-24-00-03-01.gh-issue-123240.uFPG3l.rst | 1 - ...-08-24-06-05-41.gh-issue-123228.jR_5O5.rst | 3 - ...4-08-25-16-59-20.gh-issue-73991.1w8u3K.rst | 2 - ...-08-26-13-45-20.gh-issue-123270.gXHvNJ.rst | 3 - ...-08-26-18-48-13.gh-issue-119518.QFYH9q.rst | 2 - ...-08-26-19-36-00.gh-issue-123340.mQKI1H.rst | 1 - ...-08-27-10-30-37.gh-issue-123341.5e-fjt.rst | 1 - ...-08-27-12-11-00.gh-issue-123363.gKuJp6.rst | 2 - ...-08-27-12-38-42.gh-issue-123089.vA7iFR.rst | 1 - ...-08-28-13-03-36.gh-issue-123409.lW0YF-.rst | 2 - ...-08-28-20-08-19.gh-issue-123448.tItJlp.rst | 2 - ...-08-29-09-27-12.gh-issue-123446._I_mMr.rst | 3 - ...-08-29-14-51-36.gh-issue-123430.M7wXl9.rst | 1 - ...-08-30-09-01-35.gh-issue-123504.lJ9_BB.rst | 1 - ...-08-31-12-34-44.gh-issue-123374.3kE7rb.rst | 1 - ...-09-02-20-34-04.gh-issue-123339.czgcSu.rst | 4 - ...-09-04-18-23-43.gh-issue-123657.Oks4So.rst | 2 - ...-09-06-00-00-43.gh-issue-122765.tx4hsr.rst | 1 - ...-09-06-01-35-11.gh-issue-123756.Ozbhke.rst | 1 - ...4-09-06-10-17-54.gh-issue-84808.ION67Z.rst | 3 - ...-09-10-11-26-14.gh-issue-123892.2gzIrz.rst | 1 - ...-09-11-13-33-19.gh-issue-123935.fRZ_56.rst | 2 - ...-09-11-19-05-32.gh-issue-123945.jLwybB.rst | 1 - ...-09-11-19-12-23.gh-issue-123968.OwHON_.rst | 1 - ...-09-12-10-55-19.gh-issue-124016.ncs0hd.rst | 1 - ...-09-13-10-34-19.gh-issue-123934.yMe7mL.rst | 2 - ...-09-16-12-31-48.gh-issue-123978.z3smEu.rst | 1 - ...-09-17-18-06-42.gh-issue-124171.PHCvRJ.rst | 3 - ...-09-18-17-45-52.gh-issue-124212.n6kIby.rst | 1 - ...4-09-19-00-09-48.gh-issue-84559.IrxvQe.rst | 5 - ...4-09-19-03-46-59.gh-issue-87041.9Ox7Bv.rst | 1 - ...4-09-19-10-36-18.gh-issue-81691.Hyhp_U.rst | 3 - ...-09-19-11-47-39.gh-issue-124248.g7rufd.rst | 2 - ...-09-19-16-00-22.gh-issue-111513.6jHm02.rst | 1 - ...-09-19-20-15-00.gh-issue-124217.j0KlQB.rst | 1 - ...4-09-20-12-23-11.gh-issue-53780.mrV1zi.rst | 1 - ...-09-20-18-23-19.gh-issue-100980.8nVAB6.rst | 3 - ...4-09-21-19-02-37.gh-issue-59317.OAhNZZ.rst | 2 - ...4-09-21-22-32-21.gh-issue-72795.naLmkX.rst | 4 - ...4-09-21-23-56-41.gh-issue-63143.YKu-LQ.rst | 3 - ...-09-23-17-33-47.gh-issue-104860.O86OSc.rst | 2 - ...4-09-23-18-26-17.gh-issue-90562.Yj566G.rst | 3 - ...-09-24-00-01-24.gh-issue-124400.0XCgfe.rst | 1 - ...-09-24-12-34-48.gh-issue-124345.s3vKql.rst | 2 - ...-09-24-13-32-16.gh-issue-124176.6hmOPz.rst | 4 - ...-09-24-19-32-14.gh-issue-123014.zVcfkZ.rst | 3 - ...-09-24-21-15-27.gh-issue-123017.dSAr2f.rst | 2 - ...-09-24-22-38-51.gh-issue-123884.iEPTK4.rst | 4 - ...4-09-25-10-25-57.gh-issue-53834.uyIckw.rst | 4 - ...-09-25-12-14-58.gh-issue-124498.Ozxs55.rst | 2 - ...-09-25-18-07-51.gh-issue-120378.NlBSz_.rst | 2 - ...4-09-25-18-08-29.gh-issue-80259.kO5Tw7.rst | 2 - ...-09-25-18-34-48.gh-issue-124538.nXZk4R.rst | 1 - ...-09-25-22-06-52.gh-issue-124552.1nQKNM.rst | 1 - ...-09-26-00-35-24.gh-issue-116750.X1aMHI.rst | 1 - ...4-09-26-09-18-09.gh-issue-61181.dwjmch.rst | 2 - ...-09-26-13-43-39.gh-issue-124594.peYhsP.rst | 1 - ...4-09-26-22-14-12.gh-issue-58573.hozbm9.rst | 2 - ...-09-27-06-39-32.gh-issue-101552.xYkzag.rst | 4 - ...-09-27-15-16-04.gh-issue-116850.dBkR0-.rst | 2 - ...4-09-30-19-59-28.gh-issue-66436.4gYN_n.rst | 4 - ...-09-30-20-46-32.gh-issue-124787.3FnJnP.rst | 4 - ...-10-01-02-31-13.gh-issue-124693.qzbXKB.rst | 1 - ...-10-01-12-43-42.gh-issue-124835.SVyp3K.rst | 3 - ...4-10-01-13-11-53.gh-issue-85935.CTwJUy.rst | 4 - ...-10-01-13-46-58.gh-issue-124390.dK1Zcm.rst | 1 - ...-10-01-17-12-20.gh-issue-124858.Zy0tvT.rst | 1 - ...4-10-01-23-29-09.gh-issue-91818.Kz8cPI.rst | 4 - ...-10-02-15-05-45.gh-issue-124653.tqsTu9.rst | 2 - ...4-10-02-16-35-07.gh-issue-65865.S2D4wq.rst | 3 - ...-10-02-21-11-18.gh-issue-124917.Lnwh5b.rst | 2 - ...4-10-02-22-53-48.gh-issue-90102.4qX52R.rst | 3 - ...-10-03-05-00-25.gh-issue-117151.Prdw_W.rst | 3 - ...-10-03-17-13-22.gh-issue-124944.YyLAzf.rst | 1 - ...-10-03-19-16-38.gh-issue-123961.ik1Dgs.rst | 2 - ...4-10-03-20-45-57.gh-issue-53203.3Sk4Ia.rst | 5 - ...-10-04-08-46-00.gh-issue-124958.rea9-x.rst | 1 - ...4-10-04-12-43-03.gh-issue-69998.DVqOXX.rst | 3 - ...-10-05-15-49-53.gh-issue-124960.Bol9hT.rst | 1 - ...-10-08-12-09-09.gh-issue-124969._VBQLq.rst | 3 - ...-10-08-13-28-22.gh-issue-125096.Vz0W5g.rst | 5 - ...-10-08-21-17-16.gh-issue-125069.0RP0Mx.rst | 4 - ...-10-09-07-09-00.gh-issue-125118.J9rQ1S.rst | 1 - ...4-10-09-21-42-43.gh-issue-61011.pQXZb1.rst | 4 - ...-10-10-18-33-31.gh-issue-125235.0kOB5I.rst | 2 - ...-10-10-19-57-35.gh-issue-125254.RtZxXS.rst | 1 - ...-10-10-20-39-57.gh-issue-125243.eUbbtu.rst | 2 - ...-10-11-04-04-38.gh-issue-125260.PeZ0Mb.rst | 2 - ...4-10-11-16-19-46.gh-issue-89967.vhWUOR.rst | 1 - ...-10-11-18-03-05.gh-issue-125206.pWRRK6.rst | 2 - ...4-10-13-20-21-35.gh-issue-53203.Rz1c8A.rst | 2 - ...-10-14-02-27-03.gh-issue-100141.NuAcwa.rst | 1 - ...-10-14-04-44-12.gh-issue-125422.MlVuC6.rst | 1 - ...-05-01-20-57-09.gh-issue-118486.K44KJG.rst | 4 - ...-05-08-21-59-38.gh-issue-118773.7dFRJY.rst | 2 - ...-06-25-04-42-43.gh-issue-112301.god4IC.rst | 2 - ...-07-02-13-39-20.gh-issue-121285.hrl-yI.rst | 2 - ...-07-08-23-39-04.gh-issue-112301.TD8G01.rst | 2 - ...-07-18-13-17-47.gh-issue-121957.QemKLU.rst | 3 - ...-07-22-13-11-28.gh-issue-122133.0mPeta.rst | 5 - ...-07-24-05-18-25.gh-issue-112301.lfINgZ.rst | 2 - ...-08-06-00-06-23.gh-issue-112301.4k4lw6.rst | 2 - ...-08-07-10-42-13.gh-issue-122792.oiTMo9.rst | 3 - ...-08-14-19-43-57.gh-issue-112301.IQUcOy.rst | 1 - ...-09-04-12-41-35.gh-issue-123678.N41y9n.rst | 1 - ...-10-09-20-08-13.gh-issue-125140.YgNWRB.rst | 1 - ...-08-03-17-26-55.gh-issue-107562.ZnbscS.rst | 3 - ...-05-04-22-56-41.gh-issue-101525.LHK166.rst | 2 - ...-05-18-10-59-27.gh-issue-119050.g4qiH7.rst | 2 - ...-05-20-18-06-31.gh-issue-119273.hf-yhX.rst | 3 - ...-05-29-15-28-08.gh-issue-119727.dVkaZM.rst | 2 - ...-06-20-12-51-26.gh-issue-120801.lMVXC9.rst | 2 - ...-07-01-09-04-32.gh-issue-121188.XbuTVa.rst | 3 - ...-07-01-16-15-06.gh-issue-121200.4Pc-gc.rst | 3 - ...-07-03-14-41-00.gh-issue-121160.LEtiTd.rst | 2 - ...-07-04-15-10-29.gh-issue-121084.qxcd5d.rst | 3 - ...4-07-13-11-04-44.gh-issue-99242.aGxnwz.rst | 3 - ...4-07-13-11-48-20.gh-issue-59022.fYNbQ8.rst | 1 - ...-07-13-21-55-58.gh-issue-112301.YJS1dl.rst | 2 - ...-07-17-08-25-06.gh-issue-121921.HW8CIS.rst | 2 - ...-09-17-22-21-58.gh-issue-124190.3fWhiX.rst | 1 - ...-09-18-18-39-21.gh-issue-124213.AQq_xg.rst | 3 - ...-09-25-12-39-34.gh-issue-124378.Ywwgia.rst | 1 - ...-10-07-14-13-38.gh-issue-125041.PKLWDf.rst | 3 - ...-09-04-10-07-51.gh-issue-123418.1eIFZb.rst | 2 - ...2-04-20-18-32-30.gh-issue-79846.Vggv3f.rst | 2 - ...-04-24-05-16-32.gh-issue-118209.Ryyzlz.rst | 2 - ...-04-24-22-50-33.gh-issue-117505.gcTb_p.rst | 1 - ...-05-22-19-43-29.gh-issue-119070._enton.rst | 3 - ...-05-25-18-43-10.gh-issue-111201.SLPJIx.rst | 1 - ...-05-29-11-06-12.gh-issue-119690.8q6e1p.rst | 1 - ...-05-30-17-39-25.gh-issue-119679.mZC87w.rst | 1 - ...-07-19-21-50-54.gh-issue-100256.GDrKba.rst | 1 - ...-08-01-10-55-15.gh-issue-122573.4-UCFY.rst | 1 - ...-08-29-16-13-45.gh-issue-123476.m2DFS4.rst | 1 - ...-09-04-09-59-18.gh-issue-123418.QaMC12.rst | 1 - ...-09-10-19-23-00.gh-issue-123915.yZMEDO.rst | 1 - ...-09-20-11-18-50.gh-issue-124254.iPin-L.rst | 1 - ...-09-24-19-04-56.gh-issue-124448.srVT3d.rst | 1 - ...-09-27-13-40-25.gh-issue-124609.WaKk8G.rst | 1 - ...-09-27-15-07-30.gh-issue-124487.7LrwHC.rst | 1 - ...-09-04-11-55-29.gh-issue-123418.8P4bmN.rst | 1 - ...-09-07-12-14-54.gh-issue-123797.yFDeug.rst | 1 - ...-09-24-10-48-46.gh-issue-124448.bFMrS6.rst | 1 - README.rst | 2 +- 645 files changed, 7739 insertions(+), 1993 deletions(-) create mode 100644 Misc/NEWS.d/3.14.0a1.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-05-11-15-11-30.gh-issue-118943.VI_MnY.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-05-13-15-57-58.gh-issue-118836.7yN1iB.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-05-17-19-53-27.gh-issue-119132.wepPgM.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-05-19-22-54-55.gh-issue-115119.DwMwev.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-05-22-13-18-02.gh-issue-119400.WEt83v.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-05-29-17-40-50.gh-issue-119729.k0xJ5U.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-06-02-13-23-26.gh-issue-113565.8xBlId.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-06-09-15-54-22.gh-issue-120291.IpfHzE.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-06-11-00-38-05.gh-issue-120326.JHSDF1.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-06-18-15-28-25.gh-issue-118943.aie7nn.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-06-18-15-32-36.gh-issue-120688.tjIPLD.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-06-19-21-05-15.gh-issue-120602.UyDARz.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-06-21-09-24-03.gh-issue-120671.Z8sBQB.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-06-27-18-03-20.gh-issue-121082.w3AfRx.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-07-02-12-42-25.gh-issue-120831.i3eIjg.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-07-02-20-16-09.gh-issue-121103.TMef9j.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-07-08-01-11-54.gh-issue-121467.3qWRQj.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-07-08-14-01-17.gh-issue-121487.ekHmpR.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-07-14-01-29-47.gh-issue-121731.RMPGP3.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-07-16-12-29-54.gh-issue-120371.E7x858.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-07-18-07-53-07.gh-issue-120522.dg3o5A.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-07-19-10-14-31.gh-issue-121996.IEb2sz.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-08-02-12-59-15.gh-issue-118943.vZQtET.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-08-07-00-20-18.gh-issue-116622.U9cxHM.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-08-12-15-48-49.gh-issue-122578.YJ3xEa.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-08-14-19-17-34.gh-issue-121634.eOMfHG.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-08-24-19-09-31.gh-issue-123297.fdtXoe.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-09-04-12-01-43.gh-issue-123418.ynzspB.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-09-13-17-48-37.gh-issue-124043.Bruxpq.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-09-16-09-42-05.gh-issue-124102.Ow254j.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-09-23-11-27-25.gh-issue-123990.d6HrYC.rst delete mode 100644 Misc/NEWS.d/next/Build/2024-10-13-21-11-30.gh-issue-125269.BC-fdo.rst delete mode 100644 Misc/NEWS.d/next/C API/2018-06-30-21-48-16.bpo-34008.2Wjtm0.rst delete mode 100644 Misc/NEWS.d/next/C API/2022-08-05-19-41-20.gh-issue-87135.SCNBYj.rst delete mode 100644 Misc/NEWS.d/next/C API/2022-10-01-09-56-27.gh-issue-97588.Gvg54o.rst delete mode 100644 Misc/NEWS.d/next/C API/2024-03-10-14-55-51.gh-issue-116560.x2mZaO.rst delete mode 100644 Misc/NEWS.d/next/C API/2024-04-10-16-48-04.gh-issue-117511.RZtBRK.rst delete mode 100644 Misc/NEWS.d/next/C API/2024-05-08-20-13-00.gh-issue-118789.m88uUa.rst delete mode 100644 Misc/NEWS.d/next/C API/2024-05-08-21-57-50.gh-issue-118789.Ni4UQx.rst delete mode 100644 Misc/NEWS.d/next/C API/2024-05-08-23-14-06.gh-issue-116984.5sgcDo.rst delete mode 100644 Misc/NEWS.d/next/C API/2024-05-10-15-43-14.gh-issue-118771.5KVglT.rst delete mode 100644 Misc/NEWS.d/next/C API/2024-05-20-10-35-22.gh-issue-111389.a6axBk.rst delete mode 100644 Misc/NEWS.d/next/C API/2024-05-21-11-35-11.gh-issue-119247.U6n6mh.rst delete mode 100644 Misc/NEWS.d/next/C API/2024-05-21-18-28-44.gh-issue-119333.OTsYVX.rst delete mode 100644 Misc/NEWS.d/next/C API/2024-05-21-19-41-41.gh-issue-119344.QKvzQb.rst delete mode 100644 Misc/NEWS.d/next/C API/2024-05-22-17-50-48.gh-issue-119336.ff3qnS.rst delete mode 100644 Misc/NEWS.d/next/C API/2024-05-29-09-21-37.gh-issue-119613.J2xfrC.rst delete mode 100644 Misc/NEWS.d/next/C API/2024-05-29-21-05-59.gh-issue-119585.Sn7JL3.rst delete mode 100644 Misc/NEWS.d/next/C API/2024-05-30-12-51-21.gh-issue-119775.CBq9IG.rst delete mode 100644 Misc/NEWS.d/next/C API/2024-06-04-10-58-20.gh-issue-119613.qOr9GF.rst delete mode 100644 Misc/NEWS.d/next/C API/2024-06-07-22-12-30.gh-issue-119182.yt8Ar7.rst delete mode 100644 Misc/NEWS.d/next/C API/2024-06-08-08-33-40.gh-issue-119771.Oip2dL.rst delete mode 100644 Misc/NEWS.d/next/C API/2024-06-11-21-38-32.gh-issue-70278.WDE4zM.rst delete mode 100644 Misc/NEWS.d/next/C API/2024-06-16-22-58-47.gh-issue-120600.TJdf0w.rst delete mode 100644 Misc/NEWS.d/next/C API/2024-06-19-17-27-22.gh-issue-120389.GSZeHF.rst delete mode 100644 Misc/NEWS.d/next/C API/2024-06-19-21-27-42.gh-issue-120642.UlKClN.rst delete mode 100644 Misc/NEWS.d/next/C API/2024-06-21-16-41-21.gh-issue-120858.Z5_-Mn.rst delete mode 100644 Misc/NEWS.d/next/C API/2024-06-26-11-29-01.gh-issue-120642.H7P9qK.rst delete mode 100644 Misc/NEWS.d/next/C API/2024-07-02-11-03-40.gh-issue-112136.f3fiY8.rst delete mode 100644 Misc/NEWS.d/next/C API/2024-07-04-13-23-27.gh-issue-113601.K3RLqp.rst delete mode 100644 Misc/NEWS.d/next/C API/2024-07-04-15-41-10.gh-issue-113993.cLSiWV.rst delete mode 100644 Misc/NEWS.d/next/C API/2024-07-21-17-40-07.gh-issue-121489.SUMFCr.rst delete mode 100644 Misc/NEWS.d/next/C API/2024-07-30-23-48-26.gh-issue-116622.yTTtil.rst delete mode 100644 Misc/NEWS.d/next/C_API/2024-07-09-15-55-20.gh-issue-89364.yYYroI.rst delete mode 100644 Misc/NEWS.d/next/C_API/2024-07-12-13-40-59.gh-issue-121645.96QvD3.rst delete mode 100644 Misc/NEWS.d/next/C_API/2024-07-27-00-28-35.gh-issue-105201.0-xUWq.rst delete mode 100644 Misc/NEWS.d/next/C_API/2024-08-06-14-23-11.gh-issue-122728.l-fQ-v.rst delete mode 100644 Misc/NEWS.d/next/C_API/2024-08-09-13-12-20.gh-issue-122854.-1OgvU.rst delete mode 100644 Misc/NEWS.d/next/C_API/2024-08-26-13-01-20.gh-issue-100554.0ku85o.rst delete mode 100644 Misc/NEWS.d/next/C_API/2024-08-29-15-05-19.gh-issue-123465.eqwNWq.rst delete mode 100644 Misc/NEWS.d/next/C_API/2024-08-29-15-55-55.gh-issue-107954.pr2O50.rst delete mode 100644 Misc/NEWS.d/next/C_API/2024-08-30-14-02-17.gh-issue-107954.TPvj4u.rst delete mode 100644 Misc/NEWS.d/next/C_API/2024-09-10-16-54-27.gh-issue-123909.CTGxDR.rst delete mode 100644 Misc/NEWS.d/next/C_API/2024-09-12-16-16-24.gh-issue-123880.2-8vcj.rst delete mode 100644 Misc/NEWS.d/next/C_API/2024-09-16-16-21-39.gh-issue-124127.LB8DBU.rst delete mode 100644 Misc/NEWS.d/next/C_API/2024-09-17-05-23-35.gh-issue-124153.L8TWmx.rst delete mode 100644 Misc/NEWS.d/next/C_API/2024-09-18-18-40-30.gh-issue-124160.Zy-VKi.rst delete mode 100644 Misc/NEWS.d/next/C_API/2024-09-24-20-34-21.gh-issue-124296.S4QoS1.rst delete mode 100644 Misc/NEWS.d/next/C_API/2024-09-25-11-44-02.gh-issue-124502.qWuDjT.rst delete mode 100644 Misc/NEWS.d/next/C_API/2024-10-03-14-06-08.gh-issue-123961.uwJQTY.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2018-10-09-15-14-53.bpo-24766.c_C1Wc.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-07-22-15-56-35.gh-issue-95144.FZYWX-.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2023-10-14-23-05-40.gh-issue-84978.Z0t6dg.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-01-15-18-11-48.gh-issue-113190.OwQX64.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-01-15-21-51-26.gh-issue-114091.VOtSJl.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-03-19-22-21-22.gh-issue-116022.iyHENN.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-03-25-15-07-01.gh-issue-117195.OWakgD.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-04-08-13-49-02.gh-issue-117558.9lSEpR.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-04-27-18-36-46.gh-issue-115801.SVeHSy.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-01-05-09-16.gh-issue-117139.t41w_D.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-07-16-57-56.gh-issue-118561.wNMKVd.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-08-09-44-15.gh-issue-118767.iFF5F5.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-09-02-37-25.gh-issue-118750.7aLfT-.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-09-19-47-12.gh-issue-117657.Vn0Yey.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-10-19-54-18.gh-issue-118921.O4ztZG.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-11-21-44-17.gh-issue-118844.q2H_km.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-15-12-15-58.gh-issue-119057.P3G9G2.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-16-23-02-03.gh-issue-119049.qpd_S-.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-20-10-10-51.gh-issue-119180.35xqpu.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-20-14-57-39.gh-issue-118692.Qadm7F.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-21-09-46-51.gh-issue-119011.WOe3bu.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-21-11-27-14.gh-issue-119213.nxjxrt.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-21-12-17-02.gh-issue-119180.UNDUb9.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-22-06-22-47.gh-issue-119180.vZMiXm.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-22-12-49-03.gh-issue-119372.PXig1R.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-23-06-34-14.gh-issue-119395.z-Hsqb.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-23-06-34-45.gh-issue-119311.2DBwKR.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-23-20-17-37.gh-issue-119258.wZFIpt.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-24-21-04-00.gh-issue-119525.zLFLf1.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-24-21-16-52.gh-issue-119369.qBThho.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-25-12-52-25.gh-issue-119560.wSlm8q.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-25-13-51-48.gh-issue-111999.L0q1gh.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-25-16-45-27.gh-issue-119548.pqF9Y6.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-27-19-13-49.gh-issue-109218.-sdDg0.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-28-22-49-56.gh-issue-119689.VwLFD5.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-29-18-53-43.gh-issue-119740.zP2JNM.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-30-04-11-36.gh-issue-118934.fbDqve.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-30-23-01-00.gh-issue-119821.jPGfvt.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-31-08-23-41.gh-issue-119180.KL4VxZ.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-31-12-06-11.gh-issue-119842.tCGVsv.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-02-06-12-35.gh-issue-119879.Jit951.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-03-13-25-04.gh-issue-119724.EH1dkA.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-03-13-48-44.gh-issue-119933.Kc0HG5.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-05-08-39-40.gh-issue-120080.DJFK11.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-05-10-32-44.gh-issue-120097.9S2klk.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-05-18-29-18.gh-issue-93691.6OautB.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-07-16-09-04.gh-issue-120225.kuYf9t.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-07-22-54-15.gh-issue-119726.D9EE-o.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-09-19-13-38.gh-issue-119666.S0G4rZ.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-10-10-42-48.gh-issue-120298.napREA.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-10-15-07-16.gh-issue-120198.WW_pjO.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-10-22-30-26.gh-issue-93691.68WOTS.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-11-12-47-54.gh-issue-120346.hhn_6X.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-11-17-56-12.gh-issue-120221.si9hM9.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-12-13-47-25.gh-issue-120397.n-I_cc.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-12-18-23-15.gh-issue-120380.edtqjq.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-12-18-50-29.gh-issue-120367.LmXx2y.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-13-12-17-52.gh-issue-120384.w1UBGl.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-14-07-52-00.gh-issue-120485.yy4K4b.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-14-22-02-25.gh-issue-113993.MiA0vX.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-17-12-20-20.gh-issue-120507.94lz2J.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-18-21-34-30.gh-issue-120367.zDwffP.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-18-22-41-05.gh-issue-120722.rS7tkE.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-19-01-58-54.gh-issue-120437.nCkIoI.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-19-11-10-50.gh-issue-119462.DpcqSe.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-19-19-54-35.gh-issue-120754.uF29sj.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-19-21-34-21.gh-issue-98442.cqhjkN.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-24-08-39-23.gh-issue-116017.-Bw2UY.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-25-16-26-44.gh-issue-119726.WqvHxB.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-26-13-42-36.gh-issue-113433.xKAtLB.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-26-14-09-31.gh-issue-120838.nFeTL9.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-28-10-02-58.gh-issue-121115.EeSLfc.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-28-18-34-49.gh-issue-119726.Fjv_Ab.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-28-23-17-22.gh-issue-121381.i2xL7P.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-29-10-46-14.gh-issue-121130.Rj66Xs.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-30-03-48-10.gh-issue-121149.lLBMKe.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-07-04-23-38-30.gh-issue-121368.m3EF9E.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-07-05-11-29-27.gh-issue-121288.lYKYYP.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-07-08-02-24-55.gh-issue-121439.jDHod3.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-07-08-10-31-08.gh-issue-121012.M5hHk-.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-07-08-17-15-14.gh-issue-121497.I8hMDC.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-07-09-13-53-18.gh-issue-121499.rpp7il.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-07-10-02-02-32.gh-issue-121562.8beIMi.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-07-10-15-43-54.gh-issue-117482.5WYaXR.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-07-12-18-18-44.gh-issue-121297.67VE7b.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-07-13-12-27-31.gh-issue-121657.wgOYLw.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-07-15-16-26-32.gh-issue-121794.fhBtiQ.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-07-15-20-41-06.gh-issue-121814.oR2ixR.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-07-16-15-11-51.gh-issue-121795.xkIHrI.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-07-16-18-23-22.gh-issue-121860.-FTauD.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-07-19-09-38-01.gh-issue-99108.qzM6gl.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-07-19-15-28-05.gh-issue-122026.sta2Ca.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-07-21-01-23-54.gh-issue-122029.gKv-e2.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-07-23-11-57-36.gh-issue-122160.HSnrAP.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-07-23-23-59-04.gh-issue-122208.z8KHsY.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-07-24-17-11-51.gh-issue-122234.VxsP_F.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-07-24-22-39-07.gh-issue-122245.LVa9v8.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-07-26-14-05-51.gh-issue-122300.SVIF-l.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-07-30-11-41-35.gh-issue-122445.Rq0bjS.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-08-05-19-04-06.gh-issue-116622.3LWUzE.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-08-18-18-25-54.gh-issue-123123.0ZcaEB.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-08-20-11-09-16.gh-issue-123048.2TISpv.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-08-20-12-29-52.gh-issue-123142.3PXiNb.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-08-21-15-22-53.gh-issue-121804.r5K3PS.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-08-23-13-08-27.gh-issue-123229.aHm-dw.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-08-23-15-59-54.gh-issue-123177.OLcaC5.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-08-25-10-54-22.gh-issue-122982.KLD91q.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-08-26-00-58-26.gh-issue-123321.ApxcnE.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-08-27-13-16-40.gh-issue-123344.56Or78.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-09-23-23-06-19.gh-issue-124285.mahGTg.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-10-03-22-26-39.gh-issue-124871.tAMF47.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-07-13-09-51-44.gh-issue-121609.jWsE5t.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-07-15-20-03-29.gh-issue-121295.w53ucI.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-07-18-21-19-04.gh-issue-121999.8IBbTK.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-07-25-01-45-21.gh-issue-122239.7zh-sW.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-07-26-13-56-32.gh-issue-120906.qBh2I9.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-07-29-10-55-46.gh-issue-116090.p1MhU0.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-07-29-19-20-25.gh-issue-122417.NVgs0a.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-08-01-19-13-58.gh-issue-122527.eztso6.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-08-05-19-28-12.gh-issue-122697.17MvYl.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-08-08-16-02-28.gh-issue-118093.m6Mrvy.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-08-10-12-44-03.gh-issue-122888.TUyu9r.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-08-12-11-19-37.gh-issue-122907.q68096.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-08-12-11-45-47.gh-issue-122821.WnAzTK.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-08-14-11-38-56.gh-issue-118093.3BywDP.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-08-15-19-28-43.gh-issue-123022.m3EF9E.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-08-17-17-26-25.gh-issue-123083.9xWLJ-.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-08-19-15-13-13.gh-issue-118093.dLZ8qS.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-08-21-08-53-00.gh-issue-115776.9A7Dv_.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-08-23-11-26-54.gh-issue-122298.ZMyln4.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-08-23-18-31-10.gh-issue-123275.DprIrj.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-08-23-21-20-34.gh-issue-123271.xeVViR.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-08-25-18-27-49.gh-issue-123177.yLuyqE.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-08-27-21-44-14.gh-issue-116017.ZY3yBY.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-08-28-22-42-51.gh-issue-123440.yOFB0N.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-08-29-13-18-18.gh-issue-123446.KWDrgq.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-08-29-19-46-07.gh-issue-123484.rjUn_F.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-09-01-00-02-05.gh-issue-123545.8nQNbL.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-09-01-12-08-39.gh-issue-123562.aJPKVu.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-09-02-17-32-15.gh-issue-119034.HYh5Vj.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-09-02-20-36-45.gh-issue-123339.QcmpSs.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-09-02-20-39-10.gh-issue-123614.26TMHp.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-09-03-13-34-35.gh-issue-123572.uuqoYV.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-09-06-14-13-01.gh-issue-119310.WQxyDF.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-09-06-19-23-44.gh-issue-120221.giJEDT.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-09-10-13-27-16.gh-issue-77894.ZC-Olu.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-09-10-20-25-00.gh-issue-123923.A7uxqa.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-09-11-15-48-36.gh-issue-123958.5VW2r0.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-09-12-21-53-26.gh-issue-124022.fQzUiW.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-09-13-02-25-06.gh-issue-124027.to_9DY.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-09-17-22-06-01.gh-issue-124188.aFqNAB.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-09-19-13-17-31.gh-issue-122878.4iFpsB.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-09-19-16-57-34.gh-issue-119726.DseseK.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-09-23-13-25-27.gh-issue-65961.LDqXV2.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-09-23-15-23-14.gh-issue-123856.yrgJ9m.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-09-25-11-53-22.gh-issue-124442.EXC1Ve.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-09-25-14-45-56.gh-issue-124513.ywiXtr.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-09-26-12-19-13.gh-issue-124547.P_SHfU.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-09-26-13-25-01.gh-issue-119180.k_JCX0.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-09-26-17-55-34.gh-issue-116510.dhn8w8.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-09-26-18-21-06.gh-issue-116510.FacUWO.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-09-27-17-18-53.gh-issue-124642.OCjhBJ.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-09-30-16-39-37.gh-issue-118093.J2A3gz.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-10-03-14-39-41.gh-issue-123378.dCxANf.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-10-05-23-53-06.gh-issue-125008.ETANpd.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-10-07-23-33-18.gh-issue-125039.MKTyNI.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-10-10-12-04-56.gh-issue-125174._8h6T7.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-10-10-14-47-13.gh-issue-125221.nfSQzT.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-10-15-15-29-41.gh-issue-124375.wNrWVa.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2018-07-04-20-35-25.bpo-34008.bqecIb.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2024-06-03-22-06-26.gh-issue-119574.Ik9kOO.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2024-06-05-12-36-18.gh-issue-120012.f14DbQ.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2024-07-14-11-48-10.gh-issue-121749.nxHoTk.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2024-07-14-12-25-53.gh-issue-117765.YFMOUv.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2024-07-19-12-22-48.gh-issue-121277.wF_zKd.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2024-08-01-17-18-21.gh-issue-70870.fZnBM9.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2024-09-11-16-52-08.gh-issue-123976.jhOfNR.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2024-09-19-19-33-25.gh-issue-116622.M65UZ6.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2024-09-24-11-52-36.gh-issue-124457.yrCjSV.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2024-09-27-16-47-48.gh-issue-124720.nVSTVb.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2024-10-07-00-31-17.gh-issue-125018.yKnymn.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2024-10-10-02-56-24.gh-issue-124872.0mDDOq.rst delete mode 100644 Misc/NEWS.d/next/IDLE/2024-06-05-14-54-24.gh-issue-120104.j_thj4.rst delete mode 100644 Misc/NEWS.d/next/IDLE/2024-06-16-21-42-45.gh-issue-120083.nczuyv.rst delete mode 100644 Misc/NEWS.d/next/IDLE/2024-07-16-16-57-03.gh-issue-78889.U7ghFD.rst delete mode 100644 Misc/NEWS.d/next/IDLE/2024-07-30-18-02-55.gh-issue-122482.TerE0g.rst delete mode 100644 Misc/NEWS.d/next/IDLE/2024-09-21-23-12-18.gh-issue-112938.OeiDru.rst delete mode 100644 Misc/NEWS.d/next/IDLE/2024-10-04-15-34-34.gh-issue-122392.V8K3w2.rst delete mode 100644 Misc/NEWS.d/next/Library/2018-12-04-07-36-27.bpo-14074.fMLKCu.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-08-27-01-16-50.gh-issue-67693.4NIAiy.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-03-28-21-00-54.bpo-15987.aBL8XS.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-12-22-18-08-12.bpo-41843.q9Nh2r.rst delete mode 100644 Misc/NEWS.d/next/Library/2021-08-24-19-37-46.bpo-44864.KzxaDh.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-03-10-16-47-57.bpo-45767.ywmyo1.rst delete mode 100644 Misc/NEWS.d/next/Library/2023-03-30-18-19-53.gh-issue-103134.bHrn91.rst delete mode 100644 Misc/NEWS.d/next/Library/2023-04-10-00-04-37.gh-issue-87106.UyBnPQ.rst delete mode 100644 Misc/NEWS.d/next/Library/2023-04-24-05-34-23.gh-issue-103194.GwBwWL.rst delete mode 100644 Misc/NEWS.d/next/Library/2023-04-26-22-24-17.gh-issue-92081.V8xMot.rst delete mode 100644 Misc/NEWS.d/next/Library/2023-04-28-09-54-15.gh-issue-103956.EyLDPS.rst delete mode 100644 Misc/NEWS.d/next/Library/2023-06-16-14-52-00.gh-issue-102450.MfeR6A.rst delete mode 100644 Misc/NEWS.d/next/Library/2023-06-17-09-07-06.gh-issue-105623.5G06od.rst delete mode 100644 Misc/NEWS.d/next/Library/2023-09-19-17-56-24.gh-issue-109109.WJvvX2.rst delete mode 100644 Misc/NEWS.d/next/Library/2023-12-12-15-19-58.gh-issue-108172.KyDPuG.rst delete mode 100644 Misc/NEWS.d/next/Library/2023-12-14-13-43-27.gh-issue-113008.jWYn8T.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-01-12-08-51-03.gh-issue-113978.MqTgB0.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-01-14-11-43-31.gh-issue-113878.dmEIN3.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-01-18-21-44-23.gh-issue-114264.DBKn29.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-02-22-10-12-59.gh-issue-115808.F2g2Ku.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-02-27-10-22-15.gh-issue-115937.0cVNur.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-03-19-21-41-31.gh-issue-106531.Mgd--6.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-04-19-05-58-50.gh-issue-117766.J3xepp.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-04-19-14-59-53.gh-issue-118033.amS4Gw.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-04-24-16-23-04.gh-issue-110190.TGd5qx.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-04-28-19-51-00.gh-issue-118263.Gaap3S.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-01-22-24-05.gh-issue-110863.GjYBbq.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-06-17-39-52.gh-issue-118673.sTXBit.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-07-17-38-53.gh-issue-118714.XXKpVZ.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-08-09-21-49.gh-issue-118772.c16E8X.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-08-18-33-07.gh-issue-118507.OCQsAY.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-08-18-59-19.gh-issue-78707._Lz1sw.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-08-19-47-34.gh-issue-101357.e4R_9x.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-08-20-41-48.gh-issue-74033.YebHZj.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-08-21-13-56.gh-issue-118760.mdmH3T.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-08-21-30-33.gh-issue-118760.XvyMHn.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-08-23-16-50.gh-issue-118798.Q_ybqP.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-09-00-52-30.gh-issue-118803.Wv3AvU.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-09-01-05-52.gh-issue-118805.N7dm07.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-09-02-43-37.gh-issue-101588.30bNAr.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-09-08-46-12.gh-issue-118851.aPAoJw.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-09-11-50-26.gh-issue-118824.-jBJQC.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-09-12-33-25.gh-issue-118827.JrzHz1.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-09-21-36-11.gh-issue-118868.uckxxP.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-10-05-24-32.gh-issue-118895.wUm5r2.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-10-22-36-01.gh-issue-118928.IW7Ukv.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-10-22-59-01.gh-issue-118924.9nyvSH.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-11-20-23-45.gh-issue-82805.F9bz4J.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-12-21-38-42.gh-issue-58933.0kgU2l.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-15-01-36-08.gh-issue-73991.CGknDf.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-16-17-31-46.gh-issue-118643.hAWH4C.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-17-17-32-12.gh-issue-119113.kEv1Ll.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-19-12-25-36.gh-issue-119105.VcR4ig.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-19-13-05-59.gh-issue-119121.P1gnh1.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-19-18-49-04.gh-issue-119174.5GTv7d.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-20-13-48-37.gh-issue-119189.dhJVs5.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-20-20-30-57.gh-issue-111201.DAA5lC.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-21-19-10-30.gh-issue-115225.eRmfJH.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-21-20-13-23.gh-issue-118911.iG8nMq.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-21-23-39-22.gh-issue-118830.YTqvEo.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-22-21-20-43.gh-issue-118894.xHdxR_.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-23-11-52-36.gh-issue-117398.2FG1Mk.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-23-15-48-17.gh-issue-119461.82KqUW.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-23-22-29-59.gh-issue-119443.KAGz6S.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-24-04-05-37.gh-issue-119105.aDSRFn.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-24-11-47-08.gh-issue-69214.Grl6zF.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-24-14-32-24.gh-issue-119506.-nMNqq.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-24-21-54-55.gh-issue-113892.JKDFqq.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-25-00-54-26.gh-issue-119127.LpPvag.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-25-07-25-07.gh-issue-117865.1A0Xpi.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-25-10-40-38.gh-issue-118908.XcZiq4.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-25-20-15-26.gh-issue-119555.mvHbEL.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-25-20-20-42.gh-issue-119562.DyplWc.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-26-21-28-11.gh-issue-119588.wlLBK5.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-26-22-22-51.gh-issue-119594.fnQNM8.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-28-00-56-59.gh-issue-89727._bxoL3.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-28-12-15-03.gh-issue-119118.FMKz1F.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-29-12-42-40.gh-issue-93963.cb1oJS.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-29-20-42-17.gh-issue-89727.5lPTTW.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-29-21-50-05.gh-issue-119577.S3BlKJ.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-30-21-37-05.gh-issue-89727.D6S9ig.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-31-12-57-31.gh-issue-119770.NCtels.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-31-13-56-21.gh-issue-119838.H6XHlE.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-05-31-21-17-43.gh-issue-119824.CQlxWV.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-01-16-58-43.gh-issue-117398.kR0RW7.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-02-13-35-11.gh-issue-81936.ETeW9x.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-02-15-09-17.gh-issue-118835.KUAuz6.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-03-11-18-16.gh-issue-117142.kWTXQo.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-04-08-57-02.gh-issue-65454.o9j4wF.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-04-12-23-01.gh-issue-119819.WKKrYh.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-04-14-54-46.gh-issue-120029._1YdTf.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-04-18-53-10.gh-issue-120057.RSD9_Z.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-04-19-03-25.gh-issue-112672.K2XfZH.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-04-19-49-16.gh-issue-120056.5aqozw.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-05-08-02-46.gh-issue-120108.4U9BL8.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-05-11-03-10.gh-issue-120029.QBsw47.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-05-11-39-21.gh-issue-119933.ooJXQV.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-05-16-30-28.gh-issue-120121.9dz8i7.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-06-12-07-57.gh-issue-119698.rRrprk.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-06-17-24-43.gh-issue-120161.DahNXV.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-07-02-00-31.gh-issue-120157.HnWcF9.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-07-10-10-32.gh-issue-117983.NeMR9n.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-07-11-23-31.gh-issue-71587.IjFajE.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-07-13-21-11.gh-issue-120211.Rws_gf.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-08-03-29-01.gh-issue-120254.h682ke.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-08-09-45-31.gh-issue-120244.8o9Dzr.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-08-14-36-40.gh-issue-120268.MNpd1q.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-08-15-15-29.gh-issue-114053.WQLAFG.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-08-15-46-35.gh-issue-114053.Ub2XgJ.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-08-17-41-11.gh-issue-82017.WpSTGi.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-09-19-53-11.gh-issue-120289.s4HXR0.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-10-14-00-40.gh-issue-119600.jJMf4C.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-11-07-17-25.gh-issue-119180.iH-2zy.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-11-16-34-41.gh-issue-120343.hdiXeU.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-12-10-00-31.gh-issue-90425.5CfkKG.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-12-11-54-05.gh-issue-120381.O-BNLs.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-12-15-07-58.gh-issue-120388.VuTQMT.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-14-20-05-25.gh-issue-120495.OxgZKB.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-15-12-04-46.gh-issue-120541.d3cc5y.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-15-23-38-36.gh-issue-120284.HwsAtY.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-16-21-33-56.gh-issue-120606.kugbwR.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-17-20-04-13.gh-issue-120633.kZC5wt.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-18-14-45-38.gh-issue-118710.5GZZPX.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-18-19-18-10.gh-issue-120683.xmRez7.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-19-13-20-01.gh-issue-111259.Wki5PV.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-19-15-06-58.gh-issue-120732.OvYV9b.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-19-15-43-04.gh-issue-120743.CMMl2P.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-19-19-53-42.gh-issue-41431.gnkUc5.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-19-23-08-25.gh-issue-120780.0Omopb.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-20-01-31-24.gh-issue-120769.PfiMrc.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-21-06-37-46.gh-issue-120713.WBbQx4.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-21-12-00-16.gh-issue-120782.LOE8tj.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-21-14-32-56.gh-issue-120811.eBmVTV.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-22-17-01-56.gh-issue-120678.Ik8dCg.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-22-22-23-56.gh-issue-101830.1BAoxH.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-22-22-52-24.gh-issue-120888.sd8I3N.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-23-07-23-08.gh-issue-61103.ca_U_l.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-23-11-21-27.gh-issue-120910.t0QXdB.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-23-17-50-40.gh-issue-119614.vwPGLB.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-26-03-04-24.gh-issue-121018.clVSc4.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-26-10-13-40.gh-issue-121025.M-XXlV.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-26-17-00-39.gh-issue-117784.inCtAV.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-27-12-27-52.gh-issue-121027.D4K1OX.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-27-13-47-14.gh-issue-121027.jh55EC.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-29-05-08-59.gh-issue-87744.rpF6Jw.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-29-15-21-12.gh-issue-121141.4evD6q.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-29-15-23-26.gh-issue-121151.HeLEvq.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-06-29-19-30-15.gh-issue-121163.SJKDFq.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-01-11-23-18.gh-issue-121210.cD0zfn.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-02-11-34-06.gh-issue-121245.sSkDAr.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-03-07-25-21.gh-issue-121332.Iz6FEq.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-03-10-11-53.gh-issue-121313.D7gARW.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-03-14-23-04.gh-issue-119004.L5MoUu.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-04-17-36-03.gh-issue-59110.IlI9Fz.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-06-12-37-10.gh-issue-121423.vnxrl4.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-06-16-08-39.gh-issue-119169.o0YymL.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-06-23-39-38.gh-issue-121450.vGqb3c.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-08-03-45-34.gh-issue-121474.NsvrUN.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-09-12-23-32.gh-issue-121486.Iultjh.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-10-08-13-34.gh-issue-121249.W9Gd09.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-13-06-23-24.gh-issue-121245.RfOgf4.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-14-06-24-02.gh-issue-57141.C3jhDh.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-14-11-18-28.gh-issue-120930.Kuo4L0.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-15-19-25-25.gh-issue-121798.GmuBDu.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-15-19-34-56.gh-issue-121797.qDqj59.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-16-20-49-07.gh-issue-121804.gYN-In.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-17-09-23-03.gh-issue-121889.6se9jS.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-17-09-44-35.gh-issue-119698.WlygzR.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-17-12-55-22.gh-issue-121268.41RmjR.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-21-02-00-46.gh-issue-73991.pLxdtJ.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-21-10-45-24.gh-issue-122081.dNrYMq.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-21-18-03-30.gh-issue-122088.vi2bP-.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-22-08-14-04.gh-issue-113785.6B_KNB.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-22-08-57-28.gh-issue-120754.Eo5puP.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-23-09-14-44.gh-issue-82951.-F5p5A.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-23-10-59-38.gh-issue-121723.iJEf7e.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-23-12-38-14.gh-issue-122145.sTO8nX.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-23-13-07-12.gh-issue-122129.PwbC8q.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-23-15-11-13.gh-issue-122163.4wRUuM.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-23-15-30-23.gh-issue-122170.Z9gi3Y.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-23-17-13-10.gh-issue-119180.5PZELo.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-23-22-26-00.gh-issue-119180.B2IVT8.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-24-08-48-22.gh-issue-122213.o3pdgA.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-25-15-41-14.gh-issue-105733.o3koJA.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-26-21-21-13.gh-issue-122332.fvw88r.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-27-16-10-41.gh-issue-121650.nf6oc9.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-29-10-24-48.gh-issue-122311.xChV1b.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-29-16-47-08.gh-issue-122400.fM0YSv.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-30-04-27-55.gh-issue-122272.6Wwa1V.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-30-14-46-16.gh-issue-87320.-Yk1wb.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-30-15-57-07.gh-issue-122459.AYIoeN.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-30-21-29-30.gh-issue-122334.LeoE1x.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-31-14-55-41.gh-issue-82378.eZvYmR.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-31-15-08-42.gh-issue-116622.aKxIQA.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-07-31-20-43-21.gh-issue-122478.sCU2Le.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-03-06-51-08.gh-issue-122637.gpas8J.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-04-14-07-18.gh-issue-118814.uiyks1.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-06-07-24-00.gh-issue-118974.qamsCQ.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-06-10-36-55.gh-issue-118761.q_x_1A.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-06-18-07-19.gh-issue-122744.kCzNDI.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-07-11-57-41.gh-issue-122311.LDExnJ.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-07-14-12-19.gh-issue-105376.QbGPdE.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-07-17-41-16.gh-issue-116263.EcXir0.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-10-10-21-44.gh-issue-122858.ZC1rJD.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-10-14-16-59.gh-issue-122873.XlHaUn.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-11-14-08-04.gh-issue-122905.7tDsxA.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-11-14-23-07.gh-issue-122903.xktZta.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-14-10-41-11.gh-issue-122981.BHV0Z9.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-15-09-45-34.gh-issue-121735._1q0qf.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-16-16-53-52.gh-issue-123049.izx_fH.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-16-19-13-21.gh-issue-123067.Nx9O4R.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-17-08-17-20.gh-issue-123085.7Io2yH.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-18-08-25-32.gh-issue-123084.rf8izX.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-19-17-37-18.gh-issue-122909.kP12SK.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-20-14-22-49.gh-issue-123165.vOZZOA.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-20-18-02-27.gh-issue-85110.8_iDQy.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-22-09-37-48.gh-issue-123213.owmXnP.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-22-11-25-19.gh-issue-122546.BSmeE7.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-22-20-10-13.gh-issue-123243.Kifj1L.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-23-15-49-10.gh-issue-116810.QLBUU8.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-23-22-01-30.gh-issue-76960.vsANPu.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-24-00-03-01.gh-issue-123240.uFPG3l.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-24-06-05-41.gh-issue-123228.jR_5O5.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-25-16-59-20.gh-issue-73991.1w8u3K.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-26-13-45-20.gh-issue-123270.gXHvNJ.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-26-18-48-13.gh-issue-119518.QFYH9q.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-26-19-36-00.gh-issue-123340.mQKI1H.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-27-10-30-37.gh-issue-123341.5e-fjt.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-27-12-11-00.gh-issue-123363.gKuJp6.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-27-12-38-42.gh-issue-123089.vA7iFR.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-28-13-03-36.gh-issue-123409.lW0YF-.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-28-20-08-19.gh-issue-123448.tItJlp.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-29-09-27-12.gh-issue-123446._I_mMr.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-29-14-51-36.gh-issue-123430.M7wXl9.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-30-09-01-35.gh-issue-123504.lJ9_BB.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-08-31-12-34-44.gh-issue-123374.3kE7rb.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-02-20-34-04.gh-issue-123339.czgcSu.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-04-18-23-43.gh-issue-123657.Oks4So.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-06-00-00-43.gh-issue-122765.tx4hsr.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-06-01-35-11.gh-issue-123756.Ozbhke.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-06-10-17-54.gh-issue-84808.ION67Z.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-10-11-26-14.gh-issue-123892.2gzIrz.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-11-13-33-19.gh-issue-123935.fRZ_56.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-11-19-05-32.gh-issue-123945.jLwybB.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-11-19-12-23.gh-issue-123968.OwHON_.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-12-10-55-19.gh-issue-124016.ncs0hd.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-13-10-34-19.gh-issue-123934.yMe7mL.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-16-12-31-48.gh-issue-123978.z3smEu.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-17-18-06-42.gh-issue-124171.PHCvRJ.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-18-17-45-52.gh-issue-124212.n6kIby.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-19-00-09-48.gh-issue-84559.IrxvQe.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-19-03-46-59.gh-issue-87041.9Ox7Bv.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-19-10-36-18.gh-issue-81691.Hyhp_U.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-19-11-47-39.gh-issue-124248.g7rufd.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-19-16-00-22.gh-issue-111513.6jHm02.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-19-20-15-00.gh-issue-124217.j0KlQB.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-20-12-23-11.gh-issue-53780.mrV1zi.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-20-18-23-19.gh-issue-100980.8nVAB6.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-21-19-02-37.gh-issue-59317.OAhNZZ.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-21-22-32-21.gh-issue-72795.naLmkX.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-21-23-56-41.gh-issue-63143.YKu-LQ.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-23-17-33-47.gh-issue-104860.O86OSc.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-23-18-26-17.gh-issue-90562.Yj566G.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-24-00-01-24.gh-issue-124400.0XCgfe.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-24-12-34-48.gh-issue-124345.s3vKql.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-24-13-32-16.gh-issue-124176.6hmOPz.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-24-19-32-14.gh-issue-123014.zVcfkZ.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-24-21-15-27.gh-issue-123017.dSAr2f.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-24-22-38-51.gh-issue-123884.iEPTK4.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-25-10-25-57.gh-issue-53834.uyIckw.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-25-12-14-58.gh-issue-124498.Ozxs55.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-25-18-07-51.gh-issue-120378.NlBSz_.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-25-18-08-29.gh-issue-80259.kO5Tw7.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-25-18-34-48.gh-issue-124538.nXZk4R.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-25-22-06-52.gh-issue-124552.1nQKNM.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-26-00-35-24.gh-issue-116750.X1aMHI.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-26-09-18-09.gh-issue-61181.dwjmch.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-26-13-43-39.gh-issue-124594.peYhsP.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-26-22-14-12.gh-issue-58573.hozbm9.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-27-06-39-32.gh-issue-101552.xYkzag.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-27-15-16-04.gh-issue-116850.dBkR0-.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-30-19-59-28.gh-issue-66436.4gYN_n.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-30-20-46-32.gh-issue-124787.3FnJnP.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-01-02-31-13.gh-issue-124693.qzbXKB.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-01-12-43-42.gh-issue-124835.SVyp3K.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-01-13-11-53.gh-issue-85935.CTwJUy.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-01-13-46-58.gh-issue-124390.dK1Zcm.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-01-17-12-20.gh-issue-124858.Zy0tvT.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-01-23-29-09.gh-issue-91818.Kz8cPI.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-02-15-05-45.gh-issue-124653.tqsTu9.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-02-16-35-07.gh-issue-65865.S2D4wq.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-02-21-11-18.gh-issue-124917.Lnwh5b.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-02-22-53-48.gh-issue-90102.4qX52R.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-03-05-00-25.gh-issue-117151.Prdw_W.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-03-17-13-22.gh-issue-124944.YyLAzf.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-03-19-16-38.gh-issue-123961.ik1Dgs.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-03-20-45-57.gh-issue-53203.3Sk4Ia.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-04-08-46-00.gh-issue-124958.rea9-x.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-04-12-43-03.gh-issue-69998.DVqOXX.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-05-15-49-53.gh-issue-124960.Bol9hT.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-08-12-09-09.gh-issue-124969._VBQLq.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-08-13-28-22.gh-issue-125096.Vz0W5g.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-08-21-17-16.gh-issue-125069.0RP0Mx.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-09-07-09-00.gh-issue-125118.J9rQ1S.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-09-21-42-43.gh-issue-61011.pQXZb1.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-10-18-33-31.gh-issue-125235.0kOB5I.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-10-19-57-35.gh-issue-125254.RtZxXS.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-10-20-39-57.gh-issue-125243.eUbbtu.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-11-04-04-38.gh-issue-125260.PeZ0Mb.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-11-16-19-46.gh-issue-89967.vhWUOR.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-11-18-03-05.gh-issue-125206.pWRRK6.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-13-20-21-35.gh-issue-53203.Rz1c8A.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-14-02-27-03.gh-issue-100141.NuAcwa.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-10-14-04-44-12.gh-issue-125422.MlVuC6.rst delete mode 100644 Misc/NEWS.d/next/Security/2024-05-01-20-57-09.gh-issue-118486.K44KJG.rst delete mode 100644 Misc/NEWS.d/next/Security/2024-05-08-21-59-38.gh-issue-118773.7dFRJY.rst delete mode 100644 Misc/NEWS.d/next/Security/2024-06-25-04-42-43.gh-issue-112301.god4IC.rst delete mode 100644 Misc/NEWS.d/next/Security/2024-07-02-13-39-20.gh-issue-121285.hrl-yI.rst delete mode 100644 Misc/NEWS.d/next/Security/2024-07-08-23-39-04.gh-issue-112301.TD8G01.rst delete mode 100644 Misc/NEWS.d/next/Security/2024-07-18-13-17-47.gh-issue-121957.QemKLU.rst delete mode 100644 Misc/NEWS.d/next/Security/2024-07-22-13-11-28.gh-issue-122133.0mPeta.rst delete mode 100644 Misc/NEWS.d/next/Security/2024-07-24-05-18-25.gh-issue-112301.lfINgZ.rst delete mode 100644 Misc/NEWS.d/next/Security/2024-08-06-00-06-23.gh-issue-112301.4k4lw6.rst delete mode 100644 Misc/NEWS.d/next/Security/2024-08-07-10-42-13.gh-issue-122792.oiTMo9.rst delete mode 100644 Misc/NEWS.d/next/Security/2024-08-14-19-43-57.gh-issue-112301.IQUcOy.rst delete mode 100644 Misc/NEWS.d/next/Security/2024-09-04-12-41-35.gh-issue-123678.N41y9n.rst delete mode 100644 Misc/NEWS.d/next/Security/2024-10-09-20-08-13.gh-issue-125140.YgNWRB.rst delete mode 100644 Misc/NEWS.d/next/Tests/2023-08-03-17-26-55.gh-issue-107562.ZnbscS.rst delete mode 100644 Misc/NEWS.d/next/Tests/2024-05-04-22-56-41.gh-issue-101525.LHK166.rst delete mode 100644 Misc/NEWS.d/next/Tests/2024-05-18-10-59-27.gh-issue-119050.g4qiH7.rst delete mode 100644 Misc/NEWS.d/next/Tests/2024-05-20-18-06-31.gh-issue-119273.hf-yhX.rst delete mode 100644 Misc/NEWS.d/next/Tests/2024-05-29-15-28-08.gh-issue-119727.dVkaZM.rst delete mode 100644 Misc/NEWS.d/next/Tests/2024-06-20-12-51-26.gh-issue-120801.lMVXC9.rst delete mode 100644 Misc/NEWS.d/next/Tests/2024-07-01-09-04-32.gh-issue-121188.XbuTVa.rst delete mode 100644 Misc/NEWS.d/next/Tests/2024-07-01-16-15-06.gh-issue-121200.4Pc-gc.rst delete mode 100644 Misc/NEWS.d/next/Tests/2024-07-03-14-41-00.gh-issue-121160.LEtiTd.rst delete mode 100644 Misc/NEWS.d/next/Tests/2024-07-04-15-10-29.gh-issue-121084.qxcd5d.rst delete mode 100644 Misc/NEWS.d/next/Tests/2024-07-13-11-04-44.gh-issue-99242.aGxnwz.rst delete mode 100644 Misc/NEWS.d/next/Tests/2024-07-13-11-48-20.gh-issue-59022.fYNbQ8.rst delete mode 100644 Misc/NEWS.d/next/Tests/2024-07-13-21-55-58.gh-issue-112301.YJS1dl.rst delete mode 100644 Misc/NEWS.d/next/Tests/2024-07-17-08-25-06.gh-issue-121921.HW8CIS.rst delete mode 100644 Misc/NEWS.d/next/Tests/2024-09-17-22-21-58.gh-issue-124190.3fWhiX.rst delete mode 100644 Misc/NEWS.d/next/Tests/2024-09-18-18-39-21.gh-issue-124213.AQq_xg.rst delete mode 100644 Misc/NEWS.d/next/Tests/2024-09-25-12-39-34.gh-issue-124378.Ywwgia.rst delete mode 100644 Misc/NEWS.d/next/Tests/2024-10-07-14-13-38.gh-issue-125041.PKLWDf.rst delete mode 100644 Misc/NEWS.d/next/Tools-Demos/2024-09-04-10-07-51.gh-issue-123418.1eIFZb.rst delete mode 100644 Misc/NEWS.d/next/Windows/2022-04-20-18-32-30.gh-issue-79846.Vggv3f.rst delete mode 100644 Misc/NEWS.d/next/Windows/2024-04-24-05-16-32.gh-issue-118209.Ryyzlz.rst delete mode 100644 Misc/NEWS.d/next/Windows/2024-04-24-22-50-33.gh-issue-117505.gcTb_p.rst delete mode 100644 Misc/NEWS.d/next/Windows/2024-05-22-19-43-29.gh-issue-119070._enton.rst delete mode 100644 Misc/NEWS.d/next/Windows/2024-05-25-18-43-10.gh-issue-111201.SLPJIx.rst delete mode 100644 Misc/NEWS.d/next/Windows/2024-05-29-11-06-12.gh-issue-119690.8q6e1p.rst delete mode 100644 Misc/NEWS.d/next/Windows/2024-05-30-17-39-25.gh-issue-119679.mZC87w.rst delete mode 100644 Misc/NEWS.d/next/Windows/2024-07-19-21-50-54.gh-issue-100256.GDrKba.rst delete mode 100644 Misc/NEWS.d/next/Windows/2024-08-01-10-55-15.gh-issue-122573.4-UCFY.rst delete mode 100644 Misc/NEWS.d/next/Windows/2024-08-29-16-13-45.gh-issue-123476.m2DFS4.rst delete mode 100644 Misc/NEWS.d/next/Windows/2024-09-04-09-59-18.gh-issue-123418.QaMC12.rst delete mode 100644 Misc/NEWS.d/next/Windows/2024-09-10-19-23-00.gh-issue-123915.yZMEDO.rst delete mode 100644 Misc/NEWS.d/next/Windows/2024-09-20-11-18-50.gh-issue-124254.iPin-L.rst delete mode 100644 Misc/NEWS.d/next/Windows/2024-09-24-19-04-56.gh-issue-124448.srVT3d.rst delete mode 100644 Misc/NEWS.d/next/Windows/2024-09-27-13-40-25.gh-issue-124609.WaKk8G.rst delete mode 100644 Misc/NEWS.d/next/Windows/2024-09-27-15-07-30.gh-issue-124487.7LrwHC.rst delete mode 100644 Misc/NEWS.d/next/macOS/2024-09-04-11-55-29.gh-issue-123418.8P4bmN.rst delete mode 100644 Misc/NEWS.d/next/macOS/2024-09-07-12-14-54.gh-issue-123797.yFDeug.rst delete mode 100644 Misc/NEWS.d/next/macOS/2024-09-24-10-48-46.gh-issue-124448.bFMrS6.rst diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst index 8e0cf7bb0fc088..ffc5b4223ba589 100644 --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -1195,7 +1195,7 @@ code, or when embedding the Python interpreter: created by Python. Refer to :ref:`cautions-regarding-runtime-finalization` for more details. - .. versionchanged:: next + .. versionchanged:: 3.14 Hangs the current thread, rather than terminating it, if called while the interpreter is finalizing. @@ -1257,7 +1257,7 @@ with sub-interpreters: created by Python. Refer to :ref:`cautions-regarding-runtime-finalization` for more details. - .. versionchanged:: next + .. versionchanged:: 3.14 Hangs the current thread, rather than terminating it, if called while the interpreter is finalizing. @@ -1547,7 +1547,7 @@ All of the following functions must be called after :c:func:`Py_Initialize`. :c:func:`Py_END_ALLOW_THREADS`, and :c:func:`PyGILState_Ensure`, and terminate the current thread if called while the interpreter is finalizing. - .. versionchanged:: next + .. versionchanged:: 3.14 Hangs the current thread, rather than terminating it, if called while the interpreter is finalizing. diff --git a/Doc/c-api/long.rst b/Doc/c-api/long.rst index 02ef8aa7846468..6d3463fe25a614 100644 --- a/Doc/c-api/long.rst +++ b/Doc/c-api/long.rst @@ -579,7 +579,7 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. On failure, return -1 with an exception set. This function always succeeds if *obj* is a :c:type:`PyLongObject` or its subtype. - .. versionadded:: next + .. versionadded:: 3.14 .. c:function:: PyObject* PyLong_GetInfo(void) diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst index 4daf9e9fdbf2f1..59bd7661965d93 100644 --- a/Doc/c-api/unicode.rst +++ b/Doc/c-api/unicode.rst @@ -1575,7 +1575,7 @@ PyUnicodeWriter The :c:type:`PyUnicodeWriter` API can be used to create a Python :class:`str` object. -.. versionadded:: next +.. versionadded:: 3.14 .. c:type:: PyUnicodeWriter diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst index 3d2df035a85c21..22d8c87cb58e78 100644 --- a/Doc/library/ast.rst +++ b/Doc/library/ast.rst @@ -2491,7 +2491,7 @@ effects on the compilation of a program: differ in whitespace or similar details. Attributes include line numbers and column offsets. - .. versionadded:: next + .. versionadded:: 3.14 .. _ast-cli: diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index d76b8d4809c078..d49959b4eb7da2 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -2303,7 +2303,7 @@ These are the fundamental ctypes data types: Represents the C :c:expr:`double complex` datatype, if available. The constructor accepts an optional :class:`complex` initializer. - .. versionadded:: next + .. versionadded:: 3.14 .. class:: c_float_complex diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 1d084a8bf38d98..a2e44e09ffc925 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -959,7 +959,7 @@ iterations of the loop. list of constants supported by this instruction. Used by the :keyword:`assert` statement to load :exc:`AssertionError`. - .. versionadded:: next + .. versionadded:: 3.14 .. opcode:: LOAD_BUILD_CLASS @@ -1827,7 +1827,7 @@ iterations of the loop. If ``type(STACK[-1]).__xxx__`` is not a method, leave ``STACK[-1].__xxx__; NULL`` on the stack. - .. versionadded:: next + .. versionadded:: 3.14 **Pseudo-instructions** diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index 30d0d385d0539c..4380122eb1be7d 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -1563,7 +1563,7 @@ Copying, moving and deleting This argument has no effect when copying files on Windows (where metadata is always preserved). - .. versionadded:: next + .. versionadded:: 3.14 .. method:: Path.copy_into(target_dir, *, follow_symlinks=True, \ @@ -1574,7 +1574,7 @@ Copying, moving and deleting :meth:`Path.copy`. Returns a new :class:`!Path` instance pointing to the copy. - .. versionadded:: next + .. versionadded:: 3.14 .. method:: Path.rename(target) diff --git a/Doc/library/symtable.rst b/Doc/library/symtable.rst index 56cd6b8afaa73e..54e19af4bd69a6 100644 --- a/Doc/library/symtable.rst +++ b/Doc/library/symtable.rst @@ -256,7 +256,7 @@ Examining Symbol Tables Return ``True`` if the symbol is a type parameter. - .. versionadded:: next + .. versionadded:: 3.14 .. method:: is_global() @@ -303,7 +303,7 @@ Examining Symbol Tables be free from the perspective of ``C.method``, thereby allowing the latter to return *1* at runtime and not *2*. - .. versionadded:: next + .. versionadded:: 3.14 .. method:: is_assigned() @@ -313,13 +313,13 @@ Examining Symbol Tables Return ``True`` if the symbol is a comprehension iteration variable. - .. versionadded:: next + .. versionadded:: 3.14 .. method:: is_comp_cell() Return ``True`` if the symbol is a cell in an inlined comprehension. - .. versionadded:: next + .. versionadded:: 3.14 .. method:: is_namespace() diff --git a/Include/patchlevel.h b/Include/patchlevel.h index d63af11dbd220a..c7a9496a35ed92 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -20,10 +20,10 @@ #define PY_MINOR_VERSION 14 #define PY_MICRO_VERSION 0 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA -#define PY_RELEASE_SERIAL 0 +#define PY_RELEASE_SERIAL 1 /* Version as a string */ -#define PY_VERSION "3.14.0a0" +#define PY_VERSION "3.14.0a1" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index ae56c136608472..165d3853f95e29 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Wed May 8 11:11:17 2024 +# Autogenerated by Sphinx on Tue Oct 15 22:34:02 2024 # as part of the release process. topics = {'assert': 'The "assert" statement\n' '**********************\n' @@ -308,10 +308,10 @@ 'target.\n' 'The target is only evaluated once.\n' '\n' - 'An augmented assignment expression like "x += 1" can be ' - 'rewritten as\n' - '"x = x + 1" to achieve a similar, but not exactly equal ' - 'effect. In the\n' + 'An augmented assignment statement like "x += 1" can be ' + 'rewritten as "x\n' + '= x + 1" to achieve a similar, but not exactly equal effect. ' + 'In the\n' 'augmented version, "x" is only evaluated once. Also, when ' 'possible,\n' 'the actual operation is performed *in-place*, meaning that ' @@ -362,21 +362,21 @@ 'a single\n' 'target is allowed.\n' '\n' - 'For simple names as assignment targets, if in class or module ' - 'scope,\n' - 'the annotations are evaluated and stored in a special class or ' - 'module\n' - 'attribute "__annotations__" that is a dictionary mapping from ' - 'variable\n' - 'names (mangled if private) to evaluated annotations. This ' - 'attribute is\n' - 'writable and is automatically created at the start of class or ' - 'module\n' - 'body execution, if annotations are found statically.\n' - '\n' - 'For expressions as assignment targets, the annotations are ' + 'The assignment target is considered “simple” if it consists of ' + 'a\n' + 'single name that is not enclosed in parentheses. For simple ' + 'assignment\n' + 'targets, if in class or module scope, the annotations are ' + 'gathered in\n' + 'a lazily evaluated annotation scope. The annotations can be ' 'evaluated\n' - 'if in class or module scope, but not stored.\n' + 'using the "__annotations__" attribute of a class or module, or ' + 'using\n' + 'the facilities in the "annotationlib" module.\n' + '\n' + 'If the assignment target is not simple (an attribute, ' + 'subscript node,\n' + 'or parenthesized name), the annotation is never evaluated.\n' '\n' 'If a name is annotated in a function scope, then this name is ' 'local\n' @@ -386,12 +386,13 @@ '\n' 'If the right hand side is present, an annotated assignment ' 'performs\n' - 'the actual assignment before evaluating annotations (where\n' - 'applicable). If the right hand side is not present for an ' - 'expression\n' - 'target, then the interpreter evaluates the target except for ' - 'the last\n' - '"__setitem__()" or "__setattr__()" call.\n' + 'the actual assignment as if there was no annotation present. ' + 'If the\n' + 'right hand side is not present for an expression target, then ' + 'the\n' + 'interpreter evaluates the target except for the last ' + '"__setitem__()"\n' + 'or "__setattr__()" call.\n' '\n' 'See also:\n' '\n' @@ -415,7 +416,13 @@ 'Previously,\n' 'some expressions (like un-parenthesized tuple expressions) ' 'caused a\n' - 'syntax error.\n', + 'syntax error.\n' + '\n' + 'Changed in version 3.14: Annotations are now lazily evaluated ' + 'in a\n' + 'separate annotation scope. If the assignment target is not ' + 'simple,\n' + 'annotations are never evaluated.\n', 'assignment-expressions': 'Assignment expressions\n' '**********************\n' '\n' @@ -593,31 +600,67 @@ 'evaluate it\n' 'raises a "NameError" exception.\n' '\n' - '**Private name mangling:** When an identifier that ' - 'textually occurs in\n' - 'a class definition begins with two or more underscore ' - 'characters and\n' - 'does not end in two or more underscores, it is ' - 'considered a *private\n' - 'name* of that class. Private names are transformed to a ' - 'longer form\n' - 'before code is generated for them. The transformation ' - 'inserts the\n' - 'class name, with leading underscores removed and a ' - 'single underscore\n' - 'inserted, in front of the name. For example, the ' - 'identifier "__spam"\n' - 'occurring in a class named "Ham" will be transformed to ' - '"_Ham__spam".\n' - 'This transformation is independent of the syntactical ' + '\n' + 'Private name mangling\n' + '=====================\n' + '\n' + 'When an identifier that textually occurs in a class ' + 'definition begins\n' + 'with two or more underscore characters and does not end ' + 'in two or more\n' + 'underscores, it is considered a *private name* of that ' + 'class.\n' + '\n' + 'See also: The class specifications.\n' + '\n' + 'More precisely, private names are transformed to a ' + 'longer form before\n' + 'code is generated for them. If the transformed name is ' + 'longer than\n' + '255 characters, implementation-defined truncation may ' + 'happen.\n' + '\n' + 'The transformation is independent of the syntactical ' 'context in which\n' - 'the identifier is used. If the transformed name is ' - 'extremely long\n' - '(longer than 255 characters), implementation defined ' - 'truncation may\n' - 'happen. If the class name consists only of underscores, ' - 'no\n' - 'transformation is done.\n', + 'the identifier is used but only the following private ' + 'identifiers are\n' + 'mangled:\n' + '\n' + '* Any name used as the name of a variable that is ' + 'assigned or read or\n' + ' any name of an attribute being accessed.\n' + '\n' + ' The "__name__" attribute of nested functions, classes, ' + 'and type\n' + ' aliases is however not mangled.\n' + '\n' + '* The name of imported modules, e.g., "__spam" in ' + '"import __spam". If\n' + ' the module is part of a package (i.e., its name ' + 'contains a dot), the\n' + ' name is *not* mangled, e.g., the "__foo" in "import ' + '__foo.bar" is\n' + ' not mangled.\n' + '\n' + '* The name of an imported member, e.g., "__f" in "from ' + 'spam import\n' + ' __f".\n' + '\n' + 'The transformation rule is defined as follows:\n' + '\n' + '* The class name, with leading underscores removed and a ' + 'single\n' + ' leading underscore inserted, is inserted in front of ' + 'the identifier,\n' + ' e.g., the identifier "__spam" occurring in a class ' + 'named "Foo",\n' + ' "_Foo" or "__Foo" is transformed to "_Foo__spam".\n' + '\n' + '* If the class name consists only of underscores, the ' + 'transformation\n' + ' is the identity, e.g., the identifier "__spam" ' + 'occurring in a class\n' + ' named "_" or "__" is left as is.\n', 'atom-literals': 'Literals\n' '********\n' '\n' @@ -630,10 +673,10 @@ '\n' 'Evaluation of a literal yields an object of the given type ' '(string,\n' - 'bytes, integer, floating point number, complex number) with ' + 'bytes, integer, floating-point number, complex number) with ' 'the given\n' 'value. The value may be approximated in the case of ' - 'floating point\n' + 'floating-point\n' 'and imaginary (complex) literals. See section Literals for ' 'details.\n' '\n' @@ -1091,11 +1134,13 @@ 'to the class\n' ' where it is defined. *__slots__* declared in parents ' 'are available\n' - ' in child classes. However, child subclasses will get a ' - '"__dict__"\n' - ' and *__weakref__* unless they also define *__slots__* ' - '(which should\n' - ' only contain names of any *additional* slots).\n' + ' in child classes. However, instances of a child ' + 'subclass will get a\n' + ' "__dict__" and *__weakref__* unless the subclass also ' + 'defines\n' + ' *__slots__* (which should only contain names of any ' + '*additional*\n' + ' slots).\n' '\n' '* If a class defines a slot also defined in a base ' 'class, the instance\n' @@ -1201,10 +1246,10 @@ 'target.\n' 'The target is only evaluated once.\n' '\n' - 'An augmented assignment expression like "x += 1" can be ' - 'rewritten as\n' - '"x = x + 1" to achieve a similar, but not exactly equal effect. ' - 'In the\n' + 'An augmented assignment statement like "x += 1" can be ' + 'rewritten as "x\n' + '= x + 1" to achieve a similar, but not exactly equal effect. In ' + 'the\n' 'augmented version, "x" is only evaluated once. Also, when ' 'possible,\n' 'the actual operation is performed *in-place*, meaning that ' @@ -1277,6 +1322,10 @@ 'The "@" (at) operator is intended to be used for matrix\n' 'multiplication. No builtin Python types implement this operator.\n' '\n' + 'This operation can be customized using the special "__matmul__()" ' + 'and\n' + '"__rmatmul__()" methods.\n' + '\n' 'Added in version 3.5.\n' '\n' 'The "/" (division) and "//" (floor division) operators yield the\n' @@ -1289,17 +1338,19 @@ 'result. Division by zero raises the "ZeroDivisionError" ' 'exception.\n' '\n' - 'This operation can be customized using the special "__truediv__()" ' + 'The division operation can be customized using the special\n' + '"__truediv__()" and "__rtruediv__()" methods. The floor division\n' + 'operation can be customized using the special "__floordiv__()" ' 'and\n' - '"__floordiv__()" methods.\n' + '"__rfloordiv__()" methods.\n' '\n' 'The "%" (modulo) operator yields the remainder from the division ' 'of\n' 'the first argument by the second. The numeric arguments are ' 'first\n' 'converted to a common type. A zero right argument raises the\n' - '"ZeroDivisionError" exception. The arguments may be floating ' - 'point\n' + '"ZeroDivisionError" exception. The arguments may be ' + 'floating-point\n' 'numbers, e.g., "3.14%0.7" equals "0.34" (since "3.14" equals ' '"4*0.7 +\n' '0.34".) The modulo operator always yields a result with the same ' @@ -1326,13 +1377,13 @@ '\n' 'The *modulo* operation can be customized using the special ' '"__mod__()"\n' - 'method.\n' + 'and "__rmod__()" methods.\n' '\n' 'The floor division operator, the modulo operator, and the ' '"divmod()"\n' 'function are not defined for complex numbers. Instead, convert to ' 'a\n' - 'floating point number using the "abs()" function if appropriate.\n' + 'floating-point number using the "abs()" function if appropriate.\n' '\n' 'The "+" (addition) operator yields the sum of its arguments. The\n' 'arguments must either both be numbers or both be sequences of the ' @@ -1351,7 +1402,8 @@ 'The numeric arguments are first converted to a common type.\n' '\n' 'This operation can be customized using the special "__sub__()" ' - 'method.\n', + 'and\n' + '"__rsub__()" methods.\n', 'bitwise': 'Binary bitwise operations\n' '*************************\n' '\n' @@ -2426,18 +2478,16 @@ 'An\n' 'expression-less "except" clause, if present, must be last; it ' 'matches\n' - 'any exception. For an "except" clause with an expression, that\n' - 'expression is evaluated, and the clause matches the exception if ' - 'the\n' - 'resulting object is “compatible” with the exception. An object ' - 'is\n' - 'compatible with an exception if the object is the class or a ' - '*non-\n' - 'virtual base class* of the exception object, or a tuple ' - 'containing an\n' - 'item that is the class or a non-virtual base class of the ' - 'exception\n' - 'object.\n' + 'any exception.\n' + '\n' + 'For an "except" clause with an expression, the expression must\n' + 'evaluate to an exception type or a tuple of exception types. ' + 'The\n' + 'raised exception matches an "except" clause whose expression ' + 'evaluates\n' + 'to the class or a *non-virtual base class* of the exception ' + 'object, or\n' + 'to a tuple that contains such a class.\n' '\n' 'If no "except" clause matches the exception, the search for an\n' 'exception handler continues in the surrounding code and on the\n' @@ -2586,13 +2636,16 @@ ' ...\n' " ExceptionGroup('', (BlockingIOError()))\n" '\n' - 'An "except*" clause must have a matching type, and this type ' - 'cannot be\n' - 'a subclass of "BaseExceptionGroup". It is not possible to mix ' - '"except"\n' - 'and "except*" in the same "try". "break", "continue" and ' - '"return"\n' - 'cannot appear in an "except*" clause.\n' + 'An "except*" clause must have a matching expression; it cannot ' + 'be\n' + '"except*:". Furthermore, this expression cannot contain ' + 'exception\n' + 'group types, because that would have ambiguous semantics.\n' + '\n' + 'It is not possible to mix "except" and "except*" in the same ' + '"try".\n' + '"break", "continue" and "return" cannot appear in an "except*" ' + 'clause.\n' '\n' '\n' '"else" clause\n' @@ -3090,7 +3143,7 @@ ' | "None"\n' ' | "True"\n' ' | "False"\n' - ' | signed_number: NUMBER | "-" NUMBER\n' + ' signed_number ::= ["-"] NUMBER\n' '\n' 'The rule "strings" and the token "NUMBER" are defined in the ' 'standard\n' @@ -3560,10 +3613,12 @@ ' parameter_list_no_posonly ::= defparameter ("," ' 'defparameter)* ["," [parameter_list_starargs]]\n' ' | parameter_list_starargs\n' - ' parameter_list_starargs ::= "*" [parameter] ("," ' + ' parameter_list_starargs ::= "*" [star_parameter] ("," ' 'defparameter)* ["," ["**" parameter [","]]]\n' ' | "**" parameter [","]\n' ' parameter ::= identifier [":" expression]\n' + ' star_parameter ::= identifier [":" ["*"] ' + 'expression]\n' ' defparameter ::= parameter ["=" expression]\n' ' funcname ::= identifier\n' '\n' @@ -3691,27 +3746,22 @@ 'expression"”\n' 'following the parameter name. Any parameter may have an ' 'annotation,\n' - 'even those of the form "*identifier" or "**identifier". ' - 'Functions may\n' - 'have “return” annotation of the form “"-> expression"” after ' - 'the\n' - 'parameter list. These annotations can be any valid Python ' - 'expression.\n' - 'The presence of annotations does not change the semantics of a\n' - 'function. The annotation values are available as values of a\n' - 'dictionary keyed by the parameters’ names in the ' - '"__annotations__"\n' - 'attribute of the function object. If the "annotations" import ' - 'from\n' - '"__future__" is used, annotations are preserved as strings at ' - 'runtime\n' - 'which enables postponed evaluation. Otherwise, they are ' - 'evaluated\n' - 'when the function definition is executed. In this case ' - 'annotations\n' - 'may be evaluated in a different order than they appear in the ' - 'source\n' - 'code.\n' + 'even those of the form "*identifier" or "**identifier". (As a ' + 'special\n' + 'case, parameters of the form "*identifier" may have an ' + 'annotation “":\n' + '*expression"”.) Functions may have “return” annotation of the ' + 'form\n' + '“"-> expression"” after the parameter list. These annotations ' + 'can be\n' + 'any valid Python expression. The presence of annotations does ' + 'not\n' + 'change the semantics of a function. See Annotations for more\n' + 'information on annotations.\n' + '\n' + 'Changed in version 3.11: Parameters of the form “"*identifier"” ' + 'may\n' + 'have an annotation “": *expression"”. See **PEP 646**.\n' '\n' 'It is also possible to create anonymous functions (functions not ' 'bound\n' @@ -4301,6 +4351,56 @@ 'not\n' 'actually bound at runtime.\n' '\n' + '\n' + 'Annotations\n' + '===========\n' + '\n' + 'Changed in version 3.14: Annotations are now lazily evaluated ' + 'by\n' + 'default.\n' + '\n' + 'Variables and function parameters may carry *annotations*, ' + 'created by\n' + 'adding a colon after the name, followed by an expression:\n' + '\n' + ' x: annotation = 1\n' + ' def f(param: annotation): ...\n' + '\n' + 'Functions may also carry a return annotation following an ' + 'arrow:\n' + '\n' + ' def f() -> annotation: ...\n' + '\n' + 'Annotations are conventionally used for *type hints*, but this ' + 'is not\n' + 'enforced by the language, and in general annotations may ' + 'contain\n' + 'arbitrary expressions. The presence of annotations does not ' + 'change the\n' + 'runtime semantics of the code, except if some mechanism is used ' + 'that\n' + 'introspects and uses the annotations (such as "dataclasses" or\n' + '"functools.singledispatch()").\n' + '\n' + 'By default, annotations are lazily evaluated in a annotation ' + 'scope.\n' + 'This means that they are not evaluated when the code containing ' + 'the\n' + 'annotation is evaluated. Instead, the interpreter saves ' + 'information\n' + 'that can be used to evaluate the annotation later if requested. ' + 'The\n' + '"annotationlib" module provides tools for evaluating ' + 'annotations.\n' + '\n' + 'If the future statement "from __future__ import annotations" is\n' + 'present, all annotations are instead stored as strings:\n' + '\n' + ' >>> from __future__ import annotations\n' + ' >>> def f(param: annotation): ...\n' + ' >>> f.__annotations__\n' + " {'param': 'annotation'}\n" + '\n' '-[ Footnotes ]-\n' '\n' '[1] The exception is propagated to the invocation stack unless ' @@ -4463,7 +4563,7 @@ 'converted to\n' ' complex;\n' '\n' - '* otherwise, if either argument is a floating point number, ' + '* otherwise, if either argument is a floating-point number, ' 'the other\n' ' is converted to floating point;\n' '\n' @@ -4574,6 +4674,10 @@ ' It is not guaranteed that "__del__()" methods are called ' 'for\n' ' objects that still exist when the interpreter exits.\n' + ' "weakref.finalize" provides a straightforward way to ' + 'register a\n' + ' cleanup function to be called when an object is garbage ' + 'collected.\n' '\n' ' Note:\n' '\n' @@ -5072,6 +5176,12 @@ ' 0\n' ' (Pdb)\n' '\n' + 'Changed in version 3.13: The implementation of **PEP 667** means ' + 'that\n' + 'name assignments made via "pdb" will immediately affect the ' + 'active\n' + 'scope, even when running inside an *optimized scope*.\n' + '\n' 'The module defines the following functions; each enters the ' 'debugger\n' 'in a slightly different way:\n' @@ -5113,7 +5223,7 @@ 'appears\n' ' as soon as the function is entered.\n' '\n' - 'pdb.set_trace(*, header=None)\n' + 'pdb.set_trace(*, header=None, commands=None)\n' '\n' ' Enter the debugger at the calling stack frame. This is ' 'useful to\n' @@ -5122,7 +5232,9 @@ ' code is not otherwise being debugged (e.g. when an assertion\n' ' fails). If given, *header* is printed to the console just ' 'before\n' - ' debugging begins.\n' + ' debugging begins. The *commands* argument, if given, is a ' + 'list of\n' + ' commands to execute when the debugger starts.\n' '\n' ' Changed in version 3.7: The keyword-only argument *header*.\n' '\n' @@ -5131,6 +5243,8 @@ ' immediately, rather than on the next line of code to be ' 'executed.\n' '\n' + ' Added in version 3.14: The *commands* argument.\n' + '\n' 'pdb.post_mortem(traceback=None)\n' '\n' ' Enter post-mortem debugging of the given *traceback* object. ' @@ -5153,7 +5267,7 @@ 'to access further features, you have to do this yourself:\n' '\n' "class pdb.Pdb(completekey='tab', stdin=None, stdout=None, " - 'skip=None, nosigint=False, readrc=True)\n' + 'skip=None, nosigint=False, readrc=True, mode=None)\n' '\n' ' "Pdb" is the debugger class.\n' '\n' @@ -5182,6 +5296,15 @@ 'Pdb\n' ' will load .pdbrc files from the filesystem.\n' '\n' + ' The *mode* argument specifies how the debugger was invoked. ' + 'It\n' + ' impacts the workings of some debugger commands. Valid values ' + 'are\n' + ' "\'inline\'" (used by the breakpoint() builtin), "\'cli\'" ' + '(used by the\n' + ' command line invocation) or "None" (for backwards compatible\n' + ' behaviour, as before the *mode* argument was added).\n' + '\n' ' Example call to enable tracing with *skip*:\n' '\n' " import pdb; pdb.Pdb(skip=['django.*']).set_trace()\n" @@ -5196,6 +5319,8 @@ '\n' ' Changed in version 3.6: The *readrc* argument.\n' '\n' + ' Added in version 3.14: Added the *mode* argument.\n' + '\n' ' run(statement, globals=None, locals=None)\n' ' runeval(expression, globals=None, locals=None)\n' ' runcall(function, *args, **kwds)\n' @@ -5283,7 +5408,8 @@ '* "$_exception": the exception if the frame is raising an ' 'exception\n' '\n' - 'Added in version 3.12.\n' + 'Added in version 3.12: Added the *convenience variable* ' + 'feature.\n' '\n' 'If a file ".pdbrc" exists in the user’s home directory or in ' 'the\n' @@ -5317,13 +5443,20 @@ '"help\n' ' exec" must be entered to get help on the "!" command.\n' '\n' - 'w(here)\n' + 'w(here) [count]\n' '\n' ' Print a stack trace, with the most recent frame at the ' - 'bottom. An\n' - ' arrow (">") indicates the current frame, which determines ' - 'the\n' - ' context of most commands.\n' + 'bottom. if\n' + ' *count* is 0, print the current frame entry. If *count* is\n' + ' negative, print the least recent - *count* frames. If *count* ' + 'is\n' + ' positive, print the most recent *count* frames. An arrow ' + '(">")\n' + ' indicates the current frame, which determines the context of ' + 'most\n' + ' commands.\n' + '\n' + ' Changed in version 3.14: *count* argument is added.\n' '\n' 'd(own) [count]\n' '\n' @@ -5347,7 +5480,7 @@ 'one that\n' ' hasn’t been loaded yet). The file is searched on ' '"sys.path".\n' - ' Accepatable forms of *filename* are "/abspath/to/file.py",\n' + ' Acceptable forms of *filename* are "/abspath/to/file.py",\n' ' "relpath/file.py", "module" and "package.module".\n' '\n' ' With a *function* argument, set a break at the first ' @@ -5449,25 +5582,27 @@ '\n' ' Specifying any command resuming execution (currently ' '"continue",\n' - ' "step", "next", "return", "jump", "quit" and their ' - 'abbreviations)\n' - ' terminates the command list (as if that command was ' - 'immediately\n' - ' followed by end). This is because any time you resume ' - 'execution\n' - ' (even with a simple next or step), you may encounter another\n' - ' breakpoint—which could have its own command list, leading to\n' - ' ambiguities about which list to execute.\n' - '\n' - ' If you use the "silent" command in the command list, the ' - 'usual\n' - ' message about stopping at a breakpoint is not printed. This ' - 'may be\n' - ' desirable for breakpoints that are to print a specific ' - 'message and\n' - ' then continue. If none of the other commands print anything, ' - 'you\n' - ' see no sign that the breakpoint was reached.\n' + ' "step", "next", "return", "until", "jump", "quit" and their\n' + ' abbreviations) terminates the command list (as if that ' + 'command was\n' + ' immediately followed by end). This is because any time you ' + 'resume\n' + ' execution (even with a simple next or step), you may ' + 'encounter\n' + ' another breakpoint—which could have its own command list, ' + 'leading\n' + ' to ambiguities about which list to execute.\n' + '\n' + ' If the list of commands contains the "silent" command, or a ' + 'command\n' + ' that resumes execution, then the breakpoint message ' + 'containing\n' + ' information about the frame is not displayed.\n' + '\n' + ' Changed in version 3.14: Frame information will not be ' + 'displayed if\n' + ' a command that resumes execution is present in the command ' + 'list.\n' '\n' 's(tep)\n' '\n' @@ -5658,24 +5793,22 @@ '\n' 'interact\n' '\n' - ' Start an interactive interpreter (using the "code" module) ' - 'whose\n' - ' global namespace contains all the (global and local) names ' - 'found in\n' - ' the current scope. Use "exit()" or "quit()" to exit the ' - 'interpreter\n' - ' and return to the debugger.\n' + ' Start an interactive interpreter (using the "code" module) in ' + 'a new\n' + ' global namespace initialised from the local and global ' + 'namespaces\n' + ' for the current scope. Use "exit()" or "quit()" to exit the\n' + ' interpreter and return to the debugger.\n' '\n' ' Note:\n' '\n' - ' Because interact creates a new global namespace with the ' - 'current\n' - ' global and local namespace for execution, assignment to ' - 'variables\n' - ' will not affect the original namespaces. However, ' - 'modification to\n' - ' the mutable objects will be reflected in the original ' - 'namespaces.\n' + ' As "interact" creates a new dedicated namespace for code\n' + ' execution, assignments to variables will not affect the ' + 'original\n' + ' namespaces. However, modifications to any referenced ' + 'mutable\n' + ' objects will be reflected in the original namespaces as ' + 'usual.\n' '\n' ' Added in version 3.2.\n' '\n' @@ -5755,6 +5888,10 @@ 'preserved.\n' ' "restart" is an alias for "run".\n' '\n' + ' Changed in version 3.14: "run" and "restart" commands are ' + 'disabled\n' + ' when the debugger is invoked in "\'inline\'" mode.\n' + '\n' 'q(uit)\n' '\n' ' Quit from the debugger. The program being executed is ' @@ -6264,17 +6401,18 @@ 'Annotation scopes\n' '-----------------\n' '\n' - 'Type parameter lists and "type" statements introduce ' - '*annotation\n' - 'scopes*, which behave mostly like function scopes, but with ' - 'some\n' - 'exceptions discussed below. *Annotations* currently do not use\n' - 'annotation scopes, but they are expected to use annotation ' - 'scopes in\n' - 'Python 3.13 when **PEP 649** is implemented.\n' + '*Annotations*, type parameter lists and "type" statements ' + 'introduce\n' + '*annotation scopes*, which behave mostly like function scopes, ' + 'but\n' + 'with some exceptions discussed below.\n' '\n' 'Annotation scopes are used in the following contexts:\n' '\n' + '* *Function annotations*.\n' + '\n' + '* *Variable annotations*.\n' + '\n' '* Type parameter lists for generic type aliases.\n' '\n' '* Type parameter lists for generic functions. A generic ' @@ -6328,11 +6466,11 @@ '\n' '* While annotation scopes have an internal name, that name is ' 'not\n' - ' reflected in the *__qualname__* of objects defined within the ' - 'scope.\n' - ' Instead, the "__qualname__" of such objects is as if the ' - 'object were\n' - ' defined in the enclosing scope.\n' + ' reflected in the *qualified name* of objects defined within ' + 'the\n' + ' scope. Instead, the "__qualname__" of such objects is as if ' + 'the\n' + ' object were defined in the enclosing scope.\n' '\n' 'Added in version 3.12: Annotation scopes were introduced in ' 'Python\n' @@ -6342,21 +6480,26 @@ 'type\n' 'parameter defaults, as introduced by **PEP 696**.\n' '\n' + 'Changed in version 3.14: Annotation scopes are now also used ' + 'for\n' + 'annotations, as specified in **PEP 649** and **PEP 749**.\n' + '\n' '\n' 'Lazy evaluation\n' '---------------\n' '\n' - 'The values of type aliases created through the "type" statement ' - 'are\n' - '*lazily evaluated*. The same applies to the bounds, ' - 'constraints, and\n' - 'default values of type variables created through the type ' - 'parameter\n' - 'syntax. This means that they are not evaluated when the type ' - 'alias or\n' - 'type variable is created. Instead, they are only evaluated when ' - 'doing\n' - 'so is necessary to resolve an attribute access.\n' + 'Most annotation scopes are *lazily evaluated*. This includes\n' + 'annotations, the values of type aliases created through the ' + '"type"\n' + 'statement, and the bounds, constraints, and default values of ' + 'type\n' + 'variables created through the type parameter syntax. This means ' + 'that\n' + 'they are not evaluated when the type alias or type variable is\n' + 'created, or when the object carrying annotations is created. ' + 'Instead,\n' + 'they are only evaluated when necessary, for example when the\n' + '"__value__" attribute on a type alias is accessed.\n' '\n' 'Example:\n' '\n' @@ -6534,12 +6677,17 @@ 'exprlists': 'Expression lists\n' '****************\n' '\n' - ' expression_list ::= expression ("," expression)* [","]\n' - ' starred_list ::= starred_item ("," starred_item)* ' + ' starred_expression ::= ["*"] or_expr\n' + ' flexible_expression ::= assignment_expression | ' + 'starred_expression\n' + ' flexible_expression_list ::= flexible_expression ("," ' + 'flexible_expression)* [","]\n' + ' starred_expression_list ::= starred_expression ("," ' + 'starred_expression)* [","]\n' + ' expression_list ::= expression ("," expression)* ' '[","]\n' - ' starred_expression ::= expression | (starred_item ",")* ' - '[starred_item]\n' - ' starred_item ::= assignment_expression | "*" or_expr\n' + ' yield_list ::= expression_list | ' + 'starred_expression "," [starred_expression_list]\n' '\n' 'Except when part of a list or set display, an expression list\n' 'containing at least one comma yields a tuple. The length of ' @@ -6558,6 +6706,10 @@ 'Added in version 3.5: Iterable unpacking in expression lists,\n' 'originally proposed by **PEP 448**.\n' '\n' + 'Added in version 3.11: Any item in an expression list may be ' + 'starred.\n' + 'See **PEP 646**.\n' + '\n' 'A trailing comma is required only to create a one-item tuple, ' 'such as\n' '"1,"; it is optional in all other cases. A single expression ' @@ -6567,10 +6719,10 @@ 'that expression. (To create an empty tuple, use an empty pair ' 'of\n' 'parentheses: "()".)\n', - 'floating': 'Floating point literals\n' + 'floating': 'Floating-point literals\n' '***********************\n' '\n' - 'Floating point literals are described by the following lexical\n' + 'Floating-point literals are described by the following lexical\n' 'definitions:\n' '\n' ' floatnumber ::= pointfloat | exponentfloat\n' @@ -6584,12 +6736,12 @@ 'using\n' 'radix 10. For example, "077e010" is legal, and denotes the same ' 'number\n' - 'as "77e10". The allowed range of floating point literals is\n' + 'as "77e10". The allowed range of floating-point literals is\n' 'implementation-dependent. As in integer literals, underscores ' 'are\n' 'supported for digit grouping.\n' '\n' - 'Some examples of floating point literals:\n' + 'Some examples of floating-point literals:\n' '\n' ' 3.14 10. .001 1e100 3.14e-10 0e0 ' '3.14_15_93\n' @@ -6972,7 +7124,7 @@ '\n' 'The "\'_\'" option signals the use of an underscore for a ' 'thousands\n' - 'separator for floating point presentation types and for ' + 'separator for floating-point presentation types and for ' 'integer\n' 'presentation type "\'d\'". For integer presentation types ' '"\'b\'", "\'o\'",\n' @@ -7099,11 +7251,11 @@ '\n' 'In addition to the above presentation types, integers can ' 'be formatted\n' - 'with the floating point presentation types listed below ' + 'with the floating-point presentation types listed below ' '(except "\'n\'"\n' 'and "None"). When doing so, "float()" is used to convert ' 'the integer\n' - 'to a floating point number before formatting.\n' + 'to a floating-point number before formatting.\n' '\n' 'The available presentation types for "float" and "Decimal" ' 'values are:\n' @@ -7129,12 +7281,10 @@ 'of "6" digits |\n' ' | | after the decimal point for "float", and ' 'shows all |\n' - ' | | coefficient digits for "Decimal". If no ' - 'digits follow the |\n' - ' | | decimal point, the decimal point is also ' - 'removed unless |\n' - ' | | the "#" option is ' - 'used. |\n' + ' | | coefficient digits for "Decimal". If ' + '"p=0", the decimal |\n' + ' | | point is omitted unless the "#" option is ' + 'used. |\n' ' ' '+-----------+------------------------------------------------------------+\n' ' | "\'E\'" | Scientific notation. Same as "\'e\'" ' @@ -7153,12 +7303,10 @@ 'decimal point for |\n' ' | | "float", and uses a precision large enough ' 'to show all |\n' - ' | | coefficient digits for "Decimal". If no ' - 'digits follow the |\n' - ' | | decimal point, the decimal point is also ' - 'removed unless |\n' - ' | | the "#" option is ' - 'used. |\n' + ' | | coefficient digits for "Decimal". If ' + '"p=0", the decimal |\n' + ' | | point is omitted unless the "#" option is ' + 'used. |\n' ' ' '+-----------+------------------------------------------------------------+\n' ' | "\'F\'" | Fixed-point notation. Same as "\'f\'", ' @@ -7243,18 +7391,22 @@ 'percent sign. |\n' ' ' '+-----------+------------------------------------------------------------+\n' - ' | None | For "float" this is the same as "\'g\'", ' - 'except that when |\n' - ' | | fixed-point notation is used to format the ' - 'result, it |\n' + ' | None | For "float" this is like the "\'g\'" type, ' + 'except that when |\n' + ' | | fixed- point notation is used to format ' + 'the result, it |\n' ' | | always includes at least one digit past ' - 'the decimal point. |\n' - ' | | The precision used is as large as needed ' - 'to represent the |\n' - ' | | given value faithfully. For "Decimal", ' - 'this is the same |\n' - ' | | as either "\'g\'" or "\'G\'" depending on ' - 'the value of |\n' + 'the decimal point, |\n' + ' | | and switches to the scientific notation ' + 'when "exp >= p - |\n' + ' | | 1". When the precision is not specified, ' + 'the latter will |\n' + ' | | be as large as needed to represent the ' + 'given value |\n' + ' | | faithfully. For "Decimal", this is the ' + 'same as either |\n' + ' | | "\'g\'" or "\'G\'" depending on the value ' + 'of |\n' ' | | "context.capitals" for the current decimal ' 'context. The |\n' ' | | overall effect is to match the output of ' @@ -7444,10 +7596,12 @@ ' parameter_list_no_posonly ::= defparameter ("," ' 'defparameter)* ["," [parameter_list_starargs]]\n' ' | parameter_list_starargs\n' - ' parameter_list_starargs ::= "*" [parameter] ("," ' + ' parameter_list_starargs ::= "*" [star_parameter] ("," ' 'defparameter)* ["," ["**" parameter [","]]]\n' ' | "**" parameter [","]\n' ' parameter ::= identifier [":" expression]\n' + ' star_parameter ::= identifier [":" ["*"] ' + 'expression]\n' ' defparameter ::= parameter ["=" expression]\n' ' funcname ::= identifier\n' '\n' @@ -7575,27 +7729,22 @@ 'expression"”\n' 'following the parameter name. Any parameter may have an ' 'annotation,\n' - 'even those of the form "*identifier" or "**identifier". ' - 'Functions may\n' - 'have “return” annotation of the form “"-> expression"” after ' - 'the\n' - 'parameter list. These annotations can be any valid Python ' - 'expression.\n' - 'The presence of annotations does not change the semantics of a\n' - 'function. The annotation values are available as values of a\n' - 'dictionary keyed by the parameters’ names in the ' - '"__annotations__"\n' - 'attribute of the function object. If the "annotations" import ' - 'from\n' - '"__future__" is used, annotations are preserved as strings at ' - 'runtime\n' - 'which enables postponed evaluation. Otherwise, they are ' - 'evaluated\n' - 'when the function definition is executed. In this case ' - 'annotations\n' - 'may be evaluated in a different order than they appear in the ' - 'source\n' - 'code.\n' + 'even those of the form "*identifier" or "**identifier". (As a ' + 'special\n' + 'case, parameters of the form "*identifier" may have an ' + 'annotation “":\n' + '*expression"”.) Functions may have “return” annotation of the ' + 'form\n' + '“"-> expression"” after the parameter list. These annotations ' + 'can be\n' + 'any valid Python expression. The presence of annotations does ' + 'not\n' + 'change the semantics of a function. See Annotations for more\n' + 'information on annotations.\n' + '\n' + 'Changed in version 3.11: Parameters of the form “"*identifier"” ' + 'may\n' + 'have an annotation “": *expression"”. See **PEP 646**.\n' '\n' 'It is also possible to create anonymous functions (functions not ' 'bound\n' @@ -7669,7 +7818,7 @@ 'parameters, or as targets in "with" statements or "except" ' 'clauses, or\n' 'in a "for" target list, "class" definition, function definition,\n' - '"import" statement, or variable annotation.\n' + '"import" statement, or *variable annotations*.\n' '\n' '**CPython implementation detail:** The current implementation does ' 'not\n' @@ -7764,19 +7913,16 @@ '\n' 'Within the ASCII range (U+0001..U+007F), the valid characters ' 'for\n' - 'identifiers are the same as in Python 2.x: the uppercase and ' - 'lowercase\n' - 'letters "A" through "Z", the underscore "_" and, except for ' - 'the first\n' - 'character, the digits "0" through "9".\n' - '\n' - 'Python 3.0 introduces additional characters from outside the ' - 'ASCII\n' - 'range (see **PEP 3131**). For these characters, the ' - 'classification\n' - 'uses the version of the Unicode Character Database as ' - 'included in the\n' - '"unicodedata" module.\n' + 'identifiers include the uppercase and lowercase letters "A" ' + 'through\n' + '"Z", the underscore "_" and, except for the first character, ' + 'the\n' + 'digits "0" through "9". Python 3.0 introduced additional ' + 'characters\n' + 'from outside the ASCII range (see **PEP 3131**). For these\n' + 'characters, the classification uses the version of the ' + 'Unicode\n' + 'Character Database as included in the "unicodedata" module.\n' '\n' 'Identifiers are unlimited in length. Case is significant.\n' '\n' @@ -7826,8 +7972,8 @@ '\n' 'A non-normative HTML file listing all valid identifier ' 'characters for\n' - 'Unicode 15.1.0 can be found at\n' - 'https://www.unicode.org/Public/15.1.0/ucd/DerivedCoreProperties.txt\n' + 'Unicode 16.0.0 can be found at\n' + 'https://www.unicode.org/Public/16.0.0/ucd/DerivedCoreProperties.txt\n' '\n' '\n' 'Keywords\n' @@ -7961,11 +8107,11 @@ '\n' 'An imaginary literal yields a complex number with a real part ' 'of 0.0.\n' - 'Complex numbers are represented as a pair of floating point ' + 'Complex numbers are represented as a pair of floating-point ' 'numbers\n' 'and have the same restrictions on their range. To create a ' 'complex\n' - 'number with a nonzero real part, add a floating point number to ' + 'number with a nonzero real part, add a floating-point number to ' 'it,\n' 'e.g., "(3+4j)". Some examples of imaginary literals:\n' '\n' @@ -8351,7 +8497,8 @@ 'in\n' 'square brackets:\n' '\n' - ' list_display ::= "[" [starred_list | comprehension] "]"\n' + ' list_display ::= "[" [flexible_expression_list | comprehension] ' + '"]"\n' '\n' 'A list display yields a new list object, the contents being ' 'specified\n' @@ -8545,15 +8692,18 @@ 'Annotation scopes\n' '=================\n' '\n' - 'Type parameter lists and "type" statements introduce *annotation\n' - 'scopes*, which behave mostly like function scopes, but with some\n' - 'exceptions discussed below. *Annotations* currently do not use\n' - 'annotation scopes, but they are expected to use annotation scopes ' - 'in\n' - 'Python 3.13 when **PEP 649** is implemented.\n' + '*Annotations*, type parameter lists and "type" statements ' + 'introduce\n' + '*annotation scopes*, which behave mostly like function scopes, ' + 'but\n' + 'with some exceptions discussed below.\n' '\n' 'Annotation scopes are used in the following contexts:\n' '\n' + '* *Function annotations*.\n' + '\n' + '* *Variable annotations*.\n' + '\n' '* Type parameter lists for generic type aliases.\n' '\n' '* Type parameter lists for generic functions. A generic ' @@ -8602,11 +8752,9 @@ ' can introduce new names.\n' '\n' '* While annotation scopes have an internal name, that name is not\n' - ' reflected in the *__qualname__* of objects defined within the ' - 'scope.\n' - ' Instead, the "__qualname__" of such objects is as if the object ' - 'were\n' - ' defined in the enclosing scope.\n' + ' reflected in the *qualified name* of objects defined within the\n' + ' scope. Instead, the "__qualname__" of such objects is as if the\n' + ' object were defined in the enclosing scope.\n' '\n' 'Added in version 3.12: Annotation scopes were introduced in ' 'Python\n' @@ -8615,21 +8763,25 @@ 'Changed in version 3.13: Annotation scopes are also used for type\n' 'parameter defaults, as introduced by **PEP 696**.\n' '\n' + 'Changed in version 3.14: Annotation scopes are now also used for\n' + 'annotations, as specified in **PEP 649** and **PEP 749**.\n' + '\n' '\n' 'Lazy evaluation\n' '===============\n' '\n' - 'The values of type aliases created through the "type" statement ' - 'are\n' - '*lazily evaluated*. The same applies to the bounds, constraints, ' - 'and\n' - 'default values of type variables created through the type ' - 'parameter\n' - 'syntax. This means that they are not evaluated when the type alias ' - 'or\n' - 'type variable is created. Instead, they are only evaluated when ' - 'doing\n' - 'so is necessary to resolve an attribute access.\n' + 'Most annotation scopes are *lazily evaluated*. This includes\n' + 'annotations, the values of type aliases created through the ' + '"type"\n' + 'statement, and the bounds, constraints, and default values of ' + 'type\n' + 'variables created through the type parameter syntax. This means ' + 'that\n' + 'they are not evaluated when the type alias or type variable is\n' + 'created, or when the object carrying annotations is created. ' + 'Instead,\n' + 'they are only evaluated when necessary, for example when the\n' + '"__value__" attribute on a type alias is accessed.\n' '\n' 'Example:\n' '\n' @@ -8762,8 +8914,8 @@ 'numbers': 'Numeric literals\n' '****************\n' '\n' - 'There are three types of numeric literals: integers, floating ' - 'point\n' + 'There are three types of numeric literals: integers, ' + 'floating-point\n' 'numbers, and imaginary numbers. There are no complex literals\n' '(complex numbers can be formed by adding a real number and an\n' 'imaginary number).\n' @@ -8969,13 +9121,9 @@ ' of the object truncated to an "Integral" (typically an ' '"int").\n' '\n' - ' The built-in function "int()" falls back to ' - '"__trunc__()" if\n' - ' neither "__int__()" nor "__index__()" is defined.\n' - '\n' - ' Changed in version 3.11: The delegation of "int()" to ' - '"__trunc__()"\n' - ' is deprecated.\n', + ' Changed in version 3.14: "int()" no longer delegates to ' + 'the\n' + ' "__trunc__()" method.\n', 'objects': 'Objects, values and types\n' '*************************\n' '\n' @@ -9095,16 +9243,22 @@ 'types, operations that compute new values may actually return a\n' 'reference to any existing object with the same type and value, ' 'while\n' - 'for mutable objects this is not allowed. E.g., after "a = 1; b = ' - '1",\n' - '"a" and "b" may or may not refer to the same object with the ' - 'value\n' - 'one, depending on the implementation, but after "c = []; d = []", ' - '"c"\n' - 'and "d" are guaranteed to refer to two different, unique, newly\n' - 'created empty lists. (Note that "c = d = []" assigns the same ' - 'object\n' - 'to both "c" and "d".)\n', + 'for mutable objects this is not allowed. For example, after "a = ' + '1; b\n' + '= 1", *a* and *b* may or may not refer to the same object with ' + 'the\n' + 'value one, depending on the implementation. This is because "int" ' + 'is\n' + 'an immutable type, so the reference to "1" can be reused. This\n' + 'behaviour depends on the implementation used, so should not be ' + 'relied\n' + 'upon, but is something to be aware of when making use of object\n' + 'identity tests. However, after "c = []; d = []", *c* and *d* are\n' + 'guaranteed to refer to two different, unique, newly created ' + 'empty\n' + 'lists. (Note that "e = f = []" assigns the *same* object to both ' + '*e*\n' + 'and *f*.)\n', 'operator-summary': 'Operator precedence\n' '*******************\n' '\n' @@ -9333,8 +9487,8 @@ '"complex"\n' 'number. (In earlier versions it raised a "ValueError".)\n' '\n' - 'This operation can be customized using the special "__pow__()" ' - 'method.\n', + 'This operation can be customized using the special "__pow__()" and\n' + '"__rpow__()" methods.\n', 'raise': 'The "raise" statement\n' '*********************\n' '\n' @@ -9748,9 +9902,12 @@ 'the\n' 'second argument.\n' '\n' - 'This operation can be customized using the special ' - '"__lshift__()" and\n' - '"__rshift__()" methods.\n' + 'The left shift operation can be customized using the special\n' + '"__lshift__()" and "__rlshift__()" methods. The right shift ' + 'operation\n' + 'can be customized using the special "__rshift__()" and ' + '"__rrshift__()"\n' + 'methods.\n' '\n' 'A right shift by *n* bits is defined as floor division by ' '"pow(2,n)".\n' @@ -9816,20 +9973,6 @@ 'not reported\n' 'by the "dir()" built-in function.\n' '\n' - 'object.__dict__\n' - '\n' - ' A dictionary or other mapping object used to store an ' - 'object’s\n' - ' (writable) attributes.\n' - '\n' - 'instance.__class__\n' - '\n' - ' The class to which a class instance belongs.\n' - '\n' - 'class.__bases__\n' - '\n' - ' The tuple of base classes of a class object.\n' - '\n' 'definition.__name__\n' '\n' ' The name of the class, function, method, descriptor, or ' @@ -9844,47 +9987,26 @@ '\n' ' Added in version 3.3.\n' '\n' - 'definition.__type_params__\n' - '\n' - ' The type parameters of generic classes, functions, and ' - 'type\n' - ' aliases.\n' - '\n' - ' Added in version 3.12.\n' - '\n' - 'class.__mro__\n' + 'definition.__module__\n' '\n' - ' This attribute is a tuple of classes that are considered ' - 'when\n' - ' looking for base classes during method resolution.\n' + ' The name of the module in which a class or function was ' + 'defined.\n' '\n' - 'class.mro()\n' - '\n' - ' This method can be overridden by a metaclass to customize ' - 'the\n' - ' method resolution order for its instances. It is called ' - 'at class\n' - ' instantiation, and its result is stored in "__mro__".\n' + 'definition.__doc__\n' '\n' - 'class.__subclasses__()\n' + ' The documentation string of a class or function, or ' + '"None" if\n' + ' undefined.\n' '\n' - ' Each class keeps a list of weak references to its ' - 'immediate\n' - ' subclasses. This method returns a list of all those ' - 'references\n' - ' still alive. The list is in definition order. Example:\n' - '\n' - ' >>> int.__subclasses__()\n' - " [, , , " - "]\n" - '\n' - 'class.__static_attributes__\n' + 'definition.__type_params__\n' '\n' - ' A tuple containing names of attributes of this class ' - 'which are\n' - ' accessed through "self.X" from any function in its body.\n' + ' The type parameters of generic classes, functions, and ' + 'type\n' + ' aliases. For classes and functions that are not generic, ' + 'this will\n' + ' be an empty tuple.\n' '\n' - ' Added in version 3.13.\n', + ' Added in version 3.12.\n', 'specialnames': 'Special method names\n' '********************\n' '\n' @@ -10028,6 +10150,10 @@ ' It is not guaranteed that "__del__()" methods are called ' 'for\n' ' objects that still exist when the interpreter exits.\n' + ' "weakref.finalize" provides a straightforward way to ' + 'register a\n' + ' cleanup function to be called when an object is garbage ' + 'collected.\n' '\n' ' Note:\n' '\n' @@ -10826,11 +10952,13 @@ 'the class\n' ' where it is defined. *__slots__* declared in parents are ' 'available\n' - ' in child classes. However, child subclasses will get a ' - '"__dict__"\n' - ' and *__weakref__* unless they also define *__slots__* ' - '(which should\n' - ' only contain names of any *additional* slots).\n' + ' in child classes. However, instances of a child subclass ' + 'will get a\n' + ' "__dict__" and *__weakref__* unless the subclass also ' + 'defines\n' + ' *__slots__* (which should only contain names of any ' + '*additional*\n' + ' slots).\n' '\n' '* If a class defines a slot also defined in a base class, ' 'the instance\n' @@ -11247,7 +11375,7 @@ 'built-in\n' 'types), including other ABCs.\n' '\n' - 'class.__instancecheck__(self, instance)\n' + 'type.__instancecheck__(self, instance)\n' '\n' ' Return true if *instance* should be considered a (direct ' 'or\n' @@ -11255,7 +11383,7 @@ 'implement\n' ' "isinstance(instance, class)".\n' '\n' - 'class.__subclasscheck__(self, subclass)\n' + 'type.__subclasscheck__(self, subclass)\n' '\n' ' Return true if *subclass* should be considered a (direct ' 'or\n' @@ -11909,13 +12037,9 @@ ' of the object truncated to an "Integral" (typically an ' '"int").\n' '\n' - ' The built-in function "int()" falls back to "__trunc__()" ' - 'if\n' - ' neither "__int__()" nor "__index__()" is defined.\n' - '\n' - ' Changed in version 3.11: The delegation of "int()" to ' - '"__trunc__()"\n' - ' is deprecated.\n' + ' Changed in version 3.14: "int()" no longer delegates to ' + 'the\n' + ' "__trunc__()" method.\n' '\n' '\n' 'With Statement Context Managers\n' @@ -12082,6 +12206,71 @@ ' ABC for buffer types.\n' '\n' '\n' + 'Annotations\n' + '===========\n' + '\n' + 'Functions, classes, and modules may contain *annotations*, ' + 'which are a\n' + 'way to associate information (usually *type hints*) with a ' + 'symbol.\n' + '\n' + 'object.__annotations__\n' + '\n' + ' This attribute contains the annotations for an object. It ' + 'is lazily\n' + ' evaluated, so accessing the attribute may execute ' + 'arbitrary code\n' + ' and raise exceptions. If evaluation is successful, the ' + 'attribute is\n' + ' set to a dictionary mapping from variable names to ' + 'annotations.\n' + '\n' + ' Changed in version 3.14: Annotations are now lazily ' + 'evaluated.\n' + '\n' + 'object.__annotate__(format)\n' + '\n' + ' An *annotate function*. Returns a new dictionary object ' + 'mapping\n' + ' attribute/parameter names to their annotation values.\n' + '\n' + ' Takes a format parameter specifying the format in which ' + 'annotations\n' + ' values should be provided. It must be a member of the\n' + ' "annotationlib.Format" enum, or an integer with a value\n' + ' corresponding to a member of the enum.\n' + '\n' + ' If an annotate function doesn’t support the requested ' + 'format, it\n' + ' must raise "NotImplementedError". Annotate functions must ' + 'always\n' + ' support "VALUE" format; they must not raise ' + '"NotImplementedError()"\n' + ' when called with this format.\n' + '\n' + ' When called with "VALUE" format, an annotate function ' + 'may raise\n' + ' "NameError"; it must not raise "NameError" when called ' + 'requesting\n' + ' any other format.\n' + '\n' + ' If an object does not have any annotations, ' + '"__annotate__" should\n' + ' preferably be set to "None" (it can’t be deleted), rather ' + 'than set\n' + ' to a function that returns an empty dict.\n' + '\n' + ' Added in version 3.14.\n' + '\n' + 'See also:\n' + '\n' + ' **PEP 649** — Deferred evaluation of annotation using ' + 'descriptors\n' + ' Introduces lazy evaluation of annotations and the ' + '"__annotate__"\n' + ' function.\n' + '\n' + '\n' 'Special method lookup\n' '=====================\n' '\n' @@ -12400,7 +12589,7 @@ 'the\n' ' "LC_NUMERIC" locale in some cases.\n' '\n' - 'str.format_map(mapping)\n' + 'str.format_map(mapping, /)\n' '\n' ' Similar to "str.format(**mapping)", except that ' '"mapping" is used\n' @@ -12828,11 +13017,11 @@ ' and are deemed to delimit empty strings (for example,\n' ' "\'1,,2\'.split(\',\')" returns "[\'1\', \'\', ' '\'2\']"). The *sep* argument\n' - ' may consist of multiple characters (for example,\n' - ' "\'1<>2<>3\'.split(\'<>\')" returns "[\'1\', \'2\', ' - '\'3\']"). Splitting an\n' - ' empty string with a specified separator returns ' - '"[\'\']".\n' + ' may consist of multiple characters as a single ' + 'delimiter (to split\n' + ' with multiple delimiters, use "re.split()"). Splitting ' + 'an empty\n' + ' string with a specified separator returns "[\'\']".\n' '\n' ' For example:\n' '\n' @@ -12842,6 +13031,8 @@ " ['1', '2,3']\n" " >>> '1,2,,3,'.split(',')\n" " ['1', '2', '', '3', '']\n" + " >>> '1<>2<>3<4'.split('<>')\n" + " ['1', '2', '3<4']\n" '\n' ' If *sep* is not specified or is "None", a different ' 'splitting\n' @@ -13184,15 +13375,13 @@ 'greater must be expressed with escapes.\n' '\n' 'Both string and bytes literals may optionally be prefixed with a\n' - 'letter "\'r\'" or "\'R\'"; such strings are called *raw strings* ' - 'and treat\n' - 'backslashes as literal characters. As a result, in string ' - 'literals,\n' - '"\'\\U\'" and "\'\\u\'" escapes in raw strings are not treated ' - 'specially.\n' - 'Given that Python 2.x’s raw unicode literals behave differently ' - 'than\n' - 'Python 3.x’s the "\'ur\'" syntax is not supported.\n' + 'letter "\'r\'" or "\'R\'"; such constructs are called *raw ' + 'string\n' + 'literals* and *raw bytes literals* respectively and treat ' + 'backslashes\n' + 'as literal characters. As a result, in raw string literals, ' + '"\'\\U\'"\n' + 'and "\'\\u\'" escapes are not treated specially.\n' '\n' 'Added in version 3.3: The "\'rb\'" prefix of raw bytes literals ' 'has been\n' @@ -13383,7 +13572,8 @@ '*generic\n' 'class* will generally return a GenericAlias object.\n' '\n' - ' subscription ::= primary "[" expression_list "]"\n' + ' subscription ::= primary "[" flexible_expression_list ' + '"]"\n' '\n' 'When an object is subscripted, the interpreter will ' 'evaluate the\n' @@ -13402,13 +13592,18 @@ 'see\n' '__class_getitem__ versus __getitem__.\n' '\n' - 'If the expression list contains at least one comma, it will ' - 'evaluate\n' - 'to a "tuple" containing the items of the expression list. ' - 'Otherwise,\n' - 'the expression list will evaluate to the value of the ' - 'list’s sole\n' - 'member.\n' + 'If the expression list contains at least one comma, or if ' + 'any of the\n' + 'expressions are starred, the expression list will evaluate ' + 'to a\n' + '"tuple" containing the items of the expression list. ' + 'Otherwise, the\n' + 'expression list will evaluate to the value of the list’s ' + 'sole member.\n' + '\n' + 'Changed in version 3.11: Expressions in an expression list ' + 'may be\n' + 'starred. See **PEP 646**.\n' '\n' 'For built-in objects, there are two types of objects that ' 'support\n' @@ -13522,14 +13717,15 @@ 'clauses in turn until one is found that matches the exception. An\n' 'expression-less "except" clause, if present, must be last; it ' 'matches\n' - 'any exception. For an "except" clause with an expression, that\n' - 'expression is evaluated, and the clause matches the exception if the\n' - 'resulting object is “compatible” with the exception. An object is\n' - 'compatible with an exception if the object is the class or a *non-\n' - 'virtual base class* of the exception object, or a tuple containing ' - 'an\n' - 'item that is the class or a non-virtual base class of the exception\n' - 'object.\n' + 'any exception.\n' + '\n' + 'For an "except" clause with an expression, the expression must\n' + 'evaluate to an exception type or a tuple of exception types. The\n' + 'raised exception matches an "except" clause whose expression ' + 'evaluates\n' + 'to the class or a *non-virtual base class* of the exception object, ' + 'or\n' + 'to a tuple that contains such a class.\n' '\n' 'If no "except" clause matches the exception, the search for an\n' 'exception handler continues in the surrounding code and on the\n' @@ -13658,12 +13854,13 @@ ' ...\n' " ExceptionGroup('', (BlockingIOError()))\n" '\n' - 'An "except*" clause must have a matching type, and this type cannot ' - 'be\n' - 'a subclass of "BaseExceptionGroup". It is not possible to mix ' - '"except"\n' - 'and "except*" in the same "try". "break", "continue" and "return"\n' - 'cannot appear in an "except*" clause.\n' + 'An "except*" clause must have a matching expression; it cannot be\n' + '"except*:". Furthermore, this expression cannot contain exception\n' + 'group types, because that would have ambiguous semantics.\n' + '\n' + 'It is not possible to mix "except" and "except*" in the same "try".\n' + '"break", "continue" and "return" cannot appear in an "except*" ' + 'clause.\n' '\n' '\n' '"else" clause\n' @@ -13778,11 +13975,12 @@ 'See Implementing the arithmetic operations for more details.\n' '\n' 'Changed in version 3.9: Evaluating "NotImplemented" in a boolean\n' - 'context is deprecated. While it currently evaluates as true, it ' - 'will\n' - 'emit a "DeprecationWarning". It will raise a "TypeError" in a ' - 'future\n' - 'version of Python.\n' + 'context was deprecated.\n' + '\n' + 'Changed in version 3.14: Evaluating "NotImplemented" in a boolean\n' + 'context now raises a "TypeError". It previously evaluated to ' + '"True"\n' + 'and emitted a "DeprecationWarning" since Python 3.9.\n' '\n' '\n' 'Ellipsis\n' @@ -13824,7 +14022,7 @@ '\n' '* A sign is shown only when the number is negative.\n' '\n' - 'Python distinguishes between integers, floating point numbers, and\n' + 'Python distinguishes between integers, floating-point numbers, and\n' 'complex numbers:\n' '\n' '\n' @@ -13869,28 +14067,28 @@ '"numbers.Real" ("float")\n' '------------------------\n' '\n' - 'These represent machine-level double precision floating point ' + 'These represent machine-level double precision floating-point ' 'numbers.\n' 'You are at the mercy of the underlying machine architecture (and C ' 'or\n' 'Java implementation) for the accepted range and handling of ' 'overflow.\n' - 'Python does not support single-precision floating point numbers; ' + 'Python does not support single-precision floating-point numbers; ' 'the\n' 'savings in processor and memory usage that are usually the reason ' 'for\n' 'using these are dwarfed by the overhead of using objects in Python, ' 'so\n' 'there is no reason to complicate the language with two kinds of\n' - 'floating point numbers.\n' + 'floating-point numbers.\n' '\n' '\n' '"numbers.Complex" ("complex")\n' '-----------------------------\n' '\n' 'These represent complex numbers as a pair of machine-level double\n' - 'precision floating point numbers. The same caveats apply as for\n' - 'floating point numbers. The real and imaginary parts of a complex\n' + 'precision floating-point numbers. The same caveats apply as for\n' + 'floating-point numbers. The real and imaginary parts of a complex\n' 'number "z" can be retrieved through the read-only attributes ' '"z.real"\n' 'and "z.imag".\n' @@ -14084,8 +14282,7 @@ 'however removing a key and re-inserting it will add it to the end\n' 'instead of keeping its old place.\n' '\n' - 'Dictionaries are mutable; they can be created by the "{...}" ' - 'notation\n' + 'Dictionaries are mutable; they can be created by the "{}" notation\n' '(see section Dictionary displays).\n' '\n' 'The extension modules "dbm.ndbm" and "dbm.gnu" provide additional\n' @@ -14135,13 +14332,15 @@ '| function.__closure__ | "None" or a ' '"tuple" of cells that contain bindings |\n' '| | for the ' - 'function’s free variables. A cell object |\n' - '| | has the ' - 'attribute "cell_contents". This can be |\n' - '| | used to get ' - 'the value of the cell, as well as set |\n' - '| | the ' - 'value. |\n' + 'names specified in the "co_freevars" |\n' + '| | attribute of ' + 'the function’s "code object". A cell |\n' + '| | object has ' + 'the attribute "cell_contents". This can |\n' + '| | be used to ' + 'get the value of the cell, as well as |\n' + '| | set the ' + 'value. |\n' '+----------------------------------------------------+----------------------------------------------------+\n' '\n' '\n' @@ -14156,8 +14355,8 @@ '|====================================================|====================================================|\n' '| function.__doc__ | The ' 'function’s documentation string, or "None" if |\n' - '| | unavailable. ' - 'Not inherited by subclasses. |\n' + '| | ' + 'unavailable. |\n' '+----------------------------------------------------+----------------------------------------------------+\n' '| function.__name__ | The ' 'function’s name. See also: "__name__ |\n' @@ -14198,9 +14397,20 @@ '| | parameter ' 'names, and "\'return\'" for the return |\n' '| | annotation, ' - 'if provided. See also: Annotations |\n' - '| | Best ' - 'Practices. |\n' + 'if provided. See also: |\n' + '| | ' + '"object.__annotations__". Changed in version |\n' + '| | 3.14: ' + 'Annotations are now lazily evaluated. See |\n' + '| | **PEP ' + '649**. |\n' + '+----------------------------------------------------+----------------------------------------------------+\n' + '| function.__annotate__ | The ' + '*annotate function* for this function, or |\n' + '| | "None" if ' + 'the function has no annotations. See |\n' + '| | ' + '"object.__annotate__". Added in version 3.14. |\n' '+----------------------------------------------------+----------------------------------------------------+\n' '| function.__kwdefaults__ | A ' '"dictionary" containing defaults for keyword- |\n' @@ -14305,21 +14515,10 @@ 'to\n' 'calling "f(C,1)" where "f" is the underlying function.\n' '\n' - 'Note that the transformation from function object to instance ' - 'method\n' - 'object happens each time the attribute is retrieved from the ' - 'instance.\n' - 'In some cases, a fruitful optimization is to assign the attribute ' - 'to a\n' - 'local variable and call that local variable. Also notice that this\n' - 'transformation only happens for user-defined functions; other ' - 'callable\n' - 'objects (and all non-callable objects) are retrieved without\n' - 'transformation. It is also important to note that user-defined\n' - 'functions which are attributes of a class instance are not ' - 'converted\n' - 'to bound methods; this *only* happens when the function is an\n' - 'attribute of the class.\n' + 'It is important to note that user-defined functions which are\n' + 'attributes of a class instance are not converted to bound methods;\n' + 'this *only* happens when the function is an attribute of the ' + 'class.\n' '\n' '\n' 'Generator functions\n' @@ -14456,43 +14655,279 @@ 'e.g.,\n' '"m.x = 1" is equivalent to "m.__dict__["x"] = 1".\n' '\n' - 'Predefined (writable) attributes:\n' '\n' - ' "__name__"\n' - ' The module’s name.\n' + 'Import-related attributes on module objects\n' + '-------------------------------------------\n' + '\n' + 'Module objects have the following attributes that relate to the ' + 'import\n' + 'system. When a module is created using the machinery associated ' + 'with\n' + 'the import system, these attributes are filled in based on the\n' + 'module’s *spec*, before the *loader* executes and loads the ' + 'module.\n' + '\n' + 'To create a module dynamically rather than using the import ' + 'system,\n' + 'it’s recommended to use "importlib.util.module_from_spec()", which\n' + 'will set the various import-controlled attributes to appropriate\n' + 'values. It’s also possible to use the "types.ModuleType" ' + 'constructor\n' + 'to create modules directly, but this technique is more error-prone, ' + 'as\n' + 'most attributes must be manually set on the module object after it ' + 'has\n' + 'been created when using this approach.\n' + '\n' + 'Caution:\n' + '\n' + ' With the exception of "__name__", it is **strongly** recommended\n' + ' that you rely on "__spec__" and its attributes instead of any of ' + 'the\n' + ' other individual attributes listed in this subsection. Note that\n' + ' updating an attribute on "__spec__" will not update the\n' + ' corresponding attribute on the module itself:\n' + '\n' + ' >>> import typing\n' + ' >>> typing.__name__, typing.__spec__.name\n' + " ('typing', 'typing')\n" + " >>> typing.__spec__.name = 'spelling'\n" + ' >>> typing.__name__, typing.__spec__.name\n' + " ('typing', 'spelling')\n" + " >>> typing.__name__ = 'keyboard_smashing'\n" + ' >>> typing.__name__, typing.__spec__.name\n' + " ('keyboard_smashing', 'spelling')\n" + '\n' + 'module.__name__\n' + '\n' + ' The name used to uniquely identify the module in the import ' + 'system.\n' + ' For a directly executed module, this will be set to ' + '""__main__"".\n' + '\n' + ' This attribute must be set to the fully qualified name of the\n' + ' module. It is expected to match the value of\n' + ' "module.__spec__.name".\n' + '\n' + 'module.__spec__\n' + '\n' + ' A record of the module’s import-system-related state.\n' + '\n' + ' Set to the "module spec" that was used when importing the ' + 'module.\n' + ' See Module specs for more details.\n' + '\n' + ' Added in version 3.4.\n' + '\n' + 'module.__package__\n' + '\n' + ' The *package* a module belongs to.\n' + '\n' + ' If the module is top-level (that is, not a part of any specific\n' + ' package) then the attribute should be set to "\'\'" (the empty\n' + ' string). Otherwise, it should be set to the name of the ' + 'module’s\n' + ' package (which can be equal to "module.__name__" if the module\n' + ' itself is a package). See **PEP 366** for further details.\n' + '\n' + ' This attribute is used instead of "__name__" to calculate ' + 'explicit\n' + ' relative imports for main modules. It defaults to "None" for\n' + ' modules created dynamically using the "types.ModuleType"\n' + ' constructor; use "importlib.util.module_from_spec()" instead to\n' + ' ensure the attribute is set to a "str".\n' + '\n' + ' It is **strongly** recommended that you use\n' + ' "module.__spec__.parent" instead of "module.__package__".\n' + ' "__package__" is now only used as a fallback if ' + '"__spec__.parent"\n' + ' is not set, and this fallback path is deprecated.\n' + '\n' + ' Changed in version 3.4: This attribute now defaults to "None" ' + 'for\n' + ' modules created dynamically using the "types.ModuleType"\n' + ' constructor. Previously the attribute was optional.\n' + '\n' + ' Changed in version 3.6: The value of "__package__" is expected ' + 'to\n' + ' be the same as "__spec__.parent". "__package__" is now only used ' + 'as\n' + ' a fallback during import resolution if "__spec__.parent" is not\n' + ' defined.\n' + '\n' + ' Changed in version 3.10: "ImportWarning" is raised if an import\n' + ' resolution falls back to "__package__" instead of\n' + ' "__spec__.parent".\n' + '\n' + ' Changed in version 3.12: Raise "DeprecationWarning" instead of\n' + ' "ImportWarning" when falling back to "__package__" during ' + 'import\n' + ' resolution.\n' + '\n' + ' Deprecated since version 3.13, will be removed in version 3.15:\n' + ' "__package__" will cease to be set or taken into consideration ' + 'by\n' + ' the import system or standard library.\n' + '\n' + 'module.__loader__\n' + '\n' + ' The *loader* object that the import machinery used to load the\n' + ' module.\n' '\n' - ' "__doc__"\n' - ' The module’s documentation string, or "None" if unavailable.\n' + ' This attribute is mostly useful for introspection, but can be ' + 'used\n' + ' for additional loader-specific functionality, for example ' + 'getting\n' + ' data associated with a loader.\n' + '\n' + ' "__loader__" defaults to "None" for modules created dynamically\n' + ' using the "types.ModuleType" constructor; use\n' + ' "importlib.util.module_from_spec()" instead to ensure the ' + 'attribute\n' + ' is set to a *loader* object.\n' '\n' - ' "__file__"\n' - ' The pathname of the file from which the module was loaded, if ' - 'it\n' - ' was loaded from a file. The "__file__" attribute may be ' - 'missing\n' - ' for certain types of modules, such as C modules that are\n' - ' statically linked into the interpreter. For extension ' + ' It is **strongly** recommended that you use\n' + ' "module.__spec__.loader" instead of "module.__loader__".\n' + '\n' + ' Changed in version 3.4: This attribute now defaults to "None" ' + 'for\n' + ' modules created dynamically using the "types.ModuleType"\n' + ' constructor. Previously the attribute was optional.\n' + '\n' + ' Deprecated since version 3.12, removed in version 3.14: Setting\n' + ' "__loader__" on a module while failing to set "__spec__.loader" ' + 'is\n' + ' deprecated. In Python 3.14, "__loader__" will cease to be set ' + 'or\n' + ' taken into consideration by the import system or the standard\n' + ' library.\n' + '\n' + 'module.__path__\n' + '\n' + ' A (possibly empty) *sequence* of strings enumerating the ' + 'locations\n' + ' where the package’s submodules will be found. Non-package ' 'modules\n' - ' loaded dynamically from a shared library, it’s the pathname ' - 'of\n' - ' the shared library file.\n' + ' should not have a "__path__" attribute. See __path__ attributes ' + 'on\n' + ' modules for more details.\n' '\n' - ' "__annotations__"\n' - ' A dictionary containing *variable annotations* collected ' - 'during\n' - ' module body execution. For best practices on working with\n' - ' "__annotations__", please see Annotations Best Practices.\n' + ' It is **strongly** recommended that you use\n' + ' "module.__spec__.submodule_search_locations" instead of\n' + ' "module.__path__".\n' '\n' - 'Special read-only attribute: "__dict__" is the module’s namespace ' - 'as a\n' - 'dictionary object.\n' + 'module.__file__\n' '\n' - '**CPython implementation detail:** Because of the way CPython ' - 'clears\n' - 'module dictionaries, the module dictionary will be cleared when ' + 'module.__cached__\n' + '\n' + ' "__file__" and "__cached__" are both optional attributes that ' + 'may\n' + ' or may not be set. Both attributes should be a "str" when they ' + 'are\n' + ' available.\n' + '\n' + ' "__file__" indicates the pathname of the file from which the ' + 'module\n' + ' was loaded (if loaded from a file), or the pathname of the ' + 'shared\n' + ' library file for extension modules loaded dynamically from a ' + 'shared\n' + ' library. It might be missing for certain types of modules, such ' + 'as\n' + ' C modules that are statically linked into the interpreter, and ' 'the\n' - 'module falls out of scope even if the dictionary still has live\n' - 'references. To avoid this, copy the dictionary or keep the module\n' - 'around while using its dictionary directly.\n' + ' import system may opt to leave it unset if it has no semantic\n' + ' meaning (for example, a module loaded from a database).\n' + '\n' + ' If "__file__" is set then the "__cached__" attribute might also ' + 'be\n' + ' set, which is the path to any compiled version of the code ' + '(for\n' + ' example, a byte-compiled file). The file does not need to exist ' + 'to\n' + ' set this attribute; the path can simply point to where the ' + 'compiled\n' + ' file *would* exist (see **PEP 3147**).\n' + '\n' + ' Note that "__cached__" may be set even if "__file__" is not ' + 'set.\n' + ' However, that scenario is quite atypical. Ultimately, the ' + '*loader*\n' + ' is what makes use of the module spec provided by the *finder* ' + '(from\n' + ' which "__file__" and "__cached__" are derived). So if a loader ' + 'can\n' + ' load from a cached module but otherwise does not load from a ' + 'file,\n' + ' that atypical scenario may be appropriate.\n' + '\n' + ' It is **strongly** recommended that you use\n' + ' "module.__spec__.cached" instead of "module.__cached__".\n' + '\n' + ' Deprecated since version 3.13, will be removed in version 3.15:\n' + ' Setting "__cached__" on a module while failing to set\n' + ' "__spec__.cached" is deprecated. In Python 3.15, "__cached__" ' + 'will\n' + ' cease to be set or taken into consideration by the import system ' + 'or\n' + ' standard library.\n' + '\n' + '\n' + 'Other writable attributes on module objects\n' + '-------------------------------------------\n' + '\n' + 'As well as the import-related attributes listed above, module ' + 'objects\n' + 'also have the following writable attributes:\n' + '\n' + 'module.__doc__\n' + '\n' + ' The module’s documentation string, or "None" if unavailable. ' + 'See\n' + ' also: "__doc__ attributes".\n' + '\n' + 'module.__annotations__\n' + '\n' + ' A dictionary containing *variable annotations* collected during\n' + ' module body execution. For best practices on working with\n' + ' "__annotations__", see "annotationlib".\n' + '\n' + ' Changed in version 3.14: Annotations are now lazily evaluated. ' + 'See\n' + ' **PEP 649**.\n' + '\n' + 'module.__annotate__\n' + '\n' + ' The *annotate function* for this module, or "None" if the ' + 'module\n' + ' has no annotations. See also: "__annotate__" attributes.\n' + '\n' + ' Added in version 3.14.\n' + '\n' + '\n' + 'Module dictionaries\n' + '-------------------\n' + '\n' + 'Module objects also have the following special read-only ' + 'attribute:\n' + '\n' + 'module.__dict__\n' + '\n' + ' The module’s namespace as a dictionary object. Uniquely among ' + 'the\n' + ' attributes listed here, "__dict__" cannot be accessed as a ' + 'global\n' + ' variable from within a module; it can only be accessed as an\n' + ' attribute on module objects.\n' + '\n' + ' **CPython implementation detail:** Because of the way CPython\n' + ' clears module dictionaries, the module dictionary will be ' + 'cleared\n' + ' when the module falls out of scope even if the dictionary still ' + 'has\n' + ' live references. To avoid this, copy the dictionary or keep ' + 'the\n' + ' module around while using its dictionary directly.\n' '\n' '\n' 'Custom classes\n' @@ -14538,41 +14973,147 @@ 'A class object can be called (see above) to yield a class instance\n' '(see below).\n' '\n' - 'Special attributes:\n' '\n' - ' "__name__"\n' - ' The class name.\n' + 'Special attributes\n' + '------------------\n' '\n' - ' "__module__"\n' - ' The name of the module in which the class was defined.\n' + '+----------------------------------------------------+----------------------------------------------------+\n' + '| Attribute | ' + 'Meaning |\n' + '|====================================================|====================================================|\n' + '| type.__name__ | The class’s ' + 'name. See also: "__name__ attributes". |\n' + '+----------------------------------------------------+----------------------------------------------------+\n' + '| type.__qualname__ | The class’s ' + '*qualified name*. See also: |\n' + '| | ' + '"__qualname__ attributes". |\n' + '+----------------------------------------------------+----------------------------------------------------+\n' + '| type.__module__ | The name of ' + 'the module in which the class was |\n' + '| | ' + 'defined. |\n' + '+----------------------------------------------------+----------------------------------------------------+\n' + '| type.__dict__ | A "mapping ' + 'proxy" providing a read-only view of |\n' + '| | the class’s ' + 'namespace. See also: "__dict__ |\n' + '| | ' + 'attributes". |\n' + '+----------------------------------------------------+----------------------------------------------------+\n' + '| type.__bases__ | A "tuple" ' + 'containing the class’s bases. In most |\n' + '| | cases, for a ' + 'class defined as "class X(A, B, C)", |\n' + '| | ' + '"X.__bases__" will be exactly equal to "(A, B, |\n' + '| | ' + 'C)". |\n' + '+----------------------------------------------------+----------------------------------------------------+\n' + '| type.__doc__ | The class’s ' + 'documentation string, or "None" if |\n' + '| | undefined. ' + 'Not inherited by subclasses. |\n' + '+----------------------------------------------------+----------------------------------------------------+\n' + '| type.__annotations__ | A dictionary ' + 'containing *variable annotations* |\n' + '| | collected ' + 'during class body execution. See also: |\n' + '| | ' + '"__annotations__ attributes". For best practices |\n' + '| | on working ' + 'with "__annotations__", please see |\n' + '| | ' + '"annotationlib". Caution: Accessing the |\n' + '| | ' + '"__annotations__" attribute of a class object |\n' + '| | directly may ' + 'yield incorrect results in the |\n' + '| | presence of ' + 'metaclasses. In addition, the |\n' + '| | attribute ' + 'may not exist for some classes. Use |\n' + '| | ' + '"annotationlib.get_annotations()" to retrieve |\n' + '| | class ' + 'annotations safely. Changed in version |\n' + '| | 3.14: ' + 'Annotations are now lazily evaluated. See |\n' + '| | **PEP ' + '649**. |\n' + '+----------------------------------------------------+----------------------------------------------------+\n' + '| type.__annotate__() | The ' + '*annotate function* for this class, or "None" |\n' + '| | if the class ' + 'has no annotations. See also: |\n' + '| | ' + '"__annotate__ attributes". Caution: Accessing |\n' + '| | the ' + '"__annotate__" attribute of a class object |\n' + '| | directly may ' + 'yield incorrect results in the |\n' + '| | presence of ' + 'metaclasses. Use |\n' + '| | ' + '"annotationlib.get_annotate_function()" to |\n' + '| | retrieve the ' + 'annotate function safely. Added in |\n' + '| | version ' + '3.14. |\n' + '+----------------------------------------------------+----------------------------------------------------+\n' + '| type.__type_params__ | A "tuple" ' + 'containing the type parameters of a |\n' + '| | generic ' + 'class. Added in version 3.12. |\n' + '+----------------------------------------------------+----------------------------------------------------+\n' + '| type.__static_attributes__ | A "tuple" ' + 'containing names of attributes of this |\n' + '| | class which ' + 'are assigned through "self.X" from any |\n' + '| | function in ' + 'its body. Added in version 3.13. |\n' + '+----------------------------------------------------+----------------------------------------------------+\n' + '| type.__firstlineno__ | The line ' + 'number of the first line of the class |\n' + '| | definition, ' + 'including decorators. Setting the |\n' + '| | "__module__" ' + 'attribute removes the |\n' + '| | ' + '"__firstlineno__" item from the type’s dictionary. |\n' + '| | Added in ' + 'version 3.13. |\n' + '+----------------------------------------------------+----------------------------------------------------+\n' + '| type.__mro__ | The "tuple" ' + 'of classes that are considered when |\n' + '| | looking for ' + 'base classes during method resolution. |\n' + '+----------------------------------------------------+----------------------------------------------------+\n' '\n' - ' "__dict__"\n' - ' The dictionary containing the class’s namespace.\n' '\n' - ' "__bases__"\n' - ' A tuple containing the base classes, in the order of their\n' - ' occurrence in the base class list.\n' + 'Special methods\n' + '---------------\n' + '\n' + 'In addition to the special attributes described above, all Python\n' + 'classes also have the following two methods available:\n' '\n' - ' "__doc__"\n' - ' The class’s documentation string, or "None" if undefined.\n' + 'type.mro()\n' '\n' - ' "__annotations__"\n' - ' A dictionary containing *variable annotations* collected ' - 'during\n' - ' class body execution. For best practices on working with\n' - ' "__annotations__", please see Annotations Best Practices.\n' + ' This method can be overridden by a metaclass to customize the\n' + ' method resolution order for its instances. It is called at ' + 'class\n' + ' instantiation, and its result is stored in "__mro__".\n' '\n' - ' "__type_params__"\n' - ' A tuple containing the type parameters of a generic class.\n' + 'type.__subclasses__()\n' '\n' - ' "__static_attributes__"\n' - ' A tuple containing names of attributes of this class which ' - 'are\n' - ' accessed through "self.X" from any function in its body.\n' + ' Each class keeps a list of weak references to its immediate\n' + ' subclasses. This method returns a list of all those references\n' + ' still alive. The list is in definition order. Example:\n' '\n' - ' "__firstlineno__"\n' - ' The line number of the first line of the class definition,\n' - ' including decorators.\n' + ' >>> class A: pass\n' + ' >>> class B(A): pass\n' + ' >>> A.__subclasses__()\n' + " []\n" '\n' '\n' 'Class instances\n' @@ -14612,8 +15153,19 @@ 'they have methods with certain special names. See section Special\n' 'method names.\n' '\n' - 'Special attributes: "__dict__" is the attribute dictionary;\n' - '"__class__" is the instance’s class.\n' + '\n' + 'Special attributes\n' + '------------------\n' + '\n' + 'object.__class__\n' + '\n' + ' The class to which a class instance belongs.\n' + '\n' + 'object.__dict__\n' + '\n' + ' A dictionary or other mapping object used to store an object’s\n' + ' (writable) attributes. Not all instances have a "__dict__"\n' + ' attribute; see the section on __slots__ for more details.\n' '\n' '\n' 'I/O objects (also known as file objects)\n' @@ -14712,14 +15264,20 @@ '| codeobject.co_cellvars | A "tuple" ' 'containing the names of local variables |\n' '| | that are ' - 'referenced by nested functions inside the |\n' - '| | ' - 'function |\n' + 'referenced from at least one *nested |\n' + '| | scope* ' + 'inside the function |\n' '+----------------------------------------------------+----------------------------------------------------+\n' '| codeobject.co_freevars | A "tuple" ' - 'containing the names of free variables |\n' - '| | in the ' - 'function |\n' + 'containing the names of *free (closure) |\n' + '| | variables* ' + 'that a *nested scope* references in an |\n' + '| | outer scope. ' + 'See also "function.__closure__". |\n' + '| | Note: ' + 'references to global and builtin names are |\n' + '| | *not* ' + 'included. |\n' '+----------------------------------------------------+----------------------------------------------------+\n' '| codeobject.co_code | A string ' 'representing the sequence of *bytecode* |\n' @@ -14804,10 +15362,10 @@ ' The iterator returns "tuple"s containing the "(start_line,\n' ' end_line, start_column, end_column)". The *i-th* tuple ' 'corresponds\n' - ' to the position of the source code that compiled to the *i-th*\n' - ' instruction. Column information is 0-indexed utf-8 byte offsets ' - 'on\n' - ' the given source line.\n' + ' to the position of the source code that compiled to the *i-th* ' + 'code\n' + ' unit. Column information is 0-indexed utf-8 byte offsets on the\n' + ' given source line.\n' '\n' ' This positional information can be missing. A non-exhaustive ' 'lists\n' @@ -14932,16 +15490,16 @@ '| | ' '""f_code"". |\n' '+----------------------------------------------------+----------------------------------------------------+\n' - '| frame.f_locals | The ' - 'dictionary used by the frame to look up local |\n' + '| frame.f_locals | The mapping ' + 'used by the frame to look up local |\n' '| | variables. ' - 'If the frame refers to a function or |\n' - '| | ' - 'comprehension, this may return a write- through |\n' - '| | proxy ' - 'object. Changed in version 3.13: Return a |\n' - '| | proxy for ' - 'functions and comprehensions. |\n' + 'If the frame refers to an *optimized |\n' + '| | scope*, this ' + 'may return a write-through proxy |\n' + '| | object. ' + 'Changed in version 3.13: Return a proxy |\n' + '| | for ' + 'optimized scopes. |\n' '+----------------------------------------------------+----------------------------------------------------+\n' '| frame.f_globals | The ' 'dictionary used by the frame to look up global |\n' @@ -15223,21 +15781,23 @@ '\n' ' If no positional argument is given, an empty dictionary ' 'is created.\n' - ' If a positional argument is given and it is a mapping ' - 'object, a\n' - ' dictionary is created with the same key-value pairs as ' - 'the mapping\n' - ' object. Otherwise, the positional argument must be an ' - '*iterable*\n' - ' object. Each item in the iterable must itself be an ' - 'iterable with\n' - ' exactly two objects. The first object of each item ' - 'becomes a key\n' - ' in the new dictionary, and the second object the ' - 'corresponding\n' - ' value. If a key occurs more than once, the last value ' - 'for that key\n' - ' becomes the corresponding value in the new dictionary.\n' + ' If a positional argument is given and it defines a ' + '"keys()" method,\n' + ' a dictionary is created by calling "__getitem__()" on the ' + 'argument\n' + ' with each returned key from the method. Otherwise, the ' + 'positional\n' + ' argument must be an *iterable* object. Each item in the ' + 'iterable\n' + ' must itself be an iterable with exactly two elements. ' + 'The first\n' + ' element of each item becomes a key in the new dictionary, ' + 'and the\n' + ' second element the corresponding value. If a key occurs ' + 'more than\n' + ' once, the last value for that key becomes the ' + 'corresponding value\n' + ' in the new dictionary.\n' '\n' ' If keyword arguments are given, the keyword arguments and ' 'their\n' @@ -15350,7 +15910,7 @@ '\n' ' Return a shallow copy of the dictionary.\n' '\n' - ' classmethod fromkeys(iterable[, value])\n' + ' classmethod fromkeys(iterable, value=None, /)\n' '\n' ' Create a new dictionary with keys from *iterable* and ' 'values set\n' @@ -15366,7 +15926,7 @@ 'distinct\n' ' values, use a dict comprehension instead.\n' '\n' - ' get(key[, default])\n' + ' get(key, default=None)\n' '\n' ' Return the value for *key* if *key* is in the ' 'dictionary, else\n' @@ -15418,7 +15978,7 @@ '\n' ' Added in version 3.8.\n' '\n' - ' setdefault(key[, default])\n' + ' setdefault(key, default=None)\n' '\n' ' If *key* is in the dictionary, return its value. If ' 'not, insert\n' @@ -15432,15 +15992,17 @@ '*other*,\n' ' overwriting existing keys. Return "None".\n' '\n' - ' "update()" accepts either another dictionary object or ' - 'an\n' - ' iterable of key/value pairs (as tuples or other ' - 'iterables of\n' - ' length two). If keyword arguments are specified, the ' - 'dictionary\n' - ' is then updated with those key/value pairs: ' - '"d.update(red=1,\n' - ' blue=2)".\n' + ' "update()" accepts either another object with a ' + '"keys()" method\n' + ' (in which case "__getitem__()" is called with every ' + 'key returned\n' + ' from the method). or an iterable of key/value pairs ' + '(as tuples\n' + ' or other iterables of length two). If keyword ' + 'arguments are\n' + ' specified, the dictionary is then updated with those ' + 'key/value\n' + ' pairs: "d.update(red=1, blue=2)".\n' '\n' ' values()\n' '\n' @@ -16105,8 +16667,8 @@ '| | also removes it from ' '*s* | |\n' '+--------------------------------+----------------------------------+-----------------------+\n' - '| "s.remove(x)" | remove the first item from ' - '*s* | (3) |\n' + '| "s.remove(x)" | removes the first item from ' + '*s* | (3) |\n' '| | where "s[i]" is equal to ' '*x* | |\n' '+--------------------------------+----------------------------------+-----------------------+\n' @@ -16118,7 +16680,9 @@ '\n' 'Notes:\n' '\n' - '1. *t* must have the same length as the slice it is replacing.\n' + '1. If *k* is not equal to "1", *t* must have the same length as ' + 'the\n' + ' slice it is replacing.\n' '\n' '2. The optional argument *i* defaults to "-1", so that by ' 'default the\n' @@ -16475,7 +17039,7 @@ '\n' ' * The linspace recipe shows how to implement a lazy version of ' 'range\n' - ' suitable for floating point applications.\n', + ' suitable for floating-point applications.\n', 'typesseq-mutable': 'Mutable Sequence Types\n' '**********************\n' '\n' @@ -16568,8 +17132,8 @@ '| | also removes it from ' '*s* | |\n' '+--------------------------------+----------------------------------+-----------------------+\n' - '| "s.remove(x)" | remove the first item ' - 'from *s* | (3) |\n' + '| "s.remove(x)" | removes the first ' + 'item from *s* | (3) |\n' '| | where "s[i]" is equal ' 'to *x* | |\n' '+--------------------------------+----------------------------------+-----------------------+\n' @@ -16582,8 +17146,9 @@ '\n' 'Notes:\n' '\n' - '1. *t* must have the same length as the slice it is ' - 'replacing.\n' + '1. If *k* is not equal to "1", *t* must have the same ' + 'length as the\n' + ' slice it is replacing.\n' '\n' '2. The optional argument *i* defaults to "-1", so that ' 'by default the\n' diff --git a/Misc/NEWS.d/3.14.0a1.rst b/Misc/NEWS.d/3.14.0a1.rst new file mode 100644 index 00000000000000..dfc33812611185 --- /dev/null +++ b/Misc/NEWS.d/3.14.0a1.rst @@ -0,0 +1,6604 @@ +.. date: 2024-09-24-10-48-46 +.. gh-issue: 124448 +.. nonce: bFMrS6 +.. release date: 2024-10-15 +.. section: macOS + +Update bundled Tcl/Tk in macOS installer to 8.6.15. + +.. + +.. date: 2024-09-07-12-14-54 +.. gh-issue: 123797 +.. nonce: yFDeug +.. section: macOS + +Check for runtime availability of ``ptsname_r`` function on macos. + +.. + +.. date: 2024-09-04-11-55-29 +.. gh-issue: 123418 +.. nonce: 8P4bmN +.. section: macOS + +Updated macOS installer build to use OpenSSL 3.0.15. + +.. + +.. date: 2024-09-27-15-07-30 +.. gh-issue: 124487 +.. nonce: 7LrwHC +.. section: Windows + +Increases Windows required OS and API level to Windows 10. + +.. + +.. date: 2024-09-27-13-40-25 +.. gh-issue: 124609 +.. nonce: WaKk8G +.. section: Windows + +Fix ``_Py_ThreadId`` for Windows builds using MinGW. Patch by Tony Roberts. + +.. + +.. date: 2024-09-24-19-04-56 +.. gh-issue: 124448 +.. nonce: srVT3d +.. section: Windows + +Updated bundled Tcl/Tk to 8.6.15. + +.. + +.. date: 2024-09-20-11-18-50 +.. gh-issue: 124254 +.. nonce: iPin-L +.. section: Windows + +Ensures experimental free-threaded binaries remain installed when updating. + +.. + +.. date: 2024-09-10-19-23-00 +.. gh-issue: 123915 +.. nonce: yZMEDO +.. section: Windows + +Ensure that ``Tools\msi\buildrelease.bat`` uses different directories for +AMD64 and ARM64 builds. + +.. + +.. date: 2024-09-04-09-59-18 +.. gh-issue: 123418 +.. nonce: QaMC12 +.. section: Windows + +Updated Windows build to use OpenSSL 3.0.15. + +.. + +.. date: 2024-08-29-16-13-45 +.. gh-issue: 123476 +.. nonce: m2DFS4 +.. section: Windows + +Add support for ``socket.TCP_QUICKACK`` on Windows platforms. + +.. + +.. date: 2024-08-01-10-55-15 +.. gh-issue: 122573 +.. nonce: 4-UCFY +.. section: Windows + +The Windows build of CPython now requires 3.10 or newer. + +.. + +.. date: 2024-07-19-21-50-54 +.. gh-issue: 100256 +.. nonce: GDrKba +.. section: Windows + +:mod:`mimetypes` no longer fails when it encounters an inaccessible registry +key. + +.. + +.. date: 2024-05-30-17-39-25 +.. gh-issue: 119679 +.. nonce: mZC87w +.. section: Windows + +Ensures correct import libraries are included in Windows installs. + +.. + +.. date: 2024-05-29-11-06-12 +.. gh-issue: 119690 +.. nonce: 8q6e1p +.. section: Windows + +Adds Unicode support and fixes audit events for ``_winapi.CreateNamedPipe``. + +.. + +.. date: 2024-05-25-18-43-10 +.. gh-issue: 111201 +.. nonce: SLPJIx +.. section: Windows + +Add support for new pyrepl on Windows + +.. + +.. date: 2024-05-22-19-43-29 +.. gh-issue: 119070 +.. nonce: _enton +.. section: Windows + +Fixes ``py.exe`` handling of shebangs like ``/usr/bin/env python3.12``, +which were previously interpreted as ``python3.exe`` instead of +``python3.12.exe``. + +.. + +.. date: 2024-04-24-22-50-33 +.. gh-issue: 117505 +.. nonce: gcTb_p +.. section: Windows + +Fixes an issue with the Windows installer not running ensurepip in a fully +isolated environment. This could cause unexpected interactions with the user +site-packages. + +.. + +.. date: 2024-04-24-05-16-32 +.. gh-issue: 118209 +.. nonce: Ryyzlz +.. section: Windows + +Avoid crashing in :mod:`mmap` on Windows when the mapped memory is +inaccessible due to file system errors or access violations. + +.. + +.. date: 2022-04-20-18-32-30 +.. gh-issue: 79846 +.. nonce: Vggv3f +.. section: Windows + +Makes :code:`ssl.create_default_context()` ignore invalid certificates in +the Windows certificate store + +.. + +.. date: 2024-09-04-10-07-51 +.. gh-issue: 123418 +.. nonce: 1eIFZb +.. section: Tools/Demos + +Update GitHub CI workflows to use OpenSSL 3.0.15 and multissltests to use +3.0.15, 3.1.7, and 3.2.3. + +.. + +.. date: 2024-10-07-14-13-38 +.. gh-issue: 125041 +.. nonce: PKLWDf +.. section: Tests + +Re-enable skipped tests for :mod:`zlib` on the s390x architecture: only skip +checks of the compressed bytes, which can be different between zlib's +software implementation and the hardware-accelerated implementation. + +.. + +.. date: 2024-09-25-12-39-34 +.. gh-issue: 124378 +.. nonce: Ywwgia +.. section: Tests + +Updated ``test_ttk`` to pass with Tcl/Tk 8.6.15. + +.. + +.. date: 2024-09-18-18-39-21 +.. gh-issue: 124213 +.. nonce: AQq_xg +.. section: Tests + +Detect whether the test suite is running inside a systemd-nspawn container +with ``--suppress-sync=true`` option, and skip the ``test_os`` and +``test_mmap`` tests that are failing in this scenario. + +.. + +.. date: 2024-09-17-22-21-58 +.. gh-issue: 124190 +.. nonce: 3fWhiX +.. section: Tests + +Add capability to ignore entire files or directories in check warning CI +tool + +.. + +.. date: 2024-07-17-08-25-06 +.. gh-issue: 121921 +.. nonce: HW8CIS +.. section: Tests + +Update ``Lib/test/crashers/bogus_code_obj.py`` so that it crashes properly +again. + +.. + +.. date: 2024-07-13-21-55-58 +.. gh-issue: 112301 +.. nonce: YJS1dl +.. section: Tests + +Add tooling to check for changes in compiler warnings. Patch by Nate Ohlson. + +.. + +.. date: 2024-07-13-11-48-20 +.. gh-issue: 59022 +.. nonce: fYNbQ8 +.. section: Tests + +Add tests for :func:`pkgutil.extend_path`. Patch by Andreas Stocker. + +.. + +.. date: 2024-07-13-11-04-44 +.. gh-issue: 99242 +.. nonce: aGxnwz +.. section: Tests + +:func:`os.getloadavg` may throw :exc:`OSError` when running regression tests +under certain conditions (e.g. chroot). This error is now caught and +ignored, since reporting load average is optional. + +.. + +.. date: 2024-07-04-15-10-29 +.. gh-issue: 121084 +.. nonce: qxcd5d +.. section: Tests + +Fix test_typing random leaks. Clear typing ABC caches when running tests for +refleaks (``-R`` option): call ``_abc_caches_clear()`` on typing abstract +classes and their subclasses. Patch by Victor Stinner. + +.. + +.. date: 2024-07-03-14-41-00 +.. gh-issue: 121160 +.. nonce: LEtiTd +.. section: Tests + +Add a test for :func:`readline.set_history_length`. Note that this test may +fail on readline libraries. + +.. + +.. date: 2024-07-01-16-15-06 +.. gh-issue: 121200 +.. nonce: 4Pc-gc +.. section: Tests + +Fix ``test_expanduser_pwd2()`` of ``test_posixpath``. Call ``getpwnam()`` +to get ``pw_dir``, since it can be different than ``getpwall()`` ``pw_dir``. +Patch by Victor Stinner. + +.. + +.. date: 2024-07-01-09-04-32 +.. gh-issue: 121188 +.. nonce: XbuTVa +.. section: Tests + +When creating the JUnit XML file, regrtest now escapes characters which are +invalid in XML, such as the chr(27) control character used in ANSI escape +sequences. Patch by Victor Stinner. + +.. + +.. date: 2024-06-20-12-51-26 +.. gh-issue: 120801 +.. nonce: lMVXC9 +.. section: Tests + +Cleaned up fixtures for importlib.metadata tests and consolidated behavior +with 'test.support.os_helper'. + +.. + +.. date: 2024-05-29-15-28-08 +.. gh-issue: 119727 +.. nonce: dVkaZM +.. section: Tests + +Add ``--single-process`` command line option to Python test runner +(regrtest). Patch by Victor Stinner. + +.. + +.. date: 2024-05-20-18-06-31 +.. gh-issue: 119273 +.. nonce: hf-yhX +.. section: Tests + +Python test runner no longer runs tests using TTY (ex: test_ioctl) in a +process group (using ``setsid()``). Previously, tests using TTY were +skipped. Patch by Victor Stinner. + +.. + +.. date: 2024-05-18-10-59-27 +.. gh-issue: 119050 +.. nonce: g4qiH7 +.. section: Tests + +regrtest test runner: Add XML support to the refleak checker (-R option). +Patch by Victor Stinner. + +.. + +.. date: 2024-05-04-22-56-41 +.. gh-issue: 101525 +.. nonce: LHK166 +.. section: Tests + +Skip ``test_gdb`` if the binary is relocated by BOLT. Patch by Donghee Na. + +.. + +.. date: 2023-08-03-17-26-55 +.. gh-issue: 107562 +.. nonce: ZnbscS +.. section: Tests + +Test certificates have been updated to expire far in the future. This allows +testing Y2038 with system time set to after that, so that actual Y2038 +issues can be exposed, and not masked by expired certificate errors. + +.. + +.. date: 2024-10-09-20-08-13 +.. gh-issue: 125140 +.. nonce: YgNWRB +.. section: Security + +Remove the current directory from ``sys.path`` when using PyREPL. + +.. + +.. date: 2024-09-04-12-41-35 +.. gh-issue: 123678 +.. nonce: N41y9n +.. section: Security + +Upgrade libexpat to 2.6.3 + +.. + +.. date: 2024-08-14-19-43-57 +.. gh-issue: 112301 +.. nonce: IQUcOy +.. section: Security + +Enable compiler options that warn of potential security vulnerabilities. + +.. + +.. date: 2024-08-07-10-42-13 +.. gh-issue: 122792 +.. nonce: oiTMo9 +.. section: Security + +Changed IPv4-mapped ``ipaddress.IPv6Address`` to consistently use the mapped +IPv4 address value for deciding properties. Properties which have their +behavior fixed are ``is_multicast``, ``is_reserved``, ``is_link_local``, +``is_global``, and ``is_unspecified``. + +.. + +.. date: 2024-08-06-00-06-23 +.. gh-issue: 112301 +.. nonce: 4k4lw6 +.. section: Security + +Add ability to ignore warnings per file with warning count in warning +checking tooling. Patch by Nate Ohlson. + +.. + +.. date: 2024-07-24-05-18-25 +.. gh-issue: 112301 +.. nonce: lfINgZ +.. section: Security + +Add macOS warning tracking to warning check tooling. Patch by Nate Ohlson. + +.. + +.. date: 2024-07-22-13-11-28 +.. gh-issue: 122133 +.. nonce: 0mPeta +.. section: Security + +Authenticate the socket connection for the ``socket.socketpair()`` fallback +on platforms where ``AF_UNIX`` is not available like Windows. + +Patch by Gregory P. Smith and Seth Larson +. Reported by Ellie + +.. + +.. date: 2024-07-18-13-17-47 +.. gh-issue: 121957 +.. nonce: QemKLU +.. section: Security + +Fixed missing audit events around interactive use of Python, now also +properly firing for ``python -i``, as well as for ``python -m asyncio``. The +events in question are ``cpython.run_stdin`` and ``cpython.run_startup``. + +.. + +.. date: 2024-07-08-23-39-04 +.. gh-issue: 112301 +.. nonce: TD8G01 +.. section: Security + +Enable runtime protections for glibc to abort execution when unsafe behavior +is encountered, for all platforms except Windows. + +.. + +.. date: 2024-07-02-13-39-20 +.. gh-issue: 121285 +.. nonce: hrl-yI +.. section: Security + +Remove backtracking from tarfile header parsing for ``hdrcharset``, PAX, and +GNU sparse headers. + +.. + +.. date: 2024-06-25-04-42-43 +.. gh-issue: 112301 +.. nonce: god4IC +.. section: Security + +Add default compiler options to improve security. Enable +-Wimplicit-fallthrough, -fstack-protector-strong, -Wtrampolines. + +.. + +.. date: 2024-05-08-21-59-38 +.. gh-issue: 118773 +.. nonce: 7dFRJY +.. section: Security + +Fixes creation of ACLs in :func:`os.mkdir` on Windows to work correctly on +non-English machines. + +.. + +.. date: 2024-05-01-20-57-09 +.. gh-issue: 118486 +.. nonce: K44KJG +.. section: Security + +:func:`os.mkdir` on Windows now accepts *mode* of ``0o700`` to restrict the +new directory to the current user. This fixes :cve:`2024-4030` affecting +:func:`tempfile.mkdtemp` in scenarios where the base temporary directory is +more permissive than the default. + +.. + +.. date: 2024-10-14-04-44-12 +.. gh-issue: 125422 +.. nonce: MlVuC6 +.. section: Library + +Fixed the bug where :mod:`pdb` and :mod:`bdb` can step into the bottom +caller frame. + +.. + +.. date: 2024-10-14-02-27-03 +.. gh-issue: 100141 +.. nonce: NuAcwa +.. section: Library + +Fixed the bug where :mod:`pdb` will be stuck in an infinite loop when +debugging an empty file. + +.. + +.. date: 2024-10-13-20-21-35 +.. gh-issue: 53203 +.. nonce: Rz1c8A +.. section: Library + +Fix :func:`time.strptime` for ``%c``, ``%x`` and ``%X`` formats in many +locales that use non-ASCII digits, like Persian, Burmese, Odia and Shan. + +.. + +.. date: 2024-10-11-18-03-05 +.. gh-issue: 125206 +.. nonce: pWRRK6 +.. section: Library + +Workaround for old libffi versions is added. Module ctypes supports +:c:expr:`double complex` only with libffi >= 3.3.0. Patch by Mikhail Efimov. + +.. + +.. date: 2024-10-11-16-19-46 +.. gh-issue: 89967 +.. nonce: vhWUOR +.. section: Library + +Make :class:`~weakref.WeakKeyDictionary` and +:class:`~weakref.WeakValueDictionary` safe against concurrent mutations from +other threads. Patch by Kumar Aditya. + +.. + +.. date: 2024-10-11-04-04-38 +.. gh-issue: 125260 +.. nonce: PeZ0Mb +.. section: Library + +The :func:`gzip.compress` *mtime* parameter now defaults to 0 for +reproducible output. Patch by Bernhard M. Wiedemann and Adam Turner. + +.. + +.. date: 2024-10-10-20-39-57 +.. gh-issue: 125243 +.. nonce: eUbbtu +.. section: Library + +Fix data race when creating :class:`zoneinfo.ZoneInfo` objects in the free +threading build. + +.. + +.. date: 2024-10-10-19-57-35 +.. gh-issue: 125254 +.. nonce: RtZxXS +.. section: Library + +Fix a bug where ArgumentError includes the incorrect ambiguous option in +:mod:`argparse`. + +.. + +.. date: 2024-10-10-18-33-31 +.. gh-issue: 125235 +.. nonce: 0kOB5I +.. section: Library + +Keep :mod:`tkinter` TCL paths in venv pointing to base installation on +Windows. + +.. + +.. date: 2024-10-09-21-42-43 +.. gh-issue: 61011 +.. nonce: pQXZb1 +.. section: Library + +Fix inheritance of nested mutually exclusive groups from parent parser in +:class:`argparse.ArgumentParser`. Previously, all nested mutually exclusive +groups lost their connection to the group containing them and were displayed +as belonging directly to the parser. + +.. + +.. date: 2024-10-09-07-09-00 +.. gh-issue: 125118 +.. nonce: J9rQ1S +.. section: Library + +Don't copy arbitrary values to :c:expr:`_Bool` in the :mod:`struct` module. + +.. + +.. date: 2024-10-08-21-17-16 +.. gh-issue: 125069 +.. nonce: 0RP0Mx +.. section: Library + +Fix an issue where providing a :class:`pathlib.PurePath` object as an +initializer argument to a second :class:`~pathlib.PurePath` object with a +different :attr:`~pathlib.PurePath.parser` resulted in arguments to the +former object's initializer being joined by the latter object's parser. + +.. + +.. date: 2024-10-08-13-28-22 +.. gh-issue: 125096 +.. nonce: Vz0W5g +.. section: Library + +If the :envvar:`PYTHON_BASIC_REPL` environment variable is set, the +:mod:`site` module no longer imports the :mod:`!_pyrepl` module. Moreover, +the :mod:`site` module now respects :option:`-E` and :option:`-I` command +line options: ignore :envvar:`PYTHON_BASIC_REPL` in this case. Patch by +Victor Stinner. + +.. + +.. date: 2024-10-08-12-09-09 +.. gh-issue: 124969 +.. nonce: _VBQLq +.. section: Library + +Fix ``locale.nl_langinfo(locale.ALT_DIGITS)``. Now it returns a tuple of up +to 100 strings (an empty tuple on most locales). Previously it returned the +first item of that tuple or an empty string. + +.. + +.. date: 2024-10-05-15-49-53 +.. gh-issue: 124960 +.. nonce: Bol9hT +.. section: Library + +Fix support for the ``barry_as_FLUFL`` future flag in the new REPL. + +.. + +.. date: 2024-10-04-12-43-03 +.. gh-issue: 69998 +.. nonce: DVqOXX +.. section: Library + +Fix :func:`locale.nl_langinfo` in case when different categories have +different locales. The function now sets temporarily the ``LC_CTYPE`` locale +in some cases. This temporary change affects other threads. + +.. + +.. date: 2024-10-04-08-46-00 +.. gh-issue: 124958 +.. nonce: rea9-x +.. section: Library + +Fix refcycles in exceptions raised from :class:`asyncio.TaskGroup` and the +python implementation of :class:`asyncio.Future` + +.. + +.. date: 2024-10-03-20-45-57 +.. gh-issue: 53203 +.. nonce: 3Sk4Ia +.. section: Library + +Fix :func:`time.strptime` for ``%c`` and ``%x`` formats in many locales: +Arabic, Bislama, Breton, Bodo, Kashubian, Chuvash, Estonian, French, Irish, +Ge'ez, Gurajati, Manx Gaelic, Hebrew, Hindi, Chhattisgarhi, Haitian Kreyol, +Japanese, Kannada, Korean, Marathi, Malay, Norwegian, Nynorsk, Punjabi, +Rajasthani, Tok Pisin, Yoruba, Yue Chinese, Yau/Nungon and Chinese. + +.. + +.. date: 2024-10-03-19-16-38 +.. gh-issue: 123961 +.. nonce: ik1Dgs +.. section: Library + +Convert :mod:`curses` to multi-phase initialization (:pep:`489`), thereby +fixing reference leaks at interpreter shutdown. Patch by Bénédikt Tran. + +.. + +.. date: 2024-10-03-17-13-22 +.. gh-issue: 124944 +.. nonce: YyLAzf +.. section: Library + +Add ``SO_ORIGINAL_DST`` to the :mod:`socket` module. + +.. + +.. date: 2024-10-03-05-00-25 +.. gh-issue: 117151 +.. nonce: Prdw_W +.. section: Library + +The default buffer size used by :func:`shutil.copyfileobj` has been +increased from 64k to 256k on non-Windows platforms. It was already larger +on Windows. + +.. + +.. date: 2024-10-02-22-53-48 +.. gh-issue: 90102 +.. nonce: 4qX52R +.. section: Library + +Skip the ``isatty`` system call during open() when the file is known to not +be a character device. This provides a slight performance improvement when +reading whole files. + +.. + +.. date: 2024-10-02-21-11-18 +.. gh-issue: 124917 +.. nonce: Lnwh5b +.. section: Library + +Allow calling :func:`os.path.exists` and :func:`os.path.lexists` with +keyword arguments on Windows. Fixes a regression in 3.13.0. + +.. + +.. date: 2024-10-02-16-35-07 +.. gh-issue: 65865 +.. nonce: S2D4wq +.. section: Library + +:mod:`argparse` now raises early error for invalid ``help`` arguments to +:meth:`~argparse.ArgumentParser.add_argument`, +:meth:`~argparse.ArgumentParser.add_subparsers` and :meth:`!add_parser`. + +.. + +.. date: 2024-10-02-15-05-45 +.. gh-issue: 124653 +.. nonce: tqsTu9 +.. section: Library + +Fix detection of the minimal Queue API needed by the :mod:`logging` module. +Patch by Bénédikt Tran. + +.. + +.. date: 2024-10-01-23-29-09 +.. gh-issue: 91818 +.. nonce: Kz8cPI +.. section: Library + +The CLI of many modules (:mod:`ast`, :mod:`ensurepip`, :mod:`json`, +:mod:`pdb`, :mod:`sqlite3`, :mod:`tokenize`, :mod:`venv`) now uses the +actual executable name instead of simply "python" to display in the usage +message. + +.. + +.. date: 2024-10-01-17-12-20 +.. gh-issue: 124858 +.. nonce: Zy0tvT +.. section: Library + +Fix reference cycles left in tracebacks in :func:`asyncio.open_connection` +when used with ``happy_eyeballs_delay`` + +.. + +.. date: 2024-10-01-13-46-58 +.. gh-issue: 124390 +.. nonce: dK1Zcm +.. section: Library + +Fixed :exc:`AssertionError` when using +:func:`!asyncio.staggered.staggered_race` with +:attr:`asyncio.eager_task_factory`. + +.. + +.. date: 2024-10-01-13-11-53 +.. gh-issue: 85935 +.. nonce: CTwJUy +.. section: Library + +:meth:`argparse.ArgumentParser.add_argument` now raises an exception if an +:ref:`action` that does not consume arguments (like 'store_const' or +'store_true') or explicit ``nargs=0`` are specified for positional +arguments. + +.. + +.. date: 2024-10-01-12-43-42 +.. gh-issue: 124835 +.. nonce: SVyp3K +.. section: Library + +Make :func:`tomllib.loads` raise :exc:`TypeError` not :exc:`AttributeError` +on bad input types that do not have the ``replace`` attribute. Improve error +message when :class:`bytes` is received. + +.. + +.. date: 2024-10-01-02-31-13 +.. gh-issue: 124693 +.. nonce: qzbXKB +.. section: Library + +Fix a bug where :mod:`argparse` doesn't recognize negative complex numbers +or negative numbers using scientific notation. + +.. + +.. date: 2024-09-30-20-46-32 +.. gh-issue: 124787 +.. nonce: 3FnJnP +.. section: Library + +Fix :class:`typing.TypeAliasType` with incorrect ``type_params`` argument. +Now it raises a :exc:`TypeError` when a type parameter without a default +follows one with a default, and when an entry in the ``type_params`` tuple +is not a type parameter object. + +.. + +.. date: 2024-09-30-19-59-28 +.. gh-issue: 66436 +.. nonce: 4gYN_n +.. section: Library + +Improved :ref:`prog` default value for :class:`argparse.ArgumentParser`. It +will now include the name of the Python executable along with the module or +package name, or the path to a directory, ZIP file, or directory within a +ZIP file if the code was run that way. + +.. + +.. date: 2024-09-27-15-16-04 +.. gh-issue: 116850 +.. nonce: dBkR0- +.. section: Library + +Fix :mod:`argparse` for namespaces with not directly writable dict (e.g. +classes). + +.. + +.. date: 2024-09-27-06-39-32 +.. gh-issue: 101552 +.. nonce: xYkzag +.. section: Library + +Add an *annoation_format* parameter to :func:`inspect.signature`. Add an +*quote_annotation_strings* parameter to :meth:`inspect.Signature.format`. +Use the new functionality to improve the display of annotations in +signatures in :mod:`pydoc`. Patch by Jelle Zijlstra. + +.. + +.. date: 2024-09-26-22-14-12 +.. gh-issue: 58573 +.. nonce: hozbm9 +.. section: Library + +Fix conflicts between abbreviated long options in the parent parser and +subparsers in :mod:`argparse`. + +.. + +.. date: 2024-09-26-13-43-39 +.. gh-issue: 124594 +.. nonce: peYhsP +.. section: Library + +All :mod:`asyncio` REPL prompts run in the same :class:`context +`. Contributed by Bartosz Sławecki. + +.. + +.. date: 2024-09-26-09-18-09 +.. gh-issue: 61181 +.. nonce: dwjmch +.. section: Library + +Fix support of :ref:`choices` with string value in :mod:`argparse`. +Substrings of the specified string no longer considered valid values. + +.. + +.. date: 2024-09-26-00-35-24 +.. gh-issue: 116750 +.. nonce: X1aMHI +.. section: Library + +Provide :func:`sys.monitoring.clear_tool_id` to unregister all events and +callbacks set by the tool. + +.. + +.. date: 2024-09-25-22-06-52 +.. gh-issue: 124552 +.. nonce: 1nQKNM +.. section: Library + +Improve the accuracy of :mod:`bdb`'s check for the possibility of breakpoint +in a frame. This makes it possible to disable unnecessary events in +functions. + +.. + +.. date: 2024-09-25-18-34-48 +.. gh-issue: 124538 +.. nonce: nXZk4R +.. section: Library + +Fixed crash when using :func:`gc.get_referents` on a capsule object. + +.. + +.. date: 2024-09-25-18-08-29 +.. gh-issue: 80259 +.. nonce: kO5Tw7 +.. section: Library + +Fix :mod:`argparse` support of positional arguments with ``nargs='?'``, +``default=argparse.SUPPRESS`` and specified ``type``. + +.. + +.. date: 2024-09-25-18-07-51 +.. gh-issue: 120378 +.. nonce: NlBSz_ +.. section: Library + +Fix a crash related to an integer overflow in :func:`curses.resizeterm` and +:func:`curses.resize_term`. + +.. + +.. date: 2024-09-25-12-14-58 +.. gh-issue: 124498 +.. nonce: Ozxs55 +.. section: Library + +Fix :class:`typing.TypeAliasType` not to be generic, when ``type_params`` is +an empty tuple. + +.. + +.. date: 2024-09-25-10-25-57 +.. gh-issue: 53834 +.. nonce: uyIckw +.. section: Library + +Fix support of arguments with :ref:`choices` in :mod:`argparse`. Positional +arguments with :ref:`nargs` equal to ``'?'`` or ``'*'`` no longer check +:ref:`default` against ``choices``. Optional arguments with ``nargs`` equal +to ``'?'`` no longer check :ref:`const` against ``choices``. + +.. + +.. date: 2024-09-24-22-38-51 +.. gh-issue: 123884 +.. nonce: iEPTK4 +.. section: Library + +Fixed bug in itertools.tee() handling of other tee inputs (a tee in a tee). +The output now has the promised *n* independent new iterators. Formerly, +the first iterator was identical (not independent) to the input iterator. +This would sometimes give surprising results. + +.. + +.. date: 2024-09-24-21-15-27 +.. gh-issue: 123017 +.. nonce: dSAr2f +.. section: Library + +Due to unreliable results on some devices, :func:`time.strftime` no longer +accepts negative years on Android. + +.. + +.. date: 2024-09-24-19-32-14 +.. gh-issue: 123014 +.. nonce: zVcfkZ +.. section: Library + +:func:`os.pidfd_open` and :func:`signal.pidfd_send_signal` are now +unavailable when building against Android API levels older than 31, since +the underlying system calls may cause a crash. + +.. + +.. date: 2024-09-24-13-32-16 +.. gh-issue: 124176 +.. nonce: 6hmOPz +.. section: Library + +Add support for :func:`dataclasses.dataclass` in +:func:`unittest.mock.create_autospec`. Now ``create_autospec`` will check +for potential dataclasses and use :func:`dataclasses.fields` function to +retrieve the spec information. + +.. + +.. date: 2024-09-24-12-34-48 +.. gh-issue: 124345 +.. nonce: s3vKql +.. section: Library + +:mod:`argparse` vim supports abbreviated single-dash long options separated +by ``=`` from its value. + +.. + +.. date: 2024-09-24-00-01-24 +.. gh-issue: 124400 +.. nonce: 0XCgfe +.. section: Library + +Fixed a :mod:`pdb` bug where ``until`` has no effect when it appears in a +``commands`` sequence. Also avoid printing the frame information at a +breakpoint that has a command list containing a command that resumes +execution. + +.. + +.. date: 2024-09-23-18-26-17 +.. gh-issue: 90562 +.. nonce: Yj566G +.. section: Library + +Modify dataclasses to support zero-argument super() when ``slots=True`` is +specified. This works by modifying all references to ``__class__`` to point +to the newly created class. + +.. + +.. date: 2024-09-23-17-33-47 +.. gh-issue: 104860 +.. nonce: O86OSc +.. section: Library + +Fix disallowing abbreviation of single-dash long options in :mod:`argparse` +with ``allow_abbrev=False``. + +.. + +.. date: 2024-09-21-23-56-41 +.. gh-issue: 63143 +.. nonce: YKu-LQ +.. section: Library + +Fix parsing mutually exclusive arguments in :mod:`argparse`. Arguments with +the value identical to the default value (e.g. booleans, small integers, +empty or 1-character strings) are no longer considered "not present". + +.. + +.. date: 2024-09-21-22-32-21 +.. gh-issue: 72795 +.. nonce: naLmkX +.. section: Library + +Positional arguments with :ref:`nargs` equal to ``'*'`` or +:data:`!argparse.REMAINDER` are no longer required. This allows to use +positional argument with ``nargs='*'`` and without ``default`` in mutually +exclusive group and improves error message about required arguments. + +.. + +.. date: 2024-09-21-19-02-37 +.. gh-issue: 59317 +.. nonce: OAhNZZ +.. section: Library + +Fix parsing positional argument with :ref:`nargs` equal to ``'?'`` or +``'*'`` if it is preceded by an option and another positional argument. + +.. + +.. date: 2024-09-20-18-23-19 +.. gh-issue: 100980 +.. nonce: 8nVAB6 +.. section: Library + +The :attr:`~ctypes.Structure._fields_` attribute of +:class:`ctypes.Structure` and :class:`~ctypes.Union` is no longer set if the +setattr operation raises an error. + +.. + +.. date: 2024-09-20-12-23-11 +.. gh-issue: 53780 +.. nonce: mrV1zi +.. section: Library + +:mod:`argparse` now ignores the first ``"--"`` (double dash) between an +option and command. + +.. + +.. date: 2024-09-19-20-15-00 +.. gh-issue: 124217 +.. nonce: j0KlQB +.. section: Library + +Add RFC 9637 reserved IPv6 block ``3fff::/20`` in :mod:`ipaddress` module. + +.. + +.. date: 2024-09-19-16-00-22 +.. gh-issue: 111513 +.. nonce: 6jHm02 +.. section: Library + +Improve the error message that may be raised by +:meth:`datetime.date.fromtimestamp`. + +.. + +.. date: 2024-09-19-11-47-39 +.. gh-issue: 124248 +.. nonce: g7rufd +.. section: Library + +Fixed potential crash when using :mod:`struct` to process zero-width 'Pascal +string' fields (``0p``). + +.. + +.. date: 2024-09-19-10-36-18 +.. gh-issue: 81691 +.. nonce: Hyhp_U +.. section: Library + +Fix handling of multiple ``"--"`` (double dashes) in :mod:`argparse`. Only +the first one has now been removed, all subsequent ones are now taken +literally. + +.. + +.. date: 2024-09-19-03-46-59 +.. gh-issue: 87041 +.. nonce: 9Ox7Bv +.. section: Library + +Fix a bug in :mod:`argparse` where lengthy subparser argument help is +incorrectly indented. + +.. + +.. date: 2024-09-19-00-09-48 +.. gh-issue: 84559 +.. nonce: IrxvQe +.. section: Library + +The default :mod:`multiprocessing` start method on Linux and other POSIX +systems has been changed away from often unsafe ``"fork"`` to +``"forkserver"`` (when the platform supports sending file handles over pipes +as most do) or ``"spawn"``. Mac and Windows are unchanged as they already +default to ``"spawn"``. + +.. + +.. date: 2024-09-18-17-45-52 +.. gh-issue: 124212 +.. nonce: n6kIby +.. section: Library + +Fix invalid variable in :mod:`venv` handling of failed symlink on Windows + +.. + +.. date: 2024-09-17-18-06-42 +.. gh-issue: 124171 +.. nonce: PHCvRJ +.. section: Library + +Add workaround for broken :c:func:`!fmod()` implementations on Windows, that +loose zero sign (e.g. ``fmod(-10, 1)`` returns ``0.0``). Patch by Sergey B +Kirpichev. + +.. + +.. date: 2024-09-16-12-31-48 +.. gh-issue: 123978 +.. nonce: z3smEu +.. section: Library + +Remove broken :func:`time.thread_time` and :func:`time.thread_time_ns` on +NetBSD. + +.. + +.. date: 2024-09-13-10-34-19 +.. gh-issue: 123934 +.. nonce: yMe7mL +.. section: Library + +Fix :class:`unittest.mock.MagicMock` resetting magic methods return values +after ``.reset_mock(return_value=True)`` was called. + +.. + +.. date: 2024-09-12-10-55-19 +.. gh-issue: 124016 +.. nonce: ncs0hd +.. section: Library + +Update :mod:`unicodedata` database to Unicode 16.0.0. + +.. + +.. date: 2024-09-11-19-12-23 +.. gh-issue: 123968 +.. nonce: OwHON_ +.. section: Library + +Fix the command-line interface for the :mod:`random` module to select floats +between 0 and N, not 1 and N. + +.. + +.. date: 2024-09-11-19-05-32 +.. gh-issue: 123945 +.. nonce: jLwybB +.. section: Library + +Fix a bug where :mod:`argparse` doesn't recognize negative numbers with +underscores + +.. + +.. date: 2024-09-11-13-33-19 +.. gh-issue: 123935 +.. nonce: fRZ_56 +.. section: Library + +Fix parent slots detection for dataclasses that inherit from classes with +``__dictoffset__``. + +.. + +.. date: 2024-09-10-11-26-14 +.. gh-issue: 123892 +.. nonce: 2gzIrz +.. section: Library + +Add ``"_wmi"`` to :data:`sys.stdlib_module_names`. Patch by Victor Stinner. + +.. + +.. date: 2024-09-06-10-17-54 +.. gh-issue: 84808 +.. nonce: ION67Z +.. section: Library + +Fix error handling in :py:class:`~socket.socket` method +:py:func:`~socket.socket.connect_ex` on platforms where :c:data:`errno` can +be negative. + +.. + +.. date: 2024-09-06-01-35-11 +.. gh-issue: 123756 +.. nonce: Ozbhke +.. section: Library + +Added a new argument ``mode`` to :class:`pdb.Pdb`. Only allow :mod:`pdb` +from command line to use ``restart`` command. + +.. + +.. date: 2024-09-06-00-00-43 +.. gh-issue: 122765 +.. nonce: tx4hsr +.. section: Library + +Fix unbalanced quote errors occurring when activate.csh in :mod:`venv` was +sourced with a custom prompt containing unpaired quotes or newlines. + +.. + +.. date: 2024-09-04-18-23-43 +.. gh-issue: 123657 +.. nonce: Oks4So +.. section: Library + +Fix crash and memory leak in :func:`decimal.getcontext`. It crashed when +using a thread-local context by ``--with-decimal-contextvar=no``. + +.. + +.. date: 2024-09-02-20-34-04 +.. gh-issue: 123339 +.. nonce: czgcSu +.. section: Library + +Fix :func:`inspect.getsource` for classes in :mod:`collections.abc` and +:mod:`decimal` (for pure Python implementation) modules. +:func:`inspect.getcomments` now raises OSError instead of IndexError if the +``__firstlineno__`` value for a class is out of bound. + +.. + +.. date: 2024-08-31-12-34-44 +.. gh-issue: 123374 +.. nonce: 3kE7rb +.. section: Library + +Remove check for redefined memo entry in :func:`pickletools.dis`. + +.. + +.. date: 2024-08-30-09-01-35 +.. gh-issue: 123504 +.. nonce: lJ9_BB +.. section: Library + +Fixed reference leak in the finalization of :mod:`tkinter`. + +.. + +.. date: 2024-08-29-14-51-36 +.. gh-issue: 123430 +.. nonce: M7wXl9 +.. section: Library + +Pages generated by the :mod:`http.server` module allow the browser to apply +its default dark mode. + +.. + +.. date: 2024-08-29-09-27-12 +.. gh-issue: 123446 +.. nonce: _I_mMr +.. section: Library + +Fix empty function name in :exc:`TypeError` when :func:`csv.reader`, +:func:`csv.writer`, or :func:`csv.register_dialect` are used without the +required args. + +.. + +.. date: 2024-08-28-20-08-19 +.. gh-issue: 123448 +.. nonce: tItJlp +.. section: Library + +Fixed memory leak of :class:`typing.NoDefault` by moving it to the static +types array. + +.. + +.. date: 2024-08-28-13-03-36 +.. gh-issue: 123409 +.. nonce: lW0YF- +.. section: Library + +Fix :attr:`ipaddress.IPv6Address.reverse_pointer` output according to +:rfc:`RFC 3596, §2.5 <3596#section-2.5>`. Patch by Bénédikt Tran. + +.. + +.. date: 2024-08-27-12-38-42 +.. gh-issue: 123089 +.. nonce: vA7iFR +.. section: Library + +Make :class:`weakref.WeakSet` safe against concurrent mutations while it is +being iterated. Patch by Kumar Aditya. + +.. + +.. date: 2024-08-27-12-11-00 +.. gh-issue: 123363 +.. nonce: gKuJp6 +.. section: Library + +Show string value of :opcode:`CONTAINS_OP` oparg in :mod:`dis` output. Patch +by Alexandr153. + +.. + +.. date: 2024-08-27-10-30-37 +.. gh-issue: 123341 +.. nonce: 5e-fjt +.. section: Library + +Add :meth:`~object.__class_getitem__` to :class:`!tkinter.Event` for type +subscript support at runtime. Patch by Adonis Rakateli. + +.. + +.. date: 2024-08-26-19-36-00 +.. gh-issue: 123340 +.. nonce: mQKI1H +.. section: Library + +Show string value of :opcode:`IS_OP` oparg in :mod:`dis` output. + +.. + +.. date: 2024-08-26-18-48-13 +.. gh-issue: 119518 +.. nonce: QFYH9q +.. section: Library + +Speed up normalization of :class:`pathlib.PurePath` and +:class:`~pathlib.Path` objects by not interning string parts. + +.. + +.. date: 2024-08-26-13-45-20 +.. gh-issue: 123270 +.. nonce: gXHvNJ +.. section: Library + +Applied a more surgical fix for malformed payloads in :class:`zipfile.Path` +causing infinite loops (gh-122905) without breaking contents using +legitimate characters. + +.. + +.. date: 2024-08-25-16-59-20 +.. gh-issue: 73991 +.. nonce: 1w8u3K +.. section: Library + +Add :meth:`pathlib.Path.copy_into` and :meth:`~pathlib.Path.move_into`, +which copy and move files and directories into *existing* directories. + +.. + +.. date: 2024-08-24-06-05-41 +.. gh-issue: 123228 +.. nonce: jR_5O5 +.. section: Library + +Fix return type for +:func:`!_pyrepl.readline._ReadlineWrapper.get_line_buffer` to be +:func:`str`. Patch by Sergey B Kirpichev. + +.. + +.. date: 2024-08-24-00-03-01 +.. gh-issue: 123240 +.. nonce: uFPG3l +.. section: Library + +Raise audit events for the :func:`input` in the new REPL. + +.. + +.. date: 2024-08-23-22-01-30 +.. gh-issue: 76960 +.. nonce: vsANPu +.. section: Library + +Fix :func:`urllib.parse.urljoin` and :func:`urllib.parse.urldefrag` for URIs +containing empty components. For example, :func:`!urljoin` with relative +reference "?" now sets empty query and removes fragment. Preserve empty +components (authority, params, query, fragment) in :func:`!urljoin`. +Preserve empty components (authority, params, query) in :func:`!urldefrag`. + +.. + +.. date: 2024-08-23-15-49-10 +.. gh-issue: 116810 +.. nonce: QLBUU8 +.. section: Library + +Resolve a memory leak introduced in CPython 3.10's :mod:`ssl` when the +:attr:`ssl.SSLSocket.session` property was accessed. Speeds up read and +write access to said property by no longer unnecessarily cloning session +objects via serialization. + +.. + +.. date: 2024-08-22-20-10-13 +.. gh-issue: 123243 +.. nonce: Kifj1L +.. section: Library + +Fix memory leak in :mod:`!_decimal`. + +.. + +.. date: 2024-08-22-11-25-19 +.. gh-issue: 122546 +.. nonce: BSmeE7 +.. section: Library + +Consistently use same file name for different exceptions in the new repl. +Patch by Sergey B Kirpichev. + +.. + +.. date: 2024-08-22-09-37-48 +.. gh-issue: 123213 +.. nonce: owmXnP +.. section: Library + +:meth:`xml.etree.ElementTree.Element.extend` and +:class:`~xml.etree.ElementTree.Element` assignment no longer hide the +internal exception if an erroneous generator is passed. Patch by Bar Harel. + +.. + +.. date: 2024-08-20-18-02-27 +.. gh-issue: 85110 +.. nonce: 8_iDQy +.. section: Library + +Preserve relative path in URL without netloc in +:func:`urllib.parse.urlunsplit` and :func:`urllib.parse.urlunparse`. + +.. + +.. date: 2024-08-20-14-22-49 +.. gh-issue: 123165 +.. nonce: vOZZOA +.. section: Library + +Add support for rendering :class:`~dis.Positions` in :mod:`dis`. + +.. + +.. date: 2024-08-19-17-37-18 +.. gh-issue: 122909 +.. nonce: kP12SK +.. section: Library + +In urllib.request when URLError is raised opening an ftp URL, the exception +argument is now consistently a string. Earlier versions passed either a +string or an ftplib exception instance as the argument to URLError. + +.. + +.. date: 2024-08-18-08-25-32 +.. gh-issue: 123084 +.. nonce: rf8izX +.. section: Library + +Deprecate :class:`!shutil.ExecError`, which hasn't been raised by any +:mod:`shutil` function since Python 3.4. It's now an alias for +:exc:`RuntimeError`. + +.. + +.. date: 2024-08-17-08-17-20 +.. gh-issue: 123085 +.. nonce: 7Io2yH +.. section: Library + +In a bare call to :func:`importlib.resources.files`, ensure the caller's +frame is properly detected when ``importlib.resources`` is itself available +as a compiled module only (no source). + +.. + +.. date: 2024-08-16-19-13-21 +.. gh-issue: 123067 +.. nonce: Nx9O4R +.. section: Library + +Fix quadratic complexity in parsing ``"``-quoted cookie values with +backslashes by :mod:`http.cookies`. + +.. + +.. date: 2024-08-16-16-53-52 +.. gh-issue: 123049 +.. nonce: izx_fH +.. section: Library + +Add support for :const:`~configparser.UNNAMED_SECTION` in +:meth:`configparser.ConfigParser.add_section`. + +.. + +.. date: 2024-08-15-09-45-34 +.. gh-issue: 121735 +.. nonce: _1q0qf +.. section: Library + +When working with zip archives, importlib.resources now properly honors +module-adjacent references (e.g. ``files(pkg.mod)`` and not just +``files(pkg)``). + +.. + +.. date: 2024-08-14-10-41-11 +.. gh-issue: 122981 +.. nonce: BHV0Z9 +.. section: Library + +Fix :func:`inspect.getsource` for generated classes with Python base classes +(e.g. enums). + +.. + +.. date: 2024-08-11-14-23-07 +.. gh-issue: 122903 +.. nonce: xktZta +.. section: Library + +``zipfile.Path.glob`` now correctly matches directories instead of silently +omitting them. + +.. + +.. date: 2024-08-11-14-08-04 +.. gh-issue: 122905 +.. nonce: 7tDsxA +.. section: Library + +:class:`zipfile.Path` objects now sanitize names from the zipfile. + +.. + +.. date: 2024-08-10-14-16-59 +.. gh-issue: 122873 +.. nonce: XlHaUn +.. section: Library + +Enable :mod:`json` module to work as a script using the :option:`-m` switch: +``python -m json``. See the :ref:`JSON command-line interface +` documentation. Patch by Trey Hunner. + +.. + +.. date: 2024-08-10-10-21-44 +.. gh-issue: 122858 +.. nonce: ZC1rJD +.. section: Library + +Deprecate :func:`!asyncio.iscoroutinefunction` in favor of +:func:`inspect.iscoroutinefunction`. + +.. + +.. date: 2024-08-07-17-41-16 +.. gh-issue: 116263 +.. nonce: EcXir0 +.. section: Library + +:class:`logging.handlers.RotatingFileHandler` no longer rolls over empty log +files. + +.. + +.. date: 2024-08-07-14-12-19 +.. gh-issue: 105376 +.. nonce: QbGPdE +.. section: Library + +Restore the deprecated :mod:`logging` ``warn()`` method. It was removed in +Python 3.13 alpha 1. Keep the deprecated ``warn()`` method in Python 3.13. +Patch by Victor Stinner. + +.. + +.. date: 2024-08-07-11-57-41 +.. gh-issue: 122311 +.. nonce: LDExnJ +.. section: Library + +Improve errors in the :mod:`pickle` module. :exc:`~pickle.PicklingError` is +now raised more often instead of :exc:`UnicodeEncodeError`, +:exc:`ValueError` and :exc:`AttributeError`, and the original exception is +chained to it. Improve and unify error messages in Python and C +implementations. + +.. + +.. date: 2024-08-06-18-07-19 +.. gh-issue: 122744 +.. nonce: kCzNDI +.. section: Library + +Bump the version of pip bundled in ensurepip to version 24.2. + +.. + +.. date: 2024-08-06-10-36-55 +.. gh-issue: 118761 +.. nonce: q_x_1A +.. section: Library + +Improve import time of :mod:`pprint` by around seven times. Patch by Hugo +van Kemenade. + +.. + +.. date: 2024-08-06-07-24-00 +.. gh-issue: 118974 +.. nonce: qamsCQ +.. section: Library + +Add ``decorator`` parameter to :func:`dataclasses.make_dataclass` to +customize the functional creation of dataclasses. + +.. + +.. date: 2024-08-04-14-07-18 +.. gh-issue: 118814 +.. nonce: uiyks1 +.. section: Library + +Fix the :class:`typing.TypeVar` constructor when name is passed by keyword. + +.. + +.. date: 2024-08-03-06-51-08 +.. gh-issue: 122637 +.. nonce: gpas8J +.. section: Library + +Adjust ``cmath.tanh(nanj)`` and ``cmath.tanh(infj)`` for recent C standards. + +.. + +.. date: 2024-07-31-20-43-21 +.. gh-issue: 122478 +.. nonce: sCU2Le +.. section: Library + +Remove internal frames from tracebacks shown in +:class:`code.InteractiveInterpreter` with non-default +:func:`sys.excepthook`. Save correct tracebacks in +:attr:`sys.last_traceback` and update ``__traceback__`` attribute of +:attr:`sys.last_value` and :attr:`sys.last_exc`. + +.. + +.. date: 2024-07-31-15-08-42 +.. gh-issue: 116622 +.. nonce: aKxIQA +.. section: Library + +On Android, the ``FICLONE`` and ``FICLONERANGE`` constants are no longer +exposed by :mod:`fcntl`, as these ioctls are blocked by SELinux. + +.. + +.. date: 2024-07-31-14-55-41 +.. gh-issue: 82378 +.. nonce: eZvYmR +.. section: Library + +Make sure that the new :term:`REPL` interprets :data:`sys.tracebacklimit` in +the same way that the classic REPL did. + +.. + +.. date: 2024-07-30-21-29-30 +.. gh-issue: 122334 +.. nonce: LeoE1x +.. section: Library + +Fix crash when importing :mod:`ssl` after the main interpreter restarts. + +.. + +.. date: 2024-07-30-15-57-07 +.. gh-issue: 122459 +.. nonce: AYIoeN +.. section: Library + +Optimize :mod:`pickling ` by name objects without the ``__module__`` +attribute. + +.. + +.. date: 2024-07-30-14-46-16 +.. gh-issue: 87320 +.. nonce: -Yk1wb +.. section: Library + +In :class:`code.InteractiveInterpreter`, handle exceptions caused by calling +a non-default :func:`sys.excepthook`. Before, the exception bubbled up to +the caller, ending the :term:`REPL`. + +.. + +.. date: 2024-07-30-04-27-55 +.. gh-issue: 122272 +.. nonce: 6Wwa1V +.. section: Library + +On some platforms such as Linux, year with century was not 0-padded when +formatted by :meth:`~.datetime.strftime` with C99-specific specifiers +``'%C'`` or ``'%F'``. The 0-padding behavior is now guaranteed when the +format specifiers ``'%C'`` and ``'%F'`` are supported by the C library. +Patch by Ben Hsing + +.. + +.. date: 2024-07-29-16-47-08 +.. gh-issue: 122400 +.. nonce: fM0YSv +.. section: Library + +Handle :exc:`ValueError`\s raised by :func:`os.stat` in +:class:`filecmp.dircmp` and :func:`filecmp.cmpfiles`. Patch by Bénédikt +Tran. + +.. + +.. date: 2024-07-29-10-24-48 +.. gh-issue: 122311 +.. nonce: xChV1b +.. section: Library + +Fix some error messages in :mod:`pickle`. + +.. + +.. date: 2024-07-27-16-10-41 +.. gh-issue: 121650 +.. nonce: nf6oc9 +.. section: Library + +:mod:`email` headers with embedded newlines are now quoted on output. The +:mod:`~email.generator` will now refuse to serialize (write) headers that +are unsafely folded or delimited; see +:attr:`~email.policy.Policy.verify_generated_headers`. (Contributed by Bas +Bloemsaat and Petr Viktorin in :gh:`121650`.) + +.. + +.. date: 2024-07-26-21-21-13 +.. gh-issue: 122332 +.. nonce: fvw88r +.. section: Library + +Fixed segfault with :meth:`asyncio.Task.get_coro` when using an eager task +factory. + +.. + +.. date: 2024-07-25-15-41-14 +.. gh-issue: 105733 +.. nonce: o3koJA +.. section: Library + +:func:`ctypes.ARRAY` is now :term:`soft deprecated`: it no longer emits +deprecation warnings and is not scheduled for removal. + +.. + +.. date: 2024-07-24-08-48-22 +.. gh-issue: 122213 +.. nonce: o3pdgA +.. section: Library + +Add notes for pickle serialization errors that allow to identify the source +of the error. + +.. + +.. date: 2024-07-23-22-26-00 +.. gh-issue: 119180 +.. nonce: B2IVT8 +.. section: Library + +As part of :pep:`749`, add the following attributes for customizing +evaluation of annotation scopes: + +* ``evaluate_value`` on :class:`typing.TypeAliasType` +* ``evaluate_bound``, ``evaluate_constraints``, and ``evaluate_default`` on :class:`typing.TypeVar` +* ``evaluate_default`` on :class:`typing.ParamSpec` +* ``evaluate_default`` on :class:`typing.TypeVarTuple` + +.. + +.. date: 2024-07-23-17-13-10 +.. gh-issue: 119180 +.. nonce: 5PZELo +.. section: Library + +Fix handling of classes with custom metaclasses in +``annotationlib.get_annotations``. + +.. + +.. date: 2024-07-23-15-30-23 +.. gh-issue: 122170 +.. nonce: Z9gi3Y +.. section: Library + +Handle :exc:`ValueError`\s raised by :func:`os.stat` in :mod:`linecache`. +Patch by Bénédikt Tran. + +.. + +.. date: 2024-07-23-15-11-13 +.. gh-issue: 122163 +.. nonce: 4wRUuM +.. section: Library + +Add notes for JSON serialization errors that allow to identify the source of +the error. + +.. + +.. date: 2024-07-23-13-07-12 +.. gh-issue: 122129 +.. nonce: PwbC8q +.. section: Library + +Improve support of method descriptors and wrappers in the help title. + +.. + +.. date: 2024-07-23-12-38-14 +.. gh-issue: 122145 +.. nonce: sTO8nX +.. section: Library + +Fix an issue when reporting tracebacks corresponding to Python code emitting +an empty AST body. Patch by Nikita Sobolev and Bénédikt Tran. + +.. + +.. date: 2024-07-23-10-59-38 +.. gh-issue: 121723 +.. nonce: iJEf7e +.. section: Library + +Make :func:`logging.config.dictConfig` accept any object implementing the +Queue public API. See the :ref:`queue configuration ` +section for details. Patch by Bénédikt Tran. + +.. + +.. date: 2024-07-23-09-14-44 +.. gh-issue: 82951 +.. nonce: -F5p5A +.. section: Library + +Serializing objects with complex ``__qualname__`` (such as unbound methods +and nested classes) by name no longer involves serializing parent objects by +value in pickle protocols < 4. + +.. + +.. date: 2024-07-22-08-57-28 +.. gh-issue: 120754 +.. nonce: Eo5puP +.. section: Library + +``Pathlib.read_bytes`` no longer opens the file in Python's buffered I/O +mode. This reduces overheads as the code reads a file in whole leading to a +modest speedup. + +.. + +.. date: 2024-07-22-08-14-04 +.. gh-issue: 113785 +.. nonce: 6B_KNB +.. section: Library + +:mod:`csv` now correctly parses numeric fields (when used with +:const:`csv.QUOTE_NONNUMERIC` or :const:`csv.QUOTE_STRINGS`) which start +with an escape character. + +.. + +.. date: 2024-07-21-18-03-30 +.. gh-issue: 122088 +.. nonce: vi2bP- +.. section: Library + +:func:`@warnings.deprecated ` now copies the coroutine +status of functions and methods so that :func:`inspect.iscoroutinefunction` +returns the correct result. + +.. + +.. date: 2024-07-21-10-45-24 +.. gh-issue: 122081 +.. nonce: dNrYMq +.. section: Library + +Fix a crash in the :func:`!decimal.IEEEContext` optional function available +via the ``EXTRA_FUNCTIONALITY`` configuration flag. + +.. + +.. date: 2024-07-21-02-00-46 +.. gh-issue: 73991 +.. nonce: pLxdtJ +.. section: Library + +Add :meth:`pathlib.Path.move`, which moves a file or directory tree. + +.. + +.. date: 2024-07-17-12-55-22 +.. gh-issue: 121268 +.. nonce: 41RmjR +.. section: Library + +Remove workarounds for non-IEEE 754 systems in :mod:`cmath`. + +.. + +.. date: 2024-07-17-09-44-35 +.. gh-issue: 119698 +.. nonce: WlygzR +.. section: Library + +Due to the lack of interest for :meth:`symtable.Class.get_methods`, the +method is marked as deprecated and will be removed in Python 3.16. Patch by +Bénédikt Tran. + +.. + +.. date: 2024-07-17-09-23-03 +.. gh-issue: 121889 +.. nonce: 6se9jS +.. section: Library + +Adjusts ``cmath.acosh(complex('0+nanj'))`` for recent C standards. + +.. + +.. date: 2024-07-16-20-49-07 +.. gh-issue: 121804 +.. nonce: gYN-In +.. section: Library + +Correctly show error locations, when :exc:`SyntaxError` raised in new repl. +Patch by Sergey B Kirpichev. + +.. + +.. date: 2024-07-15-19-34-56 +.. gh-issue: 121797 +.. nonce: qDqj59 +.. section: Library + +Add alternative :class:`~fractions.Fraction` constructor +:meth:`Fraction.from_number() `. + +.. + +.. date: 2024-07-15-19-25-25 +.. gh-issue: 121798 +.. nonce: GmuBDu +.. section: Library + +Add alternative :class:`~decimal.Decimal` constructor +:meth:`Decimal.from_number() `. + +.. + +.. date: 2024-07-14-11-18-28 +.. gh-issue: 120930 +.. nonce: Kuo4L0 +.. section: Library + +Fixed a bug introduced by gh-92081 that added an incorrect extra blank to +encoded words occurring in wrapped headers. + +.. + +.. date: 2024-07-14-06-24-02 +.. gh-issue: 57141 +.. nonce: C3jhDh +.. section: Library + +The *shallow* argument to :class:`filecmp.dircmp` (new in Python 3.13) is +now keyword-only. + +.. + +.. date: 2024-07-13-06-23-24 +.. gh-issue: 121245 +.. nonce: RfOgf4 +.. section: Library + +Simplify handling of the history file in ``site.register_readline()`` +helper. The ``CAN_USE_PYREPL`` variable now will be initialized, when +imported. Patch by Sergey B Kirpichev. + +.. + +.. date: 2024-07-10-08-13-34 +.. gh-issue: 121249 +.. nonce: W9Gd09 +.. section: Library + +Support the :c:expr:`float complex` and :c:expr:`double complex` C types in +the :mod:`struct` module if the compiler has C11 complex arithmetic. Patch +by Sergey B Kirpichev. + +.. + +.. date: 2024-07-09-12-23-32 +.. gh-issue: 121486 +.. nonce: Iultjh +.. section: Library + +:mod:`math` functions :func:`~math.isqrt`, :func:`~math.log`, +:func:`~math.log2` and :func:`~math.log10` now support integers larger than +``2**2**32`` on 32-bit platforms. + +.. + +.. date: 2024-07-08-03-45-34 +.. gh-issue: 121474 +.. nonce: NsvrUN +.. section: Library + +Fix missing sanity check for ``parties`` arg in :class:`threading.Barrier` +constructor. Patch by Clinton Christian (pygeek). + +.. + +.. date: 2024-07-06-23-39-38 +.. gh-issue: 121450 +.. nonce: vGqb3c +.. section: Library + +Hard-coded breakpoints (:func:`breakpoint` and :func:`pdb.set_trace`) now +reuse the most recent ``Pdb`` instance that calls ``Pdb.set_trace()``, +instead of creating a new one each time. As a result, all the instance +specific data like ``display`` and ``commands`` are preserved across +Hard-coded breakpoints. + +.. + +.. date: 2024-07-06-16-08-39 +.. gh-issue: 119169 +.. nonce: o0YymL +.. section: Library + +Slightly speed up :func:`os.walk` by simplifying exception handling. + +.. + +.. date: 2024-07-06-12-37-10 +.. gh-issue: 121423 +.. nonce: vnxrl4 +.. section: Library + +Improve import time of :mod:`socket` by lazy importing modules and writing +:data:`!socket.errorTab` as a constant. + +.. + +.. date: 2024-07-04-17-36-03 +.. gh-issue: 59110 +.. nonce: IlI9Fz +.. section: Library + +:mod:`zipimport` supports now namespace packages when no directory entry +exists. + +.. + +.. date: 2024-07-03-14-23-04 +.. gh-issue: 119004 +.. nonce: L5MoUu +.. section: Library + +Fix a crash in :ref:`OrderedDict.__eq__ ` +when operands are mutated during the check. Patch by Bénédikt Tran. + +.. + +.. date: 2024-07-03-10-11-53 +.. gh-issue: 121313 +.. nonce: D7gARW +.. section: Library + +Limit the reading size in the :class:`multiprocessing.connection.Connection` +class to 64 KiB to prevent memory overallocation and unnecessary memory +management system calls. + +.. + +.. date: 2024-07-03-07-25-21 +.. gh-issue: 121332 +.. nonce: Iz6FEq +.. section: Library + +Fix constructor of :mod:`ast` nodes with custom ``_attributes``. Previously, +passing custom attributes would raise a :py:exc:`DeprecationWarning`. +Passing arguments to the constructor that are not in ``_fields`` or +``_attributes`` remains deprecated. Patch by Jelle Zijlstra. + +.. + +.. date: 2024-07-02-11-34-06 +.. gh-issue: 121245 +.. nonce: sSkDAr +.. section: Library + +Fix a bug in the handling of the command history of the new :term:`REPL` +that caused the history file to be wiped at REPL exit. + +.. + +.. date: 2024-07-01-11-23-18 +.. gh-issue: 121210 +.. nonce: cD0zfn +.. section: Library + +Handle AST nodes with missing runtime fields or attributes in +:func:`ast.compare`. Patch by Bénédikt Tran. + +.. + +.. date: 2024-06-29-19-30-15 +.. gh-issue: 121163 +.. nonce: SJKDFq +.. section: Library + +Add support for ``all`` as an valid ``action`` for +:func:`warnings.simplefilter` and :func:`warnings.filterwarnings`. + +.. + +.. date: 2024-06-29-15-23-26 +.. gh-issue: 121151 +.. nonce: HeLEvq +.. section: Library + +Fix wrapping of long usage text of arguments inside a mutually exclusive +group in :mod:`argparse`. + +.. + +.. date: 2024-06-29-15-21-12 +.. gh-issue: 121141 +.. nonce: 4evD6q +.. section: Library + +Add support for :func:`copy.replace` to AST nodes. Patch by Bénédikt Tran. + +.. + +.. date: 2024-06-29-05-08-59 +.. gh-issue: 87744 +.. nonce: rpF6Jw +.. section: Library + +Fix waitpid race while calling +:meth:`~asyncio.subprocess.Process.send_signal` in asyncio. Patch by Kumar +Aditya. + +.. + +.. date: 2024-06-27-13-47-14 +.. gh-issue: 121027 +.. nonce: jh55EC +.. section: Library + +Add a future warning in :meth:`!functools.partial.__get__`. In future Python +versions :class:`functools.partial` will be a method descriptor. + +.. + +.. date: 2024-06-27-12-27-52 +.. gh-issue: 121027 +.. nonce: D4K1OX +.. section: Library + +Make the :class:`functools.partial` object a method descriptor. + +.. + +.. date: 2024-06-26-17-00-39 +.. gh-issue: 117784 +.. nonce: inCtAV +.. section: Library + +CPython now detects whether its linked TLS library supports TLSv1.3 +post-handshake authentication and disables that feature if support is +lacking. + +.. + +.. date: 2024-06-26-10-13-40 +.. gh-issue: 121025 +.. nonce: M-XXlV +.. section: Library + +Improve the :meth:`~object.__repr__` of :class:`functools.partialmethod`. +Patch by Bénédikt Tran. + +.. + +.. date: 2024-06-26-03-04-24 +.. gh-issue: 121018 +.. nonce: clVSc4 +.. section: Library + +Fixed issues where :meth:`!argparse.ArgumentParser.parse_args` did not honor +``exit_on_error=False``. Based on patch by Ben Hsing. + +.. + +.. date: 2024-06-23-17-50-40 +.. gh-issue: 119614 +.. nonce: vwPGLB +.. section: Library + +Fix truncation of strings with embedded null characters in some internal +operations in :mod:`tkinter`. + +.. + +.. date: 2024-06-23-11-21-27 +.. gh-issue: 120910 +.. nonce: t0QXdB +.. section: Library + +When reading installed files from an egg, use ``relative_to(walk_up=True)`` +to honor files installed outside of the installation root. + +.. + +.. date: 2024-06-23-07-23-08 +.. gh-issue: 61103 +.. nonce: ca_U_l +.. section: Library + +Support :c:expr:`float complex`, :c:expr:`double complex` and :c:expr:`long +double complex` C types in :mod:`ctypes` as +:class:`~ctypes.c_float_complex`, :class:`~ctypes.c_double_complex` and +:class:`~ctypes.c_longdouble_complex` if the compiler has C11 complex +arithmetic. Patch by Sergey B Kirpichev. + +.. + +.. date: 2024-06-22-22-52-24 +.. gh-issue: 120888 +.. nonce: sd8I3N +.. section: Library + +Upgrade pip wheel bundled with ensurepip (pip 24.1.1) + +.. + +.. date: 2024-06-22-22-23-56 +.. gh-issue: 101830 +.. nonce: 1BAoxH +.. section: Library + +Accessing the :mod:`tkinter` object's string representation no longer +converts the underlying Tcl object to a string on Windows. + +.. + +.. date: 2024-06-22-17-01-56 +.. gh-issue: 120678 +.. nonce: Ik8dCg +.. section: Library + +Fix regression in the new REPL that meant that globals from files passed +using the ``-i`` argument would not be included in the REPL's global +namespace. Patch by Alex Waygood. + +.. + +.. date: 2024-06-21-14-32-56 +.. gh-issue: 120811 +.. nonce: eBmVTV +.. section: Library + +Fix possible memory leak in :meth:`contextvars.Context.run`. + +.. + +.. date: 2024-06-21-12-00-16 +.. gh-issue: 120782 +.. nonce: LOE8tj +.. section: Library + +Fix wrong references of the :mod:`datetime` types after reloading the +module. + +.. + +.. date: 2024-06-21-06-37-46 +.. gh-issue: 120713 +.. nonce: WBbQx4 +.. section: Library + +:meth:`datetime.datetime.strftime` now 0-pads years with less than four +digits for the format specifiers ``%Y`` and ``%G`` on Linux. Patch by Ben +Hsing + +.. + +.. date: 2024-06-20-01-31-24 +.. gh-issue: 120769 +.. nonce: PfiMrc +.. section: Library + +Make empty line in :mod:`pdb` repeats the last command even when the command +is from ``cmdqueue``. + +.. + +.. date: 2024-06-19-23-08-25 +.. gh-issue: 120780 +.. nonce: 0Omopb +.. section: Library + +Show string value of LOAD_SPECIAL oparg in :mod:`dis` output. + +.. + +.. date: 2024-06-19-19-53-42 +.. gh-issue: 41431 +.. nonce: gnkUc5 +.. section: Library + +Add :meth:`datetime.time.strptime` and :meth:`datetime.date.strptime`. +Contributed by Wannes Boeykens. + +.. + +.. date: 2024-06-19-15-43-04 +.. gh-issue: 120743 +.. nonce: CMMl2P +.. section: Library + +:term:`Soft deprecate ` :func:`os.popen` and +:func:`os.spawn* ` functions. They should no longer be used to +write new code. The :mod:`subprocess` module is recommended instead. Patch +by Victor Stinner. + +.. + +.. date: 2024-06-19-15-06-58 +.. gh-issue: 120732 +.. nonce: OvYV9b +.. section: Library + +Fix ``name`` passing to :class:`unittest.mock.Mock` object when using +:func:`unittest.mock.create_autospec`. + +.. + +.. date: 2024-06-19-13-20-01 +.. gh-issue: 111259 +.. nonce: Wki5PV +.. section: Library + +:mod:`re` now handles patterns like ``"[\s\S]"`` or ``"\s|\S"`` which match +any character as effectively as a dot with the ``DOTALL`` modifier +(``"(?s:.)"``). + +.. + +.. date: 2024-06-18-19-18-10 +.. gh-issue: 120683 +.. nonce: xmRez7 +.. section: Library + +Fix an error in :class:`logging.LogRecord`, when the integer part of the +timestamp is rounded up, while the millisecond calculation truncates, +causing the log timestamp to be wrong by up to 999 ms (affected roughly 1 in +8 million timestamps). + +.. + +.. date: 2024-06-18-14-45-38 +.. gh-issue: 118710 +.. nonce: 5GZZPX +.. section: Library + +:class:`ipaddress.IPv4Address` and :class:`ipaddress.IPv6Address` attributes +``version`` and ``max_prefixlen`` are now available on the class. + +.. + +.. date: 2024-06-17-20-04-13 +.. gh-issue: 120633 +.. nonce: kZC5wt +.. section: Library + +Move scrollbar and remove tear-off menus in turtledemo. + +.. + +.. date: 2024-06-16-21-33-56 +.. gh-issue: 120606 +.. nonce: kugbwR +.. section: Library + +Allow users to use EOF to exit ``commands`` definition in :mod:`pdb` + +.. + +.. date: 2024-06-15-23-38-36 +.. gh-issue: 120284 +.. nonce: HwsAtY +.. section: Library + +Allow :meth:`asyncio.Runner.run` to accept :term:`awaitable` objects instead +of simply :term:`coroutine`\s. + +.. + +.. date: 2024-06-15-12-04-46 +.. gh-issue: 120541 +.. nonce: d3cc5y +.. section: Library + +Improve the prompt in the "less" pager when :func:`help` is called with +non-string argument. + +.. + +.. date: 2024-06-14-20-05-25 +.. gh-issue: 120495 +.. nonce: OxgZKB +.. section: Library + +Fix incorrect exception handling in Tab Nanny. Patch by Wulian233. + +.. + +.. date: 2024-06-12-15-07-58 +.. gh-issue: 120388 +.. nonce: VuTQMT +.. section: Library + +Improve a warning message when a test method in :mod:`unittest` returns +something other than ``None``. Now we show the returned object type and +optional asyncio-related tip. + +.. + +.. date: 2024-06-12-11-54-05 +.. gh-issue: 120381 +.. nonce: O-BNLs +.. section: Library + +Correct :func:`inspect.ismethoddescriptor` to check also for the lack of +:meth:`~object.__delete__`. Patch by Jan Kaliszewski. + +.. + +.. date: 2024-06-12-10-00-31 +.. gh-issue: 90425 +.. nonce: 5CfkKG +.. section: Library + +The OS byte in gzip headers is now always set to 255 when using +:func:`gzip.compress`. + +.. + +.. date: 2024-06-11-16-34-41 +.. gh-issue: 120343 +.. nonce: hdiXeU +.. section: Library + +Fix column offset reporting for tokens that come after multiline f-strings +in the :mod:`tokenize` module. + +.. + +.. date: 2024-06-11-07-17-25 +.. gh-issue: 119180 +.. nonce: iH-2zy +.. section: Library + +As part of implementing :pep:`649` and :pep:`749`, add a new module +``annotationlib``. Add support for unresolved forward references in +annotations to :mod:`dataclasses`, :class:`typing.TypedDict`, and +:class:`typing.NamedTuple`. + +.. + +.. date: 2024-06-10-14-00-40 +.. gh-issue: 119600 +.. nonce: jJMf4C +.. section: Library + +Fix :func:`unittest.mock.patch` to not read attributes of the target when +``new_callable`` is set. Patch by Robert Collins. + +.. + +.. date: 2024-06-09-19-53-11 +.. gh-issue: 120289 +.. nonce: s4HXR0 +.. section: Library + +Fixed the use-after-free issue in :mod:`cProfile` by disallowing +``disable()`` and ``clear()`` in external timers. + +.. + +.. date: 2024-06-08-17-41-11 +.. gh-issue: 82017 +.. nonce: WpSTGi +.. section: Library + +Added support for converting any objects that have the +:meth:`!as_integer_ratio` method to a :class:`~fractions.Fraction`. + +.. + +.. date: 2024-06-08-15-46-35 +.. gh-issue: 114053 +.. nonce: Ub2XgJ +.. section: Library + +Fix edge-case bug where :func:`typing.get_type_hints` would produce +incorrect results if type parameters in a class scope were overridden by +assignments in a class scope and ``from __future__ import annotations`` +semantics were enabled. Patch by Alex Waygood. + +.. + +.. date: 2024-06-08-15-15-29 +.. gh-issue: 114053 +.. nonce: WQLAFG +.. section: Library + +Fix erroneous :exc:`NameError` when calling :func:`inspect.get_annotations` +with ``eval_str=True``` on a class that made use of :pep:`695` type +parameters in a module that had ``from __future__ import annotations`` at +the top of the file. Patch by Alex Waygood. + +.. + +.. date: 2024-06-08-14-36-40 +.. gh-issue: 120268 +.. nonce: MNpd1q +.. section: Library + +Prohibit passing ``None`` to pure-Python :meth:`datetime.date.fromtimestamp` +to achieve consistency with C-extension implementation. + +.. + +.. date: 2024-06-08-09-45-31 +.. gh-issue: 120244 +.. nonce: 8o9Dzr +.. section: Library + +Fix memory leak in :func:`re.sub` when the replacement string contains +backreferences. + +.. + +.. date: 2024-06-08-03-29-01 +.. gh-issue: 120254 +.. nonce: h682ke +.. section: Library + +Added ``commands`` argument to :func:`pdb.set_trace` which allows users to +send debugger commands from the source file. + +.. + +.. date: 2024-06-07-13-21-11 +.. gh-issue: 120211 +.. nonce: Rws_gf +.. section: Library + +Fix :mod:`tkinter.ttk` with Tcl/Tk 9.0. + +.. + +.. date: 2024-06-07-11-23-31 +.. gh-issue: 71587 +.. nonce: IjFajE +.. section: Library + +Fix crash in C version of :meth:`datetime.datetime.strptime` when called +again on the restarted interpreter. + +.. + +.. date: 2024-06-07-10-10-32 +.. gh-issue: 117983 +.. nonce: NeMR9n +.. section: Library + +Defer the ``threading`` import in ``importlib.util`` until lazy loading is +used. + +.. + +.. date: 2024-06-07-02-00-31 +.. gh-issue: 120157 +.. nonce: HnWcF9 +.. section: Library + +Remove unused constant ``concurrent.futures._base._FUTURE_STATES`` in +:mod:`concurrent.futures`. Patch by Clinton Christian (pygeek). + +.. + +.. date: 2024-06-06-17-24-43 +.. gh-issue: 120161 +.. nonce: DahNXV +.. section: Library + +:mod:`datetime` no longer crashes in certain complex reference cycle +situations. + +.. + +.. date: 2024-06-06-12-07-57 +.. gh-issue: 119698 +.. nonce: rRrprk +.. section: Library + +Fix :meth:`symtable.Class.get_methods` and document its behaviour. Patch by +Bénédikt Tran. + +.. + +.. date: 2024-06-05-16-30-28 +.. gh-issue: 120121 +.. nonce: 9dz8i7 +.. section: Library + +Add :exc:`concurrent.futures.InvalidStateError` to module's ``__all__``. + +.. + +.. date: 2024-06-05-11-39-21 +.. gh-issue: 119933 +.. nonce: ooJXQV +.. section: Library + +Add the :class:`symtable.SymbolTableType` enumeration to represent the +possible outputs of the :class:`symtable.SymbolTable.get_type` method. Patch +by Bénédikt Tran. + +.. + +.. date: 2024-06-05-11-03-10 +.. gh-issue: 120029 +.. nonce: QBsw47 +.. section: Library + +Expose :class:`symtable.Symbol` methods +:meth:`~symtable.Symbol.is_free_class`, +:meth:`~symtable.Symbol.is_comp_iter` and +:meth:`~symtable.Symbol.is_comp_cell`. Patch by Bénédikt Tran. + +.. + +.. date: 2024-06-05-08-02-46 +.. gh-issue: 120108 +.. nonce: 4U9BL8 +.. section: Library + +Fix calling :func:`copy.deepcopy` on :mod:`ast` trees that have been +modified to have references to parent nodes. Patch by Jelle Zijlstra. + +.. + +.. date: 2024-06-04-19-49-16 +.. gh-issue: 120056 +.. nonce: 5aqozw +.. section: Library + +Add :data:`!socket.IP_RECVERR` and :data:`!socket.IP_RECVTTL` constants +(both available since Linux 2.2). And :data:`!socket.IP_RECVORIGDSTADDR` +constant (available since Linux 2.6.29). + +.. + +.. date: 2024-06-04-19-03-25 +.. gh-issue: 112672 +.. nonce: K2XfZH +.. section: Library + +Support building :mod:`tkinter` with Tcl 9.0. + +.. + +.. date: 2024-06-04-18-53-10 +.. gh-issue: 120057 +.. nonce: RSD9_Z +.. section: Library + +Added the :data:`os.environ.refresh() ` method to update +:data:`os.environ` with changes to the environment made by +:func:`os.putenv`, by :func:`os.unsetenv`, or made outside Python in the +same process. Patch by Victor Stinner. + +.. + +.. date: 2024-06-04-14-54-46 +.. gh-issue: 120029 +.. nonce: _1YdTf +.. section: Library + +Expose :meth:`symtable.Symbol.is_type_parameter` in the :mod:`symtable` +module. Patch by Bénédikt Tran. + +.. + +.. date: 2024-06-04-12-23-01 +.. gh-issue: 119819 +.. nonce: WKKrYh +.. section: Library + +Fix regression to allow logging configuration with multiprocessing queue +types. + +.. + +.. date: 2024-06-04-08-57-02 +.. gh-issue: 65454 +.. nonce: o9j4wF +.. section: Library + +:func:`unittest.mock.Mock.attach_mock` no longer triggers a call to a +``PropertyMock`` being attached. + +.. + +.. date: 2024-06-03-11-18-16 +.. gh-issue: 117142 +.. nonce: kWTXQo +.. section: Library + +The :mod:`ctypes` module may now be imported in all subinterpreters, +including those that have their own GIL. + +.. + +.. date: 2024-06-02-15-09-17 +.. gh-issue: 118835 +.. nonce: KUAuz6 +.. section: Library + +Fix _pyrepl crash when using custom prompt with ANSI escape codes. + +.. + +.. date: 2024-06-02-13-35-11 +.. gh-issue: 81936 +.. nonce: ETeW9x +.. section: Library + +:meth:`!help` and :meth:`!showtopic` methods now respect a configured +*output* argument to :class:`!pydoc.Helper` and not use the pager in such +cases. Patch by Enrico Tröger. + +.. + +.. date: 2024-06-01-16-58-43 +.. gh-issue: 117398 +.. nonce: kR0RW7 +.. section: Library + +The ``_datetime`` module (C implementation for :mod:`datetime`) now supports +being imported in multiple interpreters. + +.. + +.. date: 2024-05-31-21-17-43 +.. gh-issue: 119824 +.. nonce: CQlxWV +.. section: Library + +Print stack entry in :mod:`pdb` when and only when user input is needed. + +.. + +.. date: 2024-05-31-13-56-21 +.. gh-issue: 119838 +.. nonce: H6XHlE +.. section: Library + +In mixed arithmetic operations with :class:`~fractions.Fraction` and +complex, the fraction is now converted to :class:`float` instead of +:class:`complex`. + +.. + +.. date: 2024-05-31-12-57-31 +.. gh-issue: 119770 +.. nonce: NCtels +.. section: Library + +Make :mod:`termios` ``ioctl()`` constants positive. Patch by Victor Stinner. + +.. + +.. date: 2024-05-30-21-37-05 +.. gh-issue: 89727 +.. nonce: D6S9ig +.. section: Library + +Fix issue with :func:`shutil.rmtree` where a :exc:`RecursionError` is raised +on deep directory trees. + +.. + +.. date: 2024-05-29-21-50-05 +.. gh-issue: 119577 +.. nonce: S3BlKJ +.. section: Library + +The :exc:`DeprecationWarning` emitted when testing the truth value of an +:class:`xml.etree.ElementTree.Element` now describes unconditionally +returning ``True`` in a future version rather than raising an exception in +Python 3.14. + +.. + +.. date: 2024-05-29-20-42-17 +.. gh-issue: 89727 +.. nonce: 5lPTTW +.. section: Library + +Partially fix issue with :func:`shutil.rmtree` where a :exc:`RecursionError` +is raised on deep directory trees. A recursion error is no longer raised +when :data:`!rmtree.avoids_symlink_attacks` is false. + +.. + +.. date: 2024-05-29-12-42-40 +.. gh-issue: 93963 +.. nonce: cb1oJS +.. section: Library + +Remove deprecated names from ``importlib.abc`` as found in +``importlib.resources.abc``. + +.. + +.. date: 2024-05-28-12-15-03 +.. gh-issue: 119118 +.. nonce: FMKz1F +.. section: Library + +Fix performance regression in the :mod:`tokenize` module by caching the +``line`` token attribute and calculating the column offset more efficiently. + +.. + +.. date: 2024-05-28-00-56-59 +.. gh-issue: 89727 +.. nonce: _bxoL3 +.. section: Library + +Fix issue with :func:`os.fwalk` where a :exc:`RecursionError` was raised on +deep directory trees by adjusting the implementation to be iterative instead +of recursive. + +.. + +.. date: 2024-05-26-22-22-51 +.. gh-issue: 119594 +.. nonce: fnQNM8 +.. section: Library + +If one calls pow(fractions.Fraction, x, module) with modulo not None, the +error message now says that the types are incompatible rather than saying +pow only takes 2 arguments. Patch by Wim Jeantine-Glenn and Mark Dickinson. + +.. + +.. date: 2024-05-26-21-28-11 +.. gh-issue: 119588 +.. nonce: wlLBK5 +.. section: Library + +``zipfile.Path.is_symlink`` now assesses if the given path is a symlink. + +.. + +.. date: 2024-05-25-20-20-42 +.. gh-issue: 119562 +.. nonce: DyplWc +.. section: Library + +Remove :class:`!ast.Num`, :class:`!ast.Str`, :class:`!ast.Bytes`, +:class:`!ast.NameConstant` and :class:`!ast.Ellipsis`. They had all emitted +deprecation warnings since Python 3.12. Patch by Alex Waygood. + +.. + +.. date: 2024-05-25-20-15-26 +.. gh-issue: 119555 +.. nonce: mvHbEL +.. section: Library + +Catch :exc:`SyntaxError` from :func:`compile` in the runsource() method of +the InteractiveColoredConsole. Patch by Sergey B Kirpichev. + +.. + +.. date: 2024-05-25-10-40-38 +.. gh-issue: 118908 +.. nonce: XcZiq4 +.. section: Library + +Limit exposed globals from internal imports and definitions on new REPL +startup. Patch by Eugene Triguba and Pablo Galindo. + +.. + +.. date: 2024-05-25-07-25-07 +.. gh-issue: 117865 +.. nonce: 1A0Xpi +.. section: Library + +Improve the import time of the :mod:`ast` module by deferring the import of +:mod:`re`. Patch by Jelle Zijlstra. + +.. + +.. date: 2024-05-25-00-54-26 +.. gh-issue: 119127 +.. nonce: LpPvag +.. section: Library + +Positional arguments of :func:`functools.partial` objects now support +placeholders via :data:`functools.Placeholder`. + +.. + +.. date: 2024-05-24-21-54-55 +.. gh-issue: 113892 +.. nonce: JKDFqq +.. section: Library + +Now, the method ``sock_connect`` of :class:`asyncio.ProactorEventLoop` +raises a :exc:`ValueError` if given socket is not in non-blocking mode, as +well as in other loop implementations. + +.. + +.. date: 2024-05-24-14-32-24 +.. gh-issue: 119506 +.. nonce: -nMNqq +.. section: Library + +Fix :meth:`!io.TextIOWrapper.write` method breaks internal buffer when the +method is called again during flushing internal buffer. + +.. + +.. date: 2024-05-24-11-47-08 +.. gh-issue: 69214 +.. nonce: Grl6zF +.. section: Library + +Fix ``fcntl.ioctl()`` *request* parameter: use an ``unsigned long`` instead +of an ``unsigned int`` for the *request* parameter of :func:`fcntl.ioctl` to +support requests larger than ``UINT_MAX``. Patch by Victor Stinner. + +.. + +.. date: 2024-05-24-04-05-37 +.. gh-issue: 119105 +.. nonce: aDSRFn +.. section: Library + +``difflib``'s ``DIffer.compare()`` (and so also ``ndiff``) can no longer be +provoked into cubic-time behavior, or into unbounded recursion, and should +generally be faster in ordinary cases too. Results may change in some cases, +although that should be rare. Correctness of diffs is not affected. Some +similar lines far apart may be reported as deleting one and adding the +other, where before they were displayed on adjacent output lines with markup +showing the intraline differences. + +.. + +.. date: 2024-05-23-22-29-59 +.. gh-issue: 119443 +.. nonce: KAGz6S +.. section: Library + +The interactive REPL no longer runs with ``from __future__ import +annotations`` enabled. Patch by Jelle Zijlstra. + +.. + +.. date: 2024-05-23-15-48-17 +.. gh-issue: 119461 +.. nonce: 82KqUW +.. section: Library + +Add ``socket.VMADDR_CID_LOCAL`` constant. Patch by Victor Stinner. + +.. + +.. date: 2024-05-23-11-52-36 +.. gh-issue: 117398 +.. nonce: 2FG1Mk +.. section: Library + +Objects in the datetime C-API are now all statically allocated, which means +better memory safety, especially when the module is reloaded. This should be +transparent to users. + +.. + +.. date: 2024-05-22-21-20-43 +.. gh-issue: 118894 +.. nonce: xHdxR_ +.. section: Library + +:mod:`asyncio` REPL now has the same capabilities as PyREPL. + +.. + +.. date: 2024-05-21-23-39-22 +.. gh-issue: 118830 +.. nonce: YTqvEo +.. section: Library + +Bump :mod:`pickle` default protocol to ``5``. + +.. + +.. date: 2024-05-21-20-13-23 +.. gh-issue: 118911 +.. nonce: iG8nMq +.. section: Library + +In PyREPL, updated ``maybe-accept``'s logic so that if the user hits +:kbd:`Enter` twice, they are able to terminate the block even if there's +trailing whitespace. Also, now when the user hits arrow up, the cursor is on +the last functional line. This matches IPython's behavior. Patch by Aya +Elsayed. + +.. + +.. date: 2024-05-21-19-10-30 +.. gh-issue: 115225 +.. nonce: eRmfJH +.. section: Library + +Raise error on certain technically valid but pathological ISO 8601 strings +passed to :meth:`datetime.time.fromisoformat` that were previously parsed +incorrectly. + +.. + +.. date: 2024-05-20-20-30-57 +.. gh-issue: 111201 +.. nonce: DAA5lC +.. section: Library + +Remove dependency to :mod:`readline` from the new Python REPL. + +.. + +.. date: 2024-05-20-13-48-37 +.. gh-issue: 119189 +.. nonce: dhJVs5 +.. section: Library + +When using the ``**`` operator or :func:`pow` with +:class:`~fractions.Fraction` as the base and an exponent that is not +rational, a float, or a complex, the fraction is no longer converted to a +float. + +.. + +.. date: 2024-05-19-18-49-04 +.. gh-issue: 119174 +.. nonce: 5GTv7d +.. section: Library + +Fix high DPI causes turtledemo(turtle-graphics examples) windows blurry +Patch by Wulian233 and Terry Jan Reedy + +.. + +.. date: 2024-05-19-13-05-59 +.. gh-issue: 119121 +.. nonce: P1gnh1 +.. section: Library + +Fix a NameError happening in ``asyncio.staggered.staggered_race``. This +function is now tested. + +.. + +.. date: 2024-05-19-12-25-36 +.. gh-issue: 119105 +.. nonce: VcR4ig +.. section: Library + +``difflib.Differ`` is much faster for some cases of diffs where many pairs +of lines are equally similar. + +.. + +.. date: 2024-05-17-17-32-12 +.. gh-issue: 119113 +.. nonce: kEv1Ll +.. section: Library + +Fix issue where :meth:`pathlib.PurePath.with_suffix` didn't raise +:exc:`TypeError` when given ``None`` as a suffix. + +.. + +.. date: 2024-05-16-17-31-46 +.. gh-issue: 118643 +.. nonce: hAWH4C +.. section: Library + +Fix an AttributeError in the :mod:`email` module when re-fold a long address +list. Also fix more cases of incorrect encoding of the address separator in +the address list. + +.. + +.. date: 2024-05-15-01-36-08 +.. gh-issue: 73991 +.. nonce: CGknDf +.. section: Library + +Add :meth:`pathlib.Path.copy`, which copies a file or directory to another. + +.. + +.. date: 2024-05-12-21-38-42 +.. gh-issue: 58933 +.. nonce: 0kgU2l +.. section: Library + +Make :mod:`pdb` return to caller frame correctly when ``f_trace`` of the +caller frame is not set + +.. + +.. date: 2024-05-11-20-23-45 +.. gh-issue: 82805 +.. nonce: F9bz4J +.. section: Library + +Support single-dot file extensions in :attr:`pathlib.PurePath.suffix` and +related attributes and methods. For example, the +:attr:`~pathlib.PurePath.suffixes` of ``PurePath('foo.bar.')`` are now +``['.bar', '.']`` rather than ``[]``. This brings file extension splitting +in line with :func:`os.path.splitext`. + +.. + +.. date: 2024-05-10-22-59-01 +.. gh-issue: 118924 +.. nonce: 9nyvSH +.. section: Library + +Remove :data:`!version` and :data:`!version_info` from :mod:`sqlite3`. Patch +by Hugo van Kemenade. + +.. + +.. date: 2024-05-10-22-36-01 +.. gh-issue: 118928 +.. nonce: IW7Ukv +.. section: Library + +Disallow using a sequence of parameters with named placeholders in +:mod:`sqlite3` queries. Patch by Erlend E. Aasland. + +.. + +.. date: 2024-05-10-05-24-32 +.. gh-issue: 118895 +.. nonce: wUm5r2 +.. section: Library + +Setting attributes on :data:`typing.NoDefault` now raises +:exc:`AttributeError` instead of :exc:`TypeError`. + +.. + +.. date: 2024-05-09-21-36-11 +.. gh-issue: 118868 +.. nonce: uckxxP +.. section: Library + +Fixed issue where kwargs were no longer passed to the logging handler +QueueHandler + +.. + +.. date: 2024-05-09-12-33-25 +.. gh-issue: 118827 +.. nonce: JrzHz1 +.. section: Library + +Remove deprecated :class:`!Quoter` class from :mod:`urllib.parse`. It had +previously raised a :exc:`DeprecationWarning` since Python 3.11. Patch by +Nikita Sobolev. + +.. + +.. date: 2024-05-09-11-50-26 +.. gh-issue: 118824 +.. nonce: -jBJQC +.. section: Library + +Remove deprecated :func:`!pty.master_open` and :func:`!pty.slave_open`. Use +:func:`pty.openpty` instead. Patch by Nikita Sobolev. + +.. + +.. date: 2024-05-09-08-46-12 +.. gh-issue: 118851 +.. nonce: aPAoJw +.. section: Library + +``ctx`` arguments to the constructors of :mod:`ast` node classes now default +to :class:`ast.Load() `. Patch by Jelle Zijlstra. + +.. + +.. date: 2024-05-09-02-43-37 +.. gh-issue: 101588 +.. nonce: 30bNAr +.. section: Library + +Remove copy, deepcopy, and pickle from itertools. These had previously +raised a DeprecationWarning since Python 3.12. + +.. + +.. date: 2024-05-09-01-05-52 +.. gh-issue: 118805 +.. nonce: N7dm07 +.. section: Library + +Remove *type*, *choices*, and *metavar* parameters of +:class:`!argparse.BooleanOptionalAction`. They were deprecated since Python +3.12. + +.. + +.. date: 2024-05-09-00-52-30 +.. gh-issue: 118803 +.. nonce: Wv3AvU +.. section: Library + +:class:`!typing.ByteString` and :class:`!collections.abc.ByteString` are +removed. They had previously raised a :exc:`DeprecationWarning` since Python +3.12. + +.. + +.. date: 2024-05-08-23-16-50 +.. gh-issue: 118798 +.. nonce: Q_ybqP +.. section: Library + +The *isdst* parameter has been removed from :func:`email.utils.localtime`. +Patch by Hugo van Kemenade. + +.. + +.. date: 2024-05-08-21-30-33 +.. gh-issue: 118760 +.. nonce: XvyMHn +.. section: Library + +Restore the default value of ``tkiter.wantobjects`` to ``1``. + +.. + +.. date: 2024-05-08-21-13-56 +.. gh-issue: 118760 +.. nonce: mdmH3T +.. section: Library + +Fix errors in calling Tkinter bindings on Windows. + +.. + +.. date: 2024-05-08-20-41-48 +.. gh-issue: 74033 +.. nonce: YebHZj +.. section: Library + +Drop support for passing keyword arguments to :class:`pathlib.Path`. + +.. + +.. date: 2024-05-08-19-47-34 +.. gh-issue: 101357 +.. nonce: e4R_9x +.. section: Library + +Suppress all :exc:`OSError` exceptions from :meth:`pathlib.Path.exists` and +``is_*()`` methods, rather than a selection of more common errors. The new +behaviour is consistent with :func:`os.path.exists`, :func:`os.path.isdir`, +etc. Use :meth:`pathlib.Path.stat` to retrieve the file status without +suppressing exceptions. + +.. + +.. date: 2024-05-08-18-59-19 +.. gh-issue: 78707 +.. nonce: _Lz1sw +.. section: Library + +Drop support for passing additional positional arguments to +:meth:`pathlib.PurePath.relative_to` and +:meth:`~pathlib.PurePath.is_relative_to`. + +.. + +.. date: 2024-05-08-18-33-07 +.. gh-issue: 118507 +.. nonce: OCQsAY +.. section: Library + +Fix :func:`os.path.isfile` on Windows for pipes. Speedup +:func:`os.path.isjunction` and :func:`os.path.lexists` on Windows with a +native implementation. + +.. + +.. date: 2024-05-08-09-21-49 +.. gh-issue: 118772 +.. nonce: c16E8X +.. section: Library + +Allow :class:`typing.TypeVar` instances without a default to follow +instances without a default in some cases. Patch by Jelle Zijlstra. + +.. + +.. date: 2024-05-07-17-38-53 +.. gh-issue: 118714 +.. nonce: XXKpVZ +.. section: Library + +Allow ``restart`` in post-mortem debugging of :mod:`pdb`. Removed restart +message when the user quits pdb from post-mortem mode. + +.. + +.. date: 2024-05-06-17-39-52 +.. gh-issue: 118673 +.. nonce: sTXBit +.. section: Library + +Removed executable bits and shebang from stdlib modules. + +.. + +.. date: 2024-05-01-22-24-05 +.. gh-issue: 110863 +.. nonce: GjYBbq +.. section: Library + +:func:`os.path.realpath` now suppresses any :exc:`OSError` from +:func:`os.readlink` when *strict* mode is disabled (the default). + +.. + +.. date: 2024-04-28-19-51-00 +.. gh-issue: 118263 +.. nonce: Gaap3S +.. section: Library + +Speed up :func:`os.path.splitroot` & :func:`os.path.normpath` with a direct +C call. + +.. + +.. date: 2024-04-24-16-23-04 +.. gh-issue: 110190 +.. nonce: TGd5qx +.. section: Library + +Fix ctypes structs with array on SPARC by setting ``MAX_STRUCT_SIZE`` to 32 +in stgdict. Patch by Jakub Kulik + +.. + +.. date: 2024-04-19-14-59-53 +.. gh-issue: 118033 +.. nonce: amS4Gw +.. section: Library + +Fix :func:`dataclasses.dataclass` not creating a ``__weakref__`` slot when +subclassing :class:`typing.Generic`. + +.. + +.. date: 2024-04-19-05-58-50 +.. gh-issue: 117766 +.. nonce: J3xepp +.. section: Library + +Always use :func:`str` to print ``choices`` in :mod:`argparse`. + +.. + +.. date: 2024-03-19-21-41-31 +.. gh-issue: 106531 +.. nonce: Mgd--6 +.. section: Library + +In :mod:`importlib.resources`, sync with `importlib_resources 6.3.2 +`_, +including: ``MultiplexedPath`` now expects ``Traversable`` paths, +deprecating string arguments to ``MultiplexedPath``; Enabled support for +resources in namespace packages in zip files; Fixed ``NotADirectoryError`` +when calling files on a subdirectory of a namespace package. + +.. + +.. date: 2024-02-27-10-22-15 +.. gh-issue: 115937 +.. nonce: 0cVNur +.. section: Library + +Removed extra preprocessing for the ``__signature__`` attribute: the code +just check if it's a :class:`inspect.Signature` instance. Patch by Sergey B +Kirpichev. + +.. + +.. date: 2024-02-22-10-12-59 +.. gh-issue: 115808 +.. nonce: F2g2Ku +.. section: Library + +Add :func:`operator.is_none` and :func:`operator.is_not_none` functions. + +.. + +.. date: 2024-01-18-21-44-23 +.. gh-issue: 114264 +.. nonce: DBKn29 +.. section: Library + +Improve performance of :func:`copy.deepcopy` by adding a fast path for +atomic types. + +.. + +.. date: 2024-01-14-11-43-31 +.. gh-issue: 113878 +.. nonce: dmEIN3 +.. section: Library + +Add *doc* parameter to :func:`dataclasses.field`, so it can be stored and +shown as a documentation / metadata. If ``@dataclass(slots=True)`` is used, +then the supplied string is availabl in the :attr:`~object.__slots__` dict. +Otherwise, the supplied string is only available in the corresponding +:class:`dataclasses.Field` object. + +In order to support this feature we are changing the ``__slots__`` format in +dataclasses from :class:`tuple` to :class:`dict` when documentation / +metadata is present. + +.. + +.. date: 2024-01-12-08-51-03 +.. gh-issue: 113978 +.. nonce: MqTgB0 +.. section: Library + +Ignore warnings on text completion inside REPL. + +.. + +.. date: 2023-12-14-13-43-27 +.. gh-issue: 113008 +.. nonce: jWYn8T +.. section: Library + +Correct argparse usage output for required, mutually exclusive groups +containing a positional argument + +.. + +.. date: 2023-12-12-15-19-58 +.. gh-issue: 108172 +.. nonce: KyDPuG +.. section: Library + +``webbrowser`` honors OS preferred browser on Linux when its desktop entry +name contains the text of a known browser name. + +.. + +.. date: 2023-09-19-17-56-24 +.. gh-issue: 109109 +.. nonce: WJvvX2 +.. section: Library + +You can now get the raw TLS certificate chains from TLS connections via +:meth:`ssl.SSLSocket.get_verified_chain` and +:meth:`ssl.SSLSocket.get_unverified_chain` methods. + +Contributed by Mateusz Nowak. + +.. + +.. date: 2023-06-17-09-07-06 +.. gh-issue: 105623 +.. nonce: 5G06od +.. section: Library + +Fix performance degradation in +:class:`logging.handlers.RotatingFileHandler`. Patch by Craig Robson. + +.. + +.. date: 2023-06-16-14-52-00 +.. gh-issue: 102450 +.. nonce: MfeR6A +.. section: Library + +Add missing ISO-8601 24:00 alternative to midnight of next day to +:meth:`datetime.datetime.fromisoformat` and +:meth:`datetime.time.fromisoformat`. Patch by Izan "TizzySaurus" Robinson +(tizzysaurus@gmail.com) + +.. + +.. date: 2023-04-28-09-54-15 +.. gh-issue: 103956 +.. nonce: EyLDPS +.. section: Library + +Fix lack of newline characters in :mod:`trace` module output when line +tracing is enabled but source code line for current frame is not available. + +.. + +.. date: 2023-04-26-22-24-17 +.. gh-issue: 92081 +.. nonce: V8xMot +.. section: Library + +Fix missing spaces in email headers when the spaces are mixed with encoded +8-bit characters. + +.. + +.. date: 2023-04-24-05-34-23 +.. gh-issue: 103194 +.. nonce: GwBwWL +.. section: Library + +Prepare Tkinter for C API changes in Tcl 8.7/9.0 to avoid +:class:`!_tkinter.Tcl_Obj` being unexpectedly returned instead of +:class:`bool`, :class:`str`, :class:`bytearray`, or :class:`int`. + +.. + +.. date: 2023-04-10-00-04-37 +.. gh-issue: 87106 +.. nonce: UyBnPQ +.. section: Library + +Fixed handling in :meth:`inspect.Signature.bind` of keyword arguments having +the same name as positional-only arguments when a variadic keyword argument +(e.g. ``**kwargs``) is present. + +.. + +.. date: 2023-03-30-18-19-53 +.. gh-issue: 103134 +.. nonce: bHrn91 +.. section: Library + +Add additional methods to :ref:`proxy objects +` in the :mod:`!multiprocessing` module: + +* :meth:`!clear` and :meth:`!copy` for proxies of :class:`list` +* :meth:`~dict.fromkeys`, ``reversed(d)``, ``d | {}``, ``{} | d``, + ``d |= {'b': 2}`` for proxies of :class:`dict` + +.. + +.. bpo: 45767 +.. date: 2022-03-10-16-47-57 +.. nonce: ywmyo1 +.. section: Library + +Fix integer conversion in :func:`os.major`, :func:`os.minor`, and +:func:`os.makedev`. Support device numbers larger than ``2**63-1``. Support +non-existent device number (``NODEV``). + +.. + +.. bpo: 44864 +.. date: 2021-08-24-19-37-46 +.. nonce: KzxaDh +.. section: Library + +Do not translate user-provided strings in :class:`argparse.ArgumentParser`. + +.. + +.. bpo: 41843 +.. date: 2020-12-22-18-08-12 +.. nonce: q9Nh2r +.. section: Library + +Solaris now uses :func:`os.sendfile` fast-copy syscall for more efficient +:mod:`shutil` file copy related functions. + +.. + +.. bpo: 15987 +.. date: 2020-03-28-21-00-54 +.. nonce: aBL8XS +.. section: Library + +Implemented :func:`ast.compare` for comparing two ASTs. Patch by Batuhan +Taskaya with some help from Jeremy Hylton. + +.. + +.. date: 2019-08-27-01-16-50 +.. gh-issue: 67693 +.. nonce: 4NIAiy +.. section: Library + +Fix :func:`urllib.parse.urlunparse` and :func:`urllib.parse.urlunsplit` for +URIs with path starting with multiple slashes and no authority. Based on +patch by Ashwin Ramaswami. + +.. + +.. bpo: 14074 +.. date: 2018-12-04-07-36-27 +.. nonce: fMLKCu +.. section: Library + +Fix :mod:`argparse` metavar processing to allow positional arguments to have +a tuple metavar. + +.. + +.. date: 2024-10-04-15-34-34 +.. gh-issue: 122392 +.. nonce: V8K3w2 +.. section: IDLE + +Increase currently inadequate vertical spacing for the IDLE browsers (path, +module, and stack) on high-resolution monitors. + +.. + +.. date: 2024-09-21-23-12-18 +.. gh-issue: 112938 +.. nonce: OeiDru +.. section: IDLE + +Fix uninteruptable hang when Shell gets rapid continuous output. + +.. + +.. date: 2024-07-30-18-02-55 +.. gh-issue: 122482 +.. nonce: TerE0g +.. section: IDLE + +Change About IDLE to direct users to discuss.python.org instead of the now +unused idle-dev email and mailing list. + +.. + +.. date: 2024-07-16-16-57-03 +.. gh-issue: 78889 +.. nonce: U7ghFD +.. section: IDLE + +Stop Shell freezes by blocking user access to non-method sys.stdout.shell +attributes, which are all private. + +.. + +.. date: 2024-06-16-21-42-45 +.. gh-issue: 120083 +.. nonce: nczuyv +.. section: IDLE + +Add explicit black IDLE Hovertip foreground color needed for recent macOS. +Fixes Sonoma showing unreadable white on pale yellow. Patch by John +Riggles. + +.. + +.. date: 2024-06-05-14-54-24 +.. gh-issue: 120104 +.. nonce: j_thj4 +.. section: IDLE + +Fix padding in config and search dialog windows in IDLE. + +.. + +.. date: 2024-10-10-02-56-24 +.. gh-issue: 124872 +.. nonce: 0mDDOq +.. section: Documentation + +Added definitions for :term:`context`, :term:`current context`, and +:term:`context management protocol`, updated related definitions to be +consistent, and expanded the documentation for :class:`contextvars.Context`. + +.. + +.. date: 2024-10-07-00-31-17 +.. gh-issue: 125018 +.. nonce: yKnymn +.. section: Documentation + +The :mod:`importlib.metadata` documentation now includes semantic +cross-reference targets for the significant documented APIs. This means +intersphinx references like :func:`importlib.metadata.version` will now work +as expected. + +.. + +.. date: 2024-09-27-16-47-48 +.. gh-issue: 124720 +.. nonce: nVSTVb +.. section: Documentation + +Update "Using Python on a Mac" section of the "Python Setup and Usage" +document and include information on installing free-threading support. + +.. + +.. date: 2024-09-24-11-52-36 +.. gh-issue: 124457 +.. nonce: yrCjSV +.. section: Documentation + +Remove coverity scan from the CPython repo. It has not been used since 2020 +and is currently unmaintained. + +.. + +.. date: 2024-09-19-19-33-25 +.. gh-issue: 116622 +.. nonce: M65UZ6 +.. section: Documentation + +Add an Android platform guide, and flag modules not available on Android. + +.. + +.. date: 2024-09-11-16-52-08 +.. gh-issue: 123976 +.. nonce: jhOfNR +.. section: Documentation + +Refresh docs around custom providers. + +.. + +.. date: 2024-08-01-17-18-21 +.. gh-issue: 70870 +.. nonce: fZnBM9 +.. section: Documentation + +Clarified the dual usage of the term "free variable" (both the formal +meaning of any reference to names defined outside the local scope, and the +narrower pragmatic meaning of nonlocal variables named in ``co_freevars``). + +.. + +.. date: 2024-07-19-12-22-48 +.. gh-issue: 121277 +.. nonce: wF_zKd +.. section: Documentation + +Writers of CPython's documentation can now use ``next`` as the version for +the ``versionchanged``, ``versionadded``, ``deprecated`` directives. + +.. + +.. date: 2024-07-14-12-25-53 +.. gh-issue: 117765 +.. nonce: YFMOUv +.. section: Documentation + +Improved documentation for :func:`unittest.mock.patch.dict` + +.. + +.. date: 2024-07-14-11-48-10 +.. gh-issue: 121749 +.. nonce: nxHoTk +.. section: Documentation + +Fix documentation for :c:func:`PyModule_AddObjectRef`. + +.. + +.. date: 2024-06-05-12-36-18 +.. gh-issue: 120012 +.. nonce: f14DbQ +.. section: Documentation + +Clarify the behaviours of :meth:`multiprocessing.Queue.empty` and +:meth:`multiprocessing.SimpleQueue.empty` on closed queues. Patch by +Bénédikt Tran. + +.. + +.. date: 2024-06-03-22-06-26 +.. gh-issue: 119574 +.. nonce: Ik9kOO +.. section: Documentation + +Added some missing environment variables to the output of +:option:`--help-env`. + +.. + +.. bpo: 34008 +.. date: 2018-07-04-20-35-25 +.. nonce: bqecIb +.. section: Documentation + +The :c:func:`Py_Main` documentation moved from the "Very High Level API" +section to the "Initialization and Finalization" section. + +Also make it explicit that we expect ``Py_Main`` to typically be called +instead of ``Py_Initialize`` rather than after it (since ``Py_Main`` makes +its own call to ``Py_Initialize``). Document that calling both is supported +but is version dependent on which settings will be applied correctly. + +.. + +.. date: 2024-10-15-15-29-41 +.. gh-issue: 124375 +.. nonce: wNrWVa +.. section: Core and Builtins + +Fix a crash in the free threading build when the GC runs concurrently with a +new thread starting. + +.. + +.. date: 2024-10-10-14-47-13 +.. gh-issue: 125221 +.. nonce: nfSQzT +.. section: Core and Builtins + +Fix possible race condition when calling :meth:`~object.__reduce_ex__` for +the first time in the free threading build. + +.. + +.. date: 2024-10-10-12-04-56 +.. gh-issue: 125174 +.. nonce: _8h6T7 +.. section: Core and Builtins + +Make the handling of reference counts of immortal objects more robust. +Immortal objects with reference counts that deviate from their original +reference count by up to a billion (half a billion on 32 bit builds) are +still counted as immortal. + +.. + +.. date: 2024-10-07-23-33-18 +.. gh-issue: 125039 +.. nonce: MKTyNI +.. section: Core and Builtins + +Make ``this_instr`` and ``prev_instr`` const in cases generator. + +.. + +.. date: 2024-10-05-23-53-06 +.. gh-issue: 125008 +.. nonce: ETANpd +.. section: Core and Builtins + +Fix :func:`tokenize.untokenize` producing invalid syntax for double braces +preceded by certain escape characters. + +.. + +.. date: 2024-10-03-22-26-39 +.. gh-issue: 124871 +.. nonce: tAMF47 +.. section: Core and Builtins + +Fix compiler bug (in some versions of 3.13) where an assertion fails during +reachability analysis. + +.. + +.. date: 2024-10-03-14-39-41 +.. gh-issue: 123378 +.. nonce: dCxANf +.. section: Core and Builtins + +Fix a crash in the :meth:`~object.__str__` method of :exc:`UnicodeError` +objects when the :attr:`UnicodeError.start` and :attr:`UnicodeError.end` +values are invalid or out-of-range. Patch by Bénédikt Tran. + +.. + +.. date: 2024-09-30-16-39-37 +.. gh-issue: 118093 +.. nonce: J2A3gz +.. section: Core and Builtins + +Improve the experimental JIT compiler's ability to stay "on trace" when +encountering highly-biased branches. + +.. + +.. date: 2024-09-27-17-18-53 +.. gh-issue: 124642 +.. nonce: OCjhBJ +.. section: Core and Builtins + +Fixed scalability issue in free-threaded builds for lock-free reads from +dictionaries in multi-threaded scenarios + +.. + +.. date: 2024-09-26-18-21-06 +.. gh-issue: 116510 +.. nonce: FacUWO +.. section: Core and Builtins + +Fix a crash caused by immortal interned strings being shared between +sub-interpreters that use basic single-phase init. In that case, the string +can be used by an interpreter that outlives the interpreter that created and +interned it. For interpreters that share obmalloc state, also share the +interned dict with the main interpreter. + +.. + +.. date: 2024-09-26-17-55-34 +.. gh-issue: 116510 +.. nonce: dhn8w8 +.. section: Core and Builtins + +Fix a bug that can cause a crash when sub-interpreters use "basic" +single-phase extension modules. Shared objects could refer to PyGC_Head +nodes that had been freed as part of interpreter cleanup. + +.. + +.. date: 2024-09-26-13-25-01 +.. gh-issue: 119180 +.. nonce: k_JCX0 +.. section: Core and Builtins + +The ``__main__`` module no longer always contains an ``__annotations__`` +dictionary in its global namespace. + +.. + +.. date: 2024-09-26-12-19-13 +.. gh-issue: 124547 +.. nonce: P_SHfU +.. section: Core and Builtins + +When deallocating an object with inline values whose ``__dict__`` is still +live: if memory allocation for the inline values fails, clear the +dictionary. Prevents an interpreter crash. + +.. + +.. date: 2024-09-25-14-45-56 +.. gh-issue: 124513 +.. nonce: ywiXtr +.. section: Core and Builtins + +Fix a crash in FrameLocalsProxy constructor: check the number of arguments. +Patch by Victor Stinner. + +.. + +.. date: 2024-09-25-11-53-22 +.. gh-issue: 124442 +.. nonce: EXC1Ve +.. section: Core and Builtins + +Fix nondeterminism in compilation by sorting the value of +:attr:`~type.__static_attributes__`. Patch by kp2pml30. + +.. + +.. date: 2024-09-23-23-06-19 +.. gh-issue: 124285 +.. nonce: mahGTg +.. section: Core and Builtins + +Fix bug where ``bool(a)`` can be invoked more than once during the +evaluation of a compound boolean expression. + +.. + +.. date: 2024-09-23-15-23-14 +.. gh-issue: 123856 +.. nonce: yrgJ9m +.. section: Core and Builtins + +Fix PyREPL failure when a keyboard interrupt is triggered after using a +history search + +.. + +.. date: 2024-09-23-13-25-27 +.. gh-issue: 65961 +.. nonce: LDqXV2 +.. section: Core and Builtins + +Deprecate the setting and using ``__package__`` and ``__cached__``. + +.. + +.. date: 2024-09-19-16-57-34 +.. gh-issue: 119726 +.. nonce: DseseK +.. section: Core and Builtins + +The JIT now generates more efficient code for calls to C functions resulting +in up to 0.8% memory savings and 1.5% speed improvement on AArch64. Patch by +Diego Russo. + +.. + +.. date: 2024-09-19-13-17-31 +.. gh-issue: 122878 +.. nonce: 4iFpsB +.. section: Core and Builtins + +Use the ``pager`` binary, if available (e.g. on Debian and derivatives), to +display REPL ``help()``. + +.. + +.. date: 2024-09-17-22-06-01 +.. gh-issue: 124188 +.. nonce: aFqNAB +.. section: Core and Builtins + +Fix reading and decoding a line from the source file witn non-UTF-8 encoding +for syntax errors raised in the compiler. + +.. + +.. date: 2024-09-13-02-25-06 +.. gh-issue: 124027 +.. nonce: to_9DY +.. section: Core and Builtins + +Support ````, ````, and ```` keys in the Python +REPL when ``$TERM`` is set to ``vt100``. + +.. + +.. date: 2024-09-12-21-53-26 +.. gh-issue: 124022 +.. nonce: fQzUiW +.. section: Core and Builtins + +Fix bug where docstring is removed from classes in interactive mode. + +.. + +.. date: 2024-09-11-15-48-36 +.. gh-issue: 123958 +.. nonce: 5VW2r0 +.. section: Core and Builtins + +docstrings are now removed from the optimized AST in optimization level 2. + +.. + +.. date: 2024-09-10-20-25-00 +.. gh-issue: 123923 +.. nonce: A7uxqa +.. section: Core and Builtins + +The ``f_executable`` field in the internal :c:struct:`_PyInterpreterFrame` +struct now uses a tagged pointer. Profilers and debuggers that uses this +field should clear the least significant bit to recover the +:c:expr:`PyObject*` pointer. + +.. + +.. date: 2024-09-10-13-27-16 +.. gh-issue: 77894 +.. nonce: ZC-Olu +.. section: Core and Builtins + +Fix possible crash in the garbage collector when it tries to break a +reference loop containing a :class:`memoryview` object. Now a +:class:`!memoryview` object can only be cleared if there are no buffers that +refer it. + +.. + +.. date: 2024-09-06-19-23-44 +.. gh-issue: 120221 +.. nonce: giJEDT +.. section: Core and Builtins + +asyncio REPL is now again properly recognizing KeyboardInterrupts. Display +of exceptions raised in secondary threads is fixed. + +.. + +.. date: 2024-09-06-14-13-01 +.. gh-issue: 119310 +.. nonce: WQxyDF +.. section: Core and Builtins + +Allow the new interactive shell to read history files written with the +editline library that use unicode-escaped entries. Patch by aorcajo and +Łukasz Langa. + +.. + +.. date: 2024-09-03-13-34-35 +.. gh-issue: 123572 +.. nonce: uuqoYV +.. section: Core and Builtins + +Fix key mappings for various F-keys in Windows for the new REPL. Patch by +devdanzin + +.. + +.. date: 2024-09-02-20-39-10 +.. gh-issue: 123614 +.. nonce: 26TMHp +.. section: Core and Builtins + +Add :func:`turtle.save` to easily save Turtle drawings as PostScript files. +Patch by Marie Roald and Yngve Mardal Moe. + +.. + +.. date: 2024-09-02-20-36-45 +.. gh-issue: 123339 +.. nonce: QcmpSs +.. section: Core and Builtins + +Setting the :attr:`!__module__` attribute for a class now removes the +``__firstlineno__`` item from the type's dict, so they will no longer be +inconsistent. + +.. + +.. date: 2024-09-02-17-32-15 +.. gh-issue: 119034 +.. nonce: HYh5Vj +.. section: Core and Builtins + +Change ```` and ```` keys of the Python REPL to history +search forward/backward. Patch by Victor Stinner. + +.. + +.. date: 2024-09-01-12-08-39 +.. gh-issue: 123562 +.. nonce: aJPKVu +.. section: Core and Builtins + +Improve :exc:`SyntaxError` message for using ``case ... as ...`` with not a +name. + +.. + +.. date: 2024-09-01-00-02-05 +.. gh-issue: 123545 +.. nonce: 8nQNbL +.. section: Core and Builtins + +Fix a double decref in rare cases on experimental JIT builds. + +.. + +.. date: 2024-08-29-19-46-07 +.. gh-issue: 123484 +.. nonce: rjUn_F +.. section: Core and Builtins + +Fix ``_Py_DebugOffsets`` for long objects to be relative to the start of the +object rather than the start of a subobject. + +.. + +.. date: 2024-08-29-13-18-18 +.. gh-issue: 123446 +.. nonce: KWDrgq +.. section: Core and Builtins + +Fix empty function name in :exc:`TypeError` when builtin magic methods are +used without the required args. + +.. + +.. date: 2024-08-28-22-42-51 +.. gh-issue: 123440 +.. nonce: yOFB0N +.. section: Core and Builtins + +Improve :exc:`SyntaxError` message for using ``except as`` with not a name. + +.. + +.. date: 2024-08-27-21-44-14 +.. gh-issue: 116017 +.. nonce: ZY3yBY +.. section: Core and Builtins + +Improved JIT memory consumption by periodically freeing memory used by +infrequently-executed code. This change is especially likely to improve the +memory footprint of long-running programs. + +.. + +.. date: 2024-08-27-13-16-40 +.. gh-issue: 123344 +.. nonce: 56Or78 +.. section: Core and Builtins + +Add AST optimizations for type parameter defaults. + +.. + +.. date: 2024-08-26-00-58-26 +.. gh-issue: 123321 +.. nonce: ApxcnE +.. section: Core and Builtins + +Prevent Parser/myreadline race condition from segfaulting on multi-threaded +use. Patch by Bar Harel and Amit Wienner. + +.. + +.. date: 2024-08-25-18-27-49 +.. gh-issue: 123177 +.. nonce: yLuyqE +.. section: Core and Builtins + +Fix a bug causing stray prompts to appear in the middle of wrapped lines in +the new REPL. + +.. + +.. date: 2024-08-25-10-54-22 +.. gh-issue: 122982 +.. nonce: KLD91q +.. section: Core and Builtins + +Extend the deprecation period for bool inversion (``~``) by two years. + +.. + +.. date: 2024-08-23-21-20-34 +.. gh-issue: 123271 +.. nonce: xeVViR +.. section: Core and Builtins + +Make concurrent iterations over the same :func:`zip` iterator safe under +free-threading. + +.. + +.. date: 2024-08-23-18-31-10 +.. gh-issue: 123275 +.. nonce: DprIrj +.. section: Core and Builtins + +Support :option:`-X gil=1 <-X>` and :envvar:`PYTHON_GIL=1 ` on +non-free-threaded builds. + +.. + +.. date: 2024-08-23-15-59-54 +.. gh-issue: 123177 +.. nonce: OLcaC5 +.. section: Core and Builtins + +Deactivate line wrap in the Apple Terminal via a ANSI escape code. Patch by +Pablo Galindo + +.. + +.. date: 2024-08-23-13-08-27 +.. gh-issue: 123229 +.. nonce: aHm-dw +.. section: Core and Builtins + +Fix valgrind warning by initializing the f-string buffers to 0 in the +tokenizer. Patch by Pablo Galindo + +.. + +.. date: 2024-08-23-11-26-54 +.. gh-issue: 122298 +.. nonce: ZMyln4 +.. section: Core and Builtins + +Restore printout of GC stats when ``gc.set_debug(gc.DEBUG_STATS)`` is +called. This feature was accidentally removed when implementing incremental +GC. + +.. + +.. date: 2024-08-21-15-22-53 +.. gh-issue: 121804 +.. nonce: r5K3PS +.. section: Core and Builtins + +Correctly show error locations when a :exc:`SyntaxError` is raised in the +basic REPL. Patch by Sergey B Kirpichev. + +.. + +.. date: 2024-08-21-08-53-00 +.. gh-issue: 115776 +.. nonce: 9A7Dv_ +.. section: Core and Builtins + +Enables inline values (Python's equivalent of hidden classes) on any class +who's instances are of a fixed size. + +.. + +.. date: 2024-08-20-12-29-52 +.. gh-issue: 123142 +.. nonce: 3PXiNb +.. section: Core and Builtins + +Fix too-wide source location in exception tracebacks coming from broken +iterables in comprehensions. + +.. + +.. date: 2024-08-20-11-09-16 +.. gh-issue: 123048 +.. nonce: 2TISpv +.. section: Core and Builtins + +Fix a bug where pattern matching code could emit a :opcode:`JUMP_FORWARD` +with no source location. + +.. + +.. date: 2024-08-19-15-13-13 +.. gh-issue: 118093 +.. nonce: dLZ8qS +.. section: Core and Builtins + +Break up ``CALL_ALLOC_AND_ENTER_INIT`` into micro-ops and relax requirement +for exact args, in order to increase the amount of code supported by tier 2. + +.. + +.. date: 2024-08-18-18-25-54 +.. gh-issue: 123123 +.. nonce: 0ZcaEB +.. section: Core and Builtins + +Fix displaying :exc:`SyntaxError` exceptions covering multiple lines. Patch +by Pablo Galindo + +.. + +.. date: 2024-08-17-17-26-25 +.. gh-issue: 123083 +.. nonce: 9xWLJ- +.. section: Core and Builtins + +Fix a potential use-after-free in ``STORE_ATTR_WITH_HINT``. + +.. + +.. date: 2024-08-15-19-28-43 +.. gh-issue: 123022 +.. nonce: m3EF9E +.. section: Core and Builtins + +Fix crash in free-threaded build when calling :c:func:`Py_Initialize` from a +non-main thread. + +.. + +.. date: 2024-08-14-11-38-56 +.. gh-issue: 118093 +.. nonce: 3BywDP +.. section: Core and Builtins + +Add three specializations for :opcode:`CALL_KW`: + +* :opcode:`!CALL_KW_PY` for calls to Python functions +* :opcode:`!CALL_KW_BOUND_METHOD` for calls to bound methods +* :opcode:`!CALL_KW_NON_PY` for all other calls + +.. + +.. date: 2024-08-12-11-45-47 +.. gh-issue: 122821 +.. nonce: WnAzTK +.. section: Core and Builtins + +Make sure that branches in :keyword:`while` statements have consistent +offsets for :mod:`sys.monitoring`. :keyword:`!while` statements are now +compiled with a simple jump at the end of the body, instead of duplicating +the test. + +.. + +.. date: 2024-08-12-11-19-37 +.. gh-issue: 122907 +.. nonce: q68096 +.. section: Core and Builtins + +Building with ``HAVE_DYNAMIC_LOADING`` now works as well as it did in 3.12. +Existing deficiences will be addressed separately. (See +https://github.com/python/cpython/issues/122950.) + +.. + +.. date: 2024-08-10-12-44-03 +.. gh-issue: 122888 +.. nonce: TUyu9r +.. section: Core and Builtins + +Fix crash on certain calls to ``str()`` with positional arguments of the +wrong type. Patch by Jelle Zijlstra. + +.. + +.. date: 2024-08-08-16-02-28 +.. gh-issue: 118093 +.. nonce: m6Mrvy +.. section: Core and Builtins + +Improve the experimental JIT's handling of polymorphic code. + +.. + +.. date: 2024-08-05-19-28-12 +.. gh-issue: 122697 +.. nonce: 17MvYl +.. section: Core and Builtins + +Fixed memory leaks at interpreter shutdown in the free-threaded build, and +also reporting of leaked memory blocks via :option:`-X showrefcount <-X>`. + +.. + +.. date: 2024-08-05-19-04-06 +.. gh-issue: 116622 +.. nonce: 3LWUzE +.. section: Core and Builtins + +Fix Android stdout and stderr messages being truncated or lost. + +.. + +.. date: 2024-08-01-19-13-58 +.. gh-issue: 122527 +.. nonce: eztso6 +.. section: Core and Builtins + +Fix a crash that occurred when a ``PyStructSequence`` was deallocated after +its type's dictionary was cleared by the GC. The type's +:c:member:`~PyTypeObject.tp_basicsize` now accounts for non-sequence fields +that aren't included in the :c:macro:`Py_SIZE` of the sequence. + +.. + +.. date: 2024-07-30-11-41-35 +.. gh-issue: 122445 +.. nonce: Rq0bjS +.. section: Core and Builtins + +Add only fields which are modified via self.* to +:attr:`~type.__static_attributes__`. + +.. + +.. date: 2024-07-29-19-20-25 +.. gh-issue: 122417 +.. nonce: NVgs0a +.. section: Core and Builtins + +In the free-threaded build, the reference counts for heap type objects are +now partially stored in a distributed manner in per-thread arrays. This +reduces contention on the heap type's reference count fields when creating +or destroying instances of the same type from multiple threads concurrently. + +.. + +.. date: 2024-07-29-10-55-46 +.. gh-issue: 116090 +.. nonce: p1MhU0 +.. section: Core and Builtins + +Fix an issue in JIT builds that prevented some :keyword:`for` loops from +correctly firing :monitoring-event:`RAISE` monitoring events. + +.. + +.. date: 2024-07-26-14-05-51 +.. gh-issue: 122300 +.. nonce: SVIF-l +.. section: Core and Builtins + +Preserve AST nodes for f-string with single-element format specifiers. Patch +by Pablo Galindo + +.. + +.. date: 2024-07-26-13-56-32 +.. gh-issue: 120906 +.. nonce: qBh2I9 +.. section: Core and Builtins + +:attr:`frame.f_locals` now supports arbitrary hashable objects as keys. + +.. + +.. date: 2024-07-25-01-45-21 +.. gh-issue: 122239 +.. nonce: 7zh-sW +.. section: Core and Builtins + +When a :class:`list`, :class:`tuple` or :class:`dict` with too many elements +is unpacked, show the actual length in the error message. + +.. + +.. date: 2024-07-24-22-39-07 +.. gh-issue: 122245 +.. nonce: LVa9v8 +.. section: Core and Builtins + +Detection of writes to ``__debug__`` is moved from the compiler's codegen +stage to the symtable. This means that these errors are now detected even in +code that is optimized away before codegen (such as assertions with the +:option:`-O` command line option). + +.. + +.. date: 2024-07-24-17-11-51 +.. gh-issue: 122234 +.. nonce: VxsP_F +.. section: Core and Builtins + +Specializations for sums with float and complex inputs in :func:`sum` now +always use compensated summation. Also, for integer items in above +specializations: :c:func:`PyLong_AsDouble` is used, instead of +:c:func:`PyLong_AsLongAndOverflow`. Patch by Sergey B Kirpichev. + +.. + +.. date: 2024-07-23-23-59-04 +.. gh-issue: 122208 +.. nonce: z8KHsY +.. section: Core and Builtins + +Dictionary watchers now only deliver the PyDict_EVENT_ADDED event when the +insertion is in a known good state to succeed. + +.. + +.. date: 2024-07-23-11-57-36 +.. gh-issue: 122160 +.. nonce: HSnrAP +.. section: Core and Builtins + +Remove the ``BUILD_CONST_KEY_MAP`` opcode. Use :opcode:`BUILD_MAP` instead. + +.. + +.. date: 2024-07-21-01-23-54 +.. gh-issue: 122029 +.. nonce: gKv-e2 +.. section: Core and Builtins + +Emit ``c_call`` events in :func:`sys.setprofile` when a ``PyMethodObject`` +pointing to a ``PyCFunction`` is called. + +.. + +.. date: 2024-07-19-15-28-05 +.. gh-issue: 122026 +.. nonce: sta2Ca +.. section: Core and Builtins + +Fix a bug that caused the tokenizer to not correctly identify mismatched +parentheses inside f-strings in some situations. Patch by Pablo Galindo + +.. + +.. date: 2024-07-19-09-38-01 +.. gh-issue: 99108 +.. nonce: qzM6gl +.. section: Core and Builtins + +Python's hashlib now unconditionally uses the vendored HACL* library for +Blake2. Python no longer accepts libb2 as an optional dependency for Blake2. + +We refreshed HACL* to the latest version, and now vendor HACL*'s 128-bit and +256-bit wide vector implementations for Blake2, which are used on x86/x64 +toolchains when the required CPU features are available at runtime. + +HACL*'s 128-bit wide vector implementation of Blake2 can also run on ARM +NEON and Power8, but lacking evidence of a performance gain, these are not +enabled (yet). + +.. + +.. date: 2024-07-18-21-19-04 +.. gh-issue: 121999 +.. nonce: 8IBbTK +.. section: Core and Builtins + +The default extraction filter for the :mod:`tarfile` module is now set to +:func:`'data' `. + +.. + +.. date: 2024-07-16-18-23-22 +.. gh-issue: 121860 +.. nonce: -FTauD +.. section: Core and Builtins + +Fix crash when rematerializing a managed dictionary after it was deleted. + +.. + +.. date: 2024-07-16-15-11-51 +.. gh-issue: 121795 +.. nonce: xkIHrI +.. section: Core and Builtins + +Improve performance of set membership testing, ``set.remove()`` and +``set.discard()`` when the argument is a set. + +.. + +.. date: 2024-07-15-20-41-06 +.. gh-issue: 121814 +.. nonce: oR2ixR +.. section: Core and Builtins + +Fixed the SegFault when :c:func:`PyEval_SetTrace` is used with no Python +frame on stack. + +.. + +.. date: 2024-07-15-20-03-29 +.. gh-issue: 121295 +.. nonce: w53ucI +.. section: Core and Builtins + +Fix PyREPL console getting into a blocked state after interrupting a long +paste + +.. + +.. date: 2024-07-15-16-26-32 +.. gh-issue: 121794 +.. nonce: fhBtiQ +.. section: Core and Builtins + +Fix bug in free-threaded Python where a resurrected object could lead to a +negative ref count assertion failure. + +.. + +.. date: 2024-07-13-12-27-31 +.. gh-issue: 121657 +.. nonce: wgOYLw +.. section: Core and Builtins + +Improve the :exc:`SyntaxError` message if the user tries to use +:keyword:`yield from ` outside a function. + +.. + +.. date: 2024-07-13-09-51-44 +.. gh-issue: 121609 +.. nonce: jWsE5t +.. section: Core and Builtins + +Fix pasting of characters containing unicode character joiners in the new +REPL. Patch by Marta Gomez Macias + +.. + +.. date: 2024-07-12-18-18-44 +.. gh-issue: 121297 +.. nonce: 67VE7b +.. section: Core and Builtins + +Previously, incorrect usage of :keyword:`await` or asynchronous +comprehensions in code removed by the :option:`-O` option was not flagged by +the Python compiler. Now, such code raises :exc:`SyntaxError`. Patch by +Jelle Zijlstra. + +.. + +.. date: 2024-07-10-15-43-54 +.. gh-issue: 117482 +.. nonce: 5WYaXR +.. section: Core and Builtins + +Unexpected slot wrappers are no longer created for builtin static types in +subinterpreters. + +.. + +.. date: 2024-07-10-02-02-32 +.. gh-issue: 121562 +.. nonce: 8beIMi +.. section: Core and Builtins + +Optimized performance of hex_from_char by replacing switch-case with a +lookup table + +.. + +.. date: 2024-07-09-13-53-18 +.. gh-issue: 121499 +.. nonce: rpp7il +.. section: Core and Builtins + +Fix a bug affecting how multi-line history was being rendered in the new +REPL after interacting with the new screen cache. Patch by Pablo Galindo + +.. + +.. date: 2024-07-08-17-15-14 +.. gh-issue: 121497 +.. nonce: I8hMDC +.. section: Core and Builtins + +Fix a bug that was preventing the REPL to correctly respect the history when +an input hook was set. Patch by Pablo Galindo + +.. + +.. date: 2024-07-08-10-31-08 +.. gh-issue: 121012 +.. nonce: M5hHk- +.. section: Core and Builtins + +Tier 2 execution now ensures that list iterators remain exhausted, once they +become exhausted. + +.. + +.. date: 2024-07-08-02-24-55 +.. gh-issue: 121439 +.. nonce: jDHod3 +.. section: Core and Builtins + +Allow tuples of length 20 in the freelist to be reused. + +.. + +.. date: 2024-07-05-11-29-27 +.. gh-issue: 121288 +.. nonce: lYKYYP +.. section: Core and Builtins + +:exc:`ValueError` messages for :meth:`!list.index`, :meth:`!range.index`, +:meth:`!deque.index`, :meth:`!deque.remove` and :meth:`!ShareableList.index` +no longer contain the repr of the searched value (which can be arbitrary +large) and are consistent with error messages for other :meth:`!index` and +:meth:`!remove` methods. + +.. + +.. date: 2024-07-04-23-38-30 +.. gh-issue: 121368 +.. nonce: m3EF9E +.. section: Core and Builtins + +Fix race condition in ``_PyType_Lookup`` in the free-threaded build due to a +missing memory fence. This could lead to ``_PyType_Lookup`` returning +incorrect results on arm64. + +.. + +.. date: 2024-06-30-03-48-10 +.. gh-issue: 121149 +.. nonce: lLBMKe +.. section: Core and Builtins + +Added specialization for summation of complexes, this also improves accuracy +of builtin :func:`sum` for such inputs. Patch by Sergey B Kirpichev. + +.. + +.. date: 2024-06-29-10-46-14 +.. gh-issue: 121130 +.. nonce: Rj66Xs +.. section: Core and Builtins + +Fix f-strings with debug expressions in format specifiers. Patch by Pablo +Galindo + +.. + +.. date: 2024-06-28-23-17-22 +.. gh-issue: 121381 +.. nonce: i2xL7P +.. section: Core and Builtins + +Remove ``subprocess._USE_VFORK`` escape hatch code and documentation. It was +added just in case, and doesn't have any known cases that require it. + +.. + +.. date: 2024-06-28-18-34-49 +.. gh-issue: 119726 +.. nonce: Fjv_Ab +.. section: Core and Builtins + +Optimize code layout for calls to C functions from the JIT on AArch64. Patch +by Diego Russo. + +.. + +.. date: 2024-06-28-10-02-58 +.. gh-issue: 121115 +.. nonce: EeSLfc +.. section: Core and Builtins + +:c:func:`PyLong_AsNativeBytes` no longer uses :meth:`~object.__index__` +methods by default. The ``Py_ASNATIVEBYTES_ALLOW_INDEX`` flag has been added +to allow it. + +.. + +.. date: 2024-06-26-14-09-31 +.. gh-issue: 120838 +.. nonce: nFeTL9 +.. section: Core and Builtins + +:c:func:`Py_Finalize()` and :c:func:`Py_FinalizeEx()` now always run with +the main interpreter active. + +.. + +.. date: 2024-06-26-13-42-36 +.. gh-issue: 113433 +.. nonce: xKAtLB +.. section: Core and Builtins + +Subinterpreters now get cleaned up automatically during runtime +finalization. + +.. + +.. date: 2024-06-25-16-26-44 +.. gh-issue: 119726 +.. nonce: WqvHxB +.. section: Core and Builtins + +Improve the speed and memory use of C function calls from JIT code on +AArch64. Patch by Diego Russo + +.. + +.. date: 2024-06-24-08-39-23 +.. gh-issue: 116017 +.. nonce: -Bw2UY +.. section: Core and Builtins + +Simplify the warmup mechanism used for "side exits" in JIT code, resulting +in slightly better performance and slightly lower memory usage for most +platforms. + +.. + +.. date: 2024-06-19-21-34-21 +.. gh-issue: 98442 +.. nonce: cqhjkN +.. section: Core and Builtins + +Fix too wide source locations of the cleanup instructions of a with +statement. + +.. + +.. date: 2024-06-19-19-54-35 +.. gh-issue: 120754 +.. nonce: uF29sj +.. section: Core and Builtins + +Reduce the number of system calls invoked when reading a whole file (ex. +``open('a.txt').read()``). For a sample program that reads the contents of +the 400+ ``.rst`` files in the cpython repository ``Doc`` folder, there is +an over 10% reduction in system call count. + +.. + +.. date: 2024-06-19-11-10-50 +.. gh-issue: 119462 +.. nonce: DpcqSe +.. section: Core and Builtins + +Make sure that invariants of type versioning are maintained: * Superclasses +always have their version number assigned before subclasses * The version +tag is always zero if the tag is not valid. * The version tag is always +non-if the tag is valid. + +.. + +.. date: 2024-06-19-01-58-54 +.. gh-issue: 120437 +.. nonce: nCkIoI +.. section: Core and Builtins + +Fix ``_CHECK_STACK_SPACE`` optimization problems introduced in :gh:`118322`. + +.. + +.. date: 2024-06-18-22-41-05 +.. gh-issue: 120722 +.. nonce: rS7tkE +.. section: Core and Builtins + +Correctly set the bytecode position on return instructions within lambdas. +Patch by Jelle Zijlstra. + +.. + +.. date: 2024-06-18-21-34-30 +.. gh-issue: 120367 +.. nonce: zDwffP +.. section: Core and Builtins + +Fix bug where compiler creates a redundant jump during pseudo-op +replacement. Can only happen with a synthetic AST that has a try on the same +line as the instruction following the exception handler. + +.. + +.. date: 2024-06-17-12-20-20 +.. gh-issue: 120507 +.. nonce: 94lz2J +.. section: Core and Builtins + +Remove the ``BEFORE_WITH`` and ``BEFORE_ASYNC_WITH`` instructions. Add the +new :opcode:`LOAD_SPECIAL` instruction. Generate code for ``with`` and +``async with`` statements using the new instruction. + +.. + +.. date: 2024-06-14-22-02-25 +.. gh-issue: 113993 +.. nonce: MiA0vX +.. section: Core and Builtins + +Strings interned with :func:`sys.intern` are again garbage-collected when no +longer used, as per the documentation. Strings interned with the C function +:c:func:`PyUnicode_InternInPlace` are still immortal. Internals of the +string interning mechanism have been changed. This may affect performance +and identities of :class:`str` objects. + +.. + +.. date: 2024-06-14-07-52-00 +.. gh-issue: 120485 +.. nonce: yy4K4b +.. section: Core and Builtins + +Add an override of ``allow_reuse_port`` on classes subclassing +``socketserver.TCPServer`` where ``allow_reuse_address`` is also overridden. + +.. + +.. date: 2024-06-13-12-17-52 +.. gh-issue: 120384 +.. nonce: w1UBGl +.. section: Core and Builtins + +Fix an array out of bounds crash in ``list_ass_subscript``, which could be +invoked via some specifically tailored input: including concurrent +modification of a list object, where one thread assigns a slice and another +clears it. + +.. + +.. date: 2024-06-12-18-50-29 +.. gh-issue: 120367 +.. nonce: LmXx2y +.. section: Core and Builtins + +Fix crash in compiler on code with redundant NOPs and JUMPs which show up +after exception handlers are moved to the end of the code. + +.. + +.. date: 2024-06-12-18-23-15 +.. gh-issue: 120380 +.. nonce: edtqjq +.. section: Core and Builtins + +Fix Python implementation of :class:`pickle.Pickler` for :class:`bytes` and +:class:`bytearray` objects when using protocol version 5. Patch by Bénédikt +Tran. + +.. + +.. date: 2024-06-12-13-47-25 +.. gh-issue: 120397 +.. nonce: n-I_cc +.. section: Core and Builtins + +Improve the throughput by up to two times for the :meth:`str.count`, +:meth:`bytes.count` and :meth:`bytearray.count` methods for counting single +characters. + +.. + +.. date: 2024-06-11-17-56-12 +.. gh-issue: 120221 +.. nonce: si9hM9 +.. section: Core and Builtins + +Deliver real signals on Ctrl-C and Ctrl-Z in the new REPL. Patch by Pablo +Galindo + +.. + +.. date: 2024-06-11-12-47-54 +.. gh-issue: 120346 +.. nonce: hhn_6X +.. section: Core and Builtins + +Respect :envvar:`PYTHON_BASIC_REPL` when running in interactive inspect mode +(``python -i``). Patch by Pablo Galindo + +.. + +.. date: 2024-06-10-22-30-26 +.. gh-issue: 93691 +.. nonce: 68WOTS +.. section: Core and Builtins + +Fix source locations of instructions generated for the iterator of a for +statement. + +.. + +.. date: 2024-06-10-15-07-16 +.. gh-issue: 120198 +.. nonce: WW_pjO +.. section: Core and Builtins + +Fix a crash when multiple threads read and write to the same ``__class__`` +of an object concurrently. + +.. + +.. date: 2024-06-10-10-42-48 +.. gh-issue: 120298 +.. nonce: napREA +.. section: Core and Builtins + +Fix use-after free in ``list_richcompare_impl`` which can be invoked via +some specifically tailored evil input. + +.. + +.. date: 2024-06-09-19-13-38 +.. gh-issue: 119666 +.. nonce: S0G4rZ +.. section: Core and Builtins + +Fix a compiler crash in the case where two comprehensions in class scope +both reference ``__class__``. + +.. + +.. date: 2024-06-07-22-54-15 +.. gh-issue: 119726 +.. nonce: D9EE-o +.. section: Core and Builtins + +JIT: Re-use trampolines on AArch64 when creating stencils. Patch by Diego +Russo + +.. + +.. date: 2024-06-07-16-09-04 +.. gh-issue: 120225 +.. nonce: kuYf9t +.. section: Core and Builtins + +Fix crash in compiler on empty block at end of exception handler. + +.. + +.. date: 2024-06-05-18-29-18 +.. gh-issue: 93691 +.. nonce: 6OautB +.. section: Core and Builtins + +Fix source locations of instructions generated for with statements. + +.. + +.. date: 2024-06-05-10-32-44 +.. gh-issue: 120097 +.. nonce: 9S2klk +.. section: Core and Builtins + +``FrameLocalsProxy`` now subclasses ``collections.abc.Mapping`` and can be +matched as a mapping in ``match`` statements + +.. + +.. date: 2024-06-05-08-39-40 +.. gh-issue: 120080 +.. nonce: DJFK11 +.. section: Core and Builtins + +Direct call to the :meth:`!int.__round__` now accepts ``None`` as a valid +argument. + +.. + +.. date: 2024-06-03-13-48-44 +.. gh-issue: 119933 +.. nonce: Kc0HG5 +.. section: Core and Builtins + +Improve :exc:`SyntaxError` messages for invalid expressions in a type +parameters bound, a type parameter constraint tuple or a default type +parameter. Patch by Bénédikt Tran. + +.. + +.. date: 2024-06-03-13-25-04 +.. gh-issue: 119724 +.. nonce: EH1dkA +.. section: Core and Builtins + +Reverted improvements to error messages for ``elif``/``else`` statements not +matching any valid statements, which made in hard to locate the syntax +errors inside those ``elif``/``else`` blocks. + +.. + +.. date: 2024-06-02-06-12-35 +.. gh-issue: 119879 +.. nonce: Jit951 +.. section: Core and Builtins + +String search is now slightly faster for certain cases. It now utilizes last +character gap (good suffix rule) for two-way periodic needles. + +.. + +.. date: 2024-05-31-12-06-11 +.. gh-issue: 119842 +.. nonce: tCGVsv +.. section: Core and Builtins + +Honor :c:func:`PyOS_InputHook` in the new REPL. Patch by Pablo Galindo + +.. + +.. date: 2024-05-31-08-23-41 +.. gh-issue: 119180 +.. nonce: KL4VxZ +.. section: Core and Builtins + +:func:`classmethod` and :func:`staticmethod` now wrap the +:attr:`~object.__annotations__` and :attr:`~object.__annotate__` attributes +of their underlying callable lazily. See :pep:`649`. Patch by Jelle +Zijlstra. + +.. + +.. date: 2024-05-30-23-01-00 +.. gh-issue: 119821 +.. nonce: jPGfvt +.. section: Core and Builtins + +Fix execution of :ref:`annotation scopes ` within classes +when ``globals`` is set to a non-dict. Patch by Jelle Zijlstra. + +.. + +.. date: 2024-05-30-04-11-36 +.. gh-issue: 118934 +.. nonce: fbDqve +.. section: Core and Builtins + +Make ``PyEval_GetLocals`` return borrowed reference + +.. + +.. date: 2024-05-29-18-53-43 +.. gh-issue: 119740 +.. nonce: zP2JNM +.. section: Core and Builtins + +Remove the previously-deprecated delegation of :func:`int` to +:meth:`~object.__trunc__`. + +.. + +.. date: 2024-05-28-22-49-56 +.. gh-issue: 119689 +.. nonce: VwLFD5 +.. section: Core and Builtins + +Generate stack effect metadata for pseudo instructions from bytecodes.c. + +.. + +.. date: 2024-05-27-19-13-49 +.. gh-issue: 109218 +.. nonce: -sdDg0 +.. section: Core and Builtins + +:func:`complex` accepts now a string only as a positional argument. Passing +a complex number as the "real" or "imag" argument is deprecated; it should +only be passed as a single positional argument. + +.. + +.. date: 2024-05-25-16-45-27 +.. gh-issue: 119548 +.. nonce: pqF9Y6 +.. section: Core and Builtins + +Add a ``clear`` command to the REPL. Patch by Pablo Galindo + +.. + +.. date: 2024-05-25-13-51-48 +.. gh-issue: 111999 +.. nonce: L0q1gh +.. section: Core and Builtins + +Fix the signature of :meth:`str.format_map`. + +.. + +.. date: 2024-05-25-12-52-25 +.. gh-issue: 119560 +.. nonce: wSlm8q +.. section: Core and Builtins + +An invalid assert in beta 1 has been removed. The assert would fail if +``PyState_FindModule()`` was used in an extension module's init function +before the module def had been initialized. + +.. + +.. date: 2024-05-24-21-16-52 +.. gh-issue: 119369 +.. nonce: qBThho +.. section: Core and Builtins + +Fix deadlock during thread deletion in free-threaded build, which could +occur when the GIL was enabled at runtime. + +.. + +.. date: 2024-05-24-21-04-00 +.. gh-issue: 119525 +.. nonce: zLFLf1 +.. section: Core and Builtins + +Fix deadlock involving ``_PyType_Lookup()`` cache in the free-threaded build +when the GIL is dynamically enabled at runtime. + +.. + +.. date: 2024-05-23-20-17-37 +.. gh-issue: 119258 +.. nonce: wZFIpt +.. section: Core and Builtins + +Eliminate type version guards in the tier two interpreter. + +Note that setting the ``tp_version_tag`` manually (which has never been +supported) may result in crashes. + +.. + +.. date: 2024-05-23-06-34-45 +.. gh-issue: 119311 +.. nonce: 2DBwKR +.. section: Core and Builtins + +Fix bug where names are unexpectedly mangled in the bases of generic +classes. + +.. + +.. date: 2024-05-23-06-34-14 +.. gh-issue: 119395 +.. nonce: z-Hsqb +.. section: Core and Builtins + +Fix bug where names appearing after a generic class are mangled as if they +are in the generic class. + +.. + +.. date: 2024-05-22-12-49-03 +.. gh-issue: 119372 +.. nonce: PXig1R +.. section: Core and Builtins + +Correct invalid corner cases in complex division (resulted in ``(nan+nanj)`` +output), e.g. ``1/complex('(inf+infj)')``. Patch by Sergey B Kirpichev. + +.. + +.. date: 2024-05-22-06-22-47 +.. gh-issue: 119180 +.. nonce: vZMiXm +.. section: Core and Builtins + +Evaluation of annotations is now deferred. See :pep:`649` for details. + +.. + +.. date: 2024-05-21-12-17-02 +.. gh-issue: 119180 +.. nonce: UNDUb9 +.. section: Core and Builtins + +Replace :opcode:`!LOAD_ASSERTION_ERROR` opcode with +:opcode:`LOAD_COMMON_CONSTANT` and add support for +:exc:`NotImplementedError`. + +.. + +.. date: 2024-05-21-11-27-14 +.. gh-issue: 119213 +.. nonce: nxjxrt +.. section: Core and Builtins + +Non-builtin modules built with argument clinic were crashing if used in a +subinterpreter before the main interpreter. The objects that were causing +the problem by leaking between interpreters carelessly have been fixed. + +.. + +.. date: 2024-05-21-09-46-51 +.. gh-issue: 119011 +.. nonce: WOe3bu +.. section: Core and Builtins + +Fixes ``type.__type_params__`` to return an empty tuple instead of a +descriptor. + +.. + +.. date: 2024-05-20-14-57-39 +.. gh-issue: 118692 +.. nonce: Qadm7F +.. section: Core and Builtins + +Avoid creating unnecessary :exc:`StopIteration` instances for monitoring. + +.. + +.. date: 2024-05-20-10-10-51 +.. gh-issue: 119180 +.. nonce: 35xqpu +.. section: Core and Builtins + +Add an ``__annotate__`` attribute to functions, classes, and modules as part +of :pep:`649`. Patch by Jelle Zijlstra. + +.. + +.. date: 2024-05-16-23-02-03 +.. gh-issue: 119049 +.. nonce: qpd_S- +.. section: Core and Builtins + +Fix displaying the source line for warnings created by the C API if the +:mod:`warnings` module had not yet been imported. + +.. + +.. date: 2024-05-15-12-15-58 +.. gh-issue: 119057 +.. nonce: P3G9G2 +.. section: Core and Builtins + +Improve :exc:`ZeroDivisionError` error message. Now, all error messages are +harmonized: all ``/``, ``//``, and ``%`` operations just use "division by +zero" message. And ``0 ** -1`` operation uses "zero to a negative power". + +.. + +.. date: 2024-05-11-21-44-17 +.. gh-issue: 118844 +.. nonce: q2H_km +.. section: Core and Builtins + +Fix build failures when configuring with both ``--disable-gil`` and +``--enable-experimental-jit``. + +.. + +.. date: 2024-05-10-19-54-18 +.. gh-issue: 118921 +.. nonce: O4ztZG +.. section: Core and Builtins + +Add ``copy()`` method for ``FrameLocalsProxy`` which returns a snapshot +``dict`` for local variables. + +.. + +.. date: 2024-05-09-19-47-12 +.. gh-issue: 117657 +.. nonce: Vn0Yey +.. section: Core and Builtins + +Fix data races on the field that stores a pointer to the interpreter's main +thread that occur in free-threaded builds. + +.. + +.. date: 2024-05-09-02-37-25 +.. gh-issue: 118750 +.. nonce: 7aLfT- +.. section: Core and Builtins + +If the C version of the ``decimal`` module is available, ``int(str)`` now +uses it to supply an asymptotically much faster conversion. However, this +only applies if the string contains over about 2 million digits. + +.. + +.. date: 2024-05-08-09-44-15 +.. gh-issue: 118767 +.. nonce: iFF5F5 +.. section: Core and Builtins + +Using :data:`NotImplemented` in a boolean context now raises +:exc:`TypeError`. Contributed by Jelle Zijlstra. + +.. + +.. date: 2024-05-07-16-57-56 +.. gh-issue: 118561 +.. nonce: wNMKVd +.. section: Core and Builtins + +Fix race condition in free-threaded build where :meth:`!list.extend` could +expose uninitialised memory to concurrent readers. + +.. + +.. date: 2024-05-01-05-09-16 +.. gh-issue: 117139 +.. nonce: t41w_D +.. section: Core and Builtins + +Convert the Python evaluation stack to use internal stack references. The +purpose is to support tagged pointers. In :pep:`703`, this will allow for +its form of deferred reference counting. For both the default and +free-threaded builds, this sets up the infrastructure for unboxed integers +in the future. + +.. + +.. date: 2024-04-27-18-36-46 +.. gh-issue: 115801 +.. nonce: SVeHSy +.. section: Core and Builtins + +Raise ``TypeError`` when passing a string to :func:`difflib.unified_diff` +and :func:`difflib.context_diff`. + +.. + +.. date: 2024-04-08-13-49-02 +.. gh-issue: 117558 +.. nonce: 9lSEpR +.. section: Core and Builtins + +Improve error messages when a string, bytes or bytearray object of length 1 +is expected. + +.. + +.. date: 2024-03-25-15-07-01 +.. gh-issue: 117195 +.. nonce: OWakgD +.. section: Core and Builtins + +Avoid assertion failure for debug builds when calling +``object.__sizeof__(1)`` + +.. + +.. date: 2024-03-19-22-21-22 +.. gh-issue: 116022 +.. nonce: iyHENN +.. section: Core and Builtins + +Improve the :meth:`~object.__repr__` output of :class:`~ast.AST` nodes. + +.. + +.. date: 2024-01-15-21-51-26 +.. gh-issue: 114091 +.. nonce: VOtSJl +.. section: Core and Builtins + +Changed the error message for awaiting something that can't be awaited from +"object can't be used in an await expression" to "'' object +can't be awaited". + +.. + +.. date: 2024-01-15-18-11-48 +.. gh-issue: 113190 +.. nonce: OwQX64 +.. section: Core and Builtins + +:c:func:`Py_Finalize` now deletes all interned strings. + +.. + +.. date: 2023-10-14-23-05-40 +.. gh-issue: 84978 +.. nonce: Z0t6dg +.. section: Core and Builtins + +Add class methods :meth:`float.from_number` and :meth:`complex.from_number`. + +.. + +.. date: 2022-07-22-15-56-35 +.. gh-issue: 95144 +.. nonce: FZYWX- +.. section: Core and Builtins + +Improve the error message from ``a in b`` when ``b`` is not a container to +mention the term "container". + +.. + +.. bpo: 24766 +.. date: 2018-10-09-15-14-53 +.. nonce: c_C1Wc +.. section: Core and Builtins + +Fix handling of ``doc`` argument to subclasses of ``property``. + +.. + +.. date: 2024-10-03-14-06-08 +.. gh-issue: 123961 +.. nonce: uwJQTY +.. section: C API + +Convert the :ref:`curses.window ` static type exposed +by the :c:macro:`!PyCursesWindow_Type` macro in ``Include/py_curses.h`` to a +:ref:`heap type `. Patch by Bénédikt Tran. + +.. + +.. date: 2024-09-25-11-44-02 +.. gh-issue: 124502 +.. nonce: qWuDjT +.. section: C API + +Add :c:func:`PyUnicode_Equal` function to the limited C API: test if two +strings are equal. Patch by Victor Stinner. + +.. + +.. date: 2024-09-24-20-34-21 +.. gh-issue: 124296 +.. nonce: S4QoS1 +.. section: C API + +:c:type:`PyDictObject` no longer maintains a private version tag field +``ma_version_tag`` per :pep:`699`. This field was originally added in +Python 3.6 (:pep:`509`) and deprecated in Python 3.12. + +.. + +.. date: 2024-09-18-18-40-30 +.. gh-issue: 124160 +.. nonce: Zy-VKi +.. section: C API + +Fix crash when importing modules containing state and single-phase +initialization in a subinterpreter. + +.. + +.. date: 2024-09-17-05-23-35 +.. gh-issue: 124153 +.. nonce: L8TWmx +.. section: C API + +Add :c:func:`PyType_GetBaseByToken` and :c:data:`Py_tp_token` slot for +easier type checking, related to :pep:`489` and :pep:`630`. + +.. + +.. date: 2024-09-16-16-21-39 +.. gh-issue: 124127 +.. nonce: LB8DBU +.. section: C API + +In the limited C API 3.14 and newer, :c:func:`Py_REFCNT` is now implemented +as an opaque function call to hide implementation details. Patch by Victor +Stinner. + +.. + +.. date: 2024-09-12-16-16-24 +.. gh-issue: 123880 +.. nonce: 2-8vcj +.. section: C API + +Fixed a bug that prevented circular imports of extension modules that use +single-phase initialization. + +.. + +.. date: 2024-09-10-16-54-27 +.. gh-issue: 123909 +.. nonce: CTGxDR +.. section: C API + +:c:func:`PyType_FromSpec`, :c:func:`PyType_FromSpecWithBases` and +:c:func:`PyType_FromModuleAndSpec` will now fail if the metaclass of the new +type has custom :c:member:`~PyTypeObject.tp_new`. + +.. + +.. date: 2024-08-30-14-02-17 +.. gh-issue: 107954 +.. nonce: TPvj4u +.. section: C API + +Add functions to configure the Python initialization (:pep:`741`): + +* :c:func:`PyInitConfig_Create` +* :c:func:`PyInitConfig_Free` +* :c:func:`PyInitConfig_GetError` +* :c:func:`PyInitConfig_GetExitCode` +* :c:func:`PyInitConfig_HasOption` +* :c:func:`PyInitConfig_GetInt` +* :c:func:`PyInitConfig_GetStr` +* :c:func:`PyInitConfig_GetStrList` +* :c:func:`PyInitConfig_FreeStrList` +* :c:func:`PyInitConfig_SetInt` +* :c:func:`PyInitConfig_SetStr` +* :c:func:`PyInitConfig_SetStrList` +* :c:func:`PyInitConfig_AddModule` +* :c:func:`Py_InitializeFromInitConfig` + +Patch by Victor Stinner. + +.. + +.. date: 2024-08-29-15-55-55 +.. gh-issue: 107954 +.. nonce: pr2O50 +.. section: C API + +Add functions to get and set the current runtime Python configuration: + +* :c:func:`PyConfig_Get` +* :c:func:`PyConfig_GetInt` +* :c:func:`PyConfig_Set` +* :c:func:`PyConfig_Names` + +Patch by Victor Stinner. + +.. + +.. date: 2024-08-29-15-05-19 +.. gh-issue: 123465 +.. nonce: eqwNWq +.. section: C API + +:c:macro:`Py_RELATIVE_OFFSET` is now allowed in :c:type:`PyMemberDef` for +the special offset member ``"__vectorcalloffset__"``, as well as the +discouraged special offset members ``"__dictoffset__"`` and +``"__weaklistoffset__"`` + +.. + +.. date: 2024-08-26-13-01-20 +.. gh-issue: 100554 +.. nonce: 0ku85o +.. section: C API + +Added a slot ``Py_tp_vectorcall`` to set +:c:member:`~PyTypeObject.tp_vectorcall` via the :c:func:`PyType_FromSpec` +function family. Limited API extensions can use this feature to provide more +efficient vector call-based implementation of ``__new__`` and ``__init__``. + +.. + +.. date: 2024-08-09-13-12-20 +.. gh-issue: 122854 +.. nonce: -1OgvU +.. section: C API + +Add :c:func:`Py_HashBuffer` to compute and return the hash value of a +buffer. Patch by Antoine Pitrou and Victor Stinner. + +.. + +.. date: 2024-08-06-14-23-11 +.. gh-issue: 122728 +.. nonce: l-fQ-v +.. section: C API + +Fix :c:func:`PyEval_GetLocals` to avoid :exc:`SystemError` ("bad argument to +internal function"). Patch by Victor Stinner. + +.. + +.. date: 2024-07-30-23-48-26 +.. gh-issue: 116622 +.. nonce: yTTtil +.. section: C API + +Make :any:`PyObject_Print` work around a bug in Android and OpenBSD which +prevented it from throwing an exception when trying to write to a read-only +stream. + +.. + +.. date: 2024-07-27-00-28-35 +.. gh-issue: 105201 +.. nonce: 0-xUWq +.. section: C API + +Add :c:func:`PyIter_NextItem` to replace :c:func:`PyIter_Next`, which has an +ambiguous return value. Patch by Irit Katriel and Erlend Aasland. + +.. + +.. date: 2024-07-21-17-40-07 +.. gh-issue: 121489 +.. nonce: SUMFCr +.. section: C API + +Export private :c:func:`!_PyBytes_Join` again. + +.. + +.. date: 2024-07-12-13-40-59 +.. gh-issue: 121645 +.. nonce: 96QvD3 +.. section: C API + +Add :c:func:`PyBytes_Join(sep, iterable) ` function, similar +to ``sep.join(iterable)`` in Python. Patch by Victor Stinner. + +.. + +.. date: 2024-07-09-15-55-20 +.. gh-issue: 89364 +.. nonce: yYYroI +.. section: C API + +Export the :c:func:`PySignal_SetWakeupFd` function. Previously, the function +was documented but it couldn't be used in 3rd party code. Patch by Victor +Stinner. + +.. + +.. date: 2024-07-04-15-41-10 +.. gh-issue: 113993 +.. nonce: cLSiWV +.. section: C API + +:c:func:`PyUnicode_InternInPlace` no longer prevents its argument from being +garbage collected. + +Several functions that take ``char *`` are now documented as possibly +preventing string objects from being garbage collected; refer to their +documentation for details: :c:func:`PyUnicode_InternFromString`, +:c:func:`PyDict_SetItemString`, :c:func:`PyObject_SetAttrString`, +:c:func:`PyObject_DelAttrString`, :c:func:`PyUnicode_InternFromString`, and +``PyModule_Add*`` convenience functions. + +.. + +.. date: 2024-07-04-13-23-27 +.. gh-issue: 113601 +.. nonce: K3RLqp +.. section: C API + +Removed debug build assertions related to interning strings, which were +falsely triggered by stable ABI extensions. + +.. + +.. date: 2024-07-02-11-03-40 +.. gh-issue: 112136 +.. nonce: f3fiY8 +.. section: C API + +Restore the private ``_PyArg_Parser`` structure and the private +``_PyArg_ParseTupleAndKeywordsFast()`` function, previously removed in +Python 3.13 alpha 1. Patch by Victor Stinner. + +.. + +.. date: 2024-06-26-11-29-01 +.. gh-issue: 120642 +.. nonce: H7P9qK +.. section: C API + +Remove the private ``_Py_CODEUNIT`` type from the public C API. The internal +``pycore_code.h`` header should now be used to get this internal type. Patch +by Victor Stinner. + +.. + +.. date: 2024-06-21-16-41-21 +.. gh-issue: 120858 +.. nonce: Z5_-Mn +.. section: C API + +:c:func:`PyDict_Next` no longer locks the dictionary in the free-threaded +build. The locking needs to be done by the caller around the entire +iteration loop. + +.. + +.. date: 2024-06-19-21-27-42 +.. gh-issue: 120642 +.. nonce: UlKClN +.. section: C API + +Remove the following unstable functions: + +* ``PyUnstable_Replace_Executor()`` +* ``PyUnstable_SetOptimizer()`` +* ``PyUnstable_GetOptimizer()`` +* ``PyUnstable_GetExecutor()`` +* ``PyUnstable_Optimizer_NewCounter()`` +* ``PyUnstable_Optimizer_NewUOpOptimizer()`` + +Patch by Victor Stinner. + +.. + +.. date: 2024-06-19-17-27-22 +.. gh-issue: 120389 +.. nonce: GSZeHF +.. section: C API + +Add new functions to convert C ```` numbers from/to Python +:class:`int`: + +* :c:func:`PyLong_FromInt32` +* :c:func:`PyLong_FromUInt32` +* :c:func:`PyLong_FromInt64` +* :c:func:`PyLong_FromUInt64` +* :c:func:`PyLong_AsInt32` +* :c:func:`PyLong_AsUInt32` +* :c:func:`PyLong_AsInt64` +* :c:func:`PyLong_AsUInt64` + +Patch by Victor Stinner. + +.. + +.. date: 2024-06-16-22-58-47 +.. gh-issue: 120600 +.. nonce: TJdf0w +.. section: C API + +In the limited C API 3.14 and newer, :c:func:`Py_TYPE` is now implemented as +an opaque function call to hide implementation details. Patch by Victor +Stinner. + +.. + +.. date: 2024-06-11-21-38-32 +.. gh-issue: 70278 +.. nonce: WDE4zM +.. section: C API + +:c:func:`PyUnicode_FromFormat` no longer produces the ending ``\ufffd`` +character for truncated C string when use precision with ``%s`` and ``%V``. +It now truncates the string before the start of truncated multibyte +sequences. + +.. + +.. date: 2024-06-08-08-33-40 +.. gh-issue: 119771 +.. nonce: Oip2dL +.. section: C API + +Set :data:`errno` in :c:func:`_Py_c_pow` on overflows. Patch by Sergey B +Kirpichev. + +.. + +.. date: 2024-06-07-22-12-30 +.. gh-issue: 119182 +.. nonce: yt8Ar7 +.. section: C API + +Add a new :c:type:`PyUnicodeWriter` API to create a Python :class:`str` +object: + +* :c:func:`PyUnicodeWriter_Create`. +* :c:func:`PyUnicodeWriter_Discard`. +* :c:func:`PyUnicodeWriter_Finish`. +* :c:func:`PyUnicodeWriter_WriteChar`. +* :c:func:`PyUnicodeWriter_WriteUTF8`. +* :c:func:`PyUnicodeWriter_WriteUCS4`. +* :c:func:`PyUnicodeWriter_WriteWideChar`. +* :c:func:`PyUnicodeWriter_WriteStr`. +* :c:func:`PyUnicodeWriter_WriteRepr`. +* :c:func:`PyUnicodeWriter_WriteSubstring`. +* :c:func:`PyUnicodeWriter_Format`. +* :c:func:`PyUnicodeWriter_DecodeUTF8Stateful`. + +Patch by Victor Stinner. + +.. + +.. date: 2024-06-04-10-58-20 +.. gh-issue: 119613 +.. nonce: qOr9GF +.. section: C API + +Soft deprecate the :c:macro:`!Py_MEMCPY` macro: use directly ``memcpy()`` +instead. Patch by Victor Stinner. + +.. + +.. date: 2024-05-30-12-51-21 +.. gh-issue: 119775 +.. nonce: CBq9IG +.. section: C API + +Creating :c:data:`immutable types ` with mutable +bases was deprecated since 3.12 and now raises a :exc:`TypeError`. + +.. + +.. date: 2024-05-29-21-05-59 +.. gh-issue: 119585 +.. nonce: Sn7JL3 +.. section: C API + +Fix crash when a thread state that was created by +:c:func:`PyGILState_Ensure` calls a destructor that during +:c:func:`PyThreadState_Clear` that calls back into +:c:func:`PyGILState_Ensure` and :c:func:`PyGILState_Release`. This might +occur when in the free-threaded build or when using thread-local variables +whose destructors call :c:func:`PyGILState_Ensure`. + +.. + +.. date: 2024-05-29-09-21-37 +.. gh-issue: 119613 +.. nonce: J2xfrC +.. section: C API + +Macros ``Py_IS_NAN``, ``Py_IS_INFINITY`` and ``Py_IS_FINITE`` are +:term:`soft deprecated`. + +.. + +.. date: 2024-05-22-17-50-48 +.. gh-issue: 119336 +.. nonce: ff3qnS +.. section: C API + +Restore the removed ``_PyLong_NumBits()`` function. It is used by the +pywin32 project. Patch by Ethan Smith + +.. + +.. date: 2024-05-21-19-41-41 +.. gh-issue: 119344 +.. nonce: QKvzQb +.. section: C API + +The critical section API is now public as part of the non-limited C API. + +.. + +.. date: 2024-05-21-18-28-44 +.. gh-issue: 119333 +.. nonce: OTsYVX +.. section: C API + +Add :c:func:`PyContext_AddWatcher` and :c:func:`PyContext_ClearWatcher` APIs +to register callbacks to receive notification on enter and exit of context +objects. + +.. + +.. date: 2024-05-21-11-35-11 +.. gh-issue: 119247 +.. nonce: U6n6mh +.. section: C API + +Added ``Py_BEGIN_CRITICAL_SECTION_SEQUENCE_FAST`` and +``Py_END_CRITICAL_SECTION_SEQUENCE_FAST`` macros to make it possible to use +PySequence_Fast APIs safely when free-threaded, and update str.join to work +without the GIL using them. + +.. + +.. date: 2024-05-20-10-35-22 +.. gh-issue: 111389 +.. nonce: a6axBk +.. section: C API + +Add :c:macro:`PyHASH_MULTIPLIER` constant: prime multiplier used in string +and various other hashes. Patch by Victor Stinner. + +.. + +.. date: 2024-05-10-15-43-14 +.. gh-issue: 118771 +.. nonce: 5KVglT +.. section: C API + +Several C declarations with names that didn't start with the ``Py`` or +``_Py`` prefixes, which were added by mistake in 3.13 alpha and beta +releases, were moved to internal headers. + +.. + +.. date: 2024-05-08-23-14-06 +.. gh-issue: 116984 +.. nonce: 5sgcDo +.. section: C API + +Make mimalloc includes relative to the current file to avoid embedders or +extensions needing to include ``Internal/mimalloc`` if they are already +including internal CPython headers. + +.. + +.. date: 2024-05-08-21-57-50 +.. gh-issue: 118789 +.. nonce: Ni4UQx +.. section: C API + +Add :c:func:`PyUnstable_Object_ClearWeakRefsNoCallbacks`, which clears +weakrefs without calling their callbacks. + +.. + +.. date: 2024-05-08-20-13-00 +.. gh-issue: 118789 +.. nonce: m88uUa +.. section: C API + +Restore ``_PyWeakref_ClearRef`` that was previously removed in Python 3.13 +alpha 1. + +.. + +.. date: 2024-04-10-16-48-04 +.. gh-issue: 117511 +.. nonce: RZtBRK +.. section: C API + +Make the :c:type:`PyMutex` public in the non-limited C API. + +.. + +.. date: 2024-03-10-14-55-51 +.. gh-issue: 116560 +.. nonce: x2mZaO +.. section: C API + +Add :c:func:`PyLong_GetSign` function. Patch by Sergey B Kirpichev. + +.. + +.. date: 2022-10-01-09-56-27 +.. gh-issue: 97588 +.. nonce: Gvg54o +.. section: C API + +Fix creating bitfields in :mod:`ctypes` structures and unions. Fields no +longer overlap. + +.. + +.. date: 2022-08-05-19-41-20 +.. gh-issue: 87135 +.. nonce: SCNBYj +.. section: C API + +Attempting to acquire the GIL after runtime finalization has begun in a +different thread now causes the thread to hang rather than terminate, which +avoids potential crashes or memory corruption caused by attempting to +terminate a thread that is running code not specifically designed to support +termination. In most cases this hanging is harmless since the process will +soon exit anyway. + +The ``PyThread_exit_thread`` function is now deprecated. Its behavior is +inconsistent across platforms, and it can only be used safely in the +unlikely case that every function in the entire call stack has been designed +to support the platform-dependent termination mechanism. It is recommended +that users of this function change their design to not require thread +termination. In the unlikely case that thread termination is needed and can +be done safely, users may migrate to calling platform-specific APIs such as +``pthread_exit`` (POSIX) or ``_endthreadex`` (Windows) directly. + +.. + +.. bpo: 34008 +.. date: 2018-06-30-21-48-16 +.. nonce: 2Wjtm0 +.. section: C API + +Added ``Py_IsInitialized`` to the list of APIs that are safe to call before +the interpreter is initialized, and updated the embedding tests to cover it. + +.. + +.. date: 2024-10-13-21-11-30 +.. gh-issue: 125269 +.. nonce: BC-fdo +.. section: Build + +Fix detection of whether ``-latomic`` is needed when cross-compiling CPython +using the configure script. + +.. + +.. date: 2024-09-23-11-27-25 +.. gh-issue: 123990 +.. nonce: d6HrYC +.. section: Build + +Remove ``WITH_FREELISTS`` macro and ``--without-freelists`` build +configuration + +.. + +.. date: 2024-09-16-09-42-05 +.. gh-issue: 124102 +.. nonce: Ow254j +.. section: Build + +Update internal documentation under PCbuild, so it now correctly states that +Windows requires VS2017 or later and Python 3.10 or later + +.. + +.. date: 2024-09-13-17-48-37 +.. gh-issue: 124043 +.. nonce: Bruxpq +.. section: Build + +Building using :option:`--with-trace-refs` is (temporarily) disallowed when +the GIL is disabled. + +.. + +.. date: 2024-09-04-12-01-43 +.. gh-issue: 123418 +.. nonce: ynzspB +.. section: Build + +Updated Android build to use OpenSSL 3.0.15. + +.. + +.. date: 2024-08-24-19-09-31 +.. gh-issue: 123297 +.. nonce: fdtXoe +.. section: Build + +Propagate the value of ``LDFLAGS`` to ``LDCXXSHARED`` in :mod:`sysconfig`. +Patch by Pablo Galindo + +.. + +.. date: 2024-08-14-19-17-34 +.. gh-issue: 121634 +.. nonce: eOMfHG +.. section: Build + +Allow for specifying the target compile triple for WASI. + +.. + +.. date: 2024-08-12-15-48-49 +.. gh-issue: 122578 +.. nonce: YJ3xEa +.. section: Build + +Use WASI SDK 24 for testing. + +.. + +.. date: 2024-08-07-00-20-18 +.. gh-issue: 116622 +.. nonce: U9cxHM +.. section: Build + +Rename build variable ``MODULE_LDFLAGS`` back to ``LIBPYTHON``, as it's used +by package build systems (e.g. Meson). + +.. + +.. date: 2024-08-02-12-59-15 +.. gh-issue: 118943 +.. nonce: vZQtET +.. section: Build + +Fix an issue where the experimental JIT could be built several times by the +``make regen-all`` target, leading to possible race conditions on heavily +parallelized builds. + +.. + +.. date: 2024-07-19-10-14-31 +.. gh-issue: 121996 +.. nonce: IEb2sz +.. section: Build + +Introduce ./configure --disable-safety and --enable-slower-safety options. +Patch by Donghee Na. + +.. + +.. date: 2024-07-18-07-53-07 +.. gh-issue: 120522 +.. nonce: dg3o5A +.. section: Build + +Added a :option:`--with-app-store-compliance` option to patch out known +issues with macOS/iOS App Store review processes. + +.. + +.. date: 2024-07-16-12-29-54 +.. gh-issue: 120371 +.. nonce: E7x858 +.. section: Build + +Support WASI SDK 22 by explicitly skipping functions that are just stubs in +wasi-libc. + +.. + +.. date: 2024-07-14-01-29-47 +.. gh-issue: 121731 +.. nonce: RMPGP3 +.. section: Build + +Fix mimalloc compile error on GNU/Hurd + +.. + +.. date: 2024-07-08-14-01-17 +.. gh-issue: 121487 +.. nonce: ekHmpR +.. section: Build + +Fix deprecation warning for ATOMIC_VAR_INIT in mimalloc. + +.. + +.. date: 2024-07-08-01-11-54 +.. gh-issue: 121467 +.. nonce: 3qWRQj +.. section: Build + +Fix a Makefile bug that prevented mimalloc header files from being +installed. + +.. + +.. date: 2024-07-02-20-16-09 +.. gh-issue: 121103 +.. nonce: TMef9j +.. section: Build + +On POSIX systems, excluding macOS framework installs, the lib directory for +the free-threaded build now includes a "t" suffix to avoid conflicts with a +co-located default build installation. + +.. + +.. date: 2024-07-02-12-42-25 +.. gh-issue: 120831 +.. nonce: i3eIjg +.. section: Build + +The default minimum iOS version was increased to 13.0. + +.. + +.. date: 2024-06-27-18-03-20 +.. gh-issue: 121082 +.. nonce: w3AfRx +.. section: Build + +Fix build failure when the developer use ``--enable-pystats`` arguments in +configuration command after #118450. + +.. + +.. date: 2024-06-21-09-24-03 +.. gh-issue: 120671 +.. nonce: Z8sBQB +.. section: Build + +Fix failing configure tests due to a missing space when appending to CFLAGS. + +.. + +.. date: 2024-06-19-21-05-15 +.. gh-issue: 120602 +.. nonce: UyDARz +.. section: Build + +Correctly handle LLVM installs with ``LLVM_VERSION_SUFFIX`` when building +with ``--enable-experimental-jit``. + +.. + +.. date: 2024-06-18-15-32-36 +.. gh-issue: 120688 +.. nonce: tjIPLD +.. section: Build + +On WASI in debug mode, Python is now built with compiler flag ``-O3`` +instead of ``-Og``, to support more recursive calls. Patch by Victor +Stinner. + +.. + +.. date: 2024-06-18-15-28-25 +.. gh-issue: 118943 +.. nonce: aie7nn +.. section: Build + +Fix a possible race condition affecting parallel builds configured with +``--enable-experimental-jit``, in which :exc:`FileNotFoundError` could be +caused by another process already moving ``jit_stencils.h.new`` to +``jit_stencils.h``. + +.. + +.. date: 2024-06-11-00-38-05 +.. gh-issue: 120326 +.. nonce: JHSDF1 +.. section: Build + +On Windows, fix build error when ``--disable-gil`` and +``--experimental-jit`` options are combined. + +.. + +.. date: 2024-06-09-15-54-22 +.. gh-issue: 120291 +.. nonce: IpfHzE +.. section: Build + +Make the ``python-config`` shell script compatible with non-bash shells. + +.. + +.. date: 2024-06-02-13-23-26 +.. gh-issue: 113565 +.. nonce: 8xBlId +.. section: Build + +Improve :mod:`curses` and :mod:`curses.panel` dependency checks in +:program:`configure`. + +.. + +.. date: 2024-05-29-17-40-50 +.. gh-issue: 119729 +.. nonce: k0xJ5U +.. section: Build + +On POSIX systems, the pkg-config (``.pc``) filenames now include the ABI +flags, which may include debug ("d") and free-threaded ("t"). For example: +* ``python-3.14.pc`` (default, non-debug build) * ``python-3.14d.pc`` +(default, debug build) * ``python-3.14t.pc`` (free-threaded build) + +.. + +.. date: 2024-05-22-13-18-02 +.. gh-issue: 119400 +.. nonce: WEt83v +.. section: Build + +``make_ssl_certs``, the script that prepares certificate data for the test +suite, now allows specifying expiration dates. + +.. + +.. date: 2024-05-19-22-54-55 +.. gh-issue: 115119 +.. nonce: DwMwev +.. section: Build + +Fall back to the bundled libmpdec if a system version cannot be found. + +.. + +.. date: 2024-05-17-19-53-27 +.. gh-issue: 119132 +.. nonce: wepPgM +.. section: Build + +Update :data:`sys.version` to identify whether the build is default build or +free-threading build. Patch By Donghee Na. + +.. + +.. date: 2024-05-13-15-57-58 +.. gh-issue: 118836 +.. nonce: 7yN1iB +.. section: Build + +Fix an ``AssertionError`` when building with ``--enable-experimental-jit`` +and the compiler emits a ``SHT_NOTE`` section. + +.. + +.. date: 2024-05-11-15-11-30 +.. gh-issue: 118943 +.. nonce: VI_MnY +.. section: Build + +Fix a possible race condition affecting parallel builds configured with +``--enable-experimental-jit``, in which compilation errors could be caused +by an incompletely-generated header file. diff --git a/Misc/NEWS.d/next/Build/2024-05-11-15-11-30.gh-issue-118943.VI_MnY.rst b/Misc/NEWS.d/next/Build/2024-05-11-15-11-30.gh-issue-118943.VI_MnY.rst deleted file mode 100644 index 4e886be034fb82..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-05-11-15-11-30.gh-issue-118943.VI_MnY.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix a possible race condition affecting parallel builds configured with -``--enable-experimental-jit``, in which compilation errors could be caused -by an incompletely-generated header file. diff --git a/Misc/NEWS.d/next/Build/2024-05-13-15-57-58.gh-issue-118836.7yN1iB.rst b/Misc/NEWS.d/next/Build/2024-05-13-15-57-58.gh-issue-118836.7yN1iB.rst deleted file mode 100644 index 5212af7b32b940..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-05-13-15-57-58.gh-issue-118836.7yN1iB.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix an ``AssertionError`` when building with ``--enable-experimental-jit`` -and the compiler emits a ``SHT_NOTE`` section. diff --git a/Misc/NEWS.d/next/Build/2024-05-17-19-53-27.gh-issue-119132.wepPgM.rst b/Misc/NEWS.d/next/Build/2024-05-17-19-53-27.gh-issue-119132.wepPgM.rst deleted file mode 100644 index 44fe2a1a1f6725..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-05-17-19-53-27.gh-issue-119132.wepPgM.rst +++ /dev/null @@ -1,2 +0,0 @@ -Update :data:`sys.version` to identify whether the build is default build or -free-threading build. Patch By Donghee Na. diff --git a/Misc/NEWS.d/next/Build/2024-05-19-22-54-55.gh-issue-115119.DwMwev.rst b/Misc/NEWS.d/next/Build/2024-05-19-22-54-55.gh-issue-115119.DwMwev.rst deleted file mode 100644 index acaca9e0ebbdfb..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-05-19-22-54-55.gh-issue-115119.DwMwev.rst +++ /dev/null @@ -1 +0,0 @@ -Fall back to the bundled libmpdec if a system version cannot be found. diff --git a/Misc/NEWS.d/next/Build/2024-05-22-13-18-02.gh-issue-119400.WEt83v.rst b/Misc/NEWS.d/next/Build/2024-05-22-13-18-02.gh-issue-119400.WEt83v.rst deleted file mode 100644 index b4029f205797e4..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-05-22-13-18-02.gh-issue-119400.WEt83v.rst +++ /dev/null @@ -1,2 +0,0 @@ -``make_ssl_certs``, the script that prepares certificate data for the -test suite, now allows specifying expiration dates. diff --git a/Misc/NEWS.d/next/Build/2024-05-29-17-40-50.gh-issue-119729.k0xJ5U.rst b/Misc/NEWS.d/next/Build/2024-05-29-17-40-50.gh-issue-119729.k0xJ5U.rst deleted file mode 100644 index 7ac300ecf40326..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-05-29-17-40-50.gh-issue-119729.k0xJ5U.rst +++ /dev/null @@ -1,5 +0,0 @@ -On POSIX systems, the pkg-config (``.pc``) filenames now include the ABI -flags, which may include debug ("d") and free-threaded ("t"). For example: -* ``python-3.14.pc`` (default, non-debug build) -* ``python-3.14d.pc`` (default, debug build) -* ``python-3.14t.pc`` (free-threaded build) diff --git a/Misc/NEWS.d/next/Build/2024-06-02-13-23-26.gh-issue-113565.8xBlId.rst b/Misc/NEWS.d/next/Build/2024-06-02-13-23-26.gh-issue-113565.8xBlId.rst deleted file mode 100644 index e26509cd434110..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-06-02-13-23-26.gh-issue-113565.8xBlId.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve :mod:`curses` and :mod:`curses.panel` dependency checks in -:program:`configure`. diff --git a/Misc/NEWS.d/next/Build/2024-06-09-15-54-22.gh-issue-120291.IpfHzE.rst b/Misc/NEWS.d/next/Build/2024-06-09-15-54-22.gh-issue-120291.IpfHzE.rst deleted file mode 100644 index d0bb297b51dc6e..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-06-09-15-54-22.gh-issue-120291.IpfHzE.rst +++ /dev/null @@ -1 +0,0 @@ -Make the ``python-config`` shell script compatible with non-bash shells. diff --git a/Misc/NEWS.d/next/Build/2024-06-11-00-38-05.gh-issue-120326.JHSDF1.rst b/Misc/NEWS.d/next/Build/2024-06-11-00-38-05.gh-issue-120326.JHSDF1.rst deleted file mode 100644 index 25cbdf6ba50ab8..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-06-11-00-38-05.gh-issue-120326.JHSDF1.rst +++ /dev/null @@ -1,2 +0,0 @@ -On Windows, fix build error when ``--disable-gil`` and ``--experimental-jit`` -options are combined. diff --git a/Misc/NEWS.d/next/Build/2024-06-18-15-28-25.gh-issue-118943.aie7nn.rst b/Misc/NEWS.d/next/Build/2024-06-18-15-28-25.gh-issue-118943.aie7nn.rst deleted file mode 100644 index 997c990a96e476..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-06-18-15-28-25.gh-issue-118943.aie7nn.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix a possible race condition affecting parallel builds configured with -``--enable-experimental-jit``, in which :exc:`FileNotFoundError` could be caused by -another process already moving ``jit_stencils.h.new`` to ``jit_stencils.h``. diff --git a/Misc/NEWS.d/next/Build/2024-06-18-15-32-36.gh-issue-120688.tjIPLD.rst b/Misc/NEWS.d/next/Build/2024-06-18-15-32-36.gh-issue-120688.tjIPLD.rst deleted file mode 100644 index 90f1f9138b6b58..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-06-18-15-32-36.gh-issue-120688.tjIPLD.rst +++ /dev/null @@ -1,3 +0,0 @@ -On WASI in debug mode, Python is now built with compiler flag ``-O3`` -instead of ``-Og``, to support more recursive calls. Patch by Victor -Stinner. diff --git a/Misc/NEWS.d/next/Build/2024-06-19-21-05-15.gh-issue-120602.UyDARz.rst b/Misc/NEWS.d/next/Build/2024-06-19-21-05-15.gh-issue-120602.UyDARz.rst deleted file mode 100644 index f0d90ec3bb5089..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-06-19-21-05-15.gh-issue-120602.UyDARz.rst +++ /dev/null @@ -1,2 +0,0 @@ -Correctly handle LLVM installs with ``LLVM_VERSION_SUFFIX`` when building -with ``--enable-experimental-jit``. diff --git a/Misc/NEWS.d/next/Build/2024-06-21-09-24-03.gh-issue-120671.Z8sBQB.rst b/Misc/NEWS.d/next/Build/2024-06-21-09-24-03.gh-issue-120671.Z8sBQB.rst deleted file mode 100644 index bbe4a3038bc0ff..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-06-21-09-24-03.gh-issue-120671.Z8sBQB.rst +++ /dev/null @@ -1 +0,0 @@ -Fix failing configure tests due to a missing space when appending to CFLAGS. diff --git a/Misc/NEWS.d/next/Build/2024-06-27-18-03-20.gh-issue-121082.w3AfRx.rst b/Misc/NEWS.d/next/Build/2024-06-27-18-03-20.gh-issue-121082.w3AfRx.rst deleted file mode 100644 index 7657672ba880c8..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-06-27-18-03-20.gh-issue-121082.w3AfRx.rst +++ /dev/null @@ -1 +0,0 @@ -Fix build failure when the developer use ``--enable-pystats`` arguments in configuration command after #118450. diff --git a/Misc/NEWS.d/next/Build/2024-07-02-12-42-25.gh-issue-120831.i3eIjg.rst b/Misc/NEWS.d/next/Build/2024-07-02-12-42-25.gh-issue-120831.i3eIjg.rst deleted file mode 100644 index 3784cc66c41219..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-07-02-12-42-25.gh-issue-120831.i3eIjg.rst +++ /dev/null @@ -1 +0,0 @@ -The default minimum iOS version was increased to 13.0. diff --git a/Misc/NEWS.d/next/Build/2024-07-02-20-16-09.gh-issue-121103.TMef9j.rst b/Misc/NEWS.d/next/Build/2024-07-02-20-16-09.gh-issue-121103.TMef9j.rst deleted file mode 100644 index 4bc8c6de0b7733..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-07-02-20-16-09.gh-issue-121103.TMef9j.rst +++ /dev/null @@ -1,3 +0,0 @@ -On POSIX systems, excluding macOS framework installs, the lib directory -for the free-threaded build now includes a "t" suffix to avoid conflicts -with a co-located default build installation. diff --git a/Misc/NEWS.d/next/Build/2024-07-08-01-11-54.gh-issue-121467.3qWRQj.rst b/Misc/NEWS.d/next/Build/2024-07-08-01-11-54.gh-issue-121467.3qWRQj.rst deleted file mode 100644 index a2238475546eaa..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-07-08-01-11-54.gh-issue-121467.3qWRQj.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a Makefile bug that prevented mimalloc header files from being installed. diff --git a/Misc/NEWS.d/next/Build/2024-07-08-14-01-17.gh-issue-121487.ekHmpR.rst b/Misc/NEWS.d/next/Build/2024-07-08-14-01-17.gh-issue-121487.ekHmpR.rst deleted file mode 100644 index e30d4dcdbfe779..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-07-08-14-01-17.gh-issue-121487.ekHmpR.rst +++ /dev/null @@ -1 +0,0 @@ -Fix deprecation warning for ATOMIC_VAR_INIT in mimalloc. diff --git a/Misc/NEWS.d/next/Build/2024-07-14-01-29-47.gh-issue-121731.RMPGP3.rst b/Misc/NEWS.d/next/Build/2024-07-14-01-29-47.gh-issue-121731.RMPGP3.rst deleted file mode 100644 index 36e0f86a0ae455..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-07-14-01-29-47.gh-issue-121731.RMPGP3.rst +++ /dev/null @@ -1 +0,0 @@ -Fix mimalloc compile error on GNU/Hurd diff --git a/Misc/NEWS.d/next/Build/2024-07-16-12-29-54.gh-issue-120371.E7x858.rst b/Misc/NEWS.d/next/Build/2024-07-16-12-29-54.gh-issue-120371.E7x858.rst deleted file mode 100644 index d57266dafd8d67..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-07-16-12-29-54.gh-issue-120371.E7x858.rst +++ /dev/null @@ -1,2 +0,0 @@ -Support WASI SDK 22 by explicitly skipping functions that are just stubs in -wasi-libc. diff --git a/Misc/NEWS.d/next/Build/2024-07-18-07-53-07.gh-issue-120522.dg3o5A.rst b/Misc/NEWS.d/next/Build/2024-07-18-07-53-07.gh-issue-120522.dg3o5A.rst deleted file mode 100644 index e90c625a886b65..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-07-18-07-53-07.gh-issue-120522.dg3o5A.rst +++ /dev/null @@ -1,2 +0,0 @@ -Added a :option:`--with-app-store-compliance` option to patch out known -issues with macOS/iOS App Store review processes. diff --git a/Misc/NEWS.d/next/Build/2024-07-19-10-14-31.gh-issue-121996.IEb2sz.rst b/Misc/NEWS.d/next/Build/2024-07-19-10-14-31.gh-issue-121996.IEb2sz.rst deleted file mode 100644 index 171efe8388bc0d..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-07-19-10-14-31.gh-issue-121996.IEb2sz.rst +++ /dev/null @@ -1,2 +0,0 @@ -Introduce ./configure --disable-safety and --enable-slower-safety options. -Patch by Donghee Na. diff --git a/Misc/NEWS.d/next/Build/2024-08-02-12-59-15.gh-issue-118943.vZQtET.rst b/Misc/NEWS.d/next/Build/2024-08-02-12-59-15.gh-issue-118943.vZQtET.rst deleted file mode 100644 index 42cda69e01cd4c..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-08-02-12-59-15.gh-issue-118943.vZQtET.rst +++ /dev/null @@ -1 +0,0 @@ -Fix an issue where the experimental JIT could be built several times by the ``make regen-all`` target, leading to possible race conditions on heavily parallelized builds. diff --git a/Misc/NEWS.d/next/Build/2024-08-07-00-20-18.gh-issue-116622.U9cxHM.rst b/Misc/NEWS.d/next/Build/2024-08-07-00-20-18.gh-issue-116622.U9cxHM.rst deleted file mode 100644 index c9a56d65ad0cd3..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-08-07-00-20-18.gh-issue-116622.U9cxHM.rst +++ /dev/null @@ -1,2 +0,0 @@ -Rename build variable ``MODULE_LDFLAGS`` back to ``LIBPYTHON``, as it's used by -package build systems (e.g. Meson). diff --git a/Misc/NEWS.d/next/Build/2024-08-12-15-48-49.gh-issue-122578.YJ3xEa.rst b/Misc/NEWS.d/next/Build/2024-08-12-15-48-49.gh-issue-122578.YJ3xEa.rst deleted file mode 100644 index 5c1b9079909ff4..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-08-12-15-48-49.gh-issue-122578.YJ3xEa.rst +++ /dev/null @@ -1 +0,0 @@ -Use WASI SDK 24 for testing. diff --git a/Misc/NEWS.d/next/Build/2024-08-14-19-17-34.gh-issue-121634.eOMfHG.rst b/Misc/NEWS.d/next/Build/2024-08-14-19-17-34.gh-issue-121634.eOMfHG.rst deleted file mode 100644 index 025b6bca809898..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-08-14-19-17-34.gh-issue-121634.eOMfHG.rst +++ /dev/null @@ -1 +0,0 @@ -Allow for specifying the target compile triple for WASI. diff --git a/Misc/NEWS.d/next/Build/2024-08-24-19-09-31.gh-issue-123297.fdtXoe.rst b/Misc/NEWS.d/next/Build/2024-08-24-19-09-31.gh-issue-123297.fdtXoe.rst deleted file mode 100644 index d2c831b27be237..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-08-24-19-09-31.gh-issue-123297.fdtXoe.rst +++ /dev/null @@ -1,2 +0,0 @@ -Propagate the value of ``LDFLAGS`` to ``LDCXXSHARED`` in :mod:`sysconfig`. -Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Build/2024-09-04-12-01-43.gh-issue-123418.ynzspB.rst b/Misc/NEWS.d/next/Build/2024-09-04-12-01-43.gh-issue-123418.ynzspB.rst deleted file mode 100644 index 38d0e02f3ce404..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-09-04-12-01-43.gh-issue-123418.ynzspB.rst +++ /dev/null @@ -1 +0,0 @@ -Updated Android build to use OpenSSL 3.0.15. diff --git a/Misc/NEWS.d/next/Build/2024-09-13-17-48-37.gh-issue-124043.Bruxpq.rst b/Misc/NEWS.d/next/Build/2024-09-13-17-48-37.gh-issue-124043.Bruxpq.rst deleted file mode 100644 index 8111b76f95fad6..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-09-13-17-48-37.gh-issue-124043.Bruxpq.rst +++ /dev/null @@ -1,2 +0,0 @@ -Building using :option:`--with-trace-refs` is (temporarily) disallowed when the -GIL is disabled. diff --git a/Misc/NEWS.d/next/Build/2024-09-16-09-42-05.gh-issue-124102.Ow254j.rst b/Misc/NEWS.d/next/Build/2024-09-16-09-42-05.gh-issue-124102.Ow254j.rst deleted file mode 100644 index 6edc9a6abbced4..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-09-16-09-42-05.gh-issue-124102.Ow254j.rst +++ /dev/null @@ -1,2 +0,0 @@ -Update internal documentation under PCbuild, so it now correctly states that -Windows requires VS2017 or later and Python 3.10 or later diff --git a/Misc/NEWS.d/next/Build/2024-09-23-11-27-25.gh-issue-123990.d6HrYC.rst b/Misc/NEWS.d/next/Build/2024-09-23-11-27-25.gh-issue-123990.d6HrYC.rst deleted file mode 100644 index 2b4f993323297a..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-09-23-11-27-25.gh-issue-123990.d6HrYC.rst +++ /dev/null @@ -1 +0,0 @@ -Remove ``WITH_FREELISTS`` macro and ``--without-freelists`` build configuration diff --git a/Misc/NEWS.d/next/Build/2024-10-13-21-11-30.gh-issue-125269.BC-fdo.rst b/Misc/NEWS.d/next/Build/2024-10-13-21-11-30.gh-issue-125269.BC-fdo.rst deleted file mode 100644 index 24f5469e8a664b..00000000000000 --- a/Misc/NEWS.d/next/Build/2024-10-13-21-11-30.gh-issue-125269.BC-fdo.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix detection of whether ``-latomic`` is needed when cross-compiling CPython -using the configure script. diff --git a/Misc/NEWS.d/next/C API/2018-06-30-21-48-16.bpo-34008.2Wjtm0.rst b/Misc/NEWS.d/next/C API/2018-06-30-21-48-16.bpo-34008.2Wjtm0.rst deleted file mode 100644 index 1a01dafc758004..00000000000000 --- a/Misc/NEWS.d/next/C API/2018-06-30-21-48-16.bpo-34008.2Wjtm0.rst +++ /dev/null @@ -1,2 +0,0 @@ -Added ``Py_IsInitialized`` to the list of APIs that are safe to call before -the interpreter is initialized, and updated the embedding tests to cover it. diff --git a/Misc/NEWS.d/next/C API/2022-08-05-19-41-20.gh-issue-87135.SCNBYj.rst b/Misc/NEWS.d/next/C API/2022-08-05-19-41-20.gh-issue-87135.SCNBYj.rst deleted file mode 100644 index 6387d69bc267c6..00000000000000 --- a/Misc/NEWS.d/next/C API/2022-08-05-19-41-20.gh-issue-87135.SCNBYj.rst +++ /dev/null @@ -1,15 +0,0 @@ -Attempting to acquire the GIL after runtime finalization has begun in a -different thread now causes the thread to hang rather than terminate, which -avoids potential crashes or memory corruption caused by attempting to -terminate a thread that is running code not specifically designed to support -termination. In most cases this hanging is harmless since the process will -soon exit anyway. - -The ``PyThread_exit_thread`` function is now deprecated. Its behavior is -inconsistent across platforms, and it can only be used safely in the -unlikely case that every function in the entire call stack has been designed -to support the platform-dependent termination mechanism. It is recommended -that users of this function change their design to not require thread -termination. In the unlikely case that thread termination is needed and can -be done safely, users may migrate to calling platform-specific APIs such as -``pthread_exit`` (POSIX) or ``_endthreadex`` (Windows) directly. diff --git a/Misc/NEWS.d/next/C API/2022-10-01-09-56-27.gh-issue-97588.Gvg54o.rst b/Misc/NEWS.d/next/C API/2022-10-01-09-56-27.gh-issue-97588.Gvg54o.rst deleted file mode 100644 index 0bb0f5bcd501ef..00000000000000 --- a/Misc/NEWS.d/next/C API/2022-10-01-09-56-27.gh-issue-97588.Gvg54o.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix creating bitfields in :mod:`ctypes` structures and unions. Fields -no longer overlap. diff --git a/Misc/NEWS.d/next/C API/2024-03-10-14-55-51.gh-issue-116560.x2mZaO.rst b/Misc/NEWS.d/next/C API/2024-03-10-14-55-51.gh-issue-116560.x2mZaO.rst deleted file mode 100644 index 9bcadfd9247f78..00000000000000 --- a/Misc/NEWS.d/next/C API/2024-03-10-14-55-51.gh-issue-116560.x2mZaO.rst +++ /dev/null @@ -1 +0,0 @@ -Add :c:func:`PyLong_GetSign` function. Patch by Sergey B Kirpichev. diff --git a/Misc/NEWS.d/next/C API/2024-04-10-16-48-04.gh-issue-117511.RZtBRK.rst b/Misc/NEWS.d/next/C API/2024-04-10-16-48-04.gh-issue-117511.RZtBRK.rst deleted file mode 100644 index 586685a3407a3d..00000000000000 --- a/Misc/NEWS.d/next/C API/2024-04-10-16-48-04.gh-issue-117511.RZtBRK.rst +++ /dev/null @@ -1 +0,0 @@ -Make the :c:type:`PyMutex` public in the non-limited C API. diff --git a/Misc/NEWS.d/next/C API/2024-05-08-20-13-00.gh-issue-118789.m88uUa.rst b/Misc/NEWS.d/next/C API/2024-05-08-20-13-00.gh-issue-118789.m88uUa.rst deleted file mode 100644 index a2acc16b2c1d01..00000000000000 --- a/Misc/NEWS.d/next/C API/2024-05-08-20-13-00.gh-issue-118789.m88uUa.rst +++ /dev/null @@ -1,2 +0,0 @@ -Restore ``_PyWeakref_ClearRef`` that was previously removed in Python 3.13 -alpha 1. diff --git a/Misc/NEWS.d/next/C API/2024-05-08-21-57-50.gh-issue-118789.Ni4UQx.rst b/Misc/NEWS.d/next/C API/2024-05-08-21-57-50.gh-issue-118789.Ni4UQx.rst deleted file mode 100644 index 32a9ec6d0710f6..00000000000000 --- a/Misc/NEWS.d/next/C API/2024-05-08-21-57-50.gh-issue-118789.Ni4UQx.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add :c:func:`PyUnstable_Object_ClearWeakRefsNoCallbacks`, which clears -weakrefs without calling their callbacks. diff --git a/Misc/NEWS.d/next/C API/2024-05-08-23-14-06.gh-issue-116984.5sgcDo.rst b/Misc/NEWS.d/next/C API/2024-05-08-23-14-06.gh-issue-116984.5sgcDo.rst deleted file mode 100644 index 561417b80d444d..00000000000000 --- a/Misc/NEWS.d/next/C API/2024-05-08-23-14-06.gh-issue-116984.5sgcDo.rst +++ /dev/null @@ -1,3 +0,0 @@ -Make mimalloc includes relative to the current file to avoid embedders or -extensions needing to include ``Internal/mimalloc`` if they are already -including internal CPython headers. diff --git a/Misc/NEWS.d/next/C API/2024-05-10-15-43-14.gh-issue-118771.5KVglT.rst b/Misc/NEWS.d/next/C API/2024-05-10-15-43-14.gh-issue-118771.5KVglT.rst deleted file mode 100644 index 2ed8089dfe8444..00000000000000 --- a/Misc/NEWS.d/next/C API/2024-05-10-15-43-14.gh-issue-118771.5KVglT.rst +++ /dev/null @@ -1,3 +0,0 @@ -Several C declarations with names that didn't start with the ``Py`` or ``_Py`` -prefixes, which were added by mistake in 3.13 alpha and beta releases, were -moved to internal headers. diff --git a/Misc/NEWS.d/next/C API/2024-05-20-10-35-22.gh-issue-111389.a6axBk.rst b/Misc/NEWS.d/next/C API/2024-05-20-10-35-22.gh-issue-111389.a6axBk.rst deleted file mode 100644 index f47662f2e0a778..00000000000000 --- a/Misc/NEWS.d/next/C API/2024-05-20-10-35-22.gh-issue-111389.a6axBk.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add :c:macro:`PyHASH_MULTIPLIER` constant: prime multiplier used in string -and various other hashes. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2024-05-21-11-35-11.gh-issue-119247.U6n6mh.rst b/Misc/NEWS.d/next/C API/2024-05-21-11-35-11.gh-issue-119247.U6n6mh.rst deleted file mode 100644 index 3b2cdc8cf2dc5c..00000000000000 --- a/Misc/NEWS.d/next/C API/2024-05-21-11-35-11.gh-issue-119247.U6n6mh.rst +++ /dev/null @@ -1,4 +0,0 @@ -Added ``Py_BEGIN_CRITICAL_SECTION_SEQUENCE_FAST`` and -``Py_END_CRITICAL_SECTION_SEQUENCE_FAST`` macros to make it possible to use -PySequence_Fast APIs safely when free-threaded, and update str.join to work -without the GIL using them. diff --git a/Misc/NEWS.d/next/C API/2024-05-21-18-28-44.gh-issue-119333.OTsYVX.rst b/Misc/NEWS.d/next/C API/2024-05-21-18-28-44.gh-issue-119333.OTsYVX.rst deleted file mode 100644 index 6fb6013c4d442d..00000000000000 --- a/Misc/NEWS.d/next/C API/2024-05-21-18-28-44.gh-issue-119333.OTsYVX.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add :c:func:`PyContext_AddWatcher` and :c:func:`PyContext_ClearWatcher` APIs to -register callbacks to receive notification on enter and exit of context objects. diff --git a/Misc/NEWS.d/next/C API/2024-05-21-19-41-41.gh-issue-119344.QKvzQb.rst b/Misc/NEWS.d/next/C API/2024-05-21-19-41-41.gh-issue-119344.QKvzQb.rst deleted file mode 100644 index 5a2e4d980b59be..00000000000000 --- a/Misc/NEWS.d/next/C API/2024-05-21-19-41-41.gh-issue-119344.QKvzQb.rst +++ /dev/null @@ -1 +0,0 @@ -The critical section API is now public as part of the non-limited C API. diff --git a/Misc/NEWS.d/next/C API/2024-05-22-17-50-48.gh-issue-119336.ff3qnS.rst b/Misc/NEWS.d/next/C API/2024-05-22-17-50-48.gh-issue-119336.ff3qnS.rst deleted file mode 100644 index e530bb45d35e76..00000000000000 --- a/Misc/NEWS.d/next/C API/2024-05-22-17-50-48.gh-issue-119336.ff3qnS.rst +++ /dev/null @@ -1 +0,0 @@ -Restore the removed ``_PyLong_NumBits()`` function. It is used by the pywin32 project. Patch by Ethan Smith diff --git a/Misc/NEWS.d/next/C API/2024-05-29-09-21-37.gh-issue-119613.J2xfrC.rst b/Misc/NEWS.d/next/C API/2024-05-29-09-21-37.gh-issue-119613.J2xfrC.rst deleted file mode 100644 index 196a4722a98c70..00000000000000 --- a/Misc/NEWS.d/next/C API/2024-05-29-09-21-37.gh-issue-119613.J2xfrC.rst +++ /dev/null @@ -1,2 +0,0 @@ -Macros ``Py_IS_NAN``, ``Py_IS_INFINITY`` and ``Py_IS_FINITE`` -are :term:`soft deprecated`. diff --git a/Misc/NEWS.d/next/C API/2024-05-29-21-05-59.gh-issue-119585.Sn7JL3.rst b/Misc/NEWS.d/next/C API/2024-05-29-21-05-59.gh-issue-119585.Sn7JL3.rst deleted file mode 100644 index 038dec2dbf90d1..00000000000000 --- a/Misc/NEWS.d/next/C API/2024-05-29-21-05-59.gh-issue-119585.Sn7JL3.rst +++ /dev/null @@ -1,5 +0,0 @@ -Fix crash when a thread state that was created by :c:func:`PyGILState_Ensure` -calls a destructor that during :c:func:`PyThreadState_Clear` that -calls back into :c:func:`PyGILState_Ensure` and :c:func:`PyGILState_Release`. -This might occur when in the free-threaded build or when using thread-local -variables whose destructors call :c:func:`PyGILState_Ensure`. diff --git a/Misc/NEWS.d/next/C API/2024-05-30-12-51-21.gh-issue-119775.CBq9IG.rst b/Misc/NEWS.d/next/C API/2024-05-30-12-51-21.gh-issue-119775.CBq9IG.rst deleted file mode 100644 index c342a3814ed5db..00000000000000 --- a/Misc/NEWS.d/next/C API/2024-05-30-12-51-21.gh-issue-119775.CBq9IG.rst +++ /dev/null @@ -1,2 +0,0 @@ -Creating :c:data:`immutable types ` with mutable -bases was deprecated since 3.12 and now raises a :exc:`TypeError`. diff --git a/Misc/NEWS.d/next/C API/2024-06-04-10-58-20.gh-issue-119613.qOr9GF.rst b/Misc/NEWS.d/next/C API/2024-06-04-10-58-20.gh-issue-119613.qOr9GF.rst deleted file mode 100644 index 11f075b79e6f67..00000000000000 --- a/Misc/NEWS.d/next/C API/2024-06-04-10-58-20.gh-issue-119613.qOr9GF.rst +++ /dev/null @@ -1,2 +0,0 @@ -Soft deprecate the :c:macro:`!Py_MEMCPY` macro: use directly ``memcpy()`` -instead. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2024-06-07-22-12-30.gh-issue-119182.yt8Ar7.rst b/Misc/NEWS.d/next/C API/2024-06-07-22-12-30.gh-issue-119182.yt8Ar7.rst deleted file mode 100644 index 243f290fbd47e2..00000000000000 --- a/Misc/NEWS.d/next/C API/2024-06-07-22-12-30.gh-issue-119182.yt8Ar7.rst +++ /dev/null @@ -1,16 +0,0 @@ -Add a new :c:type:`PyUnicodeWriter` API to create a Python :class:`str` object: - -* :c:func:`PyUnicodeWriter_Create`. -* :c:func:`PyUnicodeWriter_Discard`. -* :c:func:`PyUnicodeWriter_Finish`. -* :c:func:`PyUnicodeWriter_WriteChar`. -* :c:func:`PyUnicodeWriter_WriteUTF8`. -* :c:func:`PyUnicodeWriter_WriteUCS4`. -* :c:func:`PyUnicodeWriter_WriteWideChar`. -* :c:func:`PyUnicodeWriter_WriteStr`. -* :c:func:`PyUnicodeWriter_WriteRepr`. -* :c:func:`PyUnicodeWriter_WriteSubstring`. -* :c:func:`PyUnicodeWriter_Format`. -* :c:func:`PyUnicodeWriter_DecodeUTF8Stateful`. - -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2024-06-08-08-33-40.gh-issue-119771.Oip2dL.rst b/Misc/NEWS.d/next/C API/2024-06-08-08-33-40.gh-issue-119771.Oip2dL.rst deleted file mode 100644 index 61619082487c3b..00000000000000 --- a/Misc/NEWS.d/next/C API/2024-06-08-08-33-40.gh-issue-119771.Oip2dL.rst +++ /dev/null @@ -1,2 +0,0 @@ -Set :data:`errno` in :c:func:`_Py_c_pow` on overflows. Patch by Sergey B -Kirpichev. diff --git a/Misc/NEWS.d/next/C API/2024-06-11-21-38-32.gh-issue-70278.WDE4zM.rst b/Misc/NEWS.d/next/C API/2024-06-11-21-38-32.gh-issue-70278.WDE4zM.rst deleted file mode 100644 index 1eca36a86bc97e..00000000000000 --- a/Misc/NEWS.d/next/C API/2024-06-11-21-38-32.gh-issue-70278.WDE4zM.rst +++ /dev/null @@ -1,4 +0,0 @@ -:c:func:`PyUnicode_FromFormat` no longer produces the ending ``\ufffd`` -character for truncated C string when use precision with ``%s`` and ``%V``. -It now truncates the string before the start of truncated multibyte -sequences. diff --git a/Misc/NEWS.d/next/C API/2024-06-16-22-58-47.gh-issue-120600.TJdf0w.rst b/Misc/NEWS.d/next/C API/2024-06-16-22-58-47.gh-issue-120600.TJdf0w.rst deleted file mode 100644 index 12ffd9b348d2b7..00000000000000 --- a/Misc/NEWS.d/next/C API/2024-06-16-22-58-47.gh-issue-120600.TJdf0w.rst +++ /dev/null @@ -1,2 +0,0 @@ -In the limited C API 3.14 and newer, :c:func:`Py_TYPE` is now implemented as an -opaque function call to hide implementation details. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2024-06-19-17-27-22.gh-issue-120389.GSZeHF.rst b/Misc/NEWS.d/next/C API/2024-06-19-17-27-22.gh-issue-120389.GSZeHF.rst deleted file mode 100644 index 094c8b00ac6859..00000000000000 --- a/Misc/NEWS.d/next/C API/2024-06-19-17-27-22.gh-issue-120389.GSZeHF.rst +++ /dev/null @@ -1,13 +0,0 @@ -Add new functions to convert C ```` numbers from/to Python -:class:`int`: - -* :c:func:`PyLong_FromInt32` -* :c:func:`PyLong_FromUInt32` -* :c:func:`PyLong_FromInt64` -* :c:func:`PyLong_FromUInt64` -* :c:func:`PyLong_AsInt32` -* :c:func:`PyLong_AsUInt32` -* :c:func:`PyLong_AsInt64` -* :c:func:`PyLong_AsUInt64` - -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2024-06-19-21-27-42.gh-issue-120642.UlKClN.rst b/Misc/NEWS.d/next/C API/2024-06-19-21-27-42.gh-issue-120642.UlKClN.rst deleted file mode 100644 index a61224ec8ef119..00000000000000 --- a/Misc/NEWS.d/next/C API/2024-06-19-21-27-42.gh-issue-120642.UlKClN.rst +++ /dev/null @@ -1,10 +0,0 @@ -Remove the following unstable functions: - -* ``PyUnstable_Replace_Executor()`` -* ``PyUnstable_SetOptimizer()`` -* ``PyUnstable_GetOptimizer()`` -* ``PyUnstable_GetExecutor()`` -* ``PyUnstable_Optimizer_NewCounter()`` -* ``PyUnstable_Optimizer_NewUOpOptimizer()`` - -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2024-06-21-16-41-21.gh-issue-120858.Z5_-Mn.rst b/Misc/NEWS.d/next/C API/2024-06-21-16-41-21.gh-issue-120858.Z5_-Mn.rst deleted file mode 100644 index b5df2a567b9da8..00000000000000 --- a/Misc/NEWS.d/next/C API/2024-06-21-16-41-21.gh-issue-120858.Z5_-Mn.rst +++ /dev/null @@ -1,3 +0,0 @@ -:c:func:`PyDict_Next` no longer locks the dictionary in the free-threaded -build. The locking needs to be done by the caller around the entire iteration -loop. diff --git a/Misc/NEWS.d/next/C API/2024-06-26-11-29-01.gh-issue-120642.H7P9qK.rst b/Misc/NEWS.d/next/C API/2024-06-26-11-29-01.gh-issue-120642.H7P9qK.rst deleted file mode 100644 index 24fb6ca569f4f3..00000000000000 --- a/Misc/NEWS.d/next/C API/2024-06-26-11-29-01.gh-issue-120642.H7P9qK.rst +++ /dev/null @@ -1,3 +0,0 @@ -Remove the private ``_Py_CODEUNIT`` type from the public C API. The internal -``pycore_code.h`` header should now be used to get this internal type. Patch by -Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2024-07-02-11-03-40.gh-issue-112136.f3fiY8.rst b/Misc/NEWS.d/next/C API/2024-07-02-11-03-40.gh-issue-112136.f3fiY8.rst deleted file mode 100644 index a240b4e852c4d1..00000000000000 --- a/Misc/NEWS.d/next/C API/2024-07-02-11-03-40.gh-issue-112136.f3fiY8.rst +++ /dev/null @@ -1,3 +0,0 @@ -Restore the private ``_PyArg_Parser`` structure and the private -``_PyArg_ParseTupleAndKeywordsFast()`` function, previously removed in Python -3.13 alpha 1. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2024-07-04-13-23-27.gh-issue-113601.K3RLqp.rst b/Misc/NEWS.d/next/C API/2024-07-04-13-23-27.gh-issue-113601.K3RLqp.rst deleted file mode 100644 index 009cc2bf017180..00000000000000 --- a/Misc/NEWS.d/next/C API/2024-07-04-13-23-27.gh-issue-113601.K3RLqp.rst +++ /dev/null @@ -1,2 +0,0 @@ -Removed debug build assertions related to interning strings, which were -falsely triggered by stable ABI extensions. diff --git a/Misc/NEWS.d/next/C API/2024-07-04-15-41-10.gh-issue-113993.cLSiWV.rst b/Misc/NEWS.d/next/C API/2024-07-04-15-41-10.gh-issue-113993.cLSiWV.rst deleted file mode 100644 index 9b7f2082065eaa..00000000000000 --- a/Misc/NEWS.d/next/C API/2024-07-04-15-41-10.gh-issue-113993.cLSiWV.rst +++ /dev/null @@ -1,12 +0,0 @@ -:c:func:`PyUnicode_InternInPlace` no longer prevents its argument from being -garbage collected. - -Several functions that take ``char *`` are now -documented as possibly preventing string objects from being garbage -collected; refer to their documentation for details: -:c:func:`PyUnicode_InternFromString`, -:c:func:`PyDict_SetItemString`, -:c:func:`PyObject_SetAttrString`, -:c:func:`PyObject_DelAttrString`, -:c:func:`PyUnicode_InternFromString`, -and ``PyModule_Add*`` convenience functions. diff --git a/Misc/NEWS.d/next/C API/2024-07-21-17-40-07.gh-issue-121489.SUMFCr.rst b/Misc/NEWS.d/next/C API/2024-07-21-17-40-07.gh-issue-121489.SUMFCr.rst deleted file mode 100644 index 8c18a49c05d547..00000000000000 --- a/Misc/NEWS.d/next/C API/2024-07-21-17-40-07.gh-issue-121489.SUMFCr.rst +++ /dev/null @@ -1 +0,0 @@ -Export private :c:func:`!_PyBytes_Join` again. diff --git a/Misc/NEWS.d/next/C API/2024-07-30-23-48-26.gh-issue-116622.yTTtil.rst b/Misc/NEWS.d/next/C API/2024-07-30-23-48-26.gh-issue-116622.yTTtil.rst deleted file mode 100644 index 7ae0f83f37bd62..00000000000000 --- a/Misc/NEWS.d/next/C API/2024-07-30-23-48-26.gh-issue-116622.yTTtil.rst +++ /dev/null @@ -1,3 +0,0 @@ -Make :any:`PyObject_Print` work around a bug in Android and OpenBSD which -prevented it from throwing an exception when trying to write to a read-only -stream. diff --git a/Misc/NEWS.d/next/C_API/2024-07-09-15-55-20.gh-issue-89364.yYYroI.rst b/Misc/NEWS.d/next/C_API/2024-07-09-15-55-20.gh-issue-89364.yYYroI.rst deleted file mode 100644 index b82e78446e4e87..00000000000000 --- a/Misc/NEWS.d/next/C_API/2024-07-09-15-55-20.gh-issue-89364.yYYroI.rst +++ /dev/null @@ -1,3 +0,0 @@ -Export the :c:func:`PySignal_SetWakeupFd` function. Previously, the function -was documented but it couldn't be used in 3rd party code. Patch by Victor -Stinner. diff --git a/Misc/NEWS.d/next/C_API/2024-07-12-13-40-59.gh-issue-121645.96QvD3.rst b/Misc/NEWS.d/next/C_API/2024-07-12-13-40-59.gh-issue-121645.96QvD3.rst deleted file mode 100644 index 1cca9b2230c3f4..00000000000000 --- a/Misc/NEWS.d/next/C_API/2024-07-12-13-40-59.gh-issue-121645.96QvD3.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add :c:func:`PyBytes_Join(sep, iterable) ` function, similar to -``sep.join(iterable)`` in Python. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C_API/2024-07-27-00-28-35.gh-issue-105201.0-xUWq.rst b/Misc/NEWS.d/next/C_API/2024-07-27-00-28-35.gh-issue-105201.0-xUWq.rst deleted file mode 100644 index bf5300b1c5d5f8..00000000000000 --- a/Misc/NEWS.d/next/C_API/2024-07-27-00-28-35.gh-issue-105201.0-xUWq.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add :c:func:`PyIter_NextItem` to replace :c:func:`PyIter_Next`, which has an -ambiguous return value. Patch by Irit Katriel and Erlend Aasland. diff --git a/Misc/NEWS.d/next/C_API/2024-08-06-14-23-11.gh-issue-122728.l-fQ-v.rst b/Misc/NEWS.d/next/C_API/2024-08-06-14-23-11.gh-issue-122728.l-fQ-v.rst deleted file mode 100644 index a128d6aef34dfc..00000000000000 --- a/Misc/NEWS.d/next/C_API/2024-08-06-14-23-11.gh-issue-122728.l-fQ-v.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix :c:func:`PyEval_GetLocals` to avoid :exc:`SystemError` ("bad argument to -internal function"). Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C_API/2024-08-09-13-12-20.gh-issue-122854.-1OgvU.rst b/Misc/NEWS.d/next/C_API/2024-08-09-13-12-20.gh-issue-122854.-1OgvU.rst deleted file mode 100644 index b94d8f4e483bda..00000000000000 --- a/Misc/NEWS.d/next/C_API/2024-08-09-13-12-20.gh-issue-122854.-1OgvU.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add :c:func:`Py_HashBuffer` to compute and return the hash value of a buffer. -Patch by Antoine Pitrou and Victor Stinner. diff --git a/Misc/NEWS.d/next/C_API/2024-08-26-13-01-20.gh-issue-100554.0ku85o.rst b/Misc/NEWS.d/next/C_API/2024-08-26-13-01-20.gh-issue-100554.0ku85o.rst deleted file mode 100644 index 97138dedf26b6f..00000000000000 --- a/Misc/NEWS.d/next/C_API/2024-08-26-13-01-20.gh-issue-100554.0ku85o.rst +++ /dev/null @@ -1,4 +0,0 @@ -Added a slot ``Py_tp_vectorcall`` to set -:c:member:`~PyTypeObject.tp_vectorcall` via the :c:func:`PyType_FromSpec` -function family. Limited API extensions can use this feature to provide more -efficient vector call-based implementation of ``__new__`` and ``__init__``. diff --git a/Misc/NEWS.d/next/C_API/2024-08-29-15-05-19.gh-issue-123465.eqwNWq.rst b/Misc/NEWS.d/next/C_API/2024-08-29-15-05-19.gh-issue-123465.eqwNWq.rst deleted file mode 100644 index 1935adfad8885b..00000000000000 --- a/Misc/NEWS.d/next/C_API/2024-08-29-15-05-19.gh-issue-123465.eqwNWq.rst +++ /dev/null @@ -1,4 +0,0 @@ -:c:macro:`Py_RELATIVE_OFFSET` is now allowed in :c:type:`PyMemberDef` for -the special offset member ``"__vectorcalloffset__"``, as well as the -discouraged special offset members ``"__dictoffset__"`` and -``"__weaklistoffset__"`` diff --git a/Misc/NEWS.d/next/C_API/2024-08-29-15-55-55.gh-issue-107954.pr2O50.rst b/Misc/NEWS.d/next/C_API/2024-08-29-15-55-55.gh-issue-107954.pr2O50.rst deleted file mode 100644 index f1116870c9d1c3..00000000000000 --- a/Misc/NEWS.d/next/C_API/2024-08-29-15-55-55.gh-issue-107954.pr2O50.rst +++ /dev/null @@ -1,8 +0,0 @@ -Add functions to get and set the current runtime Python configuration: - -* :c:func:`PyConfig_Get` -* :c:func:`PyConfig_GetInt` -* :c:func:`PyConfig_Set` -* :c:func:`PyConfig_Names` - -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C_API/2024-08-30-14-02-17.gh-issue-107954.TPvj4u.rst b/Misc/NEWS.d/next/C_API/2024-08-30-14-02-17.gh-issue-107954.TPvj4u.rst deleted file mode 100644 index e0ebd816bd6586..00000000000000 --- a/Misc/NEWS.d/next/C_API/2024-08-30-14-02-17.gh-issue-107954.TPvj4u.rst +++ /dev/null @@ -1,18 +0,0 @@ -Add functions to configure the Python initialization (:pep:`741`): - -* :c:func:`PyInitConfig_Create` -* :c:func:`PyInitConfig_Free` -* :c:func:`PyInitConfig_GetError` -* :c:func:`PyInitConfig_GetExitCode` -* :c:func:`PyInitConfig_HasOption` -* :c:func:`PyInitConfig_GetInt` -* :c:func:`PyInitConfig_GetStr` -* :c:func:`PyInitConfig_GetStrList` -* :c:func:`PyInitConfig_FreeStrList` -* :c:func:`PyInitConfig_SetInt` -* :c:func:`PyInitConfig_SetStr` -* :c:func:`PyInitConfig_SetStrList` -* :c:func:`PyInitConfig_AddModule` -* :c:func:`Py_InitializeFromInitConfig` - -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C_API/2024-09-10-16-54-27.gh-issue-123909.CTGxDR.rst b/Misc/NEWS.d/next/C_API/2024-09-10-16-54-27.gh-issue-123909.CTGxDR.rst deleted file mode 100644 index b7a4913abbcb89..00000000000000 --- a/Misc/NEWS.d/next/C_API/2024-09-10-16-54-27.gh-issue-123909.CTGxDR.rst +++ /dev/null @@ -1,3 +0,0 @@ -:c:func:`PyType_FromSpec`, :c:func:`PyType_FromSpecWithBases` and -:c:func:`PyType_FromModuleAndSpec` will now fail if the metaclass of the new -type has custom :c:member:`~PyTypeObject.tp_new`. diff --git a/Misc/NEWS.d/next/C_API/2024-09-12-16-16-24.gh-issue-123880.2-8vcj.rst b/Misc/NEWS.d/next/C_API/2024-09-12-16-16-24.gh-issue-123880.2-8vcj.rst deleted file mode 100644 index 8a31c962ec7d93..00000000000000 --- a/Misc/NEWS.d/next/C_API/2024-09-12-16-16-24.gh-issue-123880.2-8vcj.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed a bug that prevented circular imports of extension modules that use -single-phase initialization. diff --git a/Misc/NEWS.d/next/C_API/2024-09-16-16-21-39.gh-issue-124127.LB8DBU.rst b/Misc/NEWS.d/next/C_API/2024-09-16-16-21-39.gh-issue-124127.LB8DBU.rst deleted file mode 100644 index 883f173f8fbbc4..00000000000000 --- a/Misc/NEWS.d/next/C_API/2024-09-16-16-21-39.gh-issue-124127.LB8DBU.rst +++ /dev/null @@ -1,3 +0,0 @@ -In the limited C API 3.14 and newer, :c:func:`Py_REFCNT` is now implemented -as an opaque function call to hide implementation details. Patch by Victor -Stinner. diff --git a/Misc/NEWS.d/next/C_API/2024-09-17-05-23-35.gh-issue-124153.L8TWmx.rst b/Misc/NEWS.d/next/C_API/2024-09-17-05-23-35.gh-issue-124153.L8TWmx.rst deleted file mode 100644 index b8c0b4667cb730..00000000000000 --- a/Misc/NEWS.d/next/C_API/2024-09-17-05-23-35.gh-issue-124153.L8TWmx.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add :c:func:`PyType_GetBaseByToken` and :c:data:`Py_tp_token` slot for easier -type checking, related to :pep:`489` and :pep:`630`. diff --git a/Misc/NEWS.d/next/C_API/2024-09-18-18-40-30.gh-issue-124160.Zy-VKi.rst b/Misc/NEWS.d/next/C_API/2024-09-18-18-40-30.gh-issue-124160.Zy-VKi.rst deleted file mode 100644 index 26e7aef08ea4f3..00000000000000 --- a/Misc/NEWS.d/next/C_API/2024-09-18-18-40-30.gh-issue-124160.Zy-VKi.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix crash when importing modules containing state and single-phase -initialization in a subinterpreter. diff --git a/Misc/NEWS.d/next/C_API/2024-09-24-20-34-21.gh-issue-124296.S4QoS1.rst b/Misc/NEWS.d/next/C_API/2024-09-24-20-34-21.gh-issue-124296.S4QoS1.rst deleted file mode 100644 index e7b9187655eb31..00000000000000 --- a/Misc/NEWS.d/next/C_API/2024-09-24-20-34-21.gh-issue-124296.S4QoS1.rst +++ /dev/null @@ -1,3 +0,0 @@ -:c:type:`PyDictObject` no longer maintains a private version tag field -``ma_version_tag`` per :pep:`699`. This field was originally added in -Python 3.6 (:pep:`509`) and deprecated in Python 3.12. diff --git a/Misc/NEWS.d/next/C_API/2024-09-25-11-44-02.gh-issue-124502.qWuDjT.rst b/Misc/NEWS.d/next/C_API/2024-09-25-11-44-02.gh-issue-124502.qWuDjT.rst deleted file mode 100644 index f515619328b359..00000000000000 --- a/Misc/NEWS.d/next/C_API/2024-09-25-11-44-02.gh-issue-124502.qWuDjT.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add :c:func:`PyUnicode_Equal` function to the limited C API: test if two -strings are equal. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C_API/2024-10-03-14-06-08.gh-issue-123961.uwJQTY.rst b/Misc/NEWS.d/next/C_API/2024-10-03-14-06-08.gh-issue-123961.uwJQTY.rst deleted file mode 100644 index 40c26e15a2de92..00000000000000 --- a/Misc/NEWS.d/next/C_API/2024-10-03-14-06-08.gh-issue-123961.uwJQTY.rst +++ /dev/null @@ -1,3 +0,0 @@ -Convert the :ref:`curses.window ` static type exposed -by the :c:macro:`!PyCursesWindow_Type` macro in ``Include/py_curses.h`` to a -:ref:`heap type `. Patch by Bénédikt Tran. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-10-09-15-14-53.bpo-24766.c_C1Wc.rst b/Misc/NEWS.d/next/Core and Builtins/2018-10-09-15-14-53.bpo-24766.c_C1Wc.rst deleted file mode 100644 index 93a8562efe6d6f..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2018-10-09-15-14-53.bpo-24766.c_C1Wc.rst +++ /dev/null @@ -1 +0,0 @@ -Fix handling of ``doc`` argument to subclasses of ``property``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-22-15-56-35.gh-issue-95144.FZYWX-.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-22-15-56-35.gh-issue-95144.FZYWX-.rst deleted file mode 100644 index 83b1126a8a455f..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-07-22-15-56-35.gh-issue-95144.FZYWX-.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve the error message from ``a in b`` when ``b`` is not a container -to mention the term "container". diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-10-14-23-05-40.gh-issue-84978.Z0t6dg.rst b/Misc/NEWS.d/next/Core and Builtins/2023-10-14-23-05-40.gh-issue-84978.Z0t6dg.rst deleted file mode 100644 index b1f08288f925da..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-10-14-23-05-40.gh-issue-84978.Z0t6dg.rst +++ /dev/null @@ -1 +0,0 @@ -Add class methods :meth:`float.from_number` and :meth:`complex.from_number`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-01-15-18-11-48.gh-issue-113190.OwQX64.rst b/Misc/NEWS.d/next/Core and Builtins/2024-01-15-18-11-48.gh-issue-113190.OwQX64.rst deleted file mode 100644 index 4c12870c3df548..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-01-15-18-11-48.gh-issue-113190.OwQX64.rst +++ /dev/null @@ -1 +0,0 @@ -:c:func:`Py_Finalize` now deletes all interned strings. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-01-15-21-51-26.gh-issue-114091.VOtSJl.rst b/Misc/NEWS.d/next/Core and Builtins/2024-01-15-21-51-26.gh-issue-114091.VOtSJl.rst deleted file mode 100644 index 55b7d9104baed9..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-01-15-21-51-26.gh-issue-114091.VOtSJl.rst +++ /dev/null @@ -1 +0,0 @@ -Changed the error message for awaiting something that can't be awaited from "object can't be used in an await expression" to "'' object can't be awaited". diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-03-19-22-21-22.gh-issue-116022.iyHENN.rst b/Misc/NEWS.d/next/Core and Builtins/2024-03-19-22-21-22.gh-issue-116022.iyHENN.rst deleted file mode 100644 index 659ffb289129e2..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-03-19-22-21-22.gh-issue-116022.iyHENN.rst +++ /dev/null @@ -1 +0,0 @@ -Improve the :meth:`~object.__repr__` output of :class:`~ast.AST` nodes. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-03-25-15-07-01.gh-issue-117195.OWakgD.rst b/Misc/NEWS.d/next/Core and Builtins/2024-03-25-15-07-01.gh-issue-117195.OWakgD.rst deleted file mode 100644 index ae1e5acc5c333b..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-03-25-15-07-01.gh-issue-117195.OWakgD.rst +++ /dev/null @@ -1,2 +0,0 @@ -Avoid assertion failure for debug builds when calling -``object.__sizeof__(1)`` diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-04-08-13-49-02.gh-issue-117558.9lSEpR.rst b/Misc/NEWS.d/next/Core and Builtins/2024-04-08-13-49-02.gh-issue-117558.9lSEpR.rst deleted file mode 100644 index 222c516d2ef1b9..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-04-08-13-49-02.gh-issue-117558.9lSEpR.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve error messages when a string, bytes or bytearray object of length 1 -is expected. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-04-27-18-36-46.gh-issue-115801.SVeHSy.rst b/Misc/NEWS.d/next/Core and Builtins/2024-04-27-18-36-46.gh-issue-115801.SVeHSy.rst deleted file mode 100644 index 93b176d5767335..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-04-27-18-36-46.gh-issue-115801.SVeHSy.rst +++ /dev/null @@ -1 +0,0 @@ -Raise ``TypeError`` when passing a string to :func:`difflib.unified_diff` and :func:`difflib.context_diff`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-01-05-09-16.gh-issue-117139.t41w_D.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-01-05-09-16.gh-issue-117139.t41w_D.rst deleted file mode 100644 index 07d5dd53aac30a..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-01-05-09-16.gh-issue-117139.t41w_D.rst +++ /dev/null @@ -1,5 +0,0 @@ -Convert the Python evaluation stack to use internal stack references. The -purpose is to support tagged pointers. In :pep:`703`, this will -allow for its form of deferred reference counting. For both -the default and free-threaded builds, this sets up the infrastructure -for unboxed integers in the future. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-07-16-57-56.gh-issue-118561.wNMKVd.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-07-16-57-56.gh-issue-118561.wNMKVd.rst deleted file mode 100644 index c506a8cefd00f1..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-07-16-57-56.gh-issue-118561.wNMKVd.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix race condition in free-threaded build where :meth:`!list.extend` could -expose uninitialised memory to concurrent readers. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-08-09-44-15.gh-issue-118767.iFF5F5.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-08-09-44-15.gh-issue-118767.iFF5F5.rst deleted file mode 100644 index 4828f8fbf50cea..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-08-09-44-15.gh-issue-118767.iFF5F5.rst +++ /dev/null @@ -1,2 +0,0 @@ -Using :data:`NotImplemented` in a boolean context now raises -:exc:`TypeError`. Contributed by Jelle Zijlstra. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-09-02-37-25.gh-issue-118750.7aLfT-.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-09-02-37-25.gh-issue-118750.7aLfT-.rst deleted file mode 100644 index 727427d451d1e0..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-09-02-37-25.gh-issue-118750.7aLfT-.rst +++ /dev/null @@ -1 +0,0 @@ -If the C version of the ``decimal`` module is available, ``int(str)`` now uses it to supply an asymptotically much faster conversion. However, this only applies if the string contains over about 2 million digits. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-09-19-47-12.gh-issue-117657.Vn0Yey.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-09-19-47-12.gh-issue-117657.Vn0Yey.rst deleted file mode 100644 index db4c5813ca610c..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-09-19-47-12.gh-issue-117657.Vn0Yey.rst +++ /dev/null @@ -1 +0,0 @@ -Fix data races on the field that stores a pointer to the interpreter's main thread that occur in free-threaded builds. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-10-19-54-18.gh-issue-118921.O4ztZG.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-10-19-54-18.gh-issue-118921.O4ztZG.rst deleted file mode 100644 index 39ccf472067cfd..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-10-19-54-18.gh-issue-118921.O4ztZG.rst +++ /dev/null @@ -1 +0,0 @@ -Add ``copy()`` method for ``FrameLocalsProxy`` which returns a snapshot ``dict`` for local variables. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-11-21-44-17.gh-issue-118844.q2H_km.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-11-21-44-17.gh-issue-118844.q2H_km.rst deleted file mode 100644 index 6e80b773889413..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-11-21-44-17.gh-issue-118844.q2H_km.rst +++ /dev/null @@ -1 +0,0 @@ -Fix build failures when configuring with both ``--disable-gil`` and ``--enable-experimental-jit``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-15-12-15-58.gh-issue-119057.P3G9G2.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-15-12-15-58.gh-issue-119057.P3G9G2.rst deleted file mode 100644 index d252888906c348..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-15-12-15-58.gh-issue-119057.P3G9G2.rst +++ /dev/null @@ -1,4 +0,0 @@ -Improve :exc:`ZeroDivisionError` error message. -Now, all error messages are harmonized: all ``/``, ``//``, and ``%`` -operations just use "division by zero" message. -And ``0 ** -1`` operation uses "zero to a negative power". diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-16-23-02-03.gh-issue-119049.qpd_S-.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-16-23-02-03.gh-issue-119049.qpd_S-.rst deleted file mode 100644 index 1d7aad8d1e5be6..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-16-23-02-03.gh-issue-119049.qpd_S-.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix displaying the source line for warnings created by the C API if the -:mod:`warnings` module had not yet been imported. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-20-10-10-51.gh-issue-119180.35xqpu.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-20-10-10-51.gh-issue-119180.35xqpu.rst deleted file mode 100644 index 5a88ce097274fb..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-20-10-10-51.gh-issue-119180.35xqpu.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add an ``__annotate__`` attribute to functions, classes, and modules as part -of :pep:`649`. Patch by Jelle Zijlstra. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-20-14-57-39.gh-issue-118692.Qadm7F.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-20-14-57-39.gh-issue-118692.Qadm7F.rst deleted file mode 100644 index 11d177886df5b5..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-20-14-57-39.gh-issue-118692.Qadm7F.rst +++ /dev/null @@ -1 +0,0 @@ -Avoid creating unnecessary :exc:`StopIteration` instances for monitoring. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-21-09-46-51.gh-issue-119011.WOe3bu.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-21-09-46-51.gh-issue-119011.WOe3bu.rst deleted file mode 100644 index 0083c18da13278..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-21-09-46-51.gh-issue-119011.WOe3bu.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixes ``type.__type_params__`` to return an empty tuple instead of a -descriptor. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-21-11-27-14.gh-issue-119213.nxjxrt.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-21-11-27-14.gh-issue-119213.nxjxrt.rst deleted file mode 100644 index e9073b4ba08798..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-21-11-27-14.gh-issue-119213.nxjxrt.rst +++ /dev/null @@ -1,3 +0,0 @@ -Non-builtin modules built with argument clinic were crashing if used in a -subinterpreter before the main interpreter. The objects that were causing -the problem by leaking between interpreters carelessly have been fixed. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-21-12-17-02.gh-issue-119180.UNDUb9.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-21-12-17-02.gh-issue-119180.UNDUb9.rst deleted file mode 100644 index 54c6639e0fa524..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-21-12-17-02.gh-issue-119180.UNDUb9.rst +++ /dev/null @@ -1,2 +0,0 @@ -Replace :opcode:`!LOAD_ASSERTION_ERROR` opcode with :opcode:`LOAD_COMMON_CONSTANT` -and add support for :exc:`NotImplementedError`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-22-06-22-47.gh-issue-119180.vZMiXm.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-22-06-22-47.gh-issue-119180.vZMiXm.rst deleted file mode 100644 index 265ffb32e6a1f9..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-22-06-22-47.gh-issue-119180.vZMiXm.rst +++ /dev/null @@ -1 +0,0 @@ -Evaluation of annotations is now deferred. See :pep:`649` for details. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-22-12-49-03.gh-issue-119372.PXig1R.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-22-12-49-03.gh-issue-119372.PXig1R.rst deleted file mode 100644 index aa628299abbd95..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-22-12-49-03.gh-issue-119372.PXig1R.rst +++ /dev/null @@ -1,2 +0,0 @@ -Correct invalid corner cases in complex division (resulted in ``(nan+nanj)`` -output), e.g. ``1/complex('(inf+infj)')``. Patch by Sergey B Kirpichev. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-23-06-34-14.gh-issue-119395.z-Hsqb.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-23-06-34-14.gh-issue-119395.z-Hsqb.rst deleted file mode 100644 index 24cd90a8e5e5db..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-23-06-34-14.gh-issue-119395.z-Hsqb.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix bug where names appearing after a generic class are mangled as if they -are in the generic class. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-23-06-34-45.gh-issue-119311.2DBwKR.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-23-06-34-45.gh-issue-119311.2DBwKR.rst deleted file mode 100644 index 9e0db37340c49a..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-23-06-34-45.gh-issue-119311.2DBwKR.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix bug where names are unexpectedly mangled in the bases of generic -classes. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-23-20-17-37.gh-issue-119258.wZFIpt.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-23-20-17-37.gh-issue-119258.wZFIpt.rst deleted file mode 100644 index 68f1ec1efa5751..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-23-20-17-37.gh-issue-119258.wZFIpt.rst +++ /dev/null @@ -1,3 +0,0 @@ -Eliminate type version guards in the tier two interpreter. - -Note that setting the ``tp_version_tag`` manually (which has never been supported) may result in crashes. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-24-21-04-00.gh-issue-119525.zLFLf1.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-24-21-04-00.gh-issue-119525.zLFLf1.rst deleted file mode 100644 index 83c29a16e572d7..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-24-21-04-00.gh-issue-119525.zLFLf1.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix deadlock involving ``_PyType_Lookup()`` cache in the free-threaded build -when the GIL is dynamically enabled at runtime. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-24-21-16-52.gh-issue-119369.qBThho.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-24-21-16-52.gh-issue-119369.qBThho.rst deleted file mode 100644 index 7abdd5cd85ccd6..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-24-21-16-52.gh-issue-119369.qBThho.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix deadlock during thread deletion in free-threaded build, which could -occur when the GIL was enabled at runtime. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-25-12-52-25.gh-issue-119560.wSlm8q.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-25-12-52-25.gh-issue-119560.wSlm8q.rst deleted file mode 100644 index 3a28a94df0f7cf..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-25-12-52-25.gh-issue-119560.wSlm8q.rst +++ /dev/null @@ -1,3 +0,0 @@ -An invalid assert in beta 1 has been removed. The assert would fail if -``PyState_FindModule()`` was used in an extension module's init function -before the module def had been initialized. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-25-13-51-48.gh-issue-111999.L0q1gh.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-25-13-51-48.gh-issue-111999.L0q1gh.rst deleted file mode 100644 index 4b1ca6ca5b0765..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-25-13-51-48.gh-issue-111999.L0q1gh.rst +++ /dev/null @@ -1 +0,0 @@ -Fix the signature of :meth:`str.format_map`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-25-16-45-27.gh-issue-119548.pqF9Y6.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-25-16-45-27.gh-issue-119548.pqF9Y6.rst deleted file mode 100644 index 0318790d46f0a3..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-25-16-45-27.gh-issue-119548.pqF9Y6.rst +++ /dev/null @@ -1 +0,0 @@ -Add a ``clear`` command to the REPL. Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-27-19-13-49.gh-issue-109218.-sdDg0.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-27-19-13-49.gh-issue-109218.-sdDg0.rst deleted file mode 100644 index db762174a8c1e1..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-27-19-13-49.gh-issue-109218.-sdDg0.rst +++ /dev/null @@ -1,3 +0,0 @@ -:func:`complex` accepts now a string only as a positional argument. Passing -a complex number as the "real" or "imag" argument is deprecated; it should -only be passed as a single positional argument. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-28-22-49-56.gh-issue-119689.VwLFD5.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-28-22-49-56.gh-issue-119689.VwLFD5.rst deleted file mode 100644 index 56be31326216eb..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-28-22-49-56.gh-issue-119689.VwLFD5.rst +++ /dev/null @@ -1 +0,0 @@ -Generate stack effect metadata for pseudo instructions from bytecodes.c. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-29-18-53-43.gh-issue-119740.zP2JNM.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-29-18-53-43.gh-issue-119740.zP2JNM.rst deleted file mode 100644 index 111e096d262ea0..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-29-18-53-43.gh-issue-119740.zP2JNM.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove the previously-deprecated delegation of :func:`int` to -:meth:`~object.__trunc__`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-30-04-11-36.gh-issue-118934.fbDqve.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-30-04-11-36.gh-issue-118934.fbDqve.rst deleted file mode 100644 index 3087034fe458b8..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-30-04-11-36.gh-issue-118934.fbDqve.rst +++ /dev/null @@ -1 +0,0 @@ -Make ``PyEval_GetLocals`` return borrowed reference diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-30-23-01-00.gh-issue-119821.jPGfvt.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-30-23-01-00.gh-issue-119821.jPGfvt.rst deleted file mode 100644 index cc25eee6dd6ae4..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-30-23-01-00.gh-issue-119821.jPGfvt.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix execution of :ref:`annotation scopes ` within classes -when ``globals`` is set to a non-dict. Patch by Jelle Zijlstra. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-31-08-23-41.gh-issue-119180.KL4VxZ.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-31-08-23-41.gh-issue-119180.KL4VxZ.rst deleted file mode 100644 index 567c096472878f..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-31-08-23-41.gh-issue-119180.KL4VxZ.rst +++ /dev/null @@ -1,3 +0,0 @@ -:func:`classmethod` and :func:`staticmethod` now wrap the -:attr:`~object.__annotations__` and :attr:`~object.__annotate__` attributes of -their underlying callable lazily. See :pep:`649`. Patch by Jelle Zijlstra. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-31-12-06-11.gh-issue-119842.tCGVsv.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-31-12-06-11.gh-issue-119842.tCGVsv.rst deleted file mode 100644 index 2fcb170f6226e5..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-31-12-06-11.gh-issue-119842.tCGVsv.rst +++ /dev/null @@ -1 +0,0 @@ -Honor :c:func:`PyOS_InputHook` in the new REPL. Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-02-06-12-35.gh-issue-119879.Jit951.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-02-06-12-35.gh-issue-119879.Jit951.rst deleted file mode 100644 index 89de6b0299a35a..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-02-06-12-35.gh-issue-119879.Jit951.rst +++ /dev/null @@ -1 +0,0 @@ -String search is now slightly faster for certain cases. It now utilizes last character gap (good suffix rule) for two-way periodic needles. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-03-13-25-04.gh-issue-119724.EH1dkA.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-03-13-25-04.gh-issue-119724.EH1dkA.rst deleted file mode 100644 index 78dc48da934cf6..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-03-13-25-04.gh-issue-119724.EH1dkA.rst +++ /dev/null @@ -1,3 +0,0 @@ -Reverted improvements to error messages for ``elif``/``else`` statements not -matching any valid statements, which made in hard to locate the syntax -errors inside those ``elif``/``else`` blocks. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-03-13-48-44.gh-issue-119933.Kc0HG5.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-03-13-48-44.gh-issue-119933.Kc0HG5.rst deleted file mode 100644 index 513a0200dcc48a..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-03-13-48-44.gh-issue-119933.Kc0HG5.rst +++ /dev/null @@ -1,4 +0,0 @@ -Improve :exc:`SyntaxError` messages for invalid expressions in a type -parameters bound, a type parameter constraint tuple or a default type -parameter. -Patch by Bénédikt Tran. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-05-08-39-40.gh-issue-120080.DJFK11.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-05-08-39-40.gh-issue-120080.DJFK11.rst deleted file mode 100644 index 8c5602fcdb4ad2..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-05-08-39-40.gh-issue-120080.DJFK11.rst +++ /dev/null @@ -1,2 +0,0 @@ -Direct call to the :meth:`!int.__round__` now accepts ``None`` -as a valid argument. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-05-10-32-44.gh-issue-120097.9S2klk.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-05-10-32-44.gh-issue-120097.9S2klk.rst deleted file mode 100644 index 39d829bb0ed310..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-05-10-32-44.gh-issue-120097.9S2klk.rst +++ /dev/null @@ -1,2 +0,0 @@ -``FrameLocalsProxy`` now subclasses ``collections.abc.Mapping`` and can be -matched as a mapping in ``match`` statements diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-05-18-29-18.gh-issue-93691.6OautB.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-05-18-29-18.gh-issue-93691.6OautB.rst deleted file mode 100644 index c06d5a276c03eb..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-05-18-29-18.gh-issue-93691.6OautB.rst +++ /dev/null @@ -1 +0,0 @@ -Fix source locations of instructions generated for with statements. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-07-16-09-04.gh-issue-120225.kuYf9t.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-07-16-09-04.gh-issue-120225.kuYf9t.rst deleted file mode 100644 index d00b9aaa8192e3..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-07-16-09-04.gh-issue-120225.kuYf9t.rst +++ /dev/null @@ -1 +0,0 @@ -Fix crash in compiler on empty block at end of exception handler. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-07-22-54-15.gh-issue-119726.D9EE-o.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-07-22-54-15.gh-issue-119726.D9EE-o.rst deleted file mode 100644 index 595d8dda25fe1b..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-07-22-54-15.gh-issue-119726.D9EE-o.rst +++ /dev/null @@ -1 +0,0 @@ -JIT: Re-use trampolines on AArch64 when creating stencils. Patch by Diego Russo diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-09-19-13-38.gh-issue-119666.S0G4rZ.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-09-19-13-38.gh-issue-119666.S0G4rZ.rst deleted file mode 100644 index 09c1f553c48702..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-09-19-13-38.gh-issue-119666.S0G4rZ.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a compiler crash in the case where two comprehensions in class scope both reference ``__class__``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-10-10-42-48.gh-issue-120298.napREA.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-10-10-42-48.gh-issue-120298.napREA.rst deleted file mode 100644 index 2872006ee34b8b..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-10-10-42-48.gh-issue-120298.napREA.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix use-after free in ``list_richcompare_impl`` which can be invoked via -some specifically tailored evil input. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-10-15-07-16.gh-issue-120198.WW_pjO.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-10-15-07-16.gh-issue-120198.WW_pjO.rst deleted file mode 100644 index 8dc8aec44d80c4..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-10-15-07-16.gh-issue-120198.WW_pjO.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a crash when multiple threads read and write to the same ``__class__`` of an object concurrently. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-10-22-30-26.gh-issue-93691.68WOTS.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-10-22-30-26.gh-issue-93691.68WOTS.rst deleted file mode 100644 index 294f8d892b459b..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-10-22-30-26.gh-issue-93691.68WOTS.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix source locations of instructions generated for the iterator of a for -statement. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-11-12-47-54.gh-issue-120346.hhn_6X.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-11-12-47-54.gh-issue-120346.hhn_6X.rst deleted file mode 100644 index 757a21625cfb83..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-11-12-47-54.gh-issue-120346.hhn_6X.rst +++ /dev/null @@ -1,2 +0,0 @@ -Respect :envvar:`PYTHON_BASIC_REPL` when running in interactive inspect mode -(``python -i``). Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-11-17-56-12.gh-issue-120221.si9hM9.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-11-17-56-12.gh-issue-120221.si9hM9.rst deleted file mode 100644 index 3781576bc5a257..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-11-17-56-12.gh-issue-120221.si9hM9.rst +++ /dev/null @@ -1,2 +0,0 @@ -Deliver real signals on Ctrl-C and Ctrl-Z in the new REPL. Patch by Pablo -Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-12-13-47-25.gh-issue-120397.n-I_cc.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-12-13-47-25.gh-issue-120397.n-I_cc.rst deleted file mode 100644 index 24f046d9d89d51..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-12-13-47-25.gh-issue-120397.n-I_cc.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve the throughput by up to two times for the :meth:`str.count`, :meth:`bytes.count` and :meth:`bytearray.count` -methods for counting single characters. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-12-18-23-15.gh-issue-120380.edtqjq.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-12-18-23-15.gh-issue-120380.edtqjq.rst deleted file mode 100644 index c682a0b7666416..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-12-18-23-15.gh-issue-120380.edtqjq.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix Python implementation of :class:`pickle.Pickler` for :class:`bytes` and -:class:`bytearray` objects when using protocol version 5. Patch by Bénédikt -Tran. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-12-18-50-29.gh-issue-120367.LmXx2y.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-12-18-50-29.gh-issue-120367.LmXx2y.rst deleted file mode 100644 index 2d7212a66f7a84..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-12-18-50-29.gh-issue-120367.LmXx2y.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix crash in compiler on code with redundant NOPs and JUMPs which show up -after exception handlers are moved to the end of the code. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-13-12-17-52.gh-issue-120384.w1UBGl.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-13-12-17-52.gh-issue-120384.w1UBGl.rst deleted file mode 100644 index 65959ca2d28075..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-13-12-17-52.gh-issue-120384.w1UBGl.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix an array out of bounds crash in ``list_ass_subscript``, which could be -invoked via some specifically tailored input: including concurrent modification -of a list object, where one thread assigns a slice and another clears it. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-14-07-52-00.gh-issue-120485.yy4K4b.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-14-07-52-00.gh-issue-120485.yy4K4b.rst deleted file mode 100644 index f41c233908362f..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-14-07-52-00.gh-issue-120485.yy4K4b.rst +++ /dev/null @@ -1 +0,0 @@ -Add an override of ``allow_reuse_port`` on classes subclassing ``socketserver.TCPServer`` where ``allow_reuse_address`` is also overridden. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-14-22-02-25.gh-issue-113993.MiA0vX.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-14-22-02-25.gh-issue-113993.MiA0vX.rst deleted file mode 100644 index 9931787cb36d4c..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-14-22-02-25.gh-issue-113993.MiA0vX.rst +++ /dev/null @@ -1,5 +0,0 @@ -Strings interned with :func:`sys.intern` are again garbage-collected when no -longer used, as per the documentation. Strings interned with the C function -:c:func:`PyUnicode_InternInPlace` are still immortal. Internals of the -string interning mechanism have been changed. This may affect performance -and identities of :class:`str` objects. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-17-12-20-20.gh-issue-120507.94lz2J.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-17-12-20-20.gh-issue-120507.94lz2J.rst deleted file mode 100644 index c12e104fa68e70..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-17-12-20-20.gh-issue-120507.94lz2J.rst +++ /dev/null @@ -1,3 +0,0 @@ -Remove the ``BEFORE_WITH`` and ``BEFORE_ASYNC_WITH`` -instructions. Add the new :opcode:`LOAD_SPECIAL` instruction. Generate code -for ``with`` and ``async with`` statements using the new instruction. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-18-21-34-30.gh-issue-120367.zDwffP.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-18-21-34-30.gh-issue-120367.zDwffP.rst deleted file mode 100644 index 087640e5400b98..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-18-21-34-30.gh-issue-120367.zDwffP.rst +++ /dev/null @@ -1 +0,0 @@ -Fix bug where compiler creates a redundant jump during pseudo-op replacement. Can only happen with a synthetic AST that has a try on the same line as the instruction following the exception handler. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-18-22-41-05.gh-issue-120722.rS7tkE.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-18-22-41-05.gh-issue-120722.rS7tkE.rst deleted file mode 100644 index df83e69c601a32..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-18-22-41-05.gh-issue-120722.rS7tkE.rst +++ /dev/null @@ -1,2 +0,0 @@ -Correctly set the bytecode position on return instructions within lambdas. -Patch by Jelle Zijlstra. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-19-01-58-54.gh-issue-120437.nCkIoI.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-19-01-58-54.gh-issue-120437.nCkIoI.rst deleted file mode 100644 index 8923f3fcefe3c1..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-19-01-58-54.gh-issue-120437.nCkIoI.rst +++ /dev/null @@ -1 +0,0 @@ -Fix ``_CHECK_STACK_SPACE`` optimization problems introduced in :gh:`118322`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-19-11-10-50.gh-issue-119462.DpcqSe.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-19-11-10-50.gh-issue-119462.DpcqSe.rst deleted file mode 100644 index 7a3b74b63b2e40..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-19-11-10-50.gh-issue-119462.DpcqSe.rst +++ /dev/null @@ -1,4 +0,0 @@ -Make sure that invariants of type versioning are maintained: -* Superclasses always have their version number assigned before subclasses -* The version tag is always zero if the tag is not valid. -* The version tag is always non-if the tag is valid. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-19-19-54-35.gh-issue-120754.uF29sj.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-19-19-54-35.gh-issue-120754.uF29sj.rst deleted file mode 100644 index 46481d8f31aaba..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-19-19-54-35.gh-issue-120754.uF29sj.rst +++ /dev/null @@ -1 +0,0 @@ -Reduce the number of system calls invoked when reading a whole file (ex. ``open('a.txt').read()``). For a sample program that reads the contents of the 400+ ``.rst`` files in the cpython repository ``Doc`` folder, there is an over 10% reduction in system call count. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-19-21-34-21.gh-issue-98442.cqhjkN.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-19-21-34-21.gh-issue-98442.cqhjkN.rst deleted file mode 100644 index fb0a93f41a583f..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-19-21-34-21.gh-issue-98442.cqhjkN.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix too wide source locations of the cleanup instructions of a with -statement. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-24-08-39-23.gh-issue-116017.-Bw2UY.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-24-08-39-23.gh-issue-116017.-Bw2UY.rst deleted file mode 100644 index 3ca1b37f701e46..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-24-08-39-23.gh-issue-116017.-Bw2UY.rst +++ /dev/null @@ -1,3 +0,0 @@ -Simplify the warmup mechanism used for "side exits" in JIT code, resulting -in slightly better performance and slightly lower memory usage for most -platforms. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-25-16-26-44.gh-issue-119726.WqvHxB.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-25-16-26-44.gh-issue-119726.WqvHxB.rst deleted file mode 100644 index 2e5132f61e504f..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-25-16-26-44.gh-issue-119726.WqvHxB.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve the speed and memory use of C function calls from JIT code on AArch64. -Patch by Diego Russo diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-26-13-42-36.gh-issue-113433.xKAtLB.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-26-13-42-36.gh-issue-113433.xKAtLB.rst deleted file mode 100644 index bf8377ac488bcc..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-26-13-42-36.gh-issue-113433.xKAtLB.rst +++ /dev/null @@ -1,2 +0,0 @@ -Subinterpreters now get cleaned up automatically during runtime -finalization. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-26-14-09-31.gh-issue-120838.nFeTL9.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-26-14-09-31.gh-issue-120838.nFeTL9.rst deleted file mode 100644 index 057d00aeeaba11..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-26-14-09-31.gh-issue-120838.nFeTL9.rst +++ /dev/null @@ -1,2 +0,0 @@ -:c:func:`Py_Finalize()` and :c:func:`Py_FinalizeEx()` now always run with -the main interpreter active. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-28-10-02-58.gh-issue-121115.EeSLfc.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-28-10-02-58.gh-issue-121115.EeSLfc.rst deleted file mode 100644 index aaecc873551cc7..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-28-10-02-58.gh-issue-121115.EeSLfc.rst +++ /dev/null @@ -1,3 +0,0 @@ -:c:func:`PyLong_AsNativeBytes` no longer uses :meth:`~object.__index__` -methods by default. The ``Py_ASNATIVEBYTES_ALLOW_INDEX`` flag has been added -to allow it. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-28-18-34-49.gh-issue-119726.Fjv_Ab.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-28-18-34-49.gh-issue-119726.Fjv_Ab.rst deleted file mode 100644 index cf5d61450aa3ae..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-28-18-34-49.gh-issue-119726.Fjv_Ab.rst +++ /dev/null @@ -1,2 +0,0 @@ -Optimize code layout for calls to C functions from the JIT on AArch64. -Patch by Diego Russo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-28-23-17-22.gh-issue-121381.i2xL7P.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-28-23-17-22.gh-issue-121381.i2xL7P.rst deleted file mode 100644 index 3a02145378e2cd..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-28-23-17-22.gh-issue-121381.i2xL7P.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove ``subprocess._USE_VFORK`` escape hatch code and documentation. -It was added just in case, and doesn't have any known cases that require it. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-29-10-46-14.gh-issue-121130.Rj66Xs.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-29-10-46-14.gh-issue-121130.Rj66Xs.rst deleted file mode 100644 index 7084f0cbebbb73..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-29-10-46-14.gh-issue-121130.Rj66Xs.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix f-strings with debug expressions in format specifiers. Patch by Pablo -Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-30-03-48-10.gh-issue-121149.lLBMKe.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-30-03-48-10.gh-issue-121149.lLBMKe.rst deleted file mode 100644 index 38d618f06090fd..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-06-30-03-48-10.gh-issue-121149.lLBMKe.rst +++ /dev/null @@ -1,2 +0,0 @@ -Added specialization for summation of complexes, this also improves accuracy -of builtin :func:`sum` for such inputs. Patch by Sergey B Kirpichev. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-07-04-23-38-30.gh-issue-121368.m3EF9E.rst b/Misc/NEWS.d/next/Core and Builtins/2024-07-04-23-38-30.gh-issue-121368.m3EF9E.rst deleted file mode 100644 index 3df5b216cbc0af..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-07-04-23-38-30.gh-issue-121368.m3EF9E.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix race condition in ``_PyType_Lookup`` in the free-threaded build due to -a missing memory fence. This could lead to ``_PyType_Lookup`` returning -incorrect results on arm64. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-07-05-11-29-27.gh-issue-121288.lYKYYP.rst b/Misc/NEWS.d/next/Core and Builtins/2024-07-05-11-29-27.gh-issue-121288.lYKYYP.rst deleted file mode 100644 index ffe8f373c905e1..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-07-05-11-29-27.gh-issue-121288.lYKYYP.rst +++ /dev/null @@ -1,5 +0,0 @@ -:exc:`ValueError` messages for :meth:`!list.index`, :meth:`!range.index`, -:meth:`!deque.index`, :meth:`!deque.remove` and -:meth:`!ShareableList.index` no longer contain the repr of the searched -value (which can be arbitrary large) and are consistent with error messages -for other :meth:`!index` and :meth:`!remove` methods. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-07-08-02-24-55.gh-issue-121439.jDHod3.rst b/Misc/NEWS.d/next/Core and Builtins/2024-07-08-02-24-55.gh-issue-121439.jDHod3.rst deleted file mode 100644 index 361f9fc71186c6..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-07-08-02-24-55.gh-issue-121439.jDHod3.rst +++ /dev/null @@ -1 +0,0 @@ -Allow tuples of length 20 in the freelist to be reused. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-07-08-10-31-08.gh-issue-121012.M5hHk-.rst b/Misc/NEWS.d/next/Core and Builtins/2024-07-08-10-31-08.gh-issue-121012.M5hHk-.rst deleted file mode 100644 index 7b04eb68b03752..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-07-08-10-31-08.gh-issue-121012.M5hHk-.rst +++ /dev/null @@ -1,2 +0,0 @@ -Tier 2 execution now ensures that list iterators remain exhausted, once they -become exhausted. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-07-08-17-15-14.gh-issue-121497.I8hMDC.rst b/Misc/NEWS.d/next/Core and Builtins/2024-07-08-17-15-14.gh-issue-121497.I8hMDC.rst deleted file mode 100644 index 33de31abebe7c7..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-07-08-17-15-14.gh-issue-121497.I8hMDC.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a bug that was preventing the REPL to correctly respect the history when -an input hook was set. Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-07-09-13-53-18.gh-issue-121499.rpp7il.rst b/Misc/NEWS.d/next/Core and Builtins/2024-07-09-13-53-18.gh-issue-121499.rpp7il.rst deleted file mode 100644 index aec8ab9d4662b5..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-07-09-13-53-18.gh-issue-121499.rpp7il.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a bug affecting how multi-line history was being rendered in the new -REPL after interacting with the new screen cache. Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-07-10-02-02-32.gh-issue-121562.8beIMi.rst b/Misc/NEWS.d/next/Core and Builtins/2024-07-10-02-02-32.gh-issue-121562.8beIMi.rst deleted file mode 100644 index 940380971f407f..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-07-10-02-02-32.gh-issue-121562.8beIMi.rst +++ /dev/null @@ -1,2 +0,0 @@ -Optimized performance of hex_from_char by replacing switch-case with a -lookup table diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-07-10-15-43-54.gh-issue-117482.5WYaXR.rst b/Misc/NEWS.d/next/Core and Builtins/2024-07-10-15-43-54.gh-issue-117482.5WYaXR.rst deleted file mode 100644 index ec1e7327b77f19..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-07-10-15-43-54.gh-issue-117482.5WYaXR.rst +++ /dev/null @@ -1,2 +0,0 @@ -Unexpected slot wrappers are no longer created for builtin static types in -subinterpreters. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-07-12-18-18-44.gh-issue-121297.67VE7b.rst b/Misc/NEWS.d/next/Core and Builtins/2024-07-12-18-18-44.gh-issue-121297.67VE7b.rst deleted file mode 100644 index 25aae6c8c5cb10..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-07-12-18-18-44.gh-issue-121297.67VE7b.rst +++ /dev/null @@ -1,4 +0,0 @@ -Previously, incorrect usage of :keyword:`await` or asynchronous -comprehensions in code removed by the :option:`-O` option was not flagged by -the Python compiler. Now, such code raises :exc:`SyntaxError`. Patch by -Jelle Zijlstra. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-07-13-12-27-31.gh-issue-121657.wgOYLw.rst b/Misc/NEWS.d/next/Core and Builtins/2024-07-13-12-27-31.gh-issue-121657.wgOYLw.rst deleted file mode 100644 index cb18629d79f5ce..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-07-13-12-27-31.gh-issue-121657.wgOYLw.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve the :exc:`SyntaxError` message if the user tries to use -:keyword:`yield from ` outside a function. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-07-15-16-26-32.gh-issue-121794.fhBtiQ.rst b/Misc/NEWS.d/next/Core and Builtins/2024-07-15-16-26-32.gh-issue-121794.fhBtiQ.rst deleted file mode 100644 index 979efa0a0a1597..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-07-15-16-26-32.gh-issue-121794.fhBtiQ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix bug in free-threaded Python where a resurrected object could lead to -a negative ref count assertion failure. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-07-15-20-41-06.gh-issue-121814.oR2ixR.rst b/Misc/NEWS.d/next/Core and Builtins/2024-07-15-20-41-06.gh-issue-121814.oR2ixR.rst deleted file mode 100644 index 14666de45f32e3..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-07-15-20-41-06.gh-issue-121814.oR2ixR.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed the SegFault when :c:func:`PyEval_SetTrace` is used with no Python frame on stack. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-07-16-15-11-51.gh-issue-121795.xkIHrI.rst b/Misc/NEWS.d/next/Core and Builtins/2024-07-16-15-11-51.gh-issue-121795.xkIHrI.rst deleted file mode 100644 index b4102649c56758..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-07-16-15-11-51.gh-issue-121795.xkIHrI.rst +++ /dev/null @@ -1 +0,0 @@ -Improve performance of set membership testing, ``set.remove()`` and ``set.discard()`` when the argument is a set. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-07-16-18-23-22.gh-issue-121860.-FTauD.rst b/Misc/NEWS.d/next/Core and Builtins/2024-07-16-18-23-22.gh-issue-121860.-FTauD.rst deleted file mode 100644 index a03ee83d6f8ec9..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-07-16-18-23-22.gh-issue-121860.-FTauD.rst +++ /dev/null @@ -1 +0,0 @@ -Fix crash when rematerializing a managed dictionary after it was deleted. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-07-19-09-38-01.gh-issue-99108.qzM6gl.rst b/Misc/NEWS.d/next/Core and Builtins/2024-07-19-09-38-01.gh-issue-99108.qzM6gl.rst deleted file mode 100644 index 125f04a36a18c9..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-07-19-09-38-01.gh-issue-99108.qzM6gl.rst +++ /dev/null @@ -1,10 +0,0 @@ -Python's hashlib now unconditionally uses the vendored HACL* library for -Blake2. Python no longer accepts libb2 as an optional dependency for Blake2. - -We refreshed HACL* to the latest version, and now vendor HACL*'s 128-bit and -256-bit wide vector implementations for Blake2, which are used on x86/x64 -toolchains when the required CPU features are available at runtime. - -HACL*'s 128-bit wide vector implementation of Blake2 can also run on ARM -NEON and Power8, but lacking evidence of a performance gain, these are not -enabled (yet). diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-07-19-15-28-05.gh-issue-122026.sta2Ca.rst b/Misc/NEWS.d/next/Core and Builtins/2024-07-19-15-28-05.gh-issue-122026.sta2Ca.rst deleted file mode 100644 index 2721a405a50446..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-07-19-15-28-05.gh-issue-122026.sta2Ca.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a bug that caused the tokenizer to not correctly identify mismatched -parentheses inside f-strings in some situations. Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-07-21-01-23-54.gh-issue-122029.gKv-e2.rst b/Misc/NEWS.d/next/Core and Builtins/2024-07-21-01-23-54.gh-issue-122029.gKv-e2.rst deleted file mode 100644 index bddee3a57fba80..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-07-21-01-23-54.gh-issue-122029.gKv-e2.rst +++ /dev/null @@ -1 +0,0 @@ -Emit ``c_call`` events in :func:`sys.setprofile` when a ``PyMethodObject`` pointing to a ``PyCFunction`` is called. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-07-23-11-57-36.gh-issue-122160.HSnrAP.rst b/Misc/NEWS.d/next/Core and Builtins/2024-07-23-11-57-36.gh-issue-122160.HSnrAP.rst deleted file mode 100644 index 78153fc1abdaeb..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-07-23-11-57-36.gh-issue-122160.HSnrAP.rst +++ /dev/null @@ -1 +0,0 @@ -Remove the ``BUILD_CONST_KEY_MAP`` opcode. Use :opcode:`BUILD_MAP` instead. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-07-23-23-59-04.gh-issue-122208.z8KHsY.rst b/Misc/NEWS.d/next/Core and Builtins/2024-07-23-23-59-04.gh-issue-122208.z8KHsY.rst deleted file mode 100644 index e4a89d137ede0e..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-07-23-23-59-04.gh-issue-122208.z8KHsY.rst +++ /dev/null @@ -1 +0,0 @@ -Dictionary watchers now only deliver the PyDict_EVENT_ADDED event when the insertion is in a known good state to succeed. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-07-24-17-11-51.gh-issue-122234.VxsP_F.rst b/Misc/NEWS.d/next/Core and Builtins/2024-07-24-17-11-51.gh-issue-122234.VxsP_F.rst deleted file mode 100644 index 5a9a82ddef6ee4..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-07-24-17-11-51.gh-issue-122234.VxsP_F.rst +++ /dev/null @@ -1,4 +0,0 @@ -Specializations for sums with float and complex inputs in :func:`sum` now -always use compensated summation. Also, for integer items in above -specializations: :c:func:`PyLong_AsDouble` is used, instead of -:c:func:`PyLong_AsLongAndOverflow`. Patch by Sergey B Kirpichev. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-07-24-22-39-07.gh-issue-122245.LVa9v8.rst b/Misc/NEWS.d/next/Core and Builtins/2024-07-24-22-39-07.gh-issue-122245.LVa9v8.rst deleted file mode 100644 index fff99b4992e321..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-07-24-22-39-07.gh-issue-122245.LVa9v8.rst +++ /dev/null @@ -1,4 +0,0 @@ -Detection of writes to ``__debug__`` is moved from the compiler's codegen -stage to the symtable. This means that these errors are now detected even in -code that is optimized away before codegen (such as assertions with the -:option:`-O` command line option). diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-07-26-14-05-51.gh-issue-122300.SVIF-l.rst b/Misc/NEWS.d/next/Core and Builtins/2024-07-26-14-05-51.gh-issue-122300.SVIF-l.rst deleted file mode 100644 index 6b58f89247d1d4..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-07-26-14-05-51.gh-issue-122300.SVIF-l.rst +++ /dev/null @@ -1,2 +0,0 @@ -Preserve AST nodes for f-string with single-element format specifiers. Patch -by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-07-30-11-41-35.gh-issue-122445.Rq0bjS.rst b/Misc/NEWS.d/next/Core and Builtins/2024-07-30-11-41-35.gh-issue-122445.Rq0bjS.rst deleted file mode 100644 index cb9dabbc71706f..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-07-30-11-41-35.gh-issue-122445.Rq0bjS.rst +++ /dev/null @@ -1 +0,0 @@ -Add only fields which are modified via self.* to :attr:`~type.__static_attributes__`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-08-05-19-04-06.gh-issue-116622.3LWUzE.rst b/Misc/NEWS.d/next/Core and Builtins/2024-08-05-19-04-06.gh-issue-116622.3LWUzE.rst deleted file mode 100644 index 9320928477af2c..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-08-05-19-04-06.gh-issue-116622.3LWUzE.rst +++ /dev/null @@ -1 +0,0 @@ -Fix Android stdout and stderr messages being truncated or lost. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-08-18-18-25-54.gh-issue-123123.0ZcaEB.rst b/Misc/NEWS.d/next/Core and Builtins/2024-08-18-18-25-54.gh-issue-123123.0ZcaEB.rst deleted file mode 100644 index 824d307bb270a2..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-08-18-18-25-54.gh-issue-123123.0ZcaEB.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix displaying :exc:`SyntaxError` exceptions covering multiple lines. Patch -by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-08-20-11-09-16.gh-issue-123048.2TISpv.rst b/Misc/NEWS.d/next/Core and Builtins/2024-08-20-11-09-16.gh-issue-123048.2TISpv.rst deleted file mode 100644 index f0b756febbc1b8..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-08-20-11-09-16.gh-issue-123048.2TISpv.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a bug where pattern matching code could emit a :opcode:`JUMP_FORWARD` -with no source location. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-08-20-12-29-52.gh-issue-123142.3PXiNb.rst b/Misc/NEWS.d/next/Core and Builtins/2024-08-20-12-29-52.gh-issue-123142.3PXiNb.rst deleted file mode 100644 index 0aa70f23bfde87..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-08-20-12-29-52.gh-issue-123142.3PXiNb.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix too-wide source location in exception tracebacks coming from broken -iterables in comprehensions. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-08-21-15-22-53.gh-issue-121804.r5K3PS.rst b/Misc/NEWS.d/next/Core and Builtins/2024-08-21-15-22-53.gh-issue-121804.r5K3PS.rst deleted file mode 100644 index ce96c316923ce5..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-08-21-15-22-53.gh-issue-121804.r5K3PS.rst +++ /dev/null @@ -1,2 +0,0 @@ -Correctly show error locations when a :exc:`SyntaxError` is raised -in the basic REPL. Patch by Sergey B Kirpichev. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-08-23-13-08-27.gh-issue-123229.aHm-dw.rst b/Misc/NEWS.d/next/Core and Builtins/2024-08-23-13-08-27.gh-issue-123229.aHm-dw.rst deleted file mode 100644 index aa9e8d1fa93bf5..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-08-23-13-08-27.gh-issue-123229.aHm-dw.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix valgrind warning by initializing the f-string buffers to 0 in the -tokenizer. Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-08-23-15-59-54.gh-issue-123177.OLcaC5.rst b/Misc/NEWS.d/next/Core and Builtins/2024-08-23-15-59-54.gh-issue-123177.OLcaC5.rst deleted file mode 100644 index da688effca3712..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-08-23-15-59-54.gh-issue-123177.OLcaC5.rst +++ /dev/null @@ -1,2 +0,0 @@ -Deactivate line wrap in the Apple Terminal via a ANSI escape code. Patch by -Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-08-25-10-54-22.gh-issue-122982.KLD91q.rst b/Misc/NEWS.d/next/Core and Builtins/2024-08-25-10-54-22.gh-issue-122982.KLD91q.rst deleted file mode 100644 index 64882df6af10d2..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-08-25-10-54-22.gh-issue-122982.KLD91q.rst +++ /dev/null @@ -1 +0,0 @@ -Extend the deprecation period for bool inversion (``~``) by two years. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-08-26-00-58-26.gh-issue-123321.ApxcnE.rst b/Misc/NEWS.d/next/Core and Builtins/2024-08-26-00-58-26.gh-issue-123321.ApxcnE.rst deleted file mode 100644 index b0547e0e588e3d..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-08-26-00-58-26.gh-issue-123321.ApxcnE.rst +++ /dev/null @@ -1,2 +0,0 @@ -Prevent Parser/myreadline race condition from segfaulting on multi-threaded -use. Patch by Bar Harel and Amit Wienner. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-08-27-13-16-40.gh-issue-123344.56Or78.rst b/Misc/NEWS.d/next/Core and Builtins/2024-08-27-13-16-40.gh-issue-123344.56Or78.rst deleted file mode 100644 index b8b373d48b6522..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-08-27-13-16-40.gh-issue-123344.56Or78.rst +++ /dev/null @@ -1 +0,0 @@ -Add AST optimizations for type parameter defaults. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-09-23-23-06-19.gh-issue-124285.mahGTg.rst b/Misc/NEWS.d/next/Core and Builtins/2024-09-23-23-06-19.gh-issue-124285.mahGTg.rst deleted file mode 100644 index a6dec66a743f92..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-09-23-23-06-19.gh-issue-124285.mahGTg.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix bug where ``bool(a)`` can be invoked more than once during the -evaluation of a compound boolean expression. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-10-03-22-26-39.gh-issue-124871.tAMF47.rst b/Misc/NEWS.d/next/Core and Builtins/2024-10-03-22-26-39.gh-issue-124871.tAMF47.rst deleted file mode 100644 index 185cb3048fadf5..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-10-03-22-26-39.gh-issue-124871.tAMF47.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix compiler bug (in some versions of 3.13) where an assertion fails during reachability -analysis. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-07-13-09-51-44.gh-issue-121609.jWsE5t.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-07-13-09-51-44.gh-issue-121609.jWsE5t.rst deleted file mode 100644 index 72b5c071a5c67b..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-07-13-09-51-44.gh-issue-121609.jWsE5t.rst +++ /dev/null @@ -1 +0,0 @@ -Fix pasting of characters containing unicode character joiners in the new REPL. Patch by Marta Gomez Macias diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-07-15-20-03-29.gh-issue-121295.w53ucI.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-07-15-20-03-29.gh-issue-121295.w53ucI.rst deleted file mode 100644 index 7fca7d5461d39b..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-07-15-20-03-29.gh-issue-121295.w53ucI.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix PyREPL console getting into a blocked state after interrupting a long -paste diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-07-18-21-19-04.gh-issue-121999.8IBbTK.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-07-18-21-19-04.gh-issue-121999.8IBbTK.rst deleted file mode 100644 index e65aa993566446..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-07-18-21-19-04.gh-issue-121999.8IBbTK.rst +++ /dev/null @@ -1,2 +0,0 @@ -The default extraction filter for the :mod:`tarfile` module is now -set to :func:`'data' `. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-07-25-01-45-21.gh-issue-122239.7zh-sW.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-07-25-01-45-21.gh-issue-122239.7zh-sW.rst deleted file mode 100644 index 3e8116ba7d28f1..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-07-25-01-45-21.gh-issue-122239.7zh-sW.rst +++ /dev/null @@ -1,3 +0,0 @@ -When a :class:`list`, :class:`tuple` or :class:`dict` -with too many elements is unpacked, show the actual -length in the error message. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-07-26-13-56-32.gh-issue-120906.qBh2I9.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-07-26-13-56-32.gh-issue-120906.qBh2I9.rst deleted file mode 100644 index 2b753bc37d4a39..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-07-26-13-56-32.gh-issue-120906.qBh2I9.rst +++ /dev/null @@ -1 +0,0 @@ -:attr:`frame.f_locals` now supports arbitrary hashable objects as keys. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-07-29-10-55-46.gh-issue-116090.p1MhU0.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-07-29-10-55-46.gh-issue-116090.p1MhU0.rst deleted file mode 100644 index 6efb620961f498..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-07-29-10-55-46.gh-issue-116090.p1MhU0.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix an issue in JIT builds that prevented some :keyword:`for` loops from -correctly firing :monitoring-event:`RAISE` monitoring events. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-07-29-19-20-25.gh-issue-122417.NVgs0a.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-07-29-19-20-25.gh-issue-122417.NVgs0a.rst deleted file mode 100644 index b050c9ce39c054..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-07-29-19-20-25.gh-issue-122417.NVgs0a.rst +++ /dev/null @@ -1,4 +0,0 @@ -In the free-threaded build, the reference counts for heap type objects are now -partially stored in a distributed manner in per-thread arrays. This reduces -contention on the heap type's reference count fields when creating or -destroying instances of the same type from multiple threads concurrently. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-01-19-13-58.gh-issue-122527.eztso6.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-08-01-19-13-58.gh-issue-122527.eztso6.rst deleted file mode 100644 index f697ed99d0c523..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-01-19-13-58.gh-issue-122527.eztso6.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fix a crash that occurred when a ``PyStructSequence`` was deallocated after -its type's dictionary was cleared by the GC. The type's -:c:member:`~PyTypeObject.tp_basicsize` now accounts for non-sequence fields -that aren't included in the :c:macro:`Py_SIZE` of the sequence. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-05-19-28-12.gh-issue-122697.17MvYl.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-08-05-19-28-12.gh-issue-122697.17MvYl.rst deleted file mode 100644 index 34ee6a916bcf33..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-05-19-28-12.gh-issue-122697.17MvYl.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed memory leaks at interpreter shutdown in the free-threaded build, and -also reporting of leaked memory blocks via :option:`-X showrefcount <-X>`. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-08-16-02-28.gh-issue-118093.m6Mrvy.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-08-08-16-02-28.gh-issue-118093.m6Mrvy.rst deleted file mode 100644 index dacc7275d3d6dd..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-08-16-02-28.gh-issue-118093.m6Mrvy.rst +++ /dev/null @@ -1 +0,0 @@ -Improve the experimental JIT's handling of polymorphic code. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-10-12-44-03.gh-issue-122888.TUyu9r.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-08-10-12-44-03.gh-issue-122888.TUyu9r.rst deleted file mode 100644 index 93171360df0dda..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-10-12-44-03.gh-issue-122888.TUyu9r.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix crash on certain calls to ``str()`` with positional arguments of the -wrong type. Patch by Jelle Zijlstra. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-12-11-19-37.gh-issue-122907.q68096.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-08-12-11-19-37.gh-issue-122907.q68096.rst deleted file mode 100644 index 88c872f4ef45f4..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-12-11-19-37.gh-issue-122907.q68096.rst +++ /dev/null @@ -1,3 +0,0 @@ -Building with ``HAVE_DYNAMIC_LOADING`` now works as well as it did in 3.12. -Existing deficiences will be addressed separately. -(See https://github.com/python/cpython/issues/122950.) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-12-11-45-47.gh-issue-122821.WnAzTK.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-08-12-11-45-47.gh-issue-122821.WnAzTK.rst deleted file mode 100644 index 4cf31054bd0ccd..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-12-11-45-47.gh-issue-122821.WnAzTK.rst +++ /dev/null @@ -1,3 +0,0 @@ -Make sure that branches in :keyword:`while` statements have consistent offsets for -:mod:`sys.monitoring`. :keyword:`!while` statements are now compiled with a simple -jump at the end of the body, instead of duplicating the test. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-14-11-38-56.gh-issue-118093.3BywDP.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-08-14-11-38-56.gh-issue-118093.3BywDP.rst deleted file mode 100644 index 4a3a094a6fc074..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-14-11-38-56.gh-issue-118093.3BywDP.rst +++ /dev/null @@ -1,5 +0,0 @@ -Add three specializations for :opcode:`CALL_KW`: - -* :opcode:`!CALL_KW_PY` for calls to Python functions -* :opcode:`!CALL_KW_BOUND_METHOD` for calls to bound methods -* :opcode:`!CALL_KW_NON_PY` for all other calls diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-15-19-28-43.gh-issue-123022.m3EF9E.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-08-15-19-28-43.gh-issue-123022.m3EF9E.rst deleted file mode 100644 index 47107dee44eec3..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-15-19-28-43.gh-issue-123022.m3EF9E.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix crash in free-threaded build when calling :c:func:`Py_Initialize` from -a non-main thread. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-17-17-26-25.gh-issue-123083.9xWLJ-.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-08-17-17-26-25.gh-issue-123083.9xWLJ-.rst deleted file mode 100644 index edc3f1ab6a8e17..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-17-17-26-25.gh-issue-123083.9xWLJ-.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a potential use-after-free in ``STORE_ATTR_WITH_HINT``. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-19-15-13-13.gh-issue-118093.dLZ8qS.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-08-19-15-13-13.gh-issue-118093.dLZ8qS.rst deleted file mode 100644 index d8127d8b5054fe..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-19-15-13-13.gh-issue-118093.dLZ8qS.rst +++ /dev/null @@ -1,3 +0,0 @@ -Break up ``CALL_ALLOC_AND_ENTER_INIT`` into micro-ops and relax -requirement for exact args, in order to increase the amount of code -supported by tier 2. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-21-08-53-00.gh-issue-115776.9A7Dv_.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-08-21-08-53-00.gh-issue-115776.9A7Dv_.rst deleted file mode 100644 index 953ebd72382e1f..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-21-08-53-00.gh-issue-115776.9A7Dv_.rst +++ /dev/null @@ -1,2 +0,0 @@ -Enables inline values (Python's equivalent of hidden classes) on any class -who's instances are of a fixed size. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-23-11-26-54.gh-issue-122298.ZMyln4.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-08-23-11-26-54.gh-issue-122298.ZMyln4.rst deleted file mode 100644 index 722f69616b6b1b..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-23-11-26-54.gh-issue-122298.ZMyln4.rst +++ /dev/null @@ -1,3 +0,0 @@ -Restore printout of GC stats when ``gc.set_debug(gc.DEBUG_STATS)`` is -called. This feature was accidentally removed when implementing incremental -GC. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-23-18-31-10.gh-issue-123275.DprIrj.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-08-23-18-31-10.gh-issue-123275.DprIrj.rst deleted file mode 100644 index ab344a8ca40e47..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-23-18-31-10.gh-issue-123275.DprIrj.rst +++ /dev/null @@ -1 +0,0 @@ -Support :option:`-X gil=1 <-X>` and :envvar:`PYTHON_GIL=1 ` on non-free-threaded builds. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-23-21-20-34.gh-issue-123271.xeVViR.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-08-23-21-20-34.gh-issue-123271.xeVViR.rst deleted file mode 100644 index 51fdec452c1d41..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-23-21-20-34.gh-issue-123271.xeVViR.rst +++ /dev/null @@ -1 +0,0 @@ -Make concurrent iterations over the same :func:`zip` iterator safe under free-threading. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-25-18-27-49.gh-issue-123177.yLuyqE.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-08-25-18-27-49.gh-issue-123177.yLuyqE.rst deleted file mode 100644 index 1f1791d9a6cf50..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-25-18-27-49.gh-issue-123177.yLuyqE.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a bug causing stray prompts to appear in the middle of wrapped lines in -the new REPL. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-27-21-44-14.gh-issue-116017.ZY3yBY.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-08-27-21-44-14.gh-issue-116017.ZY3yBY.rst deleted file mode 100644 index de62875e16475d..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-27-21-44-14.gh-issue-116017.ZY3yBY.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improved JIT memory consumption by periodically freeing memory used by infrequently-executed code. -This change is especially likely to improve the memory footprint of long-running programs. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-28-22-42-51.gh-issue-123440.yOFB0N.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-08-28-22-42-51.gh-issue-123440.yOFB0N.rst deleted file mode 100644 index 0f2e49c10b0c64..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-28-22-42-51.gh-issue-123440.yOFB0N.rst +++ /dev/null @@ -1 +0,0 @@ -Improve :exc:`SyntaxError` message for using ``except as`` with not a name. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-29-13-18-18.gh-issue-123446.KWDrgq.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-08-29-13-18-18.gh-issue-123446.KWDrgq.rst deleted file mode 100644 index 704bde9d01cac9..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-29-13-18-18.gh-issue-123446.KWDrgq.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix empty function name in :exc:`TypeError` when builtin magic methods are -used without the required args. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-29-19-46-07.gh-issue-123484.rjUn_F.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-08-29-19-46-07.gh-issue-123484.rjUn_F.rst deleted file mode 100644 index 3062e3684c8e78..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-29-19-46-07.gh-issue-123484.rjUn_F.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix ``_Py_DebugOffsets`` for long objects to be relative to the start of the -object rather than the start of a subobject. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-01-00-02-05.gh-issue-123545.8nQNbL.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-01-00-02-05.gh-issue-123545.8nQNbL.rst deleted file mode 100644 index 4da4151416d13c..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-01-00-02-05.gh-issue-123545.8nQNbL.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a double decref in rare cases on experimental JIT builds. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-01-12-08-39.gh-issue-123562.aJPKVu.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-01-12-08-39.gh-issue-123562.aJPKVu.rst deleted file mode 100644 index 10ef82c9677d35..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-01-12-08-39.gh-issue-123562.aJPKVu.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve :exc:`SyntaxError` message for using ``case ... as ...`` with not a -name. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-02-17-32-15.gh-issue-119034.HYh5Vj.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-02-17-32-15.gh-issue-119034.HYh5Vj.rst deleted file mode 100644 index f528691e1b6f9f..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-02-17-32-15.gh-issue-119034.HYh5Vj.rst +++ /dev/null @@ -1,2 +0,0 @@ -Change ```` and ```` keys of the Python REPL to history -search forward/backward. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-02-20-36-45.gh-issue-123339.QcmpSs.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-02-20-36-45.gh-issue-123339.QcmpSs.rst deleted file mode 100644 index 25b47d5fbaefa5..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-02-20-36-45.gh-issue-123339.QcmpSs.rst +++ /dev/null @@ -1,3 +0,0 @@ -Setting the :attr:`!__module__` attribute for a class now removes the -``__firstlineno__`` item from the type's dict, so they will no longer be -inconsistent. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-02-20-39-10.gh-issue-123614.26TMHp.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-02-20-39-10.gh-issue-123614.26TMHp.rst deleted file mode 100644 index 64a5eac9f7840a..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-02-20-39-10.gh-issue-123614.26TMHp.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add :func:`turtle.save` to easily save Turtle drawings as PostScript files. -Patch by Marie Roald and Yngve Mardal Moe. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-03-13-34-35.gh-issue-123572.uuqoYV.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-03-13-34-35.gh-issue-123572.uuqoYV.rst deleted file mode 100644 index 38456ac60ca4ed..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-03-13-34-35.gh-issue-123572.uuqoYV.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix key mappings for various F-keys in Windows for the new REPL. Patch by -devdanzin diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-06-14-13-01.gh-issue-119310.WQxyDF.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-06-14-13-01.gh-issue-119310.WQxyDF.rst deleted file mode 100644 index e7bc24b537d46a..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-06-14-13-01.gh-issue-119310.WQxyDF.rst +++ /dev/null @@ -1,3 +0,0 @@ -Allow the new interactive shell to read history files written with the -editline library that use unicode-escaped entries. Patch by aorcajo and -Łukasz Langa. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-06-19-23-44.gh-issue-120221.giJEDT.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-06-19-23-44.gh-issue-120221.giJEDT.rst deleted file mode 100644 index c562b87b02a852..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-06-19-23-44.gh-issue-120221.giJEDT.rst +++ /dev/null @@ -1,2 +0,0 @@ -asyncio REPL is now again properly recognizing KeyboardInterrupts. Display -of exceptions raised in secondary threads is fixed. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-10-13-27-16.gh-issue-77894.ZC-Olu.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-10-13-27-16.gh-issue-77894.ZC-Olu.rst deleted file mode 100644 index a714033dd296b9..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-10-13-27-16.gh-issue-77894.ZC-Olu.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fix possible crash in the garbage collector when it tries to break a -reference loop containing a :class:`memoryview` object. Now a -:class:`!memoryview` object can only be cleared if there are no buffers that -refer it. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-10-20-25-00.gh-issue-123923.A7uxqa.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-10-20-25-00.gh-issue-123923.A7uxqa.rst deleted file mode 100644 index b7bc965b68b059..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-10-20-25-00.gh-issue-123923.A7uxqa.rst +++ /dev/null @@ -1,4 +0,0 @@ -The ``f_executable`` field in the internal :c:struct:`_PyInterpreterFrame` -struct now uses a tagged pointer. Profilers and debuggers that uses this -field should clear the least significant bit to recover the -:c:expr:`PyObject*` pointer. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-11-15-48-36.gh-issue-123958.5VW2r0.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-11-15-48-36.gh-issue-123958.5VW2r0.rst deleted file mode 100644 index fc2623a7cbf789..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-11-15-48-36.gh-issue-123958.5VW2r0.rst +++ /dev/null @@ -1 +0,0 @@ -docstrings are now removed from the optimized AST in optimization level 2. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-12-21-53-26.gh-issue-124022.fQzUiW.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-12-21-53-26.gh-issue-124022.fQzUiW.rst deleted file mode 100644 index 90a77a5346d22b..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-12-21-53-26.gh-issue-124022.fQzUiW.rst +++ /dev/null @@ -1 +0,0 @@ -Fix bug where docstring is removed from classes in interactive mode. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-13-02-25-06.gh-issue-124027.to_9DY.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-13-02-25-06.gh-issue-124027.to_9DY.rst deleted file mode 100644 index 1834ba0ba08bfb..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-13-02-25-06.gh-issue-124027.to_9DY.rst +++ /dev/null @@ -1,2 +0,0 @@ -Support ````, ````, and ```` keys in the Python -REPL when ``$TERM`` is set to ``vt100``. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-17-22-06-01.gh-issue-124188.aFqNAB.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-17-22-06-01.gh-issue-124188.aFqNAB.rst deleted file mode 100644 index 0c2935fbe000bc..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-17-22-06-01.gh-issue-124188.aFqNAB.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix reading and decoding a line from the source file witn non-UTF-8 encoding -for syntax errors raised in the compiler. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-19-13-17-31.gh-issue-122878.4iFpsB.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-19-13-17-31.gh-issue-122878.4iFpsB.rst deleted file mode 100644 index 85dd0fd769be68..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-19-13-17-31.gh-issue-122878.4iFpsB.rst +++ /dev/null @@ -1 +0,0 @@ -Use the ``pager`` binary, if available (e.g. on Debian and derivatives), to display REPL ``help()``. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-19-16-57-34.gh-issue-119726.DseseK.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-19-16-57-34.gh-issue-119726.DseseK.rst deleted file mode 100644 index c01eeff952534f..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-19-16-57-34.gh-issue-119726.DseseK.rst +++ /dev/null @@ -1,2 +0,0 @@ -The JIT now generates more efficient code for calls to C functions resulting -in up to 0.8% memory savings and 1.5% speed improvement on AArch64. Patch by Diego Russo. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-23-13-25-27.gh-issue-65961.LDqXV2.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-23-13-25-27.gh-issue-65961.LDqXV2.rst deleted file mode 100644 index d380027f3c5776..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-23-13-25-27.gh-issue-65961.LDqXV2.rst +++ /dev/null @@ -1 +0,0 @@ -Deprecate the setting and using ``__package__`` and ``__cached__``. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-23-15-23-14.gh-issue-123856.yrgJ9m.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-23-15-23-14.gh-issue-123856.yrgJ9m.rst deleted file mode 100644 index b5f423f3ff1c96..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-23-15-23-14.gh-issue-123856.yrgJ9m.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix PyREPL failure when a keyboard interrupt is triggered after using a -history search diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-25-11-53-22.gh-issue-124442.EXC1Ve.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-25-11-53-22.gh-issue-124442.EXC1Ve.rst deleted file mode 100644 index 58e79f22ac0f90..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-25-11-53-22.gh-issue-124442.EXC1Ve.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix nondeterminism in compilation by sorting the value of -:attr:`~type.__static_attributes__`. Patch by kp2pml30. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-25-14-45-56.gh-issue-124513.ywiXtr.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-25-14-45-56.gh-issue-124513.ywiXtr.rst deleted file mode 100644 index 691e03b3b98e7a..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-25-14-45-56.gh-issue-124513.ywiXtr.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a crash in FrameLocalsProxy constructor: check the number of arguments. -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-26-12-19-13.gh-issue-124547.P_SHfU.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-26-12-19-13.gh-issue-124547.P_SHfU.rst deleted file mode 100644 index 1005c651849f45..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-26-12-19-13.gh-issue-124547.P_SHfU.rst +++ /dev/null @@ -1,3 +0,0 @@ -When deallocating an object with inline values whose ``__dict__`` is still -live: if memory allocation for the inline values fails, clear the -dictionary. Prevents an interpreter crash. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-26-13-25-01.gh-issue-119180.k_JCX0.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-26-13-25-01.gh-issue-119180.k_JCX0.rst deleted file mode 100644 index 4cdbb205c962c4..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-26-13-25-01.gh-issue-119180.k_JCX0.rst +++ /dev/null @@ -1,2 +0,0 @@ -The ``__main__`` module no longer always contains an ``__annotations__`` -dictionary in its global namespace. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-26-17-55-34.gh-issue-116510.dhn8w8.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-26-17-55-34.gh-issue-116510.dhn8w8.rst deleted file mode 100644 index fc3f8af72d87bf..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-26-17-55-34.gh-issue-116510.dhn8w8.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix a bug that can cause a crash when sub-interpreters use "basic" -single-phase extension modules. Shared objects could refer to PyGC_Head -nodes that had been freed as part of interpreter cleanup. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-26-18-21-06.gh-issue-116510.FacUWO.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-26-18-21-06.gh-issue-116510.FacUWO.rst deleted file mode 100644 index e3741321006548..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-26-18-21-06.gh-issue-116510.FacUWO.rst +++ /dev/null @@ -1,5 +0,0 @@ -Fix a crash caused by immortal interned strings being shared between -sub-interpreters that use basic single-phase init. In that case, the string -can be used by an interpreter that outlives the interpreter that created and -interned it. For interpreters that share obmalloc state, also share the -interned dict with the main interpreter. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-27-17-18-53.gh-issue-124642.OCjhBJ.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-27-17-18-53.gh-issue-124642.OCjhBJ.rst deleted file mode 100644 index 29763844a9f592..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-27-17-18-53.gh-issue-124642.OCjhBJ.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed scalability issue in free-threaded builds for lock-free reads from dictionaries in multi-threaded scenarios diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-30-16-39-37.gh-issue-118093.J2A3gz.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-30-16-39-37.gh-issue-118093.J2A3gz.rst deleted file mode 100644 index 2e5c64581b6aef..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-30-16-39-37.gh-issue-118093.J2A3gz.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve the experimental JIT compiler's ability to stay "on trace" when -encountering highly-biased branches. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-10-03-14-39-41.gh-issue-123378.dCxANf.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-03-14-39-41.gh-issue-123378.dCxANf.rst deleted file mode 100644 index 5cd34535d674d3..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-10-03-14-39-41.gh-issue-123378.dCxANf.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix a crash in the :meth:`~object.__str__` method of :exc:`UnicodeError` -objects when the :attr:`UnicodeError.start` and :attr:`UnicodeError.end` -values are invalid or out-of-range. Patch by Bénédikt Tran. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-10-05-23-53-06.gh-issue-125008.ETANpd.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-05-23-53-06.gh-issue-125008.ETANpd.rst deleted file mode 100644 index 8971e052860225..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-10-05-23-53-06.gh-issue-125008.ETANpd.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix :func:`tokenize.untokenize` producing invalid syntax for -double braces preceded by certain escape characters. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-10-07-23-33-18.gh-issue-125039.MKTyNI.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-07-23-33-18.gh-issue-125039.MKTyNI.rst deleted file mode 100644 index 93716c0b1c0df1..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-10-07-23-33-18.gh-issue-125039.MKTyNI.rst +++ /dev/null @@ -1 +0,0 @@ -Make ``this_instr`` and ``prev_instr`` const in cases generator. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-10-10-12-04-56.gh-issue-125174._8h6T7.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-10-12-04-56.gh-issue-125174._8h6T7.rst deleted file mode 100644 index c7eaac32601bb3..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-10-10-12-04-56.gh-issue-125174._8h6T7.rst +++ /dev/null @@ -1,4 +0,0 @@ -Make the handling of reference counts of immortal objects more robust. -Immortal objects with reference counts that deviate from their original -reference count by up to a billion (half a billion on 32 bit builds) are -still counted as immortal. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-10-10-14-47-13.gh-issue-125221.nfSQzT.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-10-14-47-13.gh-issue-125221.nfSQzT.rst deleted file mode 100644 index c79650c3a64feb..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-10-10-14-47-13.gh-issue-125221.nfSQzT.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix possible race condition when calling :meth:`~object.__reduce_ex__` for the -first time in the free threading build. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-10-15-15-29-41.gh-issue-124375.wNrWVa.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-15-15-29-41.gh-issue-124375.wNrWVa.rst deleted file mode 100644 index 4bd17a6e683bc7..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-10-15-15-29-41.gh-issue-124375.wNrWVa.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a crash in the free threading build when the GC runs concurrently with a new thread starting. diff --git a/Misc/NEWS.d/next/Documentation/2018-07-04-20-35-25.bpo-34008.bqecIb.rst b/Misc/NEWS.d/next/Documentation/2018-07-04-20-35-25.bpo-34008.bqecIb.rst deleted file mode 100644 index a89086af35bfc1..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2018-07-04-20-35-25.bpo-34008.bqecIb.rst +++ /dev/null @@ -1,8 +0,0 @@ -The :c:func:`Py_Main` documentation moved from the "Very High Level API" section to the -"Initialization and Finalization" section. - -Also make it explicit that we expect ``Py_Main`` to typically be called instead -of ``Py_Initialize`` rather than after it (since ``Py_Main`` makes its own -call to ``Py_Initialize``). Document that calling both is -supported but is version dependent on which settings -will be applied correctly. diff --git a/Misc/NEWS.d/next/Documentation/2024-06-03-22-06-26.gh-issue-119574.Ik9kOO.rst b/Misc/NEWS.d/next/Documentation/2024-06-03-22-06-26.gh-issue-119574.Ik9kOO.rst deleted file mode 100644 index 902e7c17fc2e9d..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2024-06-03-22-06-26.gh-issue-119574.Ik9kOO.rst +++ /dev/null @@ -1 +0,0 @@ -Added some missing environment variables to the output of :option:`--help-env`. diff --git a/Misc/NEWS.d/next/Documentation/2024-06-05-12-36-18.gh-issue-120012.f14DbQ.rst b/Misc/NEWS.d/next/Documentation/2024-06-05-12-36-18.gh-issue-120012.f14DbQ.rst deleted file mode 100644 index 2bf0c977b90387..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2024-06-05-12-36-18.gh-issue-120012.f14DbQ.rst +++ /dev/null @@ -1,3 +0,0 @@ -Clarify the behaviours of :meth:`multiprocessing.Queue.empty` and -:meth:`multiprocessing.SimpleQueue.empty` on closed queues. -Patch by Bénédikt Tran. diff --git a/Misc/NEWS.d/next/Documentation/2024-07-14-11-48-10.gh-issue-121749.nxHoTk.rst b/Misc/NEWS.d/next/Documentation/2024-07-14-11-48-10.gh-issue-121749.nxHoTk.rst deleted file mode 100644 index 17dc60c11468f4..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2024-07-14-11-48-10.gh-issue-121749.nxHoTk.rst +++ /dev/null @@ -1 +0,0 @@ -Fix documentation for :c:func:`PyModule_AddObjectRef`. diff --git a/Misc/NEWS.d/next/Documentation/2024-07-14-12-25-53.gh-issue-117765.YFMOUv.rst b/Misc/NEWS.d/next/Documentation/2024-07-14-12-25-53.gh-issue-117765.YFMOUv.rst deleted file mode 100644 index a727c1aa9a0571..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2024-07-14-12-25-53.gh-issue-117765.YFMOUv.rst +++ /dev/null @@ -1 +0,0 @@ -Improved documentation for :func:`unittest.mock.patch.dict` diff --git a/Misc/NEWS.d/next/Documentation/2024-07-19-12-22-48.gh-issue-121277.wF_zKd.rst b/Misc/NEWS.d/next/Documentation/2024-07-19-12-22-48.gh-issue-121277.wF_zKd.rst deleted file mode 100644 index 60f75ae0c21326..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2024-07-19-12-22-48.gh-issue-121277.wF_zKd.rst +++ /dev/null @@ -1,2 +0,0 @@ -Writers of CPython's documentation can now use ``next`` as the version for -the ``versionchanged``, ``versionadded``, ``deprecated`` directives. diff --git a/Misc/NEWS.d/next/Documentation/2024-08-01-17-18-21.gh-issue-70870.fZnBM9.rst b/Misc/NEWS.d/next/Documentation/2024-08-01-17-18-21.gh-issue-70870.fZnBM9.rst deleted file mode 100644 index ba607bf7a42cd9..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2024-08-01-17-18-21.gh-issue-70870.fZnBM9.rst +++ /dev/null @@ -1,3 +0,0 @@ -Clarified the dual usage of the term "free variable" (both the formal -meaning of any reference to names defined outside the local scope, and the -narrower pragmatic meaning of nonlocal variables named in ``co_freevars``). diff --git a/Misc/NEWS.d/next/Documentation/2024-09-11-16-52-08.gh-issue-123976.jhOfNR.rst b/Misc/NEWS.d/next/Documentation/2024-09-11-16-52-08.gh-issue-123976.jhOfNR.rst deleted file mode 100644 index 7f8e5801ae6597..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2024-09-11-16-52-08.gh-issue-123976.jhOfNR.rst +++ /dev/null @@ -1 +0,0 @@ -Refresh docs around custom providers. diff --git a/Misc/NEWS.d/next/Documentation/2024-09-19-19-33-25.gh-issue-116622.M65UZ6.rst b/Misc/NEWS.d/next/Documentation/2024-09-19-19-33-25.gh-issue-116622.M65UZ6.rst deleted file mode 100644 index f047a8c6caa698..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2024-09-19-19-33-25.gh-issue-116622.M65UZ6.rst +++ /dev/null @@ -1 +0,0 @@ -Add an Android platform guide, and flag modules not available on Android. diff --git a/Misc/NEWS.d/next/Documentation/2024-09-24-11-52-36.gh-issue-124457.yrCjSV.rst b/Misc/NEWS.d/next/Documentation/2024-09-24-11-52-36.gh-issue-124457.yrCjSV.rst deleted file mode 100644 index f9da7b8a5724f5..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2024-09-24-11-52-36.gh-issue-124457.yrCjSV.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove coverity scan from the CPython repo. It has not been used since 2020 -and is currently unmaintained. diff --git a/Misc/NEWS.d/next/Documentation/2024-09-27-16-47-48.gh-issue-124720.nVSTVb.rst b/Misc/NEWS.d/next/Documentation/2024-09-27-16-47-48.gh-issue-124720.nVSTVb.rst deleted file mode 100644 index 6bef1e4158400b..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2024-09-27-16-47-48.gh-issue-124720.nVSTVb.rst +++ /dev/null @@ -1,2 +0,0 @@ -Update "Using Python on a Mac" section of the "Python Setup and Usage" -document and include information on installing free-threading support. diff --git a/Misc/NEWS.d/next/Documentation/2024-10-07-00-31-17.gh-issue-125018.yKnymn.rst b/Misc/NEWS.d/next/Documentation/2024-10-07-00-31-17.gh-issue-125018.yKnymn.rst deleted file mode 100644 index e910da5b879ba5..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2024-10-07-00-31-17.gh-issue-125018.yKnymn.rst +++ /dev/null @@ -1,4 +0,0 @@ -The :mod:`importlib.metadata` documentation now includes semantic -cross-reference targets for the significant documented APIs. This means -intersphinx references like :func:`importlib.metadata.version` will -now work as expected. diff --git a/Misc/NEWS.d/next/Documentation/2024-10-10-02-56-24.gh-issue-124872.0mDDOq.rst b/Misc/NEWS.d/next/Documentation/2024-10-10-02-56-24.gh-issue-124872.0mDDOq.rst deleted file mode 100644 index 69a5c764d05a2e..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2024-10-10-02-56-24.gh-issue-124872.0mDDOq.rst +++ /dev/null @@ -1,3 +0,0 @@ -Added definitions for :term:`context`, :term:`current context`, and -:term:`context management protocol`, updated related definitions to be -consistent, and expanded the documentation for :class:`contextvars.Context`. diff --git a/Misc/NEWS.d/next/IDLE/2024-06-05-14-54-24.gh-issue-120104.j_thj4.rst b/Misc/NEWS.d/next/IDLE/2024-06-05-14-54-24.gh-issue-120104.j_thj4.rst deleted file mode 100644 index 10f5e345bf3e4f..00000000000000 --- a/Misc/NEWS.d/next/IDLE/2024-06-05-14-54-24.gh-issue-120104.j_thj4.rst +++ /dev/null @@ -1 +0,0 @@ -Fix padding in config and search dialog windows in IDLE. diff --git a/Misc/NEWS.d/next/IDLE/2024-06-16-21-42-45.gh-issue-120083.nczuyv.rst b/Misc/NEWS.d/next/IDLE/2024-06-16-21-42-45.gh-issue-120083.nczuyv.rst deleted file mode 100644 index 643c2bb38c6e1f..00000000000000 --- a/Misc/NEWS.d/next/IDLE/2024-06-16-21-42-45.gh-issue-120083.nczuyv.rst +++ /dev/null @@ -1 +0,0 @@ -Add explicit black IDLE Hovertip foreground color needed for recent macOS. Fixes Sonoma showing unreadable white on pale yellow. Patch by John Riggles. diff --git a/Misc/NEWS.d/next/IDLE/2024-07-16-16-57-03.gh-issue-78889.U7ghFD.rst b/Misc/NEWS.d/next/IDLE/2024-07-16-16-57-03.gh-issue-78889.U7ghFD.rst deleted file mode 100644 index 604194ebb2e859..00000000000000 --- a/Misc/NEWS.d/next/IDLE/2024-07-16-16-57-03.gh-issue-78889.U7ghFD.rst +++ /dev/null @@ -1,2 +0,0 @@ -Stop Shell freezes by blocking user access to non-method sys.stdout.shell attributes, -which are all private. diff --git a/Misc/NEWS.d/next/IDLE/2024-07-30-18-02-55.gh-issue-122482.TerE0g.rst b/Misc/NEWS.d/next/IDLE/2024-07-30-18-02-55.gh-issue-122482.TerE0g.rst deleted file mode 100644 index 8a11e73305992f..00000000000000 --- a/Misc/NEWS.d/next/IDLE/2024-07-30-18-02-55.gh-issue-122482.TerE0g.rst +++ /dev/null @@ -1,2 +0,0 @@ -Change About IDLE to direct users to discuss.python.org instead of the now -unused idle-dev email and mailing list. diff --git a/Misc/NEWS.d/next/IDLE/2024-09-21-23-12-18.gh-issue-112938.OeiDru.rst b/Misc/NEWS.d/next/IDLE/2024-09-21-23-12-18.gh-issue-112938.OeiDru.rst deleted file mode 100644 index 0cd058eeffb1d5..00000000000000 --- a/Misc/NEWS.d/next/IDLE/2024-09-21-23-12-18.gh-issue-112938.OeiDru.rst +++ /dev/null @@ -1 +0,0 @@ -Fix uninteruptable hang when Shell gets rapid continuous output. diff --git a/Misc/NEWS.d/next/IDLE/2024-10-04-15-34-34.gh-issue-122392.V8K3w2.rst b/Misc/NEWS.d/next/IDLE/2024-10-04-15-34-34.gh-issue-122392.V8K3w2.rst deleted file mode 100644 index 541f6212794ef2..00000000000000 --- a/Misc/NEWS.d/next/IDLE/2024-10-04-15-34-34.gh-issue-122392.V8K3w2.rst +++ /dev/null @@ -1,2 +0,0 @@ -Increase currently inadequate vertical spacing for the IDLE browsers (path, -module, and stack) on high-resolution monitors. diff --git a/Misc/NEWS.d/next/Library/2018-12-04-07-36-27.bpo-14074.fMLKCu.rst b/Misc/NEWS.d/next/Library/2018-12-04-07-36-27.bpo-14074.fMLKCu.rst deleted file mode 100644 index 221c8e05fa98aa..00000000000000 --- a/Misc/NEWS.d/next/Library/2018-12-04-07-36-27.bpo-14074.fMLKCu.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix :mod:`argparse` metavar processing to allow positional arguments to have a -tuple metavar. diff --git a/Misc/NEWS.d/next/Library/2019-08-27-01-16-50.gh-issue-67693.4NIAiy.rst b/Misc/NEWS.d/next/Library/2019-08-27-01-16-50.gh-issue-67693.4NIAiy.rst deleted file mode 100644 index 22457df03e65c9..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-27-01-16-50.gh-issue-67693.4NIAiy.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix :func:`urllib.parse.urlunparse` and :func:`urllib.parse.urlunsplit` for URIs with path starting with multiple slashes and no authority. -Based on patch by Ashwin Ramaswami. diff --git a/Misc/NEWS.d/next/Library/2020-03-28-21-00-54.bpo-15987.aBL8XS.rst b/Misc/NEWS.d/next/Library/2020-03-28-21-00-54.bpo-15987.aBL8XS.rst deleted file mode 100644 index b906393449656d..00000000000000 --- a/Misc/NEWS.d/next/Library/2020-03-28-21-00-54.bpo-15987.aBL8XS.rst +++ /dev/null @@ -1,2 +0,0 @@ -Implemented :func:`ast.compare` for comparing two ASTs. Patch by Batuhan -Taskaya with some help from Jeremy Hylton. diff --git a/Misc/NEWS.d/next/Library/2020-12-22-18-08-12.bpo-41843.q9Nh2r.rst b/Misc/NEWS.d/next/Library/2020-12-22-18-08-12.bpo-41843.q9Nh2r.rst deleted file mode 100644 index 4e525f7ed6a757..00000000000000 --- a/Misc/NEWS.d/next/Library/2020-12-22-18-08-12.bpo-41843.q9Nh2r.rst +++ /dev/null @@ -1,2 +0,0 @@ -Solaris now uses :func:`os.sendfile` fast-copy syscall for more efficient -:mod:`shutil` file copy related functions. diff --git a/Misc/NEWS.d/next/Library/2021-08-24-19-37-46.bpo-44864.KzxaDh.rst b/Misc/NEWS.d/next/Library/2021-08-24-19-37-46.bpo-44864.KzxaDh.rst deleted file mode 100644 index 9610fa90ef0a98..00000000000000 --- a/Misc/NEWS.d/next/Library/2021-08-24-19-37-46.bpo-44864.KzxaDh.rst +++ /dev/null @@ -1 +0,0 @@ -Do not translate user-provided strings in :class:`argparse.ArgumentParser`. diff --git a/Misc/NEWS.d/next/Library/2022-03-10-16-47-57.bpo-45767.ywmyo1.rst b/Misc/NEWS.d/next/Library/2022-03-10-16-47-57.bpo-45767.ywmyo1.rst deleted file mode 100644 index 0cdf1e84157777..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-10-16-47-57.bpo-45767.ywmyo1.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix integer conversion in :func:`os.major`, :func:`os.minor`, and -:func:`os.makedev`. Support device numbers larger than ``2**63-1``. Support -non-existent device number (``NODEV``). diff --git a/Misc/NEWS.d/next/Library/2023-03-30-18-19-53.gh-issue-103134.bHrn91.rst b/Misc/NEWS.d/next/Library/2023-03-30-18-19-53.gh-issue-103134.bHrn91.rst deleted file mode 100644 index 11559dce0ae2b4..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-03-30-18-19-53.gh-issue-103134.bHrn91.rst +++ /dev/null @@ -1,6 +0,0 @@ -Add additional methods to :ref:`proxy objects ` -in the :mod:`!multiprocessing` module: - -* :meth:`!clear` and :meth:`!copy` for proxies of :class:`list` -* :meth:`~dict.fromkeys`, ``reversed(d)``, ``d | {}``, ``{} | d``, - ``d |= {'b': 2}`` for proxies of :class:`dict` diff --git a/Misc/NEWS.d/next/Library/2023-04-10-00-04-37.gh-issue-87106.UyBnPQ.rst b/Misc/NEWS.d/next/Library/2023-04-10-00-04-37.gh-issue-87106.UyBnPQ.rst deleted file mode 100644 index 2c736e72476313..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-04-10-00-04-37.gh-issue-87106.UyBnPQ.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fixed handling in :meth:`inspect.Signature.bind` of keyword arguments having -the same name as positional-only arguments when a variadic keyword argument -(e.g. ``**kwargs``) is present. diff --git a/Misc/NEWS.d/next/Library/2023-04-24-05-34-23.gh-issue-103194.GwBwWL.rst b/Misc/NEWS.d/next/Library/2023-04-24-05-34-23.gh-issue-103194.GwBwWL.rst deleted file mode 100644 index bc9187309c6a53..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-04-24-05-34-23.gh-issue-103194.GwBwWL.rst +++ /dev/null @@ -1,4 +0,0 @@ -Prepare Tkinter for C API changes in Tcl 8.7/9.0 to avoid -:class:`!_tkinter.Tcl_Obj` being unexpectedly returned -instead of :class:`bool`, :class:`str`, -:class:`bytearray`, or :class:`int`. diff --git a/Misc/NEWS.d/next/Library/2023-04-26-22-24-17.gh-issue-92081.V8xMot.rst b/Misc/NEWS.d/next/Library/2023-04-26-22-24-17.gh-issue-92081.V8xMot.rst deleted file mode 100644 index 0302e957b884cf..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-04-26-22-24-17.gh-issue-92081.V8xMot.rst +++ /dev/null @@ -1 +0,0 @@ -Fix missing spaces in email headers when the spaces are mixed with encoded 8-bit characters. diff --git a/Misc/NEWS.d/next/Library/2023-04-28-09-54-15.gh-issue-103956.EyLDPS.rst b/Misc/NEWS.d/next/Library/2023-04-28-09-54-15.gh-issue-103956.EyLDPS.rst deleted file mode 100644 index 4ce1491ffa91e2..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-04-28-09-54-15.gh-issue-103956.EyLDPS.rst +++ /dev/null @@ -1 +0,0 @@ -Fix lack of newline characters in :mod:`trace` module output when line tracing is enabled but source code line for current frame is not available. diff --git a/Misc/NEWS.d/next/Library/2023-06-16-14-52-00.gh-issue-102450.MfeR6A.rst b/Misc/NEWS.d/next/Library/2023-06-16-14-52-00.gh-issue-102450.MfeR6A.rst deleted file mode 100644 index abfad5fa63b777..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-16-14-52-00.gh-issue-102450.MfeR6A.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add missing ISO-8601 24:00 alternative to midnight of next day to :meth:`datetime.datetime.fromisoformat` and :meth:`datetime.time.fromisoformat`. -Patch by Izan "TizzySaurus" Robinson (tizzysaurus@gmail.com) diff --git a/Misc/NEWS.d/next/Library/2023-06-17-09-07-06.gh-issue-105623.5G06od.rst b/Misc/NEWS.d/next/Library/2023-06-17-09-07-06.gh-issue-105623.5G06od.rst deleted file mode 100644 index 2890674aac4bbc..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-17-09-07-06.gh-issue-105623.5G06od.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix performance degradation in -:class:`logging.handlers.RotatingFileHandler`. Patch by Craig Robson. diff --git a/Misc/NEWS.d/next/Library/2023-09-19-17-56-24.gh-issue-109109.WJvvX2.rst b/Misc/NEWS.d/next/Library/2023-09-19-17-56-24.gh-issue-109109.WJvvX2.rst deleted file mode 100644 index e741e60ff41a9b..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-19-17-56-24.gh-issue-109109.WJvvX2.rst +++ /dev/null @@ -1,5 +0,0 @@ -You can now get the raw TLS certificate chains from TLS connections via -:meth:`ssl.SSLSocket.get_verified_chain` and -:meth:`ssl.SSLSocket.get_unverified_chain` methods. - -Contributed by Mateusz Nowak. diff --git a/Misc/NEWS.d/next/Library/2023-12-12-15-19-58.gh-issue-108172.KyDPuG.rst b/Misc/NEWS.d/next/Library/2023-12-12-15-19-58.gh-issue-108172.KyDPuG.rst deleted file mode 100644 index 5c6b9cd3f81a21..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-12-12-15-19-58.gh-issue-108172.KyDPuG.rst +++ /dev/null @@ -1 +0,0 @@ -``webbrowser`` honors OS preferred browser on Linux when its desktop entry name contains the text of a known browser name. diff --git a/Misc/NEWS.d/next/Library/2023-12-14-13-43-27.gh-issue-113008.jWYn8T.rst b/Misc/NEWS.d/next/Library/2023-12-14-13-43-27.gh-issue-113008.jWYn8T.rst deleted file mode 100644 index 0f2a44299717c0..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-12-14-13-43-27.gh-issue-113008.jWYn8T.rst +++ /dev/null @@ -1 +0,0 @@ -Correct argparse usage output for required, mutually exclusive groups containing a positional argument diff --git a/Misc/NEWS.d/next/Library/2024-01-12-08-51-03.gh-issue-113978.MqTgB0.rst b/Misc/NEWS.d/next/Library/2024-01-12-08-51-03.gh-issue-113978.MqTgB0.rst deleted file mode 100644 index b8f9f255e0a75d..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-01-12-08-51-03.gh-issue-113978.MqTgB0.rst +++ /dev/null @@ -1 +0,0 @@ -Ignore warnings on text completion inside REPL. diff --git a/Misc/NEWS.d/next/Library/2024-01-14-11-43-31.gh-issue-113878.dmEIN3.rst b/Misc/NEWS.d/next/Library/2024-01-14-11-43-31.gh-issue-113878.dmEIN3.rst deleted file mode 100644 index 8e1937ab73c31b..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-01-14-11-43-31.gh-issue-113878.dmEIN3.rst +++ /dev/null @@ -1,9 +0,0 @@ -Add *doc* parameter to :func:`dataclasses.field`, so it can be stored and -shown as a documentation / metadata. If ``@dataclass(slots=True)`` is used, -then the supplied string is availabl in the :attr:`~object.__slots__` dict. -Otherwise, the supplied string is only available in the corresponding -:class:`dataclasses.Field` object. - -In order to support this feature we are changing the ``__slots__`` format -in dataclasses from :class:`tuple` to :class:`dict` -when documentation / metadata is present. diff --git a/Misc/NEWS.d/next/Library/2024-01-18-21-44-23.gh-issue-114264.DBKn29.rst b/Misc/NEWS.d/next/Library/2024-01-18-21-44-23.gh-issue-114264.DBKn29.rst deleted file mode 100644 index 069ac68b4f3a95..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-01-18-21-44-23.gh-issue-114264.DBKn29.rst +++ /dev/null @@ -1 +0,0 @@ -Improve performance of :func:`copy.deepcopy` by adding a fast path for atomic types. diff --git a/Misc/NEWS.d/next/Library/2024-02-22-10-12-59.gh-issue-115808.F2g2Ku.rst b/Misc/NEWS.d/next/Library/2024-02-22-10-12-59.gh-issue-115808.F2g2Ku.rst deleted file mode 100644 index 0fe6a336bdf95b..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-02-22-10-12-59.gh-issue-115808.F2g2Ku.rst +++ /dev/null @@ -1 +0,0 @@ -Add :func:`operator.is_none` and :func:`operator.is_not_none` functions. diff --git a/Misc/NEWS.d/next/Library/2024-02-27-10-22-15.gh-issue-115937.0cVNur.rst b/Misc/NEWS.d/next/Library/2024-02-27-10-22-15.gh-issue-115937.0cVNur.rst deleted file mode 100644 index f9dae0c9b8e2b2..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-02-27-10-22-15.gh-issue-115937.0cVNur.rst +++ /dev/null @@ -1,3 +0,0 @@ -Removed extra preprocessing for the ``__signature__`` attribute: the code -just check if it's a :class:`inspect.Signature` instance. Patch by Sergey B -Kirpichev. diff --git a/Misc/NEWS.d/next/Library/2024-03-19-21-41-31.gh-issue-106531.Mgd--6.rst b/Misc/NEWS.d/next/Library/2024-03-19-21-41-31.gh-issue-106531.Mgd--6.rst deleted file mode 100644 index 6a5783c5ad9846..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-03-19-21-41-31.gh-issue-106531.Mgd--6.rst +++ /dev/null @@ -1,6 +0,0 @@ -In :mod:`importlib.resources`, sync with `importlib_resources 6.3.2 -`_, -including: ``MultiplexedPath`` now expects ``Traversable`` paths, -deprecating string arguments to ``MultiplexedPath``; Enabled support for -resources in namespace packages in zip files; Fixed ``NotADirectoryError`` -when calling files on a subdirectory of a namespace package. diff --git a/Misc/NEWS.d/next/Library/2024-04-19-05-58-50.gh-issue-117766.J3xepp.rst b/Misc/NEWS.d/next/Library/2024-04-19-05-58-50.gh-issue-117766.J3xepp.rst deleted file mode 100644 index d090f931f0238d..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-04-19-05-58-50.gh-issue-117766.J3xepp.rst +++ /dev/null @@ -1 +0,0 @@ -Always use :func:`str` to print ``choices`` in :mod:`argparse`. diff --git a/Misc/NEWS.d/next/Library/2024-04-19-14-59-53.gh-issue-118033.amS4Gw.rst b/Misc/NEWS.d/next/Library/2024-04-19-14-59-53.gh-issue-118033.amS4Gw.rst deleted file mode 100644 index 7ceb29330abf22..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-04-19-14-59-53.gh-issue-118033.amS4Gw.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix :func:`dataclasses.dataclass` not creating a ``__weakref__`` slot when -subclassing :class:`typing.Generic`. diff --git a/Misc/NEWS.d/next/Library/2024-04-24-16-23-04.gh-issue-110190.TGd5qx.rst b/Misc/NEWS.d/next/Library/2024-04-24-16-23-04.gh-issue-110190.TGd5qx.rst deleted file mode 100644 index abc3ddb4ab5597..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-04-24-16-23-04.gh-issue-110190.TGd5qx.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix ctypes structs with array on SPARC by setting ``MAX_STRUCT_SIZE`` to 32 -in stgdict. Patch by Jakub Kulik diff --git a/Misc/NEWS.d/next/Library/2024-04-28-19-51-00.gh-issue-118263.Gaap3S.rst b/Misc/NEWS.d/next/Library/2024-04-28-19-51-00.gh-issue-118263.Gaap3S.rst deleted file mode 100644 index 165a1ba69a811b..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-04-28-19-51-00.gh-issue-118263.Gaap3S.rst +++ /dev/null @@ -1 +0,0 @@ -Speed up :func:`os.path.splitroot` & :func:`os.path.normpath` with a direct C call. diff --git a/Misc/NEWS.d/next/Library/2024-05-01-22-24-05.gh-issue-110863.GjYBbq.rst b/Misc/NEWS.d/next/Library/2024-05-01-22-24-05.gh-issue-110863.GjYBbq.rst deleted file mode 100644 index 37e27a6e37c7d0..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-01-22-24-05.gh-issue-110863.GjYBbq.rst +++ /dev/null @@ -1,2 +0,0 @@ -:func:`os.path.realpath` now suppresses any :exc:`OSError` from -:func:`os.readlink` when *strict* mode is disabled (the default). diff --git a/Misc/NEWS.d/next/Library/2024-05-06-17-39-52.gh-issue-118673.sTXBit.rst b/Misc/NEWS.d/next/Library/2024-05-06-17-39-52.gh-issue-118673.sTXBit.rst deleted file mode 100644 index f0a87d2a91df3c..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-06-17-39-52.gh-issue-118673.sTXBit.rst +++ /dev/null @@ -1 +0,0 @@ -Removed executable bits and shebang from stdlib modules. diff --git a/Misc/NEWS.d/next/Library/2024-05-07-17-38-53.gh-issue-118714.XXKpVZ.rst b/Misc/NEWS.d/next/Library/2024-05-07-17-38-53.gh-issue-118714.XXKpVZ.rst deleted file mode 100644 index f41baee303482a..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-07-17-38-53.gh-issue-118714.XXKpVZ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Allow ``restart`` in post-mortem debugging of :mod:`pdb`. Removed restart message -when the user quits pdb from post-mortem mode. diff --git a/Misc/NEWS.d/next/Library/2024-05-08-09-21-49.gh-issue-118772.c16E8X.rst b/Misc/NEWS.d/next/Library/2024-05-08-09-21-49.gh-issue-118772.c16E8X.rst deleted file mode 100644 index 474454b36da956..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-08-09-21-49.gh-issue-118772.c16E8X.rst +++ /dev/null @@ -1,2 +0,0 @@ -Allow :class:`typing.TypeVar` instances without a default to follow -instances without a default in some cases. Patch by Jelle Zijlstra. diff --git a/Misc/NEWS.d/next/Library/2024-05-08-18-33-07.gh-issue-118507.OCQsAY.rst b/Misc/NEWS.d/next/Library/2024-05-08-18-33-07.gh-issue-118507.OCQsAY.rst deleted file mode 100644 index 67b1fea4f83cb4..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-08-18-33-07.gh-issue-118507.OCQsAY.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix :func:`os.path.isfile` on Windows for pipes. -Speedup :func:`os.path.isjunction` and :func:`os.path.lexists` on Windows with a native implementation. diff --git a/Misc/NEWS.d/next/Library/2024-05-08-18-59-19.gh-issue-78707._Lz1sw.rst b/Misc/NEWS.d/next/Library/2024-05-08-18-59-19.gh-issue-78707._Lz1sw.rst deleted file mode 100644 index c73bab97b75838..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-08-18-59-19.gh-issue-78707._Lz1sw.rst +++ /dev/null @@ -1,3 +0,0 @@ -Drop support for passing additional positional arguments to -:meth:`pathlib.PurePath.relative_to` and -:meth:`~pathlib.PurePath.is_relative_to`. diff --git a/Misc/NEWS.d/next/Library/2024-05-08-19-47-34.gh-issue-101357.e4R_9x.rst b/Misc/NEWS.d/next/Library/2024-05-08-19-47-34.gh-issue-101357.e4R_9x.rst deleted file mode 100644 index c99a7e5f024823..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-08-19-47-34.gh-issue-101357.e4R_9x.rst +++ /dev/null @@ -1,5 +0,0 @@ -Suppress all :exc:`OSError` exceptions from :meth:`pathlib.Path.exists` and -``is_*()`` methods, rather than a selection of more common errors. The new -behaviour is consistent with :func:`os.path.exists`, :func:`os.path.isdir`, -etc. Use :meth:`pathlib.Path.stat` to retrieve the file status without -suppressing exceptions. diff --git a/Misc/NEWS.d/next/Library/2024-05-08-20-41-48.gh-issue-74033.YebHZj.rst b/Misc/NEWS.d/next/Library/2024-05-08-20-41-48.gh-issue-74033.YebHZj.rst deleted file mode 100644 index e6ff47e1a3e57b..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-08-20-41-48.gh-issue-74033.YebHZj.rst +++ /dev/null @@ -1 +0,0 @@ -Drop support for passing keyword arguments to :class:`pathlib.Path`. diff --git a/Misc/NEWS.d/next/Library/2024-05-08-21-13-56.gh-issue-118760.mdmH3T.rst b/Misc/NEWS.d/next/Library/2024-05-08-21-13-56.gh-issue-118760.mdmH3T.rst deleted file mode 100644 index 89ef9334fbc65d..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-08-21-13-56.gh-issue-118760.mdmH3T.rst +++ /dev/null @@ -1 +0,0 @@ -Fix errors in calling Tkinter bindings on Windows. diff --git a/Misc/NEWS.d/next/Library/2024-05-08-21-30-33.gh-issue-118760.XvyMHn.rst b/Misc/NEWS.d/next/Library/2024-05-08-21-30-33.gh-issue-118760.XvyMHn.rst deleted file mode 100644 index 0e2712c26b1c13..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-08-21-30-33.gh-issue-118760.XvyMHn.rst +++ /dev/null @@ -1 +0,0 @@ -Restore the default value of ``tkiter.wantobjects`` to ``1``. diff --git a/Misc/NEWS.d/next/Library/2024-05-08-23-16-50.gh-issue-118798.Q_ybqP.rst b/Misc/NEWS.d/next/Library/2024-05-08-23-16-50.gh-issue-118798.Q_ybqP.rst deleted file mode 100644 index 28847e13207ffe..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-08-23-16-50.gh-issue-118798.Q_ybqP.rst +++ /dev/null @@ -1,2 +0,0 @@ -The *isdst* parameter has been removed from :func:`email.utils.localtime`. -Patch by Hugo van Kemenade. diff --git a/Misc/NEWS.d/next/Library/2024-05-09-00-52-30.gh-issue-118803.Wv3AvU.rst b/Misc/NEWS.d/next/Library/2024-05-09-00-52-30.gh-issue-118803.Wv3AvU.rst deleted file mode 100644 index 2d86dff57faf72..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-09-00-52-30.gh-issue-118803.Wv3AvU.rst +++ /dev/null @@ -1,3 +0,0 @@ -:class:`!typing.ByteString` and :class:`!collections.abc.ByteString` are -removed. They had previously raised a :exc:`DeprecationWarning` since Python -3.12. diff --git a/Misc/NEWS.d/next/Library/2024-05-09-01-05-52.gh-issue-118805.N7dm07.rst b/Misc/NEWS.d/next/Library/2024-05-09-01-05-52.gh-issue-118805.N7dm07.rst deleted file mode 100644 index 4f1db04d8bd67f..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-09-01-05-52.gh-issue-118805.N7dm07.rst +++ /dev/null @@ -1,3 +0,0 @@ -Remove *type*, *choices*, and *metavar* parameters of -:class:`!argparse.BooleanOptionalAction`. -They were deprecated since Python 3.12. diff --git a/Misc/NEWS.d/next/Library/2024-05-09-02-43-37.gh-issue-101588.30bNAr.rst b/Misc/NEWS.d/next/Library/2024-05-09-02-43-37.gh-issue-101588.30bNAr.rst deleted file mode 100644 index 3e0f496047bc8e..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-09-02-43-37.gh-issue-101588.30bNAr.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove copy, deepcopy, and pickle from itertools. These had previously -raised a DeprecationWarning since Python 3.12. diff --git a/Misc/NEWS.d/next/Library/2024-05-09-08-46-12.gh-issue-118851.aPAoJw.rst b/Misc/NEWS.d/next/Library/2024-05-09-08-46-12.gh-issue-118851.aPAoJw.rst deleted file mode 100644 index d036d0cda617ef..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-09-08-46-12.gh-issue-118851.aPAoJw.rst +++ /dev/null @@ -1,2 +0,0 @@ -``ctx`` arguments to the constructors of :mod:`ast` node classes now default -to :class:`ast.Load() `. Patch by Jelle Zijlstra. diff --git a/Misc/NEWS.d/next/Library/2024-05-09-11-50-26.gh-issue-118824.-jBJQC.rst b/Misc/NEWS.d/next/Library/2024-05-09-11-50-26.gh-issue-118824.-jBJQC.rst deleted file mode 100644 index c9254f1b9dbea8..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-09-11-50-26.gh-issue-118824.-jBJQC.rst +++ /dev/null @@ -1,3 +0,0 @@ -Remove deprecated :func:`!pty.master_open` and :func:`!pty.slave_open`. -Use :func:`pty.openpty` instead. -Patch by Nikita Sobolev. diff --git a/Misc/NEWS.d/next/Library/2024-05-09-12-33-25.gh-issue-118827.JrzHz1.rst b/Misc/NEWS.d/next/Library/2024-05-09-12-33-25.gh-issue-118827.JrzHz1.rst deleted file mode 100644 index 40612dd93bd6da..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-09-12-33-25.gh-issue-118827.JrzHz1.rst +++ /dev/null @@ -1,3 +0,0 @@ -Remove deprecated :class:`!Quoter` class from :mod:`urllib.parse`. It had -previously raised a :exc:`DeprecationWarning` since Python 3.11. -Patch by Nikita Sobolev. diff --git a/Misc/NEWS.d/next/Library/2024-05-09-21-36-11.gh-issue-118868.uckxxP.rst b/Misc/NEWS.d/next/Library/2024-05-09-21-36-11.gh-issue-118868.uckxxP.rst deleted file mode 100644 index 372a809d9594b0..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-09-21-36-11.gh-issue-118868.uckxxP.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed issue where kwargs were no longer passed to the logging handler -QueueHandler diff --git a/Misc/NEWS.d/next/Library/2024-05-10-05-24-32.gh-issue-118895.wUm5r2.rst b/Misc/NEWS.d/next/Library/2024-05-10-05-24-32.gh-issue-118895.wUm5r2.rst deleted file mode 100644 index 226c8d612a039c..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-10-05-24-32.gh-issue-118895.wUm5r2.rst +++ /dev/null @@ -1,2 +0,0 @@ -Setting attributes on :data:`typing.NoDefault` now raises -:exc:`AttributeError` instead of :exc:`TypeError`. diff --git a/Misc/NEWS.d/next/Library/2024-05-10-22-36-01.gh-issue-118928.IW7Ukv.rst b/Misc/NEWS.d/next/Library/2024-05-10-22-36-01.gh-issue-118928.IW7Ukv.rst deleted file mode 100644 index 91c95e4a5395d4..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-10-22-36-01.gh-issue-118928.IW7Ukv.rst +++ /dev/null @@ -1,2 +0,0 @@ -Disallow using a sequence of parameters with named placeholders in -:mod:`sqlite3` queries. Patch by Erlend E. Aasland. diff --git a/Misc/NEWS.d/next/Library/2024-05-10-22-59-01.gh-issue-118924.9nyvSH.rst b/Misc/NEWS.d/next/Library/2024-05-10-22-59-01.gh-issue-118924.9nyvSH.rst deleted file mode 100644 index 36581dbb9bb11b..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-10-22-59-01.gh-issue-118924.9nyvSH.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove :data:`!version` and :data:`!version_info` from :mod:`sqlite3`. -Patch by Hugo van Kemenade. diff --git a/Misc/NEWS.d/next/Library/2024-05-11-20-23-45.gh-issue-82805.F9bz4J.rst b/Misc/NEWS.d/next/Library/2024-05-11-20-23-45.gh-issue-82805.F9bz4J.rst deleted file mode 100644 index 8715deda7d9c41..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-11-20-23-45.gh-issue-82805.F9bz4J.rst +++ /dev/null @@ -1,5 +0,0 @@ -Support single-dot file extensions in :attr:`pathlib.PurePath.suffix` and -related attributes and methods. For example, the -:attr:`~pathlib.PurePath.suffixes` of ``PurePath('foo.bar.')`` are now -``['.bar', '.']`` rather than ``[]``. This brings file extension splitting -in line with :func:`os.path.splitext`. diff --git a/Misc/NEWS.d/next/Library/2024-05-12-21-38-42.gh-issue-58933.0kgU2l.rst b/Misc/NEWS.d/next/Library/2024-05-12-21-38-42.gh-issue-58933.0kgU2l.rst deleted file mode 100644 index fa70b954e1e9ee..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-12-21-38-42.gh-issue-58933.0kgU2l.rst +++ /dev/null @@ -1 +0,0 @@ -Make :mod:`pdb` return to caller frame correctly when ``f_trace`` of the caller frame is not set diff --git a/Misc/NEWS.d/next/Library/2024-05-15-01-36-08.gh-issue-73991.CGknDf.rst b/Misc/NEWS.d/next/Library/2024-05-15-01-36-08.gh-issue-73991.CGknDf.rst deleted file mode 100644 index d8e3bdf59ed092..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-15-01-36-08.gh-issue-73991.CGknDf.rst +++ /dev/null @@ -1 +0,0 @@ -Add :meth:`pathlib.Path.copy`, which copies a file or directory to another. diff --git a/Misc/NEWS.d/next/Library/2024-05-16-17-31-46.gh-issue-118643.hAWH4C.rst b/Misc/NEWS.d/next/Library/2024-05-16-17-31-46.gh-issue-118643.hAWH4C.rst deleted file mode 100644 index e86a49af74c9d6..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-16-17-31-46.gh-issue-118643.hAWH4C.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix an AttributeError in the :mod:`email` module when re-fold a long address -list. Also fix more cases of incorrect encoding of the address separator in the address list. diff --git a/Misc/NEWS.d/next/Library/2024-05-17-17-32-12.gh-issue-119113.kEv1Ll.rst b/Misc/NEWS.d/next/Library/2024-05-17-17-32-12.gh-issue-119113.kEv1Ll.rst deleted file mode 100644 index 195be067138b2e..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-17-17-32-12.gh-issue-119113.kEv1Ll.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix issue where :meth:`pathlib.PurePath.with_suffix` didn't raise -:exc:`TypeError` when given ``None`` as a suffix. diff --git a/Misc/NEWS.d/next/Library/2024-05-19-12-25-36.gh-issue-119105.VcR4ig.rst b/Misc/NEWS.d/next/Library/2024-05-19-12-25-36.gh-issue-119105.VcR4ig.rst deleted file mode 100644 index 30b5f97b8059f9..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-19-12-25-36.gh-issue-119105.VcR4ig.rst +++ /dev/null @@ -1 +0,0 @@ -``difflib.Differ`` is much faster for some cases of diffs where many pairs of lines are equally similar. diff --git a/Misc/NEWS.d/next/Library/2024-05-19-13-05-59.gh-issue-119121.P1gnh1.rst b/Misc/NEWS.d/next/Library/2024-05-19-13-05-59.gh-issue-119121.P1gnh1.rst deleted file mode 100644 index fd562ea4f73317..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-19-13-05-59.gh-issue-119121.P1gnh1.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a NameError happening in ``asyncio.staggered.staggered_race``. This -function is now tested. diff --git a/Misc/NEWS.d/next/Library/2024-05-19-18-49-04.gh-issue-119174.5GTv7d.rst b/Misc/NEWS.d/next/Library/2024-05-19-18-49-04.gh-issue-119174.5GTv7d.rst deleted file mode 100644 index 7b467b9ebd0d80..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-19-18-49-04.gh-issue-119174.5GTv7d.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix high DPI causes turtledemo(turtle-graphics examples) windows blurry -Patch by Wulian233 and Terry Jan Reedy - diff --git a/Misc/NEWS.d/next/Library/2024-05-20-13-48-37.gh-issue-119189.dhJVs5.rst b/Misc/NEWS.d/next/Library/2024-05-20-13-48-37.gh-issue-119189.dhJVs5.rst deleted file mode 100644 index e5cfbcf95a0b81..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-20-13-48-37.gh-issue-119189.dhJVs5.rst +++ /dev/null @@ -1,3 +0,0 @@ -When using the ``**`` operator or :func:`pow` with :class:`~fractions.Fraction` -as the base and an exponent that is not rational, a float, or a complex, the -fraction is no longer converted to a float. diff --git a/Misc/NEWS.d/next/Library/2024-05-20-20-30-57.gh-issue-111201.DAA5lC.rst b/Misc/NEWS.d/next/Library/2024-05-20-20-30-57.gh-issue-111201.DAA5lC.rst deleted file mode 100644 index 15cd79dec378ee..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-20-20-30-57.gh-issue-111201.DAA5lC.rst +++ /dev/null @@ -1 +0,0 @@ -Remove dependency to :mod:`readline` from the new Python REPL. diff --git a/Misc/NEWS.d/next/Library/2024-05-21-19-10-30.gh-issue-115225.eRmfJH.rst b/Misc/NEWS.d/next/Library/2024-05-21-19-10-30.gh-issue-115225.eRmfJH.rst deleted file mode 100644 index 2b65eaa6dd70ad..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-21-19-10-30.gh-issue-115225.eRmfJH.rst +++ /dev/null @@ -1 +0,0 @@ -Raise error on certain technically valid but pathological ISO 8601 strings passed to :meth:`datetime.time.fromisoformat` that were previously parsed incorrectly. diff --git a/Misc/NEWS.d/next/Library/2024-05-21-20-13-23.gh-issue-118911.iG8nMq.rst b/Misc/NEWS.d/next/Library/2024-05-21-20-13-23.gh-issue-118911.iG8nMq.rst deleted file mode 100644 index 4f15c1b67c9774..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-21-20-13-23.gh-issue-118911.iG8nMq.rst +++ /dev/null @@ -1,5 +0,0 @@ -In PyREPL, updated ``maybe-accept``'s logic so that if the user hits -:kbd:`Enter` twice, they are able to terminate the block even if there's -trailing whitespace. Also, now when the user hits arrow up, the cursor -is on the last functional line. This matches IPython's behavior. -Patch by Aya Elsayed. diff --git a/Misc/NEWS.d/next/Library/2024-05-21-23-39-22.gh-issue-118830.YTqvEo.rst b/Misc/NEWS.d/next/Library/2024-05-21-23-39-22.gh-issue-118830.YTqvEo.rst deleted file mode 100644 index d06499831dc009..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-21-23-39-22.gh-issue-118830.YTqvEo.rst +++ /dev/null @@ -1 +0,0 @@ -Bump :mod:`pickle` default protocol to ``5``. diff --git a/Misc/NEWS.d/next/Library/2024-05-22-21-20-43.gh-issue-118894.xHdxR_.rst b/Misc/NEWS.d/next/Library/2024-05-22-21-20-43.gh-issue-118894.xHdxR_.rst deleted file mode 100644 index ffc4ae336dc54f..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-22-21-20-43.gh-issue-118894.xHdxR_.rst +++ /dev/null @@ -1 +0,0 @@ -:mod:`asyncio` REPL now has the same capabilities as PyREPL. diff --git a/Misc/NEWS.d/next/Library/2024-05-23-11-52-36.gh-issue-117398.2FG1Mk.rst b/Misc/NEWS.d/next/Library/2024-05-23-11-52-36.gh-issue-117398.2FG1Mk.rst deleted file mode 100644 index ac595f1b7fc84c..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-23-11-52-36.gh-issue-117398.2FG1Mk.rst +++ /dev/null @@ -1,3 +0,0 @@ -Objects in the datetime C-API are now all statically allocated, which means -better memory safety, especially when the module is reloaded. This should be -transparent to users. diff --git a/Misc/NEWS.d/next/Library/2024-05-23-15-48-17.gh-issue-119461.82KqUW.rst b/Misc/NEWS.d/next/Library/2024-05-23-15-48-17.gh-issue-119461.82KqUW.rst deleted file mode 100644 index 48e18f42b5556a..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-23-15-48-17.gh-issue-119461.82KqUW.rst +++ /dev/null @@ -1 +0,0 @@ -Add ``socket.VMADDR_CID_LOCAL`` constant. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2024-05-23-22-29-59.gh-issue-119443.KAGz6S.rst b/Misc/NEWS.d/next/Library/2024-05-23-22-29-59.gh-issue-119443.KAGz6S.rst deleted file mode 100644 index 4470c566a37d88..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-23-22-29-59.gh-issue-119443.KAGz6S.rst +++ /dev/null @@ -1,2 +0,0 @@ -The interactive REPL no longer runs with ``from __future__ import -annotations`` enabled. Patch by Jelle Zijlstra. diff --git a/Misc/NEWS.d/next/Library/2024-05-24-04-05-37.gh-issue-119105.aDSRFn.rst b/Misc/NEWS.d/next/Library/2024-05-24-04-05-37.gh-issue-119105.aDSRFn.rst deleted file mode 100644 index 3205061a68ce7f..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-24-04-05-37.gh-issue-119105.aDSRFn.rst +++ /dev/null @@ -1 +0,0 @@ -``difflib``'s ``DIffer.compare()`` (and so also ``ndiff``) can no longer be provoked into cubic-time behavior, or into unbounded recursion, and should generally be faster in ordinary cases too. Results may change in some cases, although that should be rare. Correctness of diffs is not affected. Some similar lines far apart may be reported as deleting one and adding the other, where before they were displayed on adjacent output lines with markup showing the intraline differences. diff --git a/Misc/NEWS.d/next/Library/2024-05-24-11-47-08.gh-issue-69214.Grl6zF.rst b/Misc/NEWS.d/next/Library/2024-05-24-11-47-08.gh-issue-69214.Grl6zF.rst deleted file mode 100644 index 8c3a36c9f56475..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-24-11-47-08.gh-issue-69214.Grl6zF.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix ``fcntl.ioctl()`` *request* parameter: use an ``unsigned long`` instead of -an ``unsigned int`` for the *request* parameter of :func:`fcntl.ioctl` to -support requests larger than ``UINT_MAX``. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2024-05-24-14-32-24.gh-issue-119506.-nMNqq.rst b/Misc/NEWS.d/next/Library/2024-05-24-14-32-24.gh-issue-119506.-nMNqq.rst deleted file mode 100644 index f9b764ae0c49b3..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-24-14-32-24.gh-issue-119506.-nMNqq.rst +++ /dev/null @@ -1 +0,0 @@ -Fix :meth:`!io.TextIOWrapper.write` method breaks internal buffer when the method is called again during flushing internal buffer. diff --git a/Misc/NEWS.d/next/Library/2024-05-24-21-54-55.gh-issue-113892.JKDFqq.rst b/Misc/NEWS.d/next/Library/2024-05-24-21-54-55.gh-issue-113892.JKDFqq.rst deleted file mode 100644 index 639d5abe878344..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-24-21-54-55.gh-issue-113892.JKDFqq.rst +++ /dev/null @@ -1,3 +0,0 @@ -Now, the method ``sock_connect`` of :class:`asyncio.ProactorEventLoop` -raises a :exc:`ValueError` if given socket is not in -non-blocking mode, as well as in other loop implementations. diff --git a/Misc/NEWS.d/next/Library/2024-05-25-00-54-26.gh-issue-119127.LpPvag.rst b/Misc/NEWS.d/next/Library/2024-05-25-00-54-26.gh-issue-119127.LpPvag.rst deleted file mode 100644 index e47e2ae89dbff0..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-25-00-54-26.gh-issue-119127.LpPvag.rst +++ /dev/null @@ -1,2 +0,0 @@ -Positional arguments of :func:`functools.partial` objects -now support placeholders via :data:`functools.Placeholder`. diff --git a/Misc/NEWS.d/next/Library/2024-05-25-07-25-07.gh-issue-117865.1A0Xpi.rst b/Misc/NEWS.d/next/Library/2024-05-25-07-25-07.gh-issue-117865.1A0Xpi.rst deleted file mode 100644 index 48cd390d1bb128..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-25-07-25-07.gh-issue-117865.1A0Xpi.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve the import time of the :mod:`ast` module by deferring the import of -:mod:`re`. Patch by Jelle Zijlstra. diff --git a/Misc/NEWS.d/next/Library/2024-05-25-10-40-38.gh-issue-118908.XcZiq4.rst b/Misc/NEWS.d/next/Library/2024-05-25-10-40-38.gh-issue-118908.XcZiq4.rst deleted file mode 100644 index bf58d7277fcd51..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-25-10-40-38.gh-issue-118908.XcZiq4.rst +++ /dev/null @@ -1,2 +0,0 @@ -Limit exposed globals from internal imports and definitions on new REPL -startup. Patch by Eugene Triguba and Pablo Galindo. diff --git a/Misc/NEWS.d/next/Library/2024-05-25-20-15-26.gh-issue-119555.mvHbEL.rst b/Misc/NEWS.d/next/Library/2024-05-25-20-15-26.gh-issue-119555.mvHbEL.rst deleted file mode 100644 index e16cb28b471a7a..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-25-20-15-26.gh-issue-119555.mvHbEL.rst +++ /dev/null @@ -1,2 +0,0 @@ -Catch :exc:`SyntaxError` from :func:`compile` in the runsource() method of -the InteractiveColoredConsole. Patch by Sergey B Kirpichev. diff --git a/Misc/NEWS.d/next/Library/2024-05-25-20-20-42.gh-issue-119562.DyplWc.rst b/Misc/NEWS.d/next/Library/2024-05-25-20-20-42.gh-issue-119562.DyplWc.rst deleted file mode 100644 index dd23466b9d2cef..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-25-20-20-42.gh-issue-119562.DyplWc.rst +++ /dev/null @@ -1,3 +0,0 @@ -Remove :class:`!ast.Num`, :class:`!ast.Str`, :class:`!ast.Bytes`, -:class:`!ast.NameConstant` and :class:`!ast.Ellipsis`. They had all emitted -deprecation warnings since Python 3.12. Patch by Alex Waygood. diff --git a/Misc/NEWS.d/next/Library/2024-05-26-21-28-11.gh-issue-119588.wlLBK5.rst b/Misc/NEWS.d/next/Library/2024-05-26-21-28-11.gh-issue-119588.wlLBK5.rst deleted file mode 100644 index 01321d8bfe2ad5..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-26-21-28-11.gh-issue-119588.wlLBK5.rst +++ /dev/null @@ -1 +0,0 @@ -``zipfile.Path.is_symlink`` now assesses if the given path is a symlink. diff --git a/Misc/NEWS.d/next/Library/2024-05-26-22-22-51.gh-issue-119594.fnQNM8.rst b/Misc/NEWS.d/next/Library/2024-05-26-22-22-51.gh-issue-119594.fnQNM8.rst deleted file mode 100644 index d2de5273edf571..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-26-22-22-51.gh-issue-119594.fnQNM8.rst +++ /dev/null @@ -1 +0,0 @@ -If one calls pow(fractions.Fraction, x, module) with modulo not None, the error message now says that the types are incompatible rather than saying pow only takes 2 arguments. Patch by Wim Jeantine-Glenn and Mark Dickinson. diff --git a/Misc/NEWS.d/next/Library/2024-05-28-00-56-59.gh-issue-89727._bxoL3.rst b/Misc/NEWS.d/next/Library/2024-05-28-00-56-59.gh-issue-89727._bxoL3.rst deleted file mode 100644 index 92222bc673350f..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-28-00-56-59.gh-issue-89727._bxoL3.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix issue with :func:`os.fwalk` where a :exc:`RecursionError` was raised on -deep directory trees by adjusting the implementation to be iterative instead -of recursive. diff --git a/Misc/NEWS.d/next/Library/2024-05-28-12-15-03.gh-issue-119118.FMKz1F.rst b/Misc/NEWS.d/next/Library/2024-05-28-12-15-03.gh-issue-119118.FMKz1F.rst deleted file mode 100644 index 3cf61662fe7767..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-28-12-15-03.gh-issue-119118.FMKz1F.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix performance regression in the :mod:`tokenize` module by caching the ``line`` -token attribute and calculating the column offset more efficiently. diff --git a/Misc/NEWS.d/next/Library/2024-05-29-12-42-40.gh-issue-93963.cb1oJS.rst b/Misc/NEWS.d/next/Library/2024-05-29-12-42-40.gh-issue-93963.cb1oJS.rst deleted file mode 100644 index d093c8e35a5994..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-29-12-42-40.gh-issue-93963.cb1oJS.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove deprecated names from ``importlib.abc`` as found in -``importlib.resources.abc``. diff --git a/Misc/NEWS.d/next/Library/2024-05-29-20-42-17.gh-issue-89727.5lPTTW.rst b/Misc/NEWS.d/next/Library/2024-05-29-20-42-17.gh-issue-89727.5lPTTW.rst deleted file mode 100644 index 3b73d2789fd6f9..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-29-20-42-17.gh-issue-89727.5lPTTW.rst +++ /dev/null @@ -1,3 +0,0 @@ -Partially fix issue with :func:`shutil.rmtree` where a :exc:`RecursionError` -is raised on deep directory trees. A recursion error is no longer raised -when :data:`!rmtree.avoids_symlink_attacks` is false. diff --git a/Misc/NEWS.d/next/Library/2024-05-29-21-50-05.gh-issue-119577.S3BlKJ.rst b/Misc/NEWS.d/next/Library/2024-05-29-21-50-05.gh-issue-119577.S3BlKJ.rst deleted file mode 100644 index bd2daf3fb5c16d..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-29-21-50-05.gh-issue-119577.S3BlKJ.rst +++ /dev/null @@ -1,4 +0,0 @@ -The :exc:`DeprecationWarning` emitted when testing the truth value of an -:class:`xml.etree.ElementTree.Element` now describes unconditionally -returning ``True`` in a future version rather than raising an exception in -Python 3.14. diff --git a/Misc/NEWS.d/next/Library/2024-05-30-21-37-05.gh-issue-89727.D6S9ig.rst b/Misc/NEWS.d/next/Library/2024-05-30-21-37-05.gh-issue-89727.D6S9ig.rst deleted file mode 100644 index 854c56609acb8c..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-30-21-37-05.gh-issue-89727.D6S9ig.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix issue with :func:`shutil.rmtree` where a :exc:`RecursionError` is raised -on deep directory trees. diff --git a/Misc/NEWS.d/next/Library/2024-05-31-12-57-31.gh-issue-119770.NCtels.rst b/Misc/NEWS.d/next/Library/2024-05-31-12-57-31.gh-issue-119770.NCtels.rst deleted file mode 100644 index 94265e442db584..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-31-12-57-31.gh-issue-119770.NCtels.rst +++ /dev/null @@ -1 +0,0 @@ -Make :mod:`termios` ``ioctl()`` constants positive. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2024-05-31-13-56-21.gh-issue-119838.H6XHlE.rst b/Misc/NEWS.d/next/Library/2024-05-31-13-56-21.gh-issue-119838.H6XHlE.rst deleted file mode 100644 index 17a87327b5b1d6..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-31-13-56-21.gh-issue-119838.H6XHlE.rst +++ /dev/null @@ -1,3 +0,0 @@ -In mixed arithmetic operations with :class:`~fractions.Fraction` and -complex, the fraction is now converted to :class:`float` instead of -:class:`complex`. diff --git a/Misc/NEWS.d/next/Library/2024-05-31-21-17-43.gh-issue-119824.CQlxWV.rst b/Misc/NEWS.d/next/Library/2024-05-31-21-17-43.gh-issue-119824.CQlxWV.rst deleted file mode 100644 index fd6d8d79a9d157..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-31-21-17-43.gh-issue-119824.CQlxWV.rst +++ /dev/null @@ -1 +0,0 @@ -Print stack entry in :mod:`pdb` when and only when user input is needed. diff --git a/Misc/NEWS.d/next/Library/2024-06-01-16-58-43.gh-issue-117398.kR0RW7.rst b/Misc/NEWS.d/next/Library/2024-06-01-16-58-43.gh-issue-117398.kR0RW7.rst deleted file mode 100644 index b0fe06663248f6..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-01-16-58-43.gh-issue-117398.kR0RW7.rst +++ /dev/null @@ -1,2 +0,0 @@ -The ``_datetime`` module (C implementation for :mod:`datetime`) now supports -being imported in multiple interpreters. diff --git a/Misc/NEWS.d/next/Library/2024-06-02-13-35-11.gh-issue-81936.ETeW9x.rst b/Misc/NEWS.d/next/Library/2024-06-02-13-35-11.gh-issue-81936.ETeW9x.rst deleted file mode 100644 index d53cc73e728d54..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-02-13-35-11.gh-issue-81936.ETeW9x.rst +++ /dev/null @@ -1,3 +0,0 @@ -:meth:`!help` and :meth:`!showtopic` methods now respect a -configured *output* argument to :class:`!pydoc.Helper` and not use the -pager in such cases. Patch by Enrico Tröger. diff --git a/Misc/NEWS.d/next/Library/2024-06-02-15-09-17.gh-issue-118835.KUAuz6.rst b/Misc/NEWS.d/next/Library/2024-06-02-15-09-17.gh-issue-118835.KUAuz6.rst deleted file mode 100644 index ec9ca20a487d76..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-02-15-09-17.gh-issue-118835.KUAuz6.rst +++ /dev/null @@ -1 +0,0 @@ -Fix _pyrepl crash when using custom prompt with ANSI escape codes. diff --git a/Misc/NEWS.d/next/Library/2024-06-03-11-18-16.gh-issue-117142.kWTXQo.rst b/Misc/NEWS.d/next/Library/2024-06-03-11-18-16.gh-issue-117142.kWTXQo.rst deleted file mode 100644 index 80734ef3946300..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-03-11-18-16.gh-issue-117142.kWTXQo.rst +++ /dev/null @@ -1,2 +0,0 @@ -The :mod:`ctypes` module may now be imported in all subinterpreters, including -those that have their own GIL. diff --git a/Misc/NEWS.d/next/Library/2024-06-04-08-57-02.gh-issue-65454.o9j4wF.rst b/Misc/NEWS.d/next/Library/2024-06-04-08-57-02.gh-issue-65454.o9j4wF.rst deleted file mode 100644 index 0b232cf8ca1baf..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-04-08-57-02.gh-issue-65454.o9j4wF.rst +++ /dev/null @@ -1 +0,0 @@ -:func:`unittest.mock.Mock.attach_mock` no longer triggers a call to a ``PropertyMock`` being attached. diff --git a/Misc/NEWS.d/next/Library/2024-06-04-12-23-01.gh-issue-119819.WKKrYh.rst b/Misc/NEWS.d/next/Library/2024-06-04-12-23-01.gh-issue-119819.WKKrYh.rst deleted file mode 100644 index f9e49c00f671f2..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-04-12-23-01.gh-issue-119819.WKKrYh.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix regression to allow logging configuration with multiprocessing queue -types. diff --git a/Misc/NEWS.d/next/Library/2024-06-04-14-54-46.gh-issue-120029._1YdTf.rst b/Misc/NEWS.d/next/Library/2024-06-04-14-54-46.gh-issue-120029._1YdTf.rst deleted file mode 100644 index e8ea1077139f71..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-04-14-54-46.gh-issue-120029._1YdTf.rst +++ /dev/null @@ -1,2 +0,0 @@ -Expose :meth:`symtable.Symbol.is_type_parameter` in the :mod:`symtable` -module. Patch by Bénédikt Tran. diff --git a/Misc/NEWS.d/next/Library/2024-06-04-18-53-10.gh-issue-120057.RSD9_Z.rst b/Misc/NEWS.d/next/Library/2024-06-04-18-53-10.gh-issue-120057.RSD9_Z.rst deleted file mode 100644 index 955be59821ee0c..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-04-18-53-10.gh-issue-120057.RSD9_Z.rst +++ /dev/null @@ -1,4 +0,0 @@ -Added the :data:`os.environ.refresh() ` method to update -:data:`os.environ` with changes to the environment made by :func:`os.putenv`, -by :func:`os.unsetenv`, or made outside Python in the same process. -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2024-06-04-19-03-25.gh-issue-112672.K2XfZH.rst b/Misc/NEWS.d/next/Library/2024-06-04-19-03-25.gh-issue-112672.K2XfZH.rst deleted file mode 100644 index 46345bff117b19..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-04-19-03-25.gh-issue-112672.K2XfZH.rst +++ /dev/null @@ -1 +0,0 @@ -Support building :mod:`tkinter` with Tcl 9.0. diff --git a/Misc/NEWS.d/next/Library/2024-06-04-19-49-16.gh-issue-120056.5aqozw.rst b/Misc/NEWS.d/next/Library/2024-06-04-19-49-16.gh-issue-120056.5aqozw.rst deleted file mode 100644 index 0adb70f51e8a0c..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-04-19-49-16.gh-issue-120056.5aqozw.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add :data:`!socket.IP_RECVERR` and :data:`!socket.IP_RECVTTL` constants -(both available since Linux 2.2). -And :data:`!socket.IP_RECVORIGDSTADDR` constant (available since Linux 2.6.29). diff --git a/Misc/NEWS.d/next/Library/2024-06-05-08-02-46.gh-issue-120108.4U9BL8.rst b/Misc/NEWS.d/next/Library/2024-06-05-08-02-46.gh-issue-120108.4U9BL8.rst deleted file mode 100644 index e310695656255d..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-05-08-02-46.gh-issue-120108.4U9BL8.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix calling :func:`copy.deepcopy` on :mod:`ast` trees that have been -modified to have references to parent nodes. Patch by Jelle Zijlstra. diff --git a/Misc/NEWS.d/next/Library/2024-06-05-11-03-10.gh-issue-120029.QBsw47.rst b/Misc/NEWS.d/next/Library/2024-06-05-11-03-10.gh-issue-120029.QBsw47.rst deleted file mode 100644 index d1b2c592a113ce..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-05-11-03-10.gh-issue-120029.QBsw47.rst +++ /dev/null @@ -1,4 +0,0 @@ -Expose :class:`symtable.Symbol` methods :meth:`~symtable.Symbol.is_free_class`, -:meth:`~symtable.Symbol.is_comp_iter` and :meth:`~symtable.Symbol.is_comp_cell`. -Patch by Bénédikt Tran. - diff --git a/Misc/NEWS.d/next/Library/2024-06-05-11-39-21.gh-issue-119933.ooJXQV.rst b/Misc/NEWS.d/next/Library/2024-06-05-11-39-21.gh-issue-119933.ooJXQV.rst deleted file mode 100644 index 475da88914bde3..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-05-11-39-21.gh-issue-119933.ooJXQV.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add the :class:`symtable.SymbolTableType` enumeration to represent the -possible outputs of the :class:`symtable.SymbolTable.get_type` method. Patch -by Bénédikt Tran. diff --git a/Misc/NEWS.d/next/Library/2024-06-05-16-30-28.gh-issue-120121.9dz8i7.rst b/Misc/NEWS.d/next/Library/2024-06-05-16-30-28.gh-issue-120121.9dz8i7.rst deleted file mode 100644 index 4f3526477c8cce..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-05-16-30-28.gh-issue-120121.9dz8i7.rst +++ /dev/null @@ -1 +0,0 @@ -Add :exc:`concurrent.futures.InvalidStateError` to module's ``__all__``. diff --git a/Misc/NEWS.d/next/Library/2024-06-06-12-07-57.gh-issue-119698.rRrprk.rst b/Misc/NEWS.d/next/Library/2024-06-06-12-07-57.gh-issue-119698.rRrprk.rst deleted file mode 100644 index d4cca1439816b0..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-06-12-07-57.gh-issue-119698.rRrprk.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix :meth:`symtable.Class.get_methods` and document its behaviour. Patch by -Bénédikt Tran. diff --git a/Misc/NEWS.d/next/Library/2024-06-06-17-24-43.gh-issue-120161.DahNXV.rst b/Misc/NEWS.d/next/Library/2024-06-06-17-24-43.gh-issue-120161.DahNXV.rst deleted file mode 100644 index c378cac44c97bf..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-06-17-24-43.gh-issue-120161.DahNXV.rst +++ /dev/null @@ -1,2 +0,0 @@ -:mod:`datetime` no longer crashes in certain complex reference cycle -situations. diff --git a/Misc/NEWS.d/next/Library/2024-06-07-02-00-31.gh-issue-120157.HnWcF9.rst b/Misc/NEWS.d/next/Library/2024-06-07-02-00-31.gh-issue-120157.HnWcF9.rst deleted file mode 100644 index 3e905125797af7..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-07-02-00-31.gh-issue-120157.HnWcF9.rst +++ /dev/null @@ -1 +0,0 @@ -Remove unused constant ``concurrent.futures._base._FUTURE_STATES`` in :mod:`concurrent.futures`. Patch by Clinton Christian (pygeek). diff --git a/Misc/NEWS.d/next/Library/2024-06-07-10-10-32.gh-issue-117983.NeMR9n.rst b/Misc/NEWS.d/next/Library/2024-06-07-10-10-32.gh-issue-117983.NeMR9n.rst deleted file mode 100644 index cca97f50a20496..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-07-10-10-32.gh-issue-117983.NeMR9n.rst +++ /dev/null @@ -1,2 +0,0 @@ -Defer the ``threading`` import in ``importlib.util`` until lazy loading is -used. diff --git a/Misc/NEWS.d/next/Library/2024-06-07-11-23-31.gh-issue-71587.IjFajE.rst b/Misc/NEWS.d/next/Library/2024-06-07-11-23-31.gh-issue-71587.IjFajE.rst deleted file mode 100644 index 50a662977993f5..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-07-11-23-31.gh-issue-71587.IjFajE.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix crash in C version of :meth:`datetime.datetime.strptime` when called again -on the restarted interpreter. diff --git a/Misc/NEWS.d/next/Library/2024-06-07-13-21-11.gh-issue-120211.Rws_gf.rst b/Misc/NEWS.d/next/Library/2024-06-07-13-21-11.gh-issue-120211.Rws_gf.rst deleted file mode 100644 index 0106f2d93318b4..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-07-13-21-11.gh-issue-120211.Rws_gf.rst +++ /dev/null @@ -1 +0,0 @@ -Fix :mod:`tkinter.ttk` with Tcl/Tk 9.0. diff --git a/Misc/NEWS.d/next/Library/2024-06-08-03-29-01.gh-issue-120254.h682ke.rst b/Misc/NEWS.d/next/Library/2024-06-08-03-29-01.gh-issue-120254.h682ke.rst deleted file mode 100644 index 33ef1c91591c54..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-08-03-29-01.gh-issue-120254.h682ke.rst +++ /dev/null @@ -1 +0,0 @@ -Added ``commands`` argument to :func:`pdb.set_trace` which allows users to send debugger commands from the source file. diff --git a/Misc/NEWS.d/next/Library/2024-06-08-09-45-31.gh-issue-120244.8o9Dzr.rst b/Misc/NEWS.d/next/Library/2024-06-08-09-45-31.gh-issue-120244.8o9Dzr.rst deleted file mode 100644 index 2354a9afac4bc2..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-08-09-45-31.gh-issue-120244.8o9Dzr.rst +++ /dev/null @@ -1 +0,0 @@ -Fix memory leak in :func:`re.sub` when the replacement string contains backreferences. diff --git a/Misc/NEWS.d/next/Library/2024-06-08-14-36-40.gh-issue-120268.MNpd1q.rst b/Misc/NEWS.d/next/Library/2024-06-08-14-36-40.gh-issue-120268.MNpd1q.rst deleted file mode 100644 index d48d43cd047f7a..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-08-14-36-40.gh-issue-120268.MNpd1q.rst +++ /dev/null @@ -1,2 +0,0 @@ -Prohibit passing ``None`` to pure-Python :meth:`datetime.date.fromtimestamp` -to achieve consistency with C-extension implementation. diff --git a/Misc/NEWS.d/next/Library/2024-06-08-15-15-29.gh-issue-114053.WQLAFG.rst b/Misc/NEWS.d/next/Library/2024-06-08-15-15-29.gh-issue-114053.WQLAFG.rst deleted file mode 100644 index be49577a712867..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-08-15-15-29.gh-issue-114053.WQLAFG.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fix erroneous :exc:`NameError` when calling :func:`inspect.get_annotations` -with ``eval_str=True``` on a class that made use of :pep:`695` type -parameters in a module that had ``from __future__ import annotations`` at -the top of the file. Patch by Alex Waygood. diff --git a/Misc/NEWS.d/next/Library/2024-06-08-15-46-35.gh-issue-114053.Ub2XgJ.rst b/Misc/NEWS.d/next/Library/2024-06-08-15-46-35.gh-issue-114053.Ub2XgJ.rst deleted file mode 100644 index 8aea591da5274c..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-08-15-46-35.gh-issue-114053.Ub2XgJ.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fix edge-case bug where :func:`typing.get_type_hints` would produce -incorrect results if type parameters in a class scope were overridden by -assignments in a class scope and ``from __future__ import annotations`` -semantics were enabled. Patch by Alex Waygood. diff --git a/Misc/NEWS.d/next/Library/2024-06-08-17-41-11.gh-issue-82017.WpSTGi.rst b/Misc/NEWS.d/next/Library/2024-06-08-17-41-11.gh-issue-82017.WpSTGi.rst deleted file mode 100644 index 7decee7ff3384e..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-08-17-41-11.gh-issue-82017.WpSTGi.rst +++ /dev/null @@ -1,2 +0,0 @@ -Added support for converting any objects that have the -:meth:`!as_integer_ratio` method to a :class:`~fractions.Fraction`. diff --git a/Misc/NEWS.d/next/Library/2024-06-09-19-53-11.gh-issue-120289.s4HXR0.rst b/Misc/NEWS.d/next/Library/2024-06-09-19-53-11.gh-issue-120289.s4HXR0.rst deleted file mode 100644 index 518f79dc446ae7..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-09-19-53-11.gh-issue-120289.s4HXR0.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed the use-after-free issue in :mod:`cProfile` by disallowing -``disable()`` and ``clear()`` in external timers. diff --git a/Misc/NEWS.d/next/Library/2024-06-10-14-00-40.gh-issue-119600.jJMf4C.rst b/Misc/NEWS.d/next/Library/2024-06-10-14-00-40.gh-issue-119600.jJMf4C.rst deleted file mode 100644 index 04c9ca9c3fd737..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-10-14-00-40.gh-issue-119600.jJMf4C.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix :func:`unittest.mock.patch` to not read attributes of the target when -``new_callable`` is set. Patch by Robert Collins. diff --git a/Misc/NEWS.d/next/Library/2024-06-11-07-17-25.gh-issue-119180.iH-2zy.rst b/Misc/NEWS.d/next/Library/2024-06-11-07-17-25.gh-issue-119180.iH-2zy.rst deleted file mode 100644 index f24d7bd6b9d26c..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-11-07-17-25.gh-issue-119180.iH-2zy.rst +++ /dev/null @@ -1,4 +0,0 @@ -As part of implementing :pep:`649` and :pep:`749`, add a new module -``annotationlib``. Add support for unresolved forward references in -annotations to :mod:`dataclasses`, :class:`typing.TypedDict`, and -:class:`typing.NamedTuple`. diff --git a/Misc/NEWS.d/next/Library/2024-06-11-16-34-41.gh-issue-120343.hdiXeU.rst b/Misc/NEWS.d/next/Library/2024-06-11-16-34-41.gh-issue-120343.hdiXeU.rst deleted file mode 100644 index 76714b0c394eef..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-11-16-34-41.gh-issue-120343.hdiXeU.rst +++ /dev/null @@ -1 +0,0 @@ -Fix column offset reporting for tokens that come after multiline f-strings in the :mod:`tokenize` module. diff --git a/Misc/NEWS.d/next/Library/2024-06-12-10-00-31.gh-issue-90425.5CfkKG.rst b/Misc/NEWS.d/next/Library/2024-06-12-10-00-31.gh-issue-90425.5CfkKG.rst deleted file mode 100644 index d152af49287a0b..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-12-10-00-31.gh-issue-90425.5CfkKG.rst +++ /dev/null @@ -1,2 +0,0 @@ -The OS byte in gzip headers is now always set to 255 when using -:func:`gzip.compress`. diff --git a/Misc/NEWS.d/next/Library/2024-06-12-11-54-05.gh-issue-120381.O-BNLs.rst b/Misc/NEWS.d/next/Library/2024-06-12-11-54-05.gh-issue-120381.O-BNLs.rst deleted file mode 100644 index 44f49bc19a4c99..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-12-11-54-05.gh-issue-120381.O-BNLs.rst +++ /dev/null @@ -1,2 +0,0 @@ -Correct :func:`inspect.ismethoddescriptor` to check also for the lack of -:meth:`~object.__delete__`. Patch by Jan Kaliszewski. diff --git a/Misc/NEWS.d/next/Library/2024-06-12-15-07-58.gh-issue-120388.VuTQMT.rst b/Misc/NEWS.d/next/Library/2024-06-12-15-07-58.gh-issue-120388.VuTQMT.rst deleted file mode 100644 index d13df7d88b776c..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-12-15-07-58.gh-issue-120388.VuTQMT.rst +++ /dev/null @@ -1,3 +0,0 @@ -Improve a warning message when a test method in :mod:`unittest` returns -something other than ``None``. Now we show the returned object type and -optional asyncio-related tip. diff --git a/Misc/NEWS.d/next/Library/2024-06-14-20-05-25.gh-issue-120495.OxgZKB.rst b/Misc/NEWS.d/next/Library/2024-06-14-20-05-25.gh-issue-120495.OxgZKB.rst deleted file mode 100644 index d5114c3d3c904c..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-14-20-05-25.gh-issue-120495.OxgZKB.rst +++ /dev/null @@ -1 +0,0 @@ -Fix incorrect exception handling in Tab Nanny. Patch by Wulian233. diff --git a/Misc/NEWS.d/next/Library/2024-06-15-12-04-46.gh-issue-120541.d3cc5y.rst b/Misc/NEWS.d/next/Library/2024-06-15-12-04-46.gh-issue-120541.d3cc5y.rst deleted file mode 100644 index bf8830c6c50386..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-15-12-04-46.gh-issue-120541.d3cc5y.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve the prompt in the "less" pager when :func:`help` is called with -non-string argument. diff --git a/Misc/NEWS.d/next/Library/2024-06-15-23-38-36.gh-issue-120284.HwsAtY.rst b/Misc/NEWS.d/next/Library/2024-06-15-23-38-36.gh-issue-120284.HwsAtY.rst deleted file mode 100644 index a2a6883c3d7686..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-15-23-38-36.gh-issue-120284.HwsAtY.rst +++ /dev/null @@ -1,2 +0,0 @@ -Allow :meth:`asyncio.Runner.run` to accept :term:`awaitable` -objects instead of simply :term:`coroutine`\s. diff --git a/Misc/NEWS.d/next/Library/2024-06-16-21-33-56.gh-issue-120606.kugbwR.rst b/Misc/NEWS.d/next/Library/2024-06-16-21-33-56.gh-issue-120606.kugbwR.rst deleted file mode 100644 index 874823ea3486fb..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-16-21-33-56.gh-issue-120606.kugbwR.rst +++ /dev/null @@ -1 +0,0 @@ -Allow users to use EOF to exit ``commands`` definition in :mod:`pdb` diff --git a/Misc/NEWS.d/next/Library/2024-06-17-20-04-13.gh-issue-120633.kZC5wt.rst b/Misc/NEWS.d/next/Library/2024-06-17-20-04-13.gh-issue-120633.kZC5wt.rst deleted file mode 100644 index 9b396988205589..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-17-20-04-13.gh-issue-120633.kZC5wt.rst +++ /dev/null @@ -1 +0,0 @@ -Move scrollbar and remove tear-off menus in turtledemo. diff --git a/Misc/NEWS.d/next/Library/2024-06-18-14-45-38.gh-issue-118710.5GZZPX.rst b/Misc/NEWS.d/next/Library/2024-06-18-14-45-38.gh-issue-118710.5GZZPX.rst deleted file mode 100644 index a02d286bcecd7f..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-18-14-45-38.gh-issue-118710.5GZZPX.rst +++ /dev/null @@ -1 +0,0 @@ -:class:`ipaddress.IPv4Address` and :class:`ipaddress.IPv6Address` attributes ``version`` and ``max_prefixlen`` are now available on the class. diff --git a/Misc/NEWS.d/next/Library/2024-06-18-19-18-10.gh-issue-120683.xmRez7.rst b/Misc/NEWS.d/next/Library/2024-06-18-19-18-10.gh-issue-120683.xmRez7.rst deleted file mode 100644 index 50fc9279e4bad1..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-18-19-18-10.gh-issue-120683.xmRez7.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fix an error in :class:`logging.LogRecord`, when the integer part of the -timestamp is rounded up, while the millisecond calculation truncates, -causing the log timestamp to be wrong by up to 999 ms (affected roughly 1 in -8 million timestamps). diff --git a/Misc/NEWS.d/next/Library/2024-06-19-13-20-01.gh-issue-111259.Wki5PV.rst b/Misc/NEWS.d/next/Library/2024-06-19-13-20-01.gh-issue-111259.Wki5PV.rst deleted file mode 100644 index 91ed5f550e400f..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-19-13-20-01.gh-issue-111259.Wki5PV.rst +++ /dev/null @@ -1,3 +0,0 @@ -:mod:`re` now handles patterns like ``"[\s\S]"`` or ``"\s|\S"`` which match -any character as effectively as a dot with the ``DOTALL`` modifier -(``"(?s:.)"``). diff --git a/Misc/NEWS.d/next/Library/2024-06-19-15-06-58.gh-issue-120732.OvYV9b.rst b/Misc/NEWS.d/next/Library/2024-06-19-15-06-58.gh-issue-120732.OvYV9b.rst deleted file mode 100644 index e31c4dd3192d60..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-19-15-06-58.gh-issue-120732.OvYV9b.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix ``name`` passing to :class:`unittest.mock.Mock` object when using -:func:`unittest.mock.create_autospec`. diff --git a/Misc/NEWS.d/next/Library/2024-06-19-15-43-04.gh-issue-120743.CMMl2P.rst b/Misc/NEWS.d/next/Library/2024-06-19-15-43-04.gh-issue-120743.CMMl2P.rst deleted file mode 100644 index e06dcf8af26a60..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-19-15-43-04.gh-issue-120743.CMMl2P.rst +++ /dev/null @@ -1,3 +0,0 @@ -:term:`Soft deprecate ` :func:`os.popen` and :func:`os.spawn* -` functions. They should no longer be used to write new code. The -:mod:`subprocess` module is recommended instead. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2024-06-19-19-53-42.gh-issue-41431.gnkUc5.rst b/Misc/NEWS.d/next/Library/2024-06-19-19-53-42.gh-issue-41431.gnkUc5.rst deleted file mode 100644 index 18e3506a60c455..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-19-19-53-42.gh-issue-41431.gnkUc5.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add :meth:`datetime.time.strptime` and :meth:`datetime.date.strptime`. -Contributed by Wannes Boeykens. diff --git a/Misc/NEWS.d/next/Library/2024-06-19-23-08-25.gh-issue-120780.0Omopb.rst b/Misc/NEWS.d/next/Library/2024-06-19-23-08-25.gh-issue-120780.0Omopb.rst deleted file mode 100644 index df3cfbcdbd2e29..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-19-23-08-25.gh-issue-120780.0Omopb.rst +++ /dev/null @@ -1 +0,0 @@ -Show string value of LOAD_SPECIAL oparg in :mod:`dis` output. diff --git a/Misc/NEWS.d/next/Library/2024-06-20-01-31-24.gh-issue-120769.PfiMrc.rst b/Misc/NEWS.d/next/Library/2024-06-20-01-31-24.gh-issue-120769.PfiMrc.rst deleted file mode 100644 index 8ee6bf1a9c6480..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-20-01-31-24.gh-issue-120769.PfiMrc.rst +++ /dev/null @@ -1 +0,0 @@ -Make empty line in :mod:`pdb` repeats the last command even when the command is from ``cmdqueue``. diff --git a/Misc/NEWS.d/next/Library/2024-06-21-06-37-46.gh-issue-120713.WBbQx4.rst b/Misc/NEWS.d/next/Library/2024-06-21-06-37-46.gh-issue-120713.WBbQx4.rst deleted file mode 100644 index 18386a43eddc6f..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-21-06-37-46.gh-issue-120713.WBbQx4.rst +++ /dev/null @@ -1,2 +0,0 @@ -:meth:`datetime.datetime.strftime` now 0-pads years with less than four digits for the format specifiers ``%Y`` and ``%G`` on Linux. -Patch by Ben Hsing diff --git a/Misc/NEWS.d/next/Library/2024-06-21-12-00-16.gh-issue-120782.LOE8tj.rst b/Misc/NEWS.d/next/Library/2024-06-21-12-00-16.gh-issue-120782.LOE8tj.rst deleted file mode 100644 index 02acbd2873009b..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-21-12-00-16.gh-issue-120782.LOE8tj.rst +++ /dev/null @@ -1 +0,0 @@ -Fix wrong references of the :mod:`datetime` types after reloading the module. diff --git a/Misc/NEWS.d/next/Library/2024-06-21-14-32-56.gh-issue-120811.eBmVTV.rst b/Misc/NEWS.d/next/Library/2024-06-21-14-32-56.gh-issue-120811.eBmVTV.rst deleted file mode 100644 index 62cd7b5620474a..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-21-14-32-56.gh-issue-120811.eBmVTV.rst +++ /dev/null @@ -1 +0,0 @@ -Fix possible memory leak in :meth:`contextvars.Context.run`. diff --git a/Misc/NEWS.d/next/Library/2024-06-22-17-01-56.gh-issue-120678.Ik8dCg.rst b/Misc/NEWS.d/next/Library/2024-06-22-17-01-56.gh-issue-120678.Ik8dCg.rst deleted file mode 100644 index ef0d3e3299e2e9..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-22-17-01-56.gh-issue-120678.Ik8dCg.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix regression in the new REPL that meant that globals from files passed -using the ``-i`` argument would not be included in the REPL's global -namespace. Patch by Alex Waygood. diff --git a/Misc/NEWS.d/next/Library/2024-06-22-22-23-56.gh-issue-101830.1BAoxH.rst b/Misc/NEWS.d/next/Library/2024-06-22-22-23-56.gh-issue-101830.1BAoxH.rst deleted file mode 100644 index 46c18b040f30d7..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-22-22-23-56.gh-issue-101830.1BAoxH.rst +++ /dev/null @@ -1,2 +0,0 @@ -Accessing the :mod:`tkinter` object's string representation no longer converts -the underlying Tcl object to a string on Windows. diff --git a/Misc/NEWS.d/next/Library/2024-06-22-22-52-24.gh-issue-120888.sd8I3N.rst b/Misc/NEWS.d/next/Library/2024-06-22-22-52-24.gh-issue-120888.sd8I3N.rst deleted file mode 100644 index c733ff5159aa40..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-22-22-52-24.gh-issue-120888.sd8I3N.rst +++ /dev/null @@ -1 +0,0 @@ -Upgrade pip wheel bundled with ensurepip (pip 24.1.1) diff --git a/Misc/NEWS.d/next/Library/2024-06-23-07-23-08.gh-issue-61103.ca_U_l.rst b/Misc/NEWS.d/next/Library/2024-06-23-07-23-08.gh-issue-61103.ca_U_l.rst deleted file mode 100644 index 890eb62010eb33..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-23-07-23-08.gh-issue-61103.ca_U_l.rst +++ /dev/null @@ -1,5 +0,0 @@ -Support :c:expr:`float complex`, :c:expr:`double complex` and -:c:expr:`long double complex` C types in :mod:`ctypes` as -:class:`~ctypes.c_float_complex`, :class:`~ctypes.c_double_complex` and -:class:`~ctypes.c_longdouble_complex` if the compiler has C11 complex arithmetic. -Patch by Sergey B Kirpichev. diff --git a/Misc/NEWS.d/next/Library/2024-06-23-11-21-27.gh-issue-120910.t0QXdB.rst b/Misc/NEWS.d/next/Library/2024-06-23-11-21-27.gh-issue-120910.t0QXdB.rst deleted file mode 100644 index 3773cdc6ee3bf3..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-23-11-21-27.gh-issue-120910.t0QXdB.rst +++ /dev/null @@ -1,2 +0,0 @@ -When reading installed files from an egg, use ``relative_to(walk_up=True)`` -to honor files installed outside of the installation root. diff --git a/Misc/NEWS.d/next/Library/2024-06-23-17-50-40.gh-issue-119614.vwPGLB.rst b/Misc/NEWS.d/next/Library/2024-06-23-17-50-40.gh-issue-119614.vwPGLB.rst deleted file mode 100644 index d518265a7fe55a..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-23-17-50-40.gh-issue-119614.vwPGLB.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix truncation of strings with embedded null characters in some internal -operations in :mod:`tkinter`. diff --git a/Misc/NEWS.d/next/Library/2024-06-26-03-04-24.gh-issue-121018.clVSc4.rst b/Misc/NEWS.d/next/Library/2024-06-26-03-04-24.gh-issue-121018.clVSc4.rst deleted file mode 100644 index 346a89879cad41..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-26-03-04-24.gh-issue-121018.clVSc4.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fixed issues where :meth:`!argparse.ArgumentParser.parse_args` did not honor -``exit_on_error=False``. -Based on patch by Ben Hsing. diff --git a/Misc/NEWS.d/next/Library/2024-06-26-10-13-40.gh-issue-121025.M-XXlV.rst b/Misc/NEWS.d/next/Library/2024-06-26-10-13-40.gh-issue-121025.M-XXlV.rst deleted file mode 100644 index 38cad610396787..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-26-10-13-40.gh-issue-121025.M-XXlV.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve the :meth:`~object.__repr__` of :class:`functools.partialmethod`. -Patch by Bénédikt Tran. diff --git a/Misc/NEWS.d/next/Library/2024-06-26-17-00-39.gh-issue-117784.inCtAV.rst b/Misc/NEWS.d/next/Library/2024-06-26-17-00-39.gh-issue-117784.inCtAV.rst deleted file mode 100644 index 3f576eebc9a85d..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-26-17-00-39.gh-issue-117784.inCtAV.rst +++ /dev/null @@ -1 +0,0 @@ -CPython now detects whether its linked TLS library supports TLSv1.3 post-handshake authentication and disables that feature if support is lacking. diff --git a/Misc/NEWS.d/next/Library/2024-06-27-12-27-52.gh-issue-121027.D4K1OX.rst b/Misc/NEWS.d/next/Library/2024-06-27-12-27-52.gh-issue-121027.D4K1OX.rst deleted file mode 100644 index a450726d9afed9..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-27-12-27-52.gh-issue-121027.D4K1OX.rst +++ /dev/null @@ -1 +0,0 @@ -Make the :class:`functools.partial` object a method descriptor. diff --git a/Misc/NEWS.d/next/Library/2024-06-27-13-47-14.gh-issue-121027.jh55EC.rst b/Misc/NEWS.d/next/Library/2024-06-27-13-47-14.gh-issue-121027.jh55EC.rst deleted file mode 100644 index 8470c8b37ac83d..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-27-13-47-14.gh-issue-121027.jh55EC.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add a future warning in :meth:`!functools.partial.__get__`. In future Python -versions :class:`functools.partial` will be a method descriptor. diff --git a/Misc/NEWS.d/next/Library/2024-06-29-05-08-59.gh-issue-87744.rpF6Jw.rst b/Misc/NEWS.d/next/Library/2024-06-29-05-08-59.gh-issue-87744.rpF6Jw.rst deleted file mode 100644 index c0b4f349fb6dac..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-29-05-08-59.gh-issue-87744.rpF6Jw.rst +++ /dev/null @@ -1 +0,0 @@ -Fix waitpid race while calling :meth:`~asyncio.subprocess.Process.send_signal` in asyncio. Patch by Kumar Aditya. diff --git a/Misc/NEWS.d/next/Library/2024-06-29-15-21-12.gh-issue-121141.4evD6q.rst b/Misc/NEWS.d/next/Library/2024-06-29-15-21-12.gh-issue-121141.4evD6q.rst deleted file mode 100644 index f2dc621050ff4b..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-29-15-21-12.gh-issue-121141.4evD6q.rst +++ /dev/null @@ -1 +0,0 @@ -Add support for :func:`copy.replace` to AST nodes. Patch by Bénédikt Tran. diff --git a/Misc/NEWS.d/next/Library/2024-06-29-15-23-26.gh-issue-121151.HeLEvq.rst b/Misc/NEWS.d/next/Library/2024-06-29-15-23-26.gh-issue-121151.HeLEvq.rst deleted file mode 100644 index f08b6131a702f7..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-29-15-23-26.gh-issue-121151.HeLEvq.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix wrapping of long usage text of arguments inside a mutually exclusive -group in :mod:`argparse`. diff --git a/Misc/NEWS.d/next/Library/2024-06-29-19-30-15.gh-issue-121163.SJKDFq.rst b/Misc/NEWS.d/next/Library/2024-06-29-19-30-15.gh-issue-121163.SJKDFq.rst deleted file mode 100644 index 50f945ab9f1436..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-06-29-19-30-15.gh-issue-121163.SJKDFq.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add support for ``all`` as an valid ``action`` for :func:`warnings.simplefilter` -and :func:`warnings.filterwarnings`. diff --git a/Misc/NEWS.d/next/Library/2024-07-01-11-23-18.gh-issue-121210.cD0zfn.rst b/Misc/NEWS.d/next/Library/2024-07-01-11-23-18.gh-issue-121210.cD0zfn.rst deleted file mode 100644 index 55d5b221bf0765..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-01-11-23-18.gh-issue-121210.cD0zfn.rst +++ /dev/null @@ -1,2 +0,0 @@ -Handle AST nodes with missing runtime fields or attributes in -:func:`ast.compare`. Patch by Bénédikt Tran. diff --git a/Misc/NEWS.d/next/Library/2024-07-02-11-34-06.gh-issue-121245.sSkDAr.rst b/Misc/NEWS.d/next/Library/2024-07-02-11-34-06.gh-issue-121245.sSkDAr.rst deleted file mode 100644 index 6e9dec2545166f..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-02-11-34-06.gh-issue-121245.sSkDAr.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a bug in the handling of the command history of the new :term:`REPL` that caused -the history file to be wiped at REPL exit. diff --git a/Misc/NEWS.d/next/Library/2024-07-03-07-25-21.gh-issue-121332.Iz6FEq.rst b/Misc/NEWS.d/next/Library/2024-07-03-07-25-21.gh-issue-121332.Iz6FEq.rst deleted file mode 100644 index 480f27e05953a6..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-03-07-25-21.gh-issue-121332.Iz6FEq.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fix constructor of :mod:`ast` nodes with custom ``_attributes``. Previously, -passing custom attributes would raise a :py:exc:`DeprecationWarning`. Passing -arguments to the constructor that are not in ``_fields`` or ``_attributes`` -remains deprecated. Patch by Jelle Zijlstra. diff --git a/Misc/NEWS.d/next/Library/2024-07-03-10-11-53.gh-issue-121313.D7gARW.rst b/Misc/NEWS.d/next/Library/2024-07-03-10-11-53.gh-issue-121313.D7gARW.rst deleted file mode 100644 index bb41063e684da4..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-03-10-11-53.gh-issue-121313.D7gARW.rst +++ /dev/null @@ -1 +0,0 @@ -Limit the reading size in the :class:`multiprocessing.connection.Connection` class to 64 KiB to prevent memory overallocation and unnecessary memory management system calls. diff --git a/Misc/NEWS.d/next/Library/2024-07-03-14-23-04.gh-issue-119004.L5MoUu.rst b/Misc/NEWS.d/next/Library/2024-07-03-14-23-04.gh-issue-119004.L5MoUu.rst deleted file mode 100644 index 899bd163d36644..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-03-14-23-04.gh-issue-119004.L5MoUu.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a crash in :ref:`OrderedDict.__eq__ ` -when operands are mutated during the check. Patch by Bénédikt Tran. diff --git a/Misc/NEWS.d/next/Library/2024-07-04-17-36-03.gh-issue-59110.IlI9Fz.rst b/Misc/NEWS.d/next/Library/2024-07-04-17-36-03.gh-issue-59110.IlI9Fz.rst deleted file mode 100644 index b8e3ee0720cfe6..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-04-17-36-03.gh-issue-59110.IlI9Fz.rst +++ /dev/null @@ -1,2 +0,0 @@ -:mod:`zipimport` supports now namespace packages when no directory entry -exists. diff --git a/Misc/NEWS.d/next/Library/2024-07-06-12-37-10.gh-issue-121423.vnxrl4.rst b/Misc/NEWS.d/next/Library/2024-07-06-12-37-10.gh-issue-121423.vnxrl4.rst deleted file mode 100644 index 0fd89a99681292..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-06-12-37-10.gh-issue-121423.vnxrl4.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve import time of :mod:`socket` by lazy importing modules and -writing :data:`!socket.errorTab` as a constant. diff --git a/Misc/NEWS.d/next/Library/2024-07-06-16-08-39.gh-issue-119169.o0YymL.rst b/Misc/NEWS.d/next/Library/2024-07-06-16-08-39.gh-issue-119169.o0YymL.rst deleted file mode 100644 index 5d9b50d452a9cd..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-06-16-08-39.gh-issue-119169.o0YymL.rst +++ /dev/null @@ -1 +0,0 @@ -Slightly speed up :func:`os.walk` by simplifying exception handling. diff --git a/Misc/NEWS.d/next/Library/2024-07-06-23-39-38.gh-issue-121450.vGqb3c.rst b/Misc/NEWS.d/next/Library/2024-07-06-23-39-38.gh-issue-121450.vGqb3c.rst deleted file mode 100644 index 98b9453ad8c843..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-06-23-39-38.gh-issue-121450.vGqb3c.rst +++ /dev/null @@ -1,4 +0,0 @@ -Hard-coded breakpoints (:func:`breakpoint` and :func:`pdb.set_trace`) now -reuse the most recent ``Pdb`` instance that calls ``Pdb.set_trace()``, -instead of creating a new one each time. As a result, all the instance specific -data like ``display`` and ``commands`` are preserved across Hard-coded breakpoints. diff --git a/Misc/NEWS.d/next/Library/2024-07-08-03-45-34.gh-issue-121474.NsvrUN.rst b/Misc/NEWS.d/next/Library/2024-07-08-03-45-34.gh-issue-121474.NsvrUN.rst deleted file mode 100644 index 605f30d76f5d47..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-08-03-45-34.gh-issue-121474.NsvrUN.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix missing sanity check for ``parties`` arg in :class:`threading.Barrier` -constructor. Patch by Clinton Christian (pygeek). diff --git a/Misc/NEWS.d/next/Library/2024-07-09-12-23-32.gh-issue-121486.Iultjh.rst b/Misc/NEWS.d/next/Library/2024-07-09-12-23-32.gh-issue-121486.Iultjh.rst deleted file mode 100644 index 15130aafbc4408..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-09-12-23-32.gh-issue-121486.Iultjh.rst +++ /dev/null @@ -1,3 +0,0 @@ -:mod:`math` functions :func:`~math.isqrt`, :func:`~math.log`, :func:`~math.log2` and -:func:`~math.log10` now support integers larger than ``2**2**32`` on 32-bit -platforms. diff --git a/Misc/NEWS.d/next/Library/2024-07-10-08-13-34.gh-issue-121249.W9Gd09.rst b/Misc/NEWS.d/next/Library/2024-07-10-08-13-34.gh-issue-121249.W9Gd09.rst deleted file mode 100644 index 2d41fca45bcad9..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-10-08-13-34.gh-issue-121249.W9Gd09.rst +++ /dev/null @@ -1,3 +0,0 @@ -Support the :c:expr:`float complex` and :c:expr:`double complex` -C types in the :mod:`struct` module if the compiler has C11 complex -arithmetic. Patch by Sergey B Kirpichev. diff --git a/Misc/NEWS.d/next/Library/2024-07-13-06-23-24.gh-issue-121245.RfOgf4.rst b/Misc/NEWS.d/next/Library/2024-07-13-06-23-24.gh-issue-121245.RfOgf4.rst deleted file mode 100644 index 1758f587157f36..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-13-06-23-24.gh-issue-121245.RfOgf4.rst +++ /dev/null @@ -1,3 +0,0 @@ -Simplify handling of the history file in ``site.register_readline()`` -helper. The ``CAN_USE_PYREPL`` variable now will be initialized, when -imported. Patch by Sergey B Kirpichev. diff --git a/Misc/NEWS.d/next/Library/2024-07-14-06-24-02.gh-issue-57141.C3jhDh.rst b/Misc/NEWS.d/next/Library/2024-07-14-06-24-02.gh-issue-57141.C3jhDh.rst deleted file mode 100644 index 33e9ab94852e35..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-14-06-24-02.gh-issue-57141.C3jhDh.rst +++ /dev/null @@ -1,2 +0,0 @@ -The *shallow* argument to :class:`filecmp.dircmp` (new in Python 3.13) is -now keyword-only. diff --git a/Misc/NEWS.d/next/Library/2024-07-14-11-18-28.gh-issue-120930.Kuo4L0.rst b/Misc/NEWS.d/next/Library/2024-07-14-11-18-28.gh-issue-120930.Kuo4L0.rst deleted file mode 100644 index 9e11595cdb50b8..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-14-11-18-28.gh-issue-120930.Kuo4L0.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed a bug introduced by gh-92081 that added an incorrect extra -blank to encoded words occurring in wrapped headers. diff --git a/Misc/NEWS.d/next/Library/2024-07-15-19-25-25.gh-issue-121798.GmuBDu.rst b/Misc/NEWS.d/next/Library/2024-07-15-19-25-25.gh-issue-121798.GmuBDu.rst deleted file mode 100644 index 5706e4bffeb4a1..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-15-19-25-25.gh-issue-121798.GmuBDu.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add alternative :class:`~decimal.Decimal` constructor -:meth:`Decimal.from_number() `. diff --git a/Misc/NEWS.d/next/Library/2024-07-15-19-34-56.gh-issue-121797.qDqj59.rst b/Misc/NEWS.d/next/Library/2024-07-15-19-34-56.gh-issue-121797.qDqj59.rst deleted file mode 100644 index 9525379587f6cd..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-15-19-34-56.gh-issue-121797.qDqj59.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add alternative :class:`~fractions.Fraction` constructor -:meth:`Fraction.from_number() `. diff --git a/Misc/NEWS.d/next/Library/2024-07-16-20-49-07.gh-issue-121804.gYN-In.rst b/Misc/NEWS.d/next/Library/2024-07-16-20-49-07.gh-issue-121804.gYN-In.rst deleted file mode 100644 index 1cc1cde7c22704..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-16-20-49-07.gh-issue-121804.gYN-In.rst +++ /dev/null @@ -1,2 +0,0 @@ -Correctly show error locations, when :exc:`SyntaxError` raised in new repl. -Patch by Sergey B Kirpichev. diff --git a/Misc/NEWS.d/next/Library/2024-07-17-09-23-03.gh-issue-121889.6se9jS.rst b/Misc/NEWS.d/next/Library/2024-07-17-09-23-03.gh-issue-121889.6se9jS.rst deleted file mode 100644 index a7babe0580b3e4..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-17-09-23-03.gh-issue-121889.6se9jS.rst +++ /dev/null @@ -1 +0,0 @@ -Adjusts ``cmath.acosh(complex('0+nanj'))`` for recent C standards. diff --git a/Misc/NEWS.d/next/Library/2024-07-17-09-44-35.gh-issue-119698.WlygzR.rst b/Misc/NEWS.d/next/Library/2024-07-17-09-44-35.gh-issue-119698.WlygzR.rst deleted file mode 100644 index 5134e609e7f1ca..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-17-09-44-35.gh-issue-119698.WlygzR.rst +++ /dev/null @@ -1,3 +0,0 @@ -Due to the lack of interest for :meth:`symtable.Class.get_methods`, the -method is marked as deprecated and will be removed in Python 3.16. Patch by -Bénédikt Tran. diff --git a/Misc/NEWS.d/next/Library/2024-07-17-12-55-22.gh-issue-121268.41RmjR.rst b/Misc/NEWS.d/next/Library/2024-07-17-12-55-22.gh-issue-121268.41RmjR.rst deleted file mode 100644 index f88e363da16124..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-17-12-55-22.gh-issue-121268.41RmjR.rst +++ /dev/null @@ -1 +0,0 @@ -Remove workarounds for non-IEEE 754 systems in :mod:`cmath`. diff --git a/Misc/NEWS.d/next/Library/2024-07-21-02-00-46.gh-issue-73991.pLxdtJ.rst b/Misc/NEWS.d/next/Library/2024-07-21-02-00-46.gh-issue-73991.pLxdtJ.rst deleted file mode 100644 index 26fdd8c59b1c50..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-21-02-00-46.gh-issue-73991.pLxdtJ.rst +++ /dev/null @@ -1 +0,0 @@ -Add :meth:`pathlib.Path.move`, which moves a file or directory tree. diff --git a/Misc/NEWS.d/next/Library/2024-07-21-10-45-24.gh-issue-122081.dNrYMq.rst b/Misc/NEWS.d/next/Library/2024-07-21-10-45-24.gh-issue-122081.dNrYMq.rst deleted file mode 100644 index 4c988b16168047..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-21-10-45-24.gh-issue-122081.dNrYMq.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a crash in the :func:`!decimal.IEEEContext` optional function -available via the ``EXTRA_FUNCTIONALITY`` configuration flag. diff --git a/Misc/NEWS.d/next/Library/2024-07-21-18-03-30.gh-issue-122088.vi2bP-.rst b/Misc/NEWS.d/next/Library/2024-07-21-18-03-30.gh-issue-122088.vi2bP-.rst deleted file mode 100644 index 9c173d8c462feb..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-21-18-03-30.gh-issue-122088.vi2bP-.rst +++ /dev/null @@ -1,3 +0,0 @@ -:func:`@warnings.deprecated ` now copies the -coroutine status of functions and methods so that -:func:`inspect.iscoroutinefunction` returns the correct result. diff --git a/Misc/NEWS.d/next/Library/2024-07-22-08-14-04.gh-issue-113785.6B_KNB.rst b/Misc/NEWS.d/next/Library/2024-07-22-08-14-04.gh-issue-113785.6B_KNB.rst deleted file mode 100644 index 89d44a3f79c390..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-22-08-14-04.gh-issue-113785.6B_KNB.rst +++ /dev/null @@ -1 +0,0 @@ -:mod:`csv` now correctly parses numeric fields (when used with :const:`csv.QUOTE_NONNUMERIC` or :const:`csv.QUOTE_STRINGS`) which start with an escape character. diff --git a/Misc/NEWS.d/next/Library/2024-07-22-08-57-28.gh-issue-120754.Eo5puP.rst b/Misc/NEWS.d/next/Library/2024-07-22-08-57-28.gh-issue-120754.Eo5puP.rst deleted file mode 100644 index daf184153646cd..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-22-08-57-28.gh-issue-120754.Eo5puP.rst +++ /dev/null @@ -1 +0,0 @@ -``Pathlib.read_bytes`` no longer opens the file in Python's buffered I/O mode. This reduces overheads as the code reads a file in whole leading to a modest speedup. diff --git a/Misc/NEWS.d/next/Library/2024-07-23-09-14-44.gh-issue-82951.-F5p5A.rst b/Misc/NEWS.d/next/Library/2024-07-23-09-14-44.gh-issue-82951.-F5p5A.rst deleted file mode 100644 index b3f07889119c9f..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-23-09-14-44.gh-issue-82951.-F5p5A.rst +++ /dev/null @@ -1,3 +0,0 @@ -Serializing objects with complex ``__qualname__`` (such as unbound methods -and nested classes) by name no longer involves serializing parent objects by -value in pickle protocols < 4. diff --git a/Misc/NEWS.d/next/Library/2024-07-23-10-59-38.gh-issue-121723.iJEf7e.rst b/Misc/NEWS.d/next/Library/2024-07-23-10-59-38.gh-issue-121723.iJEf7e.rst deleted file mode 100644 index cabb4024fb10f1..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-23-10-59-38.gh-issue-121723.iJEf7e.rst +++ /dev/null @@ -1,3 +0,0 @@ -Make :func:`logging.config.dictConfig` accept any object implementing the -Queue public API. See the :ref:`queue configuration ` -section for details. Patch by Bénédikt Tran. diff --git a/Misc/NEWS.d/next/Library/2024-07-23-12-38-14.gh-issue-122145.sTO8nX.rst b/Misc/NEWS.d/next/Library/2024-07-23-12-38-14.gh-issue-122145.sTO8nX.rst deleted file mode 100644 index a4282f12d9742a..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-23-12-38-14.gh-issue-122145.sTO8nX.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix an issue when reporting tracebacks corresponding to Python code -emitting an empty AST body. -Patch by Nikita Sobolev and Bénédikt Tran. diff --git a/Misc/NEWS.d/next/Library/2024-07-23-13-07-12.gh-issue-122129.PwbC8q.rst b/Misc/NEWS.d/next/Library/2024-07-23-13-07-12.gh-issue-122129.PwbC8q.rst deleted file mode 100644 index 08beb45653d24b..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-23-13-07-12.gh-issue-122129.PwbC8q.rst +++ /dev/null @@ -1 +0,0 @@ -Improve support of method descriptors and wrappers in the help title. diff --git a/Misc/NEWS.d/next/Library/2024-07-23-15-11-13.gh-issue-122163.4wRUuM.rst b/Misc/NEWS.d/next/Library/2024-07-23-15-11-13.gh-issue-122163.4wRUuM.rst deleted file mode 100644 index a4625c2a0e50e3..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-23-15-11-13.gh-issue-122163.4wRUuM.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add notes for JSON serialization errors that allow to identify the source of -the error. diff --git a/Misc/NEWS.d/next/Library/2024-07-23-15-30-23.gh-issue-122170.Z9gi3Y.rst b/Misc/NEWS.d/next/Library/2024-07-23-15-30-23.gh-issue-122170.Z9gi3Y.rst deleted file mode 100644 index 7eeb9f67ad4b3a..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-23-15-30-23.gh-issue-122170.Z9gi3Y.rst +++ /dev/null @@ -1,2 +0,0 @@ -Handle :exc:`ValueError`\s raised by :func:`os.stat` in :mod:`linecache`. -Patch by Bénédikt Tran. diff --git a/Misc/NEWS.d/next/Library/2024-07-23-17-13-10.gh-issue-119180.5PZELo.rst b/Misc/NEWS.d/next/Library/2024-07-23-17-13-10.gh-issue-119180.5PZELo.rst deleted file mode 100644 index d65e89f7523b0a..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-23-17-13-10.gh-issue-119180.5PZELo.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix handling of classes with custom metaclasses in -``annotationlib.get_annotations``. diff --git a/Misc/NEWS.d/next/Library/2024-07-23-22-26-00.gh-issue-119180.B2IVT8.rst b/Misc/NEWS.d/next/Library/2024-07-23-22-26-00.gh-issue-119180.B2IVT8.rst deleted file mode 100644 index 13f51e4c42f4a0..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-23-22-26-00.gh-issue-119180.B2IVT8.rst +++ /dev/null @@ -1,7 +0,0 @@ -As part of :pep:`749`, add the following attributes for customizing -evaluation of annotation scopes: - -* ``evaluate_value`` on :class:`typing.TypeAliasType` -* ``evaluate_bound``, ``evaluate_constraints``, and ``evaluate_default`` on :class:`typing.TypeVar` -* ``evaluate_default`` on :class:`typing.ParamSpec` -* ``evaluate_default`` on :class:`typing.TypeVarTuple` diff --git a/Misc/NEWS.d/next/Library/2024-07-24-08-48-22.gh-issue-122213.o3pdgA.rst b/Misc/NEWS.d/next/Library/2024-07-24-08-48-22.gh-issue-122213.o3pdgA.rst deleted file mode 100644 index 833a2a676f9298..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-24-08-48-22.gh-issue-122213.o3pdgA.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add notes for pickle serialization errors that allow to identify the source -of the error. diff --git a/Misc/NEWS.d/next/Library/2024-07-25-15-41-14.gh-issue-105733.o3koJA.rst b/Misc/NEWS.d/next/Library/2024-07-25-15-41-14.gh-issue-105733.o3koJA.rst deleted file mode 100644 index 60c5e69d2f6f9c..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-25-15-41-14.gh-issue-105733.o3koJA.rst +++ /dev/null @@ -1,2 +0,0 @@ -:func:`ctypes.ARRAY` is now :term:`soft deprecated`: it no longer emits deprecation -warnings and is not scheduled for removal. diff --git a/Misc/NEWS.d/next/Library/2024-07-26-21-21-13.gh-issue-122332.fvw88r.rst b/Misc/NEWS.d/next/Library/2024-07-26-21-21-13.gh-issue-122332.fvw88r.rst deleted file mode 100644 index 55bb1dc44add1b..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-26-21-21-13.gh-issue-122332.fvw88r.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed segfault with :meth:`asyncio.Task.get_coro` when using an eager task -factory. diff --git a/Misc/NEWS.d/next/Library/2024-07-27-16-10-41.gh-issue-121650.nf6oc9.rst b/Misc/NEWS.d/next/Library/2024-07-27-16-10-41.gh-issue-121650.nf6oc9.rst deleted file mode 100644 index 83dd28d4ac575b..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-27-16-10-41.gh-issue-121650.nf6oc9.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`email` headers with embedded newlines are now quoted on output. The -:mod:`~email.generator` will now refuse to serialize (write) headers that -are unsafely folded or delimited; see -:attr:`~email.policy.Policy.verify_generated_headers`. (Contributed by Bas -Bloemsaat and Petr Viktorin in :gh:`121650`.) diff --git a/Misc/NEWS.d/next/Library/2024-07-29-10-24-48.gh-issue-122311.xChV1b.rst b/Misc/NEWS.d/next/Library/2024-07-29-10-24-48.gh-issue-122311.xChV1b.rst deleted file mode 100644 index 8d70c610a8dad6..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-29-10-24-48.gh-issue-122311.xChV1b.rst +++ /dev/null @@ -1 +0,0 @@ -Fix some error messages in :mod:`pickle`. diff --git a/Misc/NEWS.d/next/Library/2024-07-29-16-47-08.gh-issue-122400.fM0YSv.rst b/Misc/NEWS.d/next/Library/2024-07-29-16-47-08.gh-issue-122400.fM0YSv.rst deleted file mode 100644 index 8c47e94f78d9f0..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-29-16-47-08.gh-issue-122400.fM0YSv.rst +++ /dev/null @@ -1,3 +0,0 @@ -Handle :exc:`ValueError`\s raised by :func:`os.stat` in -:class:`filecmp.dircmp` and :func:`filecmp.cmpfiles`. -Patch by Bénédikt Tran. diff --git a/Misc/NEWS.d/next/Library/2024-07-30-04-27-55.gh-issue-122272.6Wwa1V.rst b/Misc/NEWS.d/next/Library/2024-07-30-04-27-55.gh-issue-122272.6Wwa1V.rst deleted file mode 100644 index 943010b9c16c3c..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-30-04-27-55.gh-issue-122272.6Wwa1V.rst +++ /dev/null @@ -1,2 +0,0 @@ -On some platforms such as Linux, year with century was not 0-padded when formatted by :meth:`~.datetime.strftime` with C99-specific specifiers ``'%C'`` or ``'%F'``. The 0-padding behavior is now guaranteed when the format specifiers ``'%C'`` and ``'%F'`` are supported by the C library. -Patch by Ben Hsing diff --git a/Misc/NEWS.d/next/Library/2024-07-30-14-46-16.gh-issue-87320.-Yk1wb.rst b/Misc/NEWS.d/next/Library/2024-07-30-14-46-16.gh-issue-87320.-Yk1wb.rst deleted file mode 100644 index 4322b719c690c2..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-30-14-46-16.gh-issue-87320.-Yk1wb.rst +++ /dev/null @@ -1,3 +0,0 @@ -In :class:`code.InteractiveInterpreter`, handle exceptions caused by calling a -non-default :func:`sys.excepthook`. Before, the exception bubbled up to the -caller, ending the :term:`REPL`. diff --git a/Misc/NEWS.d/next/Library/2024-07-30-15-57-07.gh-issue-122459.AYIoeN.rst b/Misc/NEWS.d/next/Library/2024-07-30-15-57-07.gh-issue-122459.AYIoeN.rst deleted file mode 100644 index 595504048302da..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-30-15-57-07.gh-issue-122459.AYIoeN.rst +++ /dev/null @@ -1,2 +0,0 @@ -Optimize :mod:`pickling ` by name objects without the ``__module__`` -attribute. diff --git a/Misc/NEWS.d/next/Library/2024-07-30-21-29-30.gh-issue-122334.LeoE1x.rst b/Misc/NEWS.d/next/Library/2024-07-30-21-29-30.gh-issue-122334.LeoE1x.rst deleted file mode 100644 index cef801c950faa6..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-30-21-29-30.gh-issue-122334.LeoE1x.rst +++ /dev/null @@ -1 +0,0 @@ -Fix crash when importing :mod:`ssl` after the main interpreter restarts. diff --git a/Misc/NEWS.d/next/Library/2024-07-31-14-55-41.gh-issue-82378.eZvYmR.rst b/Misc/NEWS.d/next/Library/2024-07-31-14-55-41.gh-issue-82378.eZvYmR.rst deleted file mode 100644 index 8af016e7c82fcb..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-31-14-55-41.gh-issue-82378.eZvYmR.rst +++ /dev/null @@ -1,2 +0,0 @@ -Make sure that the new :term:`REPL` interprets :data:`sys.tracebacklimit` in -the same way that the classic REPL did. diff --git a/Misc/NEWS.d/next/Library/2024-07-31-15-08-42.gh-issue-116622.aKxIQA.rst b/Misc/NEWS.d/next/Library/2024-07-31-15-08-42.gh-issue-116622.aKxIQA.rst deleted file mode 100644 index fc65b4d973b27d..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-31-15-08-42.gh-issue-116622.aKxIQA.rst +++ /dev/null @@ -1,2 +0,0 @@ -On Android, the ``FICLONE`` and ``FICLONERANGE`` constants are no longer -exposed by :mod:`fcntl`, as these ioctls are blocked by SELinux. diff --git a/Misc/NEWS.d/next/Library/2024-07-31-20-43-21.gh-issue-122478.sCU2Le.rst b/Misc/NEWS.d/next/Library/2024-07-31-20-43-21.gh-issue-122478.sCU2Le.rst deleted file mode 100644 index 6071324593a9ed..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-07-31-20-43-21.gh-issue-122478.sCU2Le.rst +++ /dev/null @@ -1,3 +0,0 @@ -Remove internal frames from tracebacks shown in -:class:`code.InteractiveInterpreter` with non-default :func:`sys.excepthook`. -Save correct tracebacks in :attr:`sys.last_traceback` and update ``__traceback__`` attribute of :attr:`sys.last_value` and :attr:`sys.last_exc`. diff --git a/Misc/NEWS.d/next/Library/2024-08-03-06-51-08.gh-issue-122637.gpas8J.rst b/Misc/NEWS.d/next/Library/2024-08-03-06-51-08.gh-issue-122637.gpas8J.rst deleted file mode 100644 index 2ded33d75b35bd..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-03-06-51-08.gh-issue-122637.gpas8J.rst +++ /dev/null @@ -1 +0,0 @@ -Adjust ``cmath.tanh(nanj)`` and ``cmath.tanh(infj)`` for recent C standards. diff --git a/Misc/NEWS.d/next/Library/2024-08-04-14-07-18.gh-issue-118814.uiyks1.rst b/Misc/NEWS.d/next/Library/2024-08-04-14-07-18.gh-issue-118814.uiyks1.rst deleted file mode 100644 index 14ef6c070603ae..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-04-14-07-18.gh-issue-118814.uiyks1.rst +++ /dev/null @@ -1 +0,0 @@ -Fix the :class:`typing.TypeVar` constructor when name is passed by keyword. diff --git a/Misc/NEWS.d/next/Library/2024-08-06-07-24-00.gh-issue-118974.qamsCQ.rst b/Misc/NEWS.d/next/Library/2024-08-06-07-24-00.gh-issue-118974.qamsCQ.rst deleted file mode 100644 index 79480a69c1a90e..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-06-07-24-00.gh-issue-118974.qamsCQ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add ``decorator`` parameter to :func:`dataclasses.make_dataclass` -to customize the functional creation of dataclasses. diff --git a/Misc/NEWS.d/next/Library/2024-08-06-10-36-55.gh-issue-118761.q_x_1A.rst b/Misc/NEWS.d/next/Library/2024-08-06-10-36-55.gh-issue-118761.q_x_1A.rst deleted file mode 100644 index 3f3e870b0b9565..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-06-10-36-55.gh-issue-118761.q_x_1A.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve import time of :mod:`pprint` by around seven times. Patch by Hugo -van Kemenade. diff --git a/Misc/NEWS.d/next/Library/2024-08-06-18-07-19.gh-issue-122744.kCzNDI.rst b/Misc/NEWS.d/next/Library/2024-08-06-18-07-19.gh-issue-122744.kCzNDI.rst deleted file mode 100644 index 18ac3dd10d6553..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-06-18-07-19.gh-issue-122744.kCzNDI.rst +++ /dev/null @@ -1 +0,0 @@ -Bump the version of pip bundled in ensurepip to version 24.2. diff --git a/Misc/NEWS.d/next/Library/2024-08-07-11-57-41.gh-issue-122311.LDExnJ.rst b/Misc/NEWS.d/next/Library/2024-08-07-11-57-41.gh-issue-122311.LDExnJ.rst deleted file mode 100644 index 07ade2034bfcf5..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-07-11-57-41.gh-issue-122311.LDExnJ.rst +++ /dev/null @@ -1,5 +0,0 @@ -Improve errors in the :mod:`pickle` module. :exc:`~pickle.PicklingError` is -now raised more often instead of :exc:`UnicodeEncodeError`, -:exc:`ValueError` and :exc:`AttributeError`, and the original exception is -chained to it. Improve and unify error messages in Python and C -implementations. diff --git a/Misc/NEWS.d/next/Library/2024-08-07-14-12-19.gh-issue-105376.QbGPdE.rst b/Misc/NEWS.d/next/Library/2024-08-07-14-12-19.gh-issue-105376.QbGPdE.rst deleted file mode 100644 index 9756a14cbcf67e..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-07-14-12-19.gh-issue-105376.QbGPdE.rst +++ /dev/null @@ -1,3 +0,0 @@ -Restore the deprecated :mod:`logging` ``warn()`` method. It was removed in -Python 3.13 alpha 1. Keep the deprecated ``warn()`` method in Python 3.13. -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2024-08-07-17-41-16.gh-issue-116263.EcXir0.rst b/Misc/NEWS.d/next/Library/2024-08-07-17-41-16.gh-issue-116263.EcXir0.rst deleted file mode 100644 index 167ca943b3527c..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-07-17-41-16.gh-issue-116263.EcXir0.rst +++ /dev/null @@ -1,2 +0,0 @@ -:class:`logging.handlers.RotatingFileHandler` no longer rolls over empty log -files. diff --git a/Misc/NEWS.d/next/Library/2024-08-10-10-21-44.gh-issue-122858.ZC1rJD.rst b/Misc/NEWS.d/next/Library/2024-08-10-10-21-44.gh-issue-122858.ZC1rJD.rst deleted file mode 100644 index d452ad6a4f6d90..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-10-10-21-44.gh-issue-122858.ZC1rJD.rst +++ /dev/null @@ -1,2 +0,0 @@ -Deprecate :func:`!asyncio.iscoroutinefunction` in favor of -:func:`inspect.iscoroutinefunction`. diff --git a/Misc/NEWS.d/next/Library/2024-08-10-14-16-59.gh-issue-122873.XlHaUn.rst b/Misc/NEWS.d/next/Library/2024-08-10-14-16-59.gh-issue-122873.XlHaUn.rst deleted file mode 100644 index 002ebd9d925956..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-10-14-16-59.gh-issue-122873.XlHaUn.rst +++ /dev/null @@ -1,3 +0,0 @@ -Enable :mod:`json` module to work as a script using the :option:`-m` switch: ``python -m json``. -See the :ref:`JSON command-line interface ` documentation. -Patch by Trey Hunner. diff --git a/Misc/NEWS.d/next/Library/2024-08-11-14-08-04.gh-issue-122905.7tDsxA.rst b/Misc/NEWS.d/next/Library/2024-08-11-14-08-04.gh-issue-122905.7tDsxA.rst deleted file mode 100644 index 1be44c906c4f30..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-11-14-08-04.gh-issue-122905.7tDsxA.rst +++ /dev/null @@ -1 +0,0 @@ -:class:`zipfile.Path` objects now sanitize names from the zipfile. diff --git a/Misc/NEWS.d/next/Library/2024-08-11-14-23-07.gh-issue-122903.xktZta.rst b/Misc/NEWS.d/next/Library/2024-08-11-14-23-07.gh-issue-122903.xktZta.rst deleted file mode 100644 index c2a1e64d1f6db1..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-11-14-23-07.gh-issue-122903.xktZta.rst +++ /dev/null @@ -1,2 +0,0 @@ -``zipfile.Path.glob`` now correctly matches directories instead of -silently omitting them. diff --git a/Misc/NEWS.d/next/Library/2024-08-14-10-41-11.gh-issue-122981.BHV0Z9.rst b/Misc/NEWS.d/next/Library/2024-08-14-10-41-11.gh-issue-122981.BHV0Z9.rst deleted file mode 100644 index 7713d805155f9a..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-14-10-41-11.gh-issue-122981.BHV0Z9.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix :func:`inspect.getsource` for generated classes with Python base classes -(e.g. enums). diff --git a/Misc/NEWS.d/next/Library/2024-08-15-09-45-34.gh-issue-121735._1q0qf.rst b/Misc/NEWS.d/next/Library/2024-08-15-09-45-34.gh-issue-121735._1q0qf.rst deleted file mode 100644 index e10b2e760bc063..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-15-09-45-34.gh-issue-121735._1q0qf.rst +++ /dev/null @@ -1,3 +0,0 @@ -When working with zip archives, importlib.resources now properly honors -module-adjacent references (e.g. ``files(pkg.mod)`` and not just -``files(pkg)``). diff --git a/Misc/NEWS.d/next/Library/2024-08-16-16-53-52.gh-issue-123049.izx_fH.rst b/Misc/NEWS.d/next/Library/2024-08-16-16-53-52.gh-issue-123049.izx_fH.rst deleted file mode 100644 index 2faf85092a0f8a..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-16-16-53-52.gh-issue-123049.izx_fH.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add support for :const:`~configparser.UNNAMED_SECTION` -in :meth:`configparser.ConfigParser.add_section`. diff --git a/Misc/NEWS.d/next/Library/2024-08-16-19-13-21.gh-issue-123067.Nx9O4R.rst b/Misc/NEWS.d/next/Library/2024-08-16-19-13-21.gh-issue-123067.Nx9O4R.rst deleted file mode 100644 index 6a234561fe31a3..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-16-19-13-21.gh-issue-123067.Nx9O4R.rst +++ /dev/null @@ -1 +0,0 @@ -Fix quadratic complexity in parsing ``"``-quoted cookie values with backslashes by :mod:`http.cookies`. diff --git a/Misc/NEWS.d/next/Library/2024-08-17-08-17-20.gh-issue-123085.7Io2yH.rst b/Misc/NEWS.d/next/Library/2024-08-17-08-17-20.gh-issue-123085.7Io2yH.rst deleted file mode 100644 index 2e09401ceb5b56..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-17-08-17-20.gh-issue-123085.7Io2yH.rst +++ /dev/null @@ -1,3 +0,0 @@ -In a bare call to :func:`importlib.resources.files`, ensure the caller's -frame is properly detected when ``importlib.resources`` is itself available -as a compiled module only (no source). diff --git a/Misc/NEWS.d/next/Library/2024-08-18-08-25-32.gh-issue-123084.rf8izX.rst b/Misc/NEWS.d/next/Library/2024-08-18-08-25-32.gh-issue-123084.rf8izX.rst deleted file mode 100644 index eb01d66d98aef6..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-18-08-25-32.gh-issue-123084.rf8izX.rst +++ /dev/null @@ -1,4 +0,0 @@ -Deprecate :class:`!shutil.ExecError`, which hasn't been -raised by any :mod:`shutil` function since Python 3.4. It's -now an alias for :exc:`RuntimeError`. - diff --git a/Misc/NEWS.d/next/Library/2024-08-19-17-37-18.gh-issue-122909.kP12SK.rst b/Misc/NEWS.d/next/Library/2024-08-19-17-37-18.gh-issue-122909.kP12SK.rst deleted file mode 100644 index 50eb4afd10791b..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-19-17-37-18.gh-issue-122909.kP12SK.rst +++ /dev/null @@ -1,3 +0,0 @@ -In urllib.request when URLError is raised opening an ftp URL, the exception -argument is now consistently a string. Earlier versions passed either a -string or an ftplib exception instance as the argument to URLError. diff --git a/Misc/NEWS.d/next/Library/2024-08-20-14-22-49.gh-issue-123165.vOZZOA.rst b/Misc/NEWS.d/next/Library/2024-08-20-14-22-49.gh-issue-123165.vOZZOA.rst deleted file mode 100644 index 05728adc0be388..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-20-14-22-49.gh-issue-123165.vOZZOA.rst +++ /dev/null @@ -1 +0,0 @@ -Add support for rendering :class:`~dis.Positions` in :mod:`dis`. diff --git a/Misc/NEWS.d/next/Library/2024-08-20-18-02-27.gh-issue-85110.8_iDQy.rst b/Misc/NEWS.d/next/Library/2024-08-20-18-02-27.gh-issue-85110.8_iDQy.rst deleted file mode 100644 index f22fac16b79c0b..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-20-18-02-27.gh-issue-85110.8_iDQy.rst +++ /dev/null @@ -1,2 +0,0 @@ -Preserve relative path in URL without netloc in -:func:`urllib.parse.urlunsplit` and :func:`urllib.parse.urlunparse`. diff --git a/Misc/NEWS.d/next/Library/2024-08-22-09-37-48.gh-issue-123213.owmXnP.rst b/Misc/NEWS.d/next/Library/2024-08-22-09-37-48.gh-issue-123213.owmXnP.rst deleted file mode 100644 index 5a31a00f2758f4..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-22-09-37-48.gh-issue-123213.owmXnP.rst +++ /dev/null @@ -1,3 +0,0 @@ -:meth:`xml.etree.ElementTree.Element.extend` and -:class:`~xml.etree.ElementTree.Element` assignment no longer hide the internal -exception if an erroneous generator is passed. Patch by Bar Harel. diff --git a/Misc/NEWS.d/next/Library/2024-08-22-11-25-19.gh-issue-122546.BSmeE7.rst b/Misc/NEWS.d/next/Library/2024-08-22-11-25-19.gh-issue-122546.BSmeE7.rst deleted file mode 100644 index 55681eced77666..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-22-11-25-19.gh-issue-122546.BSmeE7.rst +++ /dev/null @@ -1,2 +0,0 @@ -Consistently use same file name for different exceptions in the new repl. -Patch by Sergey B Kirpichev. diff --git a/Misc/NEWS.d/next/Library/2024-08-22-20-10-13.gh-issue-123243.Kifj1L.rst b/Misc/NEWS.d/next/Library/2024-08-22-20-10-13.gh-issue-123243.Kifj1L.rst deleted file mode 100644 index cf52585020111f..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-22-20-10-13.gh-issue-123243.Kifj1L.rst +++ /dev/null @@ -1 +0,0 @@ -Fix memory leak in :mod:`!_decimal`. diff --git a/Misc/NEWS.d/next/Library/2024-08-23-15-49-10.gh-issue-116810.QLBUU8.rst b/Misc/NEWS.d/next/Library/2024-08-23-15-49-10.gh-issue-116810.QLBUU8.rst deleted file mode 100644 index 0e5256e7151c5a..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-23-15-49-10.gh-issue-116810.QLBUU8.rst +++ /dev/null @@ -1,4 +0,0 @@ -Resolve a memory leak introduced in CPython 3.10's :mod:`ssl` when the -:attr:`ssl.SSLSocket.session` property was accessed. Speeds up read and -write access to said property by no longer unnecessarily cloning session -objects via serialization. diff --git a/Misc/NEWS.d/next/Library/2024-08-23-22-01-30.gh-issue-76960.vsANPu.rst b/Misc/NEWS.d/next/Library/2024-08-23-22-01-30.gh-issue-76960.vsANPu.rst deleted file mode 100644 index acb0a991e4c93d..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-23-22-01-30.gh-issue-76960.vsANPu.rst +++ /dev/null @@ -1,5 +0,0 @@ -Fix :func:`urllib.parse.urljoin` and :func:`urllib.parse.urldefrag` for URIs -containing empty components. For example, :func:`!urljoin` with relative -reference "?" now sets empty query and removes fragment. -Preserve empty components (authority, params, query, fragment) in :func:`!urljoin`. -Preserve empty components (authority, params, query) in :func:`!urldefrag`. diff --git a/Misc/NEWS.d/next/Library/2024-08-24-00-03-01.gh-issue-123240.uFPG3l.rst b/Misc/NEWS.d/next/Library/2024-08-24-00-03-01.gh-issue-123240.uFPG3l.rst deleted file mode 100644 index e6ea6c33f89762..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-24-00-03-01.gh-issue-123240.uFPG3l.rst +++ /dev/null @@ -1 +0,0 @@ -Raise audit events for the :func:`input` in the new REPL. diff --git a/Misc/NEWS.d/next/Library/2024-08-24-06-05-41.gh-issue-123228.jR_5O5.rst b/Misc/NEWS.d/next/Library/2024-08-24-06-05-41.gh-issue-123228.jR_5O5.rst deleted file mode 100644 index 99b3c0ca5eef28..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-24-06-05-41.gh-issue-123228.jR_5O5.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix return type for -:func:`!_pyrepl.readline._ReadlineWrapper.get_line_buffer` to be -:func:`str`. Patch by Sergey B Kirpichev. diff --git a/Misc/NEWS.d/next/Library/2024-08-25-16-59-20.gh-issue-73991.1w8u3K.rst b/Misc/NEWS.d/next/Library/2024-08-25-16-59-20.gh-issue-73991.1w8u3K.rst deleted file mode 100644 index 4ad5a06709de73..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-25-16-59-20.gh-issue-73991.1w8u3K.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add :meth:`pathlib.Path.copy_into` and :meth:`~pathlib.Path.move_into`, -which copy and move files and directories into *existing* directories. diff --git a/Misc/NEWS.d/next/Library/2024-08-26-13-45-20.gh-issue-123270.gXHvNJ.rst b/Misc/NEWS.d/next/Library/2024-08-26-13-45-20.gh-issue-123270.gXHvNJ.rst deleted file mode 100644 index ee9fde6a9ed87a..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-26-13-45-20.gh-issue-123270.gXHvNJ.rst +++ /dev/null @@ -1,3 +0,0 @@ -Applied a more surgical fix for malformed payloads in :class:`zipfile.Path` -causing infinite loops (gh-122905) without breaking contents using -legitimate characters. diff --git a/Misc/NEWS.d/next/Library/2024-08-26-18-48-13.gh-issue-119518.QFYH9q.rst b/Misc/NEWS.d/next/Library/2024-08-26-18-48-13.gh-issue-119518.QFYH9q.rst deleted file mode 100644 index 819295f7306fa4..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-26-18-48-13.gh-issue-119518.QFYH9q.rst +++ /dev/null @@ -1,2 +0,0 @@ -Speed up normalization of :class:`pathlib.PurePath` and -:class:`~pathlib.Path` objects by not interning string parts. diff --git a/Misc/NEWS.d/next/Library/2024-08-26-19-36-00.gh-issue-123340.mQKI1H.rst b/Misc/NEWS.d/next/Library/2024-08-26-19-36-00.gh-issue-123340.mQKI1H.rst deleted file mode 100644 index 8a462b2300466e..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-26-19-36-00.gh-issue-123340.mQKI1H.rst +++ /dev/null @@ -1 +0,0 @@ -Show string value of :opcode:`IS_OP` oparg in :mod:`dis` output. diff --git a/Misc/NEWS.d/next/Library/2024-08-27-10-30-37.gh-issue-123341.5e-fjt.rst b/Misc/NEWS.d/next/Library/2024-08-27-10-30-37.gh-issue-123341.5e-fjt.rst deleted file mode 100644 index 61561eeb807023..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-27-10-30-37.gh-issue-123341.5e-fjt.rst +++ /dev/null @@ -1 +0,0 @@ -Add :meth:`~object.__class_getitem__` to :class:`!tkinter.Event` for type subscript support at runtime. Patch by Adonis Rakateli. diff --git a/Misc/NEWS.d/next/Library/2024-08-27-12-11-00.gh-issue-123363.gKuJp6.rst b/Misc/NEWS.d/next/Library/2024-08-27-12-11-00.gh-issue-123363.gKuJp6.rst deleted file mode 100644 index c1f92c4d54dbb0..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-27-12-11-00.gh-issue-123363.gKuJp6.rst +++ /dev/null @@ -1,2 +0,0 @@ -Show string value of :opcode:`CONTAINS_OP` oparg in :mod:`dis` output. -Patch by Alexandr153. diff --git a/Misc/NEWS.d/next/Library/2024-08-27-12-38-42.gh-issue-123089.vA7iFR.rst b/Misc/NEWS.d/next/Library/2024-08-27-12-38-42.gh-issue-123089.vA7iFR.rst deleted file mode 100644 index 74cbdd551350f7..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-27-12-38-42.gh-issue-123089.vA7iFR.rst +++ /dev/null @@ -1 +0,0 @@ -Make :class:`weakref.WeakSet` safe against concurrent mutations while it is being iterated. Patch by Kumar Aditya. diff --git a/Misc/NEWS.d/next/Library/2024-08-28-13-03-36.gh-issue-123409.lW0YF-.rst b/Misc/NEWS.d/next/Library/2024-08-28-13-03-36.gh-issue-123409.lW0YF-.rst deleted file mode 100644 index 7c6aab632b674a..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-28-13-03-36.gh-issue-123409.lW0YF-.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix :attr:`ipaddress.IPv6Address.reverse_pointer` output according to -:rfc:`RFC 3596, §2.5 <3596#section-2.5>`. Patch by Bénédikt Tran. diff --git a/Misc/NEWS.d/next/Library/2024-08-28-20-08-19.gh-issue-123448.tItJlp.rst b/Misc/NEWS.d/next/Library/2024-08-28-20-08-19.gh-issue-123448.tItJlp.rst deleted file mode 100644 index a57c133d43545f..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-28-20-08-19.gh-issue-123448.tItJlp.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed memory leak of :class:`typing.NoDefault` by moving it to the static types -array. diff --git a/Misc/NEWS.d/next/Library/2024-08-29-09-27-12.gh-issue-123446._I_mMr.rst b/Misc/NEWS.d/next/Library/2024-08-29-09-27-12.gh-issue-123446._I_mMr.rst deleted file mode 100644 index 871b2fb2b646e7..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-29-09-27-12.gh-issue-123446._I_mMr.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix empty function name in :exc:`TypeError` when :func:`csv.reader`, -:func:`csv.writer`, or :func:`csv.register_dialect` are used without the -required args. diff --git a/Misc/NEWS.d/next/Library/2024-08-29-14-51-36.gh-issue-123430.M7wXl9.rst b/Misc/NEWS.d/next/Library/2024-08-29-14-51-36.gh-issue-123430.M7wXl9.rst deleted file mode 100644 index 0afdad7917fa8f..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-29-14-51-36.gh-issue-123430.M7wXl9.rst +++ /dev/null @@ -1 +0,0 @@ -Pages generated by the :mod:`http.server` module allow the browser to apply its default dark mode. diff --git a/Misc/NEWS.d/next/Library/2024-08-30-09-01-35.gh-issue-123504.lJ9_BB.rst b/Misc/NEWS.d/next/Library/2024-08-30-09-01-35.gh-issue-123504.lJ9_BB.rst deleted file mode 100644 index ea504d3532dc44..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-30-09-01-35.gh-issue-123504.lJ9_BB.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed reference leak in the finalization of :mod:`tkinter`. diff --git a/Misc/NEWS.d/next/Library/2024-08-31-12-34-44.gh-issue-123374.3kE7rb.rst b/Misc/NEWS.d/next/Library/2024-08-31-12-34-44.gh-issue-123374.3kE7rb.rst deleted file mode 100644 index 2fac9079b69e44..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-08-31-12-34-44.gh-issue-123374.3kE7rb.rst +++ /dev/null @@ -1 +0,0 @@ -Remove check for redefined memo entry in :func:`pickletools.dis`. diff --git a/Misc/NEWS.d/next/Library/2024-09-02-20-34-04.gh-issue-123339.czgcSu.rst b/Misc/NEWS.d/next/Library/2024-09-02-20-34-04.gh-issue-123339.czgcSu.rst deleted file mode 100644 index e388541f1c2c19..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-02-20-34-04.gh-issue-123339.czgcSu.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fix :func:`inspect.getsource` for classes in :mod:`collections.abc` and -:mod:`decimal` (for pure Python implementation) modules. -:func:`inspect.getcomments` now raises OSError instead of IndexError if the -``__firstlineno__`` value for a class is out of bound. diff --git a/Misc/NEWS.d/next/Library/2024-09-04-18-23-43.gh-issue-123657.Oks4So.rst b/Misc/NEWS.d/next/Library/2024-09-04-18-23-43.gh-issue-123657.Oks4So.rst deleted file mode 100644 index efebd21e26962a..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-04-18-23-43.gh-issue-123657.Oks4So.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix crash and memory leak in :func:`decimal.getcontext`. It crashed when using -a thread-local context by ``--with-decimal-contextvar=no``. diff --git a/Misc/NEWS.d/next/Library/2024-09-06-00-00-43.gh-issue-122765.tx4hsr.rst b/Misc/NEWS.d/next/Library/2024-09-06-00-00-43.gh-issue-122765.tx4hsr.rst deleted file mode 100644 index 8a1bc4bce81d76..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-06-00-00-43.gh-issue-122765.tx4hsr.rst +++ /dev/null @@ -1 +0,0 @@ -Fix unbalanced quote errors occurring when activate.csh in :mod:`venv` was sourced with a custom prompt containing unpaired quotes or newlines. diff --git a/Misc/NEWS.d/next/Library/2024-09-06-01-35-11.gh-issue-123756.Ozbhke.rst b/Misc/NEWS.d/next/Library/2024-09-06-01-35-11.gh-issue-123756.Ozbhke.rst deleted file mode 100644 index 258dd591fce767..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-06-01-35-11.gh-issue-123756.Ozbhke.rst +++ /dev/null @@ -1 +0,0 @@ -Added a new argument ``mode`` to :class:`pdb.Pdb`. Only allow :mod:`pdb` from command line to use ``restart`` command. diff --git a/Misc/NEWS.d/next/Library/2024-09-06-10-17-54.gh-issue-84808.ION67Z.rst b/Misc/NEWS.d/next/Library/2024-09-06-10-17-54.gh-issue-84808.ION67Z.rst deleted file mode 100644 index c804c5974241bf..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-06-10-17-54.gh-issue-84808.ION67Z.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix error handling in :py:class:`~socket.socket` method -:py:func:`~socket.socket.connect_ex` on platforms where -:c:data:`errno` can be negative. diff --git a/Misc/NEWS.d/next/Library/2024-09-10-11-26-14.gh-issue-123892.2gzIrz.rst b/Misc/NEWS.d/next/Library/2024-09-10-11-26-14.gh-issue-123892.2gzIrz.rst deleted file mode 100644 index bef534427d9a67..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-10-11-26-14.gh-issue-123892.2gzIrz.rst +++ /dev/null @@ -1 +0,0 @@ -Add ``"_wmi"`` to :data:`sys.stdlib_module_names`. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2024-09-11-13-33-19.gh-issue-123935.fRZ_56.rst b/Misc/NEWS.d/next/Library/2024-09-11-13-33-19.gh-issue-123935.fRZ_56.rst deleted file mode 100644 index de720c3714c6ff..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-11-13-33-19.gh-issue-123935.fRZ_56.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix parent slots detection for dataclasses that inherit from classes with -``__dictoffset__``. diff --git a/Misc/NEWS.d/next/Library/2024-09-11-19-05-32.gh-issue-123945.jLwybB.rst b/Misc/NEWS.d/next/Library/2024-09-11-19-05-32.gh-issue-123945.jLwybB.rst deleted file mode 100644 index 26b0ac80b1b3fd..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-11-19-05-32.gh-issue-123945.jLwybB.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a bug where :mod:`argparse` doesn't recognize negative numbers with underscores diff --git a/Misc/NEWS.d/next/Library/2024-09-11-19-12-23.gh-issue-123968.OwHON_.rst b/Misc/NEWS.d/next/Library/2024-09-11-19-12-23.gh-issue-123968.OwHON_.rst deleted file mode 100644 index 4d4894716b7144..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-11-19-12-23.gh-issue-123968.OwHON_.rst +++ /dev/null @@ -1 +0,0 @@ -Fix the command-line interface for the :mod:`random` module to select floats between 0 and N, not 1 and N. diff --git a/Misc/NEWS.d/next/Library/2024-09-12-10-55-19.gh-issue-124016.ncs0hd.rst b/Misc/NEWS.d/next/Library/2024-09-12-10-55-19.gh-issue-124016.ncs0hd.rst deleted file mode 100644 index ac2aa8a983be5d..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-12-10-55-19.gh-issue-124016.ncs0hd.rst +++ /dev/null @@ -1 +0,0 @@ -Update :mod:`unicodedata` database to Unicode 16.0.0. diff --git a/Misc/NEWS.d/next/Library/2024-09-13-10-34-19.gh-issue-123934.yMe7mL.rst b/Misc/NEWS.d/next/Library/2024-09-13-10-34-19.gh-issue-123934.yMe7mL.rst deleted file mode 100644 index 641c21331e3e54..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-13-10-34-19.gh-issue-123934.yMe7mL.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix :class:`unittest.mock.MagicMock` resetting magic methods return values -after ``.reset_mock(return_value=True)`` was called. diff --git a/Misc/NEWS.d/next/Library/2024-09-16-12-31-48.gh-issue-123978.z3smEu.rst b/Misc/NEWS.d/next/Library/2024-09-16-12-31-48.gh-issue-123978.z3smEu.rst deleted file mode 100644 index e5b3229122b509..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-16-12-31-48.gh-issue-123978.z3smEu.rst +++ /dev/null @@ -1 +0,0 @@ -Remove broken :func:`time.thread_time` and :func:`time.thread_time_ns` on NetBSD. diff --git a/Misc/NEWS.d/next/Library/2024-09-17-18-06-42.gh-issue-124171.PHCvRJ.rst b/Misc/NEWS.d/next/Library/2024-09-17-18-06-42.gh-issue-124171.PHCvRJ.rst deleted file mode 100644 index c2f0bb14f55251..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-17-18-06-42.gh-issue-124171.PHCvRJ.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add workaround for broken :c:func:`!fmod()` implementations on Windows, that -loose zero sign (e.g. ``fmod(-10, 1)`` returns ``0.0``). Patch by Sergey B -Kirpichev. diff --git a/Misc/NEWS.d/next/Library/2024-09-18-17-45-52.gh-issue-124212.n6kIby.rst b/Misc/NEWS.d/next/Library/2024-09-18-17-45-52.gh-issue-124212.n6kIby.rst deleted file mode 100644 index 7848f26511e282..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-18-17-45-52.gh-issue-124212.n6kIby.rst +++ /dev/null @@ -1 +0,0 @@ -Fix invalid variable in :mod:`venv` handling of failed symlink on Windows diff --git a/Misc/NEWS.d/next/Library/2024-09-19-00-09-48.gh-issue-84559.IrxvQe.rst b/Misc/NEWS.d/next/Library/2024-09-19-00-09-48.gh-issue-84559.IrxvQe.rst deleted file mode 100644 index a4428e20f3ccdd..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-19-00-09-48.gh-issue-84559.IrxvQe.rst +++ /dev/null @@ -1,5 +0,0 @@ -The default :mod:`multiprocessing` start method on Linux and other POSIX -systems has been changed away from often unsafe ``"fork"`` to ``"forkserver"`` -(when the platform supports sending file handles over pipes as most do) or -``"spawn"``. Mac and Windows are unchanged as they already default to -``"spawn"``. diff --git a/Misc/NEWS.d/next/Library/2024-09-19-03-46-59.gh-issue-87041.9Ox7Bv.rst b/Misc/NEWS.d/next/Library/2024-09-19-03-46-59.gh-issue-87041.9Ox7Bv.rst deleted file mode 100644 index 47a5f0c7ba520f..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-19-03-46-59.gh-issue-87041.9Ox7Bv.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a bug in :mod:`argparse` where lengthy subparser argument help is incorrectly indented. diff --git a/Misc/NEWS.d/next/Library/2024-09-19-10-36-18.gh-issue-81691.Hyhp_U.rst b/Misc/NEWS.d/next/Library/2024-09-19-10-36-18.gh-issue-81691.Hyhp_U.rst deleted file mode 100644 index 8f0108502efde6..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-19-10-36-18.gh-issue-81691.Hyhp_U.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix handling of multiple ``"--"`` (double dashes) in :mod:`argparse`. Only -the first one has now been removed, all subsequent ones are now taken -literally. diff --git a/Misc/NEWS.d/next/Library/2024-09-19-11-47-39.gh-issue-124248.g7rufd.rst b/Misc/NEWS.d/next/Library/2024-09-19-11-47-39.gh-issue-124248.g7rufd.rst deleted file mode 100644 index 1bd333f485a2ab..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-19-11-47-39.gh-issue-124248.g7rufd.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed potential crash when using :mod:`struct` to process zero-width -'Pascal string' fields (``0p``). diff --git a/Misc/NEWS.d/next/Library/2024-09-19-16-00-22.gh-issue-111513.6jHm02.rst b/Misc/NEWS.d/next/Library/2024-09-19-16-00-22.gh-issue-111513.6jHm02.rst deleted file mode 100644 index c6b85f9cd72255..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-19-16-00-22.gh-issue-111513.6jHm02.rst +++ /dev/null @@ -1 +0,0 @@ -Improve the error message that may be raised by :meth:`datetime.date.fromtimestamp`. diff --git a/Misc/NEWS.d/next/Library/2024-09-19-20-15-00.gh-issue-124217.j0KlQB.rst b/Misc/NEWS.d/next/Library/2024-09-19-20-15-00.gh-issue-124217.j0KlQB.rst deleted file mode 100644 index 46f9866f8d427c..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-19-20-15-00.gh-issue-124217.j0KlQB.rst +++ /dev/null @@ -1 +0,0 @@ -Add RFC 9637 reserved IPv6 block ``3fff::/20`` in :mod:`ipaddress` module. diff --git a/Misc/NEWS.d/next/Library/2024-09-20-12-23-11.gh-issue-53780.mrV1zi.rst b/Misc/NEWS.d/next/Library/2024-09-20-12-23-11.gh-issue-53780.mrV1zi.rst deleted file mode 100644 index fb700c722c8a8b..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-20-12-23-11.gh-issue-53780.mrV1zi.rst +++ /dev/null @@ -1 +0,0 @@ -:mod:`argparse` now ignores the first ``"--"`` (double dash) between an option and command. diff --git a/Misc/NEWS.d/next/Library/2024-09-20-18-23-19.gh-issue-100980.8nVAB6.rst b/Misc/NEWS.d/next/Library/2024-09-20-18-23-19.gh-issue-100980.8nVAB6.rst deleted file mode 100644 index 2279c205caeced..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-20-18-23-19.gh-issue-100980.8nVAB6.rst +++ /dev/null @@ -1,3 +0,0 @@ -The :attr:`~ctypes.Structure._fields_` attribute of -:class:`ctypes.Structure` and :class:`~ctypes.Union` is no longer set if -the setattr operation raises an error. diff --git a/Misc/NEWS.d/next/Library/2024-09-21-19-02-37.gh-issue-59317.OAhNZZ.rst b/Misc/NEWS.d/next/Library/2024-09-21-19-02-37.gh-issue-59317.OAhNZZ.rst deleted file mode 100644 index 0b1df9e3b7dea8..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-21-19-02-37.gh-issue-59317.OAhNZZ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix parsing positional argument with :ref:`nargs` equal to ``'?'`` or ``'*'`` -if it is preceded by an option and another positional argument. diff --git a/Misc/NEWS.d/next/Library/2024-09-21-22-32-21.gh-issue-72795.naLmkX.rst b/Misc/NEWS.d/next/Library/2024-09-21-22-32-21.gh-issue-72795.naLmkX.rst deleted file mode 100644 index 15c0918097367f..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-21-22-32-21.gh-issue-72795.naLmkX.rst +++ /dev/null @@ -1,4 +0,0 @@ -Positional arguments with :ref:`nargs` equal to ``'*'`` or -:data:`!argparse.REMAINDER` are no longer required. This allows to use -positional argument with ``nargs='*'`` and without ``default`` in mutually -exclusive group and improves error message about required arguments. diff --git a/Misc/NEWS.d/next/Library/2024-09-21-23-56-41.gh-issue-63143.YKu-LQ.rst b/Misc/NEWS.d/next/Library/2024-09-21-23-56-41.gh-issue-63143.YKu-LQ.rst deleted file mode 100644 index cb031fd601a9bd..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-21-23-56-41.gh-issue-63143.YKu-LQ.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix parsing mutually exclusive arguments in :mod:`argparse`. Arguments with -the value identical to the default value (e.g. booleans, small integers, -empty or 1-character strings) are no longer considered "not present". diff --git a/Misc/NEWS.d/next/Library/2024-09-23-17-33-47.gh-issue-104860.O86OSc.rst b/Misc/NEWS.d/next/Library/2024-09-23-17-33-47.gh-issue-104860.O86OSc.rst deleted file mode 100644 index 707c4d651cb5e6..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-23-17-33-47.gh-issue-104860.O86OSc.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix disallowing abbreviation of single-dash long options in :mod:`argparse` -with ``allow_abbrev=False``. diff --git a/Misc/NEWS.d/next/Library/2024-09-23-18-26-17.gh-issue-90562.Yj566G.rst b/Misc/NEWS.d/next/Library/2024-09-23-18-26-17.gh-issue-90562.Yj566G.rst deleted file mode 100644 index 7a389fefc6c54b..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-23-18-26-17.gh-issue-90562.Yj566G.rst +++ /dev/null @@ -1,3 +0,0 @@ -Modify dataclasses to support zero-argument super() when ``slots=True`` is -specified. This works by modifying all references to ``__class__`` to point -to the newly created class. diff --git a/Misc/NEWS.d/next/Library/2024-09-24-00-01-24.gh-issue-124400.0XCgfe.rst b/Misc/NEWS.d/next/Library/2024-09-24-00-01-24.gh-issue-124400.0XCgfe.rst deleted file mode 100644 index 25ee01e3108bf8..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-24-00-01-24.gh-issue-124400.0XCgfe.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed a :mod:`pdb` bug where ``until`` has no effect when it appears in a ``commands`` sequence. Also avoid printing the frame information at a breakpoint that has a command list containing a command that resumes execution. diff --git a/Misc/NEWS.d/next/Library/2024-09-24-12-34-48.gh-issue-124345.s3vKql.rst b/Misc/NEWS.d/next/Library/2024-09-24-12-34-48.gh-issue-124345.s3vKql.rst deleted file mode 100644 index dff902d8c6139a..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-24-12-34-48.gh-issue-124345.s3vKql.rst +++ /dev/null @@ -1,2 +0,0 @@ -:mod:`argparse` vim supports abbreviated single-dash long options separated -by ``=`` from its value. diff --git a/Misc/NEWS.d/next/Library/2024-09-24-13-32-16.gh-issue-124176.6hmOPz.rst b/Misc/NEWS.d/next/Library/2024-09-24-13-32-16.gh-issue-124176.6hmOPz.rst deleted file mode 100644 index 38c030668b6b42..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-24-13-32-16.gh-issue-124176.6hmOPz.rst +++ /dev/null @@ -1,4 +0,0 @@ -Add support for :func:`dataclasses.dataclass` in -:func:`unittest.mock.create_autospec`. Now ``create_autospec`` will check -for potential dataclasses and use :func:`dataclasses.fields` function to -retrieve the spec information. diff --git a/Misc/NEWS.d/next/Library/2024-09-24-19-32-14.gh-issue-123014.zVcfkZ.rst b/Misc/NEWS.d/next/Library/2024-09-24-19-32-14.gh-issue-123014.zVcfkZ.rst deleted file mode 100644 index 53dbabd9480ddb..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-24-19-32-14.gh-issue-123014.zVcfkZ.rst +++ /dev/null @@ -1,3 +0,0 @@ -:func:`os.pidfd_open` and :func:`signal.pidfd_send_signal` are now -unavailable when building against Android API levels older than 31, since -the underlying system calls may cause a crash. diff --git a/Misc/NEWS.d/next/Library/2024-09-24-21-15-27.gh-issue-123017.dSAr2f.rst b/Misc/NEWS.d/next/Library/2024-09-24-21-15-27.gh-issue-123017.dSAr2f.rst deleted file mode 100644 index 45fe4786fa6563..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-24-21-15-27.gh-issue-123017.dSAr2f.rst +++ /dev/null @@ -1,2 +0,0 @@ -Due to unreliable results on some devices, :func:`time.strftime` no longer -accepts negative years on Android. diff --git a/Misc/NEWS.d/next/Library/2024-09-24-22-38-51.gh-issue-123884.iEPTK4.rst b/Misc/NEWS.d/next/Library/2024-09-24-22-38-51.gh-issue-123884.iEPTK4.rst deleted file mode 100644 index 55f1d4b41125c3..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-24-22-38-51.gh-issue-123884.iEPTK4.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fixed bug in itertools.tee() handling of other tee inputs (a tee in a tee). -The output now has the promised *n* independent new iterators. Formerly, -the first iterator was identical (not independent) to the input iterator. -This would sometimes give surprising results. diff --git a/Misc/NEWS.d/next/Library/2024-09-25-10-25-57.gh-issue-53834.uyIckw.rst b/Misc/NEWS.d/next/Library/2024-09-25-10-25-57.gh-issue-53834.uyIckw.rst deleted file mode 100644 index 20ba1534f5e99d..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-25-10-25-57.gh-issue-53834.uyIckw.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fix support of arguments with :ref:`choices` in :mod:`argparse`. Positional -arguments with :ref:`nargs` equal to ``'?'`` or ``'*'`` no longer check -:ref:`default` against ``choices``. Optional arguments with ``nargs`` equal -to ``'?'`` no longer check :ref:`const` against ``choices``. diff --git a/Misc/NEWS.d/next/Library/2024-09-25-12-14-58.gh-issue-124498.Ozxs55.rst b/Misc/NEWS.d/next/Library/2024-09-25-12-14-58.gh-issue-124498.Ozxs55.rst deleted file mode 100644 index 4dbf4eb709733d..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-25-12-14-58.gh-issue-124498.Ozxs55.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix :class:`typing.TypeAliasType` not to be generic, when ``type_params`` is -an empty tuple. diff --git a/Misc/NEWS.d/next/Library/2024-09-25-18-07-51.gh-issue-120378.NlBSz_.rst b/Misc/NEWS.d/next/Library/2024-09-25-18-07-51.gh-issue-120378.NlBSz_.rst deleted file mode 100644 index 1a8c1427b6b9b9..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-25-18-07-51.gh-issue-120378.NlBSz_.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a crash related to an integer overflow in :func:`curses.resizeterm` -and :func:`curses.resize_term`. diff --git a/Misc/NEWS.d/next/Library/2024-09-25-18-08-29.gh-issue-80259.kO5Tw7.rst b/Misc/NEWS.d/next/Library/2024-09-25-18-08-29.gh-issue-80259.kO5Tw7.rst deleted file mode 100644 index bb451cdd9ae44c..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-25-18-08-29.gh-issue-80259.kO5Tw7.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix :mod:`argparse` support of positional arguments with ``nargs='?'``, -``default=argparse.SUPPRESS`` and specified ``type``. diff --git a/Misc/NEWS.d/next/Library/2024-09-25-18-34-48.gh-issue-124538.nXZk4R.rst b/Misc/NEWS.d/next/Library/2024-09-25-18-34-48.gh-issue-124538.nXZk4R.rst deleted file mode 100644 index 33ae037ae56b0b..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-25-18-34-48.gh-issue-124538.nXZk4R.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed crash when using :func:`gc.get_referents` on a capsule object. diff --git a/Misc/NEWS.d/next/Library/2024-09-25-22-06-52.gh-issue-124552.1nQKNM.rst b/Misc/NEWS.d/next/Library/2024-09-25-22-06-52.gh-issue-124552.1nQKNM.rst deleted file mode 100644 index 39dde4c774ba5d..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-25-22-06-52.gh-issue-124552.1nQKNM.rst +++ /dev/null @@ -1 +0,0 @@ -Improve the accuracy of :mod:`bdb`'s check for the possibility of breakpoint in a frame. This makes it possible to disable unnecessary events in functions. diff --git a/Misc/NEWS.d/next/Library/2024-09-26-00-35-24.gh-issue-116750.X1aMHI.rst b/Misc/NEWS.d/next/Library/2024-09-26-00-35-24.gh-issue-116750.X1aMHI.rst deleted file mode 100644 index cf9dacf4007c28..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-26-00-35-24.gh-issue-116750.X1aMHI.rst +++ /dev/null @@ -1 +0,0 @@ -Provide :func:`sys.monitoring.clear_tool_id` to unregister all events and callbacks set by the tool. diff --git a/Misc/NEWS.d/next/Library/2024-09-26-09-18-09.gh-issue-61181.dwjmch.rst b/Misc/NEWS.d/next/Library/2024-09-26-09-18-09.gh-issue-61181.dwjmch.rst deleted file mode 100644 index 801a5fdd4abd4f..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-26-09-18-09.gh-issue-61181.dwjmch.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix support of :ref:`choices` with string value in :mod:`argparse`. Substrings -of the specified string no longer considered valid values. diff --git a/Misc/NEWS.d/next/Library/2024-09-26-13-43-39.gh-issue-124594.peYhsP.rst b/Misc/NEWS.d/next/Library/2024-09-26-13-43-39.gh-issue-124594.peYhsP.rst deleted file mode 100644 index ac48bd84930745..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-26-13-43-39.gh-issue-124594.peYhsP.rst +++ /dev/null @@ -1 +0,0 @@ -All :mod:`asyncio` REPL prompts run in the same :class:`context `. Contributed by Bartosz Sławecki. diff --git a/Misc/NEWS.d/next/Library/2024-09-26-22-14-12.gh-issue-58573.hozbm9.rst b/Misc/NEWS.d/next/Library/2024-09-26-22-14-12.gh-issue-58573.hozbm9.rst deleted file mode 100644 index 37d64ee536ff49..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-26-22-14-12.gh-issue-58573.hozbm9.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix conflicts between abbreviated long options in the parent parser and -subparsers in :mod:`argparse`. diff --git a/Misc/NEWS.d/next/Library/2024-09-27-06-39-32.gh-issue-101552.xYkzag.rst b/Misc/NEWS.d/next/Library/2024-09-27-06-39-32.gh-issue-101552.xYkzag.rst deleted file mode 100644 index 913a84de5fe6a3..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-27-06-39-32.gh-issue-101552.xYkzag.rst +++ /dev/null @@ -1,4 +0,0 @@ -Add an *annoation_format* parameter to :func:`inspect.signature`. Add an -*quote_annotation_strings* parameter to :meth:`inspect.Signature.format`. Use the -new functionality to improve the display of annotations in signatures in -:mod:`pydoc`. Patch by Jelle Zijlstra. diff --git a/Misc/NEWS.d/next/Library/2024-09-27-15-16-04.gh-issue-116850.dBkR0-.rst b/Misc/NEWS.d/next/Library/2024-09-27-15-16-04.gh-issue-116850.dBkR0-.rst deleted file mode 100644 index 62639a16c52aa0..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-27-15-16-04.gh-issue-116850.dBkR0-.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix :mod:`argparse` for namespaces with not directly writable dict (e.g. -classes). diff --git a/Misc/NEWS.d/next/Library/2024-09-30-19-59-28.gh-issue-66436.4gYN_n.rst b/Misc/NEWS.d/next/Library/2024-09-30-19-59-28.gh-issue-66436.4gYN_n.rst deleted file mode 100644 index 69a77b01902873..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-30-19-59-28.gh-issue-66436.4gYN_n.rst +++ /dev/null @@ -1,4 +0,0 @@ -Improved :ref:`prog` default value for :class:`argparse.ArgumentParser`. It -will now include the name of the Python executable along with the module or -package name, or the path to a directory, ZIP file, or directory within a -ZIP file if the code was run that way. diff --git a/Misc/NEWS.d/next/Library/2024-09-30-20-46-32.gh-issue-124787.3FnJnP.rst b/Misc/NEWS.d/next/Library/2024-09-30-20-46-32.gh-issue-124787.3FnJnP.rst deleted file mode 100644 index d9d1bbcf5a2fe4..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-30-20-46-32.gh-issue-124787.3FnJnP.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fix :class:`typing.TypeAliasType` with incorrect ``type_params`` argument. -Now it raises a :exc:`TypeError` when a type parameter without a default -follows one with a default, and when an entry in the ``type_params`` tuple -is not a type parameter object. diff --git a/Misc/NEWS.d/next/Library/2024-10-01-02-31-13.gh-issue-124693.qzbXKB.rst b/Misc/NEWS.d/next/Library/2024-10-01-02-31-13.gh-issue-124693.qzbXKB.rst deleted file mode 100644 index 3e87eb457d9911..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-01-02-31-13.gh-issue-124693.qzbXKB.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a bug where :mod:`argparse` doesn't recognize negative complex numbers or negative numbers using scientific notation. diff --git a/Misc/NEWS.d/next/Library/2024-10-01-12-43-42.gh-issue-124835.SVyp3K.rst b/Misc/NEWS.d/next/Library/2024-10-01-12-43-42.gh-issue-124835.SVyp3K.rst deleted file mode 100644 index 09e5a046f83e49..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-01-12-43-42.gh-issue-124835.SVyp3K.rst +++ /dev/null @@ -1,3 +0,0 @@ -Make :func:`tomllib.loads` raise :exc:`TypeError` not :exc:`AttributeError` -on bad input types that do not have the ``replace`` attribute. Improve error -message when :class:`bytes` is received. diff --git a/Misc/NEWS.d/next/Library/2024-10-01-13-11-53.gh-issue-85935.CTwJUy.rst b/Misc/NEWS.d/next/Library/2024-10-01-13-11-53.gh-issue-85935.CTwJUy.rst deleted file mode 100644 index 553f206bf26337..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-01-13-11-53.gh-issue-85935.CTwJUy.rst +++ /dev/null @@ -1,4 +0,0 @@ -:meth:`argparse.ArgumentParser.add_argument` now raises an exception if -an :ref:`action` that does not consume arguments (like 'store_const' or -'store_true') or explicit ``nargs=0`` are specified for positional -arguments. diff --git a/Misc/NEWS.d/next/Library/2024-10-01-13-46-58.gh-issue-124390.dK1Zcm.rst b/Misc/NEWS.d/next/Library/2024-10-01-13-46-58.gh-issue-124390.dK1Zcm.rst deleted file mode 100644 index 89610fa44bf743..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-01-13-46-58.gh-issue-124390.dK1Zcm.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed :exc:`AssertionError` when using :func:`!asyncio.staggered.staggered_race` with :attr:`asyncio.eager_task_factory`. diff --git a/Misc/NEWS.d/next/Library/2024-10-01-17-12-20.gh-issue-124858.Zy0tvT.rst b/Misc/NEWS.d/next/Library/2024-10-01-17-12-20.gh-issue-124858.Zy0tvT.rst deleted file mode 100644 index c05d24a7c5aacb..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-01-17-12-20.gh-issue-124858.Zy0tvT.rst +++ /dev/null @@ -1 +0,0 @@ -Fix reference cycles left in tracebacks in :func:`asyncio.open_connection` when used with ``happy_eyeballs_delay`` diff --git a/Misc/NEWS.d/next/Library/2024-10-01-23-29-09.gh-issue-91818.Kz8cPI.rst b/Misc/NEWS.d/next/Library/2024-10-01-23-29-09.gh-issue-91818.Kz8cPI.rst deleted file mode 100644 index f45f00e48a3830..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-01-23-29-09.gh-issue-91818.Kz8cPI.rst +++ /dev/null @@ -1,4 +0,0 @@ -The CLI of many modules (:mod:`ast`, :mod:`ensurepip`, :mod:`json`, -:mod:`pdb`, :mod:`sqlite3`, :mod:`tokenize`, :mod:`venv`) now uses the -actual executable name instead of simply "python" to display in the usage -message. diff --git a/Misc/NEWS.d/next/Library/2024-10-02-15-05-45.gh-issue-124653.tqsTu9.rst b/Misc/NEWS.d/next/Library/2024-10-02-15-05-45.gh-issue-124653.tqsTu9.rst deleted file mode 100644 index 6f5ad12d2c2981..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-02-15-05-45.gh-issue-124653.tqsTu9.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix detection of the minimal Queue API needed by the :mod:`logging` module. -Patch by Bénédikt Tran. diff --git a/Misc/NEWS.d/next/Library/2024-10-02-16-35-07.gh-issue-65865.S2D4wq.rst b/Misc/NEWS.d/next/Library/2024-10-02-16-35-07.gh-issue-65865.S2D4wq.rst deleted file mode 100644 index 106a8b81140520..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-02-16-35-07.gh-issue-65865.S2D4wq.rst +++ /dev/null @@ -1,3 +0,0 @@ -:mod:`argparse` now raises early error for invalid ``help`` arguments to -:meth:`~argparse.ArgumentParser.add_argument`, -:meth:`~argparse.ArgumentParser.add_subparsers` and :meth:`!add_parser`. diff --git a/Misc/NEWS.d/next/Library/2024-10-02-21-11-18.gh-issue-124917.Lnwh5b.rst b/Misc/NEWS.d/next/Library/2024-10-02-21-11-18.gh-issue-124917.Lnwh5b.rst deleted file mode 100644 index f208793859bbf8..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-02-21-11-18.gh-issue-124917.Lnwh5b.rst +++ /dev/null @@ -1,2 +0,0 @@ -Allow calling :func:`os.path.exists` and :func:`os.path.lexists` with -keyword arguments on Windows. Fixes a regression in 3.13.0. diff --git a/Misc/NEWS.d/next/Library/2024-10-02-22-53-48.gh-issue-90102.4qX52R.rst b/Misc/NEWS.d/next/Library/2024-10-02-22-53-48.gh-issue-90102.4qX52R.rst deleted file mode 100644 index 0e708ed11d21b5..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-02-22-53-48.gh-issue-90102.4qX52R.rst +++ /dev/null @@ -1,3 +0,0 @@ -Skip the ``isatty`` system call during open() when the file is known to not -be a character device. This provides a slight performance improvement when -reading whole files. diff --git a/Misc/NEWS.d/next/Library/2024-10-03-05-00-25.gh-issue-117151.Prdw_W.rst b/Misc/NEWS.d/next/Library/2024-10-03-05-00-25.gh-issue-117151.Prdw_W.rst deleted file mode 100644 index a7d6251f1e071f..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-03-05-00-25.gh-issue-117151.Prdw_W.rst +++ /dev/null @@ -1,3 +0,0 @@ -The default buffer size used by :func:`shutil.copyfileobj` has been -increased from 64k to 256k on non-Windows platforms. It was already larger -on Windows. diff --git a/Misc/NEWS.d/next/Library/2024-10-03-17-13-22.gh-issue-124944.YyLAzf.rst b/Misc/NEWS.d/next/Library/2024-10-03-17-13-22.gh-issue-124944.YyLAzf.rst deleted file mode 100644 index 66af712c5ae5a8..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-03-17-13-22.gh-issue-124944.YyLAzf.rst +++ /dev/null @@ -1 +0,0 @@ -Add ``SO_ORIGINAL_DST`` to the :mod:`socket` module. diff --git a/Misc/NEWS.d/next/Library/2024-10-03-19-16-38.gh-issue-123961.ik1Dgs.rst b/Misc/NEWS.d/next/Library/2024-10-03-19-16-38.gh-issue-123961.ik1Dgs.rst deleted file mode 100644 index b637b895d0b803..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-03-19-16-38.gh-issue-123961.ik1Dgs.rst +++ /dev/null @@ -1,2 +0,0 @@ -Convert :mod:`curses` to multi-phase initialization (:pep:`489`), thereby -fixing reference leaks at interpreter shutdown. Patch by Bénédikt Tran. diff --git a/Misc/NEWS.d/next/Library/2024-10-03-20-45-57.gh-issue-53203.3Sk4Ia.rst b/Misc/NEWS.d/next/Library/2024-10-03-20-45-57.gh-issue-53203.3Sk4Ia.rst deleted file mode 100644 index 6895cffcf545fd..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-03-20-45-57.gh-issue-53203.3Sk4Ia.rst +++ /dev/null @@ -1,5 +0,0 @@ -Fix :func:`time.strptime` for ``%c`` and ``%x`` formats in many locales: -Arabic, Bislama, Breton, Bodo, Kashubian, Chuvash, Estonian, French, Irish, -Ge'ez, Gurajati, Manx Gaelic, Hebrew, Hindi, Chhattisgarhi, Haitian Kreyol, -Japanese, Kannada, Korean, Marathi, Malay, Norwegian, Nynorsk, Punjabi, -Rajasthani, Tok Pisin, Yoruba, Yue Chinese, Yau/Nungon and Chinese. diff --git a/Misc/NEWS.d/next/Library/2024-10-04-08-46-00.gh-issue-124958.rea9-x.rst b/Misc/NEWS.d/next/Library/2024-10-04-08-46-00.gh-issue-124958.rea9-x.rst deleted file mode 100644 index 534d5bb8c898da..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-04-08-46-00.gh-issue-124958.rea9-x.rst +++ /dev/null @@ -1 +0,0 @@ -Fix refcycles in exceptions raised from :class:`asyncio.TaskGroup` and the python implementation of :class:`asyncio.Future` diff --git a/Misc/NEWS.d/next/Library/2024-10-04-12-43-03.gh-issue-69998.DVqOXX.rst b/Misc/NEWS.d/next/Library/2024-10-04-12-43-03.gh-issue-69998.DVqOXX.rst deleted file mode 100644 index 65388e0b4e7ee4..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-04-12-43-03.gh-issue-69998.DVqOXX.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix :func:`locale.nl_langinfo` in case when different categories have -different locales. The function now sets temporarily the ``LC_CTYPE`` locale -in some cases. This temporary change affects other threads. diff --git a/Misc/NEWS.d/next/Library/2024-10-05-15-49-53.gh-issue-124960.Bol9hT.rst b/Misc/NEWS.d/next/Library/2024-10-05-15-49-53.gh-issue-124960.Bol9hT.rst deleted file mode 100644 index 332d6bb54d80c7..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-05-15-49-53.gh-issue-124960.Bol9hT.rst +++ /dev/null @@ -1 +0,0 @@ -Fix support for the ``barry_as_FLUFL`` future flag in the new REPL. diff --git a/Misc/NEWS.d/next/Library/2024-10-08-12-09-09.gh-issue-124969._VBQLq.rst b/Misc/NEWS.d/next/Library/2024-10-08-12-09-09.gh-issue-124969._VBQLq.rst deleted file mode 100644 index b5082b90721d42..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-08-12-09-09.gh-issue-124969._VBQLq.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix ``locale.nl_langinfo(locale.ALT_DIGITS)``. Now it returns a tuple of up -to 100 strings (an empty tuple on most locales). Previously it returned the -first item of that tuple or an empty string. diff --git a/Misc/NEWS.d/next/Library/2024-10-08-13-28-22.gh-issue-125096.Vz0W5g.rst b/Misc/NEWS.d/next/Library/2024-10-08-13-28-22.gh-issue-125096.Vz0W5g.rst deleted file mode 100644 index c582a2dfe7243c..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-08-13-28-22.gh-issue-125096.Vz0W5g.rst +++ /dev/null @@ -1,5 +0,0 @@ -If the :envvar:`PYTHON_BASIC_REPL` environment variable is set, the -:mod:`site` module no longer imports the :mod:`!_pyrepl` module. Moreover, -the :mod:`site` module now respects :option:`-E` and :option:`-I` command -line options: ignore :envvar:`PYTHON_BASIC_REPL` in this case. Patch by -Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2024-10-08-21-17-16.gh-issue-125069.0RP0Mx.rst b/Misc/NEWS.d/next/Library/2024-10-08-21-17-16.gh-issue-125069.0RP0Mx.rst deleted file mode 100644 index 9f1fd871e1d0b5..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-08-21-17-16.gh-issue-125069.0RP0Mx.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fix an issue where providing a :class:`pathlib.PurePath` object as an -initializer argument to a second :class:`~pathlib.PurePath` object with a -different :attr:`~pathlib.PurePath.parser` resulted in arguments to the -former object's initializer being joined by the latter object's parser. diff --git a/Misc/NEWS.d/next/Library/2024-10-09-07-09-00.gh-issue-125118.J9rQ1S.rst b/Misc/NEWS.d/next/Library/2024-10-09-07-09-00.gh-issue-125118.J9rQ1S.rst deleted file mode 100644 index 5d57cdbbbc2fe9..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-09-07-09-00.gh-issue-125118.J9rQ1S.rst +++ /dev/null @@ -1 +0,0 @@ -Don't copy arbitrary values to :c:expr:`_Bool` in the :mod:`struct` module. diff --git a/Misc/NEWS.d/next/Library/2024-10-09-21-42-43.gh-issue-61011.pQXZb1.rst b/Misc/NEWS.d/next/Library/2024-10-09-21-42-43.gh-issue-61011.pQXZb1.rst deleted file mode 100644 index 20f9c0b9c78b12..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-09-21-42-43.gh-issue-61011.pQXZb1.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fix inheritance of nested mutually exclusive groups from parent parser in -:class:`argparse.ArgumentParser`. Previously, all nested mutually exclusive -groups lost their connection to the group containing them and were displayed -as belonging directly to the parser. diff --git a/Misc/NEWS.d/next/Library/2024-10-10-18-33-31.gh-issue-125235.0kOB5I.rst b/Misc/NEWS.d/next/Library/2024-10-10-18-33-31.gh-issue-125235.0kOB5I.rst deleted file mode 100644 index f64d15917da1fc..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-10-18-33-31.gh-issue-125235.0kOB5I.rst +++ /dev/null @@ -1,2 +0,0 @@ -Keep :mod:`tkinter` TCL paths in venv pointing to base installation on -Windows. diff --git a/Misc/NEWS.d/next/Library/2024-10-10-19-57-35.gh-issue-125254.RtZxXS.rst b/Misc/NEWS.d/next/Library/2024-10-10-19-57-35.gh-issue-125254.RtZxXS.rst deleted file mode 100644 index abe37fefedc3be..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-10-19-57-35.gh-issue-125254.RtZxXS.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a bug where ArgumentError includes the incorrect ambiguous option in :mod:`argparse`. diff --git a/Misc/NEWS.d/next/Library/2024-10-10-20-39-57.gh-issue-125243.eUbbtu.rst b/Misc/NEWS.d/next/Library/2024-10-10-20-39-57.gh-issue-125243.eUbbtu.rst deleted file mode 100644 index 49f84d9711819f..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-10-20-39-57.gh-issue-125243.eUbbtu.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix data race when creating :class:`zoneinfo.ZoneInfo` objects in the free -threading build. diff --git a/Misc/NEWS.d/next/Library/2024-10-11-04-04-38.gh-issue-125260.PeZ0Mb.rst b/Misc/NEWS.d/next/Library/2024-10-11-04-04-38.gh-issue-125260.PeZ0Mb.rst deleted file mode 100644 index fab524ea0185c2..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-11-04-04-38.gh-issue-125260.PeZ0Mb.rst +++ /dev/null @@ -1,2 +0,0 @@ -The :func:`gzip.compress` *mtime* parameter now defaults to 0 for reproducible output. -Patch by Bernhard M. Wiedemann and Adam Turner. diff --git a/Misc/NEWS.d/next/Library/2024-10-11-16-19-46.gh-issue-89967.vhWUOR.rst b/Misc/NEWS.d/next/Library/2024-10-11-16-19-46.gh-issue-89967.vhWUOR.rst deleted file mode 100644 index d0860457c8e813..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-11-16-19-46.gh-issue-89967.vhWUOR.rst +++ /dev/null @@ -1 +0,0 @@ -Make :class:`~weakref.WeakKeyDictionary` and :class:`~weakref.WeakValueDictionary` safe against concurrent mutations from other threads. Patch by Kumar Aditya. diff --git a/Misc/NEWS.d/next/Library/2024-10-11-18-03-05.gh-issue-125206.pWRRK6.rst b/Misc/NEWS.d/next/Library/2024-10-11-18-03-05.gh-issue-125206.pWRRK6.rst deleted file mode 100644 index ef7975ebcb376b..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-11-18-03-05.gh-issue-125206.pWRRK6.rst +++ /dev/null @@ -1,2 +0,0 @@ -Workaround for old libffi versions is added. Module ctypes supports -:c:expr:`double complex` only with libffi >= 3.3.0. Patch by Mikhail Efimov. diff --git a/Misc/NEWS.d/next/Library/2024-10-13-20-21-35.gh-issue-53203.Rz1c8A.rst b/Misc/NEWS.d/next/Library/2024-10-13-20-21-35.gh-issue-53203.Rz1c8A.rst deleted file mode 100644 index cdfa8c191e8242..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-13-20-21-35.gh-issue-53203.Rz1c8A.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix :func:`time.strptime` for ``%c``, ``%x`` and ``%X`` formats in many -locales that use non-ASCII digits, like Persian, Burmese, Odia and Shan. diff --git a/Misc/NEWS.d/next/Library/2024-10-14-02-27-03.gh-issue-100141.NuAcwa.rst b/Misc/NEWS.d/next/Library/2024-10-14-02-27-03.gh-issue-100141.NuAcwa.rst deleted file mode 100644 index c366b0ad4040d3..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-14-02-27-03.gh-issue-100141.NuAcwa.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed the bug where :mod:`pdb` will be stuck in an infinite loop when debugging an empty file. diff --git a/Misc/NEWS.d/next/Library/2024-10-14-04-44-12.gh-issue-125422.MlVuC6.rst b/Misc/NEWS.d/next/Library/2024-10-14-04-44-12.gh-issue-125422.MlVuC6.rst deleted file mode 100644 index c890ecec8beaf8..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-10-14-04-44-12.gh-issue-125422.MlVuC6.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed the bug where :mod:`pdb` and :mod:`bdb` can step into the bottom caller frame. diff --git a/Misc/NEWS.d/next/Security/2024-05-01-20-57-09.gh-issue-118486.K44KJG.rst b/Misc/NEWS.d/next/Security/2024-05-01-20-57-09.gh-issue-118486.K44KJG.rst deleted file mode 100644 index 8ac48aac816a60..00000000000000 --- a/Misc/NEWS.d/next/Security/2024-05-01-20-57-09.gh-issue-118486.K44KJG.rst +++ /dev/null @@ -1,4 +0,0 @@ -:func:`os.mkdir` on Windows now accepts *mode* of ``0o700`` to restrict -the new directory to the current user. This fixes :cve:`2024-4030` -affecting :func:`tempfile.mkdtemp` in scenarios where the base temporary -directory is more permissive than the default. diff --git a/Misc/NEWS.d/next/Security/2024-05-08-21-59-38.gh-issue-118773.7dFRJY.rst b/Misc/NEWS.d/next/Security/2024-05-08-21-59-38.gh-issue-118773.7dFRJY.rst deleted file mode 100644 index bfec178f6318a7..00000000000000 --- a/Misc/NEWS.d/next/Security/2024-05-08-21-59-38.gh-issue-118773.7dFRJY.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixes creation of ACLs in :func:`os.mkdir` on Windows to work correctly on -non-English machines. diff --git a/Misc/NEWS.d/next/Security/2024-06-25-04-42-43.gh-issue-112301.god4IC.rst b/Misc/NEWS.d/next/Security/2024-06-25-04-42-43.gh-issue-112301.god4IC.rst deleted file mode 100644 index 68058a06f0bf49..00000000000000 --- a/Misc/NEWS.d/next/Security/2024-06-25-04-42-43.gh-issue-112301.god4IC.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add default compiler options to improve security. Enable --Wimplicit-fallthrough, -fstack-protector-strong, -Wtrampolines. diff --git a/Misc/NEWS.d/next/Security/2024-07-02-13-39-20.gh-issue-121285.hrl-yI.rst b/Misc/NEWS.d/next/Security/2024-07-02-13-39-20.gh-issue-121285.hrl-yI.rst deleted file mode 100644 index 81f918bfe2b255..00000000000000 --- a/Misc/NEWS.d/next/Security/2024-07-02-13-39-20.gh-issue-121285.hrl-yI.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove backtracking from tarfile header parsing for ``hdrcharset``, PAX, and -GNU sparse headers. diff --git a/Misc/NEWS.d/next/Security/2024-07-08-23-39-04.gh-issue-112301.TD8G01.rst b/Misc/NEWS.d/next/Security/2024-07-08-23-39-04.gh-issue-112301.TD8G01.rst deleted file mode 100644 index d9b48993a2fb1a..00000000000000 --- a/Misc/NEWS.d/next/Security/2024-07-08-23-39-04.gh-issue-112301.TD8G01.rst +++ /dev/null @@ -1,2 +0,0 @@ -Enable runtime protections for glibc to abort execution when unsafe behavior is encountered, -for all platforms except Windows. diff --git a/Misc/NEWS.d/next/Security/2024-07-18-13-17-47.gh-issue-121957.QemKLU.rst b/Misc/NEWS.d/next/Security/2024-07-18-13-17-47.gh-issue-121957.QemKLU.rst deleted file mode 100644 index 49ccc5e14633cd..00000000000000 --- a/Misc/NEWS.d/next/Security/2024-07-18-13-17-47.gh-issue-121957.QemKLU.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fixed missing audit events around interactive use of Python, now also -properly firing for ``python -i``, as well as for ``python -m asyncio``. The -events in question are ``cpython.run_stdin`` and ``cpython.run_startup``. diff --git a/Misc/NEWS.d/next/Security/2024-07-22-13-11-28.gh-issue-122133.0mPeta.rst b/Misc/NEWS.d/next/Security/2024-07-22-13-11-28.gh-issue-122133.0mPeta.rst deleted file mode 100644 index 3544eb3824d0da..00000000000000 --- a/Misc/NEWS.d/next/Security/2024-07-22-13-11-28.gh-issue-122133.0mPeta.rst +++ /dev/null @@ -1,5 +0,0 @@ -Authenticate the socket connection for the ``socket.socketpair()`` fallback -on platforms where ``AF_UNIX`` is not available like Windows. - -Patch by Gregory P. Smith and Seth Larson . Reported by Ellie - diff --git a/Misc/NEWS.d/next/Security/2024-07-24-05-18-25.gh-issue-112301.lfINgZ.rst b/Misc/NEWS.d/next/Security/2024-07-24-05-18-25.gh-issue-112301.lfINgZ.rst deleted file mode 100644 index 81237e735ebdb7..00000000000000 --- a/Misc/NEWS.d/next/Security/2024-07-24-05-18-25.gh-issue-112301.lfINgZ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add macOS warning tracking to warning check tooling. -Patch by Nate Ohlson. diff --git a/Misc/NEWS.d/next/Security/2024-08-06-00-06-23.gh-issue-112301.4k4lw6.rst b/Misc/NEWS.d/next/Security/2024-08-06-00-06-23.gh-issue-112301.4k4lw6.rst deleted file mode 100644 index 0bd2f4d7810a78..00000000000000 --- a/Misc/NEWS.d/next/Security/2024-08-06-00-06-23.gh-issue-112301.4k4lw6.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add ability to ignore warnings per file with warning count in warning checking tooling. -Patch by Nate Ohlson. diff --git a/Misc/NEWS.d/next/Security/2024-08-07-10-42-13.gh-issue-122792.oiTMo9.rst b/Misc/NEWS.d/next/Security/2024-08-07-10-42-13.gh-issue-122792.oiTMo9.rst deleted file mode 100644 index 18e293ba0c03b5..00000000000000 --- a/Misc/NEWS.d/next/Security/2024-08-07-10-42-13.gh-issue-122792.oiTMo9.rst +++ /dev/null @@ -1,3 +0,0 @@ -Changed IPv4-mapped ``ipaddress.IPv6Address`` to consistently use the mapped IPv4 -address value for deciding properties. Properties which have their behavior fixed -are ``is_multicast``, ``is_reserved``, ``is_link_local``, ``is_global``, and ``is_unspecified``. diff --git a/Misc/NEWS.d/next/Security/2024-08-14-19-43-57.gh-issue-112301.IQUcOy.rst b/Misc/NEWS.d/next/Security/2024-08-14-19-43-57.gh-issue-112301.IQUcOy.rst deleted file mode 100644 index 9750cf203eef86..00000000000000 --- a/Misc/NEWS.d/next/Security/2024-08-14-19-43-57.gh-issue-112301.IQUcOy.rst +++ /dev/null @@ -1 +0,0 @@ -Enable compiler options that warn of potential security vulnerabilities. diff --git a/Misc/NEWS.d/next/Security/2024-09-04-12-41-35.gh-issue-123678.N41y9n.rst b/Misc/NEWS.d/next/Security/2024-09-04-12-41-35.gh-issue-123678.N41y9n.rst deleted file mode 100644 index b70f578415fdc2..00000000000000 --- a/Misc/NEWS.d/next/Security/2024-09-04-12-41-35.gh-issue-123678.N41y9n.rst +++ /dev/null @@ -1 +0,0 @@ -Upgrade libexpat to 2.6.3 diff --git a/Misc/NEWS.d/next/Security/2024-10-09-20-08-13.gh-issue-125140.YgNWRB.rst b/Misc/NEWS.d/next/Security/2024-10-09-20-08-13.gh-issue-125140.YgNWRB.rst deleted file mode 100644 index f4a49302372647..00000000000000 --- a/Misc/NEWS.d/next/Security/2024-10-09-20-08-13.gh-issue-125140.YgNWRB.rst +++ /dev/null @@ -1 +0,0 @@ -Remove the current directory from ``sys.path`` when using PyREPL. diff --git a/Misc/NEWS.d/next/Tests/2023-08-03-17-26-55.gh-issue-107562.ZnbscS.rst b/Misc/NEWS.d/next/Tests/2023-08-03-17-26-55.gh-issue-107562.ZnbscS.rst deleted file mode 100644 index cc368d4bdffbd2..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-08-03-17-26-55.gh-issue-107562.ZnbscS.rst +++ /dev/null @@ -1,3 +0,0 @@ -Test certificates have been updated to expire far in the future. This allows -testing Y2038 with system time set to after that, so that actual Y2038 -issues can be exposed, and not masked by expired certificate errors. diff --git a/Misc/NEWS.d/next/Tests/2024-05-04-22-56-41.gh-issue-101525.LHK166.rst b/Misc/NEWS.d/next/Tests/2024-05-04-22-56-41.gh-issue-101525.LHK166.rst deleted file mode 100644 index ae8001ad373119..00000000000000 --- a/Misc/NEWS.d/next/Tests/2024-05-04-22-56-41.gh-issue-101525.LHK166.rst +++ /dev/null @@ -1,2 +0,0 @@ -Skip ``test_gdb`` if the binary is relocated by BOLT. -Patch by Donghee Na. diff --git a/Misc/NEWS.d/next/Tests/2024-05-18-10-59-27.gh-issue-119050.g4qiH7.rst b/Misc/NEWS.d/next/Tests/2024-05-18-10-59-27.gh-issue-119050.g4qiH7.rst deleted file mode 100644 index cfc70c16b2b279..00000000000000 --- a/Misc/NEWS.d/next/Tests/2024-05-18-10-59-27.gh-issue-119050.g4qiH7.rst +++ /dev/null @@ -1,2 +0,0 @@ -regrtest test runner: Add XML support to the refleak checker (-R option). -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Tests/2024-05-20-18-06-31.gh-issue-119273.hf-yhX.rst b/Misc/NEWS.d/next/Tests/2024-05-20-18-06-31.gh-issue-119273.hf-yhX.rst deleted file mode 100644 index 905b4e3a1c9043..00000000000000 --- a/Misc/NEWS.d/next/Tests/2024-05-20-18-06-31.gh-issue-119273.hf-yhX.rst +++ /dev/null @@ -1,3 +0,0 @@ -Python test runner no longer runs tests using TTY (ex: test_ioctl) in a -process group (using ``setsid()``). Previously, tests using TTY were -skipped. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Tests/2024-05-29-15-28-08.gh-issue-119727.dVkaZM.rst b/Misc/NEWS.d/next/Tests/2024-05-29-15-28-08.gh-issue-119727.dVkaZM.rst deleted file mode 100644 index bf28d8bb77b8a2..00000000000000 --- a/Misc/NEWS.d/next/Tests/2024-05-29-15-28-08.gh-issue-119727.dVkaZM.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add ``--single-process`` command line option to Python test runner (regrtest). -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Tests/2024-06-20-12-51-26.gh-issue-120801.lMVXC9.rst b/Misc/NEWS.d/next/Tests/2024-06-20-12-51-26.gh-issue-120801.lMVXC9.rst deleted file mode 100644 index 8559cb8b99c384..00000000000000 --- a/Misc/NEWS.d/next/Tests/2024-06-20-12-51-26.gh-issue-120801.lMVXC9.rst +++ /dev/null @@ -1,2 +0,0 @@ -Cleaned up fixtures for importlib.metadata tests and consolidated behavior -with 'test.support.os_helper'. diff --git a/Misc/NEWS.d/next/Tests/2024-07-01-09-04-32.gh-issue-121188.XbuTVa.rst b/Misc/NEWS.d/next/Tests/2024-07-01-09-04-32.gh-issue-121188.XbuTVa.rst deleted file mode 100644 index c92002d8fe3cd2..00000000000000 --- a/Misc/NEWS.d/next/Tests/2024-07-01-09-04-32.gh-issue-121188.XbuTVa.rst +++ /dev/null @@ -1,3 +0,0 @@ -When creating the JUnit XML file, regrtest now escapes characters which are -invalid in XML, such as the chr(27) control character used in ANSI escape -sequences. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Tests/2024-07-01-16-15-06.gh-issue-121200.4Pc-gc.rst b/Misc/NEWS.d/next/Tests/2024-07-01-16-15-06.gh-issue-121200.4Pc-gc.rst deleted file mode 100644 index 01e0d9b9f217d4..00000000000000 --- a/Misc/NEWS.d/next/Tests/2024-07-01-16-15-06.gh-issue-121200.4Pc-gc.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix ``test_expanduser_pwd2()`` of ``test_posixpath``. Call ``getpwnam()`` -to get ``pw_dir``, since it can be different than ``getpwall()`` ``pw_dir``. -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Tests/2024-07-03-14-41-00.gh-issue-121160.LEtiTd.rst b/Misc/NEWS.d/next/Tests/2024-07-03-14-41-00.gh-issue-121160.LEtiTd.rst deleted file mode 100644 index 2c8c9ac7201836..00000000000000 --- a/Misc/NEWS.d/next/Tests/2024-07-03-14-41-00.gh-issue-121160.LEtiTd.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add a test for :func:`readline.set_history_length`. Note that this test may -fail on readline libraries. diff --git a/Misc/NEWS.d/next/Tests/2024-07-04-15-10-29.gh-issue-121084.qxcd5d.rst b/Misc/NEWS.d/next/Tests/2024-07-04-15-10-29.gh-issue-121084.qxcd5d.rst deleted file mode 100644 index b91ea8acfadbf1..00000000000000 --- a/Misc/NEWS.d/next/Tests/2024-07-04-15-10-29.gh-issue-121084.qxcd5d.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix test_typing random leaks. Clear typing ABC caches when running tests for -refleaks (``-R`` option): call ``_abc_caches_clear()`` on typing abstract -classes and their subclasses. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Tests/2024-07-13-11-04-44.gh-issue-99242.aGxnwz.rst b/Misc/NEWS.d/next/Tests/2024-07-13-11-04-44.gh-issue-99242.aGxnwz.rst deleted file mode 100644 index 7d904f26a36ff2..00000000000000 --- a/Misc/NEWS.d/next/Tests/2024-07-13-11-04-44.gh-issue-99242.aGxnwz.rst +++ /dev/null @@ -1,3 +0,0 @@ -:func:`os.getloadavg` may throw :exc:`OSError` when running regression tests -under certain conditions (e.g. chroot). This error is now caught and -ignored, since reporting load average is optional. diff --git a/Misc/NEWS.d/next/Tests/2024-07-13-11-48-20.gh-issue-59022.fYNbQ8.rst b/Misc/NEWS.d/next/Tests/2024-07-13-11-48-20.gh-issue-59022.fYNbQ8.rst deleted file mode 100644 index e1acebe922cfdf..00000000000000 --- a/Misc/NEWS.d/next/Tests/2024-07-13-11-48-20.gh-issue-59022.fYNbQ8.rst +++ /dev/null @@ -1 +0,0 @@ -Add tests for :func:`pkgutil.extend_path`. Patch by Andreas Stocker. diff --git a/Misc/NEWS.d/next/Tests/2024-07-13-21-55-58.gh-issue-112301.YJS1dl.rst b/Misc/NEWS.d/next/Tests/2024-07-13-21-55-58.gh-issue-112301.YJS1dl.rst deleted file mode 100644 index d5718ed4be7606..00000000000000 --- a/Misc/NEWS.d/next/Tests/2024-07-13-21-55-58.gh-issue-112301.YJS1dl.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add tooling to check for changes in compiler warnings. -Patch by Nate Ohlson. diff --git a/Misc/NEWS.d/next/Tests/2024-07-17-08-25-06.gh-issue-121921.HW8CIS.rst b/Misc/NEWS.d/next/Tests/2024-07-17-08-25-06.gh-issue-121921.HW8CIS.rst deleted file mode 100644 index ef14fa9dfbd466..00000000000000 --- a/Misc/NEWS.d/next/Tests/2024-07-17-08-25-06.gh-issue-121921.HW8CIS.rst +++ /dev/null @@ -1,2 +0,0 @@ -Update ``Lib/test/crashers/bogus_code_obj.py`` so that it crashes properly -again. diff --git a/Misc/NEWS.d/next/Tests/2024-09-17-22-21-58.gh-issue-124190.3fWhiX.rst b/Misc/NEWS.d/next/Tests/2024-09-17-22-21-58.gh-issue-124190.3fWhiX.rst deleted file mode 100644 index 819b1ca49235fc..00000000000000 --- a/Misc/NEWS.d/next/Tests/2024-09-17-22-21-58.gh-issue-124190.3fWhiX.rst +++ /dev/null @@ -1 +0,0 @@ -Add capability to ignore entire files or directories in check warning CI tool diff --git a/Misc/NEWS.d/next/Tests/2024-09-18-18-39-21.gh-issue-124213.AQq_xg.rst b/Misc/NEWS.d/next/Tests/2024-09-18-18-39-21.gh-issue-124213.AQq_xg.rst deleted file mode 100644 index 021fbefb635af1..00000000000000 --- a/Misc/NEWS.d/next/Tests/2024-09-18-18-39-21.gh-issue-124213.AQq_xg.rst +++ /dev/null @@ -1,3 +0,0 @@ -Detect whether the test suite is running inside a systemd-nspawn container -with ``--suppress-sync=true`` option, and skip the ``test_os`` -and ``test_mmap`` tests that are failing in this scenario. diff --git a/Misc/NEWS.d/next/Tests/2024-09-25-12-39-34.gh-issue-124378.Ywwgia.rst b/Misc/NEWS.d/next/Tests/2024-09-25-12-39-34.gh-issue-124378.Ywwgia.rst deleted file mode 100644 index 9ddcca0eb6036d..00000000000000 --- a/Misc/NEWS.d/next/Tests/2024-09-25-12-39-34.gh-issue-124378.Ywwgia.rst +++ /dev/null @@ -1 +0,0 @@ -Updated ``test_ttk`` to pass with Tcl/Tk 8.6.15. diff --git a/Misc/NEWS.d/next/Tests/2024-10-07-14-13-38.gh-issue-125041.PKLWDf.rst b/Misc/NEWS.d/next/Tests/2024-10-07-14-13-38.gh-issue-125041.PKLWDf.rst deleted file mode 100644 index c7181eb9c1f3a9..00000000000000 --- a/Misc/NEWS.d/next/Tests/2024-10-07-14-13-38.gh-issue-125041.PKLWDf.rst +++ /dev/null @@ -1,3 +0,0 @@ -Re-enable skipped tests for :mod:`zlib` on the s390x architecture: only skip -checks of the compressed bytes, which can be different between zlib's -software implementation and the hardware-accelerated implementation. diff --git a/Misc/NEWS.d/next/Tools-Demos/2024-09-04-10-07-51.gh-issue-123418.1eIFZb.rst b/Misc/NEWS.d/next/Tools-Demos/2024-09-04-10-07-51.gh-issue-123418.1eIFZb.rst deleted file mode 100644 index fb9ac9e4f96725..00000000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2024-09-04-10-07-51.gh-issue-123418.1eIFZb.rst +++ /dev/null @@ -1,2 +0,0 @@ -Update GitHub CI workflows to use OpenSSL 3.0.15 and multissltests to use -3.0.15, 3.1.7, and 3.2.3. diff --git a/Misc/NEWS.d/next/Windows/2022-04-20-18-32-30.gh-issue-79846.Vggv3f.rst b/Misc/NEWS.d/next/Windows/2022-04-20-18-32-30.gh-issue-79846.Vggv3f.rst deleted file mode 100644 index 82c26701e0e0bc..00000000000000 --- a/Misc/NEWS.d/next/Windows/2022-04-20-18-32-30.gh-issue-79846.Vggv3f.rst +++ /dev/null @@ -1,2 +0,0 @@ -Makes :code:`ssl.create_default_context()` ignore invalid certificates in -the Windows certificate store diff --git a/Misc/NEWS.d/next/Windows/2024-04-24-05-16-32.gh-issue-118209.Ryyzlz.rst b/Misc/NEWS.d/next/Windows/2024-04-24-05-16-32.gh-issue-118209.Ryyzlz.rst deleted file mode 100644 index da70b2528919e1..00000000000000 --- a/Misc/NEWS.d/next/Windows/2024-04-24-05-16-32.gh-issue-118209.Ryyzlz.rst +++ /dev/null @@ -1,2 +0,0 @@ -Avoid crashing in :mod:`mmap` on Windows when the mapped memory is inaccessible -due to file system errors or access violations. diff --git a/Misc/NEWS.d/next/Windows/2024-04-24-22-50-33.gh-issue-117505.gcTb_p.rst b/Misc/NEWS.d/next/Windows/2024-04-24-22-50-33.gh-issue-117505.gcTb_p.rst deleted file mode 100644 index 0931687ecc521c..00000000000000 --- a/Misc/NEWS.d/next/Windows/2024-04-24-22-50-33.gh-issue-117505.gcTb_p.rst +++ /dev/null @@ -1 +0,0 @@ -Fixes an issue with the Windows installer not running ensurepip in a fully isolated environment. This could cause unexpected interactions with the user site-packages. diff --git a/Misc/NEWS.d/next/Windows/2024-05-22-19-43-29.gh-issue-119070._enton.rst b/Misc/NEWS.d/next/Windows/2024-05-22-19-43-29.gh-issue-119070._enton.rst deleted file mode 100644 index aab26f57209864..00000000000000 --- a/Misc/NEWS.d/next/Windows/2024-05-22-19-43-29.gh-issue-119070._enton.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fixes ``py.exe`` handling of shebangs like ``/usr/bin/env python3.12``, -which were previously interpreted as ``python3.exe`` instead of -``python3.12.exe``. diff --git a/Misc/NEWS.d/next/Windows/2024-05-25-18-43-10.gh-issue-111201.SLPJIx.rst b/Misc/NEWS.d/next/Windows/2024-05-25-18-43-10.gh-issue-111201.SLPJIx.rst deleted file mode 100644 index f3918ed633d78c..00000000000000 --- a/Misc/NEWS.d/next/Windows/2024-05-25-18-43-10.gh-issue-111201.SLPJIx.rst +++ /dev/null @@ -1 +0,0 @@ -Add support for new pyrepl on Windows diff --git a/Misc/NEWS.d/next/Windows/2024-05-29-11-06-12.gh-issue-119690.8q6e1p.rst b/Misc/NEWS.d/next/Windows/2024-05-29-11-06-12.gh-issue-119690.8q6e1p.rst deleted file mode 100644 index 84dd2161aa1db8..00000000000000 --- a/Misc/NEWS.d/next/Windows/2024-05-29-11-06-12.gh-issue-119690.8q6e1p.rst +++ /dev/null @@ -1 +0,0 @@ -Adds Unicode support and fixes audit events for ``_winapi.CreateNamedPipe``. diff --git a/Misc/NEWS.d/next/Windows/2024-05-30-17-39-25.gh-issue-119679.mZC87w.rst b/Misc/NEWS.d/next/Windows/2024-05-30-17-39-25.gh-issue-119679.mZC87w.rst deleted file mode 100644 index db9e798d3ddcb8..00000000000000 --- a/Misc/NEWS.d/next/Windows/2024-05-30-17-39-25.gh-issue-119679.mZC87w.rst +++ /dev/null @@ -1 +0,0 @@ -Ensures correct import libraries are included in Windows installs. diff --git a/Misc/NEWS.d/next/Windows/2024-07-19-21-50-54.gh-issue-100256.GDrKba.rst b/Misc/NEWS.d/next/Windows/2024-07-19-21-50-54.gh-issue-100256.GDrKba.rst deleted file mode 100644 index f0156ddd4772ed..00000000000000 --- a/Misc/NEWS.d/next/Windows/2024-07-19-21-50-54.gh-issue-100256.GDrKba.rst +++ /dev/null @@ -1 +0,0 @@ -:mod:`mimetypes` no longer fails when it encounters an inaccessible registry key. diff --git a/Misc/NEWS.d/next/Windows/2024-08-01-10-55-15.gh-issue-122573.4-UCFY.rst b/Misc/NEWS.d/next/Windows/2024-08-01-10-55-15.gh-issue-122573.4-UCFY.rst deleted file mode 100644 index 5cc69e206debf5..00000000000000 --- a/Misc/NEWS.d/next/Windows/2024-08-01-10-55-15.gh-issue-122573.4-UCFY.rst +++ /dev/null @@ -1 +0,0 @@ -The Windows build of CPython now requires 3.10 or newer. diff --git a/Misc/NEWS.d/next/Windows/2024-08-29-16-13-45.gh-issue-123476.m2DFS4.rst b/Misc/NEWS.d/next/Windows/2024-08-29-16-13-45.gh-issue-123476.m2DFS4.rst deleted file mode 100644 index 801214edc315ff..00000000000000 --- a/Misc/NEWS.d/next/Windows/2024-08-29-16-13-45.gh-issue-123476.m2DFS4.rst +++ /dev/null @@ -1 +0,0 @@ -Add support for ``socket.TCP_QUICKACK`` on Windows platforms. diff --git a/Misc/NEWS.d/next/Windows/2024-09-04-09-59-18.gh-issue-123418.QaMC12.rst b/Misc/NEWS.d/next/Windows/2024-09-04-09-59-18.gh-issue-123418.QaMC12.rst deleted file mode 100644 index c2b47dc40652dc..00000000000000 --- a/Misc/NEWS.d/next/Windows/2024-09-04-09-59-18.gh-issue-123418.QaMC12.rst +++ /dev/null @@ -1 +0,0 @@ -Updated Windows build to use OpenSSL 3.0.15. diff --git a/Misc/NEWS.d/next/Windows/2024-09-10-19-23-00.gh-issue-123915.yZMEDO.rst b/Misc/NEWS.d/next/Windows/2024-09-10-19-23-00.gh-issue-123915.yZMEDO.rst deleted file mode 100644 index 026b09d3601272..00000000000000 --- a/Misc/NEWS.d/next/Windows/2024-09-10-19-23-00.gh-issue-123915.yZMEDO.rst +++ /dev/null @@ -1 +0,0 @@ -Ensure that ``Tools\msi\buildrelease.bat`` uses different directories for AMD64 and ARM64 builds. diff --git a/Misc/NEWS.d/next/Windows/2024-09-20-11-18-50.gh-issue-124254.iPin-L.rst b/Misc/NEWS.d/next/Windows/2024-09-20-11-18-50.gh-issue-124254.iPin-L.rst deleted file mode 100644 index b93e356edb501d..00000000000000 --- a/Misc/NEWS.d/next/Windows/2024-09-20-11-18-50.gh-issue-124254.iPin-L.rst +++ /dev/null @@ -1 +0,0 @@ -Ensures experimental free-threaded binaries remain installed when updating. diff --git a/Misc/NEWS.d/next/Windows/2024-09-24-19-04-56.gh-issue-124448.srVT3d.rst b/Misc/NEWS.d/next/Windows/2024-09-24-19-04-56.gh-issue-124448.srVT3d.rst deleted file mode 100644 index ca9845a8daea9d..00000000000000 --- a/Misc/NEWS.d/next/Windows/2024-09-24-19-04-56.gh-issue-124448.srVT3d.rst +++ /dev/null @@ -1 +0,0 @@ -Updated bundled Tcl/Tk to 8.6.15. diff --git a/Misc/NEWS.d/next/Windows/2024-09-27-13-40-25.gh-issue-124609.WaKk8G.rst b/Misc/NEWS.d/next/Windows/2024-09-27-13-40-25.gh-issue-124609.WaKk8G.rst deleted file mode 100644 index 203868a8fee39c..00000000000000 --- a/Misc/NEWS.d/next/Windows/2024-09-27-13-40-25.gh-issue-124609.WaKk8G.rst +++ /dev/null @@ -1 +0,0 @@ -Fix ``_Py_ThreadId`` for Windows builds using MinGW. Patch by Tony Roberts. diff --git a/Misc/NEWS.d/next/Windows/2024-09-27-15-07-30.gh-issue-124487.7LrwHC.rst b/Misc/NEWS.d/next/Windows/2024-09-27-15-07-30.gh-issue-124487.7LrwHC.rst deleted file mode 100644 index 93fb68d28c702e..00000000000000 --- a/Misc/NEWS.d/next/Windows/2024-09-27-15-07-30.gh-issue-124487.7LrwHC.rst +++ /dev/null @@ -1 +0,0 @@ -Increases Windows required OS and API level to Windows 10. diff --git a/Misc/NEWS.d/next/macOS/2024-09-04-11-55-29.gh-issue-123418.8P4bmN.rst b/Misc/NEWS.d/next/macOS/2024-09-04-11-55-29.gh-issue-123418.8P4bmN.rst deleted file mode 100644 index d01afce8a12350..00000000000000 --- a/Misc/NEWS.d/next/macOS/2024-09-04-11-55-29.gh-issue-123418.8P4bmN.rst +++ /dev/null @@ -1 +0,0 @@ -Updated macOS installer build to use OpenSSL 3.0.15. diff --git a/Misc/NEWS.d/next/macOS/2024-09-07-12-14-54.gh-issue-123797.yFDeug.rst b/Misc/NEWS.d/next/macOS/2024-09-07-12-14-54.gh-issue-123797.yFDeug.rst deleted file mode 100644 index f126bd0d39bf59..00000000000000 --- a/Misc/NEWS.d/next/macOS/2024-09-07-12-14-54.gh-issue-123797.yFDeug.rst +++ /dev/null @@ -1 +0,0 @@ -Check for runtime availability of ``ptsname_r`` function on macos. diff --git a/Misc/NEWS.d/next/macOS/2024-09-24-10-48-46.gh-issue-124448.bFMrS6.rst b/Misc/NEWS.d/next/macOS/2024-09-24-10-48-46.gh-issue-124448.bFMrS6.rst deleted file mode 100644 index 6d57aa1ee190d6..00000000000000 --- a/Misc/NEWS.d/next/macOS/2024-09-24-10-48-46.gh-issue-124448.bFMrS6.rst +++ /dev/null @@ -1 +0,0 @@ -Update bundled Tcl/Tk in macOS installer to 8.6.15. diff --git a/README.rst b/README.rst index 7dd3660b198784..3f694771e090cb 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -This is Python version 3.14.0 alpha 0 +This is Python version 3.14.0 alpha 1 ===================================== .. image:: https://github.com/python/cpython/actions/workflows/build.yml/badge.svg?branch=main&event=push From 12eaadc0ad33411bb02945d700b6ed7e758bb188 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Tue, 15 Oct 2024 12:56:33 -0700 Subject: [PATCH 101/170] gh-58956: Set f_trace on frames with breakpoints after setting a new breakpoint (#124454) --- Lib/bdb.py | 8 +++++ Lib/test/test_pdb.py | 30 +++++++++++++++++++ ...4-09-24-18-16-59.gh-issue-58956.0wFrBR.rst | 1 + 3 files changed, 39 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2024-09-24-18-16-59.gh-issue-58956.0wFrBR.rst diff --git a/Lib/bdb.py b/Lib/bdb.py index 9755d61dd2696c..81bba8a130f97c 100644 --- a/Lib/bdb.py +++ b/Lib/bdb.py @@ -461,6 +461,14 @@ def set_break(self, filename, lineno, temporary=False, cond=None, return 'Line %s:%d does not exist' % (filename, lineno) self._add_to_breaks(filename, lineno) bp = Breakpoint(filename, lineno, temporary, cond, funcname) + # After we set a new breakpoint, we need to search through all frames + # and set f_trace to trace_dispatch if there could be a breakpoint in + # that frame. + frame = self.enterframe + while frame: + if self.break_anywhere(frame): + frame.f_trace = self.trace_dispatch + frame = frame.f_back return None def _load_breaks(self): diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 456effc010954a..8136c591a33001 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -3396,6 +3396,36 @@ def test_issue26053(self): self.assertRegex(res, "Restarting .* with arguments:\na b c") self.assertRegex(res, "Restarting .* with arguments:\nd e f") + def test_issue58956(self): + # Set a breakpoint in a function that already exists on the call stack + # should enable the trace function for the frame. + script = """ + import bar + def foo(): + ret = bar.bar() + pass + foo() + """ + commands = """ + b bar.bar + c + b main.py:5 + c + p ret + quit + """ + bar = """ + def bar(): + return 42 + """ + with open('bar.py', 'w') as f: + f.write(textwrap.dedent(bar)) + self.addCleanup(os_helper.unlink, 'bar.py') + stdout, stderr = self.run_pdb_script(script, commands) + lines = stdout.splitlines() + self.assertIn('-> pass', lines) + self.assertIn('(Pdb) 42', lines) + def test_step_into_botframe(self): # gh-125422 # pdb should not be able to step into the botframe (bdb.py) diff --git a/Misc/NEWS.d/next/Library/2024-09-24-18-16-59.gh-issue-58956.0wFrBR.rst b/Misc/NEWS.d/next/Library/2024-09-24-18-16-59.gh-issue-58956.0wFrBR.rst new file mode 100644 index 00000000000000..a882a632fddf1b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-09-24-18-16-59.gh-issue-58956.0wFrBR.rst @@ -0,0 +1 @@ +Fixed a bug in :mod:`pdb` where sometimes the breakpoint won't trigger if it was set on a function which is already in the call stack. From fee8fe5858c05599efb014bf4538ef8d52baa45c Mon Sep 17 00:00:00 2001 From: Kirill Podoprigora Date: Wed, 16 Oct 2024 00:25:20 +0300 Subject: [PATCH 102/170] Issue template: Remove 3.8 and add 3.14 version (#125552) --- .github/ISSUE_TEMPLATE/bug.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 395516f29b037c..7b7810cf6965fd 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -34,12 +34,12 @@ body: label: "CPython versions tested on:" multiple: true options: - - "3.8" - "3.9" - "3.10" - "3.11" - "3.12" - "3.13" + - "3.14" - "CPython main branch" validations: required: true From 299d02090f216d8cc90374013efb3ccb8de16ecc Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 16 Oct 2024 00:44:52 +0300 Subject: [PATCH 103/170] Post 3.14.0a1 --- Include/patchlevel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Include/patchlevel.h b/Include/patchlevel.h index c7a9496a35ed92..f7b33a8038570b 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -23,7 +23,7 @@ #define PY_RELEASE_SERIAL 1 /* Version as a string */ -#define PY_VERSION "3.14.0a1" +#define PY_VERSION "3.14.0a1+" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. From 7453b8f15c77a8f3b07a5049450436079476c465 Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Tue, 15 Oct 2024 17:08:00 -0500 Subject: [PATCH 104/170] Update verison options in crash issue template (GH-125555) --- .github/ISSUE_TEMPLATE/crash.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/crash.yml b/.github/ISSUE_TEMPLATE/crash.yml index 6d73f7cae5c0ae..58da2dfe0c7354 100644 --- a/.github/ISSUE_TEMPLATE/crash.yml +++ b/.github/ISSUE_TEMPLATE/crash.yml @@ -27,12 +27,12 @@ body: label: "CPython versions tested on:" multiple: true options: - - "3.8" - "3.9" - "3.10" - "3.11" - "3.12" - "3.13" + - "3.14" - "CPython main branch" validations: required: true From bee112a94d688c8048ddeddaa7bbd5150aecad11 Mon Sep 17 00:00:00 2001 From: Kirill Podoprigora Date: Wed, 16 Oct 2024 14:53:21 +0300 Subject: [PATCH 105/170] gh-124872: Replace enter/exit events with "switched" (#125532) Users want to know when the current context switches to a different context object. Right now this happens when and only when a context is entered or exited, so the enter and exit events are synonymous with "switched". However, if the changes proposed for gh-99633 are implemented, the current context will also switch for reasons other than context enter or exit. Since users actually care about context switches and not enter or exit, replace the enter and exit events with a single switched event. The former exit event was emitted just before exiting the context. The new switched event is emitted after the context is exited to match the semantics users expect of an event with a past-tense name. If users need the ability to clean up before the switch takes effect, another event type can be added in the future. It is not added here because YAGNI. I skipped 0 in the enum as a matter of practice. Skipping 0 makes it easier to troubleshoot when code forgets to set zeroed memory, and it aligns with best practices for other tools (e.g., https://protobuf.dev/programming-guides/dos-donts/#unspecified-enum). Co-authored-by: Richard Hansen Co-authored-by: Victor Stinner --- Doc/c-api/contextvars.rst | 14 ++--- Include/cpython/context.h | 17 ++---- Lib/test/test_capi/test_watchers.py | 87 +++++++++++++++------------- Modules/_testcapi/watchers.c | 79 +++++++++++++------------ Python/context.c | 31 ++++++---- Tools/c-analyzer/cpython/ignored.tsv | 4 +- 6 files changed, 118 insertions(+), 114 deletions(-) diff --git a/Doc/c-api/contextvars.rst b/Doc/c-api/contextvars.rst index 8eba54a80dc80d..b7c6550ff34aac 100644 --- a/Doc/c-api/contextvars.rst +++ b/Doc/c-api/contextvars.rst @@ -123,16 +123,10 @@ Context object management functions: Enumeration of possible context object watcher events: - - ``Py_CONTEXT_EVENT_ENTER``: A context has been entered, causing the - :term:`current context` to switch to it. The object passed to the watch - callback is the now-current :class:`contextvars.Context` object. Each - enter event will eventually have a corresponding exit event for the same - context object after any subsequently entered contexts have themselves been - exited. - - ``Py_CONTEXT_EVENT_EXIT``: A context is about to be exited, which will - cause the :term:`current context` to switch back to what it was before the - context was entered. The object passed to the watch callback is the - still-current :class:`contextvars.Context` object. + - ``Py_CONTEXT_SWITCHED``: The :term:`current context` has switched to a + different context. The object passed to the watch callback is the + now-current :class:`contextvars.Context` object, or None if no context is + current. .. versionadded:: 3.14 diff --git a/Include/cpython/context.h b/Include/cpython/context.h index 3c9be7873b9399..3a7a4b459c09ad 100644 --- a/Include/cpython/context.h +++ b/Include/cpython/context.h @@ -29,20 +29,11 @@ PyAPI_FUNC(int) PyContext_Exit(PyObject *); typedef enum { /* - * A context has been entered, causing the "current context" to switch to - * it. The object passed to the watch callback is the now-current - * contextvars.Context object. Each enter event will eventually have a - * corresponding exit event for the same context object after any - * subsequently entered contexts have themselves been exited. + * The current context has switched to a different context. The object + * passed to the watch callback is the now-current contextvars.Context + * object, or None if no context is current. */ - Py_CONTEXT_EVENT_ENTER, - /* - * A context is about to be exited, which will cause the "current context" - * to switch back to what it was before the context was entered. The - * object passed to the watch callback is the still-current - * contextvars.Context object. - */ - Py_CONTEXT_EVENT_EXIT, + Py_CONTEXT_SWITCHED = 1, } PyContextEvent; /* diff --git a/Lib/test/test_capi/test_watchers.py b/Lib/test/test_capi/test_watchers.py index f21d2627c6094b..4bb764bf9d0963 100644 --- a/Lib/test/test_capi/test_watchers.py +++ b/Lib/test/test_capi/test_watchers.py @@ -577,68 +577,66 @@ class TestContextObjectWatchers(unittest.TestCase): def context_watcher(self, which_watcher): wid = _testcapi.add_context_watcher(which_watcher) try: - yield wid + switches = _testcapi.get_context_switches(which_watcher) + except ValueError: + switches = None + try: + yield switches finally: _testcapi.clear_context_watcher(wid) - def assert_event_counts(self, exp_enter_0, exp_exit_0, - exp_enter_1, exp_exit_1): - self.assertEqual( - exp_enter_0, _testcapi.get_context_watcher_num_enter_events(0)) - self.assertEqual( - exp_exit_0, _testcapi.get_context_watcher_num_exit_events(0)) - self.assertEqual( - exp_enter_1, _testcapi.get_context_watcher_num_enter_events(1)) - self.assertEqual( - exp_exit_1, _testcapi.get_context_watcher_num_exit_events(1)) + def assert_event_counts(self, want_0, want_1): + self.assertEqual(len(_testcapi.get_context_switches(0)), want_0) + self.assertEqual(len(_testcapi.get_context_switches(1)), want_1) def test_context_object_events_dispatched(self): # verify that all counts are zero before any watchers are registered - self.assert_event_counts(0, 0, 0, 0) + self.assert_event_counts(0, 0) # verify that all counts remain zero when a context object is # entered and exited with no watchers registered ctx = contextvars.copy_context() - ctx.run(self.assert_event_counts, 0, 0, 0, 0) - self.assert_event_counts(0, 0, 0, 0) + ctx.run(self.assert_event_counts, 0, 0) + self.assert_event_counts(0, 0) # verify counts are as expected when first watcher is registered with self.context_watcher(0): - self.assert_event_counts(0, 0, 0, 0) - ctx.run(self.assert_event_counts, 1, 0, 0, 0) - self.assert_event_counts(1, 1, 0, 0) + self.assert_event_counts(0, 0) + ctx.run(self.assert_event_counts, 1, 0) + self.assert_event_counts(2, 0) # again with second watcher registered with self.context_watcher(1): - self.assert_event_counts(1, 1, 0, 0) - ctx.run(self.assert_event_counts, 2, 1, 1, 0) - self.assert_event_counts(2, 2, 1, 1) + self.assert_event_counts(2, 0) + ctx.run(self.assert_event_counts, 3, 1) + self.assert_event_counts(4, 2) # verify counts are reset and don't change after both watchers are cleared - ctx.run(self.assert_event_counts, 0, 0, 0, 0) - self.assert_event_counts(0, 0, 0, 0) + ctx.run(self.assert_event_counts, 0, 0) + self.assert_event_counts(0, 0) - def test_enter_error(self): - with self.context_watcher(2): - with catch_unraisable_exception() as cm: - ctx = contextvars.copy_context() - ctx.run(int, 0) - self.assertEqual( - cm.unraisable.err_msg, - "Exception ignored in " - f"Py_CONTEXT_EVENT_EXIT watcher callback for {ctx!r}" - ) - self.assertEqual(str(cm.unraisable.exc_value), "boom!") + def test_callback_error(self): + ctx_outer = contextvars.copy_context() + ctx_inner = contextvars.copy_context() + unraisables = [] - def test_exit_error(self): - ctx = contextvars.copy_context() - def _in_context(stack): - stack.enter_context(self.context_watcher(2)) + def _in_outer(): + with self.context_watcher(2): + with catch_unraisable_exception() as cm: + ctx_inner.run(lambda: unraisables.append(cm.unraisable)) + unraisables.append(cm.unraisable) - with catch_unraisable_exception() as cm: - with ExitStack() as stack: - ctx.run(_in_context, stack) - self.assertEqual(str(cm.unraisable.exc_value), "boom!") + try: + ctx_outer.run(_in_outer) + self.assertEqual([x.err_msg for x in unraisables], + ["Exception ignored in Py_CONTEXT_SWITCHED " + f"watcher callback for {ctx!r}" + for ctx in [ctx_inner, ctx_outer]]) + self.assertEqual([str(x.exc_value) for x in unraisables], + ["boom!", "boom!"]) + finally: + # Break reference cycle + unraisables = None def test_clear_out_of_range_watcher_id(self): with self.assertRaisesRegex(ValueError, r"Invalid context watcher ID -1"): @@ -654,5 +652,12 @@ def test_allocate_too_many_watchers(self): with self.assertRaisesRegex(RuntimeError, r"no more context watcher IDs available"): _testcapi.allocate_too_many_context_watchers() + def test_exit_base_context(self): + ctx = contextvars.Context() + _testcapi.clear_context_stack() + with self.context_watcher(0) as switches: + ctx.run(lambda: None) + self.assertEqual(switches, [ctx, None]) + if __name__ == "__main__": unittest.main() diff --git a/Modules/_testcapi/watchers.c b/Modules/_testcapi/watchers.c index b4233d07134aea..321d3aeffb6ad1 100644 --- a/Modules/_testcapi/watchers.c +++ b/Modules/_testcapi/watchers.c @@ -626,16 +626,12 @@ allocate_too_many_func_watchers(PyObject *self, PyObject *args) // Test contexct object watchers #define NUM_CONTEXT_WATCHERS 2 static int context_watcher_ids[NUM_CONTEXT_WATCHERS] = {-1, -1}; -static int num_context_object_enter_events[NUM_CONTEXT_WATCHERS] = {0, 0}; -static int num_context_object_exit_events[NUM_CONTEXT_WATCHERS] = {0, 0}; +static PyObject *context_switches[NUM_CONTEXT_WATCHERS]; static int handle_context_watcher_event(int which_watcher, PyContextEvent event, PyObject *ctx) { - if (event == Py_CONTEXT_EVENT_ENTER) { - num_context_object_enter_events[which_watcher]++; - } - else if (event == Py_CONTEXT_EVENT_EXIT) { - num_context_object_exit_events[which_watcher]++; + if (event == Py_CONTEXT_SWITCHED) { + PyList_Append(context_switches[which_watcher], ctx); } else { return -1; @@ -667,31 +663,28 @@ error_context_event_handler(PyContextEvent event, PyObject *ctx) { static PyObject * add_context_watcher(PyObject *self, PyObject *which_watcher) { - int watcher_id; + static const PyContext_WatchCallback callbacks[] = { + &first_context_watcher_callback, + &second_context_watcher_callback, + &error_context_event_handler, + }; assert(PyLong_Check(which_watcher)); long which_l = PyLong_AsLong(which_watcher); - if (which_l == 0) { - watcher_id = PyContext_AddWatcher(first_context_watcher_callback); - context_watcher_ids[0] = watcher_id; - num_context_object_enter_events[0] = 0; - num_context_object_exit_events[0] = 0; - } - else if (which_l == 1) { - watcher_id = PyContext_AddWatcher(second_context_watcher_callback); - context_watcher_ids[1] = watcher_id; - num_context_object_enter_events[1] = 0; - num_context_object_exit_events[1] = 0; - } - else if (which_l == 2) { - watcher_id = PyContext_AddWatcher(error_context_event_handler); - } - else { + if (which_l < 0 || which_l >= (long)Py_ARRAY_LENGTH(callbacks)) { PyErr_Format(PyExc_ValueError, "invalid watcher %d", which_l); return NULL; } + int watcher_id = PyContext_AddWatcher(callbacks[which_l]); if (watcher_id < 0) { return NULL; } + if (which_l >= 0 && which_l < NUM_CONTEXT_WATCHERS) { + context_watcher_ids[which_l] = watcher_id; + Py_XSETREF(context_switches[which_l], PyList_New(0)); + if (context_switches[which_l] == NULL) { + return NULL; + } + } return PyLong_FromLong(watcher_id); } @@ -708,8 +701,7 @@ clear_context_watcher(PyObject *self, PyObject *watcher_id) for (int i = 0; i < NUM_CONTEXT_WATCHERS; i++) { if (watcher_id_l == context_watcher_ids[i]) { context_watcher_ids[i] = -1; - num_context_object_enter_events[i] = 0; - num_context_object_exit_events[i] = 0; + Py_CLEAR(context_switches[i]); } } } @@ -717,21 +709,34 @@ clear_context_watcher(PyObject *self, PyObject *watcher_id) } static PyObject * -get_context_watcher_num_enter_events(PyObject *self, PyObject *watcher_id) +clear_context_stack(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args)) { - assert(PyLong_Check(watcher_id)); - long watcher_id_l = PyLong_AsLong(watcher_id); - assert(watcher_id_l >= 0 && watcher_id_l < NUM_CONTEXT_WATCHERS); - return PyLong_FromLong(num_context_object_enter_events[watcher_id_l]); + PyThreadState *tstate = PyThreadState_Get(); + if (tstate->context == NULL) { + Py_RETURN_NONE; + } + if (((PyContext *)tstate->context)->ctx_prev != NULL) { + PyErr_SetString(PyExc_RuntimeError, + "must first exit all non-base contexts"); + return NULL; + } + Py_CLEAR(tstate->context); + Py_RETURN_NONE; } static PyObject * -get_context_watcher_num_exit_events(PyObject *self, PyObject *watcher_id) +get_context_switches(PyObject *Py_UNUSED(self), PyObject *watcher_id) { assert(PyLong_Check(watcher_id)); long watcher_id_l = PyLong_AsLong(watcher_id); - assert(watcher_id_l >= 0 && watcher_id_l < NUM_CONTEXT_WATCHERS); - return PyLong_FromLong(num_context_object_exit_events[watcher_id_l]); + if (watcher_id_l < 0 || watcher_id_l >= NUM_CONTEXT_WATCHERS) { + PyErr_Format(PyExc_ValueError, "invalid watcher %ld", watcher_id_l); + return NULL; + } + if (context_switches[watcher_id_l] == NULL) { + return PyList_New(0); + } + return Py_NewRef(context_switches[watcher_id_l]); } static PyObject * @@ -835,10 +840,8 @@ static PyMethodDef test_methods[] = { // Code object watchers. {"add_context_watcher", add_context_watcher, METH_O, NULL}, {"clear_context_watcher", clear_context_watcher, METH_O, NULL}, - {"get_context_watcher_num_enter_events", - get_context_watcher_num_enter_events, METH_O, NULL}, - {"get_context_watcher_num_exit_events", - get_context_watcher_num_exit_events, METH_O, NULL}, + {"clear_context_stack", clear_context_stack, METH_NOARGS, NULL}, + {"get_context_switches", get_context_switches, METH_O, NULL}, {"allocate_too_many_context_watchers", (PyCFunction) allocate_too_many_context_watchers, METH_NOARGS, NULL}, {NULL}, diff --git a/Python/context.c b/Python/context.c index 8bc487a33c890b..95aa82206270f9 100644 --- a/Python/context.c +++ b/Python/context.c @@ -102,10 +102,8 @@ PyContext_CopyCurrent(void) static const char * context_event_name(PyContextEvent event) { switch (event) { - case Py_CONTEXT_EVENT_ENTER: - return "Py_CONTEXT_EVENT_ENTER"; - case Py_CONTEXT_EVENT_EXIT: - return "Py_CONTEXT_EVENT_EXIT"; + case Py_CONTEXT_SWITCHED: + return "Py_CONTEXT_SWITCHED"; default: return "?"; } @@ -115,6 +113,13 @@ context_event_name(PyContextEvent event) { static void notify_context_watchers(PyThreadState *ts, PyContextEvent event, PyObject *ctx) { + if (ctx == NULL) { + // This will happen after exiting the last context in the stack, which + // can occur if context_get was never called before entering a context + // (e.g., called `contextvars.Context().run()` on a fresh thread, as + // PyContext_Enter doesn't call context_get). + ctx = Py_None; + } assert(Py_REFCNT(ctx) > 0); PyInterpreterState *interp = ts->interp; assert(interp->_initialized); @@ -175,6 +180,16 @@ PyContext_ClearWatcher(int watcher_id) } +static inline void +context_switched(PyThreadState *ts) +{ + ts->context_ver++; + // ts->context is used instead of context_get() because context_get() might + // throw if ts->context is NULL. + notify_context_watchers(ts, Py_CONTEXT_SWITCHED, ts->context); +} + + static int _PyContext_Enter(PyThreadState *ts, PyObject *octx) { @@ -191,9 +206,7 @@ _PyContext_Enter(PyThreadState *ts, PyObject *octx) ctx->ctx_entered = 1; ts->context = Py_NewRef(ctx); - ts->context_ver++; - - notify_context_watchers(ts, Py_CONTEXT_EVENT_ENTER, octx); + context_switched(ts); return 0; } @@ -227,13 +240,11 @@ _PyContext_Exit(PyThreadState *ts, PyObject *octx) return -1; } - notify_context_watchers(ts, Py_CONTEXT_EVENT_EXIT, octx); Py_SETREF(ts->context, (PyObject *)ctx->ctx_prev); - ts->context_ver++; ctx->ctx_prev = NULL; ctx->ctx_entered = 0; - + context_switched(ts); return 0; } diff --git a/Tools/c-analyzer/cpython/ignored.tsv b/Tools/c-analyzer/cpython/ignored.tsv index e6c599a2ac4a46..2605825d3d0078 100644 --- a/Tools/c-analyzer/cpython/ignored.tsv +++ b/Tools/c-analyzer/cpython/ignored.tsv @@ -455,8 +455,8 @@ Modules/_testcapi/watchers.c - pyfunc_watchers - Modules/_testcapi/watchers.c - func_watcher_ids - Modules/_testcapi/watchers.c - func_watcher_callbacks - Modules/_testcapi/watchers.c - context_watcher_ids - -Modules/_testcapi/watchers.c - num_context_object_enter_events - -Modules/_testcapi/watchers.c - num_context_object_exit_events - +Modules/_testcapi/watchers.c - context_switches - +Modules/_testcapi/watchers.c add_context_watcher callbacks - Modules/_testcapimodule.c - BasicStaticTypes - Modules/_testcapimodule.c - num_basic_static_types_used - Modules/_testcapimodule.c - ContainerNoGC_members - From 51410d8bdcfe0fd215f94a098dc6cd0919c648a1 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Wed, 16 Oct 2024 08:51:15 -0400 Subject: [PATCH 106/170] gh-125217: Turn off optimization around_PyEval_EvalFrameDefault to avoid MSVC crash (#125477) --- Python/ceval.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Python/ceval.c b/Python/ceval.c index f4e0add3034707..43776e773e0deb 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -761,6 +761,16 @@ _PyObjectArray_Free(PyObject **array, PyObject **scratch) * so consume 3 units of C stack */ #define PY_EVAL_C_STACK_UNITS 2 +#if defined(_MSC_VER) && defined(_Py_USING_PGO) && defined(_Py_JIT) +/* _PyEval_EvalFrameDefault is too large to optimize for speed with + PGO on MSVC when the JIT is enabled. Disable that optimization + around this function only. If this is fixed upstream, we should + gate this on the version of MSVC. + */ +# pragma optimize("t", off) +/* This setting is reversed below following _PyEval_EvalFrameDefault */ +#endif + PyObject* _Py_HOT_FUNCTION _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int throwflag) { @@ -1136,6 +1146,10 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } +#if defined(_MSC_VER) && defined(_Py_USING_PGO) && defined(_Py_JIT) +# pragma optimize("", on) +#endif + #if defined(__GNUC__) # pragma GCC diagnostic pop #elif defined(_MSC_VER) /* MS_WINDOWS */ From feda9aa73ab95d17a291db22c416146f8e70edeb Mon Sep 17 00:00:00 2001 From: Diego Russo Date: Wed, 16 Oct 2024 14:13:07 +0100 Subject: [PATCH 107/170] gh-125444: Fix illegal instruction for older Arm architectures (#125574) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On Arm v5 it is not possible to get the thread ID via c13 register hence the illegal instruction. The c13 register started to provide thread ID since Arm v6K architecture variant. Other variants of Arm v6 (T2, Z and base) don’t provide the thread ID via c13. For the sake of simplicity we group v5 and v6 together and consider that instructions for Arm v7 only. --- Include/internal/mimalloc/mimalloc/prim.h | 4 ++-- Include/object.h | 2 +- .../2024-10-16-12-12-39.gh-issue-125444.9tG2X6.rst | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-10-16-12-12-39.gh-issue-125444.9tG2X6.rst diff --git a/Include/internal/mimalloc/mimalloc/prim.h b/Include/internal/mimalloc/mimalloc/prim.h index 8a60d528458e6c..322ab29e6b41c2 100644 --- a/Include/internal/mimalloc/mimalloc/prim.h +++ b/Include/internal/mimalloc/mimalloc/prim.h @@ -151,9 +151,9 @@ static inline mi_threadid_t _mi_prim_thread_id(void) mi_attr_noexcept { // If you test on another platform and it works please send a PR :-) // see also https://akkadia.org/drepper/tls.pdf for more info on the TLS register. #elif defined(__GNUC__) && ( \ - (defined(__GLIBC__) && (defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__))) \ + (defined(__GLIBC__) && (defined(__x86_64__) || defined(__i386__) || (defined(__arm__) && __ARM_ARCH >= 7) || defined(__aarch64__))) \ || (defined(__APPLE__) && (defined(__x86_64__) || defined(__aarch64__))) \ - || (defined(__BIONIC__) && (defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__))) \ + || (defined(__BIONIC__) && (defined(__x86_64__) || defined(__i386__) || (defined(__arm__) && __ARM_ARCH >= 7) || defined(__aarch64__))) \ || (defined(__FreeBSD__) && (defined(__x86_64__) || defined(__i386__) || defined(__aarch64__))) \ || (defined(__OpenBSD__) && (defined(__x86_64__) || defined(__i386__) || defined(__aarch64__))) \ ) diff --git a/Include/object.h b/Include/object.h index 5be4dedadc20eb..7e1b0966fc5e34 100644 --- a/Include/object.h +++ b/Include/object.h @@ -192,7 +192,7 @@ _Py_ThreadId(void) __asm__("movq %%gs:0, %0" : "=r" (tid)); // x86_64 macOSX uses GS #elif defined(__x86_64__) __asm__("movq %%fs:0, %0" : "=r" (tid)); // x86_64 Linux, BSD uses FS -#elif defined(__arm__) +#elif defined(__arm__) && __ARM_ARCH >= 7 __asm__ ("mrc p15, 0, %0, c13, c0, 3\nbic %0, %0, #3" : "=r" (tid)); #elif defined(__aarch64__) && defined(__APPLE__) __asm__ ("mrs %0, tpidrro_el0" : "=r" (tid)); diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-10-16-12-12-39.gh-issue-125444.9tG2X6.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-16-12-12-39.gh-issue-125444.9tG2X6.rst new file mode 100644 index 00000000000000..13c1e745edf8d5 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-16-12-12-39.gh-issue-125444.9tG2X6.rst @@ -0,0 +1 @@ +Fix illegal instruction for older Arm architectures. Patch by Diego Russo, testing by Ross Burton. From e4d90be84536746a966478acc4c0cf43a201f492 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Wed, 16 Oct 2024 15:24:41 +0200 Subject: [PATCH 108/170] gh-125584: Require network resource in ``test_urllib2.HandlerTests.test_ftp_error`` (#125586) --- Lib/test/test_urllib2.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py index 19179fdc9508ca..b90ccc2f125b93 100644 --- a/Lib/test/test_urllib2.py +++ b/Lib/test/test_urllib2.py @@ -794,6 +794,7 @@ def connect_ftp(self, user, passwd, host, port, dirs, self.assertEqual(headers.get("Content-type"), mimetype) self.assertEqual(int(headers["Content-length"]), len(data)) + @support.requires_resource("network") def test_ftp_error(self): class ErrorFTPHandler(urllib.request.FTPHandler): def __init__(self, exception): From d83fcf8371f2f33c7797bc8f5423a8bca8c46e5c Mon Sep 17 00:00:00 2001 From: Kirill Podoprigora Date: Wed, 16 Oct 2024 17:27:19 +0300 Subject: [PATCH 109/170] CI: Bump Python to 3.13 and mypy to 1.12 in mypy workflow (#125592) * Bump mypy to 1.12 & Python to 3.13 * Remove unnecessary `type: ignore` --- .github/workflows/mypy.yml | 2 +- Tools/clinic/libclinic/converter.py | 4 +--- Tools/requirements-dev.txt | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml index 1b2d998182e0f7..e5b05302b5ac27 100644 --- a/.github/workflows/mypy.yml +++ b/.github/workflows/mypy.yml @@ -53,7 +53,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.13" cache: pip cache-dependency-path: Tools/requirements-dev.txt - run: pip install -r Tools/requirements-dev.txt diff --git a/Tools/clinic/libclinic/converter.py b/Tools/clinic/libclinic/converter.py index 2abf06dc4e89a2..86853bb4fba253 100644 --- a/Tools/clinic/libclinic/converter.py +++ b/Tools/clinic/libclinic/converter.py @@ -545,9 +545,7 @@ def closure(f: CConverterClassT) -> CConverterClassT: if not kwargs: added_f = f else: - # type ignore due to a mypy regression :( - # https://github.com/python/mypy/issues/17646 - added_f = functools.partial(f, **kwargs) # type: ignore[misc] + added_f = functools.partial(f, **kwargs) if format_unit: legacy_converters[format_unit] = added_f return f diff --git a/Tools/requirements-dev.txt b/Tools/requirements-dev.txt index 408a9ea6607f9e..57f0b982b00f5d 100644 --- a/Tools/requirements-dev.txt +++ b/Tools/requirements-dev.txt @@ -1,6 +1,6 @@ # Requirements file for external linters and checks we run on # Tools/clinic, Tools/cases_generator/, and Tools/peg_generator/ in CI -mypy==1.11.2 +mypy==1.12 # needed for peg_generator: types-psutil==6.0.0.20240901 From 760872efecb95017db8e38a8eda614bf23d2a22c Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Wed, 16 Oct 2024 11:39:17 -0400 Subject: [PATCH 110/170] gh-125451: Fix deadlock in ProcessPoolExecutor shutdown (#125492) There was a deadlock when `ProcessPoolExecutor` shuts down at the same time that a queueing thread handles an error processing a task. Don't use `_shutdown_lock` to protect the `_ThreadWakeup` pipes -- use an internal lock instead. This fixes the ordering deadlock where the `ExecutorManagerThread` holds the `_shutdown_lock` and joins the queueing thread, while the queueing thread is attempting to acquire the `_shutdown_lock` while closing the `_ThreadWakeup`. --- Lib/concurrent/futures/process.py | 50 ++++++++----------- .../test_concurrent_futures/test_shutdown.py | 3 -- ...-10-14-17-29-34.gh-issue-125451.fmP3T9.rst | 2 + 3 files changed, 23 insertions(+), 32 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-14-17-29-34.gh-issue-125451.fmP3T9.rst diff --git a/Lib/concurrent/futures/process.py b/Lib/concurrent/futures/process.py index 7092b4757b5429..42eee72bc1457f 100644 --- a/Lib/concurrent/futures/process.py +++ b/Lib/concurrent/futures/process.py @@ -68,27 +68,31 @@ class _ThreadWakeup: def __init__(self): self._closed = False + self._lock = threading.Lock() self._reader, self._writer = mp.Pipe(duplex=False) def close(self): - # Please note that we do not take the shutdown lock when + # Please note that we do not take the self._lock when # calling clear() (to avoid deadlocking) so this method can # only be called safely from the same thread as all calls to - # clear() even if you hold the shutdown lock. Otherwise we + # clear() even if you hold the lock. Otherwise we # might try to read from the closed pipe. - if not self._closed: - self._closed = True - self._writer.close() - self._reader.close() + with self._lock: + if not self._closed: + self._closed = True + self._writer.close() + self._reader.close() def wakeup(self): - if not self._closed: - self._writer.send_bytes(b"") + with self._lock: + if not self._closed: + self._writer.send_bytes(b"") def clear(self): - if not self._closed: - while self._reader.poll(): - self._reader.recv_bytes() + if self._closed: + raise RuntimeError('operation on closed _ThreadWakeup') + while self._reader.poll(): + self._reader.recv_bytes() def _python_exit(): @@ -167,10 +171,8 @@ def __init__(self, work_id, fn, args, kwargs): class _SafeQueue(Queue): """Safe Queue set exception to the future object linked to a job""" - def __init__(self, max_size=0, *, ctx, pending_work_items, shutdown_lock, - thread_wakeup): + def __init__(self, max_size=0, *, ctx, pending_work_items, thread_wakeup): self.pending_work_items = pending_work_items - self.shutdown_lock = shutdown_lock self.thread_wakeup = thread_wakeup super().__init__(max_size, ctx=ctx) @@ -179,8 +181,7 @@ def _on_queue_feeder_error(self, e, obj): tb = format_exception(type(e), e, e.__traceback__) e.__cause__ = _RemoteTraceback('\n"""\n{}"""'.format(''.join(tb))) work_item = self.pending_work_items.pop(obj.work_id, None) - with self.shutdown_lock: - self.thread_wakeup.wakeup() + self.thread_wakeup.wakeup() # work_item can be None if another process terminated. In this # case, the executor_manager_thread fails all work_items # with BrokenProcessPool @@ -296,12 +297,10 @@ def __init__(self, executor): # if there is no pending work item. def weakref_cb(_, thread_wakeup=self.thread_wakeup, - shutdown_lock=self.shutdown_lock, mp_util_debug=mp.util.debug): mp_util_debug('Executor collected: triggering callback for' ' QueueManager wakeup') - with shutdown_lock: - thread_wakeup.wakeup() + thread_wakeup.wakeup() self.executor_reference = weakref.ref(executor, weakref_cb) @@ -429,11 +428,6 @@ def wait_result_broken_or_wakeup(self): elif wakeup_reader in ready: is_broken = False - # No need to hold the _shutdown_lock here because: - # 1. we're the only thread to use the wakeup reader - # 2. we're also the only thread to call thread_wakeup.close() - # 3. we want to avoid a possible deadlock when both reader and writer - # would block (gh-105829) self.thread_wakeup.clear() return result_item, is_broken, cause @@ -721,10 +715,9 @@ def __init__(self, max_workers=None, mp_context=None, # as it could result in a deadlock if a worker process dies with the # _result_queue write lock still acquired. # - # _shutdown_lock must be locked to access _ThreadWakeup.close() and - # .wakeup(). Care must also be taken to not call clear or close from - # more than one thread since _ThreadWakeup.clear() is not protected by - # the _shutdown_lock + # Care must be taken to only call clear and close from the + # executor_manager_thread, since _ThreadWakeup.clear() is not protected + # by a lock. self._executor_manager_thread_wakeup = _ThreadWakeup() # Create communication channels for the executor @@ -735,7 +728,6 @@ def __init__(self, max_workers=None, mp_context=None, self._call_queue = _SafeQueue( max_size=queue_size, ctx=self._mp_context, pending_work_items=self._pending_work_items, - shutdown_lock=self._shutdown_lock, thread_wakeup=self._executor_manager_thread_wakeup) # Killed worker processes can produce spurious "broken pipe" # tracebacks in the queue's own worker thread. But we detect killed diff --git a/Lib/test/test_concurrent_futures/test_shutdown.py b/Lib/test/test_concurrent_futures/test_shutdown.py index ba3618614a9bf9..7a4065afd46fc8 100644 --- a/Lib/test/test_concurrent_futures/test_shutdown.py +++ b/Lib/test/test_concurrent_futures/test_shutdown.py @@ -253,9 +253,6 @@ def test_cancel_futures_wait_false(self): class ProcessPoolShutdownTest(ExecutorShutdownTest): - # gh-125451: 'lock' cannot be serialized, the test is broken - # and hangs randomly - @unittest.skipIf(True, "broken test") def test_processes_terminate(self): def acquire_lock(lock): lock.acquire() diff --git a/Misc/NEWS.d/next/Library/2024-10-14-17-29-34.gh-issue-125451.fmP3T9.rst b/Misc/NEWS.d/next/Library/2024-10-14-17-29-34.gh-issue-125451.fmP3T9.rst new file mode 100644 index 00000000000000..589988d4d6273f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-14-17-29-34.gh-issue-125451.fmP3T9.rst @@ -0,0 +1,2 @@ +Fix deadlock when :class:`concurrent.futures.ProcessPoolExecutor` shuts down +concurrently with an error when feeding a job to a worker process. From aab3210271136ad8e8fecd927b806602c463e1f2 Mon Sep 17 00:00:00 2001 From: Cornelius Roemer Date: Wed, 16 Oct 2024 22:53:30 +0200 Subject: [PATCH 111/170] gh-125615: Fix grammar nit in tutorial's interactive interpreter appendix (GH-125617) Replace "without ... nor" with "with neither ... nor" --- Doc/tutorial/appendix.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/tutorial/appendix.rst b/Doc/tutorial/appendix.rst index da664f2f360ff1..6a1611afadb57c 100644 --- a/Doc/tutorial/appendix.rst +++ b/Doc/tutorial/appendix.rst @@ -20,7 +20,7 @@ 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. :kbd:`F1` enters the interactive help browser :mod:`pydoc`. -:kbd:`F2` allows for browsing command-line history without output nor the +:kbd:`F2` allows for browsing command-line history with neither output nor the :term:`>>>` and :term:`...` prompts. :kbd:`F3` enters "paste mode", which makes pasting larger blocks of code easier. Press :kbd:`F3` to return to the regular prompt. From aecbc2e6f40f8066f478c2d0f3be5b550e36cfd3 Mon Sep 17 00:00:00 2001 From: Vincent Fazio Date: Wed, 16 Oct 2024 17:01:42 -0500 Subject: [PATCH 112/170] gh-115382: Fix cross compiles when host and target use same SOABI Co-authored-by: Erlend E. Aasland --- Lib/sysconfig/__init__.py | 15 ++++++++++++++- Lib/test/libregrtest/main.py | 1 + Lib/test/pythoninfo.py | 1 + ...2024-03-03-20-28-23.gh-issue-115382.97hJFE.rst | 1 + configure | 2 +- configure.ac | 2 +- 6 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Build/2024-03-03-20-28-23.gh-issue-115382.97hJFE.rst diff --git a/Lib/sysconfig/__init__.py b/Lib/sysconfig/__init__.py index 80aef3447117e5..43f9276799b848 100644 --- a/Lib/sysconfig/__init__.py +++ b/Lib/sysconfig/__init__.py @@ -340,7 +340,20 @@ def _init_posix(vars): """Initialize the module as appropriate for POSIX systems.""" # _sysconfigdata is generated at build time, see _generate_posix_vars() name = _get_sysconfigdata_name() - _temp = __import__(name, globals(), locals(), ['build_time_vars'], 0) + + # For cross builds, the path to the target's sysconfigdata must be specified + # so it can be imported. It cannot be in PYTHONPATH, as foreign modules in + # sys.path can cause crashes when loaded by the host interpreter. + # Rely on truthiness as a valueless env variable is still an empty string. + # See OS X note in _generate_posix_vars re _sysconfigdata. + if (path := os.environ.get('_PYTHON_SYSCONFIGDATA_PATH')): + from importlib.machinery import FileFinder, SourceFileLoader, SOURCE_SUFFIXES + from importlib.util import module_from_spec + spec = FileFinder(path, (SourceFileLoader, SOURCE_SUFFIXES)).find_spec(name) + _temp = module_from_spec(spec) + spec.loader.exec_module(_temp) + else: + _temp = __import__(name, globals(), locals(), ['build_time_vars'], 0) build_time_vars = _temp.build_time_vars vars.update(build_time_vars) diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py index f693a788048694..2ef4349552bf5f 100644 --- a/Lib/test/libregrtest/main.py +++ b/Lib/test/libregrtest/main.py @@ -594,6 +594,7 @@ def _add_cross_compile_opts(self, regrtest_opts): '_PYTHON_PROJECT_BASE', '_PYTHON_HOST_PLATFORM', '_PYTHON_SYSCONFIGDATA_NAME', + "_PYTHON_SYSCONFIGDATA_PATH", 'PYTHONPATH' } old_environ = os.environ diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py index 05a28bda2d38ba..0b2e4b1c1988c4 100644 --- a/Lib/test/pythoninfo.py +++ b/Lib/test/pythoninfo.py @@ -334,6 +334,7 @@ def format_groups(groups): "_PYTHON_HOST_PLATFORM", "_PYTHON_PROJECT_BASE", "_PYTHON_SYSCONFIGDATA_NAME", + "_PYTHON_SYSCONFIGDATA_PATH", "__PYVENV_LAUNCHER__", # Sanitizer options diff --git a/Misc/NEWS.d/next/Build/2024-03-03-20-28-23.gh-issue-115382.97hJFE.rst b/Misc/NEWS.d/next/Build/2024-03-03-20-28-23.gh-issue-115382.97hJFE.rst new file mode 100644 index 00000000000000..f8d19651fc5854 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2024-03-03-20-28-23.gh-issue-115382.97hJFE.rst @@ -0,0 +1 @@ +Fix cross compile failures when the host and target SOABIs match. diff --git a/configure b/configure index 17c70d25f9e70c..b11f41d5379958 100755 --- a/configure +++ b/configure @@ -3708,7 +3708,7 @@ fi fi ac_cv_prog_PYTHON_FOR_REGEN=$with_build_python PYTHON_FOR_FREEZE="$with_build_python" - PYTHON_FOR_BUILD='_PYTHON_PROJECT_BASE=$(abs_builddir) _PYTHON_HOST_PLATFORM=$(_PYTHON_HOST_PLATFORM) PYTHONPATH=$(shell test -f pybuilddir.txt && echo $(abs_builddir)/`cat pybuilddir.txt`:)$(srcdir)/Lib _PYTHON_SYSCONFIGDATA_NAME=_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH) '$with_build_python + PYTHON_FOR_BUILD='_PYTHON_PROJECT_BASE=$(abs_builddir) _PYTHON_HOST_PLATFORM=$(_PYTHON_HOST_PLATFORM) PYTHONPATH=$(srcdir)/Lib _PYTHON_SYSCONFIGDATA_NAME=_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH) _PYTHON_SYSCONFIGDATA_PATH=$(shell test -f pybuilddir.txt && echo $(abs_builddir)/`cat pybuilddir.txt`) '$with_build_python { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_build_python" >&5 printf "%s\n" "$with_build_python" >&6; } diff --git a/configure.ac b/configure.ac index 56daa8b0f79bc0..d5bc739c34c90f 100644 --- a/configure.ac +++ b/configure.ac @@ -164,7 +164,7 @@ AC_ARG_WITH([build-python], dnl Build Python interpreter is used for regeneration and freezing. ac_cv_prog_PYTHON_FOR_REGEN=$with_build_python PYTHON_FOR_FREEZE="$with_build_python" - PYTHON_FOR_BUILD='_PYTHON_PROJECT_BASE=$(abs_builddir) _PYTHON_HOST_PLATFORM=$(_PYTHON_HOST_PLATFORM) PYTHONPATH=$(shell test -f pybuilddir.txt && echo $(abs_builddir)/`cat pybuilddir.txt`:)$(srcdir)/Lib _PYTHON_SYSCONFIGDATA_NAME=_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH) '$with_build_python + PYTHON_FOR_BUILD='_PYTHON_PROJECT_BASE=$(abs_builddir) _PYTHON_HOST_PLATFORM=$(_PYTHON_HOST_PLATFORM) PYTHONPATH=$(srcdir)/Lib _PYTHON_SYSCONFIGDATA_NAME=_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH) _PYTHON_SYSCONFIGDATA_PATH=$(shell test -f pybuilddir.txt && echo $(abs_builddir)/`cat pybuilddir.txt`) '$with_build_python AC_MSG_RESULT([$with_build_python]) ], [ AS_VAR_IF([cross_compiling], [yes], From 8e7b2a1161744c7d3d90966a65ed6ae1019a65cb Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Wed, 16 Oct 2024 23:05:20 +0100 Subject: [PATCH 113/170] gh-125550: Enable py.exe to detect Store installs of 3.14 (GH-125551) --- .../2024-10-15-21-28-43.gh-issue-125550.hmGWCP.rst | 2 ++ PC/launcher2.c | 9 ++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Windows/2024-10-15-21-28-43.gh-issue-125550.hmGWCP.rst diff --git a/Misc/NEWS.d/next/Windows/2024-10-15-21-28-43.gh-issue-125550.hmGWCP.rst b/Misc/NEWS.d/next/Windows/2024-10-15-21-28-43.gh-issue-125550.hmGWCP.rst new file mode 100644 index 00000000000000..c3ae00c74b3d91 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2024-10-15-21-28-43.gh-issue-125550.hmGWCP.rst @@ -0,0 +1,2 @@ +Enable the :ref:`launcher` to detect Python 3.14 installs from the Windows +Store. diff --git a/PC/launcher2.c b/PC/launcher2.c index b372044e353202..befcbe30600f2c 100644 --- a/PC/launcher2.c +++ b/PC/launcher2.c @@ -1962,6 +1962,7 @@ struct AppxSearchInfo { struct AppxSearchInfo APPX_SEARCH[] = { // Releases made through the Store + { L"PythonSoftwareFoundation.Python.3.14_qbz5n2kfra8p0", L"3.14", 10 }, { L"PythonSoftwareFoundation.Python.3.13_qbz5n2kfra8p0", L"3.13", 10 }, { L"PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0", L"3.12", 10 }, { L"PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0", L"3.11", 10 }, @@ -1970,8 +1971,9 @@ struct AppxSearchInfo APPX_SEARCH[] = { { L"PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0", L"3.8", 10 }, // Side-loadable releases. Note that the publisher ID changes whenever we - // renew our code-signing certificate, so the newer ID has a higher - // priority (lower sortKey) + // change our code signing certificate subject, so the newer IDs have higher + // priorities (lower sortKey) + { L"PythonSoftwareFoundation.Python.3.14_3847v3x7pw1km", L"3.14", 11 }, { L"PythonSoftwareFoundation.Python.3.13_3847v3x7pw1km", L"3.13", 11 }, { L"PythonSoftwareFoundation.Python.3.12_3847v3x7pw1km", L"3.12", 11 }, { L"PythonSoftwareFoundation.Python.3.11_3847v3x7pw1km", L"3.11", 11 }, @@ -2054,7 +2056,8 @@ struct StoreSearchInfo { struct StoreSearchInfo STORE_SEARCH[] = { - { L"3", /* 3.12 */ L"9NCVDN91XZQP" }, + { L"3", /* 3.13 */ L"9PNRBTZXMB4Z" }, + { L"3.14", L"9NTRHQCBBPR8" }, { L"3.13", L"9PNRBTZXMB4Z" }, { L"3.12", L"9NCVDN91XZQP" }, { L"3.11", L"9NRWMJP3717K" }, From a38fef4439139743e3334c1d69f24cafdf4d71da Mon Sep 17 00:00:00 2001 From: Furkan Onder Date: Thu, 17 Oct 2024 01:42:29 +0300 Subject: [PATCH 114/170] gh-125620: Remove unnecessary import of subprocess in spawnv_passfds (#125624) Remove unnecessary import of subprocess in multiprocessing.util.spawnv_passfds. --- Lib/multiprocessing/util.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/multiprocessing/util.py b/Lib/multiprocessing/util.py index d48ef8a86b34e1..b7192042b9cf47 100644 --- a/Lib/multiprocessing/util.py +++ b/Lib/multiprocessing/util.py @@ -438,7 +438,6 @@ def _flush_std_streams(): def spawnv_passfds(path, args, passfds): import _posixsubprocess - import subprocess passfds = tuple(sorted(map(int, passfds))) errpipe_read, errpipe_write = os.pipe() try: From a5a7f5e16d8c3938d266703ea8fba8ffee3e3ae5 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Wed, 16 Oct 2024 16:50:46 -0600 Subject: [PATCH 115/170] gh-124694: Add concurrent.futures.InterpreterPoolExecutor (gh-124548) This is an implementation of InterpreterPoolExecutor that builds on ThreadPoolExecutor. (Note that this is not tied to PEP 734, which is strictly about adding a new stdlib module.) Possible future improvements: * support passing a script for the initializer or to submit() * support passing (most) arbitrary functions without pickling * support passing closures * optionally exec functions against __main__ instead of the their original module --- Doc/library/asyncio-dev.rst | 6 +- Doc/library/asyncio-eventloop.rst | 9 +- Doc/library/asyncio-llapi-index.rst | 2 +- Doc/library/concurrent.futures.rst | 135 ++++++- Doc/whatsnew/3.14.rst | 8 + Lib/concurrent/futures/__init__.py | 12 +- Lib/concurrent/futures/interpreter.py | 241 ++++++++++++ Lib/concurrent/futures/thread.py | 90 +++-- Lib/test/test_concurrent_futures/executor.py | 4 +- .../test_interpreter_pool.py | 346 ++++++++++++++++++ Lib/test/test_concurrent_futures/util.py | 5 + ...-09-27-15-42-55.gh-issue-124694.uUy32y.rst | 6 + 12 files changed, 826 insertions(+), 38 deletions(-) create mode 100644 Lib/concurrent/futures/interpreter.py create mode 100644 Lib/test/test_concurrent_futures/test_interpreter_pool.py create mode 100644 Misc/NEWS.d/next/Library/2024-09-27-15-42-55.gh-issue-124694.uUy32y.rst diff --git a/Doc/library/asyncio-dev.rst b/Doc/library/asyncio-dev.rst index a9c3a0183bb72d..44b507a9811116 100644 --- a/Doc/library/asyncio-dev.rst +++ b/Doc/library/asyncio-dev.rst @@ -103,7 +103,8 @@ To handle signals the event loop must be run in the main thread. The :meth:`loop.run_in_executor` method can be used with a -:class:`concurrent.futures.ThreadPoolExecutor` to execute +:class:`concurrent.futures.ThreadPoolExecutor` or +:class:`~concurrent.futures.InterpreterPoolExecutor` to execute blocking code in a different OS thread without blocking the OS thread that the event loop runs in. @@ -128,7 +129,8 @@ if a function performs a CPU-intensive calculation for 1 second, all concurrent asyncio Tasks and IO operations would be delayed by 1 second. -An executor can be used to run a task in a different thread or even in +An executor can be used to run a task in a different thread, +including in a different interpreter, or even in a different process to avoid blocking the OS thread with the event loop. See the :meth:`loop.run_in_executor` method for more details. diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index 943683f6b8a7f6..14fd153f640f05 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -1305,6 +1305,12 @@ Executing code in thread or process pools pool, cpu_bound) print('custom process pool', result) + # 4. Run in a custom interpreter pool: + with concurrent.futures.InterpreterPoolExecutor() as pool: + result = await loop.run_in_executor( + pool, cpu_bound) + print('custom interpreter pool', result) + if __name__ == '__main__': asyncio.run(main()) @@ -1329,7 +1335,8 @@ Executing code in thread or process pools Set *executor* as the default executor used by :meth:`run_in_executor`. *executor* must be an instance of - :class:`~concurrent.futures.ThreadPoolExecutor`. + :class:`~concurrent.futures.ThreadPoolExecutor`, which includes + :class:`~concurrent.futures.InterpreterPoolExecutor`. .. versionchanged:: 3.11 *executor* must be an instance of diff --git a/Doc/library/asyncio-llapi-index.rst b/Doc/library/asyncio-llapi-index.rst index 3e21054aa4fe9e..f5af888f31f186 100644 --- a/Doc/library/asyncio-llapi-index.rst +++ b/Doc/library/asyncio-llapi-index.rst @@ -96,7 +96,7 @@ See also the main documentation section about the - Invoke a callback *at* the given time. -.. rubric:: Thread/Process Pool +.. rubric:: Thread/Interpreter/Process Pool .. list-table:: :widths: 50 50 :class: full-width-table diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst index ce72127127c7a6..45a73705f10e92 100644 --- a/Doc/library/concurrent.futures.rst +++ b/Doc/library/concurrent.futures.rst @@ -15,9 +15,10 @@ The :mod:`concurrent.futures` module provides a high-level interface for asynchronously executing callables. The asynchronous execution can be performed with threads, using -:class:`ThreadPoolExecutor`, or separate processes, using -:class:`ProcessPoolExecutor`. Both implement the same interface, which is -defined by the abstract :class:`Executor` class. +:class:`ThreadPoolExecutor` or :class:`InterpreterPoolExecutor`, +or separate processes, using :class:`ProcessPoolExecutor`. +Each implements the same interface, which is defined +by the abstract :class:`Executor` class. .. include:: ../includes/wasm-notavail.rst @@ -63,7 +64,8 @@ Executor Objects setting *chunksize* to a positive integer. For very long iterables, using a large value for *chunksize* can significantly improve performance compared to the default size of 1. With - :class:`ThreadPoolExecutor`, *chunksize* has no effect. + :class:`ThreadPoolExecutor` and :class:`InterpreterPoolExecutor`, + *chunksize* has no effect. .. versionchanged:: 3.5 Added the *chunksize* argument. @@ -227,6 +229,111 @@ ThreadPoolExecutor Example print('%r page is %d bytes' % (url, len(data))) +InterpreterPoolExecutor +----------------------- + +The :class:`InterpreterPoolExecutor` class uses a pool of interpreters +to execute calls asynchronously. It is a :class:`ThreadPoolExecutor` +subclass, which means each worker is running in its own thread. +The difference here is that each worker has its own interpreter, +and runs each task using that interpreter. + +The biggest benefit to using interpreters instead of only threads +is true multi-core parallelism. Each interpreter has its own +:term:`Global Interpreter Lock `, so code +running in one interpreter can run on one CPU core, while code in +another interpreter runs unblocked on a different core. + +The tradeoff is that writing concurrent code for use with multiple +interpreters can take extra effort. However, this is because it +forces you to be deliberate about how and when interpreters interact, +and to be explicit about what data is shared between interpreters. +This results in several benefits that help balance the extra effort, +including true multi-core parallelism, For example, code written +this way can make it easier to reason about concurrency. Another +major benefit is that you don't have to deal with several of the +big pain points of using threads, like nrace conditions. + +Each worker's interpreter is isolated from all the other interpreters. +"Isolated" means each interpreter has its own runtime state and +operates completely independently. For example, if you redirect +:data:`sys.stdout` in one interpreter, it will not be automatically +redirected any other interpreter. If you import a module in one +interpreter, it is not automatically imported in any other. You +would need to import the module separately in interpreter where +you need it. In fact, each module imported in an interpreter is +a completely separate object from the same module in a different +interpreter, including :mod:`sys`, :mod:`builtins`, +and even ``__main__``. + +Isolation means a mutable object, or other data, cannot be used +by more than one interpreter at the same time. That effectively means +interpreters cannot actually share such objects or data. Instead, +each interpreter must have its own copy, and you will have to +synchronize any changes between the copies manually. Immutable +objects and data, like the builtin singletons, strings, and tuples +of immutable objects, don't have these limitations. + +Communicating and synchronizing between interpreters is most effectively +done using dedicated tools, like those proposed in :pep:`734`. One less +efficient alternative is to serialize with :mod:`pickle` and then send +the bytes over a shared :mod:`socket ` or +:func:`pipe `. + +.. class:: InterpreterPoolExecutor(max_workers=None, thread_name_prefix='', initializer=None, initargs=(), shared=None) + + A :class:`ThreadPoolExecutor` subclass that executes calls asynchronously + using a pool of at most *max_workers* threads. Each thread runs + tasks in its own interpreter. The worker interpreters are isolated + from each other, which means each has its own runtime state and that + they can't share any mutable objects or other data. Each interpreter + has its own :term:`Global Interpreter Lock `, + which means code run with this executor has true multi-core parallelism. + + The optional *initializer* and *initargs* arguments have the same + meaning as for :class:`!ThreadPoolExecutor`: the initializer is run + when each worker is created, though in this case it is run.in + the worker's interpreter. The executor serializes the *initializer* + and *initargs* using :mod:`pickle` when sending them to the worker's + interpreter. + + .. note:: + Functions defined in the ``__main__`` module cannot be pickled + and thus cannot be used. + + .. note:: + The executor may replace uncaught exceptions from *initializer* + with :class:`~concurrent.futures.interpreter.ExecutionFailed`. + + The optional *shared* argument is a :class:`dict` of objects that all + interpreters in the pool share. The *shared* items are added to each + interpreter's ``__main__`` module. Not all objects are shareable. + Shareable objects include the builtin singletons, :class:`str` + and :class:`bytes`, and :class:`memoryview`. See :pep:`734` + for more info. + + Other caveats from parent :class:`ThreadPoolExecutor` apply here. + +:meth:`~Executor.submit` and :meth:`~Executor.map` work like normal, +except the worker serializes the callable and arguments using +:mod:`pickle` when sending them to its interpreter. The worker +likewise serializes the return value when sending it back. + +.. note:: + Functions defined in the ``__main__`` module cannot be pickled + and thus cannot be used. + +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` +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` +instance instead. + + ProcessPoolExecutor ------------------- @@ -574,6 +681,26 @@ Exception classes .. versionadded:: 3.7 +.. currentmodule:: concurrent.futures.interpreter + +.. exception:: BrokenInterpreterPool + + Derived from :exc:`~concurrent.futures.thread.BrokenThreadPool`, + this exception class is raised when one of the workers + of a :class:`~concurrent.futures.InterpreterPoolExecutor` + has failed initializing. + + .. versionadded:: next + +.. 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:: next + .. currentmodule:: concurrent.futures.process .. exception:: BrokenProcessPool diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index b106578fe9e8b0..9543af3c7ca225 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -225,6 +225,14 @@ ast * The ``repr()`` output for AST nodes now includes more information. (Contributed by Tomas R in :gh:`116022`.) +concurrent.futures +------------------ + +* Add :class:`~concurrent.futures.InterpreterPoolExecutor`, + which exposes "subinterpreters (multiple Python interpreters in the + same process) to Python code. This is separate from the proposed API + in :pep:`734`. + (Contributed by Eric Snow in :gh:`124548`.) ctypes ------ diff --git a/Lib/concurrent/futures/__init__.py b/Lib/concurrent/futures/__init__.py index 72de617a5b6f61..7ada7431c1ab8c 100644 --- a/Lib/concurrent/futures/__init__.py +++ b/Lib/concurrent/futures/__init__.py @@ -29,6 +29,7 @@ 'Executor', 'wait', 'as_completed', + 'InterpreterPoolExecutor', 'ProcessPoolExecutor', 'ThreadPoolExecutor', ) @@ -39,7 +40,7 @@ def __dir__(): def __getattr__(name): - global ProcessPoolExecutor, ThreadPoolExecutor + global ProcessPoolExecutor, ThreadPoolExecutor, InterpreterPoolExecutor if name == 'ProcessPoolExecutor': from .process import ProcessPoolExecutor as pe @@ -51,4 +52,13 @@ def __getattr__(name): ThreadPoolExecutor = te return te + if name == 'InterpreterPoolExecutor': + try: + from .interpreter import InterpreterPoolExecutor as ie + except ModuleNotFoundError: + ie = InterpreterPoolExecutor = None + else: + InterpreterPoolExecutor = ie + return ie + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/Lib/concurrent/futures/interpreter.py b/Lib/concurrent/futures/interpreter.py new file mode 100644 index 00000000000000..fd7941adb766bb --- /dev/null +++ b/Lib/concurrent/futures/interpreter.py @@ -0,0 +1,241 @@ +"""Implements InterpreterPoolExecutor.""" + +import contextlib +import pickle +import textwrap +from . import thread as _thread +import _interpreters +import _interpqueues + + +class ExecutionFailed(_interpreters.InterpreterError): + """An unhandled exception happened during execution.""" + + def __init__(self, excinfo): + msg = excinfo.formatted + if not msg: + if excinfo.type and excinfo.msg: + msg = f'{excinfo.type.__name__}: {excinfo.msg}' + else: + msg = excinfo.type.__name__ or excinfo.msg + super().__init__(msg) + self.excinfo = excinfo + + def __str__(self): + try: + formatted = self.excinfo.errdisplay + except Exception: + return super().__str__() + else: + return textwrap.dedent(f""" +{super().__str__()} + +Uncaught in the interpreter: + +{formatted} + """.strip()) + + +UNBOUND = 2 # error; this should not happen. + + +class WorkerContext(_thread.WorkerContext): + + @classmethod + def prepare(cls, initializer, initargs, shared): + def resolve_task(fn, args, kwargs): + if isinstance(fn, str): + # XXX Circle back to this later. + raise TypeError('scripts not supported') + if args or kwargs: + raise ValueError(f'a script does not take args or kwargs, got {args!r} and {kwargs!r}') + data = textwrap.dedent(fn) + kind = 'script' + # Make sure the script compiles. + # Ideally we wouldn't throw away the resulting code + # object. However, there isn't much to be done until + # code objects are shareable and/or we do a better job + # of supporting code objects in _interpreters.exec(). + compile(data, '', 'exec') + else: + # Functions defined in the __main__ module can't be pickled, + # so they can't be used here. In the future, we could possibly + # borrow from multiprocessing to work around this. + data = pickle.dumps((fn, args, kwargs)) + kind = 'function' + return (data, kind) + + if initializer is not None: + try: + initdata = resolve_task(initializer, initargs, {}) + except ValueError: + if isinstance(initializer, str) and initargs: + raise ValueError(f'an initializer script does not take args, got {initargs!r}') + raise # re-raise + else: + initdata = None + def create_context(): + return cls(initdata, shared) + return create_context, resolve_task + + @classmethod + @contextlib.contextmanager + def _capture_exc(cls, resultsid): + try: + yield + except BaseException as exc: + # Send the captured exception out on the results queue, + # but still leave it unhandled for the interpreter to handle. + err = pickle.dumps(exc) + _interpqueues.put(resultsid, (None, err), 1, UNBOUND) + raise # re-raise + + @classmethod + def _send_script_result(cls, resultsid): + _interpqueues.put(resultsid, (None, None), 0, UNBOUND) + + @classmethod + def _call(cls, func, args, kwargs, resultsid): + with cls._capture_exc(resultsid): + res = func(*args or (), **kwargs or {}) + # Send the result back. + try: + _interpqueues.put(resultsid, (res, None), 0, UNBOUND) + except _interpreters.NotShareableError: + res = pickle.dumps(res) + _interpqueues.put(resultsid, (res, None), 1, UNBOUND) + + @classmethod + def _call_pickled(cls, pickled, resultsid): + fn, args, kwargs = pickle.loads(pickled) + cls._call(fn, args, kwargs, resultsid) + + def __init__(self, initdata, shared=None): + self.initdata = initdata + self.shared = dict(shared) if shared else None + self.interpid = None + self.resultsid = None + + def __del__(self): + if self.interpid is not None: + self.finalize() + + def _exec(self, script): + assert self.interpid is not None + excinfo = _interpreters.exec(self.interpid, script, restrict=True) + if excinfo is not None: + raise ExecutionFailed(excinfo) + + def initialize(self): + assert self.interpid is None, self.interpid + self.interpid = _interpreters.create(reqrefs=True) + try: + _interpreters.incref(self.interpid) + + maxsize = 0 + fmt = 0 + self.resultsid = _interpqueues.create(maxsize, fmt, UNBOUND) + + self._exec(f'from {__name__} import WorkerContext') + + if self.shared: + _interpreters.set___main___attrs( + self.interpid, self.shared, restrict=True) + + if self.initdata: + self.run(self.initdata) + except BaseException: + self.finalize() + raise # re-raise + + def finalize(self): + interpid = self.interpid + resultsid = self.resultsid + self.resultsid = None + self.interpid = None + if resultsid is not None: + try: + _interpqueues.destroy(resultsid) + except _interpqueues.QueueNotFoundError: + pass + if interpid is not None: + try: + _interpreters.decref(interpid) + except _interpreters.InterpreterNotFoundError: + pass + + def run(self, task): + data, kind = task + if kind == 'script': + raise NotImplementedError('script kind disabled') + script = f""" +with WorkerContext._capture_exc({self.resultsid}): +{textwrap.indent(data, ' ')} +WorkerContext._send_script_result({self.resultsid})""" + elif kind == 'function': + script = f'WorkerContext._call_pickled({data!r}, {self.resultsid})' + else: + raise NotImplementedError(kind) + + try: + self._exec(script) + except ExecutionFailed as exc: + exc_wrapper = exc + else: + exc_wrapper = None + + # Return the result, or raise the exception. + while True: + try: + obj = _interpqueues.get(self.resultsid) + except _interpqueues.QueueNotFoundError: + raise # re-raise + except _interpqueues.QueueError: + continue + except ModuleNotFoundError: + # interpreters.queues doesn't exist, which means + # QueueEmpty doesn't. Act as though it does. + continue + else: + break + (res, excdata), pickled, unboundop = obj + assert unboundop is None, unboundop + if excdata is not None: + assert res is None, res + assert pickled + assert exc_wrapper is not None + exc = pickle.loads(excdata) + raise exc from exc_wrapper + return pickle.loads(res) if pickled else res + + +class BrokenInterpreterPool(_thread.BrokenThreadPool): + """ + Raised when a worker thread in an InterpreterPoolExecutor failed initializing. + """ + + +class InterpreterPoolExecutor(_thread.ThreadPoolExecutor): + + BROKEN = BrokenInterpreterPool + + @classmethod + def prepare_context(cls, initializer, initargs, shared): + return WorkerContext.prepare(initializer, initargs, shared) + + def __init__(self, max_workers=None, thread_name_prefix='', + initializer=None, initargs=(), shared=None): + """Initializes a new InterpreterPoolExecutor instance. + + Args: + max_workers: The maximum number of interpreters that can be used to + execute the given calls. + thread_name_prefix: An optional name prefix to give our threads. + initializer: A callable or script used to initialize + each worker interpreter. + initargs: A tuple of arguments to pass to the initializer. + shared: A mapping of shareabled objects to be inserted into + each worker interpreter. + """ + super().__init__(max_workers, thread_name_prefix, + initializer, initargs, shared=shared) diff --git a/Lib/concurrent/futures/thread.py b/Lib/concurrent/futures/thread.py index a024033f35fb54..16cc5533d429ef 100644 --- a/Lib/concurrent/futures/thread.py +++ b/Lib/concurrent/futures/thread.py @@ -43,19 +43,46 @@ def _python_exit(): after_in_parent=_global_shutdown_lock.release) +class WorkerContext: + + @classmethod + def prepare(cls, initializer, initargs): + if initializer is not None: + if not callable(initializer): + raise TypeError("initializer must be a callable") + def create_context(): + return cls(initializer, initargs) + def resolve_task(fn, args, kwargs): + return (fn, args, kwargs) + return create_context, resolve_task + + def __init__(self, initializer, initargs): + self.initializer = initializer + self.initargs = initargs + + def initialize(self): + if self.initializer is not None: + self.initializer(*self.initargs) + + def finalize(self): + pass + + def run(self, task): + fn, args, kwargs = task + return fn(*args, **kwargs) + + class _WorkItem: - def __init__(self, future, fn, args, kwargs): + def __init__(self, future, task): self.future = future - self.fn = fn - self.args = args - self.kwargs = kwargs + self.task = task - def run(self): + def run(self, ctx): if not self.future.set_running_or_notify_cancel(): return try: - result = self.fn(*self.args, **self.kwargs) + result = ctx.run(self.task) except BaseException as exc: self.future.set_exception(exc) # Break a reference cycle with the exception 'exc' @@ -66,16 +93,15 @@ def run(self): __class_getitem__ = classmethod(types.GenericAlias) -def _worker(executor_reference, work_queue, initializer, initargs): - if initializer is not None: - try: - initializer(*initargs) - except BaseException: - _base.LOGGER.critical('Exception in initializer:', exc_info=True) - executor = executor_reference() - if executor is not None: - executor._initializer_failed() - return +def _worker(executor_reference, ctx, work_queue): + try: + ctx.initialize() + except BaseException: + _base.LOGGER.critical('Exception in initializer:', exc_info=True) + executor = executor_reference() + if executor is not None: + executor._initializer_failed() + return try: while True: try: @@ -89,7 +115,7 @@ def _worker(executor_reference, work_queue, initializer, initargs): work_item = work_queue.get(block=True) if work_item is not None: - work_item.run() + work_item.run(ctx) # Delete references to object. See GH-60488 del work_item continue @@ -110,6 +136,8 @@ def _worker(executor_reference, work_queue, initializer, initargs): del executor except BaseException: _base.LOGGER.critical('Exception in worker', exc_info=True) + finally: + ctx.finalize() class BrokenThreadPool(_base.BrokenExecutor): @@ -120,11 +148,17 @@ class BrokenThreadPool(_base.BrokenExecutor): class ThreadPoolExecutor(_base.Executor): + BROKEN = BrokenThreadPool + # Used to assign unique thread names when thread_name_prefix is not supplied. _counter = itertools.count().__next__ + @classmethod + def prepare_context(cls, initializer, initargs): + return WorkerContext.prepare(initializer, initargs) + def __init__(self, max_workers=None, thread_name_prefix='', - initializer=None, initargs=()): + initializer=None, initargs=(), **ctxkwargs): """Initializes a new ThreadPoolExecutor instance. Args: @@ -133,6 +167,7 @@ def __init__(self, max_workers=None, thread_name_prefix='', thread_name_prefix: An optional name prefix to give our threads. initializer: A callable used to initialize worker threads. initargs: A tuple of arguments to pass to the initializer. + ctxkwargs: Additional arguments to cls.prepare_context(). """ if max_workers is None: # ThreadPoolExecutor is often used to: @@ -146,8 +181,9 @@ def __init__(self, max_workers=None, thread_name_prefix='', if max_workers <= 0: raise ValueError("max_workers must be greater than 0") - if initializer is not None and not callable(initializer): - raise TypeError("initializer must be a callable") + (self._create_worker_context, + self._resolve_work_item_task, + ) = type(self).prepare_context(initializer, initargs, **ctxkwargs) self._max_workers = max_workers self._work_queue = queue.SimpleQueue() @@ -158,13 +194,11 @@ def __init__(self, max_workers=None, thread_name_prefix='', self._shutdown_lock = threading.Lock() self._thread_name_prefix = (thread_name_prefix or ("ThreadPoolExecutor-%d" % self._counter())) - self._initializer = initializer - self._initargs = initargs def submit(self, fn, /, *args, **kwargs): with self._shutdown_lock, _global_shutdown_lock: if self._broken: - raise BrokenThreadPool(self._broken) + raise self.BROKEN(self._broken) if self._shutdown: raise RuntimeError('cannot schedule new futures after shutdown') @@ -173,7 +207,8 @@ def submit(self, fn, /, *args, **kwargs): 'interpreter shutdown') f = _base.Future() - w = _WorkItem(f, fn, args, kwargs) + task = self._resolve_work_item_task(fn, args, kwargs) + w = _WorkItem(f, task) self._work_queue.put(w) self._adjust_thread_count() @@ -196,9 +231,8 @@ def weakref_cb(_, q=self._work_queue): num_threads) t = threading.Thread(name=thread_name, target=_worker, args=(weakref.ref(self, weakref_cb), - self._work_queue, - self._initializer, - self._initargs)) + self._create_worker_context(), + self._work_queue)) t.start() self._threads.add(t) _threads_queues[t] = self._work_queue @@ -214,7 +248,7 @@ def _initializer_failed(self): except queue.Empty: break if work_item is not None: - work_item.future.set_exception(BrokenThreadPool(self._broken)) + work_item.future.set_exception(self.BROKEN(self._broken)) def shutdown(self, wait=True, *, cancel_futures=False): with self._shutdown_lock: diff --git a/Lib/test/test_concurrent_futures/executor.py b/Lib/test/test_concurrent_futures/executor.py index 4160656cb133ab..b97d9ffd94b1f8 100644 --- a/Lib/test/test_concurrent_futures/executor.py +++ b/Lib/test/test_concurrent_futures/executor.py @@ -23,6 +23,7 @@ def make_dummy_object(_): class ExecutorTest: + # Executor.shutdown() and context manager usage is tested by # ExecutorShutdownTest. def test_submit(self): @@ -52,7 +53,8 @@ def test_map_exception(self): i = self.executor.map(divmod, [1, 1, 1, 1], [2, 3, 0, 5]) self.assertEqual(i.__next__(), (0, 1)) self.assertEqual(i.__next__(), (0, 1)) - self.assertRaises(ZeroDivisionError, i.__next__) + with self.assertRaises(ZeroDivisionError): + i.__next__() @support.requires_resource('walltime') def test_map_timeout(self): diff --git a/Lib/test/test_concurrent_futures/test_interpreter_pool.py b/Lib/test/test_concurrent_futures/test_interpreter_pool.py new file mode 100644 index 00000000000000..0de03c0d669399 --- /dev/null +++ b/Lib/test/test_concurrent_futures/test_interpreter_pool.py @@ -0,0 +1,346 @@ +import asyncio +import contextlib +import io +import os +import pickle +import sys +import time +import unittest +from concurrent.futures.interpreter import ( + ExecutionFailed, BrokenInterpreterPool, +) +import _interpreters +from test import support +import test.test_asyncio.utils as testasyncio_utils +from test.support.interpreters import queues + +from .executor import ExecutorTest, mul +from .util import BaseTestCase, InterpreterPoolMixin, setup_module + + +def noop(): + pass + + +def write_msg(fd, msg): + os.write(fd, msg + b'\0') + + +def read_msg(fd): + msg = b'' + while ch := os.read(fd, 1): + if ch == b'\0': + return msg + msg += ch + + +def get_current_name(): + return __name__ + + +def fail(exctype, msg=None): + raise exctype(msg) + + +def get_current_interpid(*extra): + interpid, _ = _interpreters.get_current() + return (interpid, *extra) + + +class InterpretersMixin(InterpreterPoolMixin): + + def pipe(self): + r, w = os.pipe() + self.addCleanup(lambda: os.close(r)) + self.addCleanup(lambda: os.close(w)) + return r, w + + +class InterpreterPoolExecutorTest( + InterpretersMixin, ExecutorTest, BaseTestCase): + + @unittest.expectedFailure + def test_init_script(self): + msg1 = b'step: init' + msg2 = b'step: run' + r, w = self.pipe() + initscript = f""" + import os + msg = {msg2!r} + os.write({w}, {msg1!r} + b'\\0') + """ + script = f""" + os.write({w}, msg + b'\\0') + """ + os.write(w, b'\0') + + executor = self.executor_type(initializer=initscript) + before_init = os.read(r, 100) + fut = executor.submit(script) + after_init = read_msg(r) + fut.result() + after_run = read_msg(r) + + self.assertEqual(before_init, b'\0') + self.assertEqual(after_init, msg1) + self.assertEqual(after_run, msg2) + + @unittest.expectedFailure + def test_init_script_args(self): + with self.assertRaises(ValueError): + self.executor_type(initializer='pass', initargs=('spam',)) + + def test_init_func(self): + msg = b'step: init' + r, w = self.pipe() + os.write(w, b'\0') + + executor = self.executor_type( + initializer=write_msg, initargs=(w, msg)) + before = os.read(r, 100) + executor.submit(mul, 10, 10) + after = read_msg(r) + + self.assertEqual(before, b'\0') + self.assertEqual(after, msg) + + def test_init_closure(self): + count = 0 + def init1(): + assert count == 0, count + def init2(): + nonlocal count + count += 1 + + with self.assertRaises(pickle.PicklingError): + self.executor_type(initializer=init1) + with self.assertRaises(pickle.PicklingError): + self.executor_type(initializer=init2) + + def test_init_instance_method(self): + class Spam: + def initializer(self): + raise NotImplementedError + spam = Spam() + + with self.assertRaises(pickle.PicklingError): + self.executor_type(initializer=spam.initializer) + + def test_init_shared(self): + msg = b'eggs' + r, w = self.pipe() + script = f"""if True: + import os + if __name__ != '__main__': + import __main__ + spam = __main__.spam + os.write({w}, spam + b'\\0') + """ + + executor = self.executor_type(shared={'spam': msg}) + fut = executor.submit(exec, script) + fut.result() + after = read_msg(r) + + self.assertEqual(after, msg) + + @unittest.expectedFailure + def test_init_exception_in_script(self): + executor = self.executor_type(initializer='raise Exception("spam")') + with executor: + with contextlib.redirect_stderr(io.StringIO()) as stderr: + fut = executor.submit('pass') + with self.assertRaises(BrokenInterpreterPool): + fut.result() + stderr = stderr.getvalue() + self.assertIn('ExecutionFailed: Exception: spam', stderr) + self.assertIn('Uncaught in the interpreter:', stderr) + self.assertIn('The above exception was the direct cause of the following exception:', + stderr) + + def test_init_exception_in_func(self): + executor = self.executor_type(initializer=fail, + initargs=(Exception, 'spam')) + with executor: + with contextlib.redirect_stderr(io.StringIO()) as stderr: + fut = executor.submit(noop) + with self.assertRaises(BrokenInterpreterPool): + fut.result() + stderr = stderr.getvalue() + self.assertIn('ExecutionFailed: Exception: spam', stderr) + self.assertIn('Uncaught in the interpreter:', stderr) + self.assertIn('The above exception was the direct cause of the following exception:', + stderr) + + @unittest.expectedFailure + def test_submit_script(self): + msg = b'spam' + r, w = self.pipe() + script = f""" + import os + os.write({w}, __name__.encode('utf-8') + b'\\0') + """ + executor = self.executor_type() + + fut = executor.submit(script) + res = fut.result() + after = read_msg(r) + + self.assertEqual(after, b'__main__') + self.assertIs(res, None) + + def test_submit_closure(self): + spam = True + def task1(): + return spam + def task2(): + nonlocal spam + spam += 1 + return spam + + executor = self.executor_type() + with self.assertRaises(pickle.PicklingError): + executor.submit(task1) + with self.assertRaises(pickle.PicklingError): + executor.submit(task2) + + def test_submit_local_instance(self): + class Spam: + def __init__(self): + self.value = True + + executor = self.executor_type() + with self.assertRaises(pickle.PicklingError): + executor.submit(Spam) + + def test_submit_instance_method(self): + class Spam: + def run(self): + return True + spam = Spam() + + executor = self.executor_type() + with self.assertRaises(pickle.PicklingError): + executor.submit(spam.run) + + def test_submit_func_globals(self): + executor = self.executor_type() + fut = executor.submit(get_current_name) + name = fut.result() + + self.assertEqual(name, __name__) + self.assertNotEqual(name, '__main__') + + @unittest.expectedFailure + def test_submit_exception_in_script(self): + fut = self.executor.submit('raise Exception("spam")') + with self.assertRaises(Exception) as captured: + fut.result() + self.assertIs(type(captured.exception), Exception) + self.assertEqual(str(captured.exception), 'spam') + cause = captured.exception.__cause__ + self.assertIs(type(cause), ExecutionFailed) + for attr in ('__name__', '__qualname__', '__module__'): + self.assertEqual(getattr(cause.excinfo.type, attr), + getattr(Exception, attr)) + self.assertEqual(cause.excinfo.msg, 'spam') + + def test_submit_exception_in_func(self): + fut = self.executor.submit(fail, Exception, 'spam') + with self.assertRaises(Exception) as captured: + fut.result() + self.assertIs(type(captured.exception), Exception) + self.assertEqual(str(captured.exception), 'spam') + cause = captured.exception.__cause__ + self.assertIs(type(cause), ExecutionFailed) + for attr in ('__name__', '__qualname__', '__module__'): + self.assertEqual(getattr(cause.excinfo.type, attr), + getattr(Exception, attr)) + self.assertEqual(cause.excinfo.msg, 'spam') + + def test_saturation(self): + blocker = queues.create() + executor = self.executor_type(4, shared=dict(blocker=blocker)) + + for i in range(15 * executor._max_workers): + executor.submit(exec, 'import __main__; __main__.blocker.get()') + #executor.submit('blocker.get()') + self.assertEqual(len(executor._threads), executor._max_workers) + for i in range(15 * executor._max_workers): + blocker.put_nowait(None) + executor.shutdown(wait=True) + + @support.requires_gil_enabled("gh-117344: test is flaky without the GIL") + def test_idle_thread_reuse(self): + executor = self.executor_type() + executor.submit(mul, 21, 2).result() + executor.submit(mul, 6, 7).result() + executor.submit(mul, 3, 14).result() + self.assertEqual(len(executor._threads), 1) + executor.shutdown(wait=True) + + +class AsyncioTest(InterpretersMixin, testasyncio_utils.TestCase): + + def setUp(self): + super().setUp() + self.loop = asyncio.new_event_loop() + self.set_event_loop(self.loop) + + self.executor = self.executor_type() + self.addCleanup(lambda: self.executor.shutdown()) + + def tearDown(self): + if not self.loop.is_closed(): + testasyncio_utils.run_briefly(self.loop) + + self.doCleanups() + support.gc_collect() + super().tearDown() + + def test_run_in_executor(self): + unexpected, _ = _interpreters.get_current() + + func = get_current_interpid + fut = self.loop.run_in_executor(self.executor, func, 'yo') + interpid, res = self.loop.run_until_complete(fut) + + self.assertEqual(res, 'yo') + self.assertNotEqual(interpid, unexpected) + + def test_run_in_executor_cancel(self): + executor = self.executor_type() + + called = False + + def patched_call_soon(*args): + nonlocal called + called = True + + func = time.sleep + fut = self.loop.run_in_executor(self.executor, func, 0.05) + fut.cancel() + self.loop.run_until_complete( + self.loop.shutdown_default_executor()) + self.loop.close() + self.loop.call_soon = patched_call_soon + self.loop.call_soon_threadsafe = patched_call_soon + time.sleep(0.4) + self.assertFalse(called) + + def test_default_executor(self): + unexpected, _ = _interpreters.get_current() + + self.loop.set_default_executor(self.executor) + fut = self.loop.run_in_executor(None, get_current_interpid) + interpid, = self.loop.run_until_complete(fut) + + self.assertNotEqual(interpid, unexpected) + + +def setUpModule(): + setup_module() + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_concurrent_futures/util.py b/Lib/test/test_concurrent_futures/util.py index 3b8ec3e205d5aa..52baab51340fc9 100644 --- a/Lib/test/test_concurrent_futures/util.py +++ b/Lib/test/test_concurrent_futures/util.py @@ -74,6 +74,10 @@ class ThreadPoolMixin(ExecutorMixin): executor_type = futures.ThreadPoolExecutor +class InterpreterPoolMixin(ExecutorMixin): + executor_type = futures.InterpreterPoolExecutor + + class ProcessPoolForkMixin(ExecutorMixin): executor_type = futures.ProcessPoolExecutor ctx = "fork" @@ -120,6 +124,7 @@ def get_context(self): def create_executor_tests(remote_globals, mixin, bases=(BaseTestCase,), executor_mixins=(ThreadPoolMixin, + InterpreterPoolMixin, ProcessPoolForkMixin, ProcessPoolForkserverMixin, ProcessPoolSpawnMixin)): diff --git a/Misc/NEWS.d/next/Library/2024-09-27-15-42-55.gh-issue-124694.uUy32y.rst b/Misc/NEWS.d/next/Library/2024-09-27-15-42-55.gh-issue-124694.uUy32y.rst new file mode 100644 index 00000000000000..1aa1a463b0c63a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-09-27-15-42-55.gh-issue-124694.uUy32y.rst @@ -0,0 +1,6 @@ +We've added :class:`concurrent.futures.InterpreterPoolExecutor`, which +allows you to run code in multiple isolated interpreters. This allows you +to circumvent the limitations of CPU-bound threads (due to the GIL). Patch +by Eric Snow. + +This addition is unrelated to :pep:`734`. From 624be8699aec22bef137041478078c6fafaf032e Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Thu, 17 Oct 2024 00:07:37 -0700 Subject: [PATCH 116/170] GH-99749: Add optional feature to suggest correct names (ArgumentParser) (GH-124456) --- Doc/library/argparse.rst | 28 ++++- Lib/argparse.py | 35 ++++-- Lib/test/test_argparse.py | 103 +++++++++++++++--- ...4-09-24-18-49-16.gh-issue-99749.gBDJX7.rst | 1 + 4 files changed, 144 insertions(+), 23 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-09-24-18-49-16.gh-issue-99749.gBDJX7.rst diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index 51ab8e29ff96d5..ee8562b81770b6 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -61,7 +61,8 @@ ArgumentParser objects formatter_class=argparse.HelpFormatter, \ prefix_chars='-', fromfile_prefix_chars=None, \ argument_default=None, conflict_handler='error', \ - add_help=True, allow_abbrev=True, exit_on_error=True) + add_help=True, allow_abbrev=True, exit_on_error=True, \ + suggest_on_error=False) Create a new :class:`ArgumentParser` object. All parameters should be passed as keyword arguments. Each parameter has its own more detailed description @@ -103,6 +104,10 @@ ArgumentParser objects * exit_on_error_ - Determines whether or not ArgumentParser exits with error info when an error occurs. (default: ``True``) + * suggest_on_error_ - Enables suggestions for mistyped argument choices + and subparser names (default: ``False``) + + .. versionchanged:: 3.5 *allow_abbrev* parameter was added. @@ -559,6 +564,27 @@ If the user would like to catch errors manually, the feature can be enabled by s .. versionadded:: 3.9 +suggest_on_error +^^^^^^^^^^^^^^^^ + +By default, when a user passes an invalid argument choice or subparser name, +:class:`ArgumentParser` will exit with error info and list the permissible +argument choices (if specified) or subparser names as part of the error message. + +If the user would like to enable suggestions for mistyped argument choices and +subparser names, the feature can be enabled by setting ``suggest_on_error`` to +``True``. Note that this only applies for arguments when the choices specified +are strings:: + + >>> parser = argparse.ArgumentParser(description='Process some integers.', suggest_on_error=True) + >>> parser.add_argument('--action', choices=['sum', 'max']) + >>> parser.add_argument('integers', metavar='N', type=int, nargs='+', + ... help='an integer for the accumulator') + >>> parser.parse_args(['--action', 'sumn', 1, 2, 3]) + tester.py: error: argument --action: invalid choice: 'sumn', maybe you meant 'sum'? (choose from 'sum', 'max') + +.. versionadded:: 3.14 + The add_argument() method ------------------------- diff --git a/Lib/argparse.py b/Lib/argparse.py index fa9f5211257e96..ece6f2e880d5cb 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -1773,6 +1773,8 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): - allow_abbrev -- Allow long options to be abbreviated unambiguously - exit_on_error -- Determines whether or not ArgumentParser exits with error info when an error occurs + - suggest_on_error - Enables suggestions for mistyped argument choices + and subparser names. (default: ``False``) """ def __init__(self, @@ -1788,7 +1790,8 @@ def __init__(self, conflict_handler='error', add_help=True, allow_abbrev=True, - exit_on_error=True): + exit_on_error=True, + suggest_on_error=False): superinit = super(ArgumentParser, self).__init__ superinit(description=description, @@ -1804,6 +1807,7 @@ def __init__(self, self.add_help = add_help self.allow_abbrev = allow_abbrev self.exit_on_error = exit_on_error + self.suggest_on_error = suggest_on_error add_group = self.add_argument_group self._positionals = add_group(_('positional arguments')) @@ -2601,14 +2605,27 @@ def _get_value(self, action, arg_string): def _check_value(self, action, value): # converted value must be one of the choices (if specified) choices = action.choices - if choices is not None: - if isinstance(choices, str): - choices = iter(choices) - if value not in choices: - args = {'value': str(value), - 'choices': ', '.join(map(str, action.choices))} - msg = _('invalid choice: %(value)r (choose from %(choices)s)') - raise ArgumentError(action, msg % args) + if choices is None: + return + + if isinstance(choices, str): + choices = iter(choices) + + if value not in choices: + args = {'value': str(value), + 'choices': ', '.join(map(str, action.choices))} + msg = _('invalid choice: %(value)r (choose from %(choices)s)') + + if self.suggest_on_error and isinstance(value, str): + if all(isinstance(choice, str) for choice in action.choices): + import difflib + suggestions = difflib.get_close_matches(value, action.choices, 1) + if suggestions: + args['closest'] = suggestions[0] + msg = _('invalid choice: %(value)r, maybe you meant %(closest)r? ' + '(choose from %(choices)s)') + + raise ArgumentError(action, msg % args) # ======================= # Help-formatting methods diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 78692fd3474782..a3c096ef3199c8 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -2253,6 +2253,95 @@ class TestNegativeNumber(ParserTestCase): ('--complex -1e-3j', NS(int=None, float=None, complex=-0.001j)), ] +class TestArgumentAndSubparserSuggestions(TestCase): + """Test error handling and suggestion when a user makes a typo""" + + def test_wrong_argument_error_with_suggestions(self): + parser = ErrorRaisingArgumentParser(suggest_on_error=True) + parser.add_argument('foo', choices=['bar', 'baz']) + with self.assertRaises(ArgumentParserError) as excinfo: + parser.parse_args(('bazz',)) + self.assertIn( + "error: argument foo: invalid choice: 'bazz', maybe you meant 'baz'? (choose from bar, baz)", + excinfo.exception.stderr + ) + + def test_wrong_argument_error_no_suggestions(self): + parser = ErrorRaisingArgumentParser(suggest_on_error=False) + parser.add_argument('foo', choices=['bar', 'baz']) + with self.assertRaises(ArgumentParserError) as excinfo: + parser.parse_args(('bazz',)) + self.assertIn( + "error: argument foo: invalid choice: 'bazz' (choose from bar, baz)", + excinfo.exception.stderr, + ) + + def test_wrong_argument_subparsers_with_suggestions(self): + parser = ErrorRaisingArgumentParser(suggest_on_error=True) + subparsers = parser.add_subparsers(required=True) + subparsers.add_parser('foo') + subparsers.add_parser('bar') + with self.assertRaises(ArgumentParserError) as excinfo: + parser.parse_args(('baz',)) + self.assertIn( + "error: argument {foo,bar}: invalid choice: 'baz', maybe you meant" + " 'bar'? (choose from foo, bar)", + excinfo.exception.stderr, + ) + + def test_wrong_argument_subparsers_no_suggestions(self): + parser = ErrorRaisingArgumentParser(suggest_on_error=False) + subparsers = parser.add_subparsers(required=True) + subparsers.add_parser('foo') + subparsers.add_parser('bar') + with self.assertRaises(ArgumentParserError) as excinfo: + parser.parse_args(('baz',)) + self.assertIn( + "error: argument {foo,bar}: invalid choice: 'baz' (choose from foo, bar)", + excinfo.exception.stderr, + ) + + def test_wrong_argument_no_suggestion_implicit(self): + parser = ErrorRaisingArgumentParser() + parser.add_argument('foo', choices=['bar', 'baz']) + with self.assertRaises(ArgumentParserError) as excinfo: + parser.parse_args(('bazz',)) + self.assertIn( + "error: argument foo: invalid choice: 'bazz' (choose from bar, baz)", + excinfo.exception.stderr, + ) + + def test_suggestions_choices_empty(self): + parser = ErrorRaisingArgumentParser(suggest_on_error=True) + parser.add_argument('foo', choices=[]) + with self.assertRaises(ArgumentParserError) as excinfo: + parser.parse_args(('bazz',)) + self.assertIn( + "error: argument foo: invalid choice: 'bazz' (choose from )", + excinfo.exception.stderr, + ) + + def test_suggestions_choices_int(self): + parser = ErrorRaisingArgumentParser(suggest_on_error=True) + parser.add_argument('foo', choices=[1, 2]) + with self.assertRaises(ArgumentParserError) as excinfo: + parser.parse_args(('3',)) + self.assertIn( + "error: argument foo: invalid choice: '3' (choose from 1, 2)", + excinfo.exception.stderr, + ) + + def test_suggestions_choices_mixed_types(self): + parser = ErrorRaisingArgumentParser(suggest_on_error=True) + parser.add_argument('foo', choices=[1, '2']) + with self.assertRaises(ArgumentParserError) as excinfo: + parser.parse_args(('3',)) + self.assertIn( + "error: argument foo: invalid choice: '3' (choose from 1, 2)", + excinfo.exception.stderr, + ) + + class TestInvalidAction(TestCase): """Test invalid user defined Action""" @@ -2505,18 +2594,6 @@ def test_required_subparsers_no_destination_error(self): 'error: the following arguments are required: {foo,bar}\n$' ) - def test_wrong_argument_subparsers_no_destination_error(self): - parser = ErrorRaisingArgumentParser() - subparsers = parser.add_subparsers(required=True) - subparsers.add_parser('foo') - subparsers.add_parser('bar') - with self.assertRaises(ArgumentParserError) as excinfo: - parser.parse_args(('baz',)) - self.assertRegex( - excinfo.exception.stderr, - r"error: argument {foo,bar}: invalid choice: 'baz' \(choose from foo, bar\)\n$" - ) - def test_optional_subparsers(self): parser = ErrorRaisingArgumentParser() subparsers = parser.add_subparsers(dest='command', required=False) @@ -2862,7 +2939,7 @@ def test_single_parent_mutex(self): parser = ErrorRaisingArgumentParser(parents=[self.ab_mutex_parent]) self._test_mutex_ab(parser.parse_args) - def test_single_granparent_mutex(self): + def test_single_grandparent_mutex(self): parents = [self.ab_mutex_parent] parser = ErrorRaisingArgumentParser(add_help=False, parents=parents) parser = ErrorRaisingArgumentParser(parents=[parser]) diff --git a/Misc/NEWS.d/next/Library/2024-09-24-18-49-16.gh-issue-99749.gBDJX7.rst b/Misc/NEWS.d/next/Library/2024-09-24-18-49-16.gh-issue-99749.gBDJX7.rst new file mode 100644 index 00000000000000..3ecd75c5b551b6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-09-24-18-49-16.gh-issue-99749.gBDJX7.rst @@ -0,0 +1 @@ +Adds a feature to optionally enable suggestions for argument choices and subparser names if mistyped by the user. From 7b04496e5c7ed47e9653f4591674fc9ffef34587 Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Thu, 17 Oct 2024 02:11:47 -0700 Subject: [PATCH 117/170] gh-125542: Deprecate prefix_chars in ArgumentParser.add_argument_group() (GH-125563) --- .../pending-removal-in-future.rst | 9 +++++-- Doc/library/argparse.rst | 4 +++ Doc/whatsnew/3.14.rst | 6 +++++ Lib/argparse.py | 8 ++++++ Lib/test/test_argparse.py | 25 +++++++++++++++++++ ...-10-16-04-50-53.gh-issue-125542.vZJ-Ns.rst | 2 ++ 6 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-16-04-50-53.gh-issue-125542.vZJ-Ns.rst diff --git a/Doc/deprecations/pending-removal-in-future.rst b/Doc/deprecations/pending-removal-in-future.rst index f916797c07a068..d77fc86eab0ed6 100644 --- a/Doc/deprecations/pending-removal-in-future.rst +++ b/Doc/deprecations/pending-removal-in-future.rst @@ -4,8 +4,13 @@ Pending removal in future versions The following APIs will be removed in the future, although there is currently no date scheduled for their removal. -* :mod:`argparse`: Nesting argument groups and nesting mutually exclusive - groups are deprecated. +* :mod:`argparse`: + + * Nesting argument groups and nesting mutually exclusive + groups are deprecated. + * Passing the undocumented keyword argument *prefix_chars* to + :meth:`~argparse.ArgumentParser.add_argument_group` is now + deprecated. * :mod:`array`'s ``'u'`` format code (:gh:`57281`) diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index ee8562b81770b6..ef0db3e9789c98 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -1894,6 +1894,10 @@ Argument groups The function exists on the API by accident through inheritance and will be removed in the future. + .. deprecated:: 3.14 + Passing prefix_chars_ to :meth:`add_argument_group` + is now deprecated. + Mutual exclusion ^^^^^^^^^^^^^^^^ diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index 9543af3c7ca225..feb65f244827ad 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -428,6 +428,12 @@ asyncio Deprecated ========== +* :mod:`argparse`: + Passing the undocumented keyword argument *prefix_chars* to + :meth:`~argparse.ArgumentParser.add_argument_group` is now + deprecated. + (Contributed by Savannah Ostrowski in :gh:`125563`.) + * :mod:`asyncio`: :func:`!asyncio.iscoroutinefunction` is deprecated and will be removed in Python 3.16, diff --git a/Lib/argparse.py b/Lib/argparse.py index ece6f2e880d5cb..49271a146c7282 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -1662,6 +1662,14 @@ def _check_help(self, action): class _ArgumentGroup(_ActionsContainer): def __init__(self, container, title=None, description=None, **kwargs): + if 'prefix_chars' in kwargs: + import warnings + depr_msg = ( + "The use of the undocumented 'prefix_chars' parameter in " + "ArgumentParser.add_argument_group() is deprecated." + ) + warnings.warn(depr_msg, DeprecationWarning, stacklevel=3) + # add any missing keyword arguments by checking the container update = kwargs.setdefault update('conflict_handler', container.conflict_handler) diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index a3c096ef3199c8..4fa669718abc50 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -2893,6 +2893,31 @@ def test_interleaved_groups(self): result = parser.parse_args('1 2 3 4'.split()) self.assertEqual(expected, result) +class TestGroupConstructor(TestCase): + def test_group_prefix_chars(self): + parser = ErrorRaisingArgumentParser() + msg = ( + "The use of the undocumented 'prefix_chars' parameter in " + "ArgumentParser.add_argument_group() is deprecated." + ) + with self.assertWarns(DeprecationWarning) as cm: + parser.add_argument_group(prefix_chars='-+') + self.assertEqual(msg, str(cm.warning)) + self.assertEqual(cm.filename, __file__) + + def test_group_prefix_chars_default(self): + # "default" isn't quite the right word here, but it's the same as + # the parser's default prefix so it's a good test + parser = ErrorRaisingArgumentParser() + msg = ( + "The use of the undocumented 'prefix_chars' parameter in " + "ArgumentParser.add_argument_group() is deprecated." + ) + with self.assertWarns(DeprecationWarning) as cm: + parser.add_argument_group(prefix_chars='-') + self.assertEqual(msg, str(cm.warning)) + self.assertEqual(cm.filename, __file__) + # =================== # Parent parser tests # =================== diff --git a/Misc/NEWS.d/next/Library/2024-10-16-04-50-53.gh-issue-125542.vZJ-Ns.rst b/Misc/NEWS.d/next/Library/2024-10-16-04-50-53.gh-issue-125542.vZJ-Ns.rst new file mode 100644 index 00000000000000..777920cc54ff9b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-16-04-50-53.gh-issue-125542.vZJ-Ns.rst @@ -0,0 +1,2 @@ +Deprecate passing keyword-only *prefix_chars* argument to +:meth:`argparse.ArgumentParser.add_argument_group`. From dbcc5ac4709dfd8dfaf323d51f135f2218d14068 Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Thu, 17 Oct 2024 04:41:22 -0700 Subject: [PATCH 118/170] gh-95836: Add custom type converter examples to argparse tutorial (GH-125376) --- Doc/howto/argparse.rst | 47 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/Doc/howto/argparse.rst b/Doc/howto/argparse.rst index 30d9ac700376e6..1efbee64d60bb3 100644 --- a/Doc/howto/argparse.rst +++ b/Doc/howto/argparse.rst @@ -841,6 +841,53 @@ translated messages. To translate your own strings in the :mod:`argparse` output, use :mod:`gettext`. +Custom type converters +====================== + +The :mod:`argparse` module allows you to specify custom type converters for +your command-line arguments. This allows you to modify user input before it's +stored in the :class:`argparse.Namespace`. This can be useful when you need to +pre-process the input before it is used in your program. + +When using a custom type converter, you can use any callable that takes a +single string argument (the argument value) and returns the converted value. +However, if you need to handle more complex scenarios, you can use a custom +action class with the **action** parameter instead. + +For example, let's say you want to handle arguments with different prefixes and +process them accordingly:: + + import argparse + + parser = argparse.ArgumentParser(prefix_chars='-+') + + parser.add_argument('-a', metavar='', action='append', + type=lambda x: ('-', x)) + parser.add_argument('+a', metavar='', action='append', + type=lambda x: ('+', x)) + + args = parser.parse_args() + print(args) + +Output: + +.. code-block:: shell-session + + $ python prog.py -a value1 +a value2 + Namespace(a=[('-', 'value1'), ('+', 'value2')]) + +In this example, we: + +* Created a parser with custom prefix characters using the ``prefix_chars`` + parameter. + +* Defined two arguments, ``-a`` and ``+a``, which used the ``type`` parameter to + create custom type converters to store the value in a tuple with the prefix. + +Without the custom type converters, the arguments would have treated the ``-a`` +and ``+a`` as the same argument, which would have been undesirable. By using custom +type converters, we were able to differentiate between the two arguments. + Conclusion ========== From 37986e830ba25d2c382988b06bbe27410596346c Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Thu, 17 Oct 2024 08:20:30 -0400 Subject: [PATCH 119/170] gh-123153: Fix PGO builds with free-threading on Windows (#125607) * gh-123153: Fix PGO builds with free-threading * Redo how the #define works --- Python/ceval.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/Python/ceval.c b/Python/ceval.c index 43776e773e0deb..98d95b28488fd0 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -761,12 +761,20 @@ _PyObjectArray_Free(PyObject **array, PyObject **scratch) * so consume 3 units of C stack */ #define PY_EVAL_C_STACK_UNITS 2 -#if defined(_MSC_VER) && defined(_Py_USING_PGO) && defined(_Py_JIT) -/* _PyEval_EvalFrameDefault is too large to optimize for speed with - PGO on MSVC when the JIT is enabled. Disable that optimization - around this function only. If this is fixed upstream, we should - gate this on the version of MSVC. + +/* _PyEval_EvalFrameDefault is too large to optimize for speed with PGO on MSVC + when the JIT is enabled or GIL is disabled. Disable that optimization around + this function only. If this is fixed upstream, we should gate this on the + version of MSVC. */ +#if (defined(_MSC_VER) && \ + defined(_Py_USING_PGO) && \ + (defined(_Py_JIT) || \ + defined(Py_GIL_DISABLED))) +#define DO_NOT_OPTIMIZE_INTERP_LOOP +#endif + +#ifdef DO_NOT_OPTIMIZE_INTERP_LOOP # pragma optimize("t", off) /* This setting is reversed below following _PyEval_EvalFrameDefault */ #endif @@ -1146,7 +1154,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } -#if defined(_MSC_VER) && defined(_Py_USING_PGO) && defined(_Py_JIT) +#ifdef DO_NOT_OPTIMIZE_INTERP_LOOP # pragma optimize("", on) #endif From 0d88b995a641315306d56fba7d07479b2c5f57ef Mon Sep 17 00:00:00 2001 From: Emmanuel Ferdman Date: Thu, 17 Oct 2024 17:33:37 +0300 Subject: [PATCH 120/170] gh-125644: Update `locations.md` reference (#125645) Signed-off-by: Emmanuel Ferdman --- InternalDocs/compiler.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InternalDocs/compiler.md b/InternalDocs/compiler.md index acef6def563154..e9608977b0cbb3 100644 --- a/InternalDocs/compiler.md +++ b/InternalDocs/compiler.md @@ -447,7 +447,7 @@ bytecode. This includes transforming pseudo instructions into actual instruction converting jump targets from logical labels to relative offsets, and construction of the [exception table](exception_handling.md) and -[locations table](https://github.com/python/cpython/blob/main/Objects/locations.md). +[locations table](https://github.com/python/cpython/blob/main/InternalDocs/locations.md). The bytecode and tables are then wrapped into a ``PyCodeObject`` along with additional metadata, including the ``consts`` and ``names`` arrays, information about function reference to the source code (filename, etc). All of this is implemented by From 528bbab96feadbfabb798547e5bb2ad52070fb73 Mon Sep 17 00:00:00 2001 From: Jonathan Protzenko Date: Thu, 17 Oct 2024 08:08:43 -0700 Subject: [PATCH 121/170] GH-99108: Make vectorized versions of Blake2 available on x86, too (#125244) Accomplished by updating HACL* vendored code from hacl-star/hacl-star@a6a09496d9cff652b567d26f2c3ab012321b632a to hacl-star/hacl-star@315a9e491d2bc347b9dae99e0ea506995ea84d9d Co-authored-by: Victor Stinner Co-authored-by: Zachary Ware --- Misc/sbom.spdx.json | 48 ++-- Modules/_hacl/Hacl_Hash_Blake2b.c | 260 +++++++++++------- Modules/_hacl/Hacl_Hash_Blake2b_Simd256.c | 225 +++++++++------ Modules/_hacl/Hacl_Hash_Blake2s.c | 231 ++++++++++------ Modules/_hacl/Hacl_Hash_Blake2s_Simd128.c | 196 ++++++++----- .../include/krml/FStar_UInt128_Verified.h | 2 +- .../include/krml/FStar_UInt_8_16_32_64.h | 2 +- .../krml/fstar_uint128_struct_endianness.h | 2 +- Modules/_hacl/include/krml/internal/target.h | 6 +- .../_hacl/include/krml/lowstar_endianness.h | 2 +- Modules/_hacl/libintvector.h | 2 +- Modules/_hacl/refresh.sh | 2 +- 12 files changed, 619 insertions(+), 359 deletions(-) diff --git a/Misc/sbom.spdx.json b/Misc/sbom.spdx.json index f07ad9423d9039..cc73e93009b43f 100644 --- a/Misc/sbom.spdx.json +++ b/Misc/sbom.spdx.json @@ -300,11 +300,11 @@ "checksums": [ { "algorithm": "SHA1", - "checksumValue": "c96cba53034348537ac423a220803b06cd9f0a43" + "checksumValue": "a34e821b68ef5334eccf4f729b28bb7bb65b965e" }, { "algorithm": "SHA256", - "checksumValue": "9f4fb5c70678638cfd163cc990be1def356cf7b65b75faa4666db8c5f8593530" + "checksumValue": "4582db9143c0810b98838a5357c577e0b32ae77f3018486159df4e0dfd3fce3c" } ], "fileName": "Modules/_hacl/Hacl_Hash_Blake2b.c" @@ -328,11 +328,11 @@ "checksums": [ { "algorithm": "SHA1", - "checksumValue": "e11e2d1771e56c0afbdb0673906898b3a67e0cc3" + "checksumValue": "0ffe60c6d5eed5dd222515e820d461d319d16b1f" }, { "algorithm": "SHA256", - "checksumValue": "d5bf29d995f7cb9861841b813aa01206664895a1c5aa166a4796785c02117bf4" + "checksumValue": "4804cb3ce68bfdcf98853d6f1d77b4a844a3c2796f776b39770ba327e400d402" } ], "fileName": "Modules/_hacl/Hacl_Hash_Blake2b_Simd256.c" @@ -370,11 +370,11 @@ "checksums": [ { "algorithm": "SHA1", - "checksumValue": "5422517af799cf74b194821fb2a1f39e3b02c54d" + "checksumValue": "cf035ffeff875bc74345a47373ce25dc408ea9dc" }, { "algorithm": "SHA256", - "checksumValue": "c66adab0259f2c2229e010cd635a982e8c2b8836e59e43e7867992d4148e4d9a" + "checksumValue": "579059b002c45fab0fed6381e85c3f5eaf1d959400ca64b103542ac6c35bade3" } ], "fileName": "Modules/_hacl/Hacl_Hash_Blake2s.c" @@ -398,11 +398,11 @@ "checksums": [ { "algorithm": "SHA1", - "checksumValue": "7822db8e7c2f60dd64a18e112a1bc369e7f7a0ff" + "checksumValue": "9bb53022d158a9c349edb52a8def8aac7d098a4e" }, { "algorithm": "SHA256", - "checksumValue": "94b0cd3cf1f7385325ee878d2ef06affc8d6412af9302ca47d1aa6d858182050" + "checksumValue": "2abde0c6b5da0402e91b4bedfe786c24b908fbdc04e08e74651c7624729254d9" } ], "fileName": "Modules/_hacl/Hacl_Hash_Blake2s_Simd128.c" @@ -580,11 +580,11 @@ "checksums": [ { "algorithm": "SHA1", - "checksumValue": "12c0c680c93b8112b97cc575faacbb3cbbd315b1" + "checksumValue": "7665829b9396f72e7f8098080d6d6773565468e9" }, { "algorithm": "SHA256", - "checksumValue": "455e94f24a0900deda7e6e36f4714e4253d32cea077f97e23f90c569a717bc48" + "checksumValue": "ca7357ee70365c690664a44f6522e526636151d9ed2da8d0d29da15bb8556530" } ], "fileName": "Modules/_hacl/include/krml/FStar_UInt128_Verified.h" @@ -594,11 +594,11 @@ "checksums": [ { "algorithm": "SHA1", - "checksumValue": "62b44acbbdc77b749c36c242cda027bacf7679f8" + "checksumValue": "a2db924d0e8f7df3139e9a20355ffa520aded479" }, { "algorithm": "SHA256", - "checksumValue": "65decdb74c24049aa19430462a51219250cfc65d8c162778e42df88b3142fa42" + "checksumValue": "f1de79fb4c763b215c823f44471bbae6b65e6bb533eb52a5863d551d5e2e6748" } ], "fileName": "Modules/_hacl/include/krml/FStar_UInt_8_16_32_64.h" @@ -608,11 +608,11 @@ "checksums": [ { "algorithm": "SHA1", - "checksumValue": "1987119a563a8fdc5966286e274f716dbcea77ee" + "checksumValue": "7f23693151d5409623cbe886e5b45a0e4f0d3c72" }, { "algorithm": "SHA256", - "checksumValue": "fe57e1bc5ce3224d106e36cb8829b5399c63a68a70b0ccd0c91d82a4565c8869" + "checksumValue": "1c9bee7ac4b987c73cc3aba6b7ceed8ec7e75c9a741810e4411f35602490e0d8" } ], "fileName": "Modules/_hacl/include/krml/fstar_uint128_struct_endianness.h" @@ -622,11 +622,11 @@ "checksums": [ { "algorithm": "SHA1", - "checksumValue": "81872ecdbd39b09cd813dee6e1dbed113a81aa4a" + "checksumValue": "9881567f43deb32bae77a84b2d349858a24b6685" }, { "algorithm": "SHA256", - "checksumValue": "1eef18295d412129007816fe65b7f15c0be8ad32840ef5e3dfaa5b67317e1b51" + "checksumValue": "3382156e32fcb376009177d3d2dc9712ff7c8c02afb97b3e16d98b41a2114f84" } ], "fileName": "Modules/_hacl/include/krml/internal/target.h" @@ -636,11 +636,11 @@ "checksums": [ { "algorithm": "SHA1", - "checksumValue": "964e09bd99ff2366afd6193b59863fc925e7fb05" + "checksumValue": "e18efc9239a5df0f222b5f7b0a65f72509d7e304" }, { "algorithm": "SHA256", - "checksumValue": "3734c7942bec9a434e16df069fa45bdcb84b130f14417bc5f7bfe8546272d9f5" + "checksumValue": "47dd5a7d21b5302255f9fff28884f65d3056fc3f54471ed62ec85fa1904f8aa5" } ], "fileName": "Modules/_hacl/include/krml/lowstar_endianness.h" @@ -804,11 +804,11 @@ "checksums": [ { "algorithm": "SHA1", - "checksumValue": "d5d85ee8f0bd52781fe470d0bf73ec388ddb3999" + "checksumValue": "f4a33ad535768b860362ab0bd033a70da0b524b7" }, { "algorithm": "SHA256", - "checksumValue": "9a421b998add98fe366374641c4edb27617ff539a59f0963879f345065d3d39d" + "checksumValue": "433cdf4ba80bc72e0cea5d4b420ff18676baeafdb5ba19adf5b7fb33e90b424b" } ], "fileName": "Modules/_hacl/libintvector.h" @@ -1640,14 +1640,14 @@ "checksums": [ { "algorithm": "SHA256", - "checksumValue": "988a74f5fbb59baca2d54e41447997ada92f4ebc59888dfb717438013f859117" + "checksumValue": "935ae51d0ff0bf1403f0ecc1ff02b8f685d09053618558c07fbe4bd2abbc5dd1" } ], - "downloadLocation": "https://github.com/hacl-star/hacl-star/archive/a6a09496d9cff652b567d26f2c3ab012321b632a.zip", + "downloadLocation": "https://github.com/hacl-star/hacl-star/archive/315a9e491d2bc347b9dae99e0ea506995ea84d9d.zip", "externalRefs": [ { "referenceCategory": "SECURITY", - "referenceLocator": "cpe:2.3:a:hacl-star:hacl-star:a6a09496d9cff652b567d26f2c3ab012321b632a:*:*:*:*:*:*:*", + "referenceLocator": "cpe:2.3:a:hacl-star:hacl-star:315a9e491d2bc347b9dae99e0ea506995ea84d9d:*:*:*:*:*:*:*", "referenceType": "cpe23Type" } ], @@ -1655,7 +1655,7 @@ "name": "hacl-star", "originator": "Organization: HACL* Developers", "primaryPackagePurpose": "SOURCE", - "versionInfo": "a6a09496d9cff652b567d26f2c3ab012321b632a" + "versionInfo": "315a9e491d2bc347b9dae99e0ea506995ea84d9d" }, { "SPDXID": "SPDXRef-PACKAGE-macholib", diff --git a/Modules/_hacl/Hacl_Hash_Blake2b.c b/Modules/_hacl/Hacl_Hash_Blake2b.c index e13f16fd971c56..cd3b9777e09f6c 100644 --- a/Modules/_hacl/Hacl_Hash_Blake2b.c +++ b/Modules/_hacl/Hacl_Hash_Blake2b.c @@ -575,86 +575,6 @@ void Hacl_Hash_Blake2b_init(uint64_t *hash, uint32_t kk, uint32_t nn) r1[3U] = iv7_; } -static void init_with_params(uint64_t *hash, Hacl_Hash_Blake2b_blake2_params p) -{ - uint64_t tmp[8U] = { 0U }; - uint64_t *r0 = hash; - uint64_t *r1 = hash + 4U; - uint64_t *r2 = hash + 8U; - uint64_t *r3 = hash + 12U; - uint64_t iv0 = Hacl_Hash_Blake2b_ivTable_B[0U]; - uint64_t iv1 = Hacl_Hash_Blake2b_ivTable_B[1U]; - uint64_t iv2 = Hacl_Hash_Blake2b_ivTable_B[2U]; - uint64_t iv3 = Hacl_Hash_Blake2b_ivTable_B[3U]; - uint64_t iv4 = Hacl_Hash_Blake2b_ivTable_B[4U]; - uint64_t iv5 = Hacl_Hash_Blake2b_ivTable_B[5U]; - uint64_t iv6 = Hacl_Hash_Blake2b_ivTable_B[6U]; - uint64_t iv7 = Hacl_Hash_Blake2b_ivTable_B[7U]; - r2[0U] = iv0; - r2[1U] = iv1; - r2[2U] = iv2; - r2[3U] = iv3; - r3[0U] = iv4; - r3[1U] = iv5; - r3[2U] = iv6; - r3[3U] = iv7; - uint8_t kk = p.key_length; - uint8_t nn = p.digest_length; - KRML_MAYBE_FOR2(i, - 0U, - 2U, - 1U, - uint64_t *os = tmp + 4U; - uint8_t *bj = p.salt + i * 8U; - uint64_t u = load64_le(bj); - uint64_t r = u; - uint64_t x = r; - os[i] = x;); - KRML_MAYBE_FOR2(i, - 0U, - 2U, - 1U, - uint64_t *os = tmp + 6U; - uint8_t *bj = p.personal + i * 8U; - uint64_t u = load64_le(bj); - uint64_t r = u; - uint64_t x = r; - os[i] = x;); - tmp[0U] = - (uint64_t)nn - ^ - ((uint64_t)kk - << 8U - ^ ((uint64_t)p.fanout << 16U ^ ((uint64_t)p.depth << 24U ^ (uint64_t)p.leaf_length << 32U))); - tmp[1U] = p.node_offset; - tmp[2U] = (uint64_t)p.node_depth ^ (uint64_t)p.inner_length << 8U; - tmp[3U] = 0ULL; - uint64_t tmp0 = tmp[0U]; - uint64_t tmp1 = tmp[1U]; - uint64_t tmp2 = tmp[2U]; - uint64_t tmp3 = tmp[3U]; - uint64_t tmp4 = tmp[4U]; - uint64_t tmp5 = tmp[5U]; - uint64_t tmp6 = tmp[6U]; - uint64_t tmp7 = tmp[7U]; - uint64_t iv0_ = iv0 ^ tmp0; - uint64_t iv1_ = iv1 ^ tmp1; - uint64_t iv2_ = iv2 ^ tmp2; - uint64_t iv3_ = iv3 ^ tmp3; - uint64_t iv4_ = iv4 ^ tmp4; - uint64_t iv5_ = iv5 ^ tmp5; - uint64_t iv6_ = iv6 ^ tmp6; - uint64_t iv7_ = iv7 ^ tmp7; - r0[0U] = iv0_; - r0[1U] = iv1_; - r0[2U] = iv2_; - r0[3U] = iv3_; - r1[0U] = iv4_; - r1[1U] = iv5_; - r1[2U] = iv6_; - r1[3U] = iv7_; -} - static void update_key(uint64_t *wv, uint64_t *hash, uint32_t kk, uint8_t *k, uint32_t ll) { FStar_UInt128_uint128 lb = FStar_UInt128_uint64_to_uint128((uint64_t)128U); @@ -811,16 +731,92 @@ static Hacl_Hash_Blake2b_state_t uint8_t nn = p1->digest_length; bool last_node = block_state.thd; Hacl_Hash_Blake2b_index i = { .key_length = kk1, .digest_length = nn, .last_node = last_node }; - uint32_t kk2 = (uint32_t)i.key_length; + uint64_t *h = block_state.f3.snd; + uint32_t kk20 = (uint32_t)i.key_length; uint8_t *k_1 = key.snd; - if (!(kk2 == 0U)) + if (!(kk20 == 0U)) { - uint8_t *sub_b = buf + kk2; - memset(sub_b, 0U, (128U - kk2) * sizeof (uint8_t)); - memcpy(buf, k_1, kk2 * sizeof (uint8_t)); + uint8_t *sub_b = buf + kk20; + memset(sub_b, 0U, (128U - kk20) * sizeof (uint8_t)); + memcpy(buf, k_1, kk20 * sizeof (uint8_t)); } Hacl_Hash_Blake2b_blake2_params pv = p1[0U]; - init_with_params(block_state.f3.snd, pv); + uint64_t tmp[8U] = { 0U }; + uint64_t *r0 = h; + uint64_t *r1 = h + 4U; + uint64_t *r2 = h + 8U; + uint64_t *r3 = h + 12U; + uint64_t iv0 = Hacl_Hash_Blake2b_ivTable_B[0U]; + uint64_t iv1 = Hacl_Hash_Blake2b_ivTable_B[1U]; + uint64_t iv2 = Hacl_Hash_Blake2b_ivTable_B[2U]; + uint64_t iv3 = Hacl_Hash_Blake2b_ivTable_B[3U]; + uint64_t iv4 = Hacl_Hash_Blake2b_ivTable_B[4U]; + uint64_t iv5 = Hacl_Hash_Blake2b_ivTable_B[5U]; + uint64_t iv6 = Hacl_Hash_Blake2b_ivTable_B[6U]; + uint64_t iv7 = Hacl_Hash_Blake2b_ivTable_B[7U]; + r2[0U] = iv0; + r2[1U] = iv1; + r2[2U] = iv2; + r2[3U] = iv3; + r3[0U] = iv4; + r3[1U] = iv5; + r3[2U] = iv6; + r3[3U] = iv7; + uint8_t kk2 = pv.key_length; + uint8_t nn1 = pv.digest_length; + KRML_MAYBE_FOR2(i0, + 0U, + 2U, + 1U, + uint64_t *os = tmp + 4U; + uint8_t *bj = pv.salt + i0 * 8U; + uint64_t u = load64_le(bj); + uint64_t r4 = u; + uint64_t x = r4; + os[i0] = x;); + KRML_MAYBE_FOR2(i0, + 0U, + 2U, + 1U, + uint64_t *os = tmp + 6U; + uint8_t *bj = pv.personal + i0 * 8U; + uint64_t u = load64_le(bj); + uint64_t r4 = u; + uint64_t x = r4; + os[i0] = x;); + tmp[0U] = + (uint64_t)nn1 + ^ + ((uint64_t)kk2 + << 8U + ^ ((uint64_t)pv.fanout << 16U ^ ((uint64_t)pv.depth << 24U ^ (uint64_t)pv.leaf_length << 32U))); + tmp[1U] = pv.node_offset; + tmp[2U] = (uint64_t)pv.node_depth ^ (uint64_t)pv.inner_length << 8U; + tmp[3U] = 0ULL; + uint64_t tmp0 = tmp[0U]; + uint64_t tmp1 = tmp[1U]; + uint64_t tmp2 = tmp[2U]; + uint64_t tmp3 = tmp[3U]; + uint64_t tmp4 = tmp[4U]; + uint64_t tmp5 = tmp[5U]; + uint64_t tmp6 = tmp[6U]; + uint64_t tmp7 = tmp[7U]; + uint64_t iv0_ = iv0 ^ tmp0; + uint64_t iv1_ = iv1 ^ tmp1; + uint64_t iv2_ = iv2 ^ tmp2; + uint64_t iv3_ = iv3 ^ tmp3; + uint64_t iv4_ = iv4 ^ tmp4; + uint64_t iv5_ = iv5 ^ tmp5; + uint64_t iv6_ = iv6 ^ tmp6; + uint64_t iv7_ = iv7 ^ tmp7; + r0[0U] = iv0_; + r0[1U] = iv1_; + r0[2U] = iv2_; + r0[3U] = iv3_; + r1[0U] = iv4_; + r1[1U] = iv5_; + r1[2U] = iv6_; + r1[3U] = iv7_; return p; } @@ -918,16 +914,92 @@ static void reset_raw(Hacl_Hash_Blake2b_state_t *state, Hacl_Hash_Blake2b_params bool last_node = block_state.thd; Hacl_Hash_Blake2b_index i1 = { .key_length = kk1, .digest_length = nn, .last_node = last_node }; - uint32_t kk2 = (uint32_t)i1.key_length; + uint64_t *h = block_state.f3.snd; + uint32_t kk20 = (uint32_t)i1.key_length; uint8_t *k_1 = key.snd; - if (!(kk2 == 0U)) + if (!(kk20 == 0U)) { - uint8_t *sub_b = buf + kk2; - memset(sub_b, 0U, (128U - kk2) * sizeof (uint8_t)); - memcpy(buf, k_1, kk2 * sizeof (uint8_t)); + uint8_t *sub_b = buf + kk20; + memset(sub_b, 0U, (128U - kk20) * sizeof (uint8_t)); + memcpy(buf, k_1, kk20 * sizeof (uint8_t)); } Hacl_Hash_Blake2b_blake2_params pv = p[0U]; - init_with_params(block_state.f3.snd, pv); + uint64_t tmp[8U] = { 0U }; + uint64_t *r0 = h; + uint64_t *r1 = h + 4U; + uint64_t *r2 = h + 8U; + uint64_t *r3 = h + 12U; + uint64_t iv0 = Hacl_Hash_Blake2b_ivTable_B[0U]; + uint64_t iv1 = Hacl_Hash_Blake2b_ivTable_B[1U]; + uint64_t iv2 = Hacl_Hash_Blake2b_ivTable_B[2U]; + uint64_t iv3 = Hacl_Hash_Blake2b_ivTable_B[3U]; + uint64_t iv4 = Hacl_Hash_Blake2b_ivTable_B[4U]; + uint64_t iv5 = Hacl_Hash_Blake2b_ivTable_B[5U]; + uint64_t iv6 = Hacl_Hash_Blake2b_ivTable_B[6U]; + uint64_t iv7 = Hacl_Hash_Blake2b_ivTable_B[7U]; + r2[0U] = iv0; + r2[1U] = iv1; + r2[2U] = iv2; + r2[3U] = iv3; + r3[0U] = iv4; + r3[1U] = iv5; + r3[2U] = iv6; + r3[3U] = iv7; + uint8_t kk2 = pv.key_length; + uint8_t nn1 = pv.digest_length; + KRML_MAYBE_FOR2(i0, + 0U, + 2U, + 1U, + uint64_t *os = tmp + 4U; + uint8_t *bj = pv.salt + i0 * 8U; + uint64_t u = load64_le(bj); + uint64_t r = u; + uint64_t x = r; + os[i0] = x;); + KRML_MAYBE_FOR2(i0, + 0U, + 2U, + 1U, + uint64_t *os = tmp + 6U; + uint8_t *bj = pv.personal + i0 * 8U; + uint64_t u = load64_le(bj); + uint64_t r = u; + uint64_t x = r; + os[i0] = x;); + tmp[0U] = + (uint64_t)nn1 + ^ + ((uint64_t)kk2 + << 8U + ^ ((uint64_t)pv.fanout << 16U ^ ((uint64_t)pv.depth << 24U ^ (uint64_t)pv.leaf_length << 32U))); + tmp[1U] = pv.node_offset; + tmp[2U] = (uint64_t)pv.node_depth ^ (uint64_t)pv.inner_length << 8U; + tmp[3U] = 0ULL; + uint64_t tmp0 = tmp[0U]; + uint64_t tmp1 = tmp[1U]; + uint64_t tmp2 = tmp[2U]; + uint64_t tmp3 = tmp[3U]; + uint64_t tmp4 = tmp[4U]; + uint64_t tmp5 = tmp[5U]; + uint64_t tmp6 = tmp[6U]; + uint64_t tmp7 = tmp[7U]; + uint64_t iv0_ = iv0 ^ tmp0; + uint64_t iv1_ = iv1 ^ tmp1; + uint64_t iv2_ = iv2 ^ tmp2; + uint64_t iv3_ = iv3 ^ tmp3; + uint64_t iv4_ = iv4 ^ tmp4; + uint64_t iv5_ = iv5 ^ tmp5; + uint64_t iv6_ = iv6 ^ tmp6; + uint64_t iv7_ = iv7 ^ tmp7; + r0[0U] = iv0_; + r0[1U] = iv1_; + r0[2U] = iv2_; + r0[3U] = iv3_; + r1[0U] = iv4_; + r1[1U] = iv5_; + r1[2U] = iv6_; + r1[3U] = iv7_; uint8_t kk11 = i.key_length; uint32_t ite; if (kk11 != 0U) @@ -939,8 +1011,8 @@ static void reset_raw(Hacl_Hash_Blake2b_state_t *state, Hacl_Hash_Blake2b_params ite = 0U; } Hacl_Hash_Blake2b_state_t - tmp = { .block_state = block_state, .buf = buf, .total_len = (uint64_t)ite }; - state[0U] = tmp; + tmp8 = { .block_state = block_state, .buf = buf, .total_len = (uint64_t)ite }; + state[0U] = tmp8; } /** diff --git a/Modules/_hacl/Hacl_Hash_Blake2b_Simd256.c b/Modules/_hacl/Hacl_Hash_Blake2b_Simd256.c index 35608aea71a293..92b2e8f539041b 100644 --- a/Modules/_hacl/Hacl_Hash_Blake2b_Simd256.c +++ b/Modules/_hacl/Hacl_Hash_Blake2b_Simd256.c @@ -298,75 +298,6 @@ Hacl_Hash_Blake2b_Simd256_init(Lib_IntVector_Intrinsics_vec256 *hash, uint32_t k r1[0U] = Lib_IntVector_Intrinsics_vec256_load64s(iv4_, iv5_, iv6_, iv7_); } -static void -init_with_params(Lib_IntVector_Intrinsics_vec256 *hash, Hacl_Hash_Blake2b_blake2_params p) -{ - uint64_t tmp[8U] = { 0U }; - Lib_IntVector_Intrinsics_vec256 *r0 = hash; - Lib_IntVector_Intrinsics_vec256 *r1 = hash + 1U; - Lib_IntVector_Intrinsics_vec256 *r2 = hash + 2U; - Lib_IntVector_Intrinsics_vec256 *r3 = hash + 3U; - uint64_t iv0 = Hacl_Hash_Blake2b_ivTable_B[0U]; - uint64_t iv1 = Hacl_Hash_Blake2b_ivTable_B[1U]; - uint64_t iv2 = Hacl_Hash_Blake2b_ivTable_B[2U]; - uint64_t iv3 = Hacl_Hash_Blake2b_ivTable_B[3U]; - uint64_t iv4 = Hacl_Hash_Blake2b_ivTable_B[4U]; - uint64_t iv5 = Hacl_Hash_Blake2b_ivTable_B[5U]; - uint64_t iv6 = Hacl_Hash_Blake2b_ivTable_B[6U]; - uint64_t iv7 = Hacl_Hash_Blake2b_ivTable_B[7U]; - r2[0U] = Lib_IntVector_Intrinsics_vec256_load64s(iv0, iv1, iv2, iv3); - r3[0U] = Lib_IntVector_Intrinsics_vec256_load64s(iv4, iv5, iv6, iv7); - uint8_t kk = p.key_length; - uint8_t nn = p.digest_length; - KRML_MAYBE_FOR2(i, - 0U, - 2U, - 1U, - uint64_t *os = tmp + 4U; - uint8_t *bj = p.salt + i * 8U; - uint64_t u = load64_le(bj); - uint64_t r = u; - uint64_t x = r; - os[i] = x;); - KRML_MAYBE_FOR2(i, - 0U, - 2U, - 1U, - uint64_t *os = tmp + 6U; - uint8_t *bj = p.personal + i * 8U; - uint64_t u = load64_le(bj); - uint64_t r = u; - uint64_t x = r; - os[i] = x;); - tmp[0U] = - (uint64_t)nn - ^ - ((uint64_t)kk - << 8U - ^ ((uint64_t)p.fanout << 16U ^ ((uint64_t)p.depth << 24U ^ (uint64_t)p.leaf_length << 32U))); - tmp[1U] = p.node_offset; - tmp[2U] = (uint64_t)p.node_depth ^ (uint64_t)p.inner_length << 8U; - tmp[3U] = 0ULL; - uint64_t tmp0 = tmp[0U]; - uint64_t tmp1 = tmp[1U]; - uint64_t tmp2 = tmp[2U]; - uint64_t tmp3 = tmp[3U]; - uint64_t tmp4 = tmp[4U]; - uint64_t tmp5 = tmp[5U]; - uint64_t tmp6 = tmp[6U]; - uint64_t tmp7 = tmp[7U]; - uint64_t iv0_ = iv0 ^ tmp0; - uint64_t iv1_ = iv1 ^ tmp1; - uint64_t iv2_ = iv2 ^ tmp2; - uint64_t iv3_ = iv3 ^ tmp3; - uint64_t iv4_ = iv4 ^ tmp4; - uint64_t iv5_ = iv5 ^ tmp5; - uint64_t iv6_ = iv6 ^ tmp6; - uint64_t iv7_ = iv7 ^ tmp7; - r0[0U] = Lib_IntVector_Intrinsics_vec256_load64s(iv0_, iv1_, iv2_, iv3_); - r1[0U] = Lib_IntVector_Intrinsics_vec256_load64s(iv4_, iv5_, iv6_, iv7_); -} - static void update_key( Lib_IntVector_Intrinsics_vec256 *wv, @@ -647,16 +578,80 @@ static Hacl_Hash_Blake2b_Simd256_state_t uint8_t nn = p1->digest_length; bool last_node = block_state.thd; Hacl_Hash_Blake2b_index i = { .key_length = kk1, .digest_length = nn, .last_node = last_node }; - uint32_t kk2 = (uint32_t)i.key_length; + Lib_IntVector_Intrinsics_vec256 *h = block_state.f3.snd; + uint32_t kk20 = (uint32_t)i.key_length; uint8_t *k_1 = key.snd; - if (!(kk2 == 0U)) + if (!(kk20 == 0U)) { - uint8_t *sub_b = buf + kk2; - memset(sub_b, 0U, (128U - kk2) * sizeof (uint8_t)); - memcpy(buf, k_1, kk2 * sizeof (uint8_t)); + uint8_t *sub_b = buf + kk20; + memset(sub_b, 0U, (128U - kk20) * sizeof (uint8_t)); + memcpy(buf, k_1, kk20 * sizeof (uint8_t)); } Hacl_Hash_Blake2b_blake2_params pv = p1[0U]; - init_with_params(block_state.f3.snd, pv); + uint64_t tmp[8U] = { 0U }; + Lib_IntVector_Intrinsics_vec256 *r0 = h; + Lib_IntVector_Intrinsics_vec256 *r1 = h + 1U; + Lib_IntVector_Intrinsics_vec256 *r2 = h + 2U; + Lib_IntVector_Intrinsics_vec256 *r3 = h + 3U; + uint64_t iv0 = Hacl_Hash_Blake2b_ivTable_B[0U]; + uint64_t iv1 = Hacl_Hash_Blake2b_ivTable_B[1U]; + uint64_t iv2 = Hacl_Hash_Blake2b_ivTable_B[2U]; + uint64_t iv3 = Hacl_Hash_Blake2b_ivTable_B[3U]; + uint64_t iv4 = Hacl_Hash_Blake2b_ivTable_B[4U]; + uint64_t iv5 = Hacl_Hash_Blake2b_ivTable_B[5U]; + uint64_t iv6 = Hacl_Hash_Blake2b_ivTable_B[6U]; + uint64_t iv7 = Hacl_Hash_Blake2b_ivTable_B[7U]; + r2[0U] = Lib_IntVector_Intrinsics_vec256_load64s(iv0, iv1, iv2, iv3); + r3[0U] = Lib_IntVector_Intrinsics_vec256_load64s(iv4, iv5, iv6, iv7); + uint8_t kk2 = pv.key_length; + uint8_t nn1 = pv.digest_length; + KRML_MAYBE_FOR2(i0, + 0U, + 2U, + 1U, + uint64_t *os = tmp + 4U; + uint8_t *bj = pv.salt + i0 * 8U; + uint64_t u = load64_le(bj); + uint64_t r4 = u; + uint64_t x = r4; + os[i0] = x;); + KRML_MAYBE_FOR2(i0, + 0U, + 2U, + 1U, + uint64_t *os = tmp + 6U; + uint8_t *bj = pv.personal + i0 * 8U; + uint64_t u = load64_le(bj); + uint64_t r4 = u; + uint64_t x = r4; + os[i0] = x;); + tmp[0U] = + (uint64_t)nn1 + ^ + ((uint64_t)kk2 + << 8U + ^ ((uint64_t)pv.fanout << 16U ^ ((uint64_t)pv.depth << 24U ^ (uint64_t)pv.leaf_length << 32U))); + tmp[1U] = pv.node_offset; + tmp[2U] = (uint64_t)pv.node_depth ^ (uint64_t)pv.inner_length << 8U; + tmp[3U] = 0ULL; + uint64_t tmp0 = tmp[0U]; + uint64_t tmp1 = tmp[1U]; + uint64_t tmp2 = tmp[2U]; + uint64_t tmp3 = tmp[3U]; + uint64_t tmp4 = tmp[4U]; + uint64_t tmp5 = tmp[5U]; + uint64_t tmp6 = tmp[6U]; + uint64_t tmp7 = tmp[7U]; + uint64_t iv0_ = iv0 ^ tmp0; + uint64_t iv1_ = iv1 ^ tmp1; + uint64_t iv2_ = iv2 ^ tmp2; + uint64_t iv3_ = iv3 ^ tmp3; + uint64_t iv4_ = iv4 ^ tmp4; + uint64_t iv5_ = iv5 ^ tmp5; + uint64_t iv6_ = iv6 ^ tmp6; + uint64_t iv7_ = iv7 ^ tmp7; + r0[0U] = Lib_IntVector_Intrinsics_vec256_load64s(iv0_, iv1_, iv2_, iv3_); + r1[0U] = Lib_IntVector_Intrinsics_vec256_load64s(iv4_, iv5_, iv6_, iv7_); return p; } @@ -757,16 +752,80 @@ reset_raw(Hacl_Hash_Blake2b_Simd256_state_t *state, Hacl_Hash_Blake2b_params_and bool last_node = block_state.thd; Hacl_Hash_Blake2b_index i1 = { .key_length = kk1, .digest_length = nn, .last_node = last_node }; - uint32_t kk2 = (uint32_t)i1.key_length; + Lib_IntVector_Intrinsics_vec256 *h = block_state.f3.snd; + uint32_t kk20 = (uint32_t)i1.key_length; uint8_t *k_1 = key.snd; - if (!(kk2 == 0U)) + if (!(kk20 == 0U)) { - uint8_t *sub_b = buf + kk2; - memset(sub_b, 0U, (128U - kk2) * sizeof (uint8_t)); - memcpy(buf, k_1, kk2 * sizeof (uint8_t)); + uint8_t *sub_b = buf + kk20; + memset(sub_b, 0U, (128U - kk20) * sizeof (uint8_t)); + memcpy(buf, k_1, kk20 * sizeof (uint8_t)); } Hacl_Hash_Blake2b_blake2_params pv = p[0U]; - init_with_params(block_state.f3.snd, pv); + uint64_t tmp[8U] = { 0U }; + Lib_IntVector_Intrinsics_vec256 *r0 = h; + Lib_IntVector_Intrinsics_vec256 *r1 = h + 1U; + Lib_IntVector_Intrinsics_vec256 *r2 = h + 2U; + Lib_IntVector_Intrinsics_vec256 *r3 = h + 3U; + uint64_t iv0 = Hacl_Hash_Blake2b_ivTable_B[0U]; + uint64_t iv1 = Hacl_Hash_Blake2b_ivTable_B[1U]; + uint64_t iv2 = Hacl_Hash_Blake2b_ivTable_B[2U]; + uint64_t iv3 = Hacl_Hash_Blake2b_ivTable_B[3U]; + uint64_t iv4 = Hacl_Hash_Blake2b_ivTable_B[4U]; + uint64_t iv5 = Hacl_Hash_Blake2b_ivTable_B[5U]; + uint64_t iv6 = Hacl_Hash_Blake2b_ivTable_B[6U]; + uint64_t iv7 = Hacl_Hash_Blake2b_ivTable_B[7U]; + r2[0U] = Lib_IntVector_Intrinsics_vec256_load64s(iv0, iv1, iv2, iv3); + r3[0U] = Lib_IntVector_Intrinsics_vec256_load64s(iv4, iv5, iv6, iv7); + uint8_t kk2 = pv.key_length; + uint8_t nn1 = pv.digest_length; + KRML_MAYBE_FOR2(i0, + 0U, + 2U, + 1U, + uint64_t *os = tmp + 4U; + uint8_t *bj = pv.salt + i0 * 8U; + uint64_t u = load64_le(bj); + uint64_t r = u; + uint64_t x = r; + os[i0] = x;); + KRML_MAYBE_FOR2(i0, + 0U, + 2U, + 1U, + uint64_t *os = tmp + 6U; + uint8_t *bj = pv.personal + i0 * 8U; + uint64_t u = load64_le(bj); + uint64_t r = u; + uint64_t x = r; + os[i0] = x;); + tmp[0U] = + (uint64_t)nn1 + ^ + ((uint64_t)kk2 + << 8U + ^ ((uint64_t)pv.fanout << 16U ^ ((uint64_t)pv.depth << 24U ^ (uint64_t)pv.leaf_length << 32U))); + tmp[1U] = pv.node_offset; + tmp[2U] = (uint64_t)pv.node_depth ^ (uint64_t)pv.inner_length << 8U; + tmp[3U] = 0ULL; + uint64_t tmp0 = tmp[0U]; + uint64_t tmp1 = tmp[1U]; + uint64_t tmp2 = tmp[2U]; + uint64_t tmp3 = tmp[3U]; + uint64_t tmp4 = tmp[4U]; + uint64_t tmp5 = tmp[5U]; + uint64_t tmp6 = tmp[6U]; + uint64_t tmp7 = tmp[7U]; + uint64_t iv0_ = iv0 ^ tmp0; + uint64_t iv1_ = iv1 ^ tmp1; + uint64_t iv2_ = iv2 ^ tmp2; + uint64_t iv3_ = iv3 ^ tmp3; + uint64_t iv4_ = iv4 ^ tmp4; + uint64_t iv5_ = iv5 ^ tmp5; + uint64_t iv6_ = iv6 ^ tmp6; + uint64_t iv7_ = iv7 ^ tmp7; + r0[0U] = Lib_IntVector_Intrinsics_vec256_load64s(iv0_, iv1_, iv2_, iv3_); + r1[0U] = Lib_IntVector_Intrinsics_vec256_load64s(iv4_, iv5_, iv6_, iv7_); uint8_t kk11 = i.key_length; uint32_t ite; if (kk11 != 0U) @@ -778,8 +837,8 @@ reset_raw(Hacl_Hash_Blake2b_Simd256_state_t *state, Hacl_Hash_Blake2b_params_and ite = 0U; } Hacl_Hash_Blake2b_Simd256_state_t - tmp = { .block_state = block_state, .buf = buf, .total_len = (uint64_t)ite }; - state[0U] = tmp; + tmp8 = { .block_state = block_state, .buf = buf, .total_len = (uint64_t)ite }; + state[0U] = tmp8; } /** diff --git a/Modules/_hacl/Hacl_Hash_Blake2s.c b/Modules/_hacl/Hacl_Hash_Blake2s.c index 167f38fbd1c603..e5e0ecd0bfde7e 100644 --- a/Modules/_hacl/Hacl_Hash_Blake2s.c +++ b/Modules/_hacl/Hacl_Hash_Blake2s.c @@ -573,83 +573,6 @@ void Hacl_Hash_Blake2s_init(uint32_t *hash, uint32_t kk, uint32_t nn) r1[3U] = iv7_; } -static void init_with_params(uint32_t *hash, Hacl_Hash_Blake2b_blake2_params p) -{ - uint32_t tmp[8U] = { 0U }; - uint32_t *r0 = hash; - uint32_t *r1 = hash + 4U; - uint32_t *r2 = hash + 8U; - uint32_t *r3 = hash + 12U; - uint32_t iv0 = Hacl_Hash_Blake2b_ivTable_S[0U]; - uint32_t iv1 = Hacl_Hash_Blake2b_ivTable_S[1U]; - uint32_t iv2 = Hacl_Hash_Blake2b_ivTable_S[2U]; - uint32_t iv3 = Hacl_Hash_Blake2b_ivTable_S[3U]; - uint32_t iv4 = Hacl_Hash_Blake2b_ivTable_S[4U]; - uint32_t iv5 = Hacl_Hash_Blake2b_ivTable_S[5U]; - uint32_t iv6 = Hacl_Hash_Blake2b_ivTable_S[6U]; - uint32_t iv7 = Hacl_Hash_Blake2b_ivTable_S[7U]; - r2[0U] = iv0; - r2[1U] = iv1; - r2[2U] = iv2; - r2[3U] = iv3; - r3[0U] = iv4; - r3[1U] = iv5; - r3[2U] = iv6; - r3[3U] = iv7; - KRML_MAYBE_FOR2(i, - 0U, - 2U, - 1U, - uint32_t *os = tmp + 4U; - uint8_t *bj = p.salt + i * 4U; - uint32_t u = load32_le(bj); - uint32_t r = u; - uint32_t x = r; - os[i] = x;); - KRML_MAYBE_FOR2(i, - 0U, - 2U, - 1U, - uint32_t *os = tmp + 6U; - uint8_t *bj = p.personal + i * 4U; - uint32_t u = load32_le(bj); - uint32_t r = u; - uint32_t x = r; - os[i] = x;); - tmp[0U] = - (uint32_t)p.digest_length - ^ ((uint32_t)p.key_length << 8U ^ ((uint32_t)p.fanout << 16U ^ (uint32_t)p.depth << 24U)); - tmp[1U] = p.leaf_length; - tmp[2U] = (uint32_t)p.node_offset; - tmp[3U] = - (uint32_t)(p.node_offset >> 32U) - ^ ((uint32_t)p.node_depth << 16U ^ (uint32_t)p.inner_length << 24U); - uint32_t tmp0 = tmp[0U]; - uint32_t tmp1 = tmp[1U]; - uint32_t tmp2 = tmp[2U]; - uint32_t tmp3 = tmp[3U]; - uint32_t tmp4 = tmp[4U]; - uint32_t tmp5 = tmp[5U]; - uint32_t tmp6 = tmp[6U]; - uint32_t tmp7 = tmp[7U]; - uint32_t iv0_ = iv0 ^ tmp0; - uint32_t iv1_ = iv1 ^ tmp1; - uint32_t iv2_ = iv2 ^ tmp2; - uint32_t iv3_ = iv3 ^ tmp3; - uint32_t iv4_ = iv4 ^ tmp4; - uint32_t iv5_ = iv5 ^ tmp5; - uint32_t iv6_ = iv6 ^ tmp6; - uint32_t iv7_ = iv7 ^ tmp7; - r0[0U] = iv0_; - r0[1U] = iv1_; - r0[2U] = iv2_; - r0[3U] = iv3_; - r1[0U] = iv4_; - r1[1U] = iv5_; - r1[2U] = iv6_; - r1[3U] = iv7_; -} - static void update_key(uint32_t *wv, uint32_t *hash, uint32_t kk, uint8_t *k, uint32_t ll) { uint64_t lb = (uint64_t)64U; @@ -796,6 +719,7 @@ static Hacl_Hash_Blake2s_state_t uint8_t nn = p1->digest_length; bool last_node = block_state.thd; Hacl_Hash_Blake2b_index i = { .key_length = kk1, .digest_length = nn, .last_node = last_node }; + uint32_t *h = block_state.f3.snd; uint32_t kk2 = (uint32_t)i.key_length; uint8_t *k_1 = key.snd; if (!(kk2 == 0U)) @@ -805,7 +729,79 @@ static Hacl_Hash_Blake2s_state_t memcpy(buf, k_1, kk2 * sizeof (uint8_t)); } Hacl_Hash_Blake2b_blake2_params pv = p1[0U]; - init_with_params(block_state.f3.snd, pv); + uint32_t tmp[8U] = { 0U }; + uint32_t *r0 = h; + uint32_t *r1 = h + 4U; + uint32_t *r2 = h + 8U; + uint32_t *r3 = h + 12U; + uint32_t iv0 = Hacl_Hash_Blake2b_ivTable_S[0U]; + uint32_t iv1 = Hacl_Hash_Blake2b_ivTable_S[1U]; + uint32_t iv2 = Hacl_Hash_Blake2b_ivTable_S[2U]; + uint32_t iv3 = Hacl_Hash_Blake2b_ivTable_S[3U]; + uint32_t iv4 = Hacl_Hash_Blake2b_ivTable_S[4U]; + uint32_t iv5 = Hacl_Hash_Blake2b_ivTable_S[5U]; + uint32_t iv6 = Hacl_Hash_Blake2b_ivTable_S[6U]; + uint32_t iv7 = Hacl_Hash_Blake2b_ivTable_S[7U]; + r2[0U] = iv0; + r2[1U] = iv1; + r2[2U] = iv2; + r2[3U] = iv3; + r3[0U] = iv4; + r3[1U] = iv5; + r3[2U] = iv6; + r3[3U] = iv7; + KRML_MAYBE_FOR2(i0, + 0U, + 2U, + 1U, + uint32_t *os = tmp + 4U; + uint8_t *bj = pv.salt + i0 * 4U; + uint32_t u = load32_le(bj); + uint32_t r4 = u; + uint32_t x = r4; + os[i0] = x;); + KRML_MAYBE_FOR2(i0, + 0U, + 2U, + 1U, + uint32_t *os = tmp + 6U; + uint8_t *bj = pv.personal + i0 * 4U; + uint32_t u = load32_le(bj); + uint32_t r4 = u; + uint32_t x = r4; + os[i0] = x;); + tmp[0U] = + (uint32_t)pv.digest_length + ^ ((uint32_t)pv.key_length << 8U ^ ((uint32_t)pv.fanout << 16U ^ (uint32_t)pv.depth << 24U)); + tmp[1U] = pv.leaf_length; + tmp[2U] = (uint32_t)pv.node_offset; + tmp[3U] = + (uint32_t)(pv.node_offset >> 32U) + ^ ((uint32_t)pv.node_depth << 16U ^ (uint32_t)pv.inner_length << 24U); + uint32_t tmp0 = tmp[0U]; + uint32_t tmp1 = tmp[1U]; + uint32_t tmp2 = tmp[2U]; + uint32_t tmp3 = tmp[3U]; + uint32_t tmp4 = tmp[4U]; + uint32_t tmp5 = tmp[5U]; + uint32_t tmp6 = tmp[6U]; + uint32_t tmp7 = tmp[7U]; + uint32_t iv0_ = iv0 ^ tmp0; + uint32_t iv1_ = iv1 ^ tmp1; + uint32_t iv2_ = iv2 ^ tmp2; + uint32_t iv3_ = iv3 ^ tmp3; + uint32_t iv4_ = iv4 ^ tmp4; + uint32_t iv5_ = iv5 ^ tmp5; + uint32_t iv6_ = iv6 ^ tmp6; + uint32_t iv7_ = iv7 ^ tmp7; + r0[0U] = iv0_; + r0[1U] = iv1_; + r0[2U] = iv2_; + r0[3U] = iv3_; + r1[0U] = iv4_; + r1[1U] = iv5_; + r1[2U] = iv6_; + r1[3U] = iv7_; return p; } @@ -903,6 +899,7 @@ static void reset_raw(Hacl_Hash_Blake2s_state_t *state, Hacl_Hash_Blake2b_params bool last_node = block_state.thd; Hacl_Hash_Blake2b_index i1 = { .key_length = kk1, .digest_length = nn, .last_node = last_node }; + uint32_t *h = block_state.f3.snd; uint32_t kk2 = (uint32_t)i1.key_length; uint8_t *k_1 = key.snd; if (!(kk2 == 0U)) @@ -912,7 +909,79 @@ static void reset_raw(Hacl_Hash_Blake2s_state_t *state, Hacl_Hash_Blake2b_params memcpy(buf, k_1, kk2 * sizeof (uint8_t)); } Hacl_Hash_Blake2b_blake2_params pv = p[0U]; - init_with_params(block_state.f3.snd, pv); + uint32_t tmp[8U] = { 0U }; + uint32_t *r0 = h; + uint32_t *r1 = h + 4U; + uint32_t *r2 = h + 8U; + uint32_t *r3 = h + 12U; + uint32_t iv0 = Hacl_Hash_Blake2b_ivTable_S[0U]; + uint32_t iv1 = Hacl_Hash_Blake2b_ivTable_S[1U]; + uint32_t iv2 = Hacl_Hash_Blake2b_ivTable_S[2U]; + uint32_t iv3 = Hacl_Hash_Blake2b_ivTable_S[3U]; + uint32_t iv4 = Hacl_Hash_Blake2b_ivTable_S[4U]; + uint32_t iv5 = Hacl_Hash_Blake2b_ivTable_S[5U]; + uint32_t iv6 = Hacl_Hash_Blake2b_ivTable_S[6U]; + uint32_t iv7 = Hacl_Hash_Blake2b_ivTable_S[7U]; + r2[0U] = iv0; + r2[1U] = iv1; + r2[2U] = iv2; + r2[3U] = iv3; + r3[0U] = iv4; + r3[1U] = iv5; + r3[2U] = iv6; + r3[3U] = iv7; + KRML_MAYBE_FOR2(i0, + 0U, + 2U, + 1U, + uint32_t *os = tmp + 4U; + uint8_t *bj = pv.salt + i0 * 4U; + uint32_t u = load32_le(bj); + uint32_t r = u; + uint32_t x = r; + os[i0] = x;); + KRML_MAYBE_FOR2(i0, + 0U, + 2U, + 1U, + uint32_t *os = tmp + 6U; + uint8_t *bj = pv.personal + i0 * 4U; + uint32_t u = load32_le(bj); + uint32_t r = u; + uint32_t x = r; + os[i0] = x;); + tmp[0U] = + (uint32_t)pv.digest_length + ^ ((uint32_t)pv.key_length << 8U ^ ((uint32_t)pv.fanout << 16U ^ (uint32_t)pv.depth << 24U)); + tmp[1U] = pv.leaf_length; + tmp[2U] = (uint32_t)pv.node_offset; + tmp[3U] = + (uint32_t)(pv.node_offset >> 32U) + ^ ((uint32_t)pv.node_depth << 16U ^ (uint32_t)pv.inner_length << 24U); + uint32_t tmp0 = tmp[0U]; + uint32_t tmp1 = tmp[1U]; + uint32_t tmp2 = tmp[2U]; + uint32_t tmp3 = tmp[3U]; + uint32_t tmp4 = tmp[4U]; + uint32_t tmp5 = tmp[5U]; + uint32_t tmp6 = tmp[6U]; + uint32_t tmp7 = tmp[7U]; + uint32_t iv0_ = iv0 ^ tmp0; + uint32_t iv1_ = iv1 ^ tmp1; + uint32_t iv2_ = iv2 ^ tmp2; + uint32_t iv3_ = iv3 ^ tmp3; + uint32_t iv4_ = iv4 ^ tmp4; + uint32_t iv5_ = iv5 ^ tmp5; + uint32_t iv6_ = iv6 ^ tmp6; + uint32_t iv7_ = iv7 ^ tmp7; + r0[0U] = iv0_; + r0[1U] = iv1_; + r0[2U] = iv2_; + r0[3U] = iv3_; + r1[0U] = iv4_; + r1[1U] = iv5_; + r1[2U] = iv6_; + r1[3U] = iv7_; uint8_t kk11 = i.key_length; uint32_t ite; if (kk11 != 0U) @@ -924,8 +993,8 @@ static void reset_raw(Hacl_Hash_Blake2s_state_t *state, Hacl_Hash_Blake2b_params ite = 0U; } Hacl_Hash_Blake2s_state_t - tmp = { .block_state = block_state, .buf = buf, .total_len = (uint64_t)ite }; - state[0U] = tmp; + tmp8 = { .block_state = block_state, .buf = buf, .total_len = (uint64_t)ite }; + state[0U] = tmp8; } /** diff --git a/Modules/_hacl/Hacl_Hash_Blake2s_Simd128.c b/Modules/_hacl/Hacl_Hash_Blake2s_Simd128.c index a85b18a4d296ec..f675a7f14f192f 100644 --- a/Modules/_hacl/Hacl_Hash_Blake2s_Simd128.c +++ b/Modules/_hacl/Hacl_Hash_Blake2s_Simd128.c @@ -295,72 +295,6 @@ Hacl_Hash_Blake2s_Simd128_init(Lib_IntVector_Intrinsics_vec128 *hash, uint32_t k r1[0U] = Lib_IntVector_Intrinsics_vec128_load32s(iv4_, iv5_, iv6_, iv7_); } -static void -init_with_params(Lib_IntVector_Intrinsics_vec128 *hash, Hacl_Hash_Blake2b_blake2_params p) -{ - uint32_t tmp[8U] = { 0U }; - Lib_IntVector_Intrinsics_vec128 *r0 = hash; - Lib_IntVector_Intrinsics_vec128 *r1 = hash + 1U; - Lib_IntVector_Intrinsics_vec128 *r2 = hash + 2U; - Lib_IntVector_Intrinsics_vec128 *r3 = hash + 3U; - uint32_t iv0 = Hacl_Hash_Blake2b_ivTable_S[0U]; - uint32_t iv1 = Hacl_Hash_Blake2b_ivTable_S[1U]; - uint32_t iv2 = Hacl_Hash_Blake2b_ivTable_S[2U]; - uint32_t iv3 = Hacl_Hash_Blake2b_ivTable_S[3U]; - uint32_t iv4 = Hacl_Hash_Blake2b_ivTable_S[4U]; - uint32_t iv5 = Hacl_Hash_Blake2b_ivTable_S[5U]; - uint32_t iv6 = Hacl_Hash_Blake2b_ivTable_S[6U]; - uint32_t iv7 = Hacl_Hash_Blake2b_ivTable_S[7U]; - r2[0U] = Lib_IntVector_Intrinsics_vec128_load32s(iv0, iv1, iv2, iv3); - r3[0U] = Lib_IntVector_Intrinsics_vec128_load32s(iv4, iv5, iv6, iv7); - KRML_MAYBE_FOR2(i, - 0U, - 2U, - 1U, - uint32_t *os = tmp + 4U; - uint8_t *bj = p.salt + i * 4U; - uint32_t u = load32_le(bj); - uint32_t r = u; - uint32_t x = r; - os[i] = x;); - KRML_MAYBE_FOR2(i, - 0U, - 2U, - 1U, - uint32_t *os = tmp + 6U; - uint8_t *bj = p.personal + i * 4U; - uint32_t u = load32_le(bj); - uint32_t r = u; - uint32_t x = r; - os[i] = x;); - tmp[0U] = - (uint32_t)p.digest_length - ^ ((uint32_t)p.key_length << 8U ^ ((uint32_t)p.fanout << 16U ^ (uint32_t)p.depth << 24U)); - tmp[1U] = p.leaf_length; - tmp[2U] = (uint32_t)p.node_offset; - tmp[3U] = - (uint32_t)(p.node_offset >> 32U) - ^ ((uint32_t)p.node_depth << 16U ^ (uint32_t)p.inner_length << 24U); - uint32_t tmp0 = tmp[0U]; - uint32_t tmp1 = tmp[1U]; - uint32_t tmp2 = tmp[2U]; - uint32_t tmp3 = tmp[3U]; - uint32_t tmp4 = tmp[4U]; - uint32_t tmp5 = tmp[5U]; - uint32_t tmp6 = tmp[6U]; - uint32_t tmp7 = tmp[7U]; - uint32_t iv0_ = iv0 ^ tmp0; - uint32_t iv1_ = iv1 ^ tmp1; - uint32_t iv2_ = iv2 ^ tmp2; - uint32_t iv3_ = iv3 ^ tmp3; - uint32_t iv4_ = iv4 ^ tmp4; - uint32_t iv5_ = iv5 ^ tmp5; - uint32_t iv6_ = iv6 ^ tmp6; - uint32_t iv7_ = iv7 ^ tmp7; - r0[0U] = Lib_IntVector_Intrinsics_vec128_load32s(iv0_, iv1_, iv2_, iv3_); - r1[0U] = Lib_IntVector_Intrinsics_vec128_load32s(iv4_, iv5_, iv6_, iv7_); -} - static void update_key( Lib_IntVector_Intrinsics_vec128 *wv, @@ -637,6 +571,7 @@ static Hacl_Hash_Blake2s_Simd128_state_t uint8_t nn = p1->digest_length; bool last_node = block_state.thd; Hacl_Hash_Blake2b_index i = { .key_length = kk1, .digest_length = nn, .last_node = last_node }; + Lib_IntVector_Intrinsics_vec128 *h = block_state.f3.snd; uint32_t kk2 = (uint32_t)i.key_length; uint8_t *k_1 = key.snd; if (!(kk2 == 0U)) @@ -646,7 +581,67 @@ static Hacl_Hash_Blake2s_Simd128_state_t memcpy(buf, k_1, kk2 * sizeof (uint8_t)); } Hacl_Hash_Blake2b_blake2_params pv = p1[0U]; - init_with_params(block_state.f3.snd, pv); + uint32_t tmp[8U] = { 0U }; + Lib_IntVector_Intrinsics_vec128 *r0 = h; + Lib_IntVector_Intrinsics_vec128 *r1 = h + 1U; + Lib_IntVector_Intrinsics_vec128 *r2 = h + 2U; + Lib_IntVector_Intrinsics_vec128 *r3 = h + 3U; + uint32_t iv0 = Hacl_Hash_Blake2b_ivTable_S[0U]; + uint32_t iv1 = Hacl_Hash_Blake2b_ivTable_S[1U]; + uint32_t iv2 = Hacl_Hash_Blake2b_ivTable_S[2U]; + uint32_t iv3 = Hacl_Hash_Blake2b_ivTable_S[3U]; + uint32_t iv4 = Hacl_Hash_Blake2b_ivTable_S[4U]; + uint32_t iv5 = Hacl_Hash_Blake2b_ivTable_S[5U]; + uint32_t iv6 = Hacl_Hash_Blake2b_ivTable_S[6U]; + uint32_t iv7 = Hacl_Hash_Blake2b_ivTable_S[7U]; + r2[0U] = Lib_IntVector_Intrinsics_vec128_load32s(iv0, iv1, iv2, iv3); + r3[0U] = Lib_IntVector_Intrinsics_vec128_load32s(iv4, iv5, iv6, iv7); + KRML_MAYBE_FOR2(i0, + 0U, + 2U, + 1U, + uint32_t *os = tmp + 4U; + uint8_t *bj = pv.salt + i0 * 4U; + uint32_t u = load32_le(bj); + uint32_t r4 = u; + uint32_t x = r4; + os[i0] = x;); + KRML_MAYBE_FOR2(i0, + 0U, + 2U, + 1U, + uint32_t *os = tmp + 6U; + uint8_t *bj = pv.personal + i0 * 4U; + uint32_t u = load32_le(bj); + uint32_t r4 = u; + uint32_t x = r4; + os[i0] = x;); + tmp[0U] = + (uint32_t)pv.digest_length + ^ ((uint32_t)pv.key_length << 8U ^ ((uint32_t)pv.fanout << 16U ^ (uint32_t)pv.depth << 24U)); + tmp[1U] = pv.leaf_length; + tmp[2U] = (uint32_t)pv.node_offset; + tmp[3U] = + (uint32_t)(pv.node_offset >> 32U) + ^ ((uint32_t)pv.node_depth << 16U ^ (uint32_t)pv.inner_length << 24U); + uint32_t tmp0 = tmp[0U]; + uint32_t tmp1 = tmp[1U]; + uint32_t tmp2 = tmp[2U]; + uint32_t tmp3 = tmp[3U]; + uint32_t tmp4 = tmp[4U]; + uint32_t tmp5 = tmp[5U]; + uint32_t tmp6 = tmp[6U]; + uint32_t tmp7 = tmp[7U]; + uint32_t iv0_ = iv0 ^ tmp0; + uint32_t iv1_ = iv1 ^ tmp1; + uint32_t iv2_ = iv2 ^ tmp2; + uint32_t iv3_ = iv3 ^ tmp3; + uint32_t iv4_ = iv4 ^ tmp4; + uint32_t iv5_ = iv5 ^ tmp5; + uint32_t iv6_ = iv6 ^ tmp6; + uint32_t iv7_ = iv7 ^ tmp7; + r0[0U] = Lib_IntVector_Intrinsics_vec128_load32s(iv0_, iv1_, iv2_, iv3_); + r1[0U] = Lib_IntVector_Intrinsics_vec128_load32s(iv4_, iv5_, iv6_, iv7_); return p; } @@ -747,6 +742,7 @@ reset_raw(Hacl_Hash_Blake2s_Simd128_state_t *state, Hacl_Hash_Blake2b_params_and bool last_node = block_state.thd; Hacl_Hash_Blake2b_index i1 = { .key_length = kk1, .digest_length = nn, .last_node = last_node }; + Lib_IntVector_Intrinsics_vec128 *h = block_state.f3.snd; uint32_t kk2 = (uint32_t)i1.key_length; uint8_t *k_1 = key.snd; if (!(kk2 == 0U)) @@ -756,7 +752,67 @@ reset_raw(Hacl_Hash_Blake2s_Simd128_state_t *state, Hacl_Hash_Blake2b_params_and memcpy(buf, k_1, kk2 * sizeof (uint8_t)); } Hacl_Hash_Blake2b_blake2_params pv = p[0U]; - init_with_params(block_state.f3.snd, pv); + uint32_t tmp[8U] = { 0U }; + Lib_IntVector_Intrinsics_vec128 *r0 = h; + Lib_IntVector_Intrinsics_vec128 *r1 = h + 1U; + Lib_IntVector_Intrinsics_vec128 *r2 = h + 2U; + Lib_IntVector_Intrinsics_vec128 *r3 = h + 3U; + uint32_t iv0 = Hacl_Hash_Blake2b_ivTable_S[0U]; + uint32_t iv1 = Hacl_Hash_Blake2b_ivTable_S[1U]; + uint32_t iv2 = Hacl_Hash_Blake2b_ivTable_S[2U]; + uint32_t iv3 = Hacl_Hash_Blake2b_ivTable_S[3U]; + uint32_t iv4 = Hacl_Hash_Blake2b_ivTable_S[4U]; + uint32_t iv5 = Hacl_Hash_Blake2b_ivTable_S[5U]; + uint32_t iv6 = Hacl_Hash_Blake2b_ivTable_S[6U]; + uint32_t iv7 = Hacl_Hash_Blake2b_ivTable_S[7U]; + r2[0U] = Lib_IntVector_Intrinsics_vec128_load32s(iv0, iv1, iv2, iv3); + r3[0U] = Lib_IntVector_Intrinsics_vec128_load32s(iv4, iv5, iv6, iv7); + KRML_MAYBE_FOR2(i0, + 0U, + 2U, + 1U, + uint32_t *os = tmp + 4U; + uint8_t *bj = pv.salt + i0 * 4U; + uint32_t u = load32_le(bj); + uint32_t r = u; + uint32_t x = r; + os[i0] = x;); + KRML_MAYBE_FOR2(i0, + 0U, + 2U, + 1U, + uint32_t *os = tmp + 6U; + uint8_t *bj = pv.personal + i0 * 4U; + uint32_t u = load32_le(bj); + uint32_t r = u; + uint32_t x = r; + os[i0] = x;); + tmp[0U] = + (uint32_t)pv.digest_length + ^ ((uint32_t)pv.key_length << 8U ^ ((uint32_t)pv.fanout << 16U ^ (uint32_t)pv.depth << 24U)); + tmp[1U] = pv.leaf_length; + tmp[2U] = (uint32_t)pv.node_offset; + tmp[3U] = + (uint32_t)(pv.node_offset >> 32U) + ^ ((uint32_t)pv.node_depth << 16U ^ (uint32_t)pv.inner_length << 24U); + uint32_t tmp0 = tmp[0U]; + uint32_t tmp1 = tmp[1U]; + uint32_t tmp2 = tmp[2U]; + uint32_t tmp3 = tmp[3U]; + uint32_t tmp4 = tmp[4U]; + uint32_t tmp5 = tmp[5U]; + uint32_t tmp6 = tmp[6U]; + uint32_t tmp7 = tmp[7U]; + uint32_t iv0_ = iv0 ^ tmp0; + uint32_t iv1_ = iv1 ^ tmp1; + uint32_t iv2_ = iv2 ^ tmp2; + uint32_t iv3_ = iv3 ^ tmp3; + uint32_t iv4_ = iv4 ^ tmp4; + uint32_t iv5_ = iv5 ^ tmp5; + uint32_t iv6_ = iv6 ^ tmp6; + uint32_t iv7_ = iv7 ^ tmp7; + r0[0U] = Lib_IntVector_Intrinsics_vec128_load32s(iv0_, iv1_, iv2_, iv3_); + r1[0U] = Lib_IntVector_Intrinsics_vec128_load32s(iv4_, iv5_, iv6_, iv7_); uint8_t kk11 = i.key_length; uint32_t ite; if (kk11 != 0U) @@ -768,8 +824,8 @@ reset_raw(Hacl_Hash_Blake2s_Simd128_state_t *state, Hacl_Hash_Blake2b_params_and ite = 0U; } Hacl_Hash_Blake2s_Simd128_state_t - tmp = { .block_state = block_state, .buf = buf, .total_len = (uint64_t)ite }; - state[0U] = tmp; + tmp8 = { .block_state = block_state, .buf = buf, .total_len = (uint64_t)ite }; + state[0U] = tmp8; } /** diff --git a/Modules/_hacl/include/krml/FStar_UInt128_Verified.h b/Modules/_hacl/include/krml/FStar_UInt128_Verified.h index bdf25898f2bc25..659745b24265cb 100644 --- a/Modules/_hacl/include/krml/FStar_UInt128_Verified.h +++ b/Modules/_hacl/include/krml/FStar_UInt128_Verified.h @@ -1,6 +1,6 @@ /* Copyright (c) INRIA and Microsoft Corporation. All rights reserved. - Licensed under the Apache 2.0 License. + Licensed under the Apache 2.0 and MIT Licenses. */ diff --git a/Modules/_hacl/include/krml/FStar_UInt_8_16_32_64.h b/Modules/_hacl/include/krml/FStar_UInt_8_16_32_64.h index 1bdec972a2f249..68bac0b3f0aab1 100644 --- a/Modules/_hacl/include/krml/FStar_UInt_8_16_32_64.h +++ b/Modules/_hacl/include/krml/FStar_UInt_8_16_32_64.h @@ -1,6 +1,6 @@ /* Copyright (c) INRIA and Microsoft Corporation. All rights reserved. - Licensed under the Apache 2.0 License. + Licensed under the Apache 2.0 and MIT Licenses. */ diff --git a/Modules/_hacl/include/krml/fstar_uint128_struct_endianness.h b/Modules/_hacl/include/krml/fstar_uint128_struct_endianness.h index e2b6d62859a5f1..bb736add318aa8 100644 --- a/Modules/_hacl/include/krml/fstar_uint128_struct_endianness.h +++ b/Modules/_hacl/include/krml/fstar_uint128_struct_endianness.h @@ -1,5 +1,5 @@ /* Copyright (c) INRIA and Microsoft Corporation. All rights reserved. - Licensed under the Apache 2.0 License. */ + Licensed under the Apache 2.0 and MIT Licenses. */ #ifndef FSTAR_UINT128_STRUCT_ENDIANNESS_H #define FSTAR_UINT128_STRUCT_ENDIANNESS_H diff --git a/Modules/_hacl/include/krml/internal/target.h b/Modules/_hacl/include/krml/internal/target.h index 292adc1423553f..fd74d3da684567 100644 --- a/Modules/_hacl/include/krml/internal/target.h +++ b/Modules/_hacl/include/krml/internal/target.h @@ -1,5 +1,5 @@ /* Copyright (c) INRIA and Microsoft Corporation. All rights reserved. - Licensed under the Apache 2.0 License. */ + Licensed under the Apache 2.0 and MIT Licenses. */ #ifndef __KRML_TARGET_H #define __KRML_TARGET_H @@ -82,6 +82,8 @@ # define KRML_NOINLINE __declspec(noinline) # elif defined (__GNUC__) # define KRML_NOINLINE __attribute__((noinline,unused)) +# elif defined (__SUNPRO_C) +# define KRML_NOINLINE __attribute__((noinline)) # else # define KRML_NOINLINE # warning "The KRML_NOINLINE macro is not defined for this toolchain!" @@ -95,6 +97,8 @@ # define KRML_MUSTINLINE inline __forceinline # elif defined (__GNUC__) # define KRML_MUSTINLINE inline __attribute__((always_inline)) +# elif defined (__SUNPRO_C) +# define KRML_MUSTINLINE inline __attribute__((always_inline)) # else # define KRML_MUSTINLINE inline # warning "The KRML_MUSTINLINE macro defaults to plain inline for this toolchain!" diff --git a/Modules/_hacl/include/krml/lowstar_endianness.h b/Modules/_hacl/include/krml/lowstar_endianness.h index 1aa2ccd644c06f..af6b882cf259cc 100644 --- a/Modules/_hacl/include/krml/lowstar_endianness.h +++ b/Modules/_hacl/include/krml/lowstar_endianness.h @@ -1,5 +1,5 @@ /* Copyright (c) INRIA and Microsoft Corporation. All rights reserved. - Licensed under the Apache 2.0 License. */ + Licensed under the Apache 2.0 and MIT Licenses. */ #ifndef __LOWSTAR_ENDIANNESS_H #define __LOWSTAR_ENDIANNESS_H diff --git a/Modules/_hacl/libintvector.h b/Modules/_hacl/libintvector.h index 99d11336942064..11e914f7e1650a 100644 --- a/Modules/_hacl/libintvector.h +++ b/Modules/_hacl/libintvector.h @@ -19,7 +19,7 @@ #define Lib_IntVector_Intrinsics_bit_mask64(x) -((x) & 1) -#if defined(__x86_64__) || defined(_M_X64) +#if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86) #if defined(HACL_CAN_COMPILE_VEC128) diff --git a/Modules/_hacl/refresh.sh b/Modules/_hacl/refresh.sh index 44e18a15f9652a..6234fea9f17bc7 100755 --- a/Modules/_hacl/refresh.sh +++ b/Modules/_hacl/refresh.sh @@ -22,7 +22,7 @@ fi # Update this when updating to a new version after verifying that the changes # the update brings in are good. -expected_hacl_star_rev=a6a09496d9cff652b567d26f2c3ab012321b632a +expected_hacl_star_rev=315a9e491d2bc347b9dae99e0ea506995ea84d9d hacl_dir="$(realpath "$1")" cd "$(dirname "$0")" From c124577ebe915a00de4033c0f7fa7c47621d79e0 Mon Sep 17 00:00:00 2001 From: Wulian Date: Thu, 17 Oct 2024 23:23:37 +0800 Subject: [PATCH 122/170] gh-123370: Fix the canvas not clearing after running turtledemo.clock (#123457) Rewriting the day and date every tick somehow prevented them from being removed either by clicking STOP or loading another example. The solution is to rewrite them only when they change. --- Lib/turtledemo/clock.py | 33 +++++++++++-------- ...-08-28-19-27-35.gh-issue-123370.SPZ9Ux.rst | 1 + 2 files changed, 21 insertions(+), 13 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-08-28-19-27-35.gh-issue-123370.SPZ9Ux.rst diff --git a/Lib/turtledemo/clock.py b/Lib/turtledemo/clock.py index fd3b3992d466bf..8a630e29b8da50 100644 --- a/Lib/turtledemo/clock.py +++ b/Lib/turtledemo/clock.py @@ -1,7 +1,6 @@ -# -*- coding: cp1252 -*- """ turtle-example-suite: - tdemo_clock.py + turtledemo/clock.py Enhanced clock-program, showing date and time @@ -12,6 +11,9 @@ from turtle import * from datetime import datetime +dtfont = "TkFixedFont", 14, "bold" +current_day = None + def jump(distanz, winkel=0): penup() right(winkel) @@ -52,11 +54,23 @@ def clockface(radius): jump(-radius) rt(6) +def display_date_time(): + global current_day + writer.clear() + now = datetime.now() + current_day = now.day + writer.home() + writer.forward(distance=65) + writer.write(wochentag(now), align="center", font=dtfont) + writer.back(distance=150) + writer.write(datum(now), align="center", font=dtfont) + writer.forward(distance=85) + def setup(): global second_hand, minute_hand, hour_hand, writer mode("logo") make_hand_shape("second_hand", 125, 25) - make_hand_shape("minute_hand", 130, 25) + make_hand_shape("minute_hand", 115, 25) make_hand_shape("hour_hand", 90, 25) clockface(160) second_hand = Turtle() @@ -74,10 +88,10 @@ def setup(): hand.speed(0) ht() writer = Turtle() - #writer.mode("logo") writer.ht() writer.pu() writer.bk(85) + display_date_time() def wochentag(t): wochentag = ["Monday", "Tuesday", "Wednesday", @@ -99,18 +113,11 @@ def tick(): stunde = t.hour + minute/60.0 try: tracer(False) # Terminator can occur here - writer.clear() - writer.home() - writer.forward(65) - writer.write(wochentag(t), - align="center", font=("Courier", 14, "bold")) - writer.back(150) - writer.write(datum(t), - align="center", font=("Courier", 14, "bold")) - writer.forward(85) second_hand.setheading(6*sekunde) # or here minute_hand.setheading(6*minute) hour_hand.setheading(30*stunde) + if t.day != current_day: + display_date_time() tracer(True) ontimer(tick, 100) except Terminator: diff --git a/Misc/NEWS.d/next/Library/2024-08-28-19-27-35.gh-issue-123370.SPZ9Ux.rst b/Misc/NEWS.d/next/Library/2024-08-28-19-27-35.gh-issue-123370.SPZ9Ux.rst new file mode 100644 index 00000000000000..1fd5cc54eaf3e7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-08-28-19-27-35.gh-issue-123370.SPZ9Ux.rst @@ -0,0 +1 @@ +Fix the canvas not clearing after running turtledemo clock. From 0cb20f2e7e867d5c34fc17dd5b8e51e8b0020bb3 Mon Sep 17 00:00:00 2001 From: Wulian Date: Thu, 17 Oct 2024 23:40:30 +0800 Subject: [PATCH 123/170] gh-125625: Check for `py -3.13` in PCbuild/find_python.bat (GH-125626) --- PCbuild/find_python.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PCbuild/find_python.bat b/PCbuild/find_python.bat index 6db579fa8de08a..d65d080ca71a90 100644 --- a/PCbuild/find_python.bat +++ b/PCbuild/find_python.bat @@ -47,7 +47,7 @@ @rem If py.exe finds a recent enough version, use that one @rem It is fine to add new versions to this list when they have released, @rem but we do not use prerelease builds here. -@for %%p in (3.12 3.11 3.10) do @py -%%p -EV >nul 2>&1 && (set PYTHON=py -%%p) && (set _Py_Python_Source=found %%p with py.exe) && goto :found +@for %%p in (3.13 3.12 3.11 3.10) do @py -%%p -EV >nul 2>&1 && (set PYTHON=py -%%p) && (set _Py_Python_Source=found %%p with py.exe) && goto :found @if NOT exist "%_Py_EXTERNALS_DIR%" mkdir "%_Py_EXTERNALS_DIR%" @set _Py_NUGET=%NUGET% From ad3eac1963a5f195ef9b2c1dbb5e44fa3cce4c72 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 17 Oct 2024 18:46:59 +0300 Subject: [PATCH 124/170] gh-52551: Fix encoding issues in strftime() (GH-125193) Fix time.strftime(), the strftime() method and formatting of the datetime classes datetime, date and time. * Characters not encodable in the current locale are now acceptable in the format string. * Surrogate pairs and sequence of surrogatescape-encoded bytes are no longer recombinated. * Embedded null character no longer terminates the format string. This fixes also gh-78662 and gh-124531. --- Lib/test/datetimetester.py | 63 ++++- Lib/test/test_time.py | 29 ++- ...4-10-09-17-07-33.gh-issue-52551.PBakSY.rst | 8 + Modules/_datetimemodule.c | 206 +++++++--------- Modules/timemodule.c | 233 ++++++++++-------- 5 files changed, 307 insertions(+), 232 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-09-17-07-33.gh-issue-52551.PBakSY.rst diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index c81408b344968d..dbe25ef57dea83 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -2949,11 +2949,32 @@ def test_more_strftime(self): self.assertEqual(t.strftime("%z"), "-0200" + z) self.assertEqual(t.strftime("%:z"), "-02:00:" + z) - # bpo-34482: Check that surrogates don't cause a crash. - try: - t.strftime('%y\ud800%m %H\ud800%M') - except UnicodeEncodeError: - pass + def test_strftime_special(self): + t = self.theclass(2004, 12, 31, 6, 22, 33, 47) + s1 = t.strftime('%c') + s2 = t.strftime('%B') + # gh-52551, gh-78662: Unicode strings should pass through strftime, + # independently from locale. + self.assertEqual(t.strftime('\U0001f40d'), '\U0001f40d') + self.assertEqual(t.strftime('\U0001f4bb%c\U0001f40d%B'), f'\U0001f4bb{s1}\U0001f40d{s2}') + self.assertEqual(t.strftime('%c\U0001f4bb%B\U0001f40d'), f'{s1}\U0001f4bb{s2}\U0001f40d') + # Lone surrogates should pass through. + self.assertEqual(t.strftime('\ud83d'), '\ud83d') + self.assertEqual(t.strftime('\udc0d'), '\udc0d') + self.assertEqual(t.strftime('\ud83d%c\udc0d%B'), f'\ud83d{s1}\udc0d{s2}') + self.assertEqual(t.strftime('%c\ud83d%B\udc0d'), f'{s1}\ud83d{s2}\udc0d') + self.assertEqual(t.strftime('%c\udc0d%B\ud83d'), f'{s1}\udc0d{s2}\ud83d') + # Surrogate pairs should not recombine. + self.assertEqual(t.strftime('\ud83d\udc0d'), '\ud83d\udc0d') + self.assertEqual(t.strftime('%c\ud83d\udc0d%B'), f'{s1}\ud83d\udc0d{s2}') + # Surrogate-escaped bytes should not recombine. + self.assertEqual(t.strftime('\udcf0\udc9f\udc90\udc8d'), '\udcf0\udc9f\udc90\udc8d') + self.assertEqual(t.strftime('%c\udcf0\udc9f\udc90\udc8d%B'), f'{s1}\udcf0\udc9f\udc90\udc8d{s2}') + # gh-124531: The null character should not terminate the format string. + self.assertEqual(t.strftime('\0'), '\0') + self.assertEqual(t.strftime('\0'*1000), '\0'*1000) + self.assertEqual(t.strftime('\0%c\0%B'), f'\0{s1}\0{s2}') + self.assertEqual(t.strftime('%c\0%B\0'), f'{s1}\0{s2}\0') def test_extract(self): dt = self.theclass(2002, 3, 4, 18, 45, 3, 1234) @@ -3736,6 +3757,33 @@ def test_strftime(self): # gh-85432: The parameter was named "fmt" in the pure-Python impl. t.strftime(format="%f") + def test_strftime_special(self): + t = self.theclass(1, 2, 3, 4) + s1 = t.strftime('%I%p%Z') + s2 = t.strftime('%X') + # gh-52551, gh-78662: Unicode strings should pass through strftime, + # independently from locale. + self.assertEqual(t.strftime('\U0001f40d'), '\U0001f40d') + self.assertEqual(t.strftime('\U0001f4bb%I%p%Z\U0001f40d%X'), f'\U0001f4bb{s1}\U0001f40d{s2}') + self.assertEqual(t.strftime('%I%p%Z\U0001f4bb%X\U0001f40d'), f'{s1}\U0001f4bb{s2}\U0001f40d') + # Lone surrogates should pass through. + self.assertEqual(t.strftime('\ud83d'), '\ud83d') + self.assertEqual(t.strftime('\udc0d'), '\udc0d') + self.assertEqual(t.strftime('\ud83d%I%p%Z\udc0d%X'), f'\ud83d{s1}\udc0d{s2}') + self.assertEqual(t.strftime('%I%p%Z\ud83d%X\udc0d'), f'{s1}\ud83d{s2}\udc0d') + self.assertEqual(t.strftime('%I%p%Z\udc0d%X\ud83d'), f'{s1}\udc0d{s2}\ud83d') + # Surrogate pairs should not recombine. + self.assertEqual(t.strftime('\ud83d\udc0d'), '\ud83d\udc0d') + self.assertEqual(t.strftime('%I%p%Z\ud83d\udc0d%X'), f'{s1}\ud83d\udc0d{s2}') + # Surrogate-escaped bytes should not recombine. + self.assertEqual(t.strftime('\udcf0\udc9f\udc90\udc8d'), '\udcf0\udc9f\udc90\udc8d') + self.assertEqual(t.strftime('%I%p%Z\udcf0\udc9f\udc90\udc8d%X'), f'{s1}\udcf0\udc9f\udc90\udc8d{s2}') + # gh-124531: The null character should not terminate the format string. + self.assertEqual(t.strftime('\0'), '\0') + self.assertEqual(t.strftime('\0'*1000), '\0'*1000) + self.assertEqual(t.strftime('\0%I%p%Z\0%X'), f'\0{s1}\0{s2}') + self.assertEqual(t.strftime('%I%p%Z\0%X\0'), f'{s1}\0{s2}\0') + def test_format(self): t = self.theclass(1, 2, 3, 4) self.assertEqual(t.__format__(''), str(t)) @@ -4259,9 +4307,8 @@ def tzname(self, dt): return self.tz self.assertRaises(TypeError, t.strftime, "%Z") # Issue #6697: - if '_Fast' in self.__class__.__name__: - Badtzname.tz = '\ud800' - self.assertRaises(ValueError, t.strftime, "%Z") + Badtzname.tz = '\ud800' + self.assertEqual(t.strftime("%Z"), '\ud800') def test_hash_edge_cases(self): # Offsets that overflow a basic time. diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py index 27c0f51acc58ab..f8b99a9b6a63f5 100644 --- a/Lib/test/test_time.py +++ b/Lib/test/test_time.py @@ -181,8 +181,33 @@ def test_strftime(self): self.fail('conversion specifier: %r failed.' % format) self.assertRaises(TypeError, time.strftime, b'%S', tt) - # embedded null character - self.assertRaises(ValueError, time.strftime, '%S\0', tt) + + def test_strftime_special(self): + tt = time.gmtime(self.t) + s1 = time.strftime('%c', tt) + s2 = time.strftime('%B', tt) + # gh-52551, gh-78662: Unicode strings should pass through strftime, + # independently from locale. + self.assertEqual(time.strftime('\U0001f40d', tt), '\U0001f40d') + self.assertEqual(time.strftime('\U0001f4bb%c\U0001f40d%B', tt), f'\U0001f4bb{s1}\U0001f40d{s2}') + self.assertEqual(time.strftime('%c\U0001f4bb%B\U0001f40d', tt), f'{s1}\U0001f4bb{s2}\U0001f40d') + # Lone surrogates should pass through. + self.assertEqual(time.strftime('\ud83d', tt), '\ud83d') + self.assertEqual(time.strftime('\udc0d', tt), '\udc0d') + self.assertEqual(time.strftime('\ud83d%c\udc0d%B', tt), f'\ud83d{s1}\udc0d{s2}') + self.assertEqual(time.strftime('%c\ud83d%B\udc0d', tt), f'{s1}\ud83d{s2}\udc0d') + self.assertEqual(time.strftime('%c\udc0d%B\ud83d', tt), f'{s1}\udc0d{s2}\ud83d') + # Surrogate pairs should not recombine. + self.assertEqual(time.strftime('\ud83d\udc0d', tt), '\ud83d\udc0d') + self.assertEqual(time.strftime('%c\ud83d\udc0d%B', tt), f'{s1}\ud83d\udc0d{s2}') + # Surrogate-escaped bytes should not recombine. + self.assertEqual(time.strftime('\udcf0\udc9f\udc90\udc8d', tt), '\udcf0\udc9f\udc90\udc8d') + self.assertEqual(time.strftime('%c\udcf0\udc9f\udc90\udc8d%B', tt), f'{s1}\udcf0\udc9f\udc90\udc8d{s2}') + # gh-124531: The null character should not terminate the format string. + self.assertEqual(time.strftime('\0', tt), '\0') + self.assertEqual(time.strftime('\0'*1000, tt), '\0'*1000) + self.assertEqual(time.strftime('\0%c\0%B', tt), f'\0{s1}\0{s2}') + self.assertEqual(time.strftime('%c\0%B\0', tt), f'{s1}\0{s2}\0') def _bounds_checking(self, func): # Make sure that strftime() checks the bounds of the various parts diff --git a/Misc/NEWS.d/next/Library/2024-10-09-17-07-33.gh-issue-52551.PBakSY.rst b/Misc/NEWS.d/next/Library/2024-10-09-17-07-33.gh-issue-52551.PBakSY.rst new file mode 100644 index 00000000000000..edc9ac5bb23117 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-09-17-07-33.gh-issue-52551.PBakSY.rst @@ -0,0 +1,8 @@ +Fix encoding issues in :func:`time.strftime`, the +:meth:`~datetime.datetime.strftime` method of the :mod:`datetime` classes +:class:`~datetime.datetime`, :class:`~datetime.date` and +:class:`~datetime.time` and formatting of these classes. Characters not +encodable in the current locale are now acceptable in the format string. +Surrogate pairs and sequence of surrogatescape-encoded bytes are no longer +recombinated. Embedded null character no longer terminates the format +string. diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 2ba46cddb4f558..e1bb98fcf05862 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -1747,7 +1747,7 @@ make_somezreplacement(PyObject *object, char *sep, PyObject *tzinfoarg) PyObject *tzinfo = get_tzinfo_member(object); if (tzinfo == Py_None || tzinfo == NULL) { - return PyBytes_FromStringAndSize(NULL, 0); + return PyUnicode_FromStringAndSize(NULL, 0); } assert(tzinfoarg != NULL); @@ -1758,7 +1758,7 @@ make_somezreplacement(PyObject *object, char *sep, PyObject *tzinfoarg) tzinfoarg) < 0) return NULL; - return PyBytes_FromStringAndSize(buf, strlen(buf)); + return PyUnicode_FromString(buf); } static PyObject * @@ -1815,7 +1815,7 @@ make_freplacement(PyObject *object) else sprintf(freplacement, "%06d", 0); - return PyBytes_FromStringAndSize(freplacement, strlen(freplacement)); + return PyUnicode_FromString(freplacement); } /* I sure don't want to reproduce the strftime code from the time module, @@ -1836,94 +1836,60 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple, PyObject *Zreplacement = NULL; /* py string, replacement for %Z */ PyObject *freplacement = NULL; /* py string, replacement for %f */ - const char *pin; /* pointer to next char in input format */ - Py_ssize_t flen; /* length of input format */ - char ch; /* next char in input format */ - - PyObject *newfmt = NULL; /* py string, the output format */ - char *pnew; /* pointer to available byte in output format */ - size_t totalnew; /* number bytes total in output format buffer, - exclusive of trailing \0 */ - size_t usednew; /* number bytes used so far in output format buffer */ - - const char *ptoappend; /* ptr to string to append to output buffer */ - Py_ssize_t ntoappend; /* # of bytes to append to output buffer */ - -#ifdef Py_NORMALIZE_CENTURY - /* Buffer of maximum size of formatted year permitted by long. */ - char buf[SIZEOF_LONG * 5 / 2 + 2 -#ifdef Py_STRFTIME_C99_SUPPORT - /* Need 6 more to accommodate dashes, 2-digit month and day for %F. */ - + 6 -#endif - ]; -#endif - assert(object && format && timetuple); assert(PyUnicode_Check(format)); - /* Convert the input format to a C string and size */ - pin = PyUnicode_AsUTF8AndSize(format, &flen); - if (!pin) - return NULL; PyObject *strftime = _PyImport_GetModuleAttrString("time", "strftime"); if (strftime == NULL) { - goto Done; + return NULL; } /* Scan the input format, looking for %z/%Z/%f escapes, building * a new format. Since computing the replacements for those codes * is expensive, don't unless they're actually used. */ - if (flen > INT_MAX - 1) { - PyErr_NoMemory(); - goto Done; - } - - totalnew = flen + 1; /* realistic if no %z/%Z */ - newfmt = PyBytes_FromStringAndSize(NULL, totalnew); - if (newfmt == NULL) goto Done; - pnew = PyBytes_AsString(newfmt); - usednew = 0; - while ((ch = *pin++) != '\0') { - if (ch != '%') { - ptoappend = pin - 1; - ntoappend = 1; + _PyUnicodeWriter writer; + _PyUnicodeWriter_Init(&writer); + writer.overallocate = 1; + + Py_ssize_t flen = PyUnicode_GET_LENGTH(format); + Py_ssize_t i = 0; + Py_ssize_t start = 0; + Py_ssize_t end = 0; + while (i != flen) { + i = PyUnicode_FindChar(format, '%', i, flen, 1); + if (i < 0) { + assert(!PyErr_Occurred()); + break; } - else if ((ch = *pin++) == '\0') { - /* Null byte follows %, copy only '%'. - * - * Back the pin up one char so that we catch the null check - * the next time through the loop.*/ - pin--; - ptoappend = pin - 1; - ntoappend = 1; + end = i; + i++; + if (i == flen) { + break; } + Py_UCS4 ch = PyUnicode_READ_CHAR(format, i); + i++; /* A % has been seen and ch is the character after it. */ - else if (ch == 'z') { + PyObject *replacement = NULL; + if (ch == 'z') { /* %z -> +HHMM */ if (zreplacement == NULL) { zreplacement = make_somezreplacement(object, "", tzinfoarg); if (zreplacement == NULL) - goto Done; + goto Error; } - assert(zreplacement != NULL); - assert(PyBytes_Check(zreplacement)); - ptoappend = PyBytes_AS_STRING(zreplacement); - ntoappend = PyBytes_GET_SIZE(zreplacement); + replacement = zreplacement; } - else if (ch == ':' && *pin == 'z' && pin++) { + else if (ch == ':' && i < flen && PyUnicode_READ_CHAR(format, i) == 'z') { /* %:z -> +HH:MM */ + i++; if (colonzreplacement == NULL) { colonzreplacement = make_somezreplacement(object, ":", tzinfoarg); if (colonzreplacement == NULL) - goto Done; + goto Error; } - assert(colonzreplacement != NULL); - assert(PyBytes_Check(colonzreplacement)); - ptoappend = PyBytes_AS_STRING(colonzreplacement); - ntoappend = PyBytes_GET_SIZE(colonzreplacement); + replacement = colonzreplacement; } else if (ch == 'Z') { /* format tzname */ @@ -1931,26 +1897,18 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple, Zreplacement = make_Zreplacement(object, tzinfoarg); if (Zreplacement == NULL) - goto Done; + goto Error; } - assert(Zreplacement != NULL); - assert(PyUnicode_Check(Zreplacement)); - ptoappend = PyUnicode_AsUTF8AndSize(Zreplacement, - &ntoappend); - if (ptoappend == NULL) - goto Done; + replacement = Zreplacement; } else if (ch == 'f') { /* format microseconds */ if (freplacement == NULL) { freplacement = make_freplacement(object); if (freplacement == NULL) - goto Done; + goto Error; } - assert(freplacement != NULL); - assert(PyBytes_Check(freplacement)); - ptoappend = PyBytes_AS_STRING(freplacement); - ntoappend = PyBytes_GET_SIZE(freplacement); + replacement = freplacement; } #ifdef Py_NORMALIZE_CENTURY else if (ch == 'Y' || ch == 'G' @@ -1961,100 +1919,102 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple, /* 0-pad year with century as necessary */ PyObject *item = PySequence_GetItem(timetuple, 0); if (item == NULL) { - goto Done; + goto Error; } long year_long = PyLong_AsLong(item); Py_DECREF(item); if (year_long == -1 && PyErr_Occurred()) { - goto Done; + goto Error; } /* Note that datetime(1000, 1, 1).strftime('%G') == '1000' so year 1000 for %G can go on the fast path. */ if (year_long >= 1000) { - goto PassThrough; + continue; } if (ch == 'G') { PyObject *year_str = PyObject_CallFunction(strftime, "sO", "%G", timetuple); if (year_str == NULL) { - goto Done; + goto Error; } PyObject *year = PyNumber_Long(year_str); Py_DECREF(year_str); if (year == NULL) { - goto Done; + goto Error; } year_long = PyLong_AsLong(year); Py_DECREF(year); if (year_long == -1 && PyErr_Occurred()) { - goto Done; + goto Error; } } - ntoappend = PyOS_snprintf(buf, sizeof(buf), + /* Buffer of maximum size of formatted year permitted by long. + * +6 to accommodate dashes, 2-digit month and day for %F. */ + char buf[SIZEOF_LONG * 5 / 2 + 2 + 6]; + Py_ssize_t n = PyOS_snprintf(buf, sizeof(buf), #ifdef Py_STRFTIME_C99_SUPPORT ch == 'F' ? "%04ld-%%m-%%d" : #endif "%04ld", year_long); #ifdef Py_STRFTIME_C99_SUPPORT if (ch == 'C') { - ntoappend -= 2; + n -= 2; } #endif - ptoappend = buf; + if (_PyUnicodeWriter_WriteSubstring(&writer, format, start, end) < 0) { + goto Error; + } + start = i; + if (_PyUnicodeWriter_WriteASCIIString(&writer, buf, n) < 0) { + goto Error; + } + continue; } #endif else { /* percent followed by something else */ -#ifdef Py_NORMALIZE_CENTURY - PassThrough: -#endif - ptoappend = pin - 2; - ntoappend = 2; - } - - /* Append the ntoappend chars starting at ptoappend to - * the new format. - */ - if (ntoappend == 0) continue; - assert(ptoappend != NULL); - assert(ntoappend > 0); - while (usednew + ntoappend > totalnew) { - if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */ - PyErr_NoMemory(); - goto Done; - } - totalnew <<= 1; - if (_PyBytes_Resize(&newfmt, totalnew) < 0) - goto Done; - pnew = PyBytes_AsString(newfmt) + usednew; } - memcpy(pnew, ptoappend, ntoappend); - pnew += ntoappend; - usednew += ntoappend; - assert(usednew <= totalnew); + assert(replacement != NULL); + assert(PyUnicode_Check(replacement)); + if (_PyUnicodeWriter_WriteSubstring(&writer, format, start, end) < 0) { + goto Error; + } + start = i; + if (_PyUnicodeWriter_WriteStr(&writer, replacement) < 0) { + goto Error; + } } /* end while() */ - if (_PyBytes_Resize(&newfmt, usednew) < 0) - goto Done; - { - PyObject *format; - - format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt)); - if (format != NULL) { - result = PyObject_CallFunctionObjArgs(strftime, - format, timetuple, NULL); - Py_DECREF(format); + PyObject *newformat; + if (start == 0) { + _PyUnicodeWriter_Dealloc(&writer); + newformat = Py_NewRef(format); + } + else { + if (_PyUnicodeWriter_WriteSubstring(&writer, format, start, flen) < 0) { + goto Error; + } + newformat = _PyUnicodeWriter_Finish(&writer); + if (newformat == NULL) { + goto Done; } } + result = PyObject_CallFunctionObjArgs(strftime, + newformat, timetuple, NULL); + Py_DECREF(newformat); + Done: Py_XDECREF(freplacement); Py_XDECREF(zreplacement); Py_XDECREF(colonzreplacement); Py_XDECREF(Zreplacement); - Py_XDECREF(newfmt); Py_XDECREF(strftime); return result; + + Error: + _PyUnicodeWriter_Dealloc(&writer); + goto Done; } /* --------------------------------------------------------------------------- diff --git a/Modules/timemodule.c b/Modules/timemodule.c index 9720c201a184a8..b9d114ada0dfcd 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -776,27 +776,100 @@ the C library strftime function.\n" #endif static PyObject * -time_strftime(PyObject *module, PyObject *args) +time_strftime1(time_char **outbuf, size_t *bufsize, + time_char *format, size_t fmtlen, + struct tm *tm) { - PyObject *tup = NULL; - struct tm buf; - const time_char *fmt; + size_t buflen; +#if defined(MS_WINDOWS) && !defined(HAVE_WCSFTIME) + /* check that the format string contains only valid directives */ + for (const time_char *f = strchr(format, '%'); + f != NULL; + f = strchr(f + 2, '%')) + { + if (f[1] == '#') + ++f; /* not documented by python, */ + if (f[1] == '\0') + break; + if ((f[1] == 'y') && tm->tm_year < 0) { + PyErr_SetString(PyExc_ValueError, + "format %y requires year >= 1900 on Windows"); + return NULL; + } + } +#elif (defined(_AIX) || (defined(__sun) && defined(__SVR4))) && defined(HAVE_WCSFTIME) + for (const time_char *f = wcschr(format, '%'); + f != NULL; + f = wcschr(f + 2, '%')) + { + if (f[1] == L'\0') + break; + /* Issue #19634: On AIX, wcsftime("y", (1899, 1, 1, 0, 0, 0, 0, 0, 0)) + returns "0/" instead of "99" */ + if (f[1] == L'y' && tm->tm_year < 0) { + PyErr_SetString(PyExc_ValueError, + "format %y requires year >= 1900 on AIX"); + return NULL; + } + } +#endif + + /* I hate these functions that presume you know how big the output + * will be ahead of time... + */ + while (1) { + if (*bufsize > PY_SSIZE_T_MAX/sizeof(time_char)) { + PyErr_NoMemory(); + return NULL; + } + *outbuf = (time_char *)PyMem_Realloc(*outbuf, + *bufsize*sizeof(time_char)); + if (*outbuf == NULL) { + PyErr_NoMemory(); + return NULL; + } +#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__) + errno = 0; +#endif + _Py_BEGIN_SUPPRESS_IPH + buflen = format_time(*outbuf, *bufsize, format, tm); + _Py_END_SUPPRESS_IPH +#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__) + /* VisualStudio .NET 2005 does this properly */ + if (buflen == 0 && errno == EINVAL) { + PyErr_SetString(PyExc_ValueError, "Invalid format string"); + return NULL; + } +#endif + if (buflen == 0 && *bufsize < 256 * fmtlen) { + *bufsize += *bufsize; + continue; + } + /* If the buffer is 256 times as long as the format, + it's probably not failing for lack of room! + More likely, the format yields an empty result, + e.g. an empty format, or %Z when the timezone + is unknown. */ #ifdef HAVE_WCSFTIME - wchar_t *format; + return PyUnicode_FromWideChar(*outbuf, buflen); #else - PyObject *format; + return PyUnicode_DecodeLocaleAndSize(*outbuf, buflen, "surrogateescape"); #endif + } +} + +static PyObject * +time_strftime(PyObject *module, PyObject *args) +{ + PyObject *tup = NULL; + struct tm buf; PyObject *format_arg; - size_t fmtlen, buflen; - time_char *outbuf = NULL; - size_t i; - PyObject *ret = NULL; + Py_ssize_t format_size; + time_char *format, *outbuf = NULL; + size_t fmtlen, bufsize = 1024; memset((void *) &buf, '\0', sizeof(buf)); - /* Will always expect a unicode string to be passed as format. - Given that there's no str type anymore in py3k this seems safe. - */ if (!PyArg_ParseTuple(args, "U|O:strftime", &format_arg, &tup)) return NULL; @@ -834,101 +907,63 @@ time_strftime(PyObject *module, PyObject *args) else if (buf.tm_isdst > 1) buf.tm_isdst = 1; -#ifdef HAVE_WCSFTIME - format = PyUnicode_AsWideCharString(format_arg, NULL); - if (format == NULL) + format_size = PyUnicode_GET_LENGTH(format_arg); + if ((size_t)format_size > PY_SSIZE_T_MAX/sizeof(time_char) - 1) { + PyErr_NoMemory(); return NULL; - fmt = format; -#else - /* Convert the unicode string to an ascii one */ - format = PyUnicode_EncodeLocale(format_arg, "surrogateescape"); - if (format == NULL) + } + format = PyMem_Malloc((format_size + 1)*sizeof(time_char)); + if (format == NULL) { + PyErr_NoMemory(); return NULL; - fmt = PyBytes_AS_STRING(format); -#endif - -#if defined(MS_WINDOWS) && !defined(HAVE_WCSFTIME) - /* check that the format string contains only valid directives */ - for (outbuf = strchr(fmt, '%'); - outbuf != NULL; - outbuf = strchr(outbuf+2, '%')) - { - if (outbuf[1] == '#') - ++outbuf; /* not documented by python, */ - if (outbuf[1] == '\0') - break; - if ((outbuf[1] == 'y') && buf.tm_year < 0) { - PyErr_SetString(PyExc_ValueError, - "format %y requires year >= 1900 on Windows"); - Py_DECREF(format); - return NULL; - } } -#elif (defined(_AIX) || (defined(__sun) && defined(__SVR4))) && defined(HAVE_WCSFTIME) - for (outbuf = wcschr(fmt, '%'); - outbuf != NULL; - outbuf = wcschr(outbuf+2, '%')) - { - if (outbuf[1] == L'\0') - break; - /* Issue #19634: On AIX, wcsftime("y", (1899, 1, 1, 0, 0, 0, 0, 0, 0)) - returns "0/" instead of "99" */ - if (outbuf[1] == L'y' && buf.tm_year < 0) { - PyErr_SetString(PyExc_ValueError, - "format %y requires year >= 1900 on AIX"); - PyMem_Free(format); - return NULL; + _PyUnicodeWriter writer; + _PyUnicodeWriter_Init(&writer); + writer.overallocate = 1; + Py_ssize_t i = 0; + while (i < format_size) { + fmtlen = 0; + for (; i < format_size; i++) { + Py_UCS4 c = PyUnicode_READ_CHAR(format_arg, i); + if (!c || c > 127) { + break; + } + format[fmtlen++] = (char)c; } - } -#endif - - fmtlen = time_strlen(fmt); - - /* I hate these functions that presume you know how big the output - * will be ahead of time... - */ - for (i = 1024; ; i += i) { - outbuf = (time_char *)PyMem_Malloc(i*sizeof(time_char)); - if (outbuf == NULL) { - PyErr_NoMemory(); - break; + if (fmtlen) { + format[fmtlen] = 0; + PyObject *unicode = time_strftime1(&outbuf, &bufsize, + format, fmtlen, &buf); + if (unicode == NULL) { + goto error; + } + if (_PyUnicodeWriter_WriteStr(&writer, unicode) < 0) { + Py_DECREF(unicode); + goto error; + } + Py_DECREF(unicode); } -#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__) - errno = 0; -#endif - _Py_BEGIN_SUPPRESS_IPH - buflen = format_time(outbuf, i, fmt, &buf); - _Py_END_SUPPRESS_IPH -#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__) - /* VisualStudio .NET 2005 does this properly */ - if (buflen == 0 && errno == EINVAL) { - PyErr_SetString(PyExc_ValueError, "Invalid format string"); - PyMem_Free(outbuf); - break; + + Py_ssize_t start = i; + for (; i < format_size; i++) { + Py_UCS4 c = PyUnicode_READ_CHAR(format_arg, i); + if (c == '%') { + break; + } } -#endif - if (buflen > 0 || i >= 256 * fmtlen) { - /* If the buffer is 256 times as long as the format, - it's probably not failing for lack of room! - More likely, the format yields an empty result, - e.g. an empty format, or %Z when the timezone - is unknown. */ -#ifdef HAVE_WCSFTIME - ret = PyUnicode_FromWideChar(outbuf, buflen); -#else - ret = PyUnicode_DecodeLocaleAndSize(outbuf, buflen, "surrogateescape"); -#endif - PyMem_Free(outbuf); - break; + if (_PyUnicodeWriter_WriteSubstring(&writer, format_arg, start, i) < 0) { + goto error; } - PyMem_Free(outbuf); } -#ifdef HAVE_WCSFTIME + + PyMem_Free(outbuf); PyMem_Free(format); -#else - Py_DECREF(format); -#endif - return ret; + return _PyUnicodeWriter_Finish(&writer); +error: + PyMem_Free(outbuf); + PyMem_Free(format); + _PyUnicodeWriter_Dealloc(&writer); + return NULL; } #undef time_char From 04d6dd23e2d8a3132772cf7ce928676e26313585 Mon Sep 17 00:00:00 2001 From: George Pittock <66332098+georgepittock@users.noreply.github.com> Date: Thu, 17 Oct 2024 17:34:37 +0100 Subject: [PATCH 125/170] gh-113570: reprlib.repr does not use builtin __repr__ for reshadowed builtins (GH-113577) --- Lib/reprlib.py | 31 ++++++++++--- Lib/test/test_reprlib.py | 44 +++++++++++++++++++ ...-12-30-00-21-45.gh-issue-113570._XQgsW.rst | 1 + 3 files changed, 71 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2023-12-30-00-21-45.gh-issue-113570._XQgsW.rst diff --git a/Lib/reprlib.py b/Lib/reprlib.py index 05bb1a0eb01795..19dbe3a07eb618 100644 --- a/Lib/reprlib.py +++ b/Lib/reprlib.py @@ -36,6 +36,17 @@ def wrapper(self): return decorating_function class Repr: + _lookup = { + 'tuple': 'builtins', + 'list': 'builtins', + 'array': 'array', + 'set': 'builtins', + 'frozenset': 'builtins', + 'deque': 'collections', + 'dict': 'builtins', + 'str': 'builtins', + 'int': 'builtins' + } def __init__( self, *, maxlevel=6, maxtuple=6, maxlist=6, maxarray=5, maxdict=4, @@ -60,14 +71,24 @@ def repr(self, x): return self.repr1(x, self.maxlevel) def repr1(self, x, level): - typename = type(x).__name__ + cls = type(x) + typename = cls.__name__ + if ' ' in typename: parts = typename.split() typename = '_'.join(parts) - if hasattr(self, 'repr_' + typename): - return getattr(self, 'repr_' + typename)(x, level) - else: - return self.repr_instance(x, level) + + method = getattr(self, 'repr_' + typename, None) + if method: + # not defined in this class + if typename not in self._lookup: + return method(x, level) + module = getattr(cls, '__module__', None) + # defined in this class and is the module intended + if module == self._lookup[typename]: + return method(x, level) + + return self.repr_instance(x, level) def _join(self, pieces, level): if self.indent is None: diff --git a/Lib/test/test_reprlib.py b/Lib/test/test_reprlib.py index 3e93b561c143d8..ffeb1fba7b80c6 100644 --- a/Lib/test/test_reprlib.py +++ b/Lib/test/test_reprlib.py @@ -580,6 +580,50 @@ def test_invalid_indent(self): with self.assertRaisesRegex(expected_error, expected_msg): r.repr(test_object) + def test_shadowed_stdlib_array(self): + # Issue #113570: repr() should not be fooled by an array + class array: + def __repr__(self): + return "not array.array" + + self.assertEqual(r(array()), "not array.array") + + def test_shadowed_builtin(self): + # Issue #113570: repr() should not be fooled + # by a shadowed builtin function + class list: + def __repr__(self): + return "not builtins.list" + + self.assertEqual(r(list()), "not builtins.list") + + def test_custom_repr(self): + class MyRepr(Repr): + + def repr_TextIOWrapper(self, obj, level): + if obj.name in {'', '', ''}: + return obj.name + return repr(obj) + + aRepr = MyRepr() + self.assertEqual(aRepr.repr(sys.stdin), "") + + def test_custom_repr_class_with_spaces(self): + class TypeWithSpaces: + pass + + t = TypeWithSpaces() + type(t).__name__ = "type with spaces" + self.assertEqual(type(t).__name__, "type with spaces") + + class MyRepr(Repr): + def repr_type_with_spaces(self, obj, level): + return "Type With Spaces" + + + aRepr = MyRepr() + self.assertEqual(aRepr.repr(t), "Type With Spaces") + def write_file(path, text): with open(path, 'w', encoding='ASCII') as fp: fp.write(text) diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-12-30-00-21-45.gh-issue-113570._XQgsW.rst b/Misc/NEWS.d/next/Core and Builtins/2023-12-30-00-21-45.gh-issue-113570._XQgsW.rst new file mode 100644 index 00000000000000..6e0f0afe05369b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-12-30-00-21-45.gh-issue-113570._XQgsW.rst @@ -0,0 +1 @@ +Fixed a bug in ``reprlib.repr`` where it incorrectly called the repr method on shadowed Python built-in types. From f203d1cb52f7697140337a73841c8412282e2ee0 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Thu, 17 Oct 2024 09:45:25 -0700 Subject: [PATCH 126/170] gh-125017: Fix crash on premature access to classmethod/staticmethod annotations (#125636) --- Lib/test/test_descr.py | 14 +++++++ ...-10-16-23-06-06.gh-issue-125017.fcltj0.rst | 2 + Objects/funcobject.c | 41 ++++++++++++------- 3 files changed, 43 insertions(+), 14 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-10-16-23-06-06.gh-issue-125017.fcltj0.rst diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 9d15ab3a96bad6..b7e0f4d6d64018 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -1618,6 +1618,9 @@ def annotated(cls) -> int: pass for method in (annotated, unannotated): with self.subTest(deco=deco, method=method): + with self.assertRaises(AttributeError): + del unannotated.__annotations__ + original_annotations = dict(method.__wrapped__.__annotations__) self.assertNotIn('__annotations__', method.__dict__) self.assertEqual(method.__annotations__, original_annotations) @@ -1644,6 +1647,17 @@ def annotated(cls) -> int: pass del method.__annotate__ self.assertIs(method.__annotate__, original_annotate) + def test_staticmethod_annotations_without_dict_access(self): + # gh-125017: this used to crash + class Spam: + def __new__(cls, x, y): + pass + + self.assertEqual(Spam.__new__.__annotations__, {}) + obj = Spam.__dict__['__new__'] + self.assertIsInstance(obj, staticmethod) + self.assertEqual(obj.__annotations__, {}) + @support.refcount_test def test_refleaks_in_classmethod___init__(self): gettotalrefcount = support.get_attribute(sys, 'gettotalrefcount') diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-10-16-23-06-06.gh-issue-125017.fcltj0.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-16-23-06-06.gh-issue-125017.fcltj0.rst new file mode 100644 index 00000000000000..11c526643c3122 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-16-23-06-06.gh-issue-125017.fcltj0.rst @@ -0,0 +1,2 @@ +Fix crash on certain accesses to the ``__annotations__`` of +:class:`staticmethod` and :class:`classmethod` objects. diff --git a/Objects/funcobject.c b/Objects/funcobject.c index 6119a96b4aae76..f86ef32f1827bf 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -1220,30 +1220,43 @@ functools_wraps(PyObject *wrapper, PyObject *wrapped) // Used for wrapping __annotations__ and __annotate__ on classmethod // and staticmethod objects. static PyObject * -descriptor_get_wrapped_attribute(PyObject *wrapped, PyObject *dict, PyObject *name) +descriptor_get_wrapped_attribute(PyObject *wrapped, PyObject *obj, PyObject *name) { + PyObject *dict = PyObject_GenericGetDict(obj, NULL); + if (dict == NULL) { + return NULL; + } PyObject *res; if (PyDict_GetItemRef(dict, name, &res) < 0) { + Py_DECREF(dict); return NULL; } if (res != NULL) { + Py_DECREF(dict); return res; } res = PyObject_GetAttr(wrapped, name); if (res == NULL) { + Py_DECREF(dict); return NULL; } if (PyDict_SetItem(dict, name, res) < 0) { + Py_DECREF(dict); Py_DECREF(res); return NULL; } + Py_DECREF(dict); return res; } static int -descriptor_set_wrapped_attribute(PyObject *dict, PyObject *name, PyObject *value, +descriptor_set_wrapped_attribute(PyObject *oobj, PyObject *name, PyObject *value, char *type_name) { + PyObject *dict = PyObject_GenericGetDict(oobj, NULL); + if (dict == NULL) { + return -1; + } if (value == NULL) { if (PyDict_DelItem(dict, name) < 0) { if (PyErr_ExceptionMatches(PyExc_KeyError)) { @@ -1251,14 +1264,18 @@ descriptor_set_wrapped_attribute(PyObject *dict, PyObject *name, PyObject *value PyErr_Format(PyExc_AttributeError, "'%.200s' object has no attribute '%U'", type_name, name); + return -1; } else { + Py_DECREF(dict); return -1; } } + Py_DECREF(dict); return 0; } else { + Py_DECREF(dict); return PyDict_SetItem(dict, name, value); } } @@ -1380,28 +1397,26 @@ static PyObject * cm_get___annotations__(PyObject *self, void *closure) { classmethod *cm = _PyClassMethod_CAST(self); - return descriptor_get_wrapped_attribute(cm->cm_callable, cm->cm_dict, &_Py_ID(__annotations__)); + return descriptor_get_wrapped_attribute(cm->cm_callable, self, &_Py_ID(__annotations__)); } static int cm_set___annotations__(PyObject *self, PyObject *value, void *closure) { - classmethod *cm = _PyClassMethod_CAST(self); - return descriptor_set_wrapped_attribute(cm->cm_dict, &_Py_ID(__annotations__), value, "classmethod"); + return descriptor_set_wrapped_attribute(self, &_Py_ID(__annotations__), value, "classmethod"); } static PyObject * cm_get___annotate__(PyObject *self, void *closure) { classmethod *cm = _PyClassMethod_CAST(self); - return descriptor_get_wrapped_attribute(cm->cm_callable, cm->cm_dict, &_Py_ID(__annotate__)); + return descriptor_get_wrapped_attribute(cm->cm_callable, self, &_Py_ID(__annotate__)); } static int cm_set___annotate__(PyObject *self, PyObject *value, void *closure) { - classmethod *cm = _PyClassMethod_CAST(self); - return descriptor_set_wrapped_attribute(cm->cm_dict, &_Py_ID(__annotate__), value, "classmethod"); + return descriptor_set_wrapped_attribute(self, &_Py_ID(__annotate__), value, "classmethod"); } @@ -1615,28 +1630,26 @@ static PyObject * sm_get___annotations__(PyObject *self, void *closure) { staticmethod *sm = _PyStaticMethod_CAST(self); - return descriptor_get_wrapped_attribute(sm->sm_callable, sm->sm_dict, &_Py_ID(__annotations__)); + return descriptor_get_wrapped_attribute(sm->sm_callable, self, &_Py_ID(__annotations__)); } static int sm_set___annotations__(PyObject *self, PyObject *value, void *closure) { - staticmethod *sm = _PyStaticMethod_CAST(self); - return descriptor_set_wrapped_attribute(sm->sm_dict, &_Py_ID(__annotations__), value, "staticmethod"); + return descriptor_set_wrapped_attribute(self, &_Py_ID(__annotations__), value, "staticmethod"); } static PyObject * sm_get___annotate__(PyObject *self, void *closure) { staticmethod *sm = _PyStaticMethod_CAST(self); - return descriptor_get_wrapped_attribute(sm->sm_callable, sm->sm_dict, &_Py_ID(__annotate__)); + return descriptor_get_wrapped_attribute(sm->sm_callable, self, &_Py_ID(__annotate__)); } static int sm_set___annotate__(PyObject *self, PyObject *value, void *closure) { - staticmethod *sm = _PyStaticMethod_CAST(self); - return descriptor_set_wrapped_attribute(sm->sm_dict, &_Py_ID(__annotate__), value, "staticmethod"); + return descriptor_set_wrapped_attribute(self, &_Py_ID(__annotate__), value, "staticmethod"); } static PyGetSetDef sm_getsetlist[] = { From b454662921fd3a1fc27169e91aca03aadea08817 Mon Sep 17 00:00:00 2001 From: chrysn Date: Thu, 17 Oct 2024 19:49:12 +0200 Subject: [PATCH 127/170] gh-118986: expose `socket.IPV6_RECVERR` (#118987) --- Doc/library/socket.rst | 4 ++-- .../Library/2024-05-13-10-09-41.gh-issue-118986.-r4W9h.rst | 1 + Modules/socketmodule.c | 3 +++ 3 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-05-13-10-09-41.gh-issue-118986.-r4W9h.rst diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index 935d4a85342876..0c7b9328648f66 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -451,8 +451,8 @@ Constants network interface instead of its name. .. versionchanged:: 3.14 - Added missing ``IP_RECVERR``, ``IP_RECVTTL``, and ``IP_RECVORIGDSTADDR`` - on Linux. + Added missing ``IP_RECVERR``, ``IPV6_RECVERR``, ``IP_RECVTTL``, and + ``IP_RECVORIGDSTADDR`` on Linux. .. versionchanged:: 3.14 Added support for ``TCP_QUICKACK`` on Windows platforms when available. diff --git a/Misc/NEWS.d/next/Library/2024-05-13-10-09-41.gh-issue-118986.-r4W9h.rst b/Misc/NEWS.d/next/Library/2024-05-13-10-09-41.gh-issue-118986.-r4W9h.rst new file mode 100644 index 00000000000000..196da60a950bfb --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-05-13-10-09-41.gh-issue-118986.-r4W9h.rst @@ -0,0 +1 @@ +Add :data:`!socket.IPV6_RECVERR` constant (available since Linux 2.2). diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 744e5e0c0b2b54..2764bd6e2b2a47 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -8578,6 +8578,9 @@ socket_exec(PyObject *m) #ifdef IPV6_RECVDSTOPTS ADD_INT_MACRO(m, IPV6_RECVDSTOPTS); #endif +#ifdef IPV6_RECVERR + ADD_INT_MACRO(m, IPV6_RECVERR); +#endif #ifdef IPV6_RECVHOPLIMIT ADD_INT_MACRO(m, IPV6_RECVHOPLIMIT); #endif From d8c864816121547338efa43c56e3f75ead98a924 Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Thu, 17 Oct 2024 14:10:55 -0400 Subject: [PATCH 128/170] gh-125541: Make Ctrl-C interrupt `threading.Lock.acquire()` on Windows (#125546) --- Doc/library/_thread.rst | 9 +++------ Doc/library/threading.rst | 3 +++ ...24-10-15-16-50-03.gh-issue-125541.FfhmWo.rst | 4 ++++ Python/parking_lot.c | 17 +++++++++++++++-- 4 files changed, 25 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-15-16-50-03.gh-issue-125541.FfhmWo.rst diff --git a/Doc/library/_thread.rst b/Doc/library/_thread.rst index 6a66fc4c64bc45..ed29ac70035597 100644 --- a/Doc/library/_thread.rst +++ b/Doc/library/_thread.rst @@ -187,6 +187,9 @@ Lock objects have the following methods: .. versionchanged:: 3.2 Lock acquires can now be interrupted by signals on POSIX. + .. versionchanged:: 3.14 + Lock acquires can now be interrupted by signals on Windows. + .. method:: lock.release() @@ -219,12 +222,6 @@ In addition to these methods, lock objects can also be used via the * Calling :func:`sys.exit` or raising the :exc:`SystemExit` exception is equivalent to calling :func:`_thread.exit`. -* It is platform-dependent whether the :meth:`~threading.Lock.acquire` method - on a lock can be interrupted (so that the :exc:`KeyboardInterrupt` exception - will happen immediately, rather than only after the lock has been acquired or - the operation has timed out). It can be interrupted on POSIX, but not on - Windows. - * When the main thread exits, it is system defined whether the other threads survive. On most systems, they are killed without executing :keyword:`try` ... :keyword:`finally` clauses or executing object diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index cb82fea377697b..d4b343db36efb3 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -567,6 +567,9 @@ All methods are executed atomically. Lock acquisition can now be interrupted by signals on POSIX if the underlying threading implementation supports it. + .. versionchanged:: 3.14 + Lock acquisition can now be interrupted by signals on Windows. + .. method:: release() diff --git a/Misc/NEWS.d/next/Library/2024-10-15-16-50-03.gh-issue-125541.FfhmWo.rst b/Misc/NEWS.d/next/Library/2024-10-15-16-50-03.gh-issue-125541.FfhmWo.rst new file mode 100644 index 00000000000000..7a20bca1739869 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-15-16-50-03.gh-issue-125541.FfhmWo.rst @@ -0,0 +1,4 @@ +Pressing :kbd:`Ctrl-C` while blocked in :meth:`threading.Lock.acquire`, +:meth:`threading.RLock.acquire`, and :meth:`threading.Thread.join` now +interrupts the function call and raises a :exc:`KeyboardInterrupt` exception +on Windows, similar to how those functions behave on macOS and Linux. diff --git a/Python/parking_lot.c b/Python/parking_lot.c index a7e9760e35d87a..bffc959e5d0978 100644 --- a/Python/parking_lot.c +++ b/Python/parking_lot.c @@ -111,15 +111,28 @@ _PySemaphore_PlatformWait(_PySemaphore *sema, PyTime_t timeout) millis = (DWORD) div; } } - wait = WaitForSingleObjectEx(sema->platform_sem, millis, FALSE); + + // NOTE: we wait on the sigint event even in non-main threads to match the + // behavior of the other platforms. Non-main threads will ignore the + // Py_PARK_INTR result. + HANDLE sigint_event = _PyOS_SigintEvent(); + HANDLE handles[2] = { sema->platform_sem, sigint_event }; + DWORD count = sigint_event != NULL ? 2 : 1; + wait = WaitForMultipleObjects(count, handles, FALSE, millis); if (wait == WAIT_OBJECT_0) { res = Py_PARK_OK; } + else if (wait == WAIT_OBJECT_0 + 1) { + ResetEvent(sigint_event); + res = Py_PARK_INTR; + } else if (wait == WAIT_TIMEOUT) { res = Py_PARK_TIMEOUT; } else { - res = Py_PARK_INTR; + _Py_FatalErrorFormat(__func__, + "unexpected error from semaphore: %u (error: %u)", + wait, GetLastError()); } #elif defined(_Py_USE_SEMAPHORES) int err; From c3164ae3cf4e8f9ccc4df8ea5f5664c5927ea839 Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Thu, 17 Oct 2024 17:21:32 -0500 Subject: [PATCH 129/170] gh-125017: Fix refleak from GH-125636 (GH-125664) --- Objects/funcobject.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Objects/funcobject.c b/Objects/funcobject.c index f86ef32f1827bf..3cb247691386bf 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -1264,6 +1264,7 @@ descriptor_set_wrapped_attribute(PyObject *oobj, PyObject *name, PyObject *value PyErr_Format(PyExc_AttributeError, "'%.200s' object has no attribute '%U'", type_name, name); + Py_DECREF(dict); return -1; } else { From 7cf2dbc3cb3ef7be65a98bbfc87246d36d795c82 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Thu, 17 Oct 2024 17:49:15 -0600 Subject: [PATCH 130/170] gh-125667: Statically Initialize the Arg Converter Data Values in _interpqueuesmodule.c (gh-125668) --- Modules/_interpqueuesmodule.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Modules/_interpqueuesmodule.c b/Modules/_interpqueuesmodule.c index 5dec240f02c4db..55c43199ee4d79 100644 --- a/Modules/_interpqueuesmodule.c +++ b/Modules/_interpqueuesmodule.c @@ -1518,7 +1518,7 @@ static PyObject * queuesmod_destroy(PyObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"qid", NULL}; - qidarg_converter_data qidarg; + qidarg_converter_data qidarg = {0}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&:destroy", kwlist, qidarg_converter, &qidarg)) { return NULL; @@ -1579,7 +1579,7 @@ static PyObject * queuesmod_put(PyObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"qid", "obj", "fmt", "unboundop", NULL}; - qidarg_converter_data qidarg; + qidarg_converter_data qidarg = {0}; PyObject *obj; int fmt; int unboundop; @@ -1615,7 +1615,7 @@ static PyObject * queuesmod_get(PyObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"qid", NULL}; - qidarg_converter_data qidarg; + qidarg_converter_data qidarg = {0}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&:get", kwlist, qidarg_converter, &qidarg)) { return NULL; @@ -1651,7 +1651,7 @@ static PyObject * queuesmod_bind(PyObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"qid", NULL}; - qidarg_converter_data qidarg; + qidarg_converter_data qidarg = {0}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&:bind", kwlist, qidarg_converter, &qidarg)) { return NULL; @@ -1681,7 +1681,7 @@ queuesmod_release(PyObject *self, PyObject *args, PyObject *kwds) { // Note that only the current interpreter is affected. static char *kwlist[] = {"qid", NULL}; - qidarg_converter_data qidarg; + qidarg_converter_data qidarg = {0}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&:release", kwlist, qidarg_converter, &qidarg)) { @@ -1710,7 +1710,7 @@ static PyObject * queuesmod_get_maxsize(PyObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"qid", NULL}; - qidarg_converter_data qidarg; + qidarg_converter_data qidarg = {0}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&:get_maxsize", kwlist, qidarg_converter, &qidarg)) { @@ -1735,7 +1735,7 @@ static PyObject * queuesmod_get_queue_defaults(PyObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"qid", NULL}; - qidarg_converter_data qidarg; + qidarg_converter_data qidarg = {0}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&:get_queue_defaults", kwlist, qidarg_converter, &qidarg)) { @@ -1765,7 +1765,7 @@ static PyObject * queuesmod_is_full(PyObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"qid", NULL}; - qidarg_converter_data qidarg; + qidarg_converter_data qidarg = {0}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&:is_full", kwlist, qidarg_converter, &qidarg)) { @@ -1793,7 +1793,7 @@ static PyObject * queuesmod_get_count(PyObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"qid", NULL}; - qidarg_converter_data qidarg; + qidarg_converter_data qidarg = {0}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&:get_count", kwlist, qidarg_converter, &qidarg)) { From 77cebb1ce9baac9e01a45d34113c3bea74940d90 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Thu, 17 Oct 2024 17:29:11 -0700 Subject: [PATCH 131/170] gh-125600: Only show stale code warning on source code display commands (#125601) --- Lib/pdb.py | 24 +++++++++++++++---- Lib/test/test_pdb.py | 19 +++++++++++++++ ...-10-16-15-55-50.gh-issue-125600.yMsJx0.rst | 1 + 3 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-16-15-55-50.gh-issue-125600.yMsJx0.rst diff --git a/Lib/pdb.py b/Lib/pdb.py index 3e5e6088fdcc7e..cd7a7042fa6987 100644 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -402,6 +402,8 @@ def setup(self, f, tb): self.curframe = self.stack[self.curindex][0] self.set_convenience_variable(self.curframe, '_frame', self.curframe) + self._save_initial_file_mtime(self.curframe) + if self._chained_exceptions: self.set_convenience_variable( self.curframe, @@ -494,9 +496,21 @@ def _cmdloop(self): except KeyboardInterrupt: self.message('--KeyboardInterrupt--') + def _save_initial_file_mtime(self, frame): + """save the mtime of the all the files in the frame stack in the file mtime table + if they haven't been saved yet.""" + while frame: + filename = frame.f_code.co_filename + if filename not in self._file_mtime_table: + try: + self._file_mtime_table[filename] = os.path.getmtime(filename) + except Exception: + pass + frame = frame.f_back + def _validate_file_mtime(self): - """Check if the source file of the current frame has been modified since - the last time we saw it. If so, give a warning.""" + """Check if the source file of the current frame has been modified. + If so, give a warning and reset the modify time to current.""" try: filename = self.curframe.f_code.co_filename mtime = os.path.getmtime(filename) @@ -506,7 +520,7 @@ def _validate_file_mtime(self): mtime != self._file_mtime_table[filename]): self.message(f"*** WARNING: file '{filename}' was edited, " "running stale code until the program is rerun") - self._file_mtime_table[filename] = mtime + self._file_mtime_table[filename] = mtime # Called before loop, handles display expressions # Set up convenience variable containers @@ -836,7 +850,6 @@ def onecmd(self, line): a breakpoint command list definition. """ if not self.commands_defining: - self._validate_file_mtime() if line.startswith('_pdbcmd'): command, arg, line = self.parseline(line) if hasattr(self, command): @@ -980,6 +993,7 @@ def completedefault(self, text, line, begidx, endidx): def _pdbcmd_print_frame_status(self, arg): self.print_stack_trace(0) + self._validate_file_mtime() self._show_display() def _pdbcmd_silence_frame_status(self, arg): @@ -1861,6 +1875,7 @@ def do_list(self, arg): self.message('[EOF]') except KeyboardInterrupt: pass + self._validate_file_mtime() do_l = do_list def do_longlist(self, arg): @@ -1879,6 +1894,7 @@ def do_longlist(self, arg): self.error(err) return self._print_lines(lines, lineno, breaklist, self.curframe) + self._validate_file_mtime() do_ll = do_longlist def do_source(self, arg): diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 8136c591a33001..7e6f276d355a14 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -3711,6 +3711,25 @@ def test_file_modified_after_execution(self): self.assertIn("WARNING:", stdout) self.assertIn("was edited", stdout) + def test_file_modified_and_immediately_restarted(self): + script = """ + print("hello") + """ + + # the time.sleep is needed for low-resolution filesystems like HFS+ + commands = """ + filename = $_frame.f_code.co_filename + f = open(filename, "w") + f.write("print('goodbye')") + import time; time.sleep(1) + f.close() + restart + """ + + stdout, stderr = self.run_pdb_script(script, commands) + self.assertNotIn("WARNING:", stdout) + self.assertNotIn("was edited", stdout) + def test_file_modified_after_execution_with_multiple_instances(self): # the time.sleep is needed for low-resolution filesystems like HFS+ script = """ diff --git a/Misc/NEWS.d/next/Library/2024-10-16-15-55-50.gh-issue-125600.yMsJx0.rst b/Misc/NEWS.d/next/Library/2024-10-16-15-55-50.gh-issue-125600.yMsJx0.rst new file mode 100644 index 00000000000000..19bf4fbefb601b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-16-15-55-50.gh-issue-125600.yMsJx0.rst @@ -0,0 +1 @@ +Only show stale code warning in :mod:`pdb` when we display source code. From a0f5c8e6272a1fd5422892d773923b138e77ae5f Mon Sep 17 00:00:00 2001 From: Furkan Onder Date: Fri, 18 Oct 2024 05:08:34 +0300 Subject: [PATCH 132/170] gh-125620: Skip check_resource_tracker_death on NetBSD due to long wait for SIGKILL process termination (GH-125621) * Skip test_resource_tracker_sigkill on NetBSD --- Lib/test/_test_multiprocessing.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index a059a6b8340448..065fc27b770438 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -5761,6 +5761,8 @@ def test_resource_tracker_sigterm(self): # Catchable signal (ignored by semaphore tracker) self.check_resource_tracker_death(signal.SIGTERM, False) + @unittest.skipIf(sys.platform.startswith("netbsd"), + "gh-125620: Skip on NetBSD due to long wait for SIGKILL process termination.") def test_resource_tracker_sigkill(self): # Uncatchable signal. self.check_resource_tracker_death(signal.SIGKILL, True) From d358425e6968858e52908794d15f37e62abc74ec Mon Sep 17 00:00:00 2001 From: Nice Zombies Date: Fri, 18 Oct 2024 14:26:29 +0200 Subject: [PATCH 133/170] gh-125682: Reject non-ASCII digits in the Python implementation of JSON decoder (GH-125687) --- Lib/json/scanner.py | 2 +- Lib/test/test_json/test_decode.py | 6 ++++++ .../Library/2024-10-18-09-51-29.gh-issue-125682.vsj4cU.rst | 2 ++ 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-18-09-51-29.gh-issue-125682.vsj4cU.rst diff --git a/Lib/json/scanner.py b/Lib/json/scanner.py index 7a61cfc2d24dce..090897515fe2f3 100644 --- a/Lib/json/scanner.py +++ b/Lib/json/scanner.py @@ -9,7 +9,7 @@ __all__ = ['make_scanner'] NUMBER_RE = re.compile( - r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?', + r'(-?(?:0|[1-9][0-9]*))(\.[0-9]+)?([eE][-+]?[0-9]+)?', (re.VERBOSE | re.MULTILINE | re.DOTALL)) def py_make_scanner(context): diff --git a/Lib/test/test_json/test_decode.py b/Lib/test/test_json/test_decode.py index 79fb239b35d3f2..2250af964c022b 100644 --- a/Lib/test/test_json/test_decode.py +++ b/Lib/test/test_json/test_decode.py @@ -16,6 +16,12 @@ def test_float(self): self.assertIsInstance(rval, float) self.assertEqual(rval, 1.0) + def test_nonascii_digits_rejected(self): + # JSON specifies only ascii digits, see gh-125687 + for num in ["1\uff10", "0.\uff10", "0e\uff10"]: + with self.assertRaises(self.JSONDecodeError): + self.loads(num) + def test_bytes(self): self.assertEqual(self.loads(b"1"), 1) diff --git a/Misc/NEWS.d/next/Library/2024-10-18-09-51-29.gh-issue-125682.vsj4cU.rst b/Misc/NEWS.d/next/Library/2024-10-18-09-51-29.gh-issue-125682.vsj4cU.rst new file mode 100644 index 00000000000000..3eb2905ad8d810 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-18-09-51-29.gh-issue-125682.vsj4cU.rst @@ -0,0 +1,2 @@ +Reject non-ASCII digits in the Python implementation of :func:`json.loads` +conforming to the JSON specification. From df751363e386d1f77c5ba9515a5539902457d386 Mon Sep 17 00:00:00 2001 From: Nice Zombies Date: Fri, 18 Oct 2024 14:29:47 +0200 Subject: [PATCH 134/170] gh-125660: Reject invalid unicode escapes for Python implementation of JSON decoder (GH-125683) --- Lib/json/decoder.py | 9 +++++---- Lib/test/test_json/test_scanstring.py | 10 ++++++++++ .../2024-10-18-08-58-10.gh-issue-125660.sDdDqO.rst | 1 + 3 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-18-08-58-10.gh-issue-125660.sDdDqO.rst diff --git a/Lib/json/decoder.py b/Lib/json/decoder.py index d69a45d6793069..ff4bfcdcc407b9 100644 --- a/Lib/json/decoder.py +++ b/Lib/json/decoder.py @@ -50,17 +50,18 @@ def __reduce__(self): } +HEXDIGITS = re.compile(r'[0-9A-Fa-f]{4}', FLAGS) STRINGCHUNK = re.compile(r'(.*?)(["\\\x00-\x1f])', FLAGS) BACKSLASH = { '"': '"', '\\': '\\', '/': '/', 'b': '\b', 'f': '\f', 'n': '\n', 'r': '\r', 't': '\t', } -def _decode_uXXXX(s, pos): - esc = s[pos + 1:pos + 5] - if len(esc) == 4 and esc[1] not in 'xX': +def _decode_uXXXX(s, pos, _m=HEXDIGITS.match): + esc = _m(s, pos + 1) + if esc is not None: try: - return int(esc, 16) + return int(esc.group(), 16) except ValueError: pass msg = "Invalid \\uXXXX escape" diff --git a/Lib/test/test_json/test_scanstring.py b/Lib/test/test_json/test_scanstring.py index 2d3ee8a8bf0f92..cca556a3b95bab 100644 --- a/Lib/test/test_json/test_scanstring.py +++ b/Lib/test/test_json/test_scanstring.py @@ -116,6 +116,11 @@ def test_bad_escapes(self): '"\\u012z"', '"\\u0x12"', '"\\u0X12"', + '"\\u{0}"'.format("\uff10" * 4), + '"\\u 123"', + '"\\u-123"', + '"\\u+123"', + '"\\u1_23"', '"\\ud834\\"', '"\\ud834\\u"', '"\\ud834\\ud"', @@ -127,6 +132,11 @@ def test_bad_escapes(self): '"\\ud834\\udd2z"', '"\\ud834\\u0x20"', '"\\ud834\\u0X20"', + '"\\ud834\\u{0}"'.format("\uff10" * 4), + '"\\ud834\\u 123"', + '"\\ud834\\u-123"', + '"\\ud834\\u+123"', + '"\\ud834\\u1_23"', ] for s in bad_escapes: with self.assertRaises(self.JSONDecodeError, msg=s): diff --git a/Misc/NEWS.d/next/Library/2024-10-18-08-58-10.gh-issue-125660.sDdDqO.rst b/Misc/NEWS.d/next/Library/2024-10-18-08-58-10.gh-issue-125660.sDdDqO.rst new file mode 100644 index 00000000000000..74d76c7bddae7d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-18-08-58-10.gh-issue-125660.sDdDqO.rst @@ -0,0 +1 @@ +Reject invalid unicode escapes for Python implementation of :func:`json.loads`. From 10c4c95395771fb37e93811aaace42f026c16de5 Mon Sep 17 00:00:00 2001 From: "RUANG (Roy James)" Date: Fri, 18 Oct 2024 20:45:17 +0800 Subject: [PATCH 135/170] gh-123610: Added additional types to ctypes/wintypes.py (GH-124086) --- Lib/ctypes/wintypes.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Lib/ctypes/wintypes.py b/Lib/ctypes/wintypes.py index 9c4e721438aad5..4beba0d19513e2 100644 --- a/Lib/ctypes/wintypes.py +++ b/Lib/ctypes/wintypes.py @@ -63,10 +63,16 @@ def __repr__(self): HBITMAP = HANDLE HBRUSH = HANDLE HCOLORSPACE = HANDLE +HCONV = HANDLE +HCONVLIST = HANDLE +HCURSOR = HANDLE HDC = HANDLE +HDDEDATA = HANDLE HDESK = HANDLE +HDROP = HANDLE HDWP = HANDLE HENHMETAFILE = HANDLE +HFILE = INT HFONT = HANDLE HGDIOBJ = HANDLE HGLOBAL = HANDLE @@ -82,9 +88,11 @@ def __repr__(self): HMONITOR = HANDLE HPALETTE = HANDLE HPEN = HANDLE +HRESULT = LONG HRGN = HANDLE HRSRC = HANDLE HSTR = HANDLE +HSZ = HANDLE HTASK = HANDLE HWINSTA = HANDLE HWND = HANDLE From cda0ec8e7c4e9a010e5f73c5afaf18f86cb27b97 Mon Sep 17 00:00:00 2001 From: Wulian Date: Fri, 18 Oct 2024 20:48:18 +0800 Subject: [PATCH 136/170] gh-124102: Clean up unsupported VS and WiX detections (GH-124784) --- PCbuild/pyproject.props | 5 ----- Tools/msi/README.txt | 20 +++++++++++--------- Tools/msi/wix.props | 2 -- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/PCbuild/pyproject.props b/PCbuild/pyproject.props index 9c85e5efa4af4a..c65341179376ea 100644 --- a/PCbuild/pyproject.props +++ b/PCbuild/pyproject.props @@ -217,11 +217,6 @@ public override bool Execute() { - - - $(VCInstallDir)\redist\ - - <_RedistFiles Include="$(VCInstallDir)\Redist\MSVC\*\*.*" /> diff --git a/Tools/msi/README.txt b/Tools/msi/README.txt index 98e5ba039d2bcd..8ae156450d5240 100644 --- a/Tools/msi/README.txt +++ b/Tools/msi/README.txt @@ -61,18 +61,20 @@ the initial download size by separating them into their own MSIs. Building the Installer ====================== -Before building the installer, download extra build dependencies using -Tools\msi\get_externals.bat. (Note that this is in addition to the +Before building the installer, download the extra build dependencies +using Tools\msi\get_externals.bat. (Note that this is in addition to the similarly named file in PCbuild.) -One of the dependencies used in builds is WiX, a toolset that lets developers -create installers for Windows Installer, the Windows installation engine. +One of the dependencies used in the build process is WiX, a toolset that +allows developers to create installers for Windows Installer, the +Windows installation engine. If you're not using the copy of WiX +installed by Tools\msi\get_externals.bat, you'll need to set the +"WixInstallPath" environment variable before building. -Additionally, make sure "MSVC v14x - VS 20xx C++ ARM64 build tools" are -selected under "Desktop Development with C++" in "Visual Studio installer", -even if you are not building on ARM64. This is required because we have -upgraded to WiX-3.14, which requires these tools for Python 3.11 and later -versions. +Additionally, ensure that "MSVC v14x - VS 20xx C++ ARM64/ARM64EC build tools" +is selected under "Desktop Development with C++" in the "Visual Studio Installer", +even if you're not building on ARM64. This is required because we've upgraded +to WiX 3.14, which requires these tools for Python 3.10 and later versions. For testing, the installer should be built with the Tools/msi/build.bat script: diff --git a/Tools/msi/wix.props b/Tools/msi/wix.props index d8ced317d0ce81..707c8aeacb648d 100644 --- a/Tools/msi/wix.props +++ b/Tools/msi/wix.props @@ -5,8 +5,6 @@ $(MSBuildThisFileDirectory)\Wix\ $(ExternalsDir)\windows-installer\wix-314\ - $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Installer XML\3.10@InstallRoot) - $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows Installer XML\3.10@InstallRoot) $(WixInstallPath)\Wix.targets \ No newline at end of file From 2e950e341930ea79549137d4d3771d5edb940e65 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 18 Oct 2024 16:51:29 +0300 Subject: [PATCH 137/170] Add tests for time.strftime() with invalid format string (GH-125696) --- Lib/test/test_time.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py index f8b99a9b6a63f5..d368f08b610870 100644 --- a/Lib/test/test_time.py +++ b/Lib/test/test_time.py @@ -18,7 +18,7 @@ except ImportError: _testinternalcapi = None -from test.support import skip_if_buggy_ucrt_strfptime +from test.support import skip_if_buggy_ucrt_strfptime, SuppressCrashReport # Max year is only limited by the size of C int. SIZEOF_INT = sysconfig.get_config_var('SIZEOF_INT') or 4 @@ -182,6 +182,17 @@ def test_strftime(self): self.assertRaises(TypeError, time.strftime, b'%S', tt) + def test_strftime_invalid_format(self): + tt = time.gmtime(self.t) + with SuppressCrashReport(): + for i in range(1, 128): + format = ' %' + chr(i) + with self.subTest(format=format): + try: + time.strftime(format, tt) + except ValueError as exc: + self.assertEqual(str(exc), 'Invalid format string') + def test_strftime_special(self): tt = time.gmtime(self.t) s1 = time.strftime('%c', tt) From 6d93690954daae9e9a368084765a4005f957686d Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Fri, 18 Oct 2024 09:26:08 -0600 Subject: [PATCH 138/170] gh-125604: Move _Py_AuditHookEntry, etc. Out of pycore_runtime.h (gh-125605) This is essentially a cleanup, moving a handful of API declarations to the header files where they fit best, creating new ones when needed. We do the following: * add pycore_debug_offsets.h and move _Py_DebugOffsets, etc. there * inline struct _getargs_runtime_state and struct _gilstate_runtime_state in _PyRuntimeState * move struct _reftracer_runtime_state to the existing pycore_object_state.h * add pycore_audit.h and move to it _Py_AuditHookEntry , _PySys_Audit(), and _PySys_ClearAuditHooks * add audit.h and cpython/audit.h and move the existing audit-related API there *move the perfmap/trampoline API from cpython/sysmodule.h to cpython/ceval.h, and remove the now-empty cpython/sysmodule.h --- Include/Python.h | 1 + Include/audit.h | 30 +++ Include/cpython/audit.h | 8 + Include/cpython/ceval.h | 18 ++ Include/cpython/sysmodule.h | 22 -- Include/internal/pycore_audit.h | 35 +++ Include/internal/pycore_debug_offsets.h | 269 ++++++++++++++++++++++++ Include/internal/pycore_object_state.h | 8 + Include/internal/pycore_runtime.h | 197 ++--------------- Include/internal/pycore_runtime_init.h | 107 +--------- Include/internal/pycore_sysmodule.h | 10 - Include/sysmodule.h | 17 -- Makefile.pre.in | 5 +- Modules/_testexternalinspection.c | 4 +- Objects/object.c | 1 + PCbuild/pythoncore.vcxproj | 5 +- PCbuild/pythoncore.vcxproj.filters | 15 +- Python/bytecodes.c | 2 +- Python/ceval.c | 2 +- Python/errors.c | 3 +- Python/import.c | 3 +- Python/legacy_tracing.c | 2 +- Python/pylifecycle.c | 5 +- Python/pystate.c | 2 +- Python/pythonrun.c | 3 +- Python/sysmodule.c | 1 + 26 files changed, 429 insertions(+), 346 deletions(-) create mode 100644 Include/audit.h create mode 100644 Include/cpython/audit.h delete mode 100644 Include/cpython/sysmodule.h create mode 100644 Include/internal/pycore_audit.h create mode 100644 Include/internal/pycore_debug_offsets.h diff --git a/Include/Python.h b/Include/Python.h index e1abdd16f031fb..717e27feab62db 100644 --- a/Include/Python.h +++ b/Include/Python.h @@ -124,6 +124,7 @@ #include "pylifecycle.h" #include "ceval.h" #include "sysmodule.h" +#include "audit.h" #include "osmodule.h" #include "intrcheck.h" #include "import.h" diff --git a/Include/audit.h b/Include/audit.h new file mode 100644 index 00000000000000..793b7077e1027b --- /dev/null +++ b/Include/audit.h @@ -0,0 +1,30 @@ +#ifndef Py_AUDIT_H +#define Py_AUDIT_H +#ifdef __cplusplus +extern "C" { +#endif + + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030d0000 +PyAPI_FUNC(int) PySys_Audit( + const char *event, + const char *argFormat, + ...); + +PyAPI_FUNC(int) PySys_AuditTuple( + const char *event, + PyObject *args); +#endif + + +#ifndef Py_LIMITED_API +# define Py_CPYTHON_AUDIT_H +# include "cpython/audit.h" +# undef Py_CPYTHON_AUDIT_H +#endif + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_AUDIT_H */ diff --git a/Include/cpython/audit.h b/Include/cpython/audit.h new file mode 100644 index 00000000000000..3c5c7a8c06091d --- /dev/null +++ b/Include/cpython/audit.h @@ -0,0 +1,8 @@ +#ifndef Py_CPYTHON_AUDIT_H +# error "this header file must not be included directly" +#endif + + +typedef int(*Py_AuditHookFunction)(const char *, PyObject *, void *); + +PyAPI_FUNC(int) PySys_AddAuditHook(Py_AuditHookFunction, void*); diff --git a/Include/cpython/ceval.h b/Include/cpython/ceval.h index 78f7405661662f..ca8109e3248a8d 100644 --- a/Include/cpython/ceval.h +++ b/Include/cpython/ceval.h @@ -23,3 +23,21 @@ _PyEval_RequestCodeExtraIndex(freefunc f) { PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *); PyAPI_FUNC(int) _PyEval_SliceIndexNotNone(PyObject *, Py_ssize_t *); + + +// Trampoline API + +typedef struct { + FILE* perf_map; + PyThread_type_lock map_lock; +} PerfMapState; + +PyAPI_FUNC(int) PyUnstable_PerfMapState_Init(void); +PyAPI_FUNC(int) PyUnstable_WritePerfMapEntry( + const void *code_addr, + unsigned int code_size, + const char *entry_name); +PyAPI_FUNC(void) PyUnstable_PerfMapState_Fini(void); +PyAPI_FUNC(int) PyUnstable_CopyPerfMapFile(const char* parent_filename); +PyAPI_FUNC(int) PyUnstable_PerfTrampoline_CompileCode(PyCodeObject *); +PyAPI_FUNC(int) PyUnstable_PerfTrampoline_SetPersistAfterFork(int enable); diff --git a/Include/cpython/sysmodule.h b/Include/cpython/sysmodule.h deleted file mode 100644 index a3ac07f538a94f..00000000000000 --- a/Include/cpython/sysmodule.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef Py_CPYTHON_SYSMODULE_H -# error "this header file must not be included directly" -#endif - -typedef int(*Py_AuditHookFunction)(const char *, PyObject *, void *); - -PyAPI_FUNC(int) PySys_AddAuditHook(Py_AuditHookFunction, void*); - -typedef struct { - FILE* perf_map; - PyThread_type_lock map_lock; -} PerfMapState; - -PyAPI_FUNC(int) PyUnstable_PerfMapState_Init(void); -PyAPI_FUNC(int) PyUnstable_WritePerfMapEntry( - const void *code_addr, - unsigned int code_size, - const char *entry_name); -PyAPI_FUNC(void) PyUnstable_PerfMapState_Fini(void); -PyAPI_FUNC(int) PyUnstable_CopyPerfMapFile(const char* parent_filename); -PyAPI_FUNC(int) PyUnstable_PerfTrampoline_CompileCode(PyCodeObject *); -PyAPI_FUNC(int) PyUnstable_PerfTrampoline_SetPersistAfterFork(int enable); diff --git a/Include/internal/pycore_audit.h b/Include/internal/pycore_audit.h new file mode 100644 index 00000000000000..2811aaa6236123 --- /dev/null +++ b/Include/internal/pycore_audit.h @@ -0,0 +1,35 @@ +#ifndef Py_INTERNAL_AUDIT_H +#define Py_INTERNAL_AUDIT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + + +/* Runtime audit hook state */ + +typedef struct _Py_AuditHookEntry { + struct _Py_AuditHookEntry *next; + Py_AuditHookFunction hookCFunction; + void *userData; +} _Py_AuditHookEntry; + + +extern int _PySys_Audit( + PyThreadState *tstate, + const char *event, + const char *argFormat, + ...); + +// _PySys_ClearAuditHooks() must not be exported: use extern rather than +// PyAPI_FUNC(). We want minimal exposure of this function. +extern void _PySys_ClearAuditHooks(PyThreadState *tstate); + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_AUDIT_H */ diff --git a/Include/internal/pycore_debug_offsets.h b/Include/internal/pycore_debug_offsets.h new file mode 100644 index 00000000000000..184f4b9360b6d3 --- /dev/null +++ b/Include/internal/pycore_debug_offsets.h @@ -0,0 +1,269 @@ +#ifndef Py_INTERNAL_DEBUG_OFFSETS_H +#define Py_INTERNAL_DEBUG_OFFSETS_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + + +#define _Py_Debug_Cookie "xdebugpy" + +#ifdef Py_GIL_DISABLED +# define _Py_Debug_gilruntimestate_enabled offsetof(struct _gil_runtime_state, enabled) +# define _Py_Debug_Free_Threaded 1 +#else +# define _Py_Debug_gilruntimestate_enabled 0 +# define _Py_Debug_Free_Threaded 0 +#endif + + +typedef struct _Py_DebugOffsets { + char cookie[8]; + uint64_t version; + uint64_t free_threaded; + // Runtime state offset; + struct _runtime_state { + uint64_t size; + uint64_t finalizing; + uint64_t interpreters_head; + } runtime_state; + + // Interpreter state offset; + struct _interpreter_state { + uint64_t size; + uint64_t id; + uint64_t next; + uint64_t threads_head; + uint64_t gc; + uint64_t imports_modules; + uint64_t sysdict; + uint64_t builtins; + uint64_t ceval_gil; + uint64_t gil_runtime_state; + uint64_t gil_runtime_state_enabled; + uint64_t gil_runtime_state_locked; + uint64_t gil_runtime_state_holder; + } interpreter_state; + + // Thread state offset; + struct _thread_state{ + uint64_t size; + uint64_t prev; + uint64_t next; + uint64_t interp; + uint64_t current_frame; + uint64_t thread_id; + uint64_t native_thread_id; + uint64_t datastack_chunk; + uint64_t status; + } thread_state; + + // InterpreterFrame offset; + struct _interpreter_frame { + uint64_t size; + uint64_t previous; + uint64_t executable; + uint64_t instr_ptr; + uint64_t localsplus; + uint64_t owner; + } interpreter_frame; + + // Code object offset; + struct _code_object { + uint64_t size; + uint64_t filename; + uint64_t name; + uint64_t qualname; + uint64_t linetable; + uint64_t firstlineno; + uint64_t argcount; + uint64_t localsplusnames; + uint64_t localspluskinds; + uint64_t co_code_adaptive; + } code_object; + + // PyObject offset; + struct _pyobject { + uint64_t size; + uint64_t ob_type; + } pyobject; + + // PyTypeObject object offset; + struct _type_object { + uint64_t size; + uint64_t tp_name; + uint64_t tp_repr; + uint64_t tp_flags; + } type_object; + + // PyTuple object offset; + struct _tuple_object { + uint64_t size; + uint64_t ob_item; + uint64_t ob_size; + } tuple_object; + + // PyList object offset; + struct _list_object { + uint64_t size; + uint64_t ob_item; + uint64_t ob_size; + } list_object; + + // PyDict object offset; + struct _dict_object { + uint64_t size; + uint64_t ma_keys; + uint64_t ma_values; + } dict_object; + + // PyFloat object offset; + struct _float_object { + uint64_t size; + uint64_t ob_fval; + } float_object; + + // PyLong object offset; + struct _long_object { + uint64_t size; + uint64_t lv_tag; + uint64_t ob_digit; + } long_object; + + // PyBytes object offset; + struct _bytes_object { + uint64_t size; + uint64_t ob_size; + uint64_t ob_sval; + } bytes_object; + + // Unicode object offset; + struct _unicode_object { + uint64_t size; + uint64_t state; + uint64_t length; + uint64_t asciiobject_size; + } unicode_object; + + // GC runtime state offset; + struct _gc { + uint64_t size; + uint64_t collecting; + } gc; +} _Py_DebugOffsets; + + +#define _Py_DebugOffsets_INIT(debug_cookie) { \ + .cookie = debug_cookie, \ + .version = PY_VERSION_HEX, \ + .free_threaded = _Py_Debug_Free_Threaded, \ + .runtime_state = { \ + .size = sizeof(_PyRuntimeState), \ + .finalizing = offsetof(_PyRuntimeState, _finalizing), \ + .interpreters_head = offsetof(_PyRuntimeState, interpreters.head), \ + }, \ + .interpreter_state = { \ + .size = sizeof(PyInterpreterState), \ + .id = offsetof(PyInterpreterState, id), \ + .next = offsetof(PyInterpreterState, next), \ + .threads_head = offsetof(PyInterpreterState, threads.head), \ + .gc = offsetof(PyInterpreterState, gc), \ + .imports_modules = offsetof(PyInterpreterState, imports.modules), \ + .sysdict = offsetof(PyInterpreterState, sysdict), \ + .builtins = offsetof(PyInterpreterState, builtins), \ + .ceval_gil = offsetof(PyInterpreterState, ceval.gil), \ + .gil_runtime_state = offsetof(PyInterpreterState, _gil), \ + .gil_runtime_state_enabled = _Py_Debug_gilruntimestate_enabled, \ + .gil_runtime_state_locked = offsetof(PyInterpreterState, _gil.locked), \ + .gil_runtime_state_holder = offsetof(PyInterpreterState, _gil.last_holder), \ + }, \ + .thread_state = { \ + .size = sizeof(PyThreadState), \ + .prev = offsetof(PyThreadState, prev), \ + .next = offsetof(PyThreadState, next), \ + .interp = offsetof(PyThreadState, interp), \ + .current_frame = offsetof(PyThreadState, current_frame), \ + .thread_id = offsetof(PyThreadState, thread_id), \ + .native_thread_id = offsetof(PyThreadState, native_thread_id), \ + .datastack_chunk = offsetof(PyThreadState, datastack_chunk), \ + .status = offsetof(PyThreadState, _status), \ + }, \ + .interpreter_frame = { \ + .size = sizeof(_PyInterpreterFrame), \ + .previous = offsetof(_PyInterpreterFrame, previous), \ + .executable = offsetof(_PyInterpreterFrame, f_executable), \ + .instr_ptr = offsetof(_PyInterpreterFrame, instr_ptr), \ + .localsplus = offsetof(_PyInterpreterFrame, localsplus), \ + .owner = offsetof(_PyInterpreterFrame, owner), \ + }, \ + .code_object = { \ + .size = sizeof(PyCodeObject), \ + .filename = offsetof(PyCodeObject, co_filename), \ + .name = offsetof(PyCodeObject, co_name), \ + .qualname = offsetof(PyCodeObject, co_qualname), \ + .linetable = offsetof(PyCodeObject, co_linetable), \ + .firstlineno = offsetof(PyCodeObject, co_firstlineno), \ + .argcount = offsetof(PyCodeObject, co_argcount), \ + .localsplusnames = offsetof(PyCodeObject, co_localsplusnames), \ + .localspluskinds = offsetof(PyCodeObject, co_localspluskinds), \ + .co_code_adaptive = offsetof(PyCodeObject, co_code_adaptive), \ + }, \ + .pyobject = { \ + .size = sizeof(PyObject), \ + .ob_type = offsetof(PyObject, ob_type), \ + }, \ + .type_object = { \ + .size = sizeof(PyTypeObject), \ + .tp_name = offsetof(PyTypeObject, tp_name), \ + .tp_repr = offsetof(PyTypeObject, tp_repr), \ + .tp_flags = offsetof(PyTypeObject, tp_flags), \ + }, \ + .tuple_object = { \ + .size = sizeof(PyTupleObject), \ + .ob_item = offsetof(PyTupleObject, ob_item), \ + .ob_size = offsetof(PyTupleObject, ob_base.ob_size), \ + }, \ + .list_object = { \ + .size = sizeof(PyListObject), \ + .ob_item = offsetof(PyListObject, ob_item), \ + .ob_size = offsetof(PyListObject, ob_base.ob_size), \ + }, \ + .dict_object = { \ + .size = sizeof(PyDictObject), \ + .ma_keys = offsetof(PyDictObject, ma_keys), \ + .ma_values = offsetof(PyDictObject, ma_values), \ + }, \ + .float_object = { \ + .size = sizeof(PyFloatObject), \ + .ob_fval = offsetof(PyFloatObject, ob_fval), \ + }, \ + .long_object = { \ + .size = sizeof(PyLongObject), \ + .lv_tag = offsetof(PyLongObject, long_value.lv_tag), \ + .ob_digit = offsetof(PyLongObject, long_value.ob_digit), \ + }, \ + .bytes_object = { \ + .size = sizeof(PyBytesObject), \ + .ob_size = offsetof(PyBytesObject, ob_base.ob_size), \ + .ob_sval = offsetof(PyBytesObject, ob_sval), \ + }, \ + .unicode_object = { \ + .size = sizeof(PyUnicodeObject), \ + .state = offsetof(PyUnicodeObject, _base._base.state), \ + .length = offsetof(PyUnicodeObject, _base._base.length), \ + .asciiobject_size = sizeof(PyASCIIObject), \ + }, \ + .gc = { \ + .size = sizeof(struct _gc_runtime_state), \ + .collecting = offsetof(struct _gc_runtime_state, collecting), \ + }, \ +} + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_DEBUG_OFFSETS_H */ diff --git a/Include/internal/pycore_object_state.h b/Include/internal/pycore_object_state.h index e7fa7c1f10d6d1..8a47a6d9e6eb0d 100644 --- a/Include/internal/pycore_object_state.h +++ b/Include/internal/pycore_object_state.h @@ -11,6 +11,14 @@ extern "C" { #include "pycore_freelist_state.h" // _Py_freelists #include "pycore_hashtable.h" // _Py_hashtable_t + +/* Reference tracer state */ +struct _reftracer_runtime_state { + PyRefTracer tracer_func; + void* tracer_data; +}; + + struct _py_object_runtime_state { #ifdef Py_REF_DEBUG Py_ssize_t interpreter_leaks; diff --git a/Include/internal/pycore_runtime.h b/Include/internal/pycore_runtime.h index d4291b87261ae0..7f592aa6cf9f05 100644 --- a/Include/internal/pycore_runtime.h +++ b/Include/internal/pycore_runtime.h @@ -9,8 +9,10 @@ extern "C" { #endif #include "pycore_atexit.h" // struct _atexit_runtime_state +#include "pycore_audit.h" // _Py_AuditHookEntry #include "pycore_ceval_state.h" // struct _ceval_runtime_state -#include "pycore_crossinterp.h" // struct _xidregistry +#include "pycore_crossinterp.h" // struct _xidregistry +#include "pycore_debug_offsets.h" // _Py_DebugOffsets #include "pycore_faulthandler.h" // struct _faulthandler_runtime_state #include "pycore_floatobject.h" // struct _Py_float_runtime_state #include "pycore_import.h" // struct _import_runtime_state @@ -25,185 +27,12 @@ extern "C" { #include "pycore_typeobject.h" // struct _types_runtime_state #include "pycore_unicodeobject.h" // struct _Py_unicode_runtime_state -struct _getargs_runtime_state { - struct _PyArg_Parser *static_parsers; -}; - -/* GIL state */ - -struct _gilstate_runtime_state { - /* bpo-26558: Flag to disable PyGILState_Check(). - If set to non-zero, PyGILState_Check() always return 1. */ - int check_enabled; - /* The single PyInterpreterState used by this process' - GILState implementation - */ - /* TODO: Given interp_main, it may be possible to kill this ref */ - PyInterpreterState *autoInterpreterState; -}; - -/* Runtime audit hook state */ - -#define _Py_Debug_Cookie "xdebugpy" - -#ifdef Py_GIL_DISABLED -# define _Py_Debug_gilruntimestate_enabled offsetof(struct _gil_runtime_state, enabled) -# define _Py_Debug_Free_Threaded 1 -#else -# define _Py_Debug_gilruntimestate_enabled 0 -# define _Py_Debug_Free_Threaded 0 -#endif -typedef struct _Py_AuditHookEntry { - struct _Py_AuditHookEntry *next; - Py_AuditHookFunction hookCFunction; - void *userData; -} _Py_AuditHookEntry; - -typedef struct _Py_DebugOffsets { - char cookie[8]; - uint64_t version; - uint64_t free_threaded; - // Runtime state offset; - struct _runtime_state { - uint64_t size; - uint64_t finalizing; - uint64_t interpreters_head; - } runtime_state; - - // Interpreter state offset; - struct _interpreter_state { - uint64_t size; - uint64_t id; - uint64_t next; - uint64_t threads_head; - uint64_t gc; - uint64_t imports_modules; - uint64_t sysdict; - uint64_t builtins; - uint64_t ceval_gil; - uint64_t gil_runtime_state; - uint64_t gil_runtime_state_enabled; - uint64_t gil_runtime_state_locked; - uint64_t gil_runtime_state_holder; - } interpreter_state; - - // Thread state offset; - struct _thread_state{ - uint64_t size; - uint64_t prev; - uint64_t next; - uint64_t interp; - uint64_t current_frame; - uint64_t thread_id; - uint64_t native_thread_id; - uint64_t datastack_chunk; - uint64_t status; - } thread_state; - - // InterpreterFrame offset; - struct _interpreter_frame { - uint64_t size; - uint64_t previous; - uint64_t executable; - uint64_t instr_ptr; - uint64_t localsplus; - uint64_t owner; - } interpreter_frame; - - // Code object offset; - struct _code_object { - uint64_t size; - uint64_t filename; - uint64_t name; - uint64_t qualname; - uint64_t linetable; - uint64_t firstlineno; - uint64_t argcount; - uint64_t localsplusnames; - uint64_t localspluskinds; - uint64_t co_code_adaptive; - } code_object; - - // PyObject offset; - struct _pyobject { - uint64_t size; - uint64_t ob_type; - } pyobject; - - // PyTypeObject object offset; - struct _type_object { - uint64_t size; - uint64_t tp_name; - uint64_t tp_repr; - uint64_t tp_flags; - } type_object; - - // PyTuple object offset; - struct _tuple_object { - uint64_t size; - uint64_t ob_item; - uint64_t ob_size; - } tuple_object; - - // PyList object offset; - struct _list_object { - uint64_t size; - uint64_t ob_item; - uint64_t ob_size; - } list_object; - - // PyDict object offset; - struct _dict_object { - uint64_t size; - uint64_t ma_keys; - uint64_t ma_values; - } dict_object; - - // PyFloat object offset; - struct _float_object { - uint64_t size; - uint64_t ob_fval; - } float_object; - - // PyLong object offset; - struct _long_object { - uint64_t size; - uint64_t lv_tag; - uint64_t ob_digit; - } long_object; - - // PyBytes object offset; - struct _bytes_object { - uint64_t size; - uint64_t ob_size; - uint64_t ob_sval; - } bytes_object; - - // Unicode object offset; - struct _unicode_object { - uint64_t size; - uint64_t state; - uint64_t length; - uint64_t asciiobject_size; - } unicode_object; - - // GC runtime state offset; - struct _gc { - uint64_t size; - uint64_t collecting; - } gc; -} _Py_DebugOffsets; - -/* Reference tracer state */ -struct _reftracer_runtime_state { - PyRefTracer tracer_func; - void* tracer_data; -}; /* Full Python runtime state */ /* _PyRuntimeState holds the global state for the CPython runtime. - That data is exposed in the internal API as a static variable (_PyRuntime). + That data is exported by the internal API as a global variable + (_PyRuntime, defined near the top of pylifecycle.c). */ typedef struct pyruntimestate { /* This field must be first to facilitate locating it by out of process @@ -299,8 +128,19 @@ typedef struct pyruntimestate { struct _import_runtime_state imports; struct _ceval_runtime_state ceval; - struct _gilstate_runtime_state gilstate; - struct _getargs_runtime_state getargs; + struct _gilstate_runtime_state { + /* bpo-26558: Flag to disable PyGILState_Check(). + If set to non-zero, PyGILState_Check() always return 1. */ + int check_enabled; + /* The single PyInterpreterState used by this process' + GILState implementation + */ + /* TODO: Given interp_main, it may be possible to kill this ref */ + PyInterpreterState *autoInterpreterState; + } gilstate; + struct _getargs_runtime_state { + struct _PyArg_Parser *static_parsers; + } getargs; struct _fileutils_state fileutils; struct _faulthandler_runtime_state faulthandler; struct _tracemalloc_runtime_state tracemalloc; @@ -404,6 +244,7 @@ _PyRuntimeState_SetFinalizing(_PyRuntimeState *runtime, PyThreadState *tstate) { } } + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h index a17ba46966daa1..e99febab2f3d57 100644 --- a/Include/internal/pycore_runtime_init.h +++ b/Include/internal/pycore_runtime_init.h @@ -9,6 +9,7 @@ extern "C" { #endif #include "pycore_ceval_state.h" // _PyEval_RUNTIME_PERF_INIT +#include "pycore_debug_offsets.h" // _Py_DebugOffsets_INIT() #include "pycore_faulthandler.h" // _faulthandler_runtime_state_INIT #include "pycore_floatobject.h" // _py_float_format_unknown #include "pycore_function.h" @@ -32,111 +33,7 @@ extern PyTypeObject _PyExc_MemoryError; #define _PyRuntimeState_INIT(runtime, debug_cookie) \ { \ - .debug_offsets = { \ - .cookie = debug_cookie, \ - .version = PY_VERSION_HEX, \ - .free_threaded = _Py_Debug_Free_Threaded, \ - .runtime_state = { \ - .size = sizeof(_PyRuntimeState), \ - .finalizing = offsetof(_PyRuntimeState, _finalizing), \ - .interpreters_head = offsetof(_PyRuntimeState, interpreters.head), \ - }, \ - .interpreter_state = { \ - .size = sizeof(PyInterpreterState), \ - .id = offsetof(PyInterpreterState, id), \ - .next = offsetof(PyInterpreterState, next), \ - .threads_head = offsetof(PyInterpreterState, threads.head), \ - .gc = offsetof(PyInterpreterState, gc), \ - .imports_modules = offsetof(PyInterpreterState, imports.modules), \ - .sysdict = offsetof(PyInterpreterState, sysdict), \ - .builtins = offsetof(PyInterpreterState, builtins), \ - .ceval_gil = offsetof(PyInterpreterState, ceval.gil), \ - .gil_runtime_state = offsetof(PyInterpreterState, _gil), \ - .gil_runtime_state_enabled = _Py_Debug_gilruntimestate_enabled, \ - .gil_runtime_state_locked = offsetof(PyInterpreterState, _gil.locked), \ - .gil_runtime_state_holder = offsetof(PyInterpreterState, _gil.last_holder), \ - }, \ - .thread_state = { \ - .size = sizeof(PyThreadState), \ - .prev = offsetof(PyThreadState, prev), \ - .next = offsetof(PyThreadState, next), \ - .interp = offsetof(PyThreadState, interp), \ - .current_frame = offsetof(PyThreadState, current_frame), \ - .thread_id = offsetof(PyThreadState, thread_id), \ - .native_thread_id = offsetof(PyThreadState, native_thread_id), \ - .datastack_chunk = offsetof(PyThreadState, datastack_chunk), \ - .status = offsetof(PyThreadState, _status), \ - }, \ - .interpreter_frame = { \ - .size = sizeof(_PyInterpreterFrame), \ - .previous = offsetof(_PyInterpreterFrame, previous), \ - .executable = offsetof(_PyInterpreterFrame, f_executable), \ - .instr_ptr = offsetof(_PyInterpreterFrame, instr_ptr), \ - .localsplus = offsetof(_PyInterpreterFrame, localsplus), \ - .owner = offsetof(_PyInterpreterFrame, owner), \ - }, \ - .code_object = { \ - .size = sizeof(PyCodeObject), \ - .filename = offsetof(PyCodeObject, co_filename), \ - .name = offsetof(PyCodeObject, co_name), \ - .qualname = offsetof(PyCodeObject, co_qualname), \ - .linetable = offsetof(PyCodeObject, co_linetable), \ - .firstlineno = offsetof(PyCodeObject, co_firstlineno), \ - .argcount = offsetof(PyCodeObject, co_argcount), \ - .localsplusnames = offsetof(PyCodeObject, co_localsplusnames), \ - .localspluskinds = offsetof(PyCodeObject, co_localspluskinds), \ - .co_code_adaptive = offsetof(PyCodeObject, co_code_adaptive), \ - }, \ - .pyobject = { \ - .size = sizeof(PyObject), \ - .ob_type = offsetof(PyObject, ob_type), \ - }, \ - .type_object = { \ - .size = sizeof(PyTypeObject), \ - .tp_name = offsetof(PyTypeObject, tp_name), \ - .tp_repr = offsetof(PyTypeObject, tp_repr), \ - .tp_flags = offsetof(PyTypeObject, tp_flags), \ - }, \ - .tuple_object = { \ - .size = sizeof(PyTupleObject), \ - .ob_item = offsetof(PyTupleObject, ob_item), \ - .ob_size = offsetof(PyTupleObject, ob_base.ob_size), \ - }, \ - .list_object = { \ - .size = sizeof(PyListObject), \ - .ob_item = offsetof(PyListObject, ob_item), \ - .ob_size = offsetof(PyListObject, ob_base.ob_size), \ - }, \ - .dict_object = { \ - .size = sizeof(PyDictObject), \ - .ma_keys = offsetof(PyDictObject, ma_keys), \ - .ma_values = offsetof(PyDictObject, ma_values), \ - }, \ - .float_object = { \ - .size = sizeof(PyFloatObject), \ - .ob_fval = offsetof(PyFloatObject, ob_fval), \ - }, \ - .long_object = { \ - .size = sizeof(PyLongObject), \ - .lv_tag = offsetof(PyLongObject, long_value.lv_tag), \ - .ob_digit = offsetof(PyLongObject, long_value.ob_digit), \ - }, \ - .bytes_object = { \ - .size = sizeof(PyBytesObject), \ - .ob_size = offsetof(PyBytesObject, ob_base.ob_size), \ - .ob_sval = offsetof(PyBytesObject, ob_sval), \ - }, \ - .unicode_object = { \ - .size = sizeof(PyUnicodeObject), \ - .state = offsetof(PyUnicodeObject, _base._base.state), \ - .length = offsetof(PyUnicodeObject, _base._base.length), \ - .asciiobject_size = sizeof(PyASCIIObject), \ - }, \ - .gc = { \ - .size = sizeof(struct _gc_runtime_state), \ - .collecting = offsetof(struct _gc_runtime_state, collecting), \ - }, \ - }, \ + .debug_offsets = _Py_DebugOffsets_INIT(debug_cookie), \ .allocators = { \ .standard = _pymem_allocators_standard_INIT(runtime), \ .debug = _pymem_allocators_debug_INIT, \ diff --git a/Include/internal/pycore_sysmodule.h b/Include/internal/pycore_sysmodule.h index a1d795e284f6ac..99968df54a45f6 100644 --- a/Include/internal/pycore_sysmodule.h +++ b/Include/internal/pycore_sysmodule.h @@ -14,16 +14,6 @@ PyAPI_FUNC(PyObject*) _PySys_GetAttr(PyThreadState *tstate, PyObject *name); // Export for '_pickle' shared extension PyAPI_FUNC(size_t) _PySys_GetSizeOf(PyObject *); -extern int _PySys_Audit( - PyThreadState *tstate, - const char *event, - const char *argFormat, - ...); - -// _PySys_ClearAuditHooks() must not be exported: use extern rather than -// PyAPI_FUNC(). We want minimal exposure of this function. -extern void _PySys_ClearAuditHooks(PyThreadState *tstate); - extern int _PySys_SetAttr(PyObject *, PyObject *); extern int _PySys_ClearAttrString(PyInterpreterState *interp, diff --git a/Include/sysmodule.h b/Include/sysmodule.h index 5a0af2e1578eb7..c1d5f610fe08a5 100644 --- a/Include/sysmodule.h +++ b/Include/sysmodule.h @@ -21,23 +21,6 @@ Py_DEPRECATED(3.13) PyAPI_FUNC(void) PySys_ResetWarnOptions(void); PyAPI_FUNC(PyObject *) PySys_GetXOptions(void); -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030d0000 -PyAPI_FUNC(int) PySys_Audit( - const char *event, - const char *argFormat, - ...); - -PyAPI_FUNC(int) PySys_AuditTuple( - const char *event, - PyObject *args); -#endif - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_SYSMODULE_H -# include "cpython/sysmodule.h" -# undef Py_CPYTHON_SYSMODULE_H -#endif - #ifdef __cplusplus } #endif diff --git a/Makefile.pre.in b/Makefile.pre.in index 07c8a4d20142db..fb6f22d57397db 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1032,6 +1032,7 @@ python.worker.js: $(srcdir)/Tools/wasm/python.worker.js PYTHON_HEADERS= \ $(srcdir)/Include/Python.h \ $(srcdir)/Include/abstract.h \ + $(srcdir)/Include/audit.h \ $(srcdir)/Include/bltinmodule.h \ $(srcdir)/Include/boolobject.h \ $(srcdir)/Include/bytearrayobject.h \ @@ -1110,6 +1111,7 @@ PYTHON_HEADERS= \ $(PARSER_HEADERS) \ \ $(srcdir)/Include/cpython/abstract.h \ + $(srcdir)/Include/cpython/audit.h \ $(srcdir)/Include/cpython/bytearrayobject.h \ $(srcdir)/Include/cpython/bytesobject.h \ $(srcdir)/Include/cpython/cellobject.h \ @@ -1159,7 +1161,6 @@ PYTHON_HEADERS= \ $(srcdir)/Include/cpython/pythonrun.h \ $(srcdir)/Include/cpython/pythread.h \ $(srcdir)/Include/cpython/setobject.h \ - $(srcdir)/Include/cpython/sysmodule.h \ $(srcdir)/Include/cpython/traceback.h \ $(srcdir)/Include/cpython/tracemalloc.h \ $(srcdir)/Include/cpython/tupleobject.h \ @@ -1174,6 +1175,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/internal/pycore_ast.h \ $(srcdir)/Include/internal/pycore_ast_state.h \ $(srcdir)/Include/internal/pycore_atexit.h \ + $(srcdir)/Include/internal/pycore_audit.h \ $(srcdir)/Include/internal/pycore_backoff.h \ $(srcdir)/Include/internal/pycore_bitutils.h \ $(srcdir)/Include/internal/pycore_blocks_output_buffer.h \ @@ -1193,6 +1195,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/internal/pycore_context.h \ $(srcdir)/Include/internal/pycore_critical_section.h \ $(srcdir)/Include/internal/pycore_crossinterp.h \ + $(srcdir)/Include/internal/pycore_debug_offsets.h \ $(srcdir)/Include/internal/pycore_descrobject.h \ $(srcdir)/Include/internal/pycore_dict.h \ $(srcdir)/Include/internal/pycore_dict_state.h \ diff --git a/Modules/_testexternalinspection.c b/Modules/_testexternalinspection.c index 2476346777c319..0807d1e47b6736 100644 --- a/Modules/_testexternalinspection.c +++ b/Modules/_testexternalinspection.c @@ -51,7 +51,9 @@ # define Py_BUILD_CORE_MODULE 1 #endif #include "Python.h" -#include +#include // _Py_DebugOffsets +#include // FRAME_OWNED_BY_CSTACK +#include // Py_TAG_BITS #ifndef HAVE_PROCESS_VM_READV # define HAVE_PROCESS_VM_READV 0 diff --git a/Objects/object.c b/Objects/object.c index 4a4c5bf7d7f08a..1a15b70d3dc63f 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -17,6 +17,7 @@ #include "pycore_memoryobject.h" // _PyManagedBuffer_Type #include "pycore_namespace.h" // _PyNamespace_Type #include "pycore_object.h" // PyAPI_DATA() _Py_SwappedOp definition +#include "pycore_object_state.h" // struct _reftracer_runtime_state #include "pycore_long.h" // _PyLong_GetZero() #include "pycore_optimizer.h" // _PyUOpExecutor_Type, _PyUOpOptimizer_Type, ... #include "pycore_pyerrors.h" // _PyErr_Occurred() diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 3b33c6bf6bb91d..a4881e9256e4dd 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -128,6 +128,7 @@ + @@ -137,6 +138,7 @@ + @@ -185,7 +187,6 @@ - @@ -208,6 +209,7 @@ + @@ -227,6 +229,7 @@ + diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index ee2930b10439a9..6b294683320a73 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -48,6 +48,9 @@ Include + + Include + Include @@ -354,6 +357,9 @@ Include\cpython + + Include\cpython + Include\cpython @@ -513,9 +519,6 @@ Include\cpython - - Include\cpython - Include\cpython @@ -552,6 +555,9 @@ Include\internal + + Include\internal + Include\internal @@ -603,6 +609,9 @@ Include\internal + + Include\internal + Include\internal diff --git a/Python/bytecodes.c b/Python/bytecodes.c index e6525657cabc2b..c59a35c3e828ca 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -8,6 +8,7 @@ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() +#include "pycore_audit.h" // _PySys_Audit() #include "pycore_backoff.h" #include "pycore_cell.h" // PyCell_GetRef() #include "pycore_ceval.h" @@ -27,7 +28,6 @@ #include "pycore_range.h" // _PyRangeIterObject #include "pycore_setobject.h" // _PySet_NextEntry() #include "pycore_sliceobject.h" // _PyBuildSlice_ConsumeRefs -#include "pycore_sysmodule.h" // _PySys_Audit() #include "pycore_tuple.h" // _PyTuple_ITEMS() #include "pycore_typeobject.h" // _PySuper_Lookup() diff --git a/Python/ceval.c b/Python/ceval.c index 98d95b28488fd0..55e5eba25eaa21 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -4,6 +4,7 @@ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() +#include "pycore_audit.h" // _PySys_Audit() #include "pycore_backoff.h" #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_cell.h" // PyCell_GetRef() @@ -26,7 +27,6 @@ #include "pycore_range.h" // _PyRangeIterObject #include "pycore_setobject.h" // _PySet_Update() #include "pycore_sliceobject.h" // _PyBuildSlice_ConsumeRefs -#include "pycore_sysmodule.h" // _PySys_Audit() #include "pycore_tuple.h" // _PyTuple_ITEMS() #include "pycore_typeobject.h" // _PySuper_Lookup() #include "pycore_uop_ids.h" // Uops diff --git a/Python/errors.c b/Python/errors.c index 9e2a3ce062a6fe..7f3b4aabc432d7 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -2,12 +2,13 @@ /* Error handling */ #include "Python.h" +#include "pycore_audit.h" // _PySys_Audit() #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_initconfig.h" // _PyStatus_ERR() #include "pycore_pyerrors.h" // _PyErr_Format() #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_structseq.h" // _PyStructSequence_FiniBuiltin() -#include "pycore_sysmodule.h" // _PySys_Audit() +#include "pycore_sysmodule.h" // _PySys_GetAttr() #include "pycore_traceback.h" // _PyTraceBack_FromFrame() #ifdef MS_WINDOWS diff --git a/Python/import.c b/Python/import.c index acf849f14562b9..d8ad37b2422795 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1,6 +1,7 @@ /* Module definition and import implementation */ #include "Python.h" +#include "pycore_audit.h" // _PySys_Audit() #include "pycore_ceval.h" #include "pycore_hashtable.h" // _Py_hashtable_new_full() #include "pycore_import.h" // _PyImport_BootstrapImp() @@ -14,7 +15,7 @@ #include "pycore_pylifecycle.h" #include "pycore_pymem.h" // _PyMem_SetDefaultAllocator() #include "pycore_pystate.h" // _PyInterpreterState_GET() -#include "pycore_sysmodule.h" // _PySys_Audit() +#include "pycore_sysmodule.h" // _PySys_ClearAttrString() #include "pycore_time.h" // _PyTime_AsMicroseconds() #include "pycore_weakref.h" // _PyWeakref_GET_REF() diff --git a/Python/legacy_tracing.c b/Python/legacy_tracing.c index 1436921a19b768..45af275f1f6dce 100644 --- a/Python/legacy_tracing.c +++ b/Python/legacy_tracing.c @@ -3,9 +3,9 @@ */ #include "Python.h" +#include "pycore_audit.h" // _PySys_Audit() #include "pycore_ceval.h" // export _PyEval_SetProfile() #include "pycore_object.h" -#include "pycore_sysmodule.h" // _PySys_Audit() #include "opcode.h" #include diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 5fb9c4f7c719fe..b8f424854ecb86 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -2,6 +2,7 @@ #include "Python.h" +#include "pycore_audit.h" // _PySys_ClearAuditHooks() #include "pycore_call.h" // _PyObject_CallMethod() #include "pycore_ceval.h" // _PyEval_FiniGIL() #include "pycore_codecs.h" // _PyCodec_Lookup() @@ -26,7 +27,7 @@ #include "pycore_runtime_init.h" // _PyRuntimeState_INIT #include "pycore_setobject.h" // _PySet_NextEntry() #include "pycore_sliceobject.h" // _PySlice_Fini() -#include "pycore_sysmodule.h" // _PySys_ClearAuditHooks() +#include "pycore_sysmodule.h" // _PySys_GetAttr() #include "pycore_traceback.h" // _Py_DumpTracebackThreads() #include "pycore_uniqueid.h" // _PyObject_FinalizeUniqueIdPool() #include "pycore_typeobject.h" // _PyTypes_InitTypes() @@ -78,6 +79,7 @@ static void wait_for_thread_shutdown(PyThreadState *tstate); static void finalize_subinterpreters(void); static void call_ll_exitfuncs(_PyRuntimeState *runtime); + /* The following places the `_PyRuntime` structure in a location that can be * found without any external information. This is meant to ease access to the * interpreter state for various runtime debugging tools, but is *not* an @@ -107,6 +109,7 @@ __attribute__ ((section (".PyRuntime"))) = _PyRuntimeState_INIT(_PyRuntime, _Py_Debug_Cookie); _Py_COMP_DIAG_POP + static int runtime_initialized = 0; PyStatus diff --git a/Python/pystate.c b/Python/pystate.c index e3812cba41d9c2..7df872cd6d7d8a 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -3,6 +3,7 @@ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() +#include "pycore_audit.h" // _Py_AuditHookEntry #include "pycore_ceval.h" #include "pycore_code.h" // stats #include "pycore_critical_section.h" // _PyCriticalSection_Resume() @@ -18,7 +19,6 @@ #include "pycore_pymem.h" // _PyMem_SetDefaultAllocator() #include "pycore_pystate.h" #include "pycore_runtime_init.h" // _PyRuntimeState_INIT -#include "pycore_sysmodule.h" // _PySys_Audit() #include "pycore_obmalloc.h" // _PyMem_obmalloc_state_on_heap() #include "pycore_uniqueid.h" // _PyObject_FinalizePerThreadRefcounts() diff --git a/Python/pythonrun.c b/Python/pythonrun.c index b67597113ead45..fc0f11bc4e8af4 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -13,6 +13,7 @@ #include "Python.h" #include "pycore_ast.h" // PyAST_mod2obj() +#include "pycore_audit.h" // _PySys_Audit() #include "pycore_ceval.h" // _Py_EnterRecursiveCall() #include "pycore_compile.h" // _PyAST_Compile() #include "pycore_interp.h" // PyInterpreterState.importlib @@ -22,7 +23,7 @@ #include "pycore_pylifecycle.h" // _Py_FdIsInteractive() #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_pythonrun.h" // export _PyRun_InteractiveLoopObject() -#include "pycore_sysmodule.h" // _PySys_Audit() +#include "pycore_sysmodule.h" // _PySys_GetAttr() #include "pycore_traceback.h" // _PyTraceBack_Print() #include "errcode.h" // E_EOF diff --git a/Python/sysmodule.c b/Python/sysmodule.c index ac343a8048e008..8b9209324002ce 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -15,6 +15,7 @@ Data members: */ #include "Python.h" +#include "pycore_audit.h" // _Py_AuditHookEntry #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_ceval.h" // _PyEval_SetAsyncGenFinalizer() #include "pycore_dict.h" // _PyDict_GetItemWithError() From f8ba9fb2ce6690d2dd05b356583e8e4790badad7 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Salgado Date: Fri, 18 Oct 2024 17:09:34 +0100 Subject: [PATCH 139/170] gh-125703: Correctly honour tracemalloc hooks on specialized DECREF paths (#125704) --- Include/internal/pycore_object.h | 5 +++++ .../2024-10-18-16-00-10.gh-issue-125703.QRoqMo.rst | 2 ++ 2 files changed, 7 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-10-18-16-00-10.gh-issue-125703.QRoqMo.rst diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index ad1a7d7e120519..96f6d61e1c620b 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -208,6 +208,11 @@ _Py_DECREF_SPECIALIZED(PyObject *op, const destructor destruct) #ifdef Py_TRACE_REFS _Py_ForgetReference(op); #endif + struct _reftracer_runtime_state *tracer = &_PyRuntime.ref_tracer; + if (tracer->tracer_func != NULL) { + void* data = tracer->tracer_data; + tracer->tracer_func(op, PyRefTracer_DESTROY, data); + } destruct(op); } } diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-10-18-16-00-10.gh-issue-125703.QRoqMo.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-18-16-00-10.gh-issue-125703.QRoqMo.rst new file mode 100644 index 00000000000000..7cbfa725e78cef --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-18-16-00-10.gh-issue-125703.QRoqMo.rst @@ -0,0 +1,2 @@ +Correctly honour :mod:`tracemalloc` hooks in specialized ``Py_DECREF`` +paths. Patch by Pablo Galindo From c8fd4b12e3db49d795de55f74d9bac445c059f1b Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Fri, 18 Oct 2024 15:51:29 -0400 Subject: [PATCH 140/170] gh-125207: Fix MSVC 1935 build with JIT (#125209) * gh-125207: Use {0} array initializers * Simplify, as suggested in PR * Revert change to explicitly specify length --- Python/jit.c | 2 +- Tools/jit/_stencils.py | 2 +- Tools/jit/_writer.py | 7 +++++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Python/jit.c b/Python/jit.c index 234fc7dda83231..963bde2303dc2c 100644 --- a/Python/jit.c +++ b/Python/jit.c @@ -469,7 +469,7 @@ _PyJIT_Compile(_PyExecutorObject *executor, const _PyUOpInstruction trace[], siz // Loop once to find the total compiled size: size_t code_size = 0; size_t data_size = 0; - jit_state state = {}; + jit_state state = {0}; group = &trampoline; code_size += group->code_size; data_size += group->data_size; diff --git a/Tools/jit/_stencils.py b/Tools/jit/_stencils.py index bbb52f391f4b01..e4b2bf6e4702b3 100644 --- a/Tools/jit/_stencils.py +++ b/Tools/jit/_stencils.py @@ -339,7 +339,7 @@ def _get_trampoline_mask(self) -> str: word = bitmask & ((1 << 32) - 1) trampoline_mask.append(f"{word:#04x}") bitmask >>= 32 - return "{" + ", ".join(trampoline_mask) + "}" + return "{" + (", ".join(trampoline_mask) or "0") + "}" def as_c(self, opname: str) -> str: """Dump this hole as a StencilGroup initializer.""" diff --git a/Tools/jit/_writer.py b/Tools/jit/_writer.py index 7b99d10310a645..4e7f614b0e9d23 100644 --- a/Tools/jit/_writer.py +++ b/Tools/jit/_writer.py @@ -32,8 +32,11 @@ def _dump_footer( yield "};" yield "" yield f"static const void * const symbols_map[{max(len(symbols), 1)}] = {{" - for symbol, ordinal in symbols.items(): - yield f" [{ordinal}] = &{symbol}," + if symbols: + for symbol, ordinal in symbols.items(): + yield f" [{ordinal}] = &{symbol}," + else: + yield " 0" yield "};" From 322f14eeff9e3b5853eaac3233f7580ca0214cf8 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Fri, 18 Oct 2024 16:05:12 -0600 Subject: [PATCH 141/170] gh-124694: In test_interpreter_pool, Restore the Asyncio Event Loop Policy During Cleanup (gh-125708) This resolves a failure on the android buildbot. --- .../test_interpreter_pool.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Lib/test/test_concurrent_futures/test_interpreter_pool.py b/Lib/test/test_concurrent_futures/test_interpreter_pool.py index 0de03c0d669399..5264b1bb6e9c75 100644 --- a/Lib/test/test_concurrent_futures/test_interpreter_pool.py +++ b/Lib/test/test_concurrent_futures/test_interpreter_pool.py @@ -282,6 +282,19 @@ def test_idle_thread_reuse(self): class AsyncioTest(InterpretersMixin, testasyncio_utils.TestCase): + @classmethod + def setUpClass(cls): + # Most uses of asyncio will implicitly call set_event_loop_policy() + # with the default policy if a policy hasn't been set already. + # If that happens in a test, like here, we'll end up with a failure + # when --fail-env-changed is used. That's why the other tests that + # use asyncio are careful to set the policy back to None and why + # we're careful to do so here. We also validate that no other + # tests left a policy in place, just in case. + policy = support.maybe_get_event_loop_policy() + assert policy is None, policy + cls.addClassCleanup(lambda: asyncio.set_event_loop_policy(None)) + def setUp(self): super().setUp() self.loop = asyncio.new_event_loop() From 2bb7ab7ad364ec804eab8ed6867df01ece887240 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Date: Sat, 19 Oct 2024 04:59:22 +0100 Subject: [PATCH 142/170] GH-125277: Increase minimum supported Sphinx to 7.2.6 (#125368) --- .github/workflows/reusable-docs.yml | 2 +- Doc/conf.py | 2 +- Doc/requirements-oldest-sphinx.txt | 30 +++++++++---------- ...-10-10-23-46-54.gh-issue-125277.QAby09.rst | 2 ++ 4 files changed, 19 insertions(+), 17 deletions(-) create mode 100644 Misc/NEWS.d/next/Documentation/2024-10-10-23-46-54.gh-issue-125277.QAby09.rst diff --git a/.github/workflows/reusable-docs.yml b/.github/workflows/reusable-docs.yml index 3809f24dcc977e..39a97392e898aa 100644 --- a/.github/workflows/reusable-docs.yml +++ b/.github/workflows/reusable-docs.yml @@ -84,7 +84,7 @@ jobs: - name: 'Set up Python' uses: actions/setup-python@v5 with: - python-version: '3.12' # known to work with Sphinx 6.2.1 + python-version: '3.13' # known to work with Sphinx 7.2.6 cache: 'pip' cache-dependency-path: 'Doc/requirements-oldest-sphinx.txt' - name: 'Install build dependencies' diff --git a/Doc/conf.py b/Doc/conf.py index 839beaad08bebd..db8fb9a9a68c6b 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -90,7 +90,7 @@ highlight_language = 'python3' # Minimum version of sphinx required -needs_sphinx = '6.2.1' +needs_sphinx = '7.2.6' # Create table of contents entries for domain objects (e.g. functions, classes, # attributes, etc.). Default is True. diff --git a/Doc/requirements-oldest-sphinx.txt b/Doc/requirements-oldest-sphinx.txt index 068fe0cb426ecd..3483faea6b56cb 100644 --- a/Doc/requirements-oldest-sphinx.txt +++ b/Doc/requirements-oldest-sphinx.txt @@ -7,29 +7,29 @@ blurb python-docs-theme>=2022.1 # Generated from: -# pip install "Sphinx~=6.2.1" +# pip install "Sphinx~=7.2.6" # pip freeze # -# Sphinx 6.2.1 comes from ``needs_sphinx = '6.2.1'`` in ``Doc/conf.py``. +# Sphinx 7.2.6 comes from ``needs_sphinx = '7.2.6'`` in ``Doc/conf.py``. alabaster==0.7.16 -Babel==2.15.0 -certifi==2024.7.4 -charset-normalizer==3.3.2 -docutils==0.19 -idna==3.7 +Babel==2.16.0 +certifi==2024.8.30 +charset-normalizer==3.4.0 +docutils==0.20.1 +idna==3.10 imagesize==1.4.1 Jinja2==3.1.4 -MarkupSafe==2.1.5 +MarkupSafe==3.0.1 packaging==24.1 Pygments==2.18.0 requests==2.32.3 snowballstemmer==2.2.0 -Sphinx==6.2.1 -sphinxcontrib-applehelp==1.0.8 -sphinxcontrib-devhelp==1.0.6 -sphinxcontrib-htmlhelp==2.0.5 +Sphinx==7.2.6 +sphinxcontrib-applehelp==2.0.0 +sphinxcontrib-devhelp==2.0.0 +sphinxcontrib-htmlhelp==2.1.0 sphinxcontrib-jsmath==1.0.1 -sphinxcontrib-qthelp==1.0.7 -sphinxcontrib-serializinghtml==1.1.10 -urllib3==2.2.2 +sphinxcontrib-qthelp==2.0.0 +sphinxcontrib-serializinghtml==2.0.0 +urllib3==2.2.3 diff --git a/Misc/NEWS.d/next/Documentation/2024-10-10-23-46-54.gh-issue-125277.QAby09.rst b/Misc/NEWS.d/next/Documentation/2024-10-10-23-46-54.gh-issue-125277.QAby09.rst new file mode 100644 index 00000000000000..fcd6e22c27b5f4 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2024-10-10-23-46-54.gh-issue-125277.QAby09.rst @@ -0,0 +1,2 @@ +Require Sphinx 7.2.6 or later to build the Python documentation. +Patch by Adam Turner. From 84074a4fd810948350cec5500e77dc974cb5433d Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Sat, 19 Oct 2024 01:26:46 -0700 Subject: [PATCH 143/170] GH-99749: Add What's New entry for GH-124456 (GH-125671) --- Doc/whatsnew/3.14.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index feb65f244827ad..ad841538ccc547 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -210,6 +210,11 @@ argparse interpreter was instructed to find the ``__main__`` module code. (Contributed by Serhiy Storchaka and Alyssa Coghlan in :gh:`66436`.) +* Introduced the optional *suggest_on_error* parameter to + :class:`argparse.ArgumentParser`, enabling suggestions for argument choices + and subparser names if mistyped by the user. + (Contributed by Savannah Ostrowski in :gh:`124456`) + ast --- From a7443a1735c33d5758b47ac9b8a1c34bac4ef994 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 19 Oct 2024 11:29:51 +0300 Subject: [PATCH 144/170] gh-52551: Use wcsftime() to implement time.strftime() on Windows (GH-125658) --- Lib/test/test_strftime.py | 3 +-- .../Library/2024-10-17-20-36-06.gh-issue-52551.EIVNYY.rst | 1 + Modules/timemodule.c | 4 ---- 3 files changed, 2 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-17-20-36-06.gh-issue-52551.EIVNYY.rst diff --git a/Lib/test/test_strftime.py b/Lib/test/test_strftime.py index cebfc8927862a7..752e31359cf206 100644 --- a/Lib/test/test_strftime.py +++ b/Lib/test/test_strftime.py @@ -183,8 +183,7 @@ class Y1900Tests(unittest.TestCase): def test_y_before_1900(self): # Issue #13674, #19634 t = (1899, 1, 1, 0, 0, 0, 0, 0, 0) - if (sys.platform == "win32" - or sys.platform.startswith(("aix", "sunos", "solaris"))): + if sys.platform.startswith(("aix", "sunos", "solaris")): with self.assertRaises(ValueError): time.strftime("%y", t) else: diff --git a/Misc/NEWS.d/next/Library/2024-10-17-20-36-06.gh-issue-52551.EIVNYY.rst b/Misc/NEWS.d/next/Library/2024-10-17-20-36-06.gh-issue-52551.EIVNYY.rst new file mode 100644 index 00000000000000..48d3d93c3d72af --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-17-20-36-06.gh-issue-52551.EIVNYY.rst @@ -0,0 +1 @@ +Use :c:func:`!wcsftime` to implement :func:`time.strftime` on Windows. diff --git a/Modules/timemodule.c b/Modules/timemodule.c index b9d114ada0dfcd..340011fc08b551 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -739,10 +739,6 @@ checktm(struct tm* buf) return 1; } -#ifdef MS_WINDOWS - /* wcsftime() doesn't format correctly time zones, see issue #10653 */ -# undef HAVE_WCSFTIME -#endif #define STRFTIME_FORMAT_CODES \ "Commonly used format codes:\n\ \n\ From 4b421e8aca7f2dccc5ac8604b78589941dd7974c Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Sat, 19 Oct 2024 12:49:14 +0100 Subject: [PATCH 145/170] gh-125522: Fix bare except in test_math.testTan (#125544) --- Lib/test/test_math.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index e2e2a419c7778c..fecafd53aa6e6f 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -1902,7 +1902,7 @@ def testTan(self): try: self.assertTrue(math.isnan(math.tan(INF))) self.assertTrue(math.isnan(math.tan(NINF))) - except: + except ValueError: self.assertRaises(ValueError, math.tan, INF) self.assertRaises(ValueError, math.tan, NINF) self.assertTrue(math.isnan(math.tan(NAN))) From 2a378dba987e125521b678364f0cd44b92dd5d52 Mon Sep 17 00:00:00 2001 From: Julien Date: Sat, 19 Oct 2024 13:34:41 -0400 Subject: [PATCH 146/170] gh-125398: Convert paths in venv activate script when using Git Bash under Windows (GH-125399) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Convert paths in venv activate script when using Git Bash under Windows With https://github.com/python/cpython/pull/112508 the check to converts paths when running on Windows was changed from using the non-posix environment variable `$OSTYPE` to using `uname` instead. However this missed the fact that when running under Git Bash on Windows, uname reports `MINGW*` (`$OSTYPE` is still `msys`). This results in `$PATH` being set to something like `D:\a\github-actions-shells\github-actions-shells\venv/Scripts:…`, instead of `/d/a/github-actions-shells/github-actions-shells/venv/Scripts`. Notably, the Git Bash is the bash shell that’s used for GitHub Actions Windows runners, and ships with VSCode. --- Lib/venv/scripts/common/activate | 4 ++-- .../Library/2024-10-13-15-04-58.gh-issue-125398.UW7Ndv.rst | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-13-15-04-58.gh-issue-125398.UW7Ndv.rst diff --git a/Lib/venv/scripts/common/activate b/Lib/venv/scripts/common/activate index 4593799b7e9b0e..44f137672e9d2e 100644 --- a/Lib/venv/scripts/common/activate +++ b/Lib/venv/scripts/common/activate @@ -38,8 +38,8 @@ deactivate nondestructive # on Windows, a path can contain colons and backslashes and has to be converted: case "$(uname)" in - CYGWIN*|MSYS*) - # transform D:\path\to\venv to /d/path/to/venv on MSYS + CYGWIN*|MSYS*|MINGW*) + # transform D:\path\to\venv to /d/path/to/venv on MSYS and MINGW # and to /cygdrive/d/path/to/venv on Cygwin VIRTUAL_ENV=$(cygpath "__VENV_DIR__") export VIRTUAL_ENV diff --git a/Misc/NEWS.d/next/Library/2024-10-13-15-04-58.gh-issue-125398.UW7Ndv.rst b/Misc/NEWS.d/next/Library/2024-10-13-15-04-58.gh-issue-125398.UW7Ndv.rst new file mode 100644 index 00000000000000..a188b35e1fbdbc --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-13-15-04-58.gh-issue-125398.UW7Ndv.rst @@ -0,0 +1 @@ +Fix the conversion of the :envvar:`!VIRTUAL_ENV` path in the activate script in :mod:`venv` when running in Git Bash for Windows. From 4c53b2577531c77193430cdcd66ad6385fcda81f Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Sat, 19 Oct 2024 17:16:36 -0400 Subject: [PATCH 147/170] gh-124984: Enhance `ssl` thread safety (#124993) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make SSL objects thread safe in Free Theaded build by using critical sections. Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> --- Lib/test/test_ssl.py | 51 + ...-10-04-22-43-48.gh-issue-124984.xjMv9b.rst | 1 + Modules/_ssl.c | 683 ++++++--- Modules/clinic/_ssl.c.h | 1347 +++++++++++++++-- 4 files changed, 1767 insertions(+), 315 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-04-22-43-48.gh-issue-124984.xjMv9b.rst diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index b93fa0ed99f8ce..de5110a1cc4b6d 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -4,6 +4,7 @@ import unittest import unittest.mock from ast import literal_eval +from threading import Thread from test import support from test.support import import_helper from test.support import os_helper @@ -277,11 +278,19 @@ def test_wrap_socket(sock, *, return context.wrap_socket(sock, **kwargs) +USE_SAME_TEST_CONTEXT = False +_TEST_CONTEXT = None + def testing_context(server_cert=SIGNED_CERTFILE, *, server_chain=True): """Create context client_context, server_context, hostname = testing_context() """ + global _TEST_CONTEXT + if USE_SAME_TEST_CONTEXT: + if _TEST_CONTEXT is not None: + return _TEST_CONTEXT + if server_cert == SIGNED_CERTFILE: hostname = SIGNED_CERTFILE_HOSTNAME elif server_cert == SIGNED_CERTFILE2: @@ -299,6 +308,10 @@ def testing_context(server_cert=SIGNED_CERTFILE, *, server_chain=True): if server_chain: server_context.load_verify_locations(SIGNING_CA) + if USE_SAME_TEST_CONTEXT: + if _TEST_CONTEXT is not None: + _TEST_CONTEXT = client_context, server_context, hostname + return client_context, server_context, hostname @@ -2801,6 +2814,44 @@ def test_echo(self): 'Cannot create a client socket with a PROTOCOL_TLS_SERVER context', str(e.exception)) + @unittest.skipUnless(support.Py_GIL_DISABLED, "test is only useful if the GIL is disabled") + def test_ssl_in_multiple_threads(self): + # See GH-124984: OpenSSL is not thread safe. + threads = [] + + global USE_SAME_TEST_CONTEXT + USE_SAME_TEST_CONTEXT = True + try: + for func in ( + self.test_echo, + self.test_alpn_protocols, + self.test_getpeercert, + self.test_crl_check, + self.test_check_hostname_idn, + self.test_wrong_cert_tls12, + self.test_wrong_cert_tls13, + ): + # Be careful with the number of threads here. + # Too many can result in failing tests. + for num in range(5): + with self.subTest(func=func, num=num): + threads.append(Thread(target=func)) + + with threading_helper.catch_threading_exception() as cm: + for thread in threads: + with self.subTest(thread=thread): + thread.start() + + for thread in threads: + with self.subTest(thread=thread): + thread.join() + if cm.exc_value is not None: + # Some threads can skip their test + if not isinstance(cm.exc_value, unittest.SkipTest): + raise cm.exc_value + finally: + USE_SAME_TEST_CONTEXT = False + def test_getpeercert(self): if support.verbose: sys.stdout.write("\n") diff --git a/Misc/NEWS.d/next/Library/2024-10-04-22-43-48.gh-issue-124984.xjMv9b.rst b/Misc/NEWS.d/next/Library/2024-10-04-22-43-48.gh-issue-124984.xjMv9b.rst new file mode 100644 index 00000000000000..dd0a55a6854c25 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-04-22-43-48.gh-issue-124984.xjMv9b.rst @@ -0,0 +1 @@ +Fixed thread safety in :mod:`ssl` in the free-threaded build. OpenSSL operations are now protected by a per-object lock. diff --git a/Modules/_ssl.c b/Modules/_ssl.c index f2d3b331226a7a..62a94314512dd9 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -51,7 +51,6 @@ PySSL_BEGIN_ALLOW_THREADS_S(_save); #define PySSL_END_ALLOW_THREADS PySSL_END_ALLOW_THREADS_S(_save); } - #if defined(HAVE_POLL_H) #include #elif defined(HAVE_SYS_POLL_H) @@ -376,9 +375,6 @@ class _ssl.SSLSession "PySSLSession *" "get_state_type(type)->PySSLSession_Type" static int PySSL_select(PySocketSockObject *s, int writing, PyTime_t timeout); -static int PySSL_set_owner(PySSLSocket *, PyObject *, void *); -static int PySSL_set_session(PySSLSocket *, PyObject *, void *); - typedef enum { SOCKET_IS_NONBLOCKING, SOCKET_IS_BLOCKING, @@ -616,6 +612,7 @@ PySSL_SetError(PySSLSocket *sslsock, const char *filename, int lineno) _sslmodulestate *state = get_state_sock(sslsock); type = state->PySSLErrorObject; + // ERR functions are thread local, no need to lock them. e = ERR_peek_last_error(); if (sslsock->ssl != NULL) { @@ -926,13 +923,13 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, } } if (owner && owner != Py_None) { - if (PySSL_set_owner(self, owner, NULL) == -1) { + if (_ssl__SSLSocket_owner_set(self, owner, NULL) == -1) { Py_DECREF(self); return NULL; } } if (session && session != Py_None) { - if (PySSL_set_session(self, session, NULL) == -1) { + if (_ssl__SSLSocket_session_set(self, session, NULL) == -1) { Py_DECREF(self); return NULL; } @@ -945,12 +942,13 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, /* SSL object methods */ /*[clinic input] +@critical_section _ssl._SSLSocket.do_handshake [clinic start generated code]*/ static PyObject * _ssl__SSLSocket_do_handshake_impl(PySSLSocket *self) -/*[clinic end generated code: output=6c0898a8936548f6 input=d2d737de3df018c8]*/ +/*[clinic end generated code: output=6c0898a8936548f6 input=65619a7a4bea3176]*/ { int ret; _PySSLError err; @@ -1820,6 +1818,7 @@ _ssl__test_decode_cert_impl(PyObject *module, PyObject *path) /*[clinic input] +@critical_section _ssl._SSLSocket.getpeercert der as binary_mode: bool = False / @@ -1837,7 +1836,7 @@ return the certificate even if it wasn't validated. static PyObject * _ssl__SSLSocket_getpeercert_impl(PySSLSocket *self, int binary_mode) -/*[clinic end generated code: output=1f0ab66dfb693c88 input=c0fbe802e57629b7]*/ +/*[clinic end generated code: output=1f0ab66dfb693c88 input=e35af55fa5f9bab8]*/ { int verification; X509 *peer_cert; @@ -1867,13 +1866,14 @@ _ssl__SSLSocket_getpeercert_impl(PySSLSocket *self, int binary_mode) } /*[clinic input] +@critical_section _ssl._SSLSocket.get_verified_chain [clinic start generated code]*/ static PyObject * _ssl__SSLSocket_get_verified_chain_impl(PySSLSocket *self) -/*[clinic end generated code: output=802421163cdc3110 input=5fb0714f77e2bd51]*/ +/*[clinic end generated code: output=802421163cdc3110 input=83035fe238ec057b]*/ { /* borrowed reference */ STACK_OF(X509) *chain = SSL_get0_verified_chain(self->ssl); @@ -1884,13 +1884,14 @@ _ssl__SSLSocket_get_verified_chain_impl(PySSLSocket *self) } /*[clinic input] +@critical_section _ssl._SSLSocket.get_unverified_chain [clinic start generated code]*/ static PyObject * _ssl__SSLSocket_get_unverified_chain_impl(PySSLSocket *self) -/*[clinic end generated code: output=5acdae414e13f913 input=78c33c360c635cb5]*/ +/*[clinic end generated code: output=5acdae414e13f913 input=079f8ff5c205cb3b]*/ { PyObject *retval; /* borrowed reference */ @@ -2020,12 +2021,13 @@ cipher_to_dict(const SSL_CIPHER *cipher) } /*[clinic input] +@critical_section _ssl._SSLSocket.shared_ciphers [clinic start generated code]*/ static PyObject * _ssl__SSLSocket_shared_ciphers_impl(PySSLSocket *self) -/*[clinic end generated code: output=3d174ead2e42c4fd input=0bfe149da8fe6306]*/ +/*[clinic end generated code: output=3d174ead2e42c4fd input=869645271e3bc6d0]*/ { STACK_OF(SSL_CIPHER) *server_ciphers; STACK_OF(SSL_CIPHER) *client_ciphers; @@ -2069,12 +2071,13 @@ _ssl__SSLSocket_shared_ciphers_impl(PySSLSocket *self) } /*[clinic input] +@critical_section _ssl._SSLSocket.cipher [clinic start generated code]*/ static PyObject * _ssl__SSLSocket_cipher_impl(PySSLSocket *self) -/*[clinic end generated code: output=376417c16d0e5815 input=548fb0e27243796d]*/ +/*[clinic end generated code: output=376417c16d0e5815 input=39e180269a36f486]*/ { const SSL_CIPHER *current; @@ -2087,12 +2090,13 @@ _ssl__SSLSocket_cipher_impl(PySSLSocket *self) } /*[clinic input] +@critical_section _ssl._SSLSocket.version [clinic start generated code]*/ static PyObject * _ssl__SSLSocket_version_impl(PySSLSocket *self) -/*[clinic end generated code: output=178aed33193b2cdb input=900186a503436fd6]*/ +/*[clinic end generated code: output=178aed33193b2cdb input=2732bc3f7f597d09]*/ { const char *version; @@ -2109,12 +2113,13 @@ _ssl__SSLSocket_version_impl(PySSLSocket *self) } /*[clinic input] +@critical_section _ssl._SSLSocket.selected_alpn_protocol [clinic start generated code]*/ static PyObject * _ssl__SSLSocket_selected_alpn_protocol_impl(PySSLSocket *self) -/*[clinic end generated code: output=ec33688b303d250f input=442de30e35bc2913]*/ +/*[clinic end generated code: output=ec33688b303d250f input=f0b53506c9acdf8c]*/ { const unsigned char *out; unsigned int outlen; @@ -2152,13 +2157,29 @@ _ssl__SSLSocket_compression_impl(PySSLSocket *self) #endif } -static PySSLContext *PySSL_get_context(PySSLSocket *self, void *closure) { - return (PySSLContext*)Py_NewRef(self->ctx); +/*[clinic input] +@critical_section +@getter +_ssl._SSLSocket.context +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLSocket_context_get_impl(PySSLSocket *self) +/*[clinic end generated code: output=d23e82f72f32e3d7 input=25aa82e4d9fa344a]*/ +{ + return Py_NewRef(self->ctx); } -static int PySSL_set_context(PySSLSocket *self, PyObject *value, - void *closure) { +/*[clinic input] +@critical_section +@setter +_ssl._SSLSocket.context +[clinic start generated code]*/ +static int +_ssl__SSLSocket_context_set_impl(PySSLSocket *self, PyObject *value) +/*[clinic end generated code: output=6b0a6cc5cf33d9fe input=48ece77724fd9dd4]*/ +{ if (PyObject_TypeCheck(value, self->ctx->state->PySSLContext_Type)) { Py_SETREF(self->ctx, (PySSLContext *)Py_NewRef(value)); SSL_set_SSL_CTX(self->ssl, self->ctx->ctx); @@ -2175,37 +2196,47 @@ static int PySSL_set_context(PySSLSocket *self, PyObject *value, return 0; } -PyDoc_STRVAR(PySSL_set_context_doc, -"_setter_context(ctx)\n\ -\ -This changes the context associated with the SSLSocket. This is typically\n\ -used from within a callback function set by the sni_callback\n\ -on the SSLContext to change the certificate information associated with the\n\ -SSLSocket before the cryptographic exchange handshake messages\n"); +/*[clinic input] +@critical_section +@getter +_ssl._SSLSocket.server_side +Whether this is a server-side socket. +[clinic start generated code]*/ static PyObject * -PySSL_get_server_side(PySSLSocket *self, void *c) +_ssl__SSLSocket_server_side_get_impl(PySSLSocket *self) +/*[clinic end generated code: output=ae51e372489148e3 input=b09b320510bc7cae]*/ { return PyBool_FromLong(self->socket_type == PY_SSL_SERVER); } -PyDoc_STRVAR(PySSL_get_server_side_doc, -"Whether this is a server-side socket."); +/*[clinic input] +@critical_section +@getter +_ssl._SSLSocket.server_hostname + +The currently set server hostname (for SNI). +[clinic start generated code]*/ static PyObject * -PySSL_get_server_hostname(PySSLSocket *self, void *c) +_ssl__SSLSocket_server_hostname_get_impl(PySSLSocket *self) +/*[clinic end generated code: output=1f40ea5a076de8e7 input=55d12a1dc6634b08]*/ { if (self->server_hostname == NULL) Py_RETURN_NONE; return Py_NewRef(self->server_hostname); } -PyDoc_STRVAR(PySSL_get_server_hostname_doc, -"The currently set server hostname (for SNI)."); +/*[clinic input] +@critical_section +@getter +_ssl._SSLSocket.owner +[clinic start generated code]*/ static PyObject * -PySSL_get_owner(PySSLSocket *self, void *c) +_ssl__SSLSocket_owner_get_impl(PySSLSocket *self) +/*[clinic end generated code: output=1f278cb930382927 input=bc2861ff3cf1402e]*/ { if (self->owner == NULL) { Py_RETURN_NONE; @@ -2217,8 +2248,15 @@ PySSL_get_owner(PySSLSocket *self, void *c) return owner; } +/*[clinic input] +@critical_section +@setter +_ssl._SSLSocket.owner +[clinic start generated code]*/ + static int -PySSL_set_owner(PySSLSocket *self, PyObject *value, void *c) +_ssl__SSLSocket_owner_set_impl(PySSLSocket *self, PyObject *value) +/*[clinic end generated code: output=2e3924498f2b6cde input=875666fd32367a73]*/ { Py_XSETREF(self->owner, PyWeakref_NewRef(value, NULL)); if (self->owner == NULL) @@ -2226,10 +2264,6 @@ PySSL_set_owner(PySSLSocket *self, PyObject *value, void *c) return 0; } -PyDoc_STRVAR(PySSL_get_owner_doc, -"The Python-level owner of this object.\ -Passed as \"self\" in servername callback."); - static int PySSL_traverse(PySSLSocket *self, visitproc visit, void *arg) { @@ -2343,6 +2377,7 @@ PySSL_select(PySocketSockObject *s, int writing, PyTime_t timeout) } /*[clinic input] +@critical_section _ssl._SSLSocket.write b: Py_buffer / @@ -2354,7 +2389,7 @@ Returns the number of bytes written. static PyObject * _ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b) -/*[clinic end generated code: output=aa7a6be5527358d8 input=77262d994fe5100a]*/ +/*[clinic end generated code: output=aa7a6be5527358d8 input=967b5feeae641a26]*/ { size_t count = 0; int retval; @@ -2452,6 +2487,7 @@ _ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b) } /*[clinic input] +@critical_section _ssl._SSLSocket.pending Returns the number of already decrypted bytes available for read, pending on the connection. @@ -2459,7 +2495,7 @@ Returns the number of already decrypted bytes available for read, pending on the static PyObject * _ssl__SSLSocket_pending_impl(PySSLSocket *self) -/*[clinic end generated code: output=983d9fecdc308a83 input=2b77487d6dfd597f]*/ +/*[clinic end generated code: output=983d9fecdc308a83 input=32ab982a254e8866]*/ { int count = 0; _PySSLError err; @@ -2477,6 +2513,7 @@ _ssl__SSLSocket_pending_impl(PySSLSocket *self) } /*[clinic input] +@critical_section _ssl._SSLSocket.read size as len: Py_ssize_t [ @@ -2490,7 +2527,7 @@ Read up to size bytes from the SSL socket. static PyObject * _ssl__SSLSocket_read_impl(PySSLSocket *self, Py_ssize_t len, int group_right_1, Py_buffer *buffer) -/*[clinic end generated code: output=49b16e6406023734 input=ec48bf622be1c4a1]*/ +/*[clinic end generated code: output=49b16e6406023734 input=80ed30436df01a71]*/ { PyObject *dest = NULL; char *mem; @@ -2619,6 +2656,7 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, Py_ssize_t len, } /*[clinic input] +@critical_section _ssl._SSLSocket.shutdown Does the SSL shutdown handshake with the remote end. @@ -2626,7 +2664,7 @@ Does the SSL shutdown handshake with the remote end. static PyObject * _ssl__SSLSocket_shutdown_impl(PySSLSocket *self) -/*[clinic end generated code: output=ca1aa7ed9d25ca42 input=11d39e69b0a2bf4a]*/ +/*[clinic end generated code: output=ca1aa7ed9d25ca42 input=98d9635cd4e16514]*/ { _PySSLError err; int sockstate, nonblocking, ret; @@ -2738,6 +2776,7 @@ _ssl__SSLSocket_shutdown_impl(PySSLSocket *self) } /*[clinic input] +@critical_section _ssl._SSLSocket.get_channel_binding cb_type: str = "tls-unique" @@ -2751,7 +2790,7 @@ Only 'tls-unique' channel binding data from RFC 5929 is supported. static PyObject * _ssl__SSLSocket_get_channel_binding_impl(PySSLSocket *self, const char *cb_type) -/*[clinic end generated code: output=34bac9acb6a61d31 input=08b7e43b99c17d41]*/ +/*[clinic end generated code: output=34bac9acb6a61d31 input=e008004fc08744db]*/ { char buf[PySSL_CB_MAXLEN]; size_t len; @@ -2783,6 +2822,7 @@ _ssl__SSLSocket_get_channel_binding_impl(PySSLSocket *self, } /*[clinic input] +@critical_section _ssl._SSLSocket.verify_client_post_handshake Initiate TLS 1.3 post-handshake authentication @@ -2790,7 +2830,7 @@ Initiate TLS 1.3 post-handshake authentication static PyObject * _ssl__SSLSocket_verify_client_post_handshake_impl(PySSLSocket *self) -/*[clinic end generated code: output=532147f3b1341425 input=6bfa874810a3d889]*/ +/*[clinic end generated code: output=532147f3b1341425 input=42b5bb1f0981eda1]*/ { #if defined(PySSL_HAVE_POST_HS_AUTH) int err = SSL_verify_client_post_handshake(self->ssl); @@ -2806,8 +2846,16 @@ _ssl__SSLSocket_verify_client_post_handshake_impl(PySSLSocket *self) #endif } +/*[clinic input] +@critical_section +@getter +_ssl._SSLSocket.session +[clinic start generated code]*/ + static PyObject * -PySSL_get_session(PySSLSocket *self, void *closure) { +_ssl__SSLSocket_session_get_impl(PySSLSocket *self) +/*[clinic end generated code: output=a5cd5755b35da670 input=b9792df9255a9f63]*/ +{ /* get_session can return sessions from a server-side connection, * it does not check for handshake done or client socket. */ PySSLSession *pysess; @@ -2819,6 +2867,8 @@ PySSL_get_session(PySSLSocket *self, void *closure) { } pysess = PyObject_GC_New(PySSLSession, self->ctx->state->PySSLSession_Type); if (pysess == NULL) { + // It's not possible for another thread to access this, so + // we don't need to lock it. SSL_SESSION_free(session); return NULL; } @@ -2830,8 +2880,16 @@ PySSL_get_session(PySSLSocket *self, void *closure) { return (PyObject *)pysess; } -static int PySSL_set_session(PySSLSocket *self, PyObject *value, - void *closure) { +/*[clinic input] +@critical_section +@setter +_ssl._SSLSocket.session +[clinic start generated code]*/ + +static int +_ssl__SSLSocket_session_set_impl(PySSLSocket *self, PyObject *value) +/*[clinic end generated code: output=a3fa2ddd7c2d54a2 input=5fa5f921640db98b]*/ +{ PySSLSession *pysess; if (!Py_IS_TYPE(value, get_state_sock(self)->PySSLSession_Type)) { @@ -2855,6 +2913,7 @@ static int PySSL_set_session(PySSLSocket *self, PyObject *value, "Cannot set session after handshake."); return -1; } + if (SSL_set_session(self->ssl, pysess->session) == 0) { _setSSLError(get_state_sock(self), NULL, 0, __FILE__, __LINE__); return -1; @@ -2862,36 +2921,29 @@ static int PySSL_set_session(PySSLSocket *self, PyObject *value, return 0; } -PyDoc_STRVAR(PySSL_set_session_doc, -"_setter_session(session)\n\ -\ -Get / set SSLSession."); +/*[clinic input] +@critical_section +@getter +_ssl._SSLSocket.session_reused + +Was the client session reused during handshake? +[clinic start generated code]*/ static PyObject * -PySSL_get_session_reused(PySSLSocket *self, void *closure) { - if (SSL_session_reused(self->ssl)) { - Py_RETURN_TRUE; - } else { - Py_RETURN_FALSE; - } +_ssl__SSLSocket_session_reused_get_impl(PySSLSocket *self) +/*[clinic end generated code: output=c8916909bcb80893 input=cec8bfec73a4461e]*/ +{ + int res = SSL_session_reused(self->ssl); + return res ? Py_True : Py_False; } -PyDoc_STRVAR(PySSL_get_session_reused_doc, -"Was the client session reused during handshake?"); - static PyGetSetDef ssl_getsetlist[] = { - {"context", (getter) PySSL_get_context, - (setter) PySSL_set_context, PySSL_set_context_doc}, - {"server_side", (getter) PySSL_get_server_side, NULL, - PySSL_get_server_side_doc}, - {"server_hostname", (getter) PySSL_get_server_hostname, NULL, - PySSL_get_server_hostname_doc}, - {"owner", (getter) PySSL_get_owner, (setter) PySSL_set_owner, - PySSL_get_owner_doc}, - {"session", (getter) PySSL_get_session, - (setter) PySSL_set_session, PySSL_set_session_doc}, - {"session_reused", (getter) PySSL_get_session_reused, NULL, - PySSL_get_session_reused_doc}, + _SSL__SSLSOCKET_CONTEXT_GETSETDEF + _SSL__SSLSOCKET_SERVER_SIDE_GETSETDEF + _SSL__SSLSOCKET_SERVER_HOSTNAME_GETSETDEF + _SSL__SSLSOCKET_OWNER_GETSETDEF + _SSL__SSLSOCKET_SESSION_GETSETDEF + _SSL__SSLSOCKET_SESSION_REUSED_GETSETDEF {NULL}, /* sentinel */ }; @@ -2964,6 +3016,7 @@ _set_verify_mode(PySSLContext *self, enum py_ssl_cert_requirements n) } /*[clinic input] +@critical_section @classmethod _ssl._SSLContext.__new__ protocol as proto_version: int @@ -2972,7 +3025,7 @@ _ssl._SSLContext.__new__ static PyObject * _ssl__SSLContext_impl(PyTypeObject *type, int proto_version) -/*[clinic end generated code: output=2cf0d7a0741b6bd1 input=8d58a805b95fc534]*/ +/*[clinic end generated code: output=2cf0d7a0741b6bd1 input=6fc79e62ae9d143c]*/ { PySSLContext *self; uint64_t options; @@ -3042,6 +3095,10 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version) return NULL; } + // This is the constructor, no need to lock it, because + // no other thread can be touching this object yet. + // (Technically, we can't even lock if we wanted to, as the + // lock hasn't been initialized yet.) PySSL_BEGIN_ALLOW_THREADS ctx = SSL_CTX_new(method); PySSL_END_ALLOW_THREADS @@ -3208,6 +3265,7 @@ context_dealloc(PySSLContext *self) } /*[clinic input] +@critical_section _ssl._SSLContext.set_ciphers cipherlist: str / @@ -3215,7 +3273,7 @@ _ssl._SSLContext.set_ciphers static PyObject * _ssl__SSLContext_set_ciphers_impl(PySSLContext *self, const char *cipherlist) -/*[clinic end generated code: output=3a3162f3557c0f3f input=a7ac931b9f3ca7fc]*/ +/*[clinic end generated code: output=3a3162f3557c0f3f input=40b583cded5c6ff9]*/ { int ret = SSL_CTX_set_cipher_list(self->ctx, cipherlist); if (ret == 0) { @@ -3231,12 +3289,13 @@ _ssl__SSLContext_set_ciphers_impl(PySSLContext *self, const char *cipherlist) } /*[clinic input] +@critical_section _ssl._SSLContext.get_ciphers [clinic start generated code]*/ static PyObject * _ssl__SSLContext_get_ciphers_impl(PySSLContext *self) -/*[clinic end generated code: output=a56e4d68a406dfc4 input=a2aadc9af89b79c5]*/ +/*[clinic end generated code: output=a56e4d68a406dfc4 input=d7fff51631a260ae]*/ { SSL *ssl = NULL; STACK_OF(SSL_CIPHER) *sk = NULL; @@ -3311,6 +3370,7 @@ _selectALPN_cb(SSL *s, } /*[clinic input] +@critical_section _ssl._SSLContext._set_alpn_protocols protos: Py_buffer / @@ -3319,7 +3379,7 @@ _ssl._SSLContext._set_alpn_protocols static PyObject * _ssl__SSLContext__set_alpn_protocols_impl(PySSLContext *self, Py_buffer *protos) -/*[clinic end generated code: output=87599a7f76651a9b input=9bba964595d519be]*/ +/*[clinic end generated code: output=87599a7f76651a9b input=b5096b186e49287d]*/ { if ((size_t)protos->len > UINT_MAX) { PyErr_Format(PyExc_OverflowError, @@ -3329,25 +3389,34 @@ _ssl__SSLContext__set_alpn_protocols_impl(PySSLContext *self, PyMem_Free(self->alpn_protocols); self->alpn_protocols = PyMem_Malloc(protos->len); - if (!self->alpn_protocols) + if (!self->alpn_protocols) { return PyErr_NoMemory(); + } memcpy(self->alpn_protocols, protos->buf, protos->len); self->alpn_protocols_len = (unsigned int)protos->len; - - if (SSL_CTX_set_alpn_protos(self->ctx, self->alpn_protocols, self->alpn_protocols_len)) + if (SSL_CTX_set_alpn_protos(self->ctx, self->alpn_protocols, self->alpn_protocols_len)) { return PyErr_NoMemory(); + } SSL_CTX_set_alpn_select_cb(self->ctx, _selectALPN_cb, self); Py_RETURN_NONE; } +/*[clinic input] +@critical_section +@getter +_ssl._SSLContext.verify_mode +[clinic start generated code]*/ + static PyObject * -get_verify_mode(PySSLContext *self, void *c) +_ssl__SSLContext_verify_mode_get_impl(PySSLContext *self) +/*[clinic end generated code: output=3e788736cc7229bc input=7e3c7f4454121d0a]*/ { /* ignore SSL_VERIFY_CLIENT_ONCE and SSL_VERIFY_POST_HANDSHAKE */ int mask = (SSL_VERIFY_NONE | SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT); - switch (SSL_CTX_get_verify_mode(self->ctx) & mask) { + int verify_mode = SSL_CTX_get_verify_mode(self->ctx); + switch (verify_mode & mask) { case SSL_VERIFY_NONE: return PyLong_FromLong(PY_SSL_CERT_NONE); case SSL_VERIFY_PEER: @@ -3360,11 +3429,18 @@ get_verify_mode(PySSLContext *self, void *c) return NULL; } +/*[clinic input] +@critical_section +@setter +_ssl._SSLContext.verify_mode +[clinic start generated code]*/ + static int -set_verify_mode(PySSLContext *self, PyObject *arg, void *c) +_ssl__SSLContext_verify_mode_set_impl(PySSLContext *self, PyObject *value) +/*[clinic end generated code: output=d698e16c58db3118 input=3ee60057c3a22378]*/ { int n; - if (!PyArg_Parse(arg, "i", &n)) + if (!PyArg_Parse(value, "i", &n)) return -1; if (n == PY_SSL_CERT_NONE && self->check_hostname) { PyErr_SetString(PyExc_ValueError, @@ -3375,8 +3451,15 @@ set_verify_mode(PySSLContext *self, PyObject *arg, void *c) return _set_verify_mode(self, n); } +/*[clinic input] +@critical_section +@getter +_ssl._SSLContext.verify_flags +[clinic start generated code]*/ + static PyObject * -get_verify_flags(PySSLContext *self, void *c) +_ssl__SSLContext_verify_flags_get_impl(PySSLContext *self) +/*[clinic end generated code: output=fbbf8ba28ad6e56e input=c1ec36d610b3f391]*/ { X509_VERIFY_PARAM *param; unsigned long flags; @@ -3386,13 +3469,20 @@ get_verify_flags(PySSLContext *self, void *c) return PyLong_FromUnsignedLong(flags); } +/*[clinic input] +@critical_section +@setter +_ssl._SSLContext.verify_flags +[clinic start generated code]*/ + static int -set_verify_flags(PySSLContext *self, PyObject *arg, void *c) +_ssl__SSLContext_verify_flags_set_impl(PySSLContext *self, PyObject *value) +/*[clinic end generated code: output=a3e3b2a0ce6c2e99 input=b2a0c42583d4f34e]*/ { X509_VERIFY_PARAM *param; unsigned long new_flags, flags, set, clear; - if (!PyArg_Parse(arg, "k", &new_flags)) + if (!PyArg_Parse(value, "k", &new_flags)) return -1; param = SSL_CTX_get0_param(self->ctx); flags = X509_VERIFY_PARAM_get_flags(param); @@ -3500,8 +3590,15 @@ set_min_max_proto_version(PySSLContext *self, PyObject *arg, int what) return 0; } +/*[clinic input] +@critical_section +@getter +_ssl._SSLContext.minimum_version +[clinic start generated code]*/ + static PyObject * -get_minimum_version(PySSLContext *self, void *c) +_ssl__SSLContext_minimum_version_get_impl(PySSLContext *self) +/*[clinic end generated code: output=27fa8382276635ed input=6832821e7e974d40]*/ { int v = SSL_CTX_get_min_proto_version(self->ctx); if (v == 0) { @@ -3510,14 +3607,29 @@ get_minimum_version(PySSLContext *self, void *c) return PyLong_FromLong(v); } +/*[clinic input] +@critical_section +@setter +_ssl._SSLContext.minimum_version +[clinic start generated code]*/ + static int -set_minimum_version(PySSLContext *self, PyObject *arg, void *c) +_ssl__SSLContext_minimum_version_set_impl(PySSLContext *self, + PyObject *value) +/*[clinic end generated code: output=482e82f7372afb78 input=2c64724901a514b3]*/ { - return set_min_max_proto_version(self, arg, 0); + return set_min_max_proto_version(self, value, 0); } +/*[clinic input] +@critical_section +@getter +_ssl._SSLContext.maximum_version +[clinic start generated code]*/ + static PyObject * -get_maximum_version(PySSLContext *self, void *c) +_ssl__SSLContext_maximum_version_get_impl(PySSLContext *self) +/*[clinic end generated code: output=889249475112826a input=2b9e4c2d45f16b14]*/ { int v = SSL_CTX_get_max_proto_version(self->ctx); if (v == 0) { @@ -3526,24 +3638,51 @@ get_maximum_version(PySSLContext *self, void *c) return PyLong_FromLong(v); } +/*[clinic input] +@critical_section +@setter +_ssl._SSLContext.maximum_version +[clinic start generated code]*/ + static int -set_maximum_version(PySSLContext *self, PyObject *arg, void *c) +_ssl__SSLContext_maximum_version_set_impl(PySSLContext *self, + PyObject *value) +/*[clinic end generated code: output=4c0eed3042ca20d5 input=fe27e9fbbeb73c89]*/ { - return set_min_max_proto_version(self, arg, 1); + return set_min_max_proto_version(self, value, 1); } -#if defined(TLS1_3_VERSION) && !defined(OPENSSL_NO_TLS1_3) +/*[clinic input] +@critical_section +@getter +_ssl._SSLContext.num_tickets +[clinic start generated code]*/ + static PyObject * -get_num_tickets(PySSLContext *self, void *c) +_ssl__SSLContext_num_tickets_get_impl(PySSLContext *self) +/*[clinic end generated code: output=3d06d016318846c9 input=1dee26d75163c073]*/ { - return PyLong_FromSize_t(SSL_CTX_get_num_tickets(self->ctx)); + // Clinic seems to be misbehaving when the comment is wrapped with in directive +#if defined(TLS1_3_VERSION) && !defined(OPENSSL_NO_TLS1_3) + PyObject *res = PyLong_FromSize_t(SSL_CTX_get_num_tickets(self->ctx)); + return res; +#else + return 0; +#endif } +/*[clinic input] +@critical_section +@setter +_ssl._SSLContext.num_tickets +[clinic start generated code]*/ + static int -set_num_tickets(PySSLContext *self, PyObject *arg, void *c) +_ssl__SSLContext_num_tickets_set_impl(PySSLContext *self, PyObject *value) +/*[clinic end generated code: output=ced81b46f3beab09 input=6ef8067ac55607e7]*/ { long num; - if (!PyArg_Parse(arg, "l", &num)) + if (!PyArg_Parse(value, "l", &num)) return -1; if (num < 0) { PyErr_SetString(PyExc_ValueError, "value must be non-negative"); @@ -3561,27 +3700,44 @@ set_num_tickets(PySSLContext *self, PyObject *arg, void *c) return 0; } -PyDoc_STRVAR(PySSLContext_num_tickets_doc, -"Control the number of TLSv1.3 session tickets"); -#endif /* defined(TLS1_3_VERSION) */ +/*[clinic input] +@critical_section +@getter +_ssl._SSLContext.security_level +[clinic start generated code]*/ static PyObject * -get_security_level(PySSLContext *self, void *c) +_ssl__SSLContext_security_level_get_impl(PySSLContext *self) +/*[clinic end generated code: output=56ece09e6a9572d0 input=a0416598e07c3183]*/ { - return PyLong_FromLong(SSL_CTX_get_security_level(self->ctx)); + PyObject *res = PyLong_FromLong(SSL_CTX_get_security_level(self->ctx)); + return res; } -PyDoc_STRVAR(PySSLContext_security_level_doc, "The current security level"); + +/*[clinic input] +@critical_section +@getter +_ssl._SSLContext.options +[clinic start generated code]*/ static PyObject * -get_options(PySSLContext *self, void *c) +_ssl__SSLContext_options_get_impl(PySSLContext *self) +/*[clinic end generated code: output=3dfa6a74837f525b input=f5a2805c7cda6f25]*/ { uint64_t options = SSL_CTX_get_options(self->ctx); Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(options)); return PyLong_FromUnsignedLongLong(options); } +/*[clinic input] +@critical_section +@setter +_ssl._SSLContext.options +[clinic start generated code]*/ + static int -set_options(PySSLContext *self, PyObject *arg, void *c) +_ssl__SSLContext_options_set_impl(PySSLContext *self, PyObject *value) +/*[clinic end generated code: output=92ca34731ece5dbb input=2b94bf789e9ae5dd]*/ { PyObject *new_opts_obj; unsigned long long new_opts_arg; @@ -3591,7 +3747,7 @@ set_options(PySSLContext *self, PyObject *arg, void *c) SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2 | SSL_OP_NO_TLSv1_3 ); - if (!PyArg_Parse(arg, "O!", &PyLong_Type, &new_opts_obj)) { + if (!PyArg_Parse(value, "O!", &PyLong_Type, &new_opts_obj)) { return -1; } new_opts_arg = PyLong_AsUnsignedLongLong(new_opts_obj); @@ -3620,19 +3776,33 @@ set_options(PySSLContext *self, PyObject *arg, void *c) return 0; } +/*[clinic input] +@critical_section +@getter +_ssl._SSLContext._host_flags +[clinic start generated code]*/ + static PyObject * -get_host_flags(PySSLContext *self, void *c) +_ssl__SSLContext__host_flags_get_impl(PySSLContext *self) +/*[clinic end generated code: output=0f9db6654ce32582 input=8e3c49499eefd0e5]*/ { return PyLong_FromUnsignedLong(self->hostflags); } +/*[clinic input] +@critical_section +@setter +_ssl._SSLContext._host_flags +[clinic start generated code]*/ + static int -set_host_flags(PySSLContext *self, PyObject *arg, void *c) +_ssl__SSLContext__host_flags_set_impl(PySSLContext *self, PyObject *value) +/*[clinic end generated code: output=1ed6f4027aaf2e3e input=28caf1fb9c32f6cb]*/ { X509_VERIFY_PARAM *param; unsigned int new_flags = 0; - if (!PyArg_Parse(arg, "I", &new_flags)) + if (!PyArg_Parse(value, "I", &new_flags)) return -1; param = SSL_CTX_get0_param(self->ctx); @@ -3641,20 +3811,35 @@ set_host_flags(PySSLContext *self, PyObject *arg, void *c) return 0; } +/*[clinic input] +@critical_section +@getter +_ssl._SSLContext.check_hostname +[clinic start generated code]*/ + static PyObject * -get_check_hostname(PySSLContext *self, void *c) +_ssl__SSLContext_check_hostname_get_impl(PySSLContext *self) +/*[clinic end generated code: output=e046d6eeefc76063 input=1b8341e705f9ecf5]*/ { return PyBool_FromLong(self->check_hostname); } +/*[clinic input] +@critical_section +@setter +_ssl._SSLContext.check_hostname +[clinic start generated code]*/ + static int -set_check_hostname(PySSLContext *self, PyObject *arg, void *c) +_ssl__SSLContext_check_hostname_set_impl(PySSLContext *self, PyObject *value) +/*[clinic end generated code: output=0e767b4784e7dc3f input=e6a771cb5919f74d]*/ { int check_hostname; - if (!PyArg_Parse(arg, "p", &check_hostname)) + if (!PyArg_Parse(value, "p", &check_hostname)) return -1; + int verify_mode = check_hostname ? SSL_CTX_get_verify_mode(self->ctx) : 0; if (check_hostname && - SSL_CTX_get_verify_mode(self->ctx) == SSL_VERIFY_NONE) { + verify_mode == SSL_VERIFY_NONE) { /* check_hostname = True sets verify_mode = CERT_REQUIRED */ if (_set_verify_mode(self, PY_SSL_CERT_REQUIRED) == -1) { return -1; @@ -3694,8 +3879,16 @@ set_post_handshake_auth(PySSLContext *self, PyObject *arg, void *c) { } #endif +/*[clinic input] +@critical_section +@getter +_ssl._SSLContext.protocol +[clinic start generated code]*/ + static PyObject * -get_protocol(PySSLContext *self, void *c) { +_ssl__SSLContext_protocol_get_impl(PySSLContext *self) +/*[clinic end generated code: output=a9a48febc16cee22 input=c9f5fa1a2bd4b8a8]*/ +{ return PyLong_FromLong(self->protocol); } @@ -3809,6 +4002,7 @@ _password_callback(char *buf, int size, int rwflag, void *userdata) } /*[clinic input] +@critical_section _ssl._SSLContext.load_cert_chain certfile: object keyfile: object = None @@ -3819,7 +4013,7 @@ _ssl._SSLContext.load_cert_chain static PyObject * _ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile, PyObject *keyfile, PyObject *password) -/*[clinic end generated code: output=9480bc1c380e2095 input=30bc7e967ea01a58]*/ +/*[clinic end generated code: output=9480bc1c380e2095 input=6c7c5e8b73e4264b]*/ { PyObject *certfile_bytes = NULL, *keyfile_bytes = NULL; pem_password_cb *orig_passwd_cb = SSL_CTX_get_default_passwd_cb(self->ctx); @@ -4013,6 +4207,7 @@ _add_ca_certs(PySSLContext *self, const void *data, Py_ssize_t len, /*[clinic input] +@critical_section _ssl._SSLContext.load_verify_locations cafile: object = None capath: object = None @@ -4025,7 +4220,7 @@ _ssl__SSLContext_load_verify_locations_impl(PySSLContext *self, PyObject *cafile, PyObject *capath, PyObject *cadata) -/*[clinic end generated code: output=454c7e41230ca551 input=42ecfe258233e194]*/ +/*[clinic end generated code: output=454c7e41230ca551 input=b178852b41618414]*/ { PyObject *cafile_bytes = NULL, *capath_bytes = NULL; const char *cafile_buf = NULL, *capath_buf = NULL; @@ -4141,6 +4336,7 @@ _ssl__SSLContext_load_verify_locations_impl(PySSLContext *self, } /*[clinic input] +@critical_section _ssl._SSLContext.load_dh_params path as filepath: object / @@ -4148,8 +4344,8 @@ _ssl._SSLContext.load_dh_params [clinic start generated code]*/ static PyObject * -_ssl__SSLContext_load_dh_params(PySSLContext *self, PyObject *filepath) -/*[clinic end generated code: output=1c8e57a38e055af0 input=c8871f3c796ae1d6]*/ +_ssl__SSLContext_load_dh_params_impl(PySSLContext *self, PyObject *filepath) +/*[clinic end generated code: output=dd74b3c524dd2723 input=832769a0734b8c4d]*/ { FILE *f; DH *dh; @@ -4182,6 +4378,7 @@ _ssl__SSLContext_load_dh_params(PySSLContext *self, PyObject *filepath) } /*[clinic input] +@critical_section _ssl._SSLContext._wrap_socket sock: object(subclass_of="get_state_ctx(self)->Sock_Type") server_side: bool @@ -4196,7 +4393,7 @@ static PyObject * _ssl__SSLContext__wrap_socket_impl(PySSLContext *self, PyObject *sock, int server_side, PyObject *hostname_obj, PyObject *owner, PyObject *session) -/*[clinic end generated code: output=f103f238633940b4 input=700ca8fedff53994]*/ +/*[clinic end generated code: output=f103f238633940b4 input=eceadcee4434a06f]*/ { char *hostname = NULL; PyObject *res; @@ -4218,6 +4415,7 @@ _ssl__SSLContext__wrap_socket_impl(PySSLContext *self, PyObject *sock, } /*[clinic input] +@critical_section _ssl._SSLContext._wrap_bio incoming: object(subclass_of="get_state_ctx(self)->PySSLMemoryBIO_Type", type="PySSLMemoryBIO *") outgoing: object(subclass_of="get_state_ctx(self)->PySSLMemoryBIO_Type", type="PySSLMemoryBIO *") @@ -4234,7 +4432,7 @@ _ssl__SSLContext__wrap_bio_impl(PySSLContext *self, PySSLMemoryBIO *incoming, PySSLMemoryBIO *outgoing, int server_side, PyObject *hostname_obj, PyObject *owner, PyObject *session) -/*[clinic end generated code: output=5c5d6d9b41f99332 input=a9205d097fd45a82]*/ +/*[clinic end generated code: output=5c5d6d9b41f99332 input=58277fc962a60182]*/ { char *hostname = NULL; PyObject *res; @@ -4255,12 +4453,13 @@ _ssl__SSLContext__wrap_bio_impl(PySSLContext *self, PySSLMemoryBIO *incoming, } /*[clinic input] +@critical_section _ssl._SSLContext.session_stats [clinic start generated code]*/ static PyObject * _ssl__SSLContext_session_stats_impl(PySSLContext *self) -/*[clinic end generated code: output=0d96411c42893bfb input=7e0a81fb11102c8b]*/ +/*[clinic end generated code: output=0d96411c42893bfb input=db62af53004127a4]*/ { int r; PyObject *value, *stats = PyDict_New(); @@ -4299,12 +4498,13 @@ _ssl__SSLContext_session_stats_impl(PySSLContext *self) } /*[clinic input] +@critical_section _ssl._SSLContext.set_default_verify_paths [clinic start generated code]*/ static PyObject * _ssl__SSLContext_set_default_verify_paths_impl(PySSLContext *self) -/*[clinic end generated code: output=0bee74e6e09deaaa input=35f3408021463d74]*/ +/*[clinic end generated code: output=0bee74e6e09deaaa input=939a88e78f634119]*/ { int rc; Py_BEGIN_ALLOW_THREADS @@ -4318,6 +4518,7 @@ _ssl__SSLContext_set_default_verify_paths_impl(PySSLContext *self) } /*[clinic input] +@critical_section _ssl._SSLContext.set_ecdh_curve name: object / @@ -4325,8 +4526,8 @@ _ssl._SSLContext.set_ecdh_curve [clinic start generated code]*/ static PyObject * -_ssl__SSLContext_set_ecdh_curve(PySSLContext *self, PyObject *name) -/*[clinic end generated code: output=23022c196e40d7d2 input=c2bafb6f6e34726b]*/ +_ssl__SSLContext_set_ecdh_curve_impl(PySSLContext *self, PyObject *name) +/*[clinic end generated code: output=01081151ce0ecc45 input=039df032e666870e]*/ { PyObject *name_bytes; int nid; @@ -4460,8 +4661,15 @@ _servername_callback(SSL *s, int *al, void *args) return ret; } +/*[clinic input] +@critical_section +@getter +_ssl._SSLContext.sni_callback +[clinic start generated code]*/ + static PyObject * -get_sni_callback(PySSLContext *self, void *c) +_ssl__SSLContext_sni_callback_get_impl(PySSLContext *self) +/*[clinic end generated code: output=961e6575cdfaf036 input=22dd28c31fdc4318]*/ { PyObject *cb = self->set_sni_cb; if (cb == NULL) { @@ -4470,8 +4678,15 @@ get_sni_callback(PySSLContext *self, void *c) return Py_NewRef(cb); } +/*[clinic input] +@critical_section +@setter +_ssl._SSLContext.sni_callback +[clinic start generated code]*/ + static int -set_sni_callback(PySSLContext *self, PyObject *arg, void *c) +_ssl__SSLContext_sni_callback_set_impl(PySSLContext *self, PyObject *value) +/*[clinic end generated code: output=b32736c6b891f61a input=c3c4ff33540b3c85]*/ { if (self->protocol == PY_SSL_VERSION_TLS_CLIENT) { PyErr_SetString(PyExc_ValueError, @@ -4479,17 +4694,17 @@ set_sni_callback(PySSLContext *self, PyObject *arg, void *c) return -1; } Py_CLEAR(self->set_sni_cb); - if (arg == Py_None) { + if (value == Py_None) { SSL_CTX_set_tlsext_servername_callback(self->ctx, NULL); } else { - if (!PyCallable_Check(arg)) { + if (!PyCallable_Check(value)) { SSL_CTX_set_tlsext_servername_callback(self->ctx, NULL); PyErr_SetString(PyExc_TypeError, "not a callable object"); return -1; } - self->set_sni_cb = Py_NewRef(arg); + self->set_sni_cb = Py_NewRef(value); SSL_CTX_set_tlsext_servername_callback(self->ctx, _servername_callback); SSL_CTX_set_tlsext_servername_arg(self->ctx, self); } @@ -4540,14 +4755,8 @@ X509_STORE_get1_objects(X509_STORE *store) } #endif -PyDoc_STRVAR(PySSLContext_sni_callback_doc, -"Set a callback that will be called when a server name is provided by the SSL/TLS client in the SNI extension.\n\ -\n\ -If the argument is None then the callback is disabled. The method is called\n\ -with the SSLSocket, the server name as a string, and the SSLContext object.\n\ -See RFC 6066 for details of the SNI extension."); - /*[clinic input] +@critical_section _ssl._SSLContext.cert_store_stats Returns quantities of loaded X.509 certificates. @@ -4561,7 +4770,7 @@ been used at least once. static PyObject * _ssl__SSLContext_cert_store_stats_impl(PySSLContext *self) -/*[clinic end generated code: output=5f356f4d9cca874d input=eb40dd0f6d0e40cf]*/ +/*[clinic end generated code: output=5f356f4d9cca874d input=d13c6e3f2b48539b]*/ { X509_STORE *store; STACK_OF(X509_OBJECT) *objs; @@ -4598,6 +4807,7 @@ _ssl__SSLContext_cert_store_stats_impl(PySSLContext *self) } /*[clinic input] +@critical_section _ssl._SSLContext.get_ca_certs binary_form: bool = False @@ -4612,7 +4822,7 @@ been used at least once. static PyObject * _ssl__SSLContext_get_ca_certs_impl(PySSLContext *self, int binary_form) -/*[clinic end generated code: output=0d58f148f37e2938 input=6887b5a09b7f9076]*/ +/*[clinic end generated code: output=0d58f148f37e2938 input=eb0592909c9ad6e7]*/ { X509_STORE *store; STACK_OF(X509_OBJECT) *objs; @@ -4738,6 +4948,7 @@ static unsigned int psk_client_callback(SSL *s, #endif /*[clinic input] +@critical_section _ssl._SSLContext.set_psk_client_callback callback: object @@ -4746,7 +4957,7 @@ _ssl._SSLContext.set_psk_client_callback static PyObject * _ssl__SSLContext_set_psk_client_callback_impl(PySSLContext *self, PyObject *callback) -/*[clinic end generated code: output=0aba86f6ed75119e input=7627bae0e5ee7635]*/ +/*[clinic end generated code: output=0aba86f6ed75119e input=1e436eea625cfc35]*/ { #ifndef OPENSSL_NO_PSK if (self->protocol == PY_SSL_VERSION_TLS_SERVER) { @@ -4846,6 +5057,7 @@ static unsigned int psk_server_callback(SSL *s, #endif /*[clinic input] +@critical_section _ssl._SSLContext.set_psk_server_callback callback: object identity_hint: str(accept={str, NoneType}) = None @@ -4856,7 +5068,7 @@ static PyObject * _ssl__SSLContext_set_psk_server_callback_impl(PySSLContext *self, PyObject *callback, const char *identity_hint) -/*[clinic end generated code: output=1f4d6a4e09a92b03 input=65d4b6022aa85ea3]*/ +/*[clinic end generated code: output=1f4d6a4e09a92b03 input=5f79d932458284a7]*/ { #ifndef OPENSSL_NO_PSK if (self->protocol == PY_SSL_VERSION_TLS_CLIENT) { @@ -4901,26 +5113,19 @@ _ssl__SSLContext_set_psk_server_callback_impl(PySSLContext *self, static PyGetSetDef context_getsetlist[] = { - {"check_hostname", (getter) get_check_hostname, - (setter) set_check_hostname, NULL}, - {"_host_flags", (getter) get_host_flags, - (setter) set_host_flags, NULL}, - {"minimum_version", (getter) get_minimum_version, - (setter) set_minimum_version, NULL}, - {"maximum_version", (getter) get_maximum_version, - (setter) set_maximum_version, NULL}, + _SSL__SSLCONTEXT_CHECK_HOSTNAME_GETSETDEF + _SSL__SSLCONTEXT__HOST_FLAGS_GETSETDEF + _SSL__SSLCONTEXT_MINIMUM_VERSION_GETSETDEF + _SSL__SSLCONTEXT_MAXIMUM_VERSION_GETSETDEF {"keylog_filename", (getter) _PySSLContext_get_keylog_filename, (setter) _PySSLContext_set_keylog_filename, NULL}, {"_msg_callback", (getter) _PySSLContext_get_msg_callback, (setter) _PySSLContext_set_msg_callback, NULL}, - {"sni_callback", (getter) get_sni_callback, - (setter) set_sni_callback, PySSLContext_sni_callback_doc}, + _SSL__SSLCONTEXT_SNI_CALLBACK_GETSETDEF #if defined(TLS1_3_VERSION) && !defined(OPENSSL_NO_TLS1_3) - {"num_tickets", (getter) get_num_tickets, - (setter) set_num_tickets, PySSLContext_num_tickets_doc}, + _SSL__SSLCONTEXT_NUM_TICKETS_GETSETDEF #endif - {"options", (getter) get_options, - (setter) set_options, NULL}, + _SSL__SSLCONTEXT_OPTIONS_GETSETDEF {"post_handshake_auth", (getter) get_post_handshake_auth, #if defined(PySSL_HAVE_POST_HS_AUTH) (setter) set_post_handshake_auth, @@ -4928,14 +5133,10 @@ static PyGetSetDef context_getsetlist[] = { NULL, #endif NULL}, - {"protocol", (getter) get_protocol, - NULL, NULL}, - {"verify_flags", (getter) get_verify_flags, - (setter) set_verify_flags, NULL}, - {"verify_mode", (getter) get_verify_mode, - (setter) set_verify_mode, NULL}, - {"security_level", (getter) get_security_level, - NULL, PySSLContext_security_level_doc}, + _SSL__SSLCONTEXT_PROTOCOL_GETSETDEF + _SSL__SSLCONTEXT_VERIFY_FLAGS_GETSETDEF + _SSL__SSLCONTEXT_VERIFY_MODE_GETSETDEF + _SSL__SSLCONTEXT_SECURITY_LEVEL_GETSETDEF {NULL}, /* sentinel */ }; @@ -4982,6 +5183,7 @@ static PyType_Spec PySSLContext_spec = { */ /*[clinic input] +@critical_section @classmethod _ssl.MemoryBIO.__new__ @@ -4989,7 +5191,7 @@ _ssl.MemoryBIO.__new__ static PyObject * _ssl_MemoryBIO_impl(PyTypeObject *type) -/*[clinic end generated code: output=8820a58db78330ac input=26d22e4909ecb1b5]*/ +/*[clinic end generated code: output=8820a58db78330ac input=87f146cf30af454e]*/ { BIO *bio; PySSLMemoryBIO *self; @@ -5034,26 +5236,36 @@ memory_bio_dealloc(PySSLMemoryBIO *self) Py_DECREF(tp); } +/*[clinic input] +@critical_section +@getter +_ssl.MemoryBIO.pending +[clinic start generated code]*/ + static PyObject * -memory_bio_get_pending(PySSLMemoryBIO *self, void *c) +_ssl_MemoryBIO_pending_get_impl(PySSLMemoryBIO *self) +/*[clinic end generated code: output=19236a32a51ac8ff input=c0b6d14eba107f6a]*/ { - return PyLong_FromSize_t(BIO_ctrl_pending(self->bio)); + size_t res = BIO_ctrl_pending(self->bio); + return PyLong_FromSize_t(res); } -PyDoc_STRVAR(PySSL_memory_bio_pending_doc, -"The number of bytes pending in the memory BIO."); +/*[clinic input] +@critical_section +@getter +_ssl.MemoryBIO.eof +[clinic start generated code]*/ static PyObject * -memory_bio_get_eof(PySSLMemoryBIO *self, void *c) +_ssl_MemoryBIO_eof_get_impl(PySSLMemoryBIO *self) +/*[clinic end generated code: output=c255a9ea16e31b92 input=0f5c6be69752e04c]*/ { - return PyBool_FromLong((BIO_ctrl_pending(self->bio) == 0) - && self->eof_written); + size_t pending = BIO_ctrl_pending(self->bio); + return PyBool_FromLong((pending == 0) && self->eof_written); } -PyDoc_STRVAR(PySSL_memory_bio_eof_doc, -"Whether the memory BIO is at EOF."); - /*[clinic input] +@critical_section _ssl.MemoryBIO.read size as len: int = -1 / @@ -5068,7 +5280,7 @@ distinguish between the two. static PyObject * _ssl_MemoryBIO_read_impl(PySSLMemoryBIO *self, int len) -/*[clinic end generated code: output=a657aa1e79cd01b3 input=574d7be06a902366]*/ +/*[clinic end generated code: output=a657aa1e79cd01b3 input=21046f2d7dac3a90]*/ { int avail, nbytes; PyObject *result; @@ -5098,6 +5310,7 @@ _ssl_MemoryBIO_read_impl(PySSLMemoryBIO *self, int len) } /*[clinic input] +@critical_section _ssl.MemoryBIO.write b: Py_buffer / @@ -5109,7 +5322,7 @@ Returns the number of bytes written. static PyObject * _ssl_MemoryBIO_write_impl(PySSLMemoryBIO *self, Py_buffer *b) -/*[clinic end generated code: output=156ec59110d75935 input=e45757b3e17c4808]*/ +/*[clinic end generated code: output=156ec59110d75935 input=107da3f5fba26b37]*/ { int nbytes; @@ -5139,6 +5352,7 @@ _ssl_MemoryBIO_write_impl(PySSLMemoryBIO *self, Py_buffer *b) } /*[clinic input] +@critical_section _ssl.MemoryBIO.write_eof Write an EOF marker to the memory BIO. @@ -5148,7 +5362,7 @@ When all data has been read, the "eof" property will be True. static PyObject * _ssl_MemoryBIO_write_eof_impl(PySSLMemoryBIO *self) -/*[clinic end generated code: output=d4106276ccd1ed34 input=56a945f1d29e8bd6]*/ +/*[clinic end generated code: output=d4106276ccd1ed34 input=1e914231b1c5900a]*/ { self->eof_written = 1; /* After an EOF is written, a zero return from read() should be a real EOF @@ -5160,10 +5374,8 @@ _ssl_MemoryBIO_write_eof_impl(PySSLMemoryBIO *self) } static PyGetSetDef memory_bio_getsetlist[] = { - {"pending", (getter) memory_bio_get_pending, NULL, - PySSL_memory_bio_pending_doc}, - {"eof", (getter) memory_bio_get_eof, NULL, - PySSL_memory_bio_eof_doc}, + _SSL_MEMORYBIO_PENDING_GETSETDEF + _SSL_MEMORYBIO_EOF_GETSETDEF {NULL}, /* sentinel */ }; @@ -5283,8 +5495,16 @@ PySSLSession_clear(PySSLSession *self) } +/*[clinic input] +@critical_section +@getter +_ssl.SSLSession.time +[clinic start generated code]*/ + static PyObject * -PySSLSession_get_time(PySSLSession *self, void *closure) { +_ssl_SSLSession_time_get_impl(PySSLSession *self) +/*[clinic end generated code: output=4b887b9299de9be4 input=8d1e4afd09103279]*/ +{ #if OPENSSL_VERSION_NUMBER >= 0x30300000L return _PyLong_FromTime_t(SSL_SESSION_get_time_ex(self->session)); #else @@ -5292,65 +5512,72 @@ PySSLSession_get_time(PySSLSession *self, void *closure) { #endif } -PyDoc_STRVAR(PySSLSession_get_time_doc, -"Session creation time (seconds since epoch)."); - +/*[clinic input] +@critical_section +@getter +_ssl.SSLSession.timeout +[clinic start generated code]*/ static PyObject * -PySSLSession_get_timeout(PySSLSession *self, void *closure) { - return PyLong_FromLong(SSL_SESSION_get_timeout(self->session)); +_ssl_SSLSession_timeout_get_impl(PySSLSession *self) +/*[clinic end generated code: output=82339c148ab2f7d1 input=ae5e84a9d85df60d]*/ +{ + long timeout = SSL_SESSION_get_timeout(self->session); + PyObject *res = PyLong_FromLong(timeout); + return res; } -PyDoc_STRVAR(PySSLSession_get_timeout_doc, -"Session timeout (delta in seconds)."); - +/*[clinic input] +@critical_section +@getter +_ssl.SSLSession.ticket_lifetime_hint +[clinic start generated code]*/ static PyObject * -PySSLSession_get_ticket_lifetime_hint(PySSLSession *self, void *closure) { +_ssl_SSLSession_ticket_lifetime_hint_get_impl(PySSLSession *self) +/*[clinic end generated code: output=c8b6db498136c275 input=d0e06942ddd8d07f]*/ +{ unsigned long hint = SSL_SESSION_get_ticket_lifetime_hint(self->session); return PyLong_FromUnsignedLong(hint); } -PyDoc_STRVAR(PySSLSession_get_ticket_lifetime_hint_doc, -"Ticket life time hint."); - +/*[clinic input] +@critical_section +@getter +_ssl.SSLSession.id +[clinic start generated code]*/ static PyObject * -PySSLSession_get_session_id(PySSLSession *self, void *closure) { +_ssl_SSLSession_id_get_impl(PySSLSession *self) +/*[clinic end generated code: output=c532fb96b10c5adf input=e7322372cf6325dd]*/ + +{ const unsigned char *id; unsigned int len; id = SSL_SESSION_get_id(self->session, &len); return PyBytes_FromStringAndSize((const char *)id, len); } -PyDoc_STRVAR(PySSLSession_get_session_id_doc, -"Session id"); - +/*[clinic input] +@critical_section +@getter +_ssl.SSLSession.has_ticket +[clinic start generated code]*/ static PyObject * -PySSLSession_get_has_ticket(PySSLSession *self, void *closure) { - if (SSL_SESSION_has_ticket(self->session)) { - Py_RETURN_TRUE; - } else { - Py_RETURN_FALSE; - } +_ssl_SSLSession_has_ticket_get_impl(PySSLSession *self) +/*[clinic end generated code: output=aa3ccfc40b10b96d input=1a48ae8955fa9601]*/ +{ + int res = SSL_SESSION_has_ticket(self->session); + return res ? Py_True : Py_False; } -PyDoc_STRVAR(PySSLSession_get_has_ticket_doc, -"Does the session contain a ticket?"); - - static PyGetSetDef PySSLSession_getsetlist[] = { - {"has_ticket", (getter) PySSLSession_get_has_ticket, NULL, - PySSLSession_get_has_ticket_doc}, - {"id", (getter) PySSLSession_get_session_id, NULL, - PySSLSession_get_session_id_doc}, - {"ticket_lifetime_hint", (getter) PySSLSession_get_ticket_lifetime_hint, - NULL, PySSLSession_get_ticket_lifetime_hint_doc}, - {"time", (getter) PySSLSession_get_time, NULL, - PySSLSession_get_time_doc}, - {"timeout", (getter) PySSLSession_get_timeout, NULL, - PySSLSession_get_timeout_doc}, + _SSL_SSLSESSION_HAS_TICKET_GETSETDEF + _SSL_SSLSESSION_ID_GETSETDEF + _SSL_SSLSESSION_TICKET_LIFETIME_HINT_GETSETDEF + _SSL_SSLSESSION_TIME_GETSETDEF + _SSL_SSLSESSION_TIMEOUT_GETSETDEF {NULL}, /* sentinel */ }; @@ -5375,6 +5602,7 @@ static PyType_Spec PySSLSession_spec = { /* helper routines for seeding the SSL PRNG */ /*[clinic input] +@critical_section _ssl.RAND_add string as view: Py_buffer(accept={str, buffer}) entropy: double @@ -5388,7 +5616,7 @@ string. See RFC 4086. static PyObject * _ssl_RAND_add_impl(PyObject *module, Py_buffer *view, double entropy) -/*[clinic end generated code: output=e6dd48df9c9024e9 input=5c33017422828f5c]*/ +/*[clinic end generated code: output=e6dd48df9c9024e9 input=313cb73b34db31d5]*/ { const char *buf; Py_ssize_t len, written; @@ -5444,6 +5672,7 @@ PySSL_RAND(PyObject *module, int len, int pseudo) } /*[clinic input] +@critical_section _ssl.RAND_bytes n: int / @@ -5453,13 +5682,14 @@ Generate n cryptographically strong pseudo-random bytes. static PyObject * _ssl_RAND_bytes_impl(PyObject *module, int n) -/*[clinic end generated code: output=977da635e4838bc7 input=678ddf2872dfebfc]*/ +/*[clinic end generated code: output=977da635e4838bc7 input=2e78ce1e86336776]*/ { return PySSL_RAND(module, n, 0); } /*[clinic input] +@critical_section _ssl.RAND_status Returns True if the OpenSSL PRNG has been seeded with enough data and False if not. @@ -5470,12 +5700,13 @@ using the ssl() function. static PyObject * _ssl_RAND_status_impl(PyObject *module) -/*[clinic end generated code: output=7e0aaa2d39fdc1ad input=d5ae5aea52f36e01]*/ +/*[clinic end generated code: output=7e0aaa2d39fdc1ad input=636fb5659ea2e727]*/ { return PyBool_FromLong(RAND_status()); } /*[clinic input] +@critical_section _ssl.get_default_verify_paths Return search paths and environment vars that are used by SSLContext's set_default_verify_paths() to load default CAs. @@ -5485,7 +5716,7 @@ The values are 'cert_file_env', 'cert_file', 'cert_dir_env', 'cert_dir'. static PyObject * _ssl_get_default_verify_paths_impl(PyObject *module) -/*[clinic end generated code: output=e5b62a466271928b input=5210c953d98c3eb5]*/ +/*[clinic end generated code: output=e5b62a466271928b input=c6ae00bc04eb2b6e]*/ { PyObject *ofile_env = NULL; PyObject *ofile = NULL; @@ -5534,6 +5765,7 @@ asn1obj2py(_sslmodulestate *state, ASN1_OBJECT *obj) } /*[clinic input] +@critical_section _ssl.txt2obj txt: str name: bool = False @@ -5546,7 +5778,7 @@ long name are also matched. static PyObject * _ssl_txt2obj_impl(PyObject *module, const char *txt, int name) -/*[clinic end generated code: output=c38e3991347079c1 input=1c1e7d0aa7c48602]*/ +/*[clinic end generated code: output=c38e3991347079c1 input=c99b134d70173c5e]*/ { PyObject *result = NULL; ASN1_OBJECT *obj; @@ -5562,6 +5794,7 @@ _ssl_txt2obj_impl(PyObject *module, const char *txt, int name) } /*[clinic input] +@critical_section _ssl.nid2obj nid: int / @@ -5571,7 +5804,7 @@ Lookup NID, short name, long name and OID of an ASN1_OBJECT by NID. static PyObject * _ssl_nid2obj_impl(PyObject *module, int nid) -/*[clinic end generated code: output=4a98ab691cd4f84a input=51787a3bee7d8f98]*/ +/*[clinic end generated code: output=4a98ab691cd4f84a input=1b1170506fa83a53]*/ { PyObject *result = NULL; ASN1_OBJECT *obj; @@ -5723,6 +5956,7 @@ ssl_collect_certificates(const char *store_name) } /*[clinic input] +@critical_section _ssl.enum_certificates store_name: str @@ -5737,7 +5971,7 @@ a set of OIDs or the boolean True. static PyObject * _ssl_enum_certificates_impl(PyObject *module, const char *store_name) -/*[clinic end generated code: output=5134dc8bb3a3c893 input=915f60d70461ea4e]*/ +/*[clinic end generated code: output=5134dc8bb3a3c893 input=263c22e6c6988cf3]*/ { HCERTSTORE hCollectionStore = NULL; PCCERT_CONTEXT pCertCtx = NULL; @@ -5822,6 +6056,7 @@ _ssl_enum_certificates_impl(PyObject *module, const char *store_name) } /*[clinic input] +@critical_section _ssl.enum_crls store_name: str @@ -5835,7 +6070,7 @@ X509_ASN_ENCODING or PKCS_7_ASN_ENCODING. static PyObject * _ssl_enum_crls_impl(PyObject *module, const char *store_name) -/*[clinic end generated code: output=bce467f60ccd03b6 input=a1f1d7629f1c5d3d]*/ +/*[clinic end generated code: output=bce467f60ccd03b6 input=51a1b1059e55ce43]*/ { HCERTSTORE hCollectionStore = NULL; PCCRL_CONTEXT pCrlCtx = NULL; diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index e8d1342ed35e66..9d5b70dfad553d 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_critical_section.h"// Py_BEGIN_CRITICAL_SECTION() #include "pycore_modsupport.h" // _PyArg_CheckPositional() PyDoc_STRVAR(_ssl__SSLSocket_do_handshake__doc__, @@ -22,7 +23,13 @@ _ssl__SSLSocket_do_handshake_impl(PySSLSocket *self); static PyObject * _ssl__SSLSocket_do_handshake(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) { - return _ssl__SSLSocket_do_handshake_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_do_handshake_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl__test_decode_cert__doc__, @@ -88,7 +95,9 @@ _ssl__SSLSocket_getpeercert(PySSLSocket *self, PyObject *const *args, Py_ssize_t goto exit; } skip_optional: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLSocket_getpeercert_impl(self, binary_mode); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -108,7 +117,13 @@ _ssl__SSLSocket_get_verified_chain_impl(PySSLSocket *self); static PyObject * _ssl__SSLSocket_get_verified_chain(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) { - return _ssl__SSLSocket_get_verified_chain_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_get_verified_chain_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl__SSLSocket_get_unverified_chain__doc__, @@ -125,7 +140,13 @@ _ssl__SSLSocket_get_unverified_chain_impl(PySSLSocket *self); static PyObject * _ssl__SSLSocket_get_unverified_chain(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) { - return _ssl__SSLSocket_get_unverified_chain_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_get_unverified_chain_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl__SSLSocket_shared_ciphers__doc__, @@ -142,7 +163,13 @@ _ssl__SSLSocket_shared_ciphers_impl(PySSLSocket *self); static PyObject * _ssl__SSLSocket_shared_ciphers(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) { - return _ssl__SSLSocket_shared_ciphers_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_shared_ciphers_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl__SSLSocket_cipher__doc__, @@ -159,7 +186,13 @@ _ssl__SSLSocket_cipher_impl(PySSLSocket *self); static PyObject * _ssl__SSLSocket_cipher(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) { - return _ssl__SSLSocket_cipher_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_cipher_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl__SSLSocket_version__doc__, @@ -176,7 +209,13 @@ _ssl__SSLSocket_version_impl(PySSLSocket *self); static PyObject * _ssl__SSLSocket_version(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) { - return _ssl__SSLSocket_version_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_version_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl__SSLSocket_selected_alpn_protocol__doc__, @@ -193,7 +232,13 @@ _ssl__SSLSocket_selected_alpn_protocol_impl(PySSLSocket *self); static PyObject * _ssl__SSLSocket_selected_alpn_protocol(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) { - return _ssl__SSLSocket_selected_alpn_protocol_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_selected_alpn_protocol_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl__SSLSocket_compression__doc__, @@ -213,6 +258,176 @@ _ssl__SSLSocket_compression(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) return _ssl__SSLSocket_compression_impl(self); } +#if defined(_ssl__SSLSocket_context_HAS_DOCSTR) +# define _ssl__SSLSocket_context_DOCSTR _ssl__SSLSocket_context__doc__ +#else +# define _ssl__SSLSocket_context_DOCSTR NULL +#endif +#if defined(_SSL__SSLSOCKET_CONTEXT_GETSETDEF) +# undef _SSL__SSLSOCKET_CONTEXT_GETSETDEF +# define _SSL__SSLSOCKET_CONTEXT_GETSETDEF {"context", (getter)_ssl__SSLSocket_context_get, (setter)_ssl__SSLSocket_context_set, _ssl__SSLSocket_context_DOCSTR}, +#else +# define _SSL__SSLSOCKET_CONTEXT_GETSETDEF {"context", (getter)_ssl__SSLSocket_context_get, NULL, _ssl__SSLSocket_context_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLSocket_context_get_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_context_get(PySSLSocket *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_context_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_SSL__SSLSOCKET_CONTEXT_HAS_DOCSTR) +# define _ssl__SSLSocket_context_DOCSTR _ssl__SSLSocket_context__doc__ +#else +# define _ssl__SSLSocket_context_DOCSTR NULL +#endif +#if defined(_SSL__SSLSOCKET_CONTEXT_GETSETDEF) +# undef _SSL__SSLSOCKET_CONTEXT_GETSETDEF +# define _SSL__SSLSOCKET_CONTEXT_GETSETDEF {"context", (getter)_ssl__SSLSocket_context_get, (setter)_ssl__SSLSocket_context_set, _ssl__SSLSocket_context_DOCSTR}, +#else +# define _SSL__SSLSOCKET_CONTEXT_GETSETDEF {"context", NULL, (setter)_ssl__SSLSocket_context_set, NULL}, +#endif + +static int +_ssl__SSLSocket_context_set_impl(PySSLSocket *self, PyObject *value); + +static int +_ssl__SSLSocket_context_set(PySSLSocket *self, PyObject *value, void *Py_UNUSED(context)) +{ + int return_value; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_context_set_impl(self, value); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +PyDoc_STRVAR(_ssl__SSLSocket_server_side__doc__, +"Whether this is a server-side socket."); +#define _ssl__SSLSocket_server_side_HAS_DOCSTR + +#if defined(_ssl__SSLSocket_server_side_HAS_DOCSTR) +# define _ssl__SSLSocket_server_side_DOCSTR _ssl__SSLSocket_server_side__doc__ +#else +# define _ssl__SSLSocket_server_side_DOCSTR NULL +#endif +#if defined(_SSL__SSLSOCKET_SERVER_SIDE_GETSETDEF) +# undef _SSL__SSLSOCKET_SERVER_SIDE_GETSETDEF +# define _SSL__SSLSOCKET_SERVER_SIDE_GETSETDEF {"server_side", (getter)_ssl__SSLSocket_server_side_get, (setter)_ssl__SSLSocket_server_side_set, _ssl__SSLSocket_server_side_DOCSTR}, +#else +# define _SSL__SSLSOCKET_SERVER_SIDE_GETSETDEF {"server_side", (getter)_ssl__SSLSocket_server_side_get, NULL, _ssl__SSLSocket_server_side_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLSocket_server_side_get_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_server_side_get(PySSLSocket *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_server_side_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +PyDoc_STRVAR(_ssl__SSLSocket_server_hostname__doc__, +"The currently set server hostname (for SNI)."); +#define _ssl__SSLSocket_server_hostname_HAS_DOCSTR + +#if defined(_ssl__SSLSocket_server_hostname_HAS_DOCSTR) +# define _ssl__SSLSocket_server_hostname_DOCSTR _ssl__SSLSocket_server_hostname__doc__ +#else +# define _ssl__SSLSocket_server_hostname_DOCSTR NULL +#endif +#if defined(_SSL__SSLSOCKET_SERVER_HOSTNAME_GETSETDEF) +# undef _SSL__SSLSOCKET_SERVER_HOSTNAME_GETSETDEF +# define _SSL__SSLSOCKET_SERVER_HOSTNAME_GETSETDEF {"server_hostname", (getter)_ssl__SSLSocket_server_hostname_get, (setter)_ssl__SSLSocket_server_hostname_set, _ssl__SSLSocket_server_hostname_DOCSTR}, +#else +# define _SSL__SSLSOCKET_SERVER_HOSTNAME_GETSETDEF {"server_hostname", (getter)_ssl__SSLSocket_server_hostname_get, NULL, _ssl__SSLSocket_server_hostname_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLSocket_server_hostname_get_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_server_hostname_get(PySSLSocket *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_server_hostname_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_ssl__SSLSocket_owner_HAS_DOCSTR) +# define _ssl__SSLSocket_owner_DOCSTR _ssl__SSLSocket_owner__doc__ +#else +# define _ssl__SSLSocket_owner_DOCSTR NULL +#endif +#if defined(_SSL__SSLSOCKET_OWNER_GETSETDEF) +# undef _SSL__SSLSOCKET_OWNER_GETSETDEF +# define _SSL__SSLSOCKET_OWNER_GETSETDEF {"owner", (getter)_ssl__SSLSocket_owner_get, (setter)_ssl__SSLSocket_owner_set, _ssl__SSLSocket_owner_DOCSTR}, +#else +# define _SSL__SSLSOCKET_OWNER_GETSETDEF {"owner", (getter)_ssl__SSLSocket_owner_get, NULL, _ssl__SSLSocket_owner_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLSocket_owner_get_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_owner_get(PySSLSocket *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_owner_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_SSL__SSLSOCKET_OWNER_HAS_DOCSTR) +# define _ssl__SSLSocket_owner_DOCSTR _ssl__SSLSocket_owner__doc__ +#else +# define _ssl__SSLSocket_owner_DOCSTR NULL +#endif +#if defined(_SSL__SSLSOCKET_OWNER_GETSETDEF) +# undef _SSL__SSLSOCKET_OWNER_GETSETDEF +# define _SSL__SSLSOCKET_OWNER_GETSETDEF {"owner", (getter)_ssl__SSLSocket_owner_get, (setter)_ssl__SSLSocket_owner_set, _ssl__SSLSocket_owner_DOCSTR}, +#else +# define _SSL__SSLSOCKET_OWNER_GETSETDEF {"owner", NULL, (setter)_ssl__SSLSocket_owner_set, NULL}, +#endif + +static int +_ssl__SSLSocket_owner_set_impl(PySSLSocket *self, PyObject *value); + +static int +_ssl__SSLSocket_owner_set(PySSLSocket *self, PyObject *value, void *Py_UNUSED(context)) +{ + int return_value; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_owner_set_impl(self, value); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + PyDoc_STRVAR(_ssl__SSLSocket_write__doc__, "write($self, b, /)\n" "--\n" @@ -236,7 +451,9 @@ _ssl__SSLSocket_write(PySSLSocket *self, PyObject *arg) if (PyObject_GetBuffer(arg, &b, PyBUF_SIMPLE) != 0) { goto exit; } + Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLSocket_write_impl(self, &b); + Py_END_CRITICAL_SECTION(); exit: /* Cleanup for b */ @@ -262,7 +479,13 @@ _ssl__SSLSocket_pending_impl(PySSLSocket *self); static PyObject * _ssl__SSLSocket_pending(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) { - return _ssl__SSLSocket_pending_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_pending_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl__SSLSocket_read__doc__, @@ -300,7 +523,9 @@ _ssl__SSLSocket_read(PySSLSocket *self, PyObject *args) PyErr_SetString(PyExc_TypeError, "_ssl._SSLSocket.read requires 1 to 2 arguments"); goto exit; } + Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLSocket_read_impl(self, len, group_right_1, &buffer); + Py_END_CRITICAL_SECTION(); exit: /* Cleanup for buffer */ @@ -326,7 +551,13 @@ _ssl__SSLSocket_shutdown_impl(PySSLSocket *self); static PyObject * _ssl__SSLSocket_shutdown(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) { - return _ssl__SSLSocket_shutdown_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_shutdown_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl__SSLSocket_get_channel_binding__doc__, @@ -400,7 +631,9 @@ _ssl__SSLSocket_get_channel_binding(PySSLSocket *self, PyObject *const *args, Py goto exit; } skip_optional_pos: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLSocket_get_channel_binding_impl(self, cb_type); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -421,117 +654,708 @@ _ssl__SSLSocket_verify_client_post_handshake_impl(PySSLSocket *self); static PyObject * _ssl__SSLSocket_verify_client_post_handshake(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) { - return _ssl__SSLSocket_verify_client_post_handshake_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_verify_client_post_handshake_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_ssl__SSLSocket_session_HAS_DOCSTR) +# define _ssl__SSLSocket_session_DOCSTR _ssl__SSLSocket_session__doc__ +#else +# define _ssl__SSLSocket_session_DOCSTR NULL +#endif +#if defined(_SSL__SSLSOCKET_SESSION_GETSETDEF) +# undef _SSL__SSLSOCKET_SESSION_GETSETDEF +# define _SSL__SSLSOCKET_SESSION_GETSETDEF {"session", (getter)_ssl__SSLSocket_session_get, (setter)_ssl__SSLSocket_session_set, _ssl__SSLSocket_session_DOCSTR}, +#else +# define _SSL__SSLSOCKET_SESSION_GETSETDEF {"session", (getter)_ssl__SSLSocket_session_get, NULL, _ssl__SSLSocket_session_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLSocket_session_get_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_session_get(PySSLSocket *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_session_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_SSL__SSLSOCKET_SESSION_HAS_DOCSTR) +# define _ssl__SSLSocket_session_DOCSTR _ssl__SSLSocket_session__doc__ +#else +# define _ssl__SSLSocket_session_DOCSTR NULL +#endif +#if defined(_SSL__SSLSOCKET_SESSION_GETSETDEF) +# undef _SSL__SSLSOCKET_SESSION_GETSETDEF +# define _SSL__SSLSOCKET_SESSION_GETSETDEF {"session", (getter)_ssl__SSLSocket_session_get, (setter)_ssl__SSLSocket_session_set, _ssl__SSLSocket_session_DOCSTR}, +#else +# define _SSL__SSLSOCKET_SESSION_GETSETDEF {"session", NULL, (setter)_ssl__SSLSocket_session_set, NULL}, +#endif + +static int +_ssl__SSLSocket_session_set_impl(PySSLSocket *self, PyObject *value); + +static int +_ssl__SSLSocket_session_set(PySSLSocket *self, PyObject *value, void *Py_UNUSED(context)) +{ + int return_value; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_session_set_impl(self, value); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +PyDoc_STRVAR(_ssl__SSLSocket_session_reused__doc__, +"Was the client session reused during handshake?"); +#define _ssl__SSLSocket_session_reused_HAS_DOCSTR + +#if defined(_ssl__SSLSocket_session_reused_HAS_DOCSTR) +# define _ssl__SSLSocket_session_reused_DOCSTR _ssl__SSLSocket_session_reused__doc__ +#else +# define _ssl__SSLSocket_session_reused_DOCSTR NULL +#endif +#if defined(_SSL__SSLSOCKET_SESSION_REUSED_GETSETDEF) +# undef _SSL__SSLSOCKET_SESSION_REUSED_GETSETDEF +# define _SSL__SSLSOCKET_SESSION_REUSED_GETSETDEF {"session_reused", (getter)_ssl__SSLSocket_session_reused_get, (setter)_ssl__SSLSocket_session_reused_set, _ssl__SSLSocket_session_reused_DOCSTR}, +#else +# define _SSL__SSLSOCKET_SESSION_REUSED_GETSETDEF {"session_reused", (getter)_ssl__SSLSocket_session_reused_get, NULL, _ssl__SSLSocket_session_reused_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLSocket_session_reused_get_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_session_reused_get(PySSLSocket *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_session_reused_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +static PyObject * +_ssl__SSLContext_impl(PyTypeObject *type, int proto_version); + +static PyObject * +_ssl__SSLContext(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + PyTypeObject *base_tp = get_state_type(type)->PySSLContext_Type; + int proto_version; + + if ((type == base_tp || type->tp_init == base_tp->tp_init) && + !_PyArg_NoKeywords("_SSLContext", kwargs)) { + goto exit; + } + if (!_PyArg_CheckPositional("_SSLContext", PyTuple_GET_SIZE(args), 1, 1)) { + goto exit; + } + proto_version = PyLong_AsInt(PyTuple_GET_ITEM(args, 0)); + if (proto_version == -1 && PyErr_Occurred()) { + goto exit; + } + Py_BEGIN_CRITICAL_SECTION(type); + return_value = _ssl__SSLContext_impl(type, proto_version); + Py_END_CRITICAL_SECTION(); + +exit: + return return_value; +} + +PyDoc_STRVAR(_ssl__SSLContext_set_ciphers__doc__, +"set_ciphers($self, cipherlist, /)\n" +"--\n" +"\n"); + +#define _SSL__SSLCONTEXT_SET_CIPHERS_METHODDEF \ + {"set_ciphers", (PyCFunction)_ssl__SSLContext_set_ciphers, METH_O, _ssl__SSLContext_set_ciphers__doc__}, + +static PyObject * +_ssl__SSLContext_set_ciphers_impl(PySSLContext *self, const char *cipherlist); + +static PyObject * +_ssl__SSLContext_set_ciphers(PySSLContext *self, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *cipherlist; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("set_ciphers", "argument", "str", arg); + goto exit; + } + Py_ssize_t cipherlist_length; + cipherlist = PyUnicode_AsUTF8AndSize(arg, &cipherlist_length); + if (cipherlist == NULL) { + goto exit; + } + if (strlen(cipherlist) != (size_t)cipherlist_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_set_ciphers_impl(self, cipherlist); + Py_END_CRITICAL_SECTION(); + +exit: + return return_value; +} + +PyDoc_STRVAR(_ssl__SSLContext_get_ciphers__doc__, +"get_ciphers($self, /)\n" +"--\n" +"\n"); + +#define _SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF \ + {"get_ciphers", (PyCFunction)_ssl__SSLContext_get_ciphers, METH_NOARGS, _ssl__SSLContext_get_ciphers__doc__}, + +static PyObject * +_ssl__SSLContext_get_ciphers_impl(PySSLContext *self); + +static PyObject * +_ssl__SSLContext_get_ciphers(PySSLContext *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_get_ciphers_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +PyDoc_STRVAR(_ssl__SSLContext__set_alpn_protocols__doc__, +"_set_alpn_protocols($self, protos, /)\n" +"--\n" +"\n"); + +#define _SSL__SSLCONTEXT__SET_ALPN_PROTOCOLS_METHODDEF \ + {"_set_alpn_protocols", (PyCFunction)_ssl__SSLContext__set_alpn_protocols, METH_O, _ssl__SSLContext__set_alpn_protocols__doc__}, + +static PyObject * +_ssl__SSLContext__set_alpn_protocols_impl(PySSLContext *self, + Py_buffer *protos); + +static PyObject * +_ssl__SSLContext__set_alpn_protocols(PySSLContext *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer protos = {NULL, NULL}; + + if (PyObject_GetBuffer(arg, &protos, PyBUF_SIMPLE) != 0) { + goto exit; + } + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext__set_alpn_protocols_impl(self, &protos); + Py_END_CRITICAL_SECTION(); + +exit: + /* Cleanup for protos */ + if (protos.obj) { + PyBuffer_Release(&protos); + } + + return return_value; +} + +#if defined(_ssl__SSLContext_verify_mode_HAS_DOCSTR) +# define _ssl__SSLContext_verify_mode_DOCSTR _ssl__SSLContext_verify_mode__doc__ +#else +# define _ssl__SSLContext_verify_mode_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_VERIFY_MODE_GETSETDEF) +# undef _SSL__SSLCONTEXT_VERIFY_MODE_GETSETDEF +# define _SSL__SSLCONTEXT_VERIFY_MODE_GETSETDEF {"verify_mode", (getter)_ssl__SSLContext_verify_mode_get, (setter)_ssl__SSLContext_verify_mode_set, _ssl__SSLContext_verify_mode_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_VERIFY_MODE_GETSETDEF {"verify_mode", (getter)_ssl__SSLContext_verify_mode_get, NULL, _ssl__SSLContext_verify_mode_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLContext_verify_mode_get_impl(PySSLContext *self); + +static PyObject * +_ssl__SSLContext_verify_mode_get(PySSLContext *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_verify_mode_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_SSL__SSLCONTEXT_VERIFY_MODE_HAS_DOCSTR) +# define _ssl__SSLContext_verify_mode_DOCSTR _ssl__SSLContext_verify_mode__doc__ +#else +# define _ssl__SSLContext_verify_mode_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_VERIFY_MODE_GETSETDEF) +# undef _SSL__SSLCONTEXT_VERIFY_MODE_GETSETDEF +# define _SSL__SSLCONTEXT_VERIFY_MODE_GETSETDEF {"verify_mode", (getter)_ssl__SSLContext_verify_mode_get, (setter)_ssl__SSLContext_verify_mode_set, _ssl__SSLContext_verify_mode_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_VERIFY_MODE_GETSETDEF {"verify_mode", NULL, (setter)_ssl__SSLContext_verify_mode_set, NULL}, +#endif + +static int +_ssl__SSLContext_verify_mode_set_impl(PySSLContext *self, PyObject *value); + +static int +_ssl__SSLContext_verify_mode_set(PySSLContext *self, PyObject *value, void *Py_UNUSED(context)) +{ + int return_value; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_verify_mode_set_impl(self, value); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_ssl__SSLContext_verify_flags_HAS_DOCSTR) +# define _ssl__SSLContext_verify_flags_DOCSTR _ssl__SSLContext_verify_flags__doc__ +#else +# define _ssl__SSLContext_verify_flags_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_VERIFY_FLAGS_GETSETDEF) +# undef _SSL__SSLCONTEXT_VERIFY_FLAGS_GETSETDEF +# define _SSL__SSLCONTEXT_VERIFY_FLAGS_GETSETDEF {"verify_flags", (getter)_ssl__SSLContext_verify_flags_get, (setter)_ssl__SSLContext_verify_flags_set, _ssl__SSLContext_verify_flags_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_VERIFY_FLAGS_GETSETDEF {"verify_flags", (getter)_ssl__SSLContext_verify_flags_get, NULL, _ssl__SSLContext_verify_flags_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLContext_verify_flags_get_impl(PySSLContext *self); + +static PyObject * +_ssl__SSLContext_verify_flags_get(PySSLContext *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_verify_flags_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_SSL__SSLCONTEXT_VERIFY_FLAGS_HAS_DOCSTR) +# define _ssl__SSLContext_verify_flags_DOCSTR _ssl__SSLContext_verify_flags__doc__ +#else +# define _ssl__SSLContext_verify_flags_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_VERIFY_FLAGS_GETSETDEF) +# undef _SSL__SSLCONTEXT_VERIFY_FLAGS_GETSETDEF +# define _SSL__SSLCONTEXT_VERIFY_FLAGS_GETSETDEF {"verify_flags", (getter)_ssl__SSLContext_verify_flags_get, (setter)_ssl__SSLContext_verify_flags_set, _ssl__SSLContext_verify_flags_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_VERIFY_FLAGS_GETSETDEF {"verify_flags", NULL, (setter)_ssl__SSLContext_verify_flags_set, NULL}, +#endif + +static int +_ssl__SSLContext_verify_flags_set_impl(PySSLContext *self, PyObject *value); + +static int +_ssl__SSLContext_verify_flags_set(PySSLContext *self, PyObject *value, void *Py_UNUSED(context)) +{ + int return_value; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_verify_flags_set_impl(self, value); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_ssl__SSLContext_minimum_version_HAS_DOCSTR) +# define _ssl__SSLContext_minimum_version_DOCSTR _ssl__SSLContext_minimum_version__doc__ +#else +# define _ssl__SSLContext_minimum_version_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_MINIMUM_VERSION_GETSETDEF) +# undef _SSL__SSLCONTEXT_MINIMUM_VERSION_GETSETDEF +# define _SSL__SSLCONTEXT_MINIMUM_VERSION_GETSETDEF {"minimum_version", (getter)_ssl__SSLContext_minimum_version_get, (setter)_ssl__SSLContext_minimum_version_set, _ssl__SSLContext_minimum_version_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_MINIMUM_VERSION_GETSETDEF {"minimum_version", (getter)_ssl__SSLContext_minimum_version_get, NULL, _ssl__SSLContext_minimum_version_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLContext_minimum_version_get_impl(PySSLContext *self); + +static PyObject * +_ssl__SSLContext_minimum_version_get(PySSLContext *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_minimum_version_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_SSL__SSLCONTEXT_MINIMUM_VERSION_HAS_DOCSTR) +# define _ssl__SSLContext_minimum_version_DOCSTR _ssl__SSLContext_minimum_version__doc__ +#else +# define _ssl__SSLContext_minimum_version_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_MINIMUM_VERSION_GETSETDEF) +# undef _SSL__SSLCONTEXT_MINIMUM_VERSION_GETSETDEF +# define _SSL__SSLCONTEXT_MINIMUM_VERSION_GETSETDEF {"minimum_version", (getter)_ssl__SSLContext_minimum_version_get, (setter)_ssl__SSLContext_minimum_version_set, _ssl__SSLContext_minimum_version_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_MINIMUM_VERSION_GETSETDEF {"minimum_version", NULL, (setter)_ssl__SSLContext_minimum_version_set, NULL}, +#endif + +static int +_ssl__SSLContext_minimum_version_set_impl(PySSLContext *self, + PyObject *value); + +static int +_ssl__SSLContext_minimum_version_set(PySSLContext *self, PyObject *value, void *Py_UNUSED(context)) +{ + int return_value; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_minimum_version_set_impl(self, value); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_ssl__SSLContext_maximum_version_HAS_DOCSTR) +# define _ssl__SSLContext_maximum_version_DOCSTR _ssl__SSLContext_maximum_version__doc__ +#else +# define _ssl__SSLContext_maximum_version_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_MAXIMUM_VERSION_GETSETDEF) +# undef _SSL__SSLCONTEXT_MAXIMUM_VERSION_GETSETDEF +# define _SSL__SSLCONTEXT_MAXIMUM_VERSION_GETSETDEF {"maximum_version", (getter)_ssl__SSLContext_maximum_version_get, (setter)_ssl__SSLContext_maximum_version_set, _ssl__SSLContext_maximum_version_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_MAXIMUM_VERSION_GETSETDEF {"maximum_version", (getter)_ssl__SSLContext_maximum_version_get, NULL, _ssl__SSLContext_maximum_version_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLContext_maximum_version_get_impl(PySSLContext *self); + +static PyObject * +_ssl__SSLContext_maximum_version_get(PySSLContext *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_maximum_version_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_SSL__SSLCONTEXT_MAXIMUM_VERSION_HAS_DOCSTR) +# define _ssl__SSLContext_maximum_version_DOCSTR _ssl__SSLContext_maximum_version__doc__ +#else +# define _ssl__SSLContext_maximum_version_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_MAXIMUM_VERSION_GETSETDEF) +# undef _SSL__SSLCONTEXT_MAXIMUM_VERSION_GETSETDEF +# define _SSL__SSLCONTEXT_MAXIMUM_VERSION_GETSETDEF {"maximum_version", (getter)_ssl__SSLContext_maximum_version_get, (setter)_ssl__SSLContext_maximum_version_set, _ssl__SSLContext_maximum_version_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_MAXIMUM_VERSION_GETSETDEF {"maximum_version", NULL, (setter)_ssl__SSLContext_maximum_version_set, NULL}, +#endif + +static int +_ssl__SSLContext_maximum_version_set_impl(PySSLContext *self, + PyObject *value); + +static int +_ssl__SSLContext_maximum_version_set(PySSLContext *self, PyObject *value, void *Py_UNUSED(context)) +{ + int return_value; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_maximum_version_set_impl(self, value); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_ssl__SSLContext_num_tickets_HAS_DOCSTR) +# define _ssl__SSLContext_num_tickets_DOCSTR _ssl__SSLContext_num_tickets__doc__ +#else +# define _ssl__SSLContext_num_tickets_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_NUM_TICKETS_GETSETDEF) +# undef _SSL__SSLCONTEXT_NUM_TICKETS_GETSETDEF +# define _SSL__SSLCONTEXT_NUM_TICKETS_GETSETDEF {"num_tickets", (getter)_ssl__SSLContext_num_tickets_get, (setter)_ssl__SSLContext_num_tickets_set, _ssl__SSLContext_num_tickets_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_NUM_TICKETS_GETSETDEF {"num_tickets", (getter)_ssl__SSLContext_num_tickets_get, NULL, _ssl__SSLContext_num_tickets_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLContext_num_tickets_get_impl(PySSLContext *self); + +static PyObject * +_ssl__SSLContext_num_tickets_get(PySSLContext *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_num_tickets_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_SSL__SSLCONTEXT_NUM_TICKETS_HAS_DOCSTR) +# define _ssl__SSLContext_num_tickets_DOCSTR _ssl__SSLContext_num_tickets__doc__ +#else +# define _ssl__SSLContext_num_tickets_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_NUM_TICKETS_GETSETDEF) +# undef _SSL__SSLCONTEXT_NUM_TICKETS_GETSETDEF +# define _SSL__SSLCONTEXT_NUM_TICKETS_GETSETDEF {"num_tickets", (getter)_ssl__SSLContext_num_tickets_get, (setter)_ssl__SSLContext_num_tickets_set, _ssl__SSLContext_num_tickets_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_NUM_TICKETS_GETSETDEF {"num_tickets", NULL, (setter)_ssl__SSLContext_num_tickets_set, NULL}, +#endif + +static int +_ssl__SSLContext_num_tickets_set_impl(PySSLContext *self, PyObject *value); + +static int +_ssl__SSLContext_num_tickets_set(PySSLContext *self, PyObject *value, void *Py_UNUSED(context)) +{ + int return_value; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_num_tickets_set_impl(self, value); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_ssl__SSLContext_security_level_HAS_DOCSTR) +# define _ssl__SSLContext_security_level_DOCSTR _ssl__SSLContext_security_level__doc__ +#else +# define _ssl__SSLContext_security_level_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_SECURITY_LEVEL_GETSETDEF) +# undef _SSL__SSLCONTEXT_SECURITY_LEVEL_GETSETDEF +# define _SSL__SSLCONTEXT_SECURITY_LEVEL_GETSETDEF {"security_level", (getter)_ssl__SSLContext_security_level_get, (setter)_ssl__SSLContext_security_level_set, _ssl__SSLContext_security_level_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_SECURITY_LEVEL_GETSETDEF {"security_level", (getter)_ssl__SSLContext_security_level_get, NULL, _ssl__SSLContext_security_level_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLContext_security_level_get_impl(PySSLContext *self); + +static PyObject * +_ssl__SSLContext_security_level_get(PySSLContext *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_security_level_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_ssl__SSLContext_options_HAS_DOCSTR) +# define _ssl__SSLContext_options_DOCSTR _ssl__SSLContext_options__doc__ +#else +# define _ssl__SSLContext_options_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_OPTIONS_GETSETDEF) +# undef _SSL__SSLCONTEXT_OPTIONS_GETSETDEF +# define _SSL__SSLCONTEXT_OPTIONS_GETSETDEF {"options", (getter)_ssl__SSLContext_options_get, (setter)_ssl__SSLContext_options_set, _ssl__SSLContext_options_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_OPTIONS_GETSETDEF {"options", (getter)_ssl__SSLContext_options_get, NULL, _ssl__SSLContext_options_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLContext_options_get_impl(PySSLContext *self); + +static PyObject * +_ssl__SSLContext_options_get(PySSLContext *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_options_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_SSL__SSLCONTEXT_OPTIONS_HAS_DOCSTR) +# define _ssl__SSLContext_options_DOCSTR _ssl__SSLContext_options__doc__ +#else +# define _ssl__SSLContext_options_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_OPTIONS_GETSETDEF) +# undef _SSL__SSLCONTEXT_OPTIONS_GETSETDEF +# define _SSL__SSLCONTEXT_OPTIONS_GETSETDEF {"options", (getter)_ssl__SSLContext_options_get, (setter)_ssl__SSLContext_options_set, _ssl__SSLContext_options_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_OPTIONS_GETSETDEF {"options", NULL, (setter)_ssl__SSLContext_options_set, NULL}, +#endif + +static int +_ssl__SSLContext_options_set_impl(PySSLContext *self, PyObject *value); + +static int +_ssl__SSLContext_options_set(PySSLContext *self, PyObject *value, void *Py_UNUSED(context)) +{ + int return_value; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_options_set_impl(self, value); + Py_END_CRITICAL_SECTION(); + + return return_value; } +#if defined(_ssl__SSLContext__host_flags_HAS_DOCSTR) +# define _ssl__SSLContext__host_flags_DOCSTR _ssl__SSLContext__host_flags__doc__ +#else +# define _ssl__SSLContext__host_flags_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT__HOST_FLAGS_GETSETDEF) +# undef _SSL__SSLCONTEXT__HOST_FLAGS_GETSETDEF +# define _SSL__SSLCONTEXT__HOST_FLAGS_GETSETDEF {"_host_flags", (getter)_ssl__SSLContext__host_flags_get, (setter)_ssl__SSLContext__host_flags_set, _ssl__SSLContext__host_flags_DOCSTR}, +#else +# define _SSL__SSLCONTEXT__HOST_FLAGS_GETSETDEF {"_host_flags", (getter)_ssl__SSLContext__host_flags_get, NULL, _ssl__SSLContext__host_flags_DOCSTR}, +#endif + static PyObject * -_ssl__SSLContext_impl(PyTypeObject *type, int proto_version); +_ssl__SSLContext__host_flags_get_impl(PySSLContext *self); static PyObject * -_ssl__SSLContext(PyTypeObject *type, PyObject *args, PyObject *kwargs) +_ssl__SSLContext__host_flags_get(PySSLContext *self, void *Py_UNUSED(context)) { PyObject *return_value = NULL; - PyTypeObject *base_tp = get_state_type(type)->PySSLContext_Type; - int proto_version; - if ((type == base_tp || type->tp_init == base_tp->tp_init) && - !_PyArg_NoKeywords("_SSLContext", kwargs)) { - goto exit; - } - if (!_PyArg_CheckPositional("_SSLContext", PyTuple_GET_SIZE(args), 1, 1)) { - goto exit; - } - proto_version = PyLong_AsInt(PyTuple_GET_ITEM(args, 0)); - if (proto_version == -1 && PyErr_Occurred()) { - goto exit; - } - return_value = _ssl__SSLContext_impl(type, proto_version); + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext__host_flags_get_impl(self); + Py_END_CRITICAL_SECTION(); -exit: return return_value; } -PyDoc_STRVAR(_ssl__SSLContext_set_ciphers__doc__, -"set_ciphers($self, cipherlist, /)\n" -"--\n" -"\n"); +#if defined(_SSL__SSLCONTEXT__HOST_FLAGS_HAS_DOCSTR) +# define _ssl__SSLContext__host_flags_DOCSTR _ssl__SSLContext__host_flags__doc__ +#else +# define _ssl__SSLContext__host_flags_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT__HOST_FLAGS_GETSETDEF) +# undef _SSL__SSLCONTEXT__HOST_FLAGS_GETSETDEF +# define _SSL__SSLCONTEXT__HOST_FLAGS_GETSETDEF {"_host_flags", (getter)_ssl__SSLContext__host_flags_get, (setter)_ssl__SSLContext__host_flags_set, _ssl__SSLContext__host_flags_DOCSTR}, +#else +# define _SSL__SSLCONTEXT__HOST_FLAGS_GETSETDEF {"_host_flags", NULL, (setter)_ssl__SSLContext__host_flags_set, NULL}, +#endif -#define _SSL__SSLCONTEXT_SET_CIPHERS_METHODDEF \ - {"set_ciphers", (PyCFunction)_ssl__SSLContext_set_ciphers, METH_O, _ssl__SSLContext_set_ciphers__doc__}, +static int +_ssl__SSLContext__host_flags_set_impl(PySSLContext *self, PyObject *value); + +static int +_ssl__SSLContext__host_flags_set(PySSLContext *self, PyObject *value, void *Py_UNUSED(context)) +{ + int return_value; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext__host_flags_set_impl(self, value); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_ssl__SSLContext_check_hostname_HAS_DOCSTR) +# define _ssl__SSLContext_check_hostname_DOCSTR _ssl__SSLContext_check_hostname__doc__ +#else +# define _ssl__SSLContext_check_hostname_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_CHECK_HOSTNAME_GETSETDEF) +# undef _SSL__SSLCONTEXT_CHECK_HOSTNAME_GETSETDEF +# define _SSL__SSLCONTEXT_CHECK_HOSTNAME_GETSETDEF {"check_hostname", (getter)_ssl__SSLContext_check_hostname_get, (setter)_ssl__SSLContext_check_hostname_set, _ssl__SSLContext_check_hostname_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_CHECK_HOSTNAME_GETSETDEF {"check_hostname", (getter)_ssl__SSLContext_check_hostname_get, NULL, _ssl__SSLContext_check_hostname_DOCSTR}, +#endif static PyObject * -_ssl__SSLContext_set_ciphers_impl(PySSLContext *self, const char *cipherlist); +_ssl__SSLContext_check_hostname_get_impl(PySSLContext *self); static PyObject * -_ssl__SSLContext_set_ciphers(PySSLContext *self, PyObject *arg) +_ssl__SSLContext_check_hostname_get(PySSLContext *self, void *Py_UNUSED(context)) { PyObject *return_value = NULL; - const char *cipherlist; - if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("set_ciphers", "argument", "str", arg); - goto exit; - } - Py_ssize_t cipherlist_length; - cipherlist = PyUnicode_AsUTF8AndSize(arg, &cipherlist_length); - if (cipherlist == NULL) { - goto exit; - } - if (strlen(cipherlist) != (size_t)cipherlist_length) { - PyErr_SetString(PyExc_ValueError, "embedded null character"); - goto exit; - } - return_value = _ssl__SSLContext_set_ciphers_impl(self, cipherlist); + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_check_hostname_get_impl(self); + Py_END_CRITICAL_SECTION(); -exit: return return_value; } -PyDoc_STRVAR(_ssl__SSLContext_get_ciphers__doc__, -"get_ciphers($self, /)\n" -"--\n" -"\n"); - -#define _SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF \ - {"get_ciphers", (PyCFunction)_ssl__SSLContext_get_ciphers, METH_NOARGS, _ssl__SSLContext_get_ciphers__doc__}, +#if defined(_SSL__SSLCONTEXT_CHECK_HOSTNAME_HAS_DOCSTR) +# define _ssl__SSLContext_check_hostname_DOCSTR _ssl__SSLContext_check_hostname__doc__ +#else +# define _ssl__SSLContext_check_hostname_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_CHECK_HOSTNAME_GETSETDEF) +# undef _SSL__SSLCONTEXT_CHECK_HOSTNAME_GETSETDEF +# define _SSL__SSLCONTEXT_CHECK_HOSTNAME_GETSETDEF {"check_hostname", (getter)_ssl__SSLContext_check_hostname_get, (setter)_ssl__SSLContext_check_hostname_set, _ssl__SSLContext_check_hostname_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_CHECK_HOSTNAME_GETSETDEF {"check_hostname", NULL, (setter)_ssl__SSLContext_check_hostname_set, NULL}, +#endif -static PyObject * -_ssl__SSLContext_get_ciphers_impl(PySSLContext *self); +static int +_ssl__SSLContext_check_hostname_set_impl(PySSLContext *self, PyObject *value); -static PyObject * -_ssl__SSLContext_get_ciphers(PySSLContext *self, PyObject *Py_UNUSED(ignored)) +static int +_ssl__SSLContext_check_hostname_set(PySSLContext *self, PyObject *value, void *Py_UNUSED(context)) { - return _ssl__SSLContext_get_ciphers_impl(self); -} + int return_value; -PyDoc_STRVAR(_ssl__SSLContext__set_alpn_protocols__doc__, -"_set_alpn_protocols($self, protos, /)\n" -"--\n" -"\n"); + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_check_hostname_set_impl(self, value); + Py_END_CRITICAL_SECTION(); -#define _SSL__SSLCONTEXT__SET_ALPN_PROTOCOLS_METHODDEF \ - {"_set_alpn_protocols", (PyCFunction)_ssl__SSLContext__set_alpn_protocols, METH_O, _ssl__SSLContext__set_alpn_protocols__doc__}, + return return_value; +} + +#if defined(_ssl__SSLContext_protocol_HAS_DOCSTR) +# define _ssl__SSLContext_protocol_DOCSTR _ssl__SSLContext_protocol__doc__ +#else +# define _ssl__SSLContext_protocol_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_PROTOCOL_GETSETDEF) +# undef _SSL__SSLCONTEXT_PROTOCOL_GETSETDEF +# define _SSL__SSLCONTEXT_PROTOCOL_GETSETDEF {"protocol", (getter)_ssl__SSLContext_protocol_get, (setter)_ssl__SSLContext_protocol_set, _ssl__SSLContext_protocol_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_PROTOCOL_GETSETDEF {"protocol", (getter)_ssl__SSLContext_protocol_get, NULL, _ssl__SSLContext_protocol_DOCSTR}, +#endif static PyObject * -_ssl__SSLContext__set_alpn_protocols_impl(PySSLContext *self, - Py_buffer *protos); +_ssl__SSLContext_protocol_get_impl(PySSLContext *self); static PyObject * -_ssl__SSLContext__set_alpn_protocols(PySSLContext *self, PyObject *arg) +_ssl__SSLContext_protocol_get(PySSLContext *self, void *Py_UNUSED(context)) { PyObject *return_value = NULL; - Py_buffer protos = {NULL, NULL}; - if (PyObject_GetBuffer(arg, &protos, PyBUF_SIMPLE) != 0) { - goto exit; - } - return_value = _ssl__SSLContext__set_alpn_protocols_impl(self, &protos); - -exit: - /* Cleanup for protos */ - if (protos.obj) { - PyBuffer_Release(&protos); - } + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_protocol_get_impl(self); + Py_END_CRITICAL_SECTION(); return return_value; } @@ -599,7 +1423,9 @@ _ssl__SSLContext_load_cert_chain(PySSLContext *self, PyObject *const *args, Py_s } password = args[2]; skip_optional_pos: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLContext_load_cert_chain_impl(self, certfile, keyfile, password); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -675,7 +1501,9 @@ _ssl__SSLContext_load_verify_locations(PySSLContext *self, PyObject *const *args } cadata = args[2]; skip_optional_pos: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLContext_load_verify_locations_impl(self, cafile, capath, cadata); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -689,6 +1517,21 @@ PyDoc_STRVAR(_ssl__SSLContext_load_dh_params__doc__, #define _SSL__SSLCONTEXT_LOAD_DH_PARAMS_METHODDEF \ {"load_dh_params", (PyCFunction)_ssl__SSLContext_load_dh_params, METH_O, _ssl__SSLContext_load_dh_params__doc__}, +static PyObject * +_ssl__SSLContext_load_dh_params_impl(PySSLContext *self, PyObject *filepath); + +static PyObject * +_ssl__SSLContext_load_dh_params(PySSLContext *self, PyObject *filepath) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_load_dh_params_impl(self, filepath); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + PyDoc_STRVAR(_ssl__SSLContext__wrap_socket__doc__, "_wrap_socket($self, /, sock, server_side, server_hostname=None, *,\n" " owner=None, session=None)\n" @@ -774,7 +1617,9 @@ _ssl__SSLContext__wrap_socket(PySSLContext *self, PyObject *const *args, Py_ssiz } session = args[4]; skip_optional_kwonly: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLContext__wrap_socket_impl(self, sock, server_side, hostname_obj, owner, session); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -872,7 +1717,9 @@ _ssl__SSLContext__wrap_bio(PySSLContext *self, PyObject *const *args, Py_ssize_t } session = args[5]; skip_optional_kwonly: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLContext__wrap_bio_impl(self, incoming, outgoing, server_side, hostname_obj, owner, session); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -892,7 +1739,13 @@ _ssl__SSLContext_session_stats_impl(PySSLContext *self); static PyObject * _ssl__SSLContext_session_stats(PySSLContext *self, PyObject *Py_UNUSED(ignored)) { - return _ssl__SSLContext_session_stats_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_session_stats_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl__SSLContext_set_default_verify_paths__doc__, @@ -909,7 +1762,13 @@ _ssl__SSLContext_set_default_verify_paths_impl(PySSLContext *self); static PyObject * _ssl__SSLContext_set_default_verify_paths(PySSLContext *self, PyObject *Py_UNUSED(ignored)) { - return _ssl__SSLContext_set_default_verify_paths_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_set_default_verify_paths_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl__SSLContext_set_ecdh_curve__doc__, @@ -920,6 +1779,75 @@ PyDoc_STRVAR(_ssl__SSLContext_set_ecdh_curve__doc__, #define _SSL__SSLCONTEXT_SET_ECDH_CURVE_METHODDEF \ {"set_ecdh_curve", (PyCFunction)_ssl__SSLContext_set_ecdh_curve, METH_O, _ssl__SSLContext_set_ecdh_curve__doc__}, +static PyObject * +_ssl__SSLContext_set_ecdh_curve_impl(PySSLContext *self, PyObject *name); + +static PyObject * +_ssl__SSLContext_set_ecdh_curve(PySSLContext *self, PyObject *name) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_set_ecdh_curve_impl(self, name); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_ssl__SSLContext_sni_callback_HAS_DOCSTR) +# define _ssl__SSLContext_sni_callback_DOCSTR _ssl__SSLContext_sni_callback__doc__ +#else +# define _ssl__SSLContext_sni_callback_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_SNI_CALLBACK_GETSETDEF) +# undef _SSL__SSLCONTEXT_SNI_CALLBACK_GETSETDEF +# define _SSL__SSLCONTEXT_SNI_CALLBACK_GETSETDEF {"sni_callback", (getter)_ssl__SSLContext_sni_callback_get, (setter)_ssl__SSLContext_sni_callback_set, _ssl__SSLContext_sni_callback_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_SNI_CALLBACK_GETSETDEF {"sni_callback", (getter)_ssl__SSLContext_sni_callback_get, NULL, _ssl__SSLContext_sni_callback_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLContext_sni_callback_get_impl(PySSLContext *self); + +static PyObject * +_ssl__SSLContext_sni_callback_get(PySSLContext *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_sni_callback_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_SSL__SSLCONTEXT_SNI_CALLBACK_HAS_DOCSTR) +# define _ssl__SSLContext_sni_callback_DOCSTR _ssl__SSLContext_sni_callback__doc__ +#else +# define _ssl__SSLContext_sni_callback_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_SNI_CALLBACK_GETSETDEF) +# undef _SSL__SSLCONTEXT_SNI_CALLBACK_GETSETDEF +# define _SSL__SSLCONTEXT_SNI_CALLBACK_GETSETDEF {"sni_callback", (getter)_ssl__SSLContext_sni_callback_get, (setter)_ssl__SSLContext_sni_callback_set, _ssl__SSLContext_sni_callback_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_SNI_CALLBACK_GETSETDEF {"sni_callback", NULL, (setter)_ssl__SSLContext_sni_callback_set, NULL}, +#endif + +static int +_ssl__SSLContext_sni_callback_set_impl(PySSLContext *self, PyObject *value); + +static int +_ssl__SSLContext_sni_callback_set(PySSLContext *self, PyObject *value, void *Py_UNUSED(context)) +{ + int return_value; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_sni_callback_set_impl(self, value); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + PyDoc_STRVAR(_ssl__SSLContext_cert_store_stats__doc__, "cert_store_stats($self, /)\n" "--\n" @@ -941,7 +1869,13 @@ _ssl__SSLContext_cert_store_stats_impl(PySSLContext *self); static PyObject * _ssl__SSLContext_cert_store_stats(PySSLContext *self, PyObject *Py_UNUSED(ignored)) { - return _ssl__SSLContext_cert_store_stats_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_cert_store_stats_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl__SSLContext_get_ca_certs__doc__, @@ -1007,7 +1941,9 @@ _ssl__SSLContext_get_ca_certs(PySSLContext *self, PyObject *const *args, Py_ssiz goto exit; } skip_optional_pos: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLContext_get_ca_certs_impl(self, binary_form); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -1062,7 +1998,9 @@ _ssl__SSLContext_set_psk_client_callback(PySSLContext *self, PyObject *const *ar goto exit; } callback = args[0]; + Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLContext_set_psk_client_callback_impl(self, callback); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -1142,7 +2080,9 @@ _ssl__SSLContext_set_psk_server_callback(PySSLContext *self, PyObject *const *ar goto exit; } skip_optional_pos: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLContext_set_psk_server_callback_impl(self, callback, identity_hint); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -1165,12 +2105,68 @@ _ssl_MemoryBIO(PyTypeObject *type, PyObject *args, PyObject *kwargs) !_PyArg_NoKeywords("MemoryBIO", kwargs)) { goto exit; } + Py_BEGIN_CRITICAL_SECTION(type); return_value = _ssl_MemoryBIO_impl(type); + Py_END_CRITICAL_SECTION(); exit: return return_value; } +#if defined(_ssl_MemoryBIO_pending_HAS_DOCSTR) +# define _ssl_MemoryBIO_pending_DOCSTR _ssl_MemoryBIO_pending__doc__ +#else +# define _ssl_MemoryBIO_pending_DOCSTR NULL +#endif +#if defined(_SSL_MEMORYBIO_PENDING_GETSETDEF) +# undef _SSL_MEMORYBIO_PENDING_GETSETDEF +# define _SSL_MEMORYBIO_PENDING_GETSETDEF {"pending", (getter)_ssl_MemoryBIO_pending_get, (setter)_ssl_MemoryBIO_pending_set, _ssl_MemoryBIO_pending_DOCSTR}, +#else +# define _SSL_MEMORYBIO_PENDING_GETSETDEF {"pending", (getter)_ssl_MemoryBIO_pending_get, NULL, _ssl_MemoryBIO_pending_DOCSTR}, +#endif + +static PyObject * +_ssl_MemoryBIO_pending_get_impl(PySSLMemoryBIO *self); + +static PyObject * +_ssl_MemoryBIO_pending_get(PySSLMemoryBIO *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl_MemoryBIO_pending_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_ssl_MemoryBIO_eof_HAS_DOCSTR) +# define _ssl_MemoryBIO_eof_DOCSTR _ssl_MemoryBIO_eof__doc__ +#else +# define _ssl_MemoryBIO_eof_DOCSTR NULL +#endif +#if defined(_SSL_MEMORYBIO_EOF_GETSETDEF) +# undef _SSL_MEMORYBIO_EOF_GETSETDEF +# define _SSL_MEMORYBIO_EOF_GETSETDEF {"eof", (getter)_ssl_MemoryBIO_eof_get, (setter)_ssl_MemoryBIO_eof_set, _ssl_MemoryBIO_eof_DOCSTR}, +#else +# define _SSL_MEMORYBIO_EOF_GETSETDEF {"eof", (getter)_ssl_MemoryBIO_eof_get, NULL, _ssl_MemoryBIO_eof_DOCSTR}, +#endif + +static PyObject * +_ssl_MemoryBIO_eof_get_impl(PySSLMemoryBIO *self); + +static PyObject * +_ssl_MemoryBIO_eof_get(PySSLMemoryBIO *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl_MemoryBIO_eof_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + PyDoc_STRVAR(_ssl_MemoryBIO_read__doc__, "read($self, size=-1, /)\n" "--\n" @@ -1205,7 +2201,9 @@ _ssl_MemoryBIO_read(PySSLMemoryBIO *self, PyObject *const *args, Py_ssize_t narg goto exit; } skip_optional: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl_MemoryBIO_read_impl(self, len); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -1234,7 +2232,9 @@ _ssl_MemoryBIO_write(PySSLMemoryBIO *self, PyObject *arg) if (PyObject_GetBuffer(arg, &b, PyBUF_SIMPLE) != 0) { goto exit; } + Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl_MemoryBIO_write_impl(self, &b); + Py_END_CRITICAL_SECTION(); exit: /* Cleanup for b */ @@ -1262,7 +2262,148 @@ _ssl_MemoryBIO_write_eof_impl(PySSLMemoryBIO *self); static PyObject * _ssl_MemoryBIO_write_eof(PySSLMemoryBIO *self, PyObject *Py_UNUSED(ignored)) { - return _ssl_MemoryBIO_write_eof_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl_MemoryBIO_write_eof_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_ssl_SSLSession_time_HAS_DOCSTR) +# define _ssl_SSLSession_time_DOCSTR _ssl_SSLSession_time__doc__ +#else +# define _ssl_SSLSession_time_DOCSTR NULL +#endif +#if defined(_SSL_SSLSESSION_TIME_GETSETDEF) +# undef _SSL_SSLSESSION_TIME_GETSETDEF +# define _SSL_SSLSESSION_TIME_GETSETDEF {"time", (getter)_ssl_SSLSession_time_get, (setter)_ssl_SSLSession_time_set, _ssl_SSLSession_time_DOCSTR}, +#else +# define _SSL_SSLSESSION_TIME_GETSETDEF {"time", (getter)_ssl_SSLSession_time_get, NULL, _ssl_SSLSession_time_DOCSTR}, +#endif + +static PyObject * +_ssl_SSLSession_time_get_impl(PySSLSession *self); + +static PyObject * +_ssl_SSLSession_time_get(PySSLSession *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl_SSLSession_time_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_ssl_SSLSession_timeout_HAS_DOCSTR) +# define _ssl_SSLSession_timeout_DOCSTR _ssl_SSLSession_timeout__doc__ +#else +# define _ssl_SSLSession_timeout_DOCSTR NULL +#endif +#if defined(_SSL_SSLSESSION_TIMEOUT_GETSETDEF) +# undef _SSL_SSLSESSION_TIMEOUT_GETSETDEF +# define _SSL_SSLSESSION_TIMEOUT_GETSETDEF {"timeout", (getter)_ssl_SSLSession_timeout_get, (setter)_ssl_SSLSession_timeout_set, _ssl_SSLSession_timeout_DOCSTR}, +#else +# define _SSL_SSLSESSION_TIMEOUT_GETSETDEF {"timeout", (getter)_ssl_SSLSession_timeout_get, NULL, _ssl_SSLSession_timeout_DOCSTR}, +#endif + +static PyObject * +_ssl_SSLSession_timeout_get_impl(PySSLSession *self); + +static PyObject * +_ssl_SSLSession_timeout_get(PySSLSession *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl_SSLSession_timeout_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_ssl_SSLSession_ticket_lifetime_hint_HAS_DOCSTR) +# define _ssl_SSLSession_ticket_lifetime_hint_DOCSTR _ssl_SSLSession_ticket_lifetime_hint__doc__ +#else +# define _ssl_SSLSession_ticket_lifetime_hint_DOCSTR NULL +#endif +#if defined(_SSL_SSLSESSION_TICKET_LIFETIME_HINT_GETSETDEF) +# undef _SSL_SSLSESSION_TICKET_LIFETIME_HINT_GETSETDEF +# define _SSL_SSLSESSION_TICKET_LIFETIME_HINT_GETSETDEF {"ticket_lifetime_hint", (getter)_ssl_SSLSession_ticket_lifetime_hint_get, (setter)_ssl_SSLSession_ticket_lifetime_hint_set, _ssl_SSLSession_ticket_lifetime_hint_DOCSTR}, +#else +# define _SSL_SSLSESSION_TICKET_LIFETIME_HINT_GETSETDEF {"ticket_lifetime_hint", (getter)_ssl_SSLSession_ticket_lifetime_hint_get, NULL, _ssl_SSLSession_ticket_lifetime_hint_DOCSTR}, +#endif + +static PyObject * +_ssl_SSLSession_ticket_lifetime_hint_get_impl(PySSLSession *self); + +static PyObject * +_ssl_SSLSession_ticket_lifetime_hint_get(PySSLSession *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl_SSLSession_ticket_lifetime_hint_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_ssl_SSLSession_id_HAS_DOCSTR) +# define _ssl_SSLSession_id_DOCSTR _ssl_SSLSession_id__doc__ +#else +# define _ssl_SSLSession_id_DOCSTR NULL +#endif +#if defined(_SSL_SSLSESSION_ID_GETSETDEF) +# undef _SSL_SSLSESSION_ID_GETSETDEF +# define _SSL_SSLSESSION_ID_GETSETDEF {"id", (getter)_ssl_SSLSession_id_get, (setter)_ssl_SSLSession_id_set, _ssl_SSLSession_id_DOCSTR}, +#else +# define _SSL_SSLSESSION_ID_GETSETDEF {"id", (getter)_ssl_SSLSession_id_get, NULL, _ssl_SSLSession_id_DOCSTR}, +#endif + +static PyObject * +_ssl_SSLSession_id_get_impl(PySSLSession *self); + +static PyObject * +_ssl_SSLSession_id_get(PySSLSession *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl_SSLSession_id_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_ssl_SSLSession_has_ticket_HAS_DOCSTR) +# define _ssl_SSLSession_has_ticket_DOCSTR _ssl_SSLSession_has_ticket__doc__ +#else +# define _ssl_SSLSession_has_ticket_DOCSTR NULL +#endif +#if defined(_SSL_SSLSESSION_HAS_TICKET_GETSETDEF) +# undef _SSL_SSLSESSION_HAS_TICKET_GETSETDEF +# define _SSL_SSLSESSION_HAS_TICKET_GETSETDEF {"has_ticket", (getter)_ssl_SSLSession_has_ticket_get, (setter)_ssl_SSLSession_has_ticket_set, _ssl_SSLSession_has_ticket_DOCSTR}, +#else +# define _SSL_SSLSESSION_HAS_TICKET_GETSETDEF {"has_ticket", (getter)_ssl_SSLSession_has_ticket_get, NULL, _ssl_SSLSession_has_ticket_DOCSTR}, +#endif + +static PyObject * +_ssl_SSLSession_has_ticket_get_impl(PySSLSession *self); + +static PyObject * +_ssl_SSLSession_has_ticket_get(PySSLSession *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl_SSLSession_has_ticket_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl_RAND_add__doc__, @@ -1315,7 +2456,9 @@ _ssl_RAND_add(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } } + Py_BEGIN_CRITICAL_SECTION(module); return_value = _ssl_RAND_add_impl(module, &view, entropy); + Py_END_CRITICAL_SECTION(); exit: /* Cleanup for view */ @@ -1348,7 +2491,9 @@ _ssl_RAND_bytes(PyObject *module, PyObject *arg) if (n == -1 && PyErr_Occurred()) { goto exit; } + Py_BEGIN_CRITICAL_SECTION(module); return_value = _ssl_RAND_bytes_impl(module, n); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -1372,7 +2517,13 @@ _ssl_RAND_status_impl(PyObject *module); static PyObject * _ssl_RAND_status(PyObject *module, PyObject *Py_UNUSED(ignored)) { - return _ssl_RAND_status_impl(module); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(module); + return_value = _ssl_RAND_status_impl(module); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl_get_default_verify_paths__doc__, @@ -1392,7 +2543,13 @@ _ssl_get_default_verify_paths_impl(PyObject *module); static PyObject * _ssl_get_default_verify_paths(PyObject *module, PyObject *Py_UNUSED(ignored)) { - return _ssl_get_default_verify_paths_impl(module); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(module); + return_value = _ssl_get_default_verify_paths_impl(module); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl_txt2obj__doc__, @@ -1469,7 +2626,9 @@ _ssl_txt2obj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto exit; } skip_optional_pos: + Py_BEGIN_CRITICAL_SECTION(module); return_value = _ssl_txt2obj_impl(module, txt, name); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -1497,7 +2656,9 @@ _ssl_nid2obj(PyObject *module, PyObject *arg) if (nid == -1 && PyErr_Occurred()) { goto exit; } + Py_BEGIN_CRITICAL_SECTION(module); return_value = _ssl_nid2obj_impl(module, nid); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -1572,7 +2733,9 @@ _ssl_enum_certificates(PyObject *module, PyObject *const *args, Py_ssize_t nargs PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } + Py_BEGIN_CRITICAL_SECTION(module); return_value = _ssl_enum_certificates_impl(module, store_name); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -1648,7 +2811,9 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } + Py_BEGIN_CRITICAL_SECTION(module); return_value = _ssl_enum_crls_impl(module, store_name); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -1663,4 +2828,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=28a22f2b09d631cb input=a9049054013a1b77]*/ +/*[clinic end generated code: output=c1489122072a9f5e input=a9049054013a1b77]*/ From 8f5e39d5c885318e3128a3e84464c098b5f79a79 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Sat, 19 Oct 2024 14:46:57 -0700 Subject: [PATCH 148/170] gh-125378: Trigger a repeat for the full multi-line statement for empty line command (#125717) --- Lib/pdb.py | 1 + Lib/test/test_pdb.py | 16 +++++++++++++--- ...024-10-19-01-30-40.gh-issue-125378.WTosxX.rst | 1 + 3 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-19-01-30-40.gh-issue-125378.WTosxX.rst diff --git a/Lib/pdb.py b/Lib/pdb.py index cd7a7042fa6987..832213abbb98e6 100644 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -755,6 +755,7 @@ def default(self, line): else: line = line.rstrip('\r\n') buffer += '\n' + line + self.lastcmd = buffer save_stdout = sys.stdout save_stdin = sys.stdin save_displayhook = sys.displayhook diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 7e6f276d355a14..1ea93ed037005d 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -2448,7 +2448,12 @@ def test_pdb_multiline_statement(): ... 'def f(x):', ... ' return x * 2', ... '', - ... 'f(2)', + ... 'val = 2', + ... 'if val > 0:', + ... ' val = f(val)', + ... '', + ... '', # empty line should repeat the multi-line statement + ... 'val', ... 'c' ... ]): ... test_function() @@ -2457,8 +2462,13 @@ def test_pdb_multiline_statement(): (Pdb) def f(x): ... return x * 2 ... - (Pdb) f(2) - 4 + (Pdb) val = 2 + (Pdb) if val > 0: + ... val = f(val) + ... + (Pdb) + (Pdb) val + 8 (Pdb) c """ diff --git a/Misc/NEWS.d/next/Library/2024-10-19-01-30-40.gh-issue-125378.WTosxX.rst b/Misc/NEWS.d/next/Library/2024-10-19-01-30-40.gh-issue-125378.WTosxX.rst new file mode 100644 index 00000000000000..dc76889d3b210a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-19-01-30-40.gh-issue-125378.WTosxX.rst @@ -0,0 +1 @@ +Fixed the bug in :mod:`pdb` where after a multi-line command, an empty line repeats the first line of the multi-line command, instead of the full command. From 14cafe1a108cf0be73a27a0001003b5897eec8f0 Mon Sep 17 00:00:00 2001 From: Tom Most Date: Sat, 19 Oct 2024 17:48:06 -0700 Subject: [PATCH 149/170] Doc: Fix pluralization in os.process_cpu_count() documentation (#125678) --- Doc/library/os.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 33dd58febd9a5e..081d7a6f97b079 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -5579,7 +5579,7 @@ Miscellaneous System Information If :option:`-X cpu_count <-X>` is given or :envvar:`PYTHON_CPU_COUNT` is set, :func:`process_cpu_count` returns the overridden value *n*. - See also the :func:`sched_getaffinity` functions. + See also the :func:`sched_getaffinity` function. .. versionadded:: 3.13 From e924bb667a19ee1812d6c7592a37dd37346dda04 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sun, 20 Oct 2024 03:10:17 +0200 Subject: [PATCH 150/170] gh-125698: Replace EXEEXT with EXE_SUFFIX (#125699) --- Makefile.pre.in | 2 +- configure | 22 +++++++++++----------- configure.ac | 20 ++++++++++---------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Makefile.pre.in b/Makefile.pre.in index fb6f22d57397db..9c313c8029fb68 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -176,7 +176,7 @@ EXPORTSYMS= @EXPORTSYMS@ EXPORTSFROM= @EXPORTSFROM@ # Executable suffix (.exe on Windows and Mac OS X) -EXE= @EXEEXT@ +EXE= @EXE_SUFFIX@ BUILDEXE= @BUILDEXEEXT@ # Name of the patch file to apply for app store compliance diff --git a/configure b/configure index b11f41d5379958..ab35f69f73011f 100755 --- a/configure +++ b/configure @@ -7296,11 +7296,11 @@ then : withval=$with_suffix; case $with_suffix in #( no) : - EXEEXT= ;; #( + EXE_SUFFIX= ;; #( yes) : - EXEEXT=.exe ;; #( + EXE_SUFFIX=.exe ;; #( *) : - EXEEXT=$with_suffix + EXE_SUFFIX=$with_suffix ;; esac @@ -7308,20 +7308,20 @@ else $as_nop case $ac_sys_system/$ac_sys_emscripten_target in #( Emscripten/browser*) : - EXEEXT=.js ;; #( + EXE_SUFFIX=.js ;; #( Emscripten/node*) : - EXEEXT=.js ;; #( + EXE_SUFFIX=.js ;; #( WASI/*) : - EXEEXT=.wasm ;; #( + EXE_SUFFIX=.wasm ;; #( *) : - EXEEXT= + EXE_SUFFIX= ;; esac fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $EXEEXT" >&5 -printf "%s\n" "$EXEEXT" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $EXE_SUFFIX" >&5 +printf "%s\n" "$EXE_SUFFIX" >&6; } # Test whether we're running on a non-case-sensitive system, in which # case we give a warning if no ext is given @@ -7332,7 +7332,7 @@ if test ! -d CaseSensitiveTestDir; then mkdir CaseSensitiveTestDir fi -if test -d casesensitivetestdir && test -z "$EXEEXT" +if test -d casesensitivetestdir && test -z "$EXE_SUFFIX" then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } @@ -7340,7 +7340,7 @@ printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - BUILDEXEEXT=$EXEEXT + BUILDEXEEXT=$EXE_SUFFIX fi rmdir CaseSensitiveTestDir diff --git a/configure.ac b/configure.ac index d5bc739c34c90f..9e50eae6a7ece8 100644 --- a/configure.ac +++ b/configure.ac @@ -1325,19 +1325,19 @@ AC_ARG_WITH([suffix], [AS_HELP_STRING([--with-suffix=SUFFIX], [set executable suffix to SUFFIX (default is empty, yes is mapped to '.exe')])], [ AS_CASE([$with_suffix], - [no], [EXEEXT=], - [yes], [EXEEXT=.exe], - [EXEEXT=$with_suffix] + [no], [EXE_SUFFIX=], + [yes], [EXE_SUFFIX=.exe], + [EXE_SUFFIX=$with_suffix] ) ], [ AS_CASE([$ac_sys_system/$ac_sys_emscripten_target], - [Emscripten/browser*], [EXEEXT=.js], - [Emscripten/node*], [EXEEXT=.js], - [WASI/*], [EXEEXT=.wasm], - [EXEEXT=] + [Emscripten/browser*], [EXE_SUFFIX=.js], + [Emscripten/node*], [EXE_SUFFIX=.js], + [WASI/*], [EXE_SUFFIX=.wasm], + [EXE_SUFFIX=] ) ]) -AC_MSG_RESULT([$EXEEXT]) +AC_MSG_RESULT([$EXE_SUFFIX]) # Test whether we're running on a non-case-sensitive system, in which # case we give a warning if no ext is given @@ -1347,13 +1347,13 @@ if test ! -d CaseSensitiveTestDir; then mkdir CaseSensitiveTestDir fi -if test -d casesensitivetestdir && test -z "$EXEEXT" +if test -d casesensitivetestdir && test -z "$EXE_SUFFIX" then AC_MSG_RESULT([yes]) BUILDEXEEXT=.exe else AC_MSG_RESULT([no]) - BUILDEXEEXT=$EXEEXT + BUILDEXEEXT=$EXE_SUFFIX fi rmdir CaseSensitiveTestDir From ed24702bd0f9925908ce48584c31dfad732208b2 Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Sun, 20 Oct 2024 16:55:26 +0900 Subject: [PATCH 151/170] gh-125741: Update check_generated_files CI to use our published container image (gh-125744) --- .github/workflows/build.yml | 53 ++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ec7904c2e2cc73..a72d4a1bb97cb9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -40,6 +40,50 @@ jobs: if: fromJSON(needs.check_source.outputs.run-docs) uses: ./.github/workflows/reusable-docs.yml + check_autoconf_regen: + name: 'Check if Autoconf files are up to date' + # Don't use ubuntu-latest but a specific version to make the job + # reproducible: to get the same tools versions (autoconf, aclocal, ...) + runs-on: ubuntu-24.04 + container: + image: ghcr.io/python/autoconf:2024.10.11.11293396815 + timeout-minutes: 60 + needs: check_source + if: needs.check_source.outputs.run_tests == 'true' + steps: + - name: Install Git + run: | + apt install git -yq + git config --global --add safe.directory "$GITHUB_WORKSPACE" + - uses: actions/checkout@v4 + with: + fetch-depth: 1 + - name: Runner image version + run: echo "IMAGE_VERSION=${ImageVersion}" >> $GITHUB_ENV + - name: Check Autoconf and aclocal versions + run: | + grep "Generated by GNU Autoconf 2.71" configure + grep "aclocal 1.16.5" aclocal.m4 + grep -q "runstatedir" configure + grep -q "PKG_PROG_PKG_CONFIG" aclocal.m4 + - name: Regenerate autoconf files + # Same command used by Tools/build/regen-configure.sh ($AUTORECONF) + run: autoreconf -ivf -Werror + - name: Check for changes + run: | + git add -u + changes=$(git status --porcelain) + # Check for changes in regenerated files + if test -n "$changes"; then + echo "Generated files not up to date." + echo "Perhaps you forgot to run make regen-all or build.bat --regen. ;)" + echo "configure files must be regenerated with a specific version of autoconf." + echo "$changes" + echo "" + git diff --staged || true + exit 1 + fi + check_generated_files: name: 'Check if generated files are up to date' # Don't use ubuntu-latest but a specific version to make the job @@ -69,19 +113,10 @@ jobs: uses: hendrikmuhs/ccache-action@v1.2 with: save: false - - name: Check Autoconf and aclocal versions - run: | - grep "Generated by GNU Autoconf 2.71" configure - grep "aclocal 1.16.5" aclocal.m4 - grep -q "runstatedir" configure - grep -q "PKG_PROG_PKG_CONFIG" aclocal.m4 - name: Configure CPython run: | # Build Python with the libpython dynamic library ./configure --config-cache --with-pydebug --enable-shared - - name: Regenerate autoconf files - # Same command used by Tools/build/regen-configure.sh ($AUTORECONF) - run: autoreconf -ivf -Werror - name: Build CPython run: | make -j4 regen-all From b3c6b2c9e19ea84f617c13399c411044afbc3813 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sun, 20 Oct 2024 23:08:01 +0200 Subject: [PATCH 152/170] gh-125698: Restore EXEEXT in configure and Make (#125758) This reverts commit e924bb667. --- Makefile.pre.in | 2 +- configure | 22 +++++++++++----------- configure.ac | 20 ++++++++++---------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Makefile.pre.in b/Makefile.pre.in index 9c313c8029fb68..fb6f22d57397db 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -176,7 +176,7 @@ EXPORTSYMS= @EXPORTSYMS@ EXPORTSFROM= @EXPORTSFROM@ # Executable suffix (.exe on Windows and Mac OS X) -EXE= @EXE_SUFFIX@ +EXE= @EXEEXT@ BUILDEXE= @BUILDEXEEXT@ # Name of the patch file to apply for app store compliance diff --git a/configure b/configure index ab35f69f73011f..b11f41d5379958 100755 --- a/configure +++ b/configure @@ -7296,11 +7296,11 @@ then : withval=$with_suffix; case $with_suffix in #( no) : - EXE_SUFFIX= ;; #( + EXEEXT= ;; #( yes) : - EXE_SUFFIX=.exe ;; #( + EXEEXT=.exe ;; #( *) : - EXE_SUFFIX=$with_suffix + EXEEXT=$with_suffix ;; esac @@ -7308,20 +7308,20 @@ else $as_nop case $ac_sys_system/$ac_sys_emscripten_target in #( Emscripten/browser*) : - EXE_SUFFIX=.js ;; #( + EXEEXT=.js ;; #( Emscripten/node*) : - EXE_SUFFIX=.js ;; #( + EXEEXT=.js ;; #( WASI/*) : - EXE_SUFFIX=.wasm ;; #( + EXEEXT=.wasm ;; #( *) : - EXE_SUFFIX= + EXEEXT= ;; esac fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $EXE_SUFFIX" >&5 -printf "%s\n" "$EXE_SUFFIX" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $EXEEXT" >&5 +printf "%s\n" "$EXEEXT" >&6; } # Test whether we're running on a non-case-sensitive system, in which # case we give a warning if no ext is given @@ -7332,7 +7332,7 @@ if test ! -d CaseSensitiveTestDir; then mkdir CaseSensitiveTestDir fi -if test -d casesensitivetestdir && test -z "$EXE_SUFFIX" +if test -d casesensitivetestdir && test -z "$EXEEXT" then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } @@ -7340,7 +7340,7 @@ printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - BUILDEXEEXT=$EXE_SUFFIX + BUILDEXEEXT=$EXEEXT fi rmdir CaseSensitiveTestDir diff --git a/configure.ac b/configure.ac index 9e50eae6a7ece8..d5bc739c34c90f 100644 --- a/configure.ac +++ b/configure.ac @@ -1325,19 +1325,19 @@ AC_ARG_WITH([suffix], [AS_HELP_STRING([--with-suffix=SUFFIX], [set executable suffix to SUFFIX (default is empty, yes is mapped to '.exe')])], [ AS_CASE([$with_suffix], - [no], [EXE_SUFFIX=], - [yes], [EXE_SUFFIX=.exe], - [EXE_SUFFIX=$with_suffix] + [no], [EXEEXT=], + [yes], [EXEEXT=.exe], + [EXEEXT=$with_suffix] ) ], [ AS_CASE([$ac_sys_system/$ac_sys_emscripten_target], - [Emscripten/browser*], [EXE_SUFFIX=.js], - [Emscripten/node*], [EXE_SUFFIX=.js], - [WASI/*], [EXE_SUFFIX=.wasm], - [EXE_SUFFIX=] + [Emscripten/browser*], [EXEEXT=.js], + [Emscripten/node*], [EXEEXT=.js], + [WASI/*], [EXEEXT=.wasm], + [EXEEXT=] ) ]) -AC_MSG_RESULT([$EXE_SUFFIX]) +AC_MSG_RESULT([$EXEEXT]) # Test whether we're running on a non-case-sensitive system, in which # case we give a warning if no ext is given @@ -1347,13 +1347,13 @@ if test ! -d CaseSensitiveTestDir; then mkdir CaseSensitiveTestDir fi -if test -d casesensitivetestdir && test -z "$EXE_SUFFIX" +if test -d casesensitivetestdir && test -z "$EXEEXT" then AC_MSG_RESULT([yes]) BUILDEXEEXT=.exe else AC_MSG_RESULT([no]) - BUILDEXEEXT=$EXE_SUFFIX + BUILDEXEEXT=$EXEEXT fi rmdir CaseSensitiveTestDir From 9256be7ff0ab035cfd262127d893c9bc88b3c84c Mon Sep 17 00:00:00 2001 From: "RUANG (Roy James)" Date: Mon, 21 Oct 2024 08:36:27 +0800 Subject: [PATCH 153/170] gh-99030: Added documentation links for types and exceptions (GH-123857) * Added documentation links for types and exceptions * Shortened description sentences * Change content * Change documentation * Move seealso * Add a spaces --- Doc/library/builtins.rst | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Doc/library/builtins.rst b/Doc/library/builtins.rst index 644344e7fef29a..c4979db52d2aed 100644 --- a/Doc/library/builtins.rst +++ b/Doc/library/builtins.rst @@ -7,10 +7,7 @@ -------------- This module provides direct access to all 'built-in' identifiers of Python; for -example, ``builtins.open`` is the full name for the built-in function -:func:`open`. See :ref:`built-in-funcs` and :ref:`built-in-consts` for -documentation. - +example, ``builtins.open`` is the full name for the built-in function :func:`open`. This module is not normally accessed explicitly by most applications, but can be useful in modules that provide objects with the same name as a built-in value, @@ -40,3 +37,10 @@ available as part of their globals. The value of ``__builtins__`` is normally either this module or the value of this module's :attr:`~object.__dict__` attribute. Since this is an implementation detail, it may not be used by alternate implementations of Python. + +.. seealso:: + + * :ref:`built-in-consts` + * :ref:`bltin-exceptions` + * :ref:`built-in-funcs` + * :ref:`bltin-types` From c5c21fee7ae1ea689a351caa454c98e716a6e537 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Mon, 21 Oct 2024 07:53:21 +0100 Subject: [PATCH 154/170] gh-125519: Improve traceback if `importlib.reload()` is called with a non-module object (#125520) --- Lib/importlib/__init__.py | 2 +- Lib/test/test_importlib/test_api.py | 15 +++++++++++++++ ...2024-10-15-14-01-03.gh-issue-125519.TqGh6a.rst | 2 ++ 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-15-14-01-03.gh-issue-125519.TqGh6a.rst diff --git a/Lib/importlib/__init__.py b/Lib/importlib/__init__.py index f38fe5c1ab461a..a7d57561ead046 100644 --- a/Lib/importlib/__init__.py +++ b/Lib/importlib/__init__.py @@ -103,7 +103,7 @@ def reload(module): try: name = module.__name__ except AttributeError: - raise TypeError("reload() argument must be a module") + raise TypeError("reload() argument must be a module") from None if sys.modules.get(name) is not module: raise ImportError(f"module {name} not in sys.modules", name=name) diff --git a/Lib/test/test_importlib/test_api.py b/Lib/test/test_importlib/test_api.py index 973237c0791a3e..51ea5270b1a928 100644 --- a/Lib/test/test_importlib/test_api.py +++ b/Lib/test/test_importlib/test_api.py @@ -9,6 +9,7 @@ from test import support from test.support import import_helper from test.support import os_helper +import traceback import types import unittest @@ -354,6 +355,20 @@ def test_module_missing_spec(self): with self.assertRaises(ModuleNotFoundError): self.init.reload(module) + def test_reload_traceback_with_non_str(self): + # gh-125519 + with support.captured_stdout() as stdout: + try: + self.init.reload("typing") + except TypeError as exc: + traceback.print_exception(exc, file=stdout) + else: + self.fail("Expected TypeError to be raised") + printed_traceback = stdout.getvalue() + self.assertIn("TypeError", printed_traceback) + self.assertNotIn("AttributeError", printed_traceback) + self.assertNotIn("module.__spec__.name", printed_traceback) + (Frozen_ReloadTests, Source_ReloadTests diff --git a/Misc/NEWS.d/next/Library/2024-10-15-14-01-03.gh-issue-125519.TqGh6a.rst b/Misc/NEWS.d/next/Library/2024-10-15-14-01-03.gh-issue-125519.TqGh6a.rst new file mode 100644 index 00000000000000..e6062625104590 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-15-14-01-03.gh-issue-125519.TqGh6a.rst @@ -0,0 +1,2 @@ +Improve traceback if :func:`importlib.reload` is called with an object that +is not a module. Patch by Alex Waygood. From ded105a62b9d78717f8dc64652e3903190b585dd Mon Sep 17 00:00:00 2001 From: ember91 <31469580+ember91@users.noreply.github.com> Date: Mon, 21 Oct 2024 10:44:18 +0200 Subject: [PATCH 155/170] Doc: Fix typos (#125728) --- Doc/c-api/init.rst | 2 +- Doc/c-api/long.rst | 2 +- Doc/c-api/monitoring.rst | 2 +- Doc/library/concurrent.futures.rst | 2 +- Doc/library/importlib.metadata.rst | 2 +- Doc/using/windows.rst | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst index ffc5b4223ba589..412a41ce02cfd7 100644 --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -2418,7 +2418,7 @@ Example usage:: In the above example, :c:macro:`Py_SETREF` calls :c:macro:`Py_DECREF`, which can call arbitrary code through an object's deallocation function. The critical -section API avoids potentital deadlocks due to reentrancy and lock ordering +section API avoids potential deadlocks due to reentrancy and lock ordering by allowing the runtime to temporarily suspend the critical section if the code triggered by the finalizer blocks and calls :c:func:`PyEval_SaveThread`. diff --git a/Doc/c-api/long.rst b/Doc/c-api/long.rst index 6d3463fe25a614..9ff3e5265004a1 100644 --- a/Doc/c-api/long.rst +++ b/Doc/c-api/long.rst @@ -511,7 +511,7 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. free(bignum); *flags* is either ``-1`` (``Py_ASNATIVEBYTES_DEFAULTS``) to select defaults - that behave most like a C cast, or a combintation of the other flags in + that behave most like a C cast, or a combination of the other flags in the table below. Note that ``-1`` cannot be combined with other flags. diff --git a/Doc/c-api/monitoring.rst b/Doc/c-api/monitoring.rst index 285ddb2889a67f..51d866cfd47469 100644 --- a/Doc/c-api/monitoring.rst +++ b/Doc/c-api/monitoring.rst @@ -147,7 +147,7 @@ would typically correspond to a python function. The ``version`` argument is a pointer to a value which should be allocated by the user together with ``state_array`` and initialized to 0, - and then set only by :c:func:`!PyMonitoring_EnterScope` itelf. It allows this + and then set only by :c:func:`!PyMonitoring_EnterScope` itself. It allows this function to determine whether event states have changed since the previous call, and to return quickly if they have not. diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst index 45a73705f10e92..48e027152a9851 100644 --- a/Doc/library/concurrent.futures.rst +++ b/Doc/library/concurrent.futures.rst @@ -208,7 +208,7 @@ ThreadPoolExecutor Example 'http://www.cnn.com/', 'http://europe.wsj.com/', 'http://www.bbc.co.uk/', - 'http://nonexistant-subdomain.python.org/'] + 'http://nonexistent-subdomain.python.org/'] # Retrieve a single page and report the URL and contents def load_url(url, timeout): diff --git a/Doc/library/importlib.metadata.rst b/Doc/library/importlib.metadata.rst index 85d5a2d684d6eb..ddfc5c06d825c0 100644 --- a/Doc/library/importlib.metadata.rst +++ b/Doc/library/importlib.metadata.rst @@ -559,7 +559,7 @@ path. ``DatabaseDistribution``, then, would look something like:: - class DatabaseDistribution(importlib.metadata.Distributon): + class DatabaseDistribution(importlib.metadata.Distribution): def __init__(self, record): self.record = record diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst index 20d872d7639219..daaf8822af1161 100644 --- a/Doc/using/windows.rst +++ b/Doc/using/windows.rst @@ -838,8 +838,8 @@ The short form of the argument (``-3``) only ever selects from core Python releases, and not other distributions. However, the longer form (``-V:3``) will select from any. -The Company is matched on the full string, case-insenitive. The Tag is matched -oneither the full string, or a prefix, provided the next character is a dot or a +The Company is matched on the full string, case-insensitive. The Tag is matched +on either the full string, or a prefix, provided the next character is a dot or a hyphen. This allows ``-V:3.1`` to match ``3.1-32``, but not ``3.10``. Tags are sorted using numerical ordering (``3.10`` is newer than ``3.1``), but are compared using text (``-V:3.01`` does not match ``3.1``). From 7d88140d5299bd086434840db66ede8ccd01a688 Mon Sep 17 00:00:00 2001 From: Y5 <124019959+y5c4l3@users.noreply.github.com> Date: Mon, 21 Oct 2024 17:35:54 +0800 Subject: [PATCH 156/170] gh-125313: Prefer `sys.base_*` paths in `Py_Get(Exec)Prefix` deprecation notes (#125317) Prefer `sys.base_*` paths in `Py_Get(Exec)Prefix` deprecation notes. Signed-off-by: y5c4l3 --- Doc/c-api/init.rst | 11 +++++++---- Doc/deprecations/c-api-pending-removal-in-3.15.rst | 4 ++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst index 412a41ce02cfd7..6e881590131cab 100644 --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -625,7 +625,7 @@ Process-wide parameters returned string points into static storage; the caller should not modify its value. This corresponds to the :makevar:`prefix` variable in the top-level :file:`Makefile` and the :option:`--prefix` argument to the :program:`configure` - script at build time. The value is available to Python code as ``sys.prefix``. + script at build time. The value is available to Python code as ``sys.base_prefix``. It is only useful on Unix. See also the next function. This function should not be called before :c:func:`Py_Initialize`, otherwise @@ -635,7 +635,8 @@ Process-wide parameters It now returns ``NULL`` if called before :c:func:`Py_Initialize`. .. deprecated-removed:: 3.13 3.15 - Get :data:`sys.prefix` instead. + Get :data:`sys.base_prefix` instead, or :data:`sys.prefix` if + :ref:`virtual environments ` need to be handled. .. c:function:: wchar_t* Py_GetExecPrefix() @@ -648,7 +649,8 @@ Process-wide parameters should not modify its value. This corresponds to the :makevar:`exec_prefix` variable in the top-level :file:`Makefile` and the ``--exec-prefix`` argument to the :program:`configure` script at build time. The value is - available to Python code as ``sys.exec_prefix``. It is only useful on Unix. + available to Python code as ``sys.base_exec_prefix``. It is only useful on + Unix. Background: The exec-prefix differs from the prefix when platform dependent files (such as executables and shared libraries) are installed in a different @@ -679,7 +681,8 @@ Process-wide parameters It now returns ``NULL`` if called before :c:func:`Py_Initialize`. .. deprecated-removed:: 3.13 3.15 - Get :data:`sys.exec_prefix` instead. + Get :data:`sys.base_exec_prefix` instead, or :data:`sys.exec_prefix` if + :ref:`virtual environments ` need to be handled. .. c:function:: wchar_t* Py_GetProgramFullPath() diff --git a/Doc/deprecations/c-api-pending-removal-in-3.15.rst b/Doc/deprecations/c-api-pending-removal-in-3.15.rst index 1bb49e5b4874f2..0ce0f9c118c094 100644 --- a/Doc/deprecations/c-api-pending-removal-in-3.15.rst +++ b/Doc/deprecations/c-api-pending-removal-in-3.15.rst @@ -13,11 +13,11 @@ Pending removal in Python 3.15 * :c:func:`PySys_ResetWarnOptions`: Clear :data:`sys.warnoptions` and :data:`!warnings.filters` instead. * :c:func:`Py_GetExecPrefix`: - Get :data:`sys.exec_prefix` instead. + Get :data:`sys.base_exec_prefix` and :data:`sys.exec_prefix` instead. * :c:func:`Py_GetPath`: Get :data:`sys.path` instead. * :c:func:`Py_GetPrefix`: - Get :data:`sys.prefix` instead. + Get :data:`sys.base_prefix` and :data:`sys.prefix` instead. * :c:func:`Py_GetProgramFullPath`: Get :data:`sys.executable` instead. * :c:func:`Py_GetProgramName`: From f36d37bbafcee711c765a8cda9ac3ca00b8258c8 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Date: Mon, 21 Oct 2024 11:54:54 +0100 Subject: [PATCH 157/170] gh-125741: Update `build.yml` for the new check_autoconf_regen job (#125772) --- .github/workflows/build.yml | 2 ++ .github/workflows/posix-deps-apt.sh | 2 -- Tools/build/regen-configure.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a72d4a1bb97cb9..88898895d15ad0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -536,6 +536,7 @@ jobs: needs: - check_source # Transitive dependency, needed to access `run_tests` value - check-docs + - check_autoconf_regen - check_generated_files - build_macos - build_ubuntu @@ -571,6 +572,7 @@ jobs: ${{ needs.check_source.outputs.run_tests != 'true' && ' + check_autoconf_regen, check_generated_files, build_macos, build_ubuntu, diff --git a/.github/workflows/posix-deps-apt.sh b/.github/workflows/posix-deps-apt.sh index fb485bd4f82bd2..bfc5a0874281bd 100755 --- a/.github/workflows/posix-deps-apt.sh +++ b/.github/workflows/posix-deps-apt.sh @@ -1,11 +1,9 @@ #!/bin/sh apt-get update -# autoconf-archive is needed by autoreconf (check_generated_files job) apt-get -yq install \ build-essential \ pkg-config \ - autoconf-archive \ ccache \ gdb \ lcov \ diff --git a/Tools/build/regen-configure.sh b/Tools/build/regen-configure.sh index 1a24b07c3ff707..ee7c03e86999c1 100755 --- a/Tools/build/regen-configure.sh +++ b/Tools/build/regen-configure.sh @@ -2,7 +2,7 @@ set -e -x -# The check_generated_files job of .github/workflows/build.yml must kept in +# The check_autoconf_regen job of .github/workflows/build.yml must kept in # sync with this script. Use the same container image than the job so the job # doesn't need to run autoreconf in a container. IMAGE="ghcr.io/python/autoconf:2024.10.11.11293396815" From 0cd21406bf84b3b4927a8117024232774823aee0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lum=C3=ADr=20=27Frenzy=27=20Balhar?= Date: Mon, 21 Oct 2024 13:14:02 +0200 Subject: [PATCH 158/170] gh-119311: Add missing magic number (3571) for 3.13.0b1 (#125771) Add missing magic number 3571 for 3.13b1 It was added after branching in https://github.com/python/cpython/commit/6394a72e99b342d980297ec437ecafea92a044c4#diff-efefe383b3a81d16150c280db0b64eed7569254299418f64cc0d749f8e16f3a4R475 --- Include/internal/pycore_magic_number.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Include/internal/pycore_magic_number.h b/Include/internal/pycore_magic_number.h index a88ff2deeba941..4aa89f3cac8063 100644 --- a/Include/internal/pycore_magic_number.h +++ b/Include/internal/pycore_magic_number.h @@ -251,6 +251,7 @@ Known values: Python 3.13a1 3568 (Change semantics of END_FOR) Python 3.13a5 3569 (Specialize CONTAINS_OP) Python 3.13a6 3570 (Add __firstlineno__ class attribute) + Python 3.13b1 3571 (Fix miscompilation of private names in generic classes) Python 3.14a1 3600 (Add LOAD_COMMON_CONSTANT) Python 3.14a1 3601 (Fix miscompilation of private names in generic classes) Python 3.14a1 3602 (Add LOAD_SPECIAL. Remove BEFORE_WITH and BEFORE_ASYNC_WITH) From 5989eb74463c26780632f17f221d6bf4c9372a01 Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Mon, 21 Oct 2024 08:23:38 -0400 Subject: [PATCH 159/170] gh-125608: Trigger dictionary watchers when inline values change (#125611) Dictionary watchers on an object's attributes dictionary (`object.__dict__`) were not triggered when the managed dictionary used the object's inline values. --- Lib/test/test_capi/test_watchers.py | 17 +++++++++++++++ ...-10-16-19-28-23.gh-issue-125608.gTsU2g.rst | 3 +++ Objects/dictobject.c | 21 +++++++++++++------ 3 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/C_API/2024-10-16-19-28-23.gh-issue-125608.gTsU2g.rst diff --git a/Lib/test/test_capi/test_watchers.py b/Lib/test/test_capi/test_watchers.py index 4bb764bf9d0963..e578a622a03487 100644 --- a/Lib/test/test_capi/test_watchers.py +++ b/Lib/test/test_capi/test_watchers.py @@ -97,6 +97,23 @@ def test_dealloc(self): del d self.assert_events(["dealloc"]) + def test_object_dict(self): + class MyObj: pass + o = MyObj() + + with self.watcher() as wid: + self.watch(wid, o.__dict__) + o.foo = "bar" + o.foo = "baz" + del o.foo + self.assert_events(["new:foo:bar", "mod:foo:baz", "del:foo"]) + + with self.watcher() as wid: + self.watch(wid, o.__dict__) + for _ in range(100): + o.foo = "bar" + self.assert_events(["new:foo:bar"] + ["mod:foo:bar"] * 99) + def test_unwatch(self): d = {} with self.watcher() as wid: diff --git a/Misc/NEWS.d/next/C_API/2024-10-16-19-28-23.gh-issue-125608.gTsU2g.rst b/Misc/NEWS.d/next/C_API/2024-10-16-19-28-23.gh-issue-125608.gTsU2g.rst new file mode 100644 index 00000000000000..e70f9f173957a2 --- /dev/null +++ b/Misc/NEWS.d/next/C_API/2024-10-16-19-28-23.gh-issue-125608.gTsU2g.rst @@ -0,0 +1,3 @@ +Fix a bug where dictionary watchers (e.g., :c:func:`PyDict_Watch`) on an +object's attribute dictionary (:attr:`~object.__dict__`) were not triggered +when the object's attributes were modified. diff --git a/Objects/dictobject.c b/Objects/dictobject.c index b27599d2815c82..806096f5814062 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -6835,15 +6835,24 @@ store_instance_attr_lock_held(PyObject *obj, PyDictValues *values, } PyObject *old_value = values->values[ix]; + if (old_value == NULL && value == NULL) { + PyErr_Format(PyExc_AttributeError, + "'%.100s' object has no attribute '%U'", + Py_TYPE(obj)->tp_name, name); + return -1; + } + + if (dict) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + PyDict_WatchEvent event = (old_value == NULL ? PyDict_EVENT_ADDED : + value == NULL ? PyDict_EVENT_DELETED : + PyDict_EVENT_MODIFIED); + _PyDict_NotifyEvent(interp, event, dict, name, value); + } + FT_ATOMIC_STORE_PTR_RELEASE(values->values[ix], Py_XNewRef(value)); if (old_value == NULL) { - if (value == NULL) { - PyErr_Format(PyExc_AttributeError, - "'%.100s' object has no attribute '%U'", - Py_TYPE(obj)->tp_name, name); - return -1; - } _PyDictValues_AddToInsertionOrder(values, ix); if (dict) { assert(dict->ma_values == values); From 3d1df3d84e5c75a52b6f1379cd7f2809fc50befa Mon Sep 17 00:00:00 2001 From: Pablo Galindo Salgado Date: Mon, 21 Oct 2024 15:39:05 +0100 Subject: [PATCH 160/170] gh-125703: Correctly honour tracemalloc hooks on more PyDECREF specialized paths (#125712) --- Python/ceval.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Python/ceval.c b/Python/ceval.c index 55e5eba25eaa21..ca75646b585f07 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -99,6 +99,11 @@ } \ _Py_DECREF_STAT_INC(); \ if (--op->ob_refcnt == 0) { \ + struct _reftracer_runtime_state *tracer = &_PyRuntime.ref_tracer; \ + if (tracer->tracer_func != NULL) { \ + void* data = tracer->tracer_data; \ + tracer->tracer_func(op, PyRefTracer_DESTROY, data); \ + } \ destructor d = (destructor)(dealloc); \ d(op); \ } \ From 5b7a872b26a9ba6c93d7c2109559a82d1c1612de Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Mon, 21 Oct 2024 08:43:08 -0700 Subject: [PATCH 161/170] gh-125590: Allow FrameLocalsProxy to delete and pop keys from extra locals (#125616) --- Lib/test/test_frame.py | 30 +++++++- ...-10-16-20-32-40.gh-issue-125590.stHzOP.rst | 1 + Objects/frameobject.c | 76 +++++++++++++++++-- 3 files changed, 99 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-16-20-32-40.gh-issue-125590.stHzOP.rst diff --git a/Lib/test/test_frame.py b/Lib/test/test_frame.py index 32de8ed9a13f80..11f191700ccef0 100644 --- a/Lib/test/test_frame.py +++ b/Lib/test/test_frame.py @@ -397,15 +397,41 @@ def test_repr(self): def test_delete(self): x = 1 d = sys._getframe().f_locals - with self.assertRaises(TypeError): + + # This needs to be tested before f_extra_locals is created + with self.assertRaisesRegex(KeyError, 'non_exist'): + del d['non_exist'] + + with self.assertRaises(KeyError): + d.pop('non_exist') + + with self.assertRaisesRegex(ValueError, 'local variables'): del d['x'] with self.assertRaises(AttributeError): d.clear() - with self.assertRaises(AttributeError): + with self.assertRaises(ValueError): d.pop('x') + with self.assertRaises(ValueError): + d.pop('x', None) + + # 'm', 'n' is stored in f_extra_locals + d['m'] = 1 + d['n'] = 1 + + with self.assertRaises(KeyError): + d.pop('non_exist') + + del d['m'] + self.assertEqual(d.pop('n'), 1) + + self.assertNotIn('m', d) + self.assertNotIn('n', d) + + self.assertEqual(d.pop('n', 2), 2) + @support.cpython_only def test_sizeof(self): proxy = sys._getframe().f_locals diff --git a/Misc/NEWS.d/next/Library/2024-10-16-20-32-40.gh-issue-125590.stHzOP.rst b/Misc/NEWS.d/next/Library/2024-10-16-20-32-40.gh-issue-125590.stHzOP.rst new file mode 100644 index 00000000000000..dc6765ada641a9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-16-20-32-40.gh-issue-125590.stHzOP.rst @@ -0,0 +1 @@ +Allow ``FrameLocalsProxy`` to delete and pop if the key is not a fast variable. diff --git a/Objects/frameobject.c b/Objects/frameobject.c index f3a66ffc9aac8f..5ef48919a081be 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -5,6 +5,7 @@ #include "pycore_code.h" // CO_FAST_LOCAL, etc. #include "pycore_function.h" // _PyFunction_FromConstructor() #include "pycore_moduleobject.h" // _PyModule_GetDict() +#include "pycore_modsupport.h" // _PyArg_CheckPositional() #include "pycore_object.h" // _PyObject_GC_UNTRACK() #include "pycore_opcode_metadata.h" // _PyOpcode_Deopt, _PyOpcode_Caches @@ -158,16 +159,16 @@ framelocalsproxy_setitem(PyObject *self, PyObject *key, PyObject *value) _PyStackRef *fast = _PyFrame_GetLocalsArray(frame->f_frame); PyCodeObject *co = _PyFrame_GetCode(frame->f_frame); - if (value == NULL) { - PyErr_SetString(PyExc_TypeError, "cannot remove variables from FrameLocalsProxy"); - return -1; - } - int i = framelocalsproxy_getkeyindex(frame, key, false); if (i == -2) { return -1; } if (i >= 0) { + if (value == NULL) { + PyErr_SetString(PyExc_ValueError, "cannot remove local variables from FrameLocalsProxy"); + return -1; + } + _Py_Executors_InvalidateDependency(PyInterpreterState_Get(), co, 1); _PyLocals_Kind kind = _PyLocals_GetKind(co->co_localspluskinds, i); @@ -202,6 +203,10 @@ framelocalsproxy_setitem(PyObject *self, PyObject *key, PyObject *value) PyObject *extra = frame->f_extra_locals; if (extra == NULL) { + if (value == NULL) { + _PyErr_SetKeyError(key); + return -1; + } extra = PyDict_New(); if (extra == NULL) { return -1; @@ -211,7 +216,11 @@ framelocalsproxy_setitem(PyObject *self, PyObject *key, PyObject *value) assert(PyDict_Check(extra)); - return PyDict_SetItem(extra, key, value); + if (value == NULL) { + return PyDict_DelItem(extra, key); + } else { + return PyDict_SetItem(extra, key, value); + } } static int @@ -676,6 +685,59 @@ framelocalsproxy_setdefault(PyObject* self, PyObject *const *args, Py_ssize_t na return result; } +static PyObject* +framelocalsproxy_pop(PyObject* self, PyObject *const *args, Py_ssize_t nargs) +{ + if (!_PyArg_CheckPositional("pop", nargs, 1, 2)) { + return NULL; + } + + PyObject *key = args[0]; + PyObject *default_value = NULL; + + if (nargs == 2) { + default_value = args[1]; + } + + PyFrameObject *frame = ((PyFrameLocalsProxyObject*)self)->frame; + + int i = framelocalsproxy_getkeyindex(frame, key, false); + if (i == -2) { + return NULL; + } + + if (i >= 0) { + PyErr_SetString(PyExc_ValueError, "cannot remove local variables from FrameLocalsProxy"); + return NULL; + } + + PyObject *result = NULL; + + if (frame->f_extra_locals == NULL) { + if (default_value != NULL) { + return Py_XNewRef(default_value); + } else { + _PyErr_SetKeyError(key); + return NULL; + } + } + + if (PyDict_Pop(frame->f_extra_locals, key, &result) < 0) { + return NULL; + } + + if (result == NULL) { + if (default_value != NULL) { + return Py_XNewRef(default_value); + } else { + _PyErr_SetKeyError(key); + return NULL; + } + } + + return result; +} + static PyObject* framelocalsproxy_copy(PyObject *self, PyObject *Py_UNUSED(ignored)) { @@ -743,6 +805,8 @@ static PyMethodDef framelocalsproxy_methods[] = { NULL}, {"get", _PyCFunction_CAST(framelocalsproxy_get), METH_FASTCALL, NULL}, + {"pop", _PyCFunction_CAST(framelocalsproxy_pop), METH_FASTCALL, + NULL}, {"setdefault", _PyCFunction_CAST(framelocalsproxy_setdefault), METH_FASTCALL, NULL}, {NULL, NULL} /* sentinel */ From d67bf2d89ab57f94608d7d2cf949dc4a8749485d Mon Sep 17 00:00:00 2001 From: partev Date: Mon, 21 Oct 2024 12:18:10 -0400 Subject: [PATCH 162/170] gh-125766: Docs: minor rewording of installation on Linux section (GH-125743) --- Doc/using/unix.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/using/unix.rst b/Doc/using/unix.rst index 58838c28e6eb86..a2bcdab09a9282 100644 --- a/Doc/using/unix.rst +++ b/Doc/using/unix.rst @@ -17,12 +17,12 @@ On Linux Python comes preinstalled on most Linux distributions, and is available as a package on all others. However there are certain features you might want to use -that are not available on your distro's package. You can easily compile the +that are not available on your distro's package. You can compile the latest version of Python from source. -In the event that Python doesn't come preinstalled and isn't in the repositories as -well, you can easily make packages for your own distro. Have a look at the -following links: +In the event that the latest version of Python doesn't come preinstalled and isn't +in the repositories as well, you can make packages for your own distro. Have a +look at the following links: .. seealso:: From d880c83ff7fb2e464bc4f469d74cc3fc3eca082c Mon Sep 17 00:00:00 2001 From: Richard Hansen Date: Mon, 21 Oct 2024 12:46:37 -0400 Subject: [PATCH 163/170] Doc: C API: Move `tp_dealloc` paragraph to `tp_dealloc` section (#125737) It looks like commit 43cf44ddcce6b225f959ea2a53e4817244ca6054 (gh-31501) accidentally moved the paragraph to the `tp_finalize` section when the intent was to move it to the `tp_dealloc` section (according to the commit message). Also: * Convert the paragraph to a warning. * Apply the appropriate font style to `tp_dealloc`. * Unlinkify the first mention of `tp_dealloc` since the paragraph is already in the `tp_dealloc` section. --- Doc/c-api/typeobj.rst | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index da1b5092fbf787..0c59b3da0795cb 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -682,6 +682,19 @@ and :c:data:`PyType_Type` effectively act as defaults.) Py_DECREF(tp); } + .. warning:: + + In a garbage collected Python, :c:member:`!tp_dealloc` may be called from + any Python thread, not just the thread which created the object (if the + object becomes part of a refcount cycle, that cycle might be collected by + a garbage collection on any thread). This is not a problem for Python + API calls, since the thread on which :c:member:`!tp_dealloc` is called + will own the Global Interpreter Lock (GIL). However, if the object being + destroyed in turn destroys objects from some other C or C++ library, care + should be taken to ensure that destroying those objects on the thread + which called :c:member:`!tp_dealloc` will not violate any assumptions of + the library. + **Inheritance:** @@ -2109,17 +2122,6 @@ and :c:data:`PyType_Type` effectively act as defaults.) PyErr_Restore(error_type, error_value, error_traceback); } - Also, note that, in a garbage collected Python, - :c:member:`~PyTypeObject.tp_dealloc` may be called from - any Python thread, not just the thread which created the object (if the object - becomes part of a refcount cycle, that cycle might be collected by a garbage - collection on any thread). This is not a problem for Python API calls, since - the thread on which tp_dealloc is called will own the Global Interpreter Lock - (GIL). However, if the object being destroyed in turn destroys objects from some - other C or C++ library, care should be taken to ensure that destroying those - objects on the thread which called tp_dealloc will not violate any assumptions - of the library. - **Inheritance:** This field is inherited by subtypes. From 9b0bfba2a265b8108610b037945c004d8e81f2b4 Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Mon, 21 Oct 2024 12:51:29 -0400 Subject: [PATCH 164/170] gh-124218: Use per-thread reference counting for globals and builtins (#125713) Use per-thread refcounting for the reference from function objects to the globals and builtins dictionaries. --- Include/cpython/dictobject.h | 4 +++- Include/internal/pycore_dict.h | 34 ++++++++++++++++++++++++++ Include/internal/pycore_object.h | 14 +++++++++++ Include/internal/pycore_uniqueid.h | 3 +++ Objects/dictobject.c | 18 ++++++++++++++ Objects/funcobject.c | 38 +++++++++++++++++++++++++----- Objects/moduleobject.c | 3 ++- Python/uniqueid.c | 12 +++++++--- 8 files changed, 115 insertions(+), 11 deletions(-) diff --git a/Include/cpython/dictobject.h b/Include/cpython/dictobject.h index b113c7fdcf6515..78473e54898fa5 100644 --- a/Include/cpython/dictobject.h +++ b/Include/cpython/dictobject.h @@ -17,7 +17,9 @@ typedef struct { /* This is a private field for CPython's internal use. * Bits 0-7 are for dict watchers. * Bits 8-11 are for the watched mutation counter (used by tier2 optimization) - * The remaining bits are not currently used. */ + * Bits 12-31 are currently unused + * Bits 32-63 are a unique id in the free threading build (used for per-thread refcounting) + */ uint64_t _ma_watcher_tag; PyDictKeysObject *ma_keys; diff --git a/Include/internal/pycore_dict.h b/Include/internal/pycore_dict.h index 1920724c1d4f57..1d185559b3ef43 100644 --- a/Include/internal/pycore_dict.h +++ b/Include/internal/pycore_dict.h @@ -229,6 +229,8 @@ static inline PyDictUnicodeEntry* DK_UNICODE_ENTRIES(PyDictKeysObject *dk) { #define DICT_VERSION_INCREMENT (1 << (DICT_MAX_WATCHERS + DICT_WATCHED_MUTATION_BITS)) #define DICT_WATCHER_MASK ((1 << DICT_MAX_WATCHERS) - 1) #define DICT_WATCHER_AND_MODIFICATION_MASK ((1 << (DICT_MAX_WATCHERS + DICT_WATCHED_MUTATION_BITS)) - 1) +#define DICT_UNIQUE_ID_SHIFT (32) +#define DICT_UNIQUE_ID_MAX ((UINT64_C(1) << (64 - DICT_UNIQUE_ID_SHIFT)) - 1) PyAPI_FUNC(void) @@ -307,8 +309,40 @@ _PyInlineValuesSize(PyTypeObject *tp) int _PyDict_DetachFromObject(PyDictObject *dict, PyObject *obj); +// Enables per-thread ref counting on this dict in the free threading build +extern void _PyDict_EnablePerThreadRefcounting(PyObject *op); + PyDictObject *_PyObject_MaterializeManagedDict_LockHeld(PyObject *); +// See `_Py_INCREF_TYPE()` in pycore_object.h +#ifndef Py_GIL_DISABLED +# define _Py_INCREF_DICT Py_INCREF +# define _Py_DECREF_DICT Py_DECREF +#else +static inline Py_ssize_t +_PyDict_UniqueId(PyDictObject *mp) +{ + // Offset by one so that _ma_watcher_tag=0 represents an unassigned id + return (Py_ssize_t)(mp->_ma_watcher_tag >> DICT_UNIQUE_ID_SHIFT) - 1; +} + +static inline void +_Py_INCREF_DICT(PyObject *op) +{ + assert(PyDict_Check(op)); + Py_ssize_t id = _PyDict_UniqueId((PyDictObject *)op); + _Py_THREAD_INCREF_OBJECT(op, id); +} + +static inline void +_Py_DECREF_DICT(PyObject *op) +{ + assert(PyDict_Check(op)); + Py_ssize_t id = _PyDict_UniqueId((PyDictObject *)op); + _Py_THREAD_DECREF_OBJECT(op, id); +} +#endif + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index 96f6d61e1c620b..c7af720b1ce43d 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -293,6 +293,20 @@ extern PyStatus _PyObject_InitState(PyInterpreterState *interp); extern void _PyObject_FiniState(PyInterpreterState *interp); extern bool _PyRefchain_IsTraced(PyInterpreterState *interp, PyObject *obj); +// Macros used for per-thread reference counting in the free threading build. +// They resolve to normal Py_INCREF/DECREF calls in the default build. +// +// The macros are used for only a few references that would otherwise cause +// scaling bottlenecks in the free threading build: +// - The reference from an object to `ob_type`. +// - The reference from a function to `func_code`. +// - The reference from a function to `func_globals` and `func_builtins`. +// +// It's safe, but not performant or necessary, to use these macros for other +// references to code, type, or dict objects. It's also safe to mix their +// usage with normal Py_INCREF/DECREF calls. +// +// See also Include/internal/pycore_dict.h for _Py_INCREF_DICT/_Py_DECREF_DICT. #ifndef Py_GIL_DISABLED # define _Py_INCREF_TYPE Py_INCREF # define _Py_DECREF_TYPE Py_DECREF diff --git a/Include/internal/pycore_uniqueid.h b/Include/internal/pycore_uniqueid.h index ad5dd38ea08483..d3db49ddb78103 100644 --- a/Include/internal/pycore_uniqueid.h +++ b/Include/internal/pycore_uniqueid.h @@ -48,6 +48,9 @@ struct _Py_unique_id_pool { // Assigns the next id from the pool of ids. extern Py_ssize_t _PyObject_AssignUniqueId(PyObject *obj); +// Releases the allocated id back to the pool. +extern void _PyObject_ReleaseUniqueId(Py_ssize_t unique_id); + // Releases the allocated id back to the pool. extern void _PyObject_DisablePerThreadRefcounting(PyObject *obj); diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 806096f5814062..c4e11a3e9c0bc7 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -1636,6 +1636,24 @@ _PyDict_MaybeUntrack(PyObject *op) _PyObject_GC_UNTRACK(op); } +void +_PyDict_EnablePerThreadRefcounting(PyObject *op) +{ + assert(PyDict_Check(op)); +#ifdef Py_GIL_DISABLED + Py_ssize_t id = _PyObject_AssignUniqueId(op); + if ((uint64_t)id >= (uint64_t)DICT_UNIQUE_ID_MAX) { + _PyObject_ReleaseUniqueId(id); + return; + } + + PyDictObject *mp = (PyDictObject *)op; + assert((mp->_ma_watcher_tag >> DICT_UNIQUE_ID_SHIFT) == 0); + // Plus 1 so that _ma_watcher_tag=0 represents an unassigned id + mp->_ma_watcher_tag += ((uint64_t)id + 1) << DICT_UNIQUE_ID_SHIFT; +#endif +} + static inline int is_unusable_slot(Py_ssize_t ix) { diff --git a/Objects/funcobject.c b/Objects/funcobject.c index 3cb247691386bf..44fb4ac0907d7b 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -3,6 +3,7 @@ #include "Python.h" #include "pycore_ceval.h" // _PyEval_BuiltinsFromGlobals() +#include "pycore_dict.h" // _Py_INCREF_DICT() #include "pycore_long.h" // _PyLong_GetOne() #include "pycore_modsupport.h" // _PyArg_NoKeywords() #include "pycore_object.h" // _PyObject_GC_UNTRACK() @@ -112,8 +113,15 @@ _PyFunction_FromConstructor(PyFrameConstructor *constr) Py_XDECREF(module); return NULL; } - op->func_globals = Py_NewRef(constr->fc_globals); - op->func_builtins = Py_NewRef(constr->fc_builtins); + _Py_INCREF_DICT(constr->fc_globals); + op->func_globals = constr->fc_globals; + if (PyDict_Check(constr->fc_builtins)) { + _Py_INCREF_DICT(constr->fc_builtins); + } + else { + Py_INCREF(constr->fc_builtins); + } + op->func_builtins = constr->fc_builtins; op->func_name = Py_NewRef(constr->fc_name); op->func_qualname = Py_NewRef(constr->fc_qualname); _Py_INCREF_CODE((PyCodeObject *)constr->fc_code); @@ -143,7 +151,7 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname { assert(globals != NULL); assert(PyDict_Check(globals)); - Py_INCREF(globals); + _Py_INCREF_DICT(globals); PyThreadState *tstate = _PyThreadState_GET(); @@ -184,7 +192,12 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname if (builtins == NULL) { goto error; } - Py_INCREF(builtins); + if (PyDict_Check(builtins)) { + _Py_INCREF_DICT(builtins); + } + else { + Py_INCREF(builtins); + } PyFunctionObject *op = PyObject_GC_New(PyFunctionObject, &PyFunction_Type); if (op == NULL) { @@ -1057,8 +1070,21 @@ func_clear(PyObject *self) { PyFunctionObject *op = _PyFunction_CAST(self); func_clear_version(_PyInterpreterState_GET(), op); - Py_CLEAR(op->func_globals); - Py_CLEAR(op->func_builtins); + PyObject *globals = op->func_globals; + op->func_globals = NULL; + if (globals != NULL) { + _Py_DECREF_DICT(globals); + } + PyObject *builtins = op->func_builtins; + op->func_builtins = NULL; + if (builtins != NULL) { + if (PyDict_Check(builtins)) { + _Py_DECREF_DICT(builtins); + } + else { + Py_DECREF(builtins); + } + } Py_CLEAR(op->func_module); Py_CLEAR(op->func_defaults); Py_CLEAR(op->func_kwdefaults); diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index f63ae4e048bcd9..c06badd5f3edfe 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -3,6 +3,7 @@ #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgs() +#include "pycore_dict.h" // _PyDict_EnablePerThreadRefcounting() #include "pycore_fileutils.h" // _Py_wgetcwd #include "pycore_interp.h" // PyInterpreterState.importlib #include "pycore_long.h" // _PyLong_GetOne() @@ -105,7 +106,7 @@ new_module_notrack(PyTypeObject *mt) static void track_module(PyModuleObject *m) { - _PyObject_SetDeferredRefcount(m->md_dict); + _PyDict_EnablePerThreadRefcounting(m->md_dict); PyObject_GC_Track(m->md_dict); _PyObject_SetDeferredRefcount((PyObject *)m); diff --git a/Python/uniqueid.c b/Python/uniqueid.c index 0cbb35c6cd2f8b..b9f30713feeb57 100644 --- a/Python/uniqueid.c +++ b/Python/uniqueid.c @@ -1,5 +1,6 @@ #include "Python.h" +#include "pycore_dict.h" // _PyDict_UniqueId() #include "pycore_lock.h" // PyMutex_LockFlags() #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_object.h" // _Py_IncRefTotal @@ -98,8 +99,8 @@ _PyObject_AssignUniqueId(PyObject *obj) return unique_id; } -static void -release_unique_id(Py_ssize_t unique_id) +void +_PyObject_ReleaseUniqueId(Py_ssize_t unique_id) { PyInterpreterState *interp = _PyInterpreterState_GET(); struct _Py_unique_id_pool *pool = &interp->unique_ids; @@ -128,6 +129,11 @@ clear_unique_id(PyObject *obj) id = co->_co_unique_id; co->_co_unique_id = -1; } + else if (PyDict_Check(obj)) { + PyDictObject *mp = (PyDictObject *)obj; + id = _PyDict_UniqueId(mp); + mp->_ma_watcher_tag &= ~(UINT64_MAX << DICT_UNIQUE_ID_SHIFT); + } return id; } @@ -136,7 +142,7 @@ _PyObject_DisablePerThreadRefcounting(PyObject *obj) { Py_ssize_t id = clear_unique_id(obj); if (id >= 0) { - release_unique_id(id); + _PyObject_ReleaseUniqueId(id); } } From 695814c6e97aad0ae2b116cedca3e77d25d5b968 Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Mon, 21 Oct 2024 18:54:24 +0100 Subject: [PATCH 165/170] gh-119786: move interpreter doc from devguide to InternalDocs (#125715) --- InternalDocs/README.md | 31 ++- InternalDocs/code_objects.md | 5 + InternalDocs/generators.md | 9 + InternalDocs/interpreter.md | 364 +++++++++++++++++++++++++++++++++++ 4 files changed, 400 insertions(+), 9 deletions(-) create mode 100644 InternalDocs/code_objects.md create mode 100644 InternalDocs/generators.md create mode 100644 InternalDocs/interpreter.md diff --git a/InternalDocs/README.md b/InternalDocs/README.md index 0a6ecf899458ed..48c893bde2a631 100644 --- a/InternalDocs/README.md +++ b/InternalDocs/README.md @@ -11,19 +11,32 @@ The core dev team attempts to keep this documentation up to date. If it is not, please report that through the [issue tracker](https://github.com/python/cpython/issues). -Index: ------ -[Guide to the parser](parser.md) +Compiling Python Source Code +--- -[Compiler Design](compiler.md) +- [Guide to the parser](parser.md) -[Frames](frames.md) +- [Compiler Design](compiler.md) -[Adaptive Instruction Families](adaptive.md) +Runtime Objects +--- -[The Source Code Locations Table](locations.md) +- [Code Objects (coming soon)](code_objects.md) -[Garbage collector design](garbage_collector.md) +- [The Source Code Locations Table](locations.md) -[Exception Handling](exception_handling.md) +- [Generators (coming soon)](generators.md) + +- [Frames](frames.md) + +Program Execution +--- + +- [The Interpreter](interpreter.md) + +- [Adaptive Instruction Families](adaptive.md) + +- [Garbage Collector Design](garbage_collector.md) + +- [Exception Handling](exception_handling.md) diff --git a/InternalDocs/code_objects.md b/InternalDocs/code_objects.md new file mode 100644 index 00000000000000..284a8b7aee5765 --- /dev/null +++ b/InternalDocs/code_objects.md @@ -0,0 +1,5 @@ + +Code objects +============ + +Coming soon. diff --git a/InternalDocs/generators.md b/InternalDocs/generators.md new file mode 100644 index 00000000000000..d53f0f9bdff4e4 --- /dev/null +++ b/InternalDocs/generators.md @@ -0,0 +1,9 @@ + +Generators +========== + +Coming soon. + + diff --git a/InternalDocs/interpreter.md b/InternalDocs/interpreter.md new file mode 100644 index 00000000000000..dcfddc99370c0e --- /dev/null +++ b/InternalDocs/interpreter.md @@ -0,0 +1,364 @@ + +The bytecode interpreter +======================== + +Overview +-------- + +This document describes the workings and implementation of the bytecode +interpreter, the part of python that executes compiled Python code. Its +entry point is in [Python/ceval.c](../Python/ceval.c). + +At a high level, the interpreter consists of a loop that iterates over the +bytecode instructions, executing each of them via a switch statement that +has a case implementing each opcode. This switch statement is generated +from the instruction definitions in [Python/bytecodes.c](../Python/bytecodes.c) +which are written in [a DSL](../Tools/cases_generator/interpreter_definition.md) +developed for this purpose. + +Recall that the [Python Compiler](compiler.md) produces a [`CodeObject`](code_object.md), +which contains the bytecode instructions along with static data that is required to execute them, +such as the consts list, variable names, +[exception table](exception_handling.md#format-of-the-exception-table), and so on. + +When the interpreter's +[`PyEval_EvalCode()`](https://docs.python.org/3.14/c-api/veryhigh.html#c.PyEval_EvalCode) +function is called to execute a `CodeObject`, it constructs a [`Frame`](frames.md) and calls +[`_PyEval_EvalFrame()`](https://docs.python.org/3.14/c-api/veryhigh.html#c.PyEval_EvalCode) +to execute the code object in this frame. The frame hold the dynamic state of the +`CodeObject`'s execution, including the instruction pointer, the globals and builtins. +It also has a reference to the `CodeObject` itself. + +In addition to the frame, `_PyEval_EvalFrame()` also receives a +[`Thread State`](https://docs.python.org/3/c-api/init.html#c.PyThreadState) +object, `tstate`, which includes things like the exception state and the +recursion depth. The thread state also provides access to the per-interpreter +state (`tstate->interp`), which has a pointer to the per-runtime (that is, +truly global) state (`tstate->interp->runtime`). + +Finally, `_PyEval_EvalFrame()` receives an integer argument `throwflag` +which, when nonzero, indicates that the interpreter should just raise the current exception +(this is used in the implementation of +[`gen.throw`](https://docs.python.org/3.14/reference/expressions.html#generator.throw). + +By default, [`_PyEval_EvalFrame()`](https://docs.python.org/3.14/c-api/veryhigh.html#c.PyEval_EvalCode) +simply calls [`_PyEval_EvalFrameDefault()`] to execute the frame. However, as per +[`PEP 523`](https://peps.python.org/pep-0523/) this is configurable by setting +`interp->eval_frame`. In the following, we describe the default function, +`_PyEval_EvalFrameDefault()`. + + +Instruction decoding +-------------------- + +The first task of the interpreter is to decode the bytecode instructions. +Bytecode is stored as an array of 16-bit code units (`_Py_CODEUNIT`). +Each code unit contains an 8-bit `opcode` and an 8-bit argument (`oparg`), both unsigned. +In order to make the bytecode format independent of the machine byte order when stored on disk, +`opcode` is always the first byte and `oparg` is always the second byte. +Macros are used to extract the `opcode` and `oparg` from a code unit +(`_Py_OPCODE(word)` and `_Py_OPARG(word)`). +Some instructions (for example, `NOP` or `POP_TOP`) have no argument -- in this case +we ignore `oparg`. + +A simplified version of the interpreter's main loop looks like this: + +```c + _Py_CODEUNIT *first_instr = code->co_code_adaptive; + _Py_CODEUNIT *next_instr = first_instr; + while (1) { + _Py_CODEUNIT word = *next_instr++; + unsigned char opcode = _Py_OPCODE(word); + unsigned int oparg = _Py_OPARG(word); + switch (opcode) { + // ... A case for each opcode ... + } + } +``` + +This loop iterates over the instructions, decoding each into its `opcode` +and `oparg`, and then executes the switch case that implements this `opcode`. + +The instruction format supports 256 different opcodes, which is sufficient. +However, it also limits `oparg` to 8-bit values, which is too restrictive. +To overcome this, the `EXTENDED_ARG` opcode allows us to prefix any instruction +with one or more additional data bytes, which combine into a larger oparg. +For example, this sequence of code units: + + EXTENDED_ARG 1 + EXTENDED_ARG 0 + LOAD_CONST 2 + +would set `opcode` to `LOAD_CONST` and `oparg` to `65538` (that is, `0x1_00_02`). +The compiler should limit itself to at most three `EXTENDED_ARG` prefixes, to allow the +resulting `oparg` to fit in 32 bits, but the interpreter does not check this. + +In the following, a `code unit` is always two bytes, while an `instruction` is a +sequence of code units consisting of zero to three `EXTENDED_ARG` opcodes followed by +a primary opcode. + +The following loop, to be inserted just above the `switch` statement, will make the above +snippet decode a complete instruction: + +```c + while (opcode == EXTENDED_ARG) { + word = *next_instr++; + opcode = _Py_OPCODE(word); + oparg = (oparg << 8) | _Py_OPARG(word); + } +``` + +For various reasons we'll get to later (mostly efficiency, given that `EXTENDED_ARG` +is rare) the actual code is different. + +Jumps +===== + +Note that when the `switch` statement is reached, `next_instr` (the "instruction offset") +already points to the next instruction. +Thus, jump instructions can be implemented by manipulating `next_instr`: + +- A jump forward (`JUMP_FORWARD`) sets `next_instr += oparg`. +- A jump backward sets `next_instr -= oparg`. + +Inline cache entries +==================== + +Some (specialized or specializable) instructions have an associated "inline cache". +The inline cache consists of one or more two-byte entries included in the bytecode +array as additional words following the `opcode`/`oparg` pair. +The size of the inline cache for a particular instruction is fixed by its `opcode`. +Moreover, the inline cache size for all instructions in a +[family of specialized/specializable instructions](adaptive.md) +(for example, `LOAD_ATTR`, `LOAD_ATTR_SLOT`, `LOAD_ATTR_MODULE`) must all be +the same. Cache entries are reserved by the compiler and initialized with zeros. +Although they are represented by code units, cache entries do not conform to the +`opcode` / `oparg` format. + +If an instruction has an inline cache, the layout of its cache is described by +a `struct` definition in (`pycore_code.h`)[../Include/internal/pycore_code.h]. +This allows us to access the cache by casting `next_instr` to a pointer to this `struct`. +The size of such a `struct` must be independent of the machine architecture, word size +and alignment requirements. For a 32-bit field, the `struct` should use `_Py_CODEUNIT field[2]`. + +The instruction implementation is responsible for advancing `next_instr` past the inline cache. +For example, if an instruction's inline cache is four bytes (that is, two code units) in size, +the code for the instruction must contain `next_instr += 2;`. +This is equivalent to a relative forward jump by that many code units. +(In the interpreter definition DSL, this is coded as `JUMPBY(n)`, where `n` is the number +of code units to jump, typically given as a named constant.) + +Serializing non-zero cache entries would present a problem because the serialization +(:mod:`marshal`) format must be independent of the machine byte order. + +More information about the use of inline caches can be found in +[PEP 659](https://peps.python.org/pep-0659/#ancillary-data). + +The evaluation stack +-------------------- + +Most instructions read or write some data in the form of object references (`PyObject *`). +The CPython bytecode interpreter is a stack machine, meaning that its instructions operate +by pushing data onto and popping it off the stack. +The stack is forms part of the frame for the code object. Its maximum depth is calculated +by the compiler and stored in the `co_stacksize` field of the code object, so that the +stack can be pre-allocated is a contiguous array of `PyObject*` pointers, when the frame +is created. + +The stack effects of each instruction are also exposed through the +[opcode metadata](../Include/internal/pycore_opcode_metadata.h) through two +functions that report how many stack elements the instructions consumes, +and how many it produces (`_PyOpcode_num_popped` and `_PyOpcode_num_pushed`). +For example, the `BINARY_OP` instruction pops two objects from the stack and pushes the +result back onto the stack. + +The stack grows up in memory; the operation `PUSH(x)` is equivalent to `*stack_pointer++ = x`, +whereas `x = POP()` means `x = *--stack_pointer`. +Overflow and underflow checks are active in debug mode, but are otherwise optimized away. + +At any point during execution, the stack level is knowable based on the instruction pointer +alone, and some properties of each item on the stack are also known. +In particular, only a few instructions may push a `NULL` onto the stack, and the positions +that may be `NULL` are known. +A few other instructions (`GET_ITER`, `FOR_ITER`) push or pop an object that is known to +be an iterator. + +Instruction sequences that do not allow statically knowing the stack depth are deemed illegal; +the bytecode compiler never generates such sequences. +For example, the following sequence is illegal, because it keeps pushing items on the stack: + + LOAD_FAST 0 + JUMP_BACKWARD 2 + +> [!NOTE] +> Do not confuse the evaluation stack with the call stack, which is used to implement calling +> and returning from functions. + +Error handling +-------------- + +When the implementation of an opcode raises an exception, it jumps to the +`exception_unwind` label in [Python/ceval.c](../Python/ceval.c). +The exception is then handled as described in the +[`exception handling documentation`](exception_handling.md#handling-exceptions). + +Python-to-Python calls +---------------------- + +The `_PyEval_EvalFrameDefault()` function is recursive, because sometimes +the interpreter calls some C function that calls back into the interpreter. +In 3.10 and before, this was the case even when a Python function called +another Python function: +The `CALL` opcode would call the `tp_call` dispatch function of the +callee, which would extract the code object, create a new frame for the call +stack, and then call back into the interpreter. This approach is very general +but consumes several C stack frames for each nested Python call, thereby +increasing the risk of an (unrecoverable) C stack overflow. + +Since 3.11, the `CALL` instruction special-cases function objects to "inline" +the call. When a call gets inlined, a new frame gets pushed onto the call +stack and the interpreter "jumps" to the start of the callee's bytecode. +When an inlined callee executes a `RETURN_VALUE` instruction, the frame is +popped off the call stack and the interpreter returns to its caller, +by popping a frame off the call stack and "jumping" to the return address. +There is a flag in the frame (`frame->is_entry`) that indicates whether +the frame was inlined (set if it wasn't). +If `RETURN_VALUE` finds this flag set, it performs the usual cleanup and +returns from `_PyEval_EvalFrameDefault()` altogether, to a C caller. + +A similar check is performed when an unhandled exception occurs. + +The call stack +-------------- + +Up through 3.10, the call stack was implemented as a singly-linked list of +[frame objects](frames.md). This was expensive because each call would require a +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. + +Sometimes an actual `PyFrameObject` is needed, such as when Python code calls +`sys._getframe()` or an extension module calls +[`PyEval_GetFrame()`](https://docs.python.org/3/c-api/reflection.html#c.PyEval_GetFrame). +In this case we allocate a proper `PyFrameObject` and initialize it from the +`_PyInterpreterFrame`. + +Things get more complicated when generators are involved, since those do not +follow the push/pop model. This includes async functions, which are based on +the same mechanism. A generator object has space for a `_PyInterpreterFrame` +structure, including the variable-size part (used for locals and the eval stack). +When a generator (or async) function is first called, a special opcode +`RETURN_GENERATOR` is executed, which is responsible for creating the +generator object. The generator object's `_PyInterpreterFrame` is initialized +with a copy of the current stack frame. The current stack frame is then popped +off the frame stack and the generator object is returned. +(Details differ depending on the `is_entry` flag.) +When the generator is resumed, the interpreter pushes its `_PyInterpreterFrame` +onto the frame stack and resumes execution. +See also the [generators](generators.md) section. + + + + + +Introducing a new bytecode instruction +-------------------------------------- + +It is occasionally necessary to add a new opcode in order to implement +a new feature or change the way that existing features are compiled. +This section describes the changes required to do this. + +First, you must choose a name for the bytecode, implement it in +[`Python/bytecodes.c`](../Python/bytecodes.c) and add a documentation +entry in [`Doc/library/dis.rst`](../Doc/library/dis.rst). +Then run `make regen-cases` to assign a number for it (see +[`Include/opcode_ids.h`](../Include/opcode_ids.h)) and regenerate a +number of files with the actual implementation of the bytecode in +[`Python/generated_cases.c.h`](../Python/generated_cases.c.h) and +metadata about it in additional files. + +With a new bytecode you must also change what is called the "magic number" for +.pyc files: bump the value of the variable `MAGIC_NUMBER` in +[`Lib/importlib/_bootstrap_external.py`](../Lib/importlib/_bootstrap_external.py). +Changing this number will lead to all .pyc files with the old `MAGIC_NUMBER` +to be recompiled by the interpreter on import. Whenever `MAGIC_NUMBER` is +changed, the ranges in the `magic_values` array in +[`PC/launcher.c`](../PC/launcher.c) may also need to be updated. Changes to +[`Lib/importlib/_bootstrap_external.py`](../Lib/importlib/_bootstrap_external.py) +will take effect only after running `make regen-importlib`. + +> [!NOTE] +> Running `make regen-importlib` before adding the new bytecode target to +> [`Python/bytecodes.c`](../Python/bytecodes.c) +> (followed by `make regen-cases`) will result in an error. You should only run +> `make regen-importlib` after the new bytecode target has been added. + +> [!NOTE] +> On Windows, running the `./build.bat` script will automatically +> regenerate the required files without requiring additional arguments. + +Finally, you need to introduce the use of the new bytecode. Update +[`Python/codegen.c`](../Python/codegen.c) to emit code with this bytecode. +Optimizations in [`Python/flowgraph.c`](../Python/flowgraph.c) may also +need to be updated. If the new opcode affects a control flow or the block +stack, you may have to update the `frame_setlineno()` function in +[`Objects/frameobject.c`](../Objects/frameobject.c). It may also be necessary +to update [`Lib/dis.py`](../Lib/dis.py) if the new opcode interprets its +argument in a special way (like `FORMAT_VALUE` or `MAKE_FUNCTION`). + +If you make a change here that can affect the output of bytecode that +is already in existence and you do not change the magic number, make +sure to delete your old .py(c|o) files! Even though you will end up changing +the magic number if you change the bytecode, while you are debugging your work +you may be changing the bytecode output without constantly bumping up the +magic number. This can leave you with stale .pyc files that will not be +recreated. +Running `find . -name '*.py[co]' -exec rm -f '{}' +` should delete all .pyc +files you have, forcing new ones to be created and thus allow you test out your +new bytecode properly. Run `make regen-importlib` for updating the +bytecode of frozen importlib files. You have to run `make` again after this +to recompile the generated C files. + +Additional resources +-------------------- + +* Brandt Bucher's talk about the specializing interpreter at PyCon US 2023. + [Slides](https://github.com/brandtbucher/brandtbucher/blob/master/2023/04/21/inside_cpython_311s_new_specializing_adaptive_interpreter.pdf) + [Video](https://www.youtube.com/watch?v=PGZPSWZSkJI&t=1470s) From de5a6c7c7d00ac37d66cba9849202b374e9cdfb7 Mon Sep 17 00:00:00 2001 From: mpage Date: Mon, 21 Oct 2024 11:08:13 -0700 Subject: [PATCH 166/170] gh-121459: Fix a couple of uses of `PyStackRef_FromPyObjectSteal` (#125711) * Fix usage of PyStackRef_FromPyObjectSteal in CALL_TUPLE_1 This was missed in gh-124894 * Fix usage of PyStackRef_FromPyObjectSteal in _CALL_STR_1 This was missed in gh-124894 * Regenerate code --- Python/bytecodes.c | 10 ++++++---- Python/executor_cases.c.h | 10 ++++++---- Python/generated_cases.c.h | 10 ++++++---- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/Python/bytecodes.c b/Python/bytecodes.c index c59a35c3e828ca..62e9b5ddd1584c 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -3629,11 +3629,12 @@ dummy_func( DEOPT_IF(!PyStackRef_IsNull(null)); DEOPT_IF(callable_o != (PyObject *)&PyUnicode_Type); STAT_INC(CALL, hit); - res = PyStackRef_FromPyObjectSteal(PyObject_Str(arg_o)); + PyObject *res_o = PyObject_Str(arg_o); DEAD(null); DEAD(callable); PyStackRef_CLOSE(arg); - ERROR_IF(PyStackRef_IsNull(res), error); + ERROR_IF(res_o == NULL, error); + res = PyStackRef_FromPyObjectSteal(res_o); } macro(CALL_STR_1) = @@ -3650,11 +3651,12 @@ dummy_func( DEOPT_IF(!PyStackRef_IsNull(null)); DEOPT_IF(callable_o != (PyObject *)&PyTuple_Type); STAT_INC(CALL, hit); - res = PyStackRef_FromPyObjectSteal(PySequence_Tuple(arg_o)); + PyObject *res_o = PySequence_Tuple(arg_o); DEAD(null); DEAD(callable); PyStackRef_CLOSE(arg); - ERROR_IF(PyStackRef_IsNull(res), error); + ERROR_IF(res_o == NULL, error); + res = PyStackRef_FromPyObjectSteal(res_o); } macro(CALL_TUPLE_1) = diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 15a6c7bc1a7966..5df4986cd838b5 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -4299,10 +4299,11 @@ } STAT_INC(CALL, hit); _PyFrame_SetStackPointer(frame, stack_pointer); - res = PyStackRef_FromPyObjectSteal(PyObject_Str(arg_o)); + PyObject *res_o = PyObject_Str(arg_o); stack_pointer = _PyFrame_GetStackPointer(frame); PyStackRef_CLOSE(arg); - if (PyStackRef_IsNull(res)) JUMP_TO_ERROR(); + if (res_o == NULL) JUMP_TO_ERROR(); + res = PyStackRef_FromPyObjectSteal(res_o); stack_pointer[-3] = res; stack_pointer += -2; assert(WITHIN_STACK_BOUNDS()); @@ -4331,10 +4332,11 @@ } STAT_INC(CALL, hit); _PyFrame_SetStackPointer(frame, stack_pointer); - res = PyStackRef_FromPyObjectSteal(PySequence_Tuple(arg_o)); + PyObject *res_o = PySequence_Tuple(arg_o); stack_pointer = _PyFrame_GetStackPointer(frame); PyStackRef_CLOSE(arg); - if (PyStackRef_IsNull(res)) JUMP_TO_ERROR(); + if (res_o == NULL) JUMP_TO_ERROR(); + res = PyStackRef_FromPyObjectSteal(res_o); stack_pointer[-3] = res; stack_pointer += -2; assert(WITHIN_STACK_BOUNDS()); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index a9290986c24f45..388031af87a79f 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -2978,10 +2978,11 @@ DEOPT_IF(callable_o != (PyObject *)&PyUnicode_Type, CALL); STAT_INC(CALL, hit); _PyFrame_SetStackPointer(frame, stack_pointer); - res = PyStackRef_FromPyObjectSteal(PyObject_Str(arg_o)); + PyObject *res_o = PyObject_Str(arg_o); stack_pointer = _PyFrame_GetStackPointer(frame); PyStackRef_CLOSE(arg); - if (PyStackRef_IsNull(res)) goto pop_3_error; + if (res_o == NULL) goto pop_3_error; + res = PyStackRef_FromPyObjectSteal(res_o); } // _CHECK_PERIODIC { @@ -3028,10 +3029,11 @@ DEOPT_IF(callable_o != (PyObject *)&PyTuple_Type, CALL); STAT_INC(CALL, hit); _PyFrame_SetStackPointer(frame, stack_pointer); - res = PyStackRef_FromPyObjectSteal(PySequence_Tuple(arg_o)); + PyObject *res_o = PySequence_Tuple(arg_o); stack_pointer = _PyFrame_GetStackPointer(frame); PyStackRef_CLOSE(arg); - if (PyStackRef_IsNull(res)) goto pop_3_error; + if (res_o == NULL) goto pop_3_error; + res = PyStackRef_FromPyObjectSteal(res_o); } // _CHECK_PERIODIC { From 5ca4e34bc1aab8321911aac6d5b2b9e75ff764d8 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 21 Oct 2024 21:30:45 +0300 Subject: [PATCH 167/170] gh-125767: Fix pickling and copying of super objects (GH-125781) Previously, copying a super object returned a copy of the instance invoking super(). Pickling a super object could pickle the instance invoking super() or fail, depending on its type and protocol. Now deep copying returns a new super object and pickling pickles the super object. Shallow copying returns the same super object. --- Doc/library/functions.rst | 4 ++ Doc/whatsnew/3.14.rst | 4 ++ Lib/copy.py | 2 +- Lib/copyreg.py | 5 ++ Lib/test/test_super.py | 70 +++++++++++++++++++ ...-10-21-13-52-37.gh-issue-125767.0kK4lX.rst | 2 + 6 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-21-13-52-37.gh-issue-125767.0kK4lX.rst diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 0638df04c6ff40..290c63827ff766 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -2032,6 +2032,10 @@ are always available. They are listed here in alphabetical order. :func:`super`, see `guide to using super() `_. + .. versionchanged:: 3.14 + :class:`super` objects are now :mod:`pickleable ` and + :mod:`copyable `. + .. _func-tuple: .. class:: tuple() diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index ad841538ccc547..d52faa614db94e 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -190,6 +190,10 @@ Other language changes They raise an error if the argument is a string. (Contributed by Serhiy Storchaka in :gh:`84978`.) +* :class:`super` objects are now :mod:`pickleable ` and + :mod:`copyable `. + (Contributed by Serhiy Storchaka in :gh:`125767`.) + New modules =========== diff --git a/Lib/copy.py b/Lib/copy.py index a79976d3a658f0..f27e109973cfb7 100644 --- a/Lib/copy.py +++ b/Lib/copy.py @@ -106,7 +106,7 @@ def _copy_immutable(x): bytes, frozenset, type, range, slice, property, types.BuiltinFunctionType, types.EllipsisType, types.NotImplementedType, types.FunctionType, types.CodeType, - weakref.ref): + weakref.ref, super): d[t] = _copy_immutable d[list] = list.copy diff --git a/Lib/copyreg.py b/Lib/copyreg.py index 578392409b403c..17c5dde67c887c 100644 --- a/Lib/copyreg.py +++ b/Lib/copyreg.py @@ -36,6 +36,11 @@ def pickle_union(obj): pickle(type(int | str), pickle_union) +def pickle_super(obj): + return super, (obj.__thisclass__, obj.__self__) + +pickle(super, pickle_super) + # Support for pickling new-style objects def _reconstructor(cls, base, state): diff --git a/Lib/test/test_super.py b/Lib/test/test_super.py index 1222ec6a3c4109..149016635522c3 100644 --- a/Lib/test/test_super.py +++ b/Lib/test/test_super.py @@ -1,5 +1,7 @@ """Unit tests for zero-argument super() & related machinery.""" +import copy +import pickle import textwrap import threading import unittest @@ -539,6 +541,74 @@ def work(): for thread in threads: thread.join() + def test_special_methods(self): + for e in E(), E: + s = super(C, e) + self.assertEqual(s.__reduce__, e.__reduce__) + self.assertEqual(s.__reduce_ex__, e.__reduce_ex__) + self.assertEqual(s.__getstate__, e.__getstate__) + self.assertFalse(hasattr(s, '__getnewargs__')) + self.assertFalse(hasattr(s, '__getnewargs_ex__')) + self.assertFalse(hasattr(s, '__setstate__')) + self.assertFalse(hasattr(s, '__copy__')) + self.assertFalse(hasattr(s, '__deepcopy__')) + + def test_pickling(self): + e = E() + e.x = 1 + s = super(C, e) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(proto=proto): + u = pickle.loads(pickle.dumps(s, proto)) + self.assertEqual(u.f(), s.f()) + self.assertIs(type(u), type(s)) + self.assertIs(type(u.__self__), E) + self.assertEqual(u.__self__.x, 1) + self.assertIs(u.__thisclass__, C) + self.assertIs(u.__self_class__, E) + + s = super(C, E) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(proto=proto): + u = pickle.loads(pickle.dumps(s, proto)) + self.assertEqual(u.cm(), s.cm()) + self.assertEqual(u.f, s.f) + self.assertIs(type(u), type(s)) + self.assertIs(u.__self__, E) + self.assertIs(u.__thisclass__, C) + self.assertIs(u.__self_class__, E) + + def test_shallow_copying(self): + s = super(C, E()) + self.assertIs(copy.copy(s), s) + s = super(C, E) + self.assertIs(copy.copy(s), s) + + def test_deep_copying(self): + e = E() + e.x = [1] + s = super(C, e) + u = copy.deepcopy(s) + self.assertEqual(u.f(), s.f()) + self.assertIs(type(u), type(s)) + self.assertIsNot(u, s) + self.assertIs(type(u.__self__), E) + self.assertIsNot(u.__self__, e) + self.assertIsNot(u.__self__.x, e.x) + self.assertEqual(u.__self__.x, [1]) + self.assertIs(u.__thisclass__, C) + self.assertIs(u.__self_class__, E) + + s = super(C, E) + u = copy.deepcopy(s) + self.assertEqual(u.cm(), s.cm()) + self.assertEqual(u.f, s.f) + self.assertIsNot(u, s) + self.assertIs(type(u), type(s)) + self.assertIs(u.__self__, E) + self.assertIs(u.__thisclass__, C) + self.assertIs(u.__self_class__, E) + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2024-10-21-13-52-37.gh-issue-125767.0kK4lX.rst b/Misc/NEWS.d/next/Library/2024-10-21-13-52-37.gh-issue-125767.0kK4lX.rst new file mode 100644 index 00000000000000..bfda740a79d10e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-21-13-52-37.gh-issue-125767.0kK4lX.rst @@ -0,0 +1,2 @@ +:class:`super` objects are now :mod:`pickleable ` and +:mod:`copyable `. From dcc4fb2c9068f60353f0c0978948b7681f7745e6 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 21 Oct 2024 21:54:12 +0300 Subject: [PATCH 168/170] gh-124969: Make locale.nl_langinfo(locale.ALT_DIGITS) returning a string again (GH-125774) This is a follow up of GH-124974. Only Glibc needed a fix. Now the returned value is a string consisting of semicolon-separated symbols on all Posix platforms. --- Doc/library/locale.rst | 7 ++-- Lib/test/test__locale.py | 30 ++++++++++----- ...-10-21-12-06-55.gh-issue-124969.xiY8UP.rst | 2 + Modules/_localemodule.c | 38 +++++++++++-------- 4 files changed, 50 insertions(+), 27 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-21-12-06-55.gh-issue-124969.xiY8UP.rst diff --git a/Doc/library/locale.rst b/Doc/library/locale.rst index 5f3c4840b5cc70..f172a55080efc9 100644 --- a/Doc/library/locale.rst +++ b/Doc/library/locale.rst @@ -158,8 +158,7 @@ The :mod:`locale` module defines the following exception and functions: .. function:: nl_langinfo(option) - Return some locale-specific information as a string (or a tuple for - ``ALT_DIGITS``). This function is not + Return some locale-specific information as a string. This function is not available on all systems, and the set of possible options might also vary across platforms. The possible argument values are numbers, for which symbolic constants are available in the locale module. @@ -312,7 +311,9 @@ The :mod:`locale` module defines the following exception and functions: .. data:: ALT_DIGITS - Get a tuple of up to 100 strings used to represent the values 0 to 99. + Get a string consisting of up to 100 semicolon-separated symbols used + to represent the values 0 to 99 in a locale-specific way. + In most locales this is an empty string. The function temporarily sets the ``LC_CTYPE`` locale to the locale of the category that determines the requested value (``LC_TIME``, diff --git a/Lib/test/test__locale.py b/Lib/test/test__locale.py index e403c2a822788d..7e6e296c069abb 100644 --- a/Lib/test/test__locale.py +++ b/Lib/test/test__locale.py @@ -26,7 +26,10 @@ 'bs_BA', 'fr_LU', 'kl_GL', 'fa_IR', 'de_BE', 'sv_SE', 'it_CH', 'uk_UA', 'eu_ES', 'vi_VN', 'af_ZA', 'nb_NO', 'en_DK', 'tg_TJ', 'ps_AF', 'en_US', 'fr_FR.ISO8859-1', 'fr_FR.UTF-8', 'fr_FR.ISO8859-15@euro', - 'ru_RU.KOI8-R', 'ko_KR.eucKR'] + 'ru_RU.KOI8-R', 'ko_KR.eucKR', + 'ja_JP.UTF-8', 'lzh_TW.UTF-8', 'my_MM.UTF-8', 'or_IN.UTF-8', 'shn_MM.UTF-8', + 'ar_AE.UTF-8', 'bn_IN.UTF-8', 'mr_IN.UTF-8', 'th_TH.TIS620', +] def setUpModule(): global candidate_locales @@ -78,11 +81,13 @@ def accept(loc): 'C': (0, {}), 'en_US': (0, {}), 'fa_IR': (100, {0: '\u06f0\u06f0', 10: '\u06f1\u06f0', 99: '\u06f9\u06f9'}), - 'ja_JP': (100, {0: '\u3007', 10: '\u5341', 99: '\u4e5d\u5341\u4e5d'}), + 'ja_JP': (100, {1: '\u4e00', 10: '\u5341', 99: '\u4e5d\u5341\u4e5d'}), 'lzh_TW': (32, {0: '\u3007', 10: '\u5341', 31: '\u5345\u4e00'}), 'my_MM': (100, {0: '\u1040\u1040', 10: '\u1041\u1040', 99: '\u1049\u1049'}), 'or_IN': (100, {0: '\u0b66', 10: '\u0b67\u0b66', 99: '\u0b6f\u0b6f'}), 'shn_MM': (100, {0: '\u1090\u1090', 10: '\u1091\u1090', 99: '\u1099\u1099'}), + 'ar_AE': (100, {0: '\u0660', 10: '\u0661\u0660', 99: '\u0669\u0669'}), + 'bn_IN': (100, {0: '\u09e6', 10: '\u09e7\u09e6', 99: '\u09ef\u09ef'}), } if sys.platform == 'win32': @@ -199,21 +204,28 @@ def test_lc_numeric_basic(self): def test_alt_digits_nl_langinfo(self): # Test nl_langinfo(ALT_DIGITS) tested = False - for loc, (count, samples) in known_alt_digits.items(): + for loc in candidate_locales: with self.subTest(locale=loc): try: setlocale(LC_TIME, loc) except Error: self.skipTest(f'no locale {loc!r}') continue + with self.subTest(locale=loc): alt_digits = nl_langinfo(locale.ALT_DIGITS) - self.assertIsInstance(alt_digits, tuple) - if count and not alt_digits and support.is_apple: - self.skipTest(f'ALT_DIGITS is not set for locale {loc!r} on Apple platforms') - self.assertEqual(len(alt_digits), count) - for i in samples: - self.assertEqual(alt_digits[i], samples[i]) + self.assertIsInstance(alt_digits, str) + alt_digits = alt_digits.split(';') if alt_digits else [] + if alt_digits: + self.assertGreaterEqual(len(alt_digits), 10, alt_digits) + loc1 = loc.split('.', 1)[0] + if loc1 in known_alt_digits: + count, samples = known_alt_digits[loc1] + if count and not alt_digits: + self.skipTest(f'ALT_DIGITS is not set for locale {loc!r} on this platform') + self.assertEqual(len(alt_digits), count, alt_digits) + for i in samples: + self.assertEqual(alt_digits[i], samples[i]) tested = True if not tested: self.skipTest('no suitable locales') diff --git a/Misc/NEWS.d/next/Library/2024-10-21-12-06-55.gh-issue-124969.xiY8UP.rst b/Misc/NEWS.d/next/Library/2024-10-21-12-06-55.gh-issue-124969.xiY8UP.rst new file mode 100644 index 00000000000000..c44550184e0000 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-21-12-06-55.gh-issue-124969.xiY8UP.rst @@ -0,0 +1,2 @@ +``locale.nl_langinfo(locale.ALT_DIGITS)`` now returns a string again. The +returned value consists of up to 100 semicolon-separated symbols. diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c index 0daec646605775..2a789ea74d27da 100644 --- a/Modules/_localemodule.c +++ b/Modules/_localemodule.c @@ -667,28 +667,36 @@ _locale_nl_langinfo_impl(PyObject *module, int item) return NULL; } PyObject *pyresult; +#ifdef __GLIBC__ #ifdef ALT_DIGITS - if (item == ALT_DIGITS) { - /* The result is a sequence of up to 100 NUL-separated strings. */ - const char *s = result; + if (item == ALT_DIGITS && *result) { + /* According to the POSIX specification the result must be + * a sequence of up to 100 semicolon-separated strings. + * But in Glibc they are NUL-separated. */ + Py_ssize_t i = 0; int count = 0; - for (; count < 100 && *s; count++) { - s += strlen(s) + 1; + for (; count < 100 && result[i]; count++) { + i += strlen(result + i) + 1; } - pyresult = PyTuple_New(count); - if (pyresult != NULL) { - for (int i = 0; i < count; i++) { - PyObject *unicode = PyUnicode_DecodeLocale(result, NULL); - if (unicode == NULL) { - Py_CLEAR(pyresult); - break; - } - PyTuple_SET_ITEM(pyresult, i, unicode); - result += strlen(result) + 1; + char *buf = PyMem_Malloc(i); + if (buf == NULL) { + PyErr_NoMemory(); + pyresult = NULL; + } + else { + memcpy(buf, result, i); + /* Replace all NULs with semicolons. */ + i = 0; + while (--count) { + i += strlen(buf + i); + buf[i++] = ';'; } + pyresult = PyUnicode_DecodeLocale(buf, NULL); + PyMem_Free(buf); } } else +#endif #endif { pyresult = PyUnicode_DecodeLocale(result, NULL); From 9dde4638e44639d45bd7d72e70a8d410995a585a Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 21 Oct 2024 22:17:39 +0300 Subject: [PATCH 169/170] gh-53203: Fix test_strptime on Solaris (GH-125785) Use fixed timezone. Skip roundtrip tests on locales with 2-digit year. --- Lib/test/test_strptime.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Lib/test/test_strptime.py b/Lib/test/test_strptime.py index 09f6f656bfcb0d..9f5cfca9c7f124 100644 --- a/Lib/test/test_strptime.py +++ b/Lib/test/test_strptime.py @@ -515,12 +515,17 @@ def test_date_time_locale(self): # NB: Dates before 1969 do not roundtrip on some locales: # az_IR, bo_CN, bo_IN, dz_BT, eu_ES, eu_FR, fa_IR, or_IN. + @support.run_with_tz('STD-1DST,M4.1.0,M10.1.0') @run_with_locales('LC_TIME', 'C', 'en_US', 'fr_FR', 'de_DE', 'ja_JP', 'he_IL', 'ar_AE', 'mfe_MU', 'yo_NG', 'csb_PL', 'br_FR', 'gez_ET', 'brx_IN', 'my_MM', 'shn_MM') def test_date_time_locale2(self): # Test %c directive + loc = locale.getlocale(locale.LC_TIME)[0] + if sys.platform.startswith('sunos'): + if loc in ('ar_AE',): + self.skipTest(f'locale {loc!r} may not work on this platform') self.roundtrip('%c', slice(0, 6), (1900, 1, 1, 0, 0, 0, 0, 1, 0)) self.roundtrip('%c', slice(0, 6), (1800, 1, 1, 0, 0, 0, 0, 1, 0)) @@ -553,6 +558,10 @@ def test_date_locale(self): 'eu_ES', 'ar_AE', 'my_MM', 'shn_MM') def test_date_locale2(self): # Test %x directive + loc = locale.getlocale(locale.LC_TIME)[0] + if sys.platform.startswith('sunos'): + if loc in ('en_US', 'de_DE', 'ar_AE'): + self.skipTest(f'locale {loc!r} may not work on this platform') self.roundtrip('%x', slice(0, 3), (1900, 1, 1, 0, 0, 0, 0, 1, 0)) self.roundtrip('%x', slice(0, 3), (1800, 1, 1, 0, 0, 0, 0, 1, 0)) From 44f841f01af0fb038e142a07f15eda1ecdd5b08a Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Mon, 21 Oct 2024 13:39:07 -0600 Subject: [PATCH 170/170] gh-125716: Raise an Exception If _globals_init() Fails In the _interpqueues Module (gh-125802) The fix applies to the _interpchannels module as well. I've also included a drive-by typo fix for _interpqueues. --- Modules/_interpchannelsmodule.c | 3 ++- Modules/_interpqueuesmodule.c | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Modules/_interpchannelsmodule.c b/Modules/_interpchannelsmodule.c index a8b4a8d76b0eaa..c52cde6da500f7 100644 --- a/Modules/_interpchannelsmodule.c +++ b/Modules/_interpchannelsmodule.c @@ -3482,7 +3482,8 @@ The 'interpreters' module provides a more convenient interface."); static int module_exec(PyObject *mod) { - if (_globals_init() != 0) { + int err = _globals_init(); + if (handle_channel_error(err, mod, -1)) { return -1; } diff --git a/Modules/_interpqueuesmodule.c b/Modules/_interpqueuesmodule.c index 55c43199ee4d79..aa70134d82b046 100644 --- a/Modules/_interpqueuesmodule.c +++ b/Modules/_interpqueuesmodule.c @@ -1312,7 +1312,7 @@ _queueid_xid_new(int64_t qid) struct _queueid_xid *data = PyMem_RawMalloc(sizeof(struct _queueid_xid)); if (data == NULL) { - _queues_incref(queues, qid); + _queues_decref(queues, qid); return NULL; } data->qid = qid; @@ -1894,7 +1894,8 @@ The 'interpreters' module provides a more convenient interface."); static int module_exec(PyObject *mod) { - if (_globals_init() != 0) { + int err = _globals_init(); + if (handle_queue_error(err, mod, -1)) { return -1; }