From 7d70a147f58edabc9691869a0e8b606c9c3ac184 Mon Sep 17 00:00:00 2001 From: Shamil Date: Mon, 27 Oct 2025 11:55:57 +0300 Subject: [PATCH 1/4] Remove dead stores to 'size' in UTF-8 decoder (unicodeobject.c) (#140637) --- Objects/unicodeobject.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index d4549b70d4dabc..f60f7dd2d13604 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -5409,7 +5409,6 @@ unicode_decode_utf8(const char *s, Py_ssize_t size, if (maxchr <= 255) { memcpy(PyUnicode_1BYTE_DATA(u), s, pos); s += pos; - size -= pos; writer.pos = pos; } @@ -5457,7 +5456,6 @@ unicode_decode_utf8_writer(_PyUnicodeWriter *writer, return 0; } s += decoded; - size -= decoded; } return unicode_decode_utf8_impl(writer, starts, s, end, From 3416e7c8dc004773d814b6f9ec9562434ed961cd Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 27 Oct 2025 10:09:22 +0100 Subject: [PATCH 2/4] gh-140633: AppleFrameworkLoader: Ignore AttributeError when setting __file__ (GH-140635) --- Lib/importlib/_bootstrap_external.py | 8 +++++++- .../2025-10-26-16-24-12.gh-issue-140633.ioayC1.rst | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2025-10-26-16-24-12.gh-issue-140633.ioayC1.rst diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 9269bb77806c83..a1319c0f6a91aa 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -1506,7 +1506,13 @@ def create_module(self, spec): ) # Ensure that the __file__ points at the .fwork location - module.__file__ = path + try: + module.__file__ = path + except AttributeError: + # Not important enough to report. + # (The error is also ignored in _bootstrap._init_module_attrs or + # import_run_extension in import.c) + pass return module diff --git a/Misc/NEWS.d/next/Library/2025-10-26-16-24-12.gh-issue-140633.ioayC1.rst b/Misc/NEWS.d/next/Library/2025-10-26-16-24-12.gh-issue-140633.ioayC1.rst new file mode 100644 index 00000000000000..9675a5d427a0d9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-10-26-16-24-12.gh-issue-140633.ioayC1.rst @@ -0,0 +1,2 @@ +Ignore :exc:`AttributeError` when setting a module's ``__file__`` attribute +when loading an extension module packaged as Apple Framework. From d12086e8228323cc2e31d263f1aeb8190bd1c1d9 Mon Sep 17 00:00:00 2001 From: RayXu <140802139+F18-Maverick@users.noreply.github.com> Date: Mon, 27 Oct 2025 17:43:24 +0800 Subject: [PATCH 3/4] Docs: Replace "encoder" with "decoder" in `Doc/c-api/codec.rst` (#140613) --- Doc/c-api/codec.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/c-api/codec.rst b/Doc/c-api/codec.rst index 9876060dd74ac4..08a99245ad6528 100644 --- a/Doc/c-api/codec.rst +++ b/Doc/c-api/codec.rst @@ -39,7 +39,7 @@ Codec registry and support functions *object* is passed through the decoder function found for the given *encoding* using the error handling method defined by *errors*. *errors* may be ``NULL`` to use the default method defined for the codec. Raises a - :exc:`LookupError` if no encoder can be found. + :exc:`LookupError` if no decoder can be found. Codec lookup API From 18e4a89e42c681fe035d4d39a71e79d3c6b70903 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 27 Oct 2025 11:39:42 +0100 Subject: [PATCH 4/4] gh-134160: Add more comments for the xxlimited module (GH-140214) --- Modules/xxlimited.c | 60 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 7 deletions(-) diff --git a/Modules/xxlimited.c b/Modules/xxlimited.c index 0480fb0849876b..09c8d9487f5426 100644 --- a/Modules/xxlimited.c +++ b/Modules/xxlimited.c @@ -14,7 +14,9 @@ This module roughly corresponds to:: class Xxo: - """A class that explicitly stores attributes in an internal dict""" + """A class that explicitly stores attributes in an internal dict + (to simulate custom attribute handling). + """ def __init__(self): # In the C class, "_x_attr" is not accessible from Python code @@ -85,13 +87,16 @@ typedef struct { // Instance state typedef struct { PyObject_HEAD - PyObject *x_attr; /* Attributes dictionary */ + PyObject *x_attr; /* Attributes dictionary. + * May be NULL, which acts as an + * empty dict. + */ char x_buffer[BUFSIZE]; /* buffer for Py_buffer */ Py_ssize_t x_exports; /* how many buffer are exported */ } XxoObject; #define XxoObject_CAST(op) ((XxoObject *)(op)) -// XXX: no good way to do this yet +// TODO: full support for type-checking was added in 3.14 (Py_tp_token) // #define XxoObject_Check(v) Py_IS_TYPE(v, Xxo_Type) static XxoObject * @@ -112,8 +117,13 @@ newXxoObject(PyObject *module) return self; } -/* Xxo finalization */ +/* Xxo finalization. + * + * Types that store references to other PyObjects generally need to implement + * the GC slots: traverse, clear, dealloc, and (optionally) finalize. + */ +// traverse: Visit all references from an object, including its type static int Xxo_traverse(PyObject *op, visitproc visit, void *arg) { @@ -126,6 +136,7 @@ Xxo_traverse(PyObject *op, visitproc visit, void *arg) return 0; } +// clear: drop references in order to break all reference cycles static int Xxo_clear(PyObject *op) { @@ -134,6 +145,8 @@ Xxo_clear(PyObject *op) return 0; } +// finalize: like clear, but should leave the object in a consistent state. +// Equivalent to `__del__` in Python. static void Xxo_finalize(PyObject *op) { @@ -141,6 +154,7 @@ Xxo_finalize(PyObject *op) Py_CLEAR(self->x_attr); } +// dealloc: drop all remaining references and free memory static void Xxo_dealloc(PyObject *self) { @@ -155,6 +169,7 @@ Xxo_dealloc(PyObject *self) /* Xxo attribute handling */ +// Get an attribute. static PyObject * Xxo_getattro(PyObject *op, PyObject *name) { @@ -168,9 +183,12 @@ Xxo_getattro(PyObject *op, PyObject *name) return NULL; } } + // Fall back to generic implementation (this handles special attributes, + // raising AttributeError, etc.) return PyObject_GenericGetAttr(op, name); } +// Set or delete an attribute. static int Xxo_setattro(PyObject *op, PyObject *name, PyObject *v) { @@ -198,7 +216,9 @@ Xxo_setattro(PyObject *op, PyObject *name, PyObject *v) } } -/* Xxo methods */ +/* Xxo methods: C functions plus a PyMethodDef array that lists them and + * specifies metadata. + */ static PyObject * Xxo_demo(PyObject *op, PyTypeObject *defining_class, @@ -234,7 +254,10 @@ static PyMethodDef Xxo_methods[] = { {NULL, NULL} /* sentinel */ }; -/* Xxo buffer interface */ +/* Xxo buffer interface: C functions later referenced from PyType_Slot array. + * Other interfaces (e.g. for sequence-like or number-like types) are defined + * similarly. + */ static int Xxo_getbuffer(PyObject *op, Py_buffer *view, int flags) @@ -300,6 +323,7 @@ static PyType_Spec Xxo_Type_spec = { /* Str type definition*/ static PyType_Slot Str_Type_slots[] = { + // slots array intentionally kept empty {0, 0}, /* sentinel */ }; @@ -400,12 +424,32 @@ xx_modexec(PyObject *m) } static PyModuleDef_Slot xx_slots[] = { + + /* exec function to initialize the module (called as part of import + * after the object was added to sys.modules) + */ {Py_mod_exec, xx_modexec}, + + /* Signal that this module supports being loaded in multiple interpreters + * with separate GILs (global interpreter locks). + * See "Isolating Extension Modules" on how to prepare a module for this: + * https://docs.python.org/3/howto/isolating-extensions.html + */ {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + + /* Signal that this module does not rely on the GIL for its own needs. + * Without this slot, free-threaded builds of CPython will enable + * the GIL when this module is loaded. + */ {Py_mod_gil, Py_MOD_GIL_NOT_USED}, + {0, NULL} }; +// Module finalization: modules that hold references in their module state +// need to implement the fullowing GC hooks. They're similar to the ones for +// types (see "Xxo finalization"). + static int xx_traverse(PyObject *module, visitproc visit, void *arg) { @@ -444,7 +488,9 @@ static struct PyModuleDef xxmodule = { }; -/* Export function for the module (*must* be called PyInit_xx) */ +/* Export function for the module. *Must* be called PyInit_xx; usually it is + * the only non-`static` object in a module definition. + */ PyMODINIT_FUNC PyInit_xxlimited(void)