From 00b8a559907f6abf4e462aebf82756360d1e31ff Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Tue, 20 Oct 2026 12:45:56 -0400 Subject: [PATCH 01/13] Document the remaining parts of the public C API! --- Doc/c-api/code.rst | 10 ++ Doc/c-api/conversion.rst | 39 ++++++++ Doc/c-api/dict.rst | 8 ++ Doc/c-api/exceptions.rst | 5 + Doc/c-api/file.rst | 8 ++ Doc/c-api/function.rst | 8 ++ Doc/c-api/hash.rst | 15 +++ Doc/c-api/intro.rst | 5 + Doc/c-api/long.rst | 14 +++ Doc/c-api/monitoring.rst | 72 ++++++++++----- Doc/c-api/profiling.rst | 11 +++ Doc/c-api/pyexpat.rst | 112 +++++++++++++++++++++++ Doc/c-api/structures.rst | 28 ++++++ Doc/c-api/synchronization.rst | 14 +++ Doc/c-api/utilities.rst | 1 + Doc/c-api/veryhigh.rst | 17 ++++ Doc/c-api/weakref.rst | 9 ++ Tools/check-c-api-docs/ignored_c_api.txt | 64 ------------- 18 files changed, 354 insertions(+), 86 deletions(-) create mode 100644 Doc/c-api/pyexpat.rst diff --git a/Doc/c-api/code.rst b/Doc/c-api/code.rst index 57b77f92a7d2e6a..6ab0e20c422aa7f 100644 --- a/Doc/c-api/code.rst +++ b/Doc/c-api/code.rst @@ -176,6 +176,16 @@ bound into a function. .. versionadded:: 3.12 +.. c:macro:: PY_FOREACH_CODE_EVENT(V) + + Expand to ``V(CREATE) V(DESTROY)``. The argument *V* must be a macro + accepting one event name, which is the suffix of a :c:type:`PyCodeEvent` + constant. It must supply any punctuation needed between expansions. + + The headers use ``PY_DEF_EVENT`` as a temporary helper macro to define + watcher event enumerations. It is undefined afterwards and is not available + to applications. + .. c:type:: int (*PyCode_WatchCallback)(PyCodeEvent event, PyCodeObject* co) Type of a code object watcher callback function. diff --git a/Doc/c-api/conversion.rst b/Doc/c-api/conversion.rst index f7c8ef8b22b9556..9913cba5b5ec982 100644 --- a/Doc/c-api/conversion.rst +++ b/Doc/c-api/conversion.rst @@ -258,3 +258,42 @@ The argument must be a signed or unsigned :c:expr:`char`. .. c:macro:: Py_TOUPPER(c) Return the uppercase equivalent of the character *c*. + + +Bit masks +--------- + +The following constants are bit masks used by the character classification +macros above: + +.. c:macro:: PY_CTF_ALNUM + + Mask for ASCII letters and decimal digits, used by :c:macro:`Py_ISALNUM`. + Equal to ``PY_CTF_ALPHA | PY_CTF_DIGIT``. + +.. c:macro:: PY_CTF_ALPHA + + Mask for ASCII letters, used by :c:macro:`Py_ISALPHA`. + Equal to ``PY_CTF_LOWER | PY_CTF_UPPER``. + +.. c:macro:: PY_CTF_DIGIT + + Mask for decimal digits (``0-9``), used by :c:macro:`Py_ISDIGIT`. + +.. c:macro:: PY_CTF_LOWER + + Mask for lowercase ASCII letters (``a-z``), used by :c:macro:`Py_ISLOWER`. + +.. c:macro:: PY_CTF_SPACE + + Mask for ASCII whitespace characters, used by :c:macro:`Py_ISSPACE`. + +.. c:macro:: PY_CTF_UPPER + + Mask for uppercase ASCII letters (``A-Z``), used by :c:macro:`Py_ISUPPER`. + +.. c:macro:: PY_CTF_XDIGIT + + Mask for hexadecimal digits (``0-9``, ``a-f``, and ``A-F``), used by + :c:macro:`Py_ISXDIGIT`. + diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst index 87d09ad2412e405..2aca1672a950c6e 100644 --- a/Doc/c-api/dict.rst +++ b/Doc/c-api/dict.rst @@ -563,6 +563,14 @@ Dictionary objects .. versionadded:: 3.12 +.. c:macro:: PY_FOREACH_DICT_EVENT(V) + + Apply the macro *V* to each of ``ADDED``, ``MODIFIED``, ``DELETED``, + ``CLONED``, ``CLEARED``, and ``DEALLOCATED``, in that order. These names + are the suffixes of :c:type:`PyDict_WatchEvent` constants. The macro *V* + must accept one event name and supply any punctuation needed between + expansions. + .. c:type:: int (*PyDict_WatchCallback)(PyDict_WatchEvent event, PyObject *dict, PyObject *key, PyObject *new_value) Type of a dict watcher callback function. diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index 0c8d14dc134ebc1..4b00bc84f59718b 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -407,6 +407,11 @@ an error value). documentation. There is no C API for warning control. +.. c:function:: int PyErr_Warn(PyObject *category, const char *message) + + Equivalent to ``PyErr_WarnEx(category, message, 1)``. + + .. c:function:: int PyErr_WarnExplicitObject(PyObject *category, PyObject *message, PyObject *filename, int lineno, PyObject *module, PyObject *registry) Issue a warning message with explicit control over all warning attributes. This diff --git a/Doc/c-api/file.rst b/Doc/c-api/file.rst index 45f2d1a6f53c697..26f846b06fc4ee9 100644 --- a/Doc/c-api/file.rst +++ b/Doc/c-api/file.rst @@ -159,6 +159,14 @@ the :mod:`io` APIs instead. failure; the appropriate exception will be set. +.. c:macro:: PY_STDIOTEXTMODE + + String literal ``"b"``, which can be appended to a C standard I/O mode + string, such as ``"r" PY_STDIOTEXTMODE``, to open a file in binary mode. + This prevents the C library from translating newlines, so that Python can + perform its own newline translation. + + Soft-deprecated API ^^^^^^^^^^^^^^^^^^^ diff --git a/Doc/c-api/function.rst b/Doc/c-api/function.rst index 75a4adc810f90aa..38371e9bf04e03b 100644 --- a/Doc/c-api/function.rst +++ b/Doc/c-api/function.rst @@ -197,6 +197,14 @@ There are a few functions specific to Python functions. .. versionadded:: 3.15 +.. c:macro:: PY_FOREACH_FUNC_EVENT(V) + + Apply the macro *V* to each of ``CREATE``, ``DESTROY``, ``MODIFY_CODE``, + ``MODIFY_DEFAULTS``, ``MODIFY_KWDEFAULTS``, and ``MODIFY_QUALNAME``, in that + order. These names are the suffixes of :c:type:`PyFunction_WatchEvent` + constants. The macro *V* must accept one event name and supply any + punctuation needed between expansions. + .. c:type:: int (*PyFunction_WatchCallback)(PyFunction_WatchEvent event, PyFunctionObject *func, PyObject *new_value) Type of a function watcher callback function. diff --git a/Doc/c-api/hash.rst b/Doc/c-api/hash.rst index 1ad712b0ce4f2b1..9f07c86029966bc 100644 --- a/Doc/c-api/hash.rst +++ b/Doc/c-api/hash.rst @@ -44,6 +44,21 @@ See also the :c:member:`PyTypeObject.tp_hash` member and :ref:`numeric-hash`. Add :c:macro:`!Py_HASH_SIPHASH13`. +.. c:macro:: Py_HASH_EXTERNAL + + Value of :c:macro:`Py_HASH_ALGORITHM` for a hash implementation supplied + by the application embedding Python. Its value is ``0``. + + When Python is built with this setting, the application must define a + :c:type:`PyHash_FuncDef` variable named ``PyHash_Func`` instead of using + one of Python's built-in hash algorithms. + + .. versionadded:: 3.4 + + .. deprecated-removed:: 3.15 3.19 + Use one of the built-in hash algorithms instead. + + .. c:macro:: Py_HASH_CUTOFF Buffers of length in range ``[1, Py_HASH_CUTOFF)`` are hashed using DJBX33A diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst index 258135a234cc50d..2b155e96b3c8094 100644 --- a/Doc/c-api/intro.rst +++ b/Doc/c-api/intro.rst @@ -306,6 +306,11 @@ Numeric utilities for. Exactly one of them is ``1`` and the other is ``0``. +.. c:macro:: PY_DWORD_MAX + + The maximum value of the Windows ``DWORD`` type. + + Assertion utilities ^^^^^^^^^^^^^^^^^^^ diff --git a/Doc/c-api/long.rst b/Doc/c-api/long.rst index 874e422d4701dd8..452e86fca22ba80 100644 --- a/Doc/c-api/long.rst +++ b/Doc/c-api/long.rst @@ -680,6 +680,20 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. .. versionadded:: 3.12 +Build configuration +^^^^^^^^^^^^^^^^^^^ + +.. c:macro:: PYLONG_BITS_IN_DIGIT + + The number of bits in each digit of CPython's internal representation of + integers. The value is either ``30`` (the default) or ``15``, selected when + building Python with :option:`--enable-big-digits`. + + To access the native representation of integers, use + :c:func:`PyLong_GetNativeLayout` and its + :c:member:`~PyLongLayout.bits_per_digit` member instead. + + Export API ^^^^^^^^^^ diff --git a/Doc/c-api/monitoring.rst b/Doc/c-api/monitoring.rst index 4bfcb86abf58ed1..e0fa772309a2888 100644 --- a/Doc/c-api/monitoring.rst +++ b/Doc/c-api/monitoring.rst @@ -170,28 +170,56 @@ would typically correspond to a Python function. .. The table is here to make the docs searchable, and to allow automatic links to the identifiers. - ================================================== ===================================== - Macro Event - ================================================== ===================================== - .. c:macro:: PY_MONITORING_EVENT_BRANCH_LEFT :monitoring-event:`BRANCH_LEFT` - .. c:macro:: PY_MONITORING_EVENT_BRANCH_RIGHT :monitoring-event:`BRANCH_RIGHT` - .. c:macro:: PY_MONITORING_EVENT_CALL :monitoring-event:`CALL` - .. c:macro:: PY_MONITORING_EVENT_C_RAISE :monitoring-event:`C_RAISE` - .. c:macro:: PY_MONITORING_EVENT_C_RETURN :monitoring-event:`C_RETURN` - .. c:macro:: PY_MONITORING_EVENT_EXCEPTION_HANDLED :monitoring-event:`EXCEPTION_HANDLED` - .. c:macro:: PY_MONITORING_EVENT_INSTRUCTION :monitoring-event:`INSTRUCTION` - .. c:macro:: PY_MONITORING_EVENT_JUMP :monitoring-event:`JUMP` - .. c:macro:: PY_MONITORING_EVENT_LINE :monitoring-event:`LINE` - .. c:macro:: PY_MONITORING_EVENT_PY_RESUME :monitoring-event:`PY_RESUME` - .. c:macro:: PY_MONITORING_EVENT_PY_RETURN :monitoring-event:`PY_RETURN` - .. c:macro:: PY_MONITORING_EVENT_PY_START :monitoring-event:`PY_START` - .. c:macro:: PY_MONITORING_EVENT_PY_THROW :monitoring-event:`PY_THROW` - .. c:macro:: PY_MONITORING_EVENT_PY_UNWIND :monitoring-event:`PY_UNWIND` - .. c:macro:: PY_MONITORING_EVENT_PY_YIELD :monitoring-event:`PY_YIELD` - .. c:macro:: PY_MONITORING_EVENT_RAISE :monitoring-event:`RAISE` - .. c:macro:: PY_MONITORING_EVENT_RERAISE :monitoring-event:`RERAISE` - .. c:macro:: PY_MONITORING_EVENT_STOP_ITERATION :monitoring-event:`STOP_ITERATION` - ================================================== ===================================== + .. list-table:: + :header-rows: 1 + :widths: 50 37 + + * - Macro + - Event + * - .. c:macro:: PY_MONITORING_EVENT_BRANCH_LEFT + - :monitoring-event:`BRANCH_LEFT` + * - .. c:macro:: PY_MONITORING_EVENT_BRANCH_RIGHT + - :monitoring-event:`BRANCH_RIGHT` + * - .. c:macro:: PY_MONITORING_EVENT_CALL + - :monitoring-event:`CALL` + * - .. c:macro:: PY_MONITORING_EVENT_C_RAISE + - :monitoring-event:`C_RAISE` + * - .. c:macro:: PY_MONITORING_EVENT_C_RETURN + - :monitoring-event:`C_RETURN` + * - .. c:macro:: PY_MONITORING_EVENT_EXCEPTION_HANDLED + - :monitoring-event:`EXCEPTION_HANDLED` + * - .. c:macro:: PY_MONITORING_EVENT_INSTRUCTION + - :monitoring-event:`INSTRUCTION` + * - .. c:macro:: PY_MONITORING_EVENT_JUMP + - :monitoring-event:`JUMP` + * - .. c:macro:: PY_MONITORING_EVENT_LINE + - :monitoring-event:`LINE` + * - .. c:macro:: PY_MONITORING_EVENT_PY_RESUME + - :monitoring-event:`PY_RESUME` + * - .. c:macro:: PY_MONITORING_EVENT_PY_RETURN + - :monitoring-event:`PY_RETURN` + * - .. c:macro:: PY_MONITORING_EVENT_PY_START + - :monitoring-event:`PY_START` + * - .. c:macro:: PY_MONITORING_EVENT_PY_THROW + - :monitoring-event:`PY_THROW` + * - .. c:macro:: PY_MONITORING_EVENT_PY_UNWIND + - :monitoring-event:`PY_UNWIND` + * - .. c:macro:: PY_MONITORING_EVENT_PY_YIELD + - :monitoring-event:`PY_YIELD` + * - .. c:macro:: PY_MONITORING_EVENT_RAISE + - :monitoring-event:`RAISE` + * - .. c:macro:: PY_MONITORING_EVENT_RERAISE + - :monitoring-event:`RERAISE` + * - .. c:macro:: PY_MONITORING_EVENT_STOP_ITERATION + - :monitoring-event:`STOP_ITERATION` + * - .. c:macro:: PY_MONITORING_EVENT_BRANCH + + .. deprecated:: 3.14 + Use :c:macro:`PY_MONITORING_EVENT_BRANCH_LEFT` + and :c:macro:`PY_MONITORING_EVENT_BRANCH_RIGHT` instead. + + - :monitoring-event:`BRANCH_LEFT` and :monitoring-event:`BRANCH_RIGHT` + .. c:function:: int PyMonitoring_ExitScope(void) diff --git a/Doc/c-api/profiling.rst b/Doc/c-api/profiling.rst index 0200f2eac6d9086..aefe9cfda28efd8 100644 --- a/Doc/c-api/profiling.rst +++ b/Doc/c-api/profiling.rst @@ -237,3 +237,14 @@ Reference tracing There must be an :term:`attached thread state` when calling this function. .. versionadded:: 3.13 + + +Performance statistics +====================== + +.. c:macro:: PYSTATS_MAX_UOP_ID + + Largest micro-operation identifier for which CPython allocates performance + statistics counters. Available only in builds configured with + :option:`--enable-pystats`. + diff --git a/Doc/c-api/pyexpat.rst b/Doc/c-api/pyexpat.rst new file mode 100644 index 000000000000000..936dfb11b7b2862 --- /dev/null +++ b/Doc/c-api/pyexpat.rst @@ -0,0 +1,112 @@ +.. highlight:: c + +Expat C API +=========== + +The :mod:`pyexpat` module exposes selected Expat functions through its +``expat_CAPI`` capsule. This allows extension modules to use the same Expat +library as Python. The interface is declared in :file:`pyexpat.h`, which must +be included after Expat's :file:`expat.h` header. It is not part of the +:ref:`Limited API `. + +.. c:macro:: PyExpat_CAPSULE_NAME + + The name of the capsule containing the Expat C API: + ``"pyexpat.expat_CAPI"``. Pass this to :c:func:`PyCapsule_Import` to obtain + a pointer to a :c:struct:`PyExpat_CAPI`. + + +.. c:macro:: PyExpat_CAPI_MAGIC + + The string identifying the layout of :c:struct:`PyExpat_CAPI`. + Before using the function pointers in the structure, check that + its ``magic`` member matches this string, its ``size`` member is + at least :c:expr:`sizeof(struct PyExpat_CAPI)`, and its + :c:member:`PyExpat_CAPI.MAJOR_VERSION`, :c:member:`PyExpat_CAPI.MINOR_VERSION`, + and :c:member:`PyExpat_CAPI.MICRO_VERSION` members match the Expat + version used to build the extension. + + +.. c:struct:: PyExpat_CAPI + + Table of function pointers exported by :mod:`pyexpat`. The capsule owns + this structure: treat it as read-only and do not free it. Keep a strong + reference to the capsule while using the table. + + Check the compatibility fields as described under + :c:macro:`PyExpat_CAPI_MAGIC` before using the function pointers. + + .. c:member:: char *magic + + Interface identifier, set to :c:macro:`PyExpat_CAPI_MAGIC`. + + .. c:member:: int size + + Size of the structure in bytes, set to ``sizeof(struct PyExpat_CAPI)`` + by the :mod:`pyexpat` module that created the capsule. + + .. c:member:: int MAJOR_VERSION + int MINOR_VERSION + int MICRO_VERSION + + Major, minor, and micro version numbers of the Expat library used by + :mod:`pyexpat`. + + .. c:member:: const XML_LChar *(*ErrorString)(enum XML_Error code) + enum XML_Error (*GetErrorCode)(XML_Parser parser) + XML_Size (*GetErrorColumnNumber)(XML_Parser parser) + XML_Size (*GetErrorLineNumber)(XML_Parser parser) + enum XML_Status (*Parse)(XML_Parser parser, const char *s, int len, int isFinal) + XML_Parser (*ParserCreate_MM)(const XML_Char *encoding, const XML_Memory_Handling_Suite *memsuite, const XML_Char *namespaceSeparator) + void (*ParserFree)(XML_Parser parser) + void (*SetCharacterDataHandler)(XML_Parser parser, XML_CharacterDataHandler handler) + void (*SetCommentHandler)(XML_Parser parser, XML_CommentHandler handler) + void (*SetDefaultHandlerExpand)(XML_Parser parser, XML_DefaultHandler handler) + void (*SetElementHandler)(XML_Parser parser, XML_StartElementHandler start, XML_EndElementHandler end) + void (*SetNamespaceDeclHandler)(XML_Parser parser, XML_StartNamespaceDeclHandler start, XML_EndNamespaceDeclHandler end) + void (*SetProcessingInstructionHandler)(XML_Parser parser, XML_ProcessingInstructionHandler handler) + void (*SetUnknownEncodingHandler)(XML_Parser parser, XML_UnknownEncodingHandler handler, void *encodingHandlerData) + void (*SetUserData)(XML_Parser parser, void *userData) + void (*SetStartDoctypeDeclHandler)(XML_Parser parser, XML_StartDoctypeDeclHandler start) + enum XML_Status (*SetEncoding)(XML_Parser parser, const XML_Char *encoding) + + Pointers to the corresponding Expat functions. The function names are + the member names prefixed with ``XML_``; for example, ``Parse`` points + to ``XML_Parse``. See the `Expat API reference + `_ for their behavior. + + .. c:member:: int (*DefaultUnknownEncodingHandler)(void *encodingHandlerData, const XML_Char *name, XML_Encoding *info) + + Python's unknown-encoding handler for Expat. It uses Python's codec + registry to fill *info* for the encoding *name*. The + *encodingHandlerData* argument is unused and may be ``NULL``. + + Return ``XML_STATUS_OK`` on success or ``XML_STATUS_ERROR`` on failure. + A Python exception may be set on failure. Calling this callback + requires an :term:`attached thread state`. + + The remaining members also point to Expat functions with the ``XML_`` + prefix. They may be ``NULL``, depending on the Expat version used by + :mod:`pyexpat`: + + .. c:member:: int (*SetHashSalt)(XML_Parser parser, unsigned long hash_salt) + + ``NULL`` with Expat versions older than 2.1.0. + + .. c:member:: XML_Bool (*SetReparseDeferralEnabled)(XML_Parser parser, XML_Bool enabled) + + ``NULL`` with Expat versions older than 2.6.0. + + .. c:member:: XML_Bool (*SetAllocTrackerActivationThreshold)(XML_Parser parser, unsigned long long activationThresholdBytes) + XML_Bool (*SetAllocTrackerMaximumAmplification)(XML_Parser parser, float maxAmplificationFactor) + + ``NULL`` with Expat versions older than 2.7.2. + + .. c:member:: XML_Bool (*SetBillionLaughsAttackProtectionActivationThreshold)(XML_Parser parser, unsigned long long activationThresholdBytes) + XML_Bool (*SetBillionLaughsAttackProtectionMaximumAmplification)(XML_Parser parser, float maxAmplificationFactor) + + ``NULL`` with Expat versions older than 2.4.0. + + .. c:member:: XML_Bool (*SetHashSalt16Bytes)(XML_Parser parser, const uint8_t entropy[16]) + + ``NULL`` with Expat versions older than 2.8.0. diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst index f281f2e8328beac..ab9ef4ae16089f3 100644 --- a/Doc/c-api/structures.rst +++ b/Doc/c-api/structures.rst @@ -221,6 +221,12 @@ under :ref:`reference counting `. .. versionadded:: 3.9 +.. c:macro:: Py_INVALID_SIZE + + A constant of type :c:type:`Py_ssize_t` with value ``-1``, representing an + invalid size. + + .. c:macro:: PyObject_HEAD_INIT(type) This is a macro which expands to initialization values for a new @@ -610,6 +616,18 @@ definition with the same method name. type checking. +.. c:function:: PyTypeObject *PyCFunction_GET_CLASS(PyObject *func) + + Return a :term:`borrowed reference` to the defining class of *func* if + its :c:member:`~PyMethodDef.ml_flags` includes :c:macro:`METH_METHOD`. + Otherwise, return ``NULL`` without setting an exception. + + *func* must be a C function object and must not be ``NULL``. + This function does not perform error or type checking. + + .. versionadded:: 3.9 + + Accessing attributes of extension types --------------------------------------- @@ -774,6 +792,16 @@ The following flags can be used with :c:member:`PyMemberDef.flags`: .. soft-deprecated:: 3.12 Use :c:macro:`Py_AUDIT_READ` instead. + +.. c:macro:: PY_WRITE_RESTRICTED + + A member flag that has no effect, retained solely for backwards compatibility. + This is only available with ``#include "structmember.h"``. + + .. soft-deprecated:: 3.0 + Omit this flag instead. + + .. _PyMemberDef-types: Member types diff --git a/Doc/c-api/synchronization.rst b/Doc/c-api/synchronization.rst index 6f18c047a24a92f..750a073314cd61a 100644 --- a/Doc/c-api/synchronization.rst +++ b/Doc/c-api/synchronization.rst @@ -264,6 +264,20 @@ These APIs are obsolete since Python 3.13 with the introduction of A pointer to a mutual exclusion lock. +.. c:macro:: PY_TIMEOUT_T + + A :term:`soft deprecated` alias to :c:expr:`long long`, the integer + type used for the timeout argument of :c:func:`PyThread_acquire_lock_timed`. + + +.. c:var:: const long long PY_TIMEOUT_MAX + + The maximum timeout, in microseconds, supported by the legacy locking APIs. + + .. note:: + This differs from :data:`_thread.TIMEOUT_MAX`, which is expressed in seconds. + + .. c:type:: PyLockStatus The result of acquiring a lock with a timeout. diff --git a/Doc/c-api/utilities.rst b/Doc/c-api/utilities.rst index 9d0abf440f791d4..d3563ed990d7c26 100644 --- a/Doc/c-api/utilities.rst +++ b/Doc/c-api/utilities.rst @@ -22,3 +22,4 @@ and parsing function arguments and constructing Python values from C values. codec.rst time.rst perfmaps.rst + pyexpat.rst diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst index bba5c7f8ecf7751..93d902d6a2a6993 100644 --- a/Doc/c-api/veryhigh.rst +++ b/Doc/c-api/veryhigh.rst @@ -156,6 +156,23 @@ the same library that the Python runtime is using. :ref:`main interpreter `. +.. c:function:: char *PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) + + Display *prompt*, if it is not ``NULL``, and read a line from *sys_stdin*. + The returned string is null-terminated and includes the trailing newline, + if one was read. This returns an empty string if the end of the file is reached + before any characters are read. This will return ``NULL`` with an exception set + on failure or interruption. + + By default, *sys_stdout* is flushed and *prompt* is written to the C + standard error stream. If both streams are terminals and the call is made + from the :ref:`main interpreter `, + :c:var:`PyOS_ReadlineFunctionPointer` can override this behavior. + + The caller must free the returned string with :c:func:`PyMem_Free`. + The caller must hold an :term:`attached thread state`. + + .. c:var:: char* (*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, const char *) Can be set to point to a function with the prototype diff --git a/Doc/c-api/weakref.rst b/Doc/c-api/weakref.rst index f41a58e8e3cd696..51f2dda6f57a844 100644 --- a/Doc/c-api/weakref.rst +++ b/Doc/c-api/weakref.rst @@ -106,6 +106,15 @@ as much as it can. been attempted. +.. c:function:: PyObject **PyObject_GET_WEAKREFS_LISTPTR(PyObject *object) + + Return a pointer to the head of the list of weak references to *object*. + *object* must support weak references and must not be ``NULL``. + + The returned pointer can be dereferenced to obtain the current head of + the list. Do not use it to modify the list or its head. + + .. c:function:: void PyUnstable_Object_ClearWeakRefsNoCallbacks(PyObject *object) Clears the weakrefs for *object* without calling the callbacks. diff --git a/Tools/check-c-api-docs/ignored_c_api.txt b/Tools/check-c-api-docs/ignored_c_api.txt index 754b8959b2e5d5d..1328eaa4a52ad8a 100644 --- a/Tools/check-c-api-docs/ignored_c_api.txt +++ b/Tools/check-c-api-docs/ignored_c_api.txt @@ -1,70 +1,6 @@ -# pydtrace_probes.h -PyDTrace_AUDIT -PyDTrace_FUNCTION_ENTRY -PyDTrace_FUNCTION_RETURN -PyDTrace_GC_DONE -PyDTrace_GC_START -PyDTrace_IMPORT_FIND_LOAD_DONE -PyDTrace_IMPORT_FIND_LOAD_START -PyDTrace_INSTANCE_DELETE_DONE -PyDTrace_INSTANCE_DELETE_START -PyDTrace_INSTANCE_NEW_DONE -PyDTrace_INSTANCE_NEW_START -PyDTrace_LINE -# fileobject.h -Py_FileSystemDefaultEncodeErrors -Py_FileSystemDefaultEncoding -Py_HasFileSystemDefaultEncoding -Py_UTF8Mode -# pyhash.h -Py_HASH_EXTERNAL -# object.h -Py_INVALID_SIZE -# pyexpat.h -PyExpat_CAPI_MAGIC -PyExpat_CAPSULE_NAME -# pyport.h -PYLONG_BITS_IN_DIGIT -PY_DWORD_MAX -# cpython/methodobject.h -PyCFunction_GET_CLASS # cpython/descrobject.h PyDescr_NAME PyDescr_TYPE PyWrapperFlag_KEYWORDS # cpython/pylifecycle.h Py_FrozenMain -# cpython/objimpl.h -PyObject_GET_WEAKREFS_LISTPTR -# cpython/pythonrun.h -PyOS_Readline -# cpython/warnings.h -PyErr_Warn -# fileobject.h -PY_STDIOTEXTMODE -# structmember.h -PY_WRITE_RESTRICTED -# pythread.h -PY_TIMEOUT_T -PY_TIMEOUT_MAX -# cpython/pyctype.h -PY_CTF_ALNUM -PY_CTF_ALPHA -PY_CTF_DIGIT -PY_CTF_LOWER -PY_CTF_SPACE -PY_CTF_UPPER -PY_CTF_XDIGIT -# cpython/code.h -PY_DEF_EVENT -PY_FOREACH_CODE_EVENT -# cpython/funcobject.h -PY_DEF_EVENT -PY_FOREACH_FUNC_EVENT -# cpython/monitoring.h -PY_MONITORING_EVENT_BRANCH -# cpython/dictobject.h -PY_DEF_EVENT -PY_FOREACH_DICT_EVENT -# cpython/pystats.h -PYSTATS_MAX_UOP_ID From 5046d1af5ca1e11b2ad8dda3e04219fd5ab551b6 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Tue, 20 Oct 2026 12:47:42 -0400 Subject: [PATCH 02/13] Use :c:expr: --- Doc/c-api/exceptions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index 4b00bc84f59718b..7f4e1ecc2aba26d 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -409,7 +409,7 @@ an error value). .. c:function:: int PyErr_Warn(PyObject *category, const char *message) - Equivalent to ``PyErr_WarnEx(category, message, 1)``. + Equivalent to :c:expr:`PyErr_WarnEx(category, message, 1)`. .. c:function:: int PyErr_WarnExplicitObject(PyObject *category, PyObject *message, PyObject *filename, int lineno, PyObject *module, PyObject *registry) From 14a70d46bbf38b298c2ec605ae94501598994fc4 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Tue, 20 Oct 2026 13:19:13 -0400 Subject: [PATCH 03/13] Fix stupid warnings. --- Doc/c-api/pyexpat.rst | 20 ++++++++++---------- Doc/conf.py | 22 +++++++++++++++++++++- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/Doc/c-api/pyexpat.rst b/Doc/c-api/pyexpat.rst index 936dfb11b7b2862..30f5ed307206eef 100644 --- a/Doc/c-api/pyexpat.rst +++ b/Doc/c-api/pyexpat.rst @@ -3,10 +3,10 @@ Expat C API =========== -The :mod:`pyexpat` module exposes selected Expat functions through its -``expat_CAPI`` capsule. This allows extension modules to use the same Expat -library as Python. The interface is declared in :file:`pyexpat.h`, which must -be included after Expat's :file:`expat.h` header. It is not part of the +The :mod:`pyexpat ` module exposes selected Expat functions +through its ``expat_CAPI`` capsule. This allows extension modules to use the +same Expat library as Python. The interface is declared in :file:`pyexpat.h`, +which must be included after Expat's :file:`expat.h` header. It is not part of the :ref:`Limited API `. .. c:macro:: PyExpat_CAPSULE_NAME @@ -29,9 +29,9 @@ be included after Expat's :file:`expat.h` header. It is not part of the .. c:struct:: PyExpat_CAPI - Table of function pointers exported by :mod:`pyexpat`. The capsule owns - this structure: treat it as read-only and do not free it. Keep a strong - reference to the capsule while using the table. + Table of function pointers exported by :mod:`pyexpat `. + The capsule owns this structure: treat it as read-only and do not free it. + Keep a strong reference to the capsule while using the table. Check the compatibility fields as described under :c:macro:`PyExpat_CAPI_MAGIC` before using the function pointers. @@ -43,14 +43,14 @@ be included after Expat's :file:`expat.h` header. It is not part of the .. c:member:: int size Size of the structure in bytes, set to ``sizeof(struct PyExpat_CAPI)`` - by the :mod:`pyexpat` module that created the capsule. + by the :mod:`pyexpat ` module that created the capsule. .. c:member:: int MAJOR_VERSION int MINOR_VERSION int MICRO_VERSION Major, minor, and micro version numbers of the Expat library used by - :mod:`pyexpat`. + :mod:`pyexpat `. .. c:member:: const XML_LChar *(*ErrorString)(enum XML_Error code) enum XML_Error (*GetErrorCode)(XML_Parser parser) @@ -87,7 +87,7 @@ be included after Expat's :file:`expat.h` header. It is not part of the The remaining members also point to Expat functions with the ``XML_`` prefix. They may be ``NULL``, depending on the Expat version used by - :mod:`pyexpat`: + :mod:`pyexpat `: .. c:member:: int (*SetHashSalt)(XML_Parser parser, unsigned long hash_salt) diff --git a/Doc/conf.py b/Doc/conf.py index 8791aba435f49ea..c16a2a926898710 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -180,6 +180,26 @@ ('c:type', 'unsigned __int64'), ('c:type', 'double'), ('c:type', '_Float16'), + # Expat types + ('c:type', 'XML_Bool'), + ('c:type', 'XML_Char'), + ('c:type', 'XML_CharacterDataHandler'), + ('c:type', 'XML_CommentHandler'), + ('c:type', 'XML_DefaultHandler'), + ('c:type', 'XML_Encoding'), + ('c:type', 'XML_EndElementHandler'), + ('c:type', 'XML_EndNamespaceDeclHandler'), + ('c:type', 'XML_Error'), + ('c:type', 'XML_LChar'), + ('c:type', 'XML_Memory_Handling_Suite'), + ('c:type', 'XML_Parser'), + ('c:type', 'XML_ProcessingInstructionHandler'), + ('c:type', 'XML_Size'), + ('c:type', 'XML_StartDoctypeDeclHandler'), + ('c:type', 'XML_StartElementHandler'), + ('c:type', 'XML_StartNamespaceDeclHandler'), + ('c:type', 'XML_Status'), + ('c:type', 'XML_UnknownEncodingHandler'), # Standard C structures ('c:struct', 'in6_addr'), ('c:struct', 'in_addr'), @@ -237,7 +257,7 @@ ('py:attr', '__wrapped__'), ] -# gh-106948: Copy standard C types declared in the "c:type" domain and C +# gh-106948: Copy C types declared in the "c:type" domain and C # structures declared in the "c:struct" domain to the "c:identifier" domain, # since "c:function" markup looks for types in the "c:identifier" domain. Use # list() to not iterate on items which are being added From 42c67df906abfb7e817abcb4c52a79256d8c1e3e Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Tue, 20 Oct 2026 14:20:49 -0400 Subject: [PATCH 04/13] Apply suggestion from @ZeroIntensity --- Doc/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/conf.py b/Doc/conf.py index c16a2a926898710..20971ec043bd1ab 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -257,7 +257,7 @@ ('py:attr', '__wrapped__'), ] -# gh-106948: Copy C types declared in the "c:type" domain and C +# gh-106948: Copy standard C types declared in the "c:type" domain and C # structures declared in the "c:struct" domain to the "c:identifier" domain, # since "c:function" markup looks for types in the "c:identifier" domain. Use # list() to not iterate on items which are being added From 93fce2f8d0e1160099e320142d110d9fe9283ef4 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Tue, 20 Oct 2026 18:07:32 -0400 Subject: [PATCH 05/13] Apply batched suggestions from code review Co-authored-by: Petr Viktorin --- Doc/c-api/code.rst | 12 +++++------ Doc/c-api/conversion.rst | 40 ++++++++++------------------------- Doc/c-api/file.rst | 8 +++---- Doc/c-api/intro.rst | 1 + Doc/c-api/long.rst | 5 ++++- Doc/c-api/pyexpat.rst | 22 ++++++++----------- Doc/c-api/structures.rst | 2 +- Doc/c-api/synchronization.rst | 4 +++- 8 files changed, 38 insertions(+), 56 deletions(-) diff --git a/Doc/c-api/code.rst b/Doc/c-api/code.rst index 6ab0e20c422aa7f..385a750c9f32b8b 100644 --- a/Doc/c-api/code.rst +++ b/Doc/c-api/code.rst @@ -178,13 +178,11 @@ bound into a function. .. c:macro:: PY_FOREACH_CODE_EVENT(V) - Expand to ``V(CREATE) V(DESTROY)``. The argument *V* must be a macro - accepting one event name, which is the suffix of a :c:type:`PyCodeEvent` - constant. It must supply any punctuation needed between expansions. - - The headers use ``PY_DEF_EVENT`` as a temporary helper macro to define - watcher event enumerations. It is undefined afterwards and is not available - to applications. + Apply the macro *V* to each suffix of :c:type:`PyCodeEvent` + constants. + Currently expands to ``V(CREATE) V(DESTROY)``. + The macro *V* must accept one event name and supply any punctuation + needed between expansions. .. c:type:: int (*PyCode_WatchCallback)(PyCodeEvent event, PyCodeObject* co) diff --git a/Doc/c-api/conversion.rst b/Doc/c-api/conversion.rst index 9913cba5b5ec982..74a6c8b648d9d1f 100644 --- a/Doc/c-api/conversion.rst +++ b/Doc/c-api/conversion.rst @@ -267,33 +267,15 @@ The following constants are bit masks used by the character classification macros above: .. c:macro:: PY_CTF_ALNUM - - Mask for ASCII letters and decimal digits, used by :c:macro:`Py_ISALNUM`. - Equal to ``PY_CTF_ALPHA | PY_CTF_DIGIT``. - -.. c:macro:: PY_CTF_ALPHA - - Mask for ASCII letters, used by :c:macro:`Py_ISALPHA`. - Equal to ``PY_CTF_LOWER | PY_CTF_UPPER``. - -.. c:macro:: PY_CTF_DIGIT - - Mask for decimal digits (``0-9``), used by :c:macro:`Py_ISDIGIT`. - -.. c:macro:: PY_CTF_LOWER - - Mask for lowercase ASCII letters (``a-z``), used by :c:macro:`Py_ISLOWER`. - -.. c:macro:: PY_CTF_SPACE - - Mask for ASCII whitespace characters, used by :c:macro:`Py_ISSPACE`. - -.. c:macro:: PY_CTF_UPPER - - Mask for uppercase ASCII letters (``A-Z``), used by :c:macro:`Py_ISUPPER`. - -.. c:macro:: PY_CTF_XDIGIT - - Mask for hexadecimal digits (``0-9``, ``a-f``, and ``A-F``), used by - :c:macro:`Py_ISXDIGIT`. + PY_CTF_ALPHA + PY_CTF_DIGIT + PY_CTF_LOWER + PY_CTF_SPACE + PY_CTF_UPPER + PY_CTF_XDIGIT + + Values used internally by the ``Py_IS*`` classification macros above. + Exposed for backwards compatibility only. + + .. soft-deprecated:: next diff --git a/Doc/c-api/file.rst b/Doc/c-api/file.rst index 26f846b06fc4ee9..c9725fb06f85ba3 100644 --- a/Doc/c-api/file.rst +++ b/Doc/c-api/file.rst @@ -161,10 +161,10 @@ the :mod:`io` APIs instead. .. c:macro:: PY_STDIOTEXTMODE - String literal ``"b"``, which can be appended to a C standard I/O mode - string, such as ``"r" PY_STDIOTEXTMODE``, to open a file in binary mode. - This prevents the C library from translating newlines, so that Python can - perform its own newline translation. + The string literal ``"b"``, used to open files in binary mode. + Exposed for backwards compatibility only. + + .. soft-deprecated:: next Soft-deprecated API diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst index 2b155e96b3c8094..fff7bbfad2017f3 100644 --- a/Doc/c-api/intro.rst +++ b/Doc/c-api/intro.rst @@ -309,6 +309,7 @@ Numeric utilities .. c:macro:: PY_DWORD_MAX The maximum value of the Windows ``DWORD`` type. + Expands to ``0xffffffff`` on all platforms. Assertion utilities diff --git a/Doc/c-api/long.rst b/Doc/c-api/long.rst index 452e86fca22ba80..d290973ffc09095 100644 --- a/Doc/c-api/long.rst +++ b/Doc/c-api/long.rst @@ -687,7 +687,10 @@ Build configuration The number of bits in each digit of CPython's internal representation of integers. The value is either ``30`` (the default) or ``15``, selected when - building Python with :option:`--enable-big-digits`. + The number of bits in each digit of CPython's native representation of + integers. + The value can currently be either ``30`` (the default) or ``15``, + selected with :option:`--enable-big-digits` when building Python. To access the native representation of integers, use :c:func:`PyLong_GetNativeLayout` and its diff --git a/Doc/c-api/pyexpat.rst b/Doc/c-api/pyexpat.rst index 30f5ed307206eef..5b1076dd702ddbf 100644 --- a/Doc/c-api/pyexpat.rst +++ b/Doc/c-api/pyexpat.rst @@ -3,11 +3,10 @@ Expat C API =========== -The :mod:`pyexpat ` module exposes selected Expat functions +The :mod:`xml.parsers.expat` module exposes selected Expat functions through its ``expat_CAPI`` capsule. This allows extension modules to use the same Expat library as Python. The interface is declared in :file:`pyexpat.h`, -which must be included after Expat's :file:`expat.h` header. It is not part of the -:ref:`Limited API `. +which must be included after Expat's :file:`expat.h` header. .. c:macro:: PyExpat_CAPSULE_NAME @@ -70,20 +69,17 @@ which must be included after Expat's :file:`expat.h` header. It is not part of t void (*SetStartDoctypeDeclHandler)(XML_Parser parser, XML_StartDoctypeDeclHandler start) enum XML_Status (*SetEncoding)(XML_Parser parser, const XML_Char *encoding) - Pointers to the corresponding Expat functions. The function names are - the member names prefixed with ``XML_``; for example, ``Parse`` points - to ``XML_Parse``. See the `Expat API reference + Pointers to the corresponding Expat functions. + Member names omit the ``XML_`` prefix; for example, ``Parse`` + exposes Expat's ``XML_Parse`` function. See the `Expat API reference `_ for their behavior. .. c:member:: int (*DefaultUnknownEncodingHandler)(void *encodingHandlerData, const XML_Char *name, XML_Encoding *info) - Python's unknown-encoding handler for Expat. It uses Python's codec - registry to fill *info* for the encoding *name*. The - *encodingHandlerData* argument is unused and may be ``NULL``. - - Return ``XML_STATUS_OK`` on success or ``XML_STATUS_ERROR`` on failure. - A Python exception may be set on failure. Calling this callback - requires an :term:`attached thread state`. + Python's unknown-encoding handler for Expat, used with + ``XML_SetUnknownEncodingHandler``. It uses Python's codec + registry to fill *info*. + The *encodingHandlerData* argument is unused. The remaining members also point to Expat functions with the ``XML_`` prefix. They may be ``NULL``, depending on the Expat version used by diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst index ab9ef4ae16089f3..c0ec9274d2a7227 100644 --- a/Doc/c-api/structures.rst +++ b/Doc/c-api/structures.rst @@ -798,7 +798,7 @@ The following flags can be used with :c:member:`PyMemberDef.flags`: A member flag that has no effect, retained solely for backwards compatibility. This is only available with ``#include "structmember.h"``. - .. soft-deprecated:: 3.0 + .. soft-deprecated:: next Omit this flag instead. diff --git a/Doc/c-api/synchronization.rst b/Doc/c-api/synchronization.rst index 750a073314cd61a..a74a92ca7cfa24e 100644 --- a/Doc/c-api/synchronization.rst +++ b/Doc/c-api/synchronization.rst @@ -269,10 +269,12 @@ These APIs are obsolete since Python 3.13 with the introduction of A :term:`soft deprecated` alias to :c:expr:`long long`, the integer type used for the timeout argument of :c:func:`PyThread_acquire_lock_timed`. + .. soft-deprecated:: next .. c:var:: const long long PY_TIMEOUT_MAX - The maximum timeout, in microseconds, supported by the legacy locking APIs. + The maximum timeout, in microseconds, supported by + :c:func:`PyThread_acquire_lock_timed`. .. note:: This differs from :data:`_thread.TIMEOUT_MAX`, which is expressed in seconds. From e5893d096e747984ebf499507f38588aff58272b Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Tue, 20 Oct 2026 18:18:33 -0400 Subject: [PATCH 06/13] Address review. --- Doc/c-api/code.rst | 2 +- Doc/c-api/conversion.rst | 3 +-- Doc/c-api/dict.rst | 11 ++++---- Doc/c-api/function.rst | 11 ++++---- Doc/c-api/hash.rst | 40 ++++++++++++++++------------- Doc/c-api/intro.rst | 19 +++++++++----- Doc/c-api/long.rst | 2 -- Doc/c-api/profiling.rst | 1 - Doc/c-api/pyexpat.rst | 49 +++++++++++++++++++++++++----------- Doc/c-api/structures.rst | 6 ----- Doc/c-api/veryhigh.rst | 49 +++++++++++++++++++++--------------- Doc/c-api/weakref.rst | 4 +-- Doc/using/configure.rst | 2 +- Include/cpython/code.h | 6 ++--- Include/cpython/dictobject.h | 6 ++--- Include/cpython/funcobject.h | 6 ++--- 16 files changed, 124 insertions(+), 93 deletions(-) diff --git a/Doc/c-api/code.rst b/Doc/c-api/code.rst index 385a750c9f32b8b..b34edb409da9a89 100644 --- a/Doc/c-api/code.rst +++ b/Doc/c-api/code.rst @@ -181,7 +181,7 @@ bound into a function. Apply the macro *V* to each suffix of :c:type:`PyCodeEvent` constants. Currently expands to ``V(CREATE) V(DESTROY)``. - The macro *V* must accept one event name and supply any punctuation + The macro *V* must accept one event name and supply any punctuation needed between expansions. .. c:type:: int (*PyCode_WatchCallback)(PyCodeEvent event, PyCodeObject* co) diff --git a/Doc/c-api/conversion.rst b/Doc/c-api/conversion.rst index 74a6c8b648d9d1f..0b176cdb118234e 100644 --- a/Doc/c-api/conversion.rst +++ b/Doc/c-api/conversion.rst @@ -276,6 +276,5 @@ macros above: Values used internally by the ``Py_IS*`` classification macros above. Exposed for backwards compatibility only. - - .. soft-deprecated:: next + .. soft-deprecated:: next diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst index 2aca1672a950c6e..4ac4445e25886c7 100644 --- a/Doc/c-api/dict.rst +++ b/Doc/c-api/dict.rst @@ -565,11 +565,12 @@ Dictionary objects .. c:macro:: PY_FOREACH_DICT_EVENT(V) - Apply the macro *V* to each of ``ADDED``, ``MODIFIED``, ``DELETED``, - ``CLONED``, ``CLEARED``, and ``DEALLOCATED``, in that order. These names - are the suffixes of :c:type:`PyDict_WatchEvent` constants. The macro *V* - must accept one event name and supply any punctuation needed between - expansions. + Apply the macro *V* to each suffix of :c:type:`PyDict_WatchEvent` + constants. + Currently expands to ``V(ADDED) V(MODIFIED) V(DELETED) V(CLONED) + V(CLEARED) V(DEALLOCATED)``. + The macro *V* must accept one event name and supply any punctuation + needed between expansions. .. c:type:: int (*PyDict_WatchCallback)(PyDict_WatchEvent event, PyObject *dict, PyObject *key, PyObject *new_value) diff --git a/Doc/c-api/function.rst b/Doc/c-api/function.rst index 38371e9bf04e03b..a0ccde984effb16 100644 --- a/Doc/c-api/function.rst +++ b/Doc/c-api/function.rst @@ -199,11 +199,12 @@ There are a few functions specific to Python functions. .. c:macro:: PY_FOREACH_FUNC_EVENT(V) - Apply the macro *V* to each of ``CREATE``, ``DESTROY``, ``MODIFY_CODE``, - ``MODIFY_DEFAULTS``, ``MODIFY_KWDEFAULTS``, and ``MODIFY_QUALNAME``, in that - order. These names are the suffixes of :c:type:`PyFunction_WatchEvent` - constants. The macro *V* must accept one event name and supply any - punctuation needed between expansions. + Apply the macro *V* to each suffix of :c:type:`PyFunction_WatchEvent` + constants. + Currently expands to ``V(CREATE) V(DESTROY) V(MODIFY_CODE) + V(MODIFY_DEFAULTS) V(MODIFY_KWDEFAULTS) V(MODIFY_QUALNAME)``. + The macro *V* must accept one event name and supply any punctuation + needed between expansions. .. c:type:: int (*PyFunction_WatchCallback)(PyFunction_WatchEvent event, PyFunctionObject *func, PyObject *new_value) diff --git a/Doc/c-api/hash.rst b/Doc/c-api/hash.rst index 9f07c86029966bc..7f1d3a656ebdd26 100644 --- a/Doc/c-api/hash.rst +++ b/Doc/c-api/hash.rst @@ -32,33 +32,24 @@ See also the :c:member:`PyTypeObject.tp_hash` member and :ref:`numeric-hash`. .. c:macro:: Py_HASH_FNV Py_HASH_SIPHASH24 Py_HASH_SIPHASH13 + Py_HASH_EXTERNAL Numerical values to compare to :c:macro:`Py_HASH_ALGORITHM` to determine - which algorithm is used for hashing. The hash algorithm can be configured - via the configure :option:`--with-hash-algorithm` option. + which algorithm is used for hashing. The built-in hash algorithm can be + configured via the configure :option:`--with-hash-algorithm` option. + + :c:macro:`!Py_HASH_EXTERNAL` has value ``0`` and indicates a hash + implementation supplied by the application embedding Python; see + :c:var:`PyHash_Func`. .. versionadded:: 3.4 - Add :c:macro:`!Py_HASH_FNV` and :c:macro:`!Py_HASH_SIPHASH24`. + Add :c:macro:`!Py_HASH_FNV`, :c:macro:`!Py_HASH_SIPHASH24`, and + :c:macro:`!Py_HASH_EXTERNAL`. .. versionadded:: 3.11 Add :c:macro:`!Py_HASH_SIPHASH13`. -.. c:macro:: Py_HASH_EXTERNAL - - Value of :c:macro:`Py_HASH_ALGORITHM` for a hash implementation supplied - by the application embedding Python. Its value is ``0``. - - When Python is built with this setting, the application must define a - :c:type:`PyHash_FuncDef` variable named ``PyHash_Func`` instead of using - one of Python's built-in hash algorithms. - - .. versionadded:: 3.4 - - .. deprecated-removed:: 3.15 3.19 - Use one of the built-in hash algorithms instead. - - .. c:macro:: Py_HASH_CUTOFF Buffers of length in range ``[1, Py_HASH_CUTOFF)`` are hashed using DJBX33A @@ -147,6 +138,19 @@ See also the :c:member:`PyTypeObject.tp_hash` member and :ref:`numeric-hash`. .. versionadded:: 3.4 +.. c:var:: PyHash_FuncDef PyHash_Func + + When Python is built with :c:macro:`Py_HASH_ALGORITHM` set to + :c:macro:`Py_HASH_EXTERNAL`, the application embedding Python must define + this variable to supply a hash implementation instead of using one of + Python's built-in hash algorithms. + + .. versionadded:: 3.4 + + .. deprecated-removed:: 3.15 3.19 + Use one of the built-in hash algorithms instead. + + .. c:function:: PyHash_FuncDef* PyHash_GetFuncDef(void) Get the hash function definition. diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst index fff7bbfad2017f3..8c63a108a78e5d8 100644 --- a/Doc/c-api/intro.rst +++ b/Doc/c-api/intro.rst @@ -306,12 +306,6 @@ Numeric utilities for. Exactly one of them is ``1`` and the other is ``0``. -.. c:macro:: PY_DWORD_MAX - - The maximum value of the Windows ``DWORD`` type. - Expands to ``0xffffffff`` on all platforms. - - Assertion utilities ^^^^^^^^^^^^^^^^^^^ @@ -930,6 +924,13 @@ use them. C99 doesn't define such a thing directly (size_t is an unsigned integral type). See :pep:`353` for details. + +.. c:macro:: Py_INVALID_SIZE + + A constant of type :c:type:`Py_ssize_t` with value ``-1``, representing an + invalid size. + + .. c:macro:: PY_SSIZE_T_MAX PY_SSIZE_T_MIN @@ -937,6 +938,12 @@ use them. respecitvely) of type :c:type:`Py_ssize_t`. +.. c:macro:: PY_DWORD_MAX + + The maximum value of the Windows ``DWORD`` type. + Expands to ``0xffffffff`` on all platforms. + + .. _api-exceptions: Exceptions diff --git a/Doc/c-api/long.rst b/Doc/c-api/long.rst index d290973ffc09095..b25dec161cb6f1a 100644 --- a/Doc/c-api/long.rst +++ b/Doc/c-api/long.rst @@ -685,8 +685,6 @@ Build configuration .. c:macro:: PYLONG_BITS_IN_DIGIT - The number of bits in each digit of CPython's internal representation of - integers. The value is either ``30`` (the default) or ``15``, selected when The number of bits in each digit of CPython's native representation of integers. The value can currently be either ``30`` (the default) or ``15``, diff --git a/Doc/c-api/profiling.rst b/Doc/c-api/profiling.rst index aefe9cfda28efd8..53827d7a3564e64 100644 --- a/Doc/c-api/profiling.rst +++ b/Doc/c-api/profiling.rst @@ -247,4 +247,3 @@ Performance statistics Largest micro-operation identifier for which CPython allocates performance statistics counters. Available only in builds configured with :option:`--enable-pystats`. - diff --git a/Doc/c-api/pyexpat.rst b/Doc/c-api/pyexpat.rst index 5b1076dd702ddbf..6723f7c1350c855 100644 --- a/Doc/c-api/pyexpat.rst +++ b/Doc/c-api/pyexpat.rst @@ -19,16 +19,18 @@ which must be included after Expat's :file:`expat.h` header. The string identifying the layout of :c:struct:`PyExpat_CAPI`. Before using the function pointers in the structure, check that - its ``magic`` member matches this string, its ``size`` member is - at least :c:expr:`sizeof(struct PyExpat_CAPI)`, and its + its ``magic`` member compares equal to this string using ``strcmp()``, + its ``size`` member is at least :c:expr:`sizeof(struct PyExpat_CAPI)`, and its :c:member:`PyExpat_CAPI.MAJOR_VERSION`, :c:member:`PyExpat_CAPI.MINOR_VERSION`, - and :c:member:`PyExpat_CAPI.MICRO_VERSION` members match the Expat - version used to build the extension. + and :c:member:`PyExpat_CAPI.MICRO_VERSION` members equal the + ``XML_MAJOR_VERSION``, ``XML_MINOR_VERSION``, and ``XML_MICRO_VERSION`` + macros, respectively, from the :file:`expat.h` header used to build the + extension. .. c:struct:: PyExpat_CAPI - Table of function pointers exported by :mod:`pyexpat `. + Table of function pointers exported by :mod:`xml.parsers.expat`. The capsule owns this structure: treat it as read-only and do not free it. Keep a strong reference to the capsule while using the table. @@ -42,14 +44,14 @@ which must be included after Expat's :file:`expat.h` header. .. c:member:: int size Size of the structure in bytes, set to ``sizeof(struct PyExpat_CAPI)`` - by the :mod:`pyexpat ` module that created the capsule. + by the :mod:`xml.parsers.expat` module that created the capsule. .. c:member:: int MAJOR_VERSION int MINOR_VERSION int MICRO_VERSION Major, minor, and micro version numbers of the Expat library used by - :mod:`pyexpat `. + :mod:`xml.parsers.expat`. .. c:member:: const XML_LChar *(*ErrorString)(enum XML_Error code) enum XML_Error (*GetErrorCode)(XML_Parser parser) @@ -64,7 +66,6 @@ which must be included after Expat's :file:`expat.h` header. void (*SetElementHandler)(XML_Parser parser, XML_StartElementHandler start, XML_EndElementHandler end) void (*SetNamespaceDeclHandler)(XML_Parser parser, XML_StartNamespaceDeclHandler start, XML_EndNamespaceDeclHandler end) void (*SetProcessingInstructionHandler)(XML_Parser parser, XML_ProcessingInstructionHandler handler) - void (*SetUnknownEncodingHandler)(XML_Parser parser, XML_UnknownEncodingHandler handler, void *encodingHandlerData) void (*SetUserData)(XML_Parser parser, void *userData) void (*SetStartDoctypeDeclHandler)(XML_Parser parser, XML_StartDoctypeDeclHandler start) enum XML_Status (*SetEncoding)(XML_Parser parser, const XML_Char *encoding) @@ -74,35 +75,53 @@ which must be included after Expat's :file:`expat.h` header. exposes Expat's ``XML_Parse`` function. See the `Expat API reference `_ for their behavior. + .. c:member:: void (*SetUnknownEncodingHandler)(XML_Parser parser, XML_UnknownEncodingHandler handler, void *encodingHandlerData) + + Pointer to `XML_SetUnknownEncodingHandler + `_. + The handler may set a Python exception on failure. The caller must + check for a Python exception after parsing. + .. c:member:: int (*DefaultUnknownEncodingHandler)(void *encodingHandlerData, const XML_Char *name, XML_Encoding *info) Python's unknown-encoding handler for Expat, used with ``XML_SetUnknownEncodingHandler``. It uses Python's codec registry to fill *info*. The *encodingHandlerData* argument is unused. + Calling this handler requires an :term:`attached thread state`. The remaining members also point to Expat functions with the ``XML_`` - prefix. They may be ``NULL``, depending on the Expat version used by - :mod:`pyexpat `: + prefix. They may be ``NULL`` if the function is unavailable in the Expat + version used by :mod:`xml.parsers.expat`. See the linked Expat + documentation for minimum versions. .. c:member:: int (*SetHashSalt)(XML_Parser parser, unsigned long hash_salt) - ``NULL`` with Expat versions older than 2.1.0. + See `XML_SetHashSalt + `_. .. c:member:: XML_Bool (*SetReparseDeferralEnabled)(XML_Parser parser, XML_Bool enabled) - ``NULL`` with Expat versions older than 2.6.0. + See `XML_SetReparseDeferralEnabled + `_. .. c:member:: XML_Bool (*SetAllocTrackerActivationThreshold)(XML_Parser parser, unsigned long long activationThresholdBytes) XML_Bool (*SetAllocTrackerMaximumAmplification)(XML_Parser parser, float maxAmplificationFactor) - ``NULL`` with Expat versions older than 2.7.2. + See `XML_SetAllocTrackerActivationThreshold + `_ + and `XML_SetAllocTrackerMaximumAmplification + `_. .. c:member:: XML_Bool (*SetBillionLaughsAttackProtectionActivationThreshold)(XML_Parser parser, unsigned long long activationThresholdBytes) XML_Bool (*SetBillionLaughsAttackProtectionMaximumAmplification)(XML_Parser parser, float maxAmplificationFactor) - ``NULL`` with Expat versions older than 2.4.0. + See `XML_SetBillionLaughsAttackProtectionActivationThreshold + `_ + and `XML_SetBillionLaughsAttackProtectionMaximumAmplification + `_. .. c:member:: XML_Bool (*SetHashSalt16Bytes)(XML_Parser parser, const uint8_t entropy[16]) - ``NULL`` with Expat versions older than 2.8.0. + See `XML_SetHashSalt16Bytes + `_. diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst index c0ec9274d2a7227..d9557491bc93bde 100644 --- a/Doc/c-api/structures.rst +++ b/Doc/c-api/structures.rst @@ -221,12 +221,6 @@ under :ref:`reference counting `. .. versionadded:: 3.9 -.. c:macro:: Py_INVALID_SIZE - - A constant of type :c:type:`Py_ssize_t` with value ``-1``, representing an - invalid size. - - .. c:macro:: PyObject_HEAD_INIT(type) This is a macro which expands to initialization values for a new diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst index 93d902d6a2a6993..13999d1f42b2a51 100644 --- a/Doc/c-api/veryhigh.rst +++ b/Doc/c-api/veryhigh.rst @@ -156,36 +156,27 @@ the same library that the Python runtime is using. :ref:`main interpreter `. -.. c:function:: char *PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) - - Display *prompt*, if it is not ``NULL``, and read a line from *sys_stdin*. - The returned string is null-terminated and includes the trailing newline, - if one was read. This returns an empty string if the end of the file is reached - before any characters are read. This will return ``NULL`` with an exception set - on failure or interruption. - - By default, *sys_stdout* is flushed and *prompt* is written to the C - standard error stream. If both streams are terminals and the call is made - from the :ref:`main interpreter `, - :c:var:`PyOS_ReadlineFunctionPointer` can override this behavior. - - The caller must free the returned string with :c:func:`PyMem_Free`. - The caller must hold an :term:`attached thread state`. - - .. c:var:: char* (*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, const char *) Can be set to point to a function with the prototype - ``char *func(FILE *stdin, FILE *stdout, char *prompt)``, + ``char *func(FILE *stdin, FILE *stdout, const char *prompt)``, overriding the default function used to read a single line of input at the interpreter's prompt. The function is expected to output the string *prompt* if it's not ``NULL``, and then read a line of input from the provided standard input file, returning the - resulting string. For example, The :mod:`readline` module sets + resulting string. For example, the :mod:`readline` module sets this hook to provide line-editing and tab-completion features. + If this pointer is ``NULL``, :c:func:`PyOS_Readline` sets it to the + default implementation before reading input. + + The returned string must be null-terminated and include the trailing + newline, if one was read. Return an empty string if the end of the file + is reached before any characters are read. Return ``NULL`` on failure + or interruption; a Python exception may be set. + The result must be a string allocated by :c:func:`PyMem_RawMalloc` or - :c:func:`PyMem_RawRealloc`, or ``NULL`` if an error occurred. + :c:func:`PyMem_RawRealloc`. .. versionchanged:: 3.4 The result must be allocated by :c:func:`PyMem_RawMalloc` or @@ -196,6 +187,24 @@ the same library that the Python runtime is using. This function is only called from the :ref:`main interpreter `. + +.. c:function:: char *PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) + + Display *prompt*, if it is not ``NULL``, and read a line from *sys_stdin*. + If both streams are terminals and the call is made from the + :ref:`main interpreter `, use + :c:var:`PyOS_ReadlineFunctionPointer`. Otherwise, use the default + implementation, which flushes *sys_stdout* and writes *prompt* to the C + standard error stream. + + The returned string follows the contract of + :c:var:`PyOS_ReadlineFunctionPointer`, but the caller must free it with + :c:func:`PyMem_Free`. Return ``NULL`` on failure or interruption; a Python + exception may be set. + + The caller must hold an :term:`attached thread state`. + + .. c:function:: PyObject* PyRun_String(const char *str, int start, PyObject *globals, PyObject *locals) This is a simplified interface to :c:func:`PyRun_StringFlags` below, leaving diff --git a/Doc/c-api/weakref.rst b/Doc/c-api/weakref.rst index 51f2dda6f57a844..423c1ba35616569 100644 --- a/Doc/c-api/weakref.rst +++ b/Doc/c-api/weakref.rst @@ -111,8 +111,8 @@ as much as it can. Return a pointer to the head of the list of weak references to *object*. *object* must support weak references and must not be ``NULL``. - The returned pointer can be dereferenced to obtain the current head of - the list. Do not use it to modify the list or its head. + This function is intended for internal use only. Do not access or modify + the weak reference list through the returned pointer. .. c:function:: void PyUnstable_Object_ClearWeakRefsNoCallbacks(PyObject *object) diff --git a/Doc/using/configure.rst b/Doc/using/configure.rst index 0d420d80f8e261e..c36328ca6f79723 100644 --- a/Doc/using/configure.rst +++ b/Doc/using/configure.rst @@ -247,7 +247,7 @@ General Options By default, the digit size is 30. - Define the ``PYLONG_BITS_IN_DIGIT`` to ``15`` or ``30``. + Define :c:macro:`PYLONG_BITS_IN_DIGIT` to ``15`` or ``30``. See :data:`sys.int_info.bits_per_digit `. diff --git a/Include/cpython/code.h b/Include/cpython/code.h index 1be47e42ed62bfb..5238447070ee548 100644 --- a/Include/cpython/code.h +++ b/Include/cpython/code.h @@ -232,9 +232,9 @@ PyAPI_FUNC(int) PyCode_Addr2Location(PyCodeObject *, int, int *, int *, int *, i V(DESTROY) typedef enum { - #define PY_DEF_EVENT(op) PY_CODE_EVENT_##op, - PY_FOREACH_CODE_EVENT(PY_DEF_EVENT) - #undef PY_DEF_EVENT + #define _Py_DEF_EVENT(op) PY_CODE_EVENT_##op, + PY_FOREACH_CODE_EVENT(_Py_DEF_EVENT) + #undef _Py_DEF_EVENT } PyCodeEvent; diff --git a/Include/cpython/dictobject.h b/Include/cpython/dictobject.h index 5e7811416aba63f..2b139a1e7db1818 100644 --- a/Include/cpython/dictobject.h +++ b/Include/cpython/dictobject.h @@ -86,9 +86,9 @@ Py_DEPRECATED(3.14) PyAPI_FUNC(PyObject *) _PyDict_Pop( V(DEALLOCATED) typedef enum { - #define PY_DEF_EVENT(EVENT) PyDict_EVENT_##EVENT, - PY_FOREACH_DICT_EVENT(PY_DEF_EVENT) - #undef PY_DEF_EVENT + #define _Py_DEF_EVENT(EVENT) PyDict_EVENT_##EVENT, + PY_FOREACH_DICT_EVENT(_Py_DEF_EVENT) + #undef _Py_DEF_EVENT } PyDict_WatchEvent; // Callback to be invoked when a watched dict is cleared, dealloced, or modified. diff --git a/Include/cpython/funcobject.h b/Include/cpython/funcobject.h index bcdd9df561def38..78a4ed41162924f 100644 --- a/Include/cpython/funcobject.h +++ b/Include/cpython/funcobject.h @@ -148,9 +148,9 @@ PyAPI_FUNC(PyObject *) PyStaticMethod_New(PyObject *); V(MODIFY_QUALNAME) typedef enum { - #define PY_DEF_EVENT(EVENT) PyFunction_EVENT_##EVENT, - PY_FOREACH_FUNC_EVENT(PY_DEF_EVENT) - #undef PY_DEF_EVENT + #define _Py_DEF_EVENT(EVENT) PyFunction_EVENT_##EVENT, + PY_FOREACH_FUNC_EVENT(_Py_DEF_EVENT) + #undef _Py_DEF_EVENT } PyFunction_WatchEvent; /* From 01552743b6e215b9b34fe6342a60c598b6c54865 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Tue, 20 Oct 2026 18:24:12 -0400 Subject: [PATCH 07/13] Add soft deprecation for weakref thing. --- Doc/c-api/weakref.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Doc/c-api/weakref.rst b/Doc/c-api/weakref.rst index 423c1ba35616569..7366db2b941eda6 100644 --- a/Doc/c-api/weakref.rst +++ b/Doc/c-api/weakref.rst @@ -114,6 +114,8 @@ as much as it can. This function is intended for internal use only. Do not access or modify the weak reference list through the returned pointer. + .. soft-deprecated:: next + .. c:function:: void PyUnstable_Object_ClearWeakRefsNoCallbacks(PyObject *object) From 38667ffc06a6852eac0c8315469d1890a367fbc1 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Tue, 20 Oct 2026 18:25:40 -0400 Subject: [PATCH 08/13] Soft-deprecate the pystats thing. --- Doc/c-api/profiling.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Doc/c-api/profiling.rst b/Doc/c-api/profiling.rst index 53827d7a3564e64..8393858c827e2dd 100644 --- a/Doc/c-api/profiling.rst +++ b/Doc/c-api/profiling.rst @@ -247,3 +247,8 @@ Performance statistics Largest micro-operation identifier for which CPython allocates performance statistics counters. Available only in builds configured with :option:`--enable-pystats`. + + This constant is intended for internal use only and is not useful to + extension modules. + + .. soft-deprecated:: next From 3557dd01d2756682b668e72cf8b900b20b3fea25 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Tue, 20 Oct 2026 18:57:28 -0400 Subject: [PATCH 09/13] Move PY_STDIOTEXTMODE to deprecated API section. --- Doc/c-api/file.rst | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/Doc/c-api/file.rst b/Doc/c-api/file.rst index c9725fb06f85ba3..a6bfa8358e3aacc 100644 --- a/Doc/c-api/file.rst +++ b/Doc/c-api/file.rst @@ -159,29 +159,33 @@ the :mod:`io` APIs instead. failure; the appropriate exception will be set. -.. c:macro:: PY_STDIOTEXTMODE - - The string literal ``"b"``, used to open files in binary mode. - Exposed for backwards compatibility only. - - .. soft-deprecated:: next - - Soft-deprecated API ^^^^^^^^^^^^^^^^^^^ -.. soft-deprecated:: 3.15 - These are APIs that were included in Python's C API by mistake. They are documented solely for completeness; use other ``PyFile*`` APIs instead. + .. c:function:: PyObject *PyFile_NewStdPrinter(int fd) Use :c:func:`PyFile_FromFd` with defaults (``fd, NULL, "w", -1, NULL, NULL, NULL, 0``) instead. + .. soft-deprecated:: 3.15 + + .. c:var:: PyTypeObject PyStdPrinter_Type Type of file-like objects used internally at Python startup when :py:mod:`io` is not yet available. Use Python :py:func:`open` or :c:func:`PyFile_FromFd` to create file objects instead. + + .. soft-deprecated:: 3.15 + + +.. c:macro:: PY_STDIOTEXTMODE + + The string literal ``"b"``, used to open files in binary mode. + Exposed for backwards compatibility only. + + .. soft-deprecated:: next From 94247b6fb401573277ad0b7d788217e68e414b08 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Tue, 20 Oct 2026 19:26:04 -0400 Subject: [PATCH 10/13] Apply batched suggestions from code review Co-authored-by: Petr Viktorin --- Doc/c-api/pyexpat.rst | 40 ++++++++++------------------------------ Doc/c-api/veryhigh.rst | 6 +++--- Doc/c-api/weakref.rst | 2 +- 3 files changed, 14 insertions(+), 34 deletions(-) diff --git a/Doc/c-api/pyexpat.rst b/Doc/c-api/pyexpat.rst index 6723f7c1350c855..948f597e065a86c 100644 --- a/Doc/c-api/pyexpat.rst +++ b/Doc/c-api/pyexpat.rst @@ -90,38 +90,18 @@ which must be included after Expat's :file:`expat.h` header. The *encodingHandlerData* argument is unused. Calling this handler requires an :term:`attached thread state`. - The remaining members also point to Expat functions with the ``XML_`` - prefix. They may be ``NULL`` if the function is unavailable in the Expat - version used by :mod:`xml.parsers.expat`. See the linked Expat - documentation for minimum versions. - .. c:member:: int (*SetHashSalt)(XML_Parser parser, unsigned long hash_salt) - - See `XML_SetHashSalt - `_. - - .. c:member:: XML_Bool (*SetReparseDeferralEnabled)(XML_Parser parser, XML_Bool enabled) - - See `XML_SetReparseDeferralEnabled - `_. - - .. c:member:: XML_Bool (*SetAllocTrackerActivationThreshold)(XML_Parser parser, unsigned long long activationThresholdBytes) + XML_Bool (*SetReparseDeferralEnabled)(XML_Parser parser, XML_Bool enabled) + XML_Bool (*SetAllocTrackerActivationThreshold)(XML_Parser parser, unsigned long long activationThresholdBytes) XML_Bool (*SetAllocTrackerMaximumAmplification)(XML_Parser parser, float maxAmplificationFactor) - - See `XML_SetAllocTrackerActivationThreshold - `_ - and `XML_SetAllocTrackerMaximumAmplification - `_. - - .. c:member:: XML_Bool (*SetBillionLaughsAttackProtectionActivationThreshold)(XML_Parser parser, unsigned long long activationThresholdBytes) + XML_Bool (*SetBillionLaughsAttackProtectionActivationThreshold)(XML_Parser parser, unsigned long long activationThresholdBytes) XML_Bool (*SetBillionLaughsAttackProtectionMaximumAmplification)(XML_Parser parser, float maxAmplificationFactor) + XML_Bool (*SetHashSalt16Bytes)(XML_Parser parser, const uint8_t entropy[16]) - See `XML_SetBillionLaughsAttackProtectionActivationThreshold - `_ - and `XML_SetBillionLaughsAttackProtectionMaximumAmplification - `_. - - .. c:member:: XML_Bool (*SetHashSalt16Bytes)(XML_Parser parser, const uint8_t entropy[16]) + Pointers to the corresponding Expat functions, or ``NULL`` if not + available in the Expat version used by :mod:`xml.parsers.expat`. - See `XML_SetHashSalt16Bytes - `_. + Member names omit the ``XML_`` prefix; for example, ``SetHashSalt`` + exposes Expat's ``XML_SetHashSalt`` function. See the `Expat API reference + `_ for their behavior + and the minimum Expat version they appear in. diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst index 13999d1f42b2a51..9d4c69eb2b93acd 100644 --- a/Doc/c-api/veryhigh.rst +++ b/Doc/c-api/veryhigh.rst @@ -168,14 +168,15 @@ the same library that the Python runtime is using. this hook to provide line-editing and tab-completion features. If this pointer is ``NULL``, :c:func:`PyOS_Readline` sets it to the - default implementation before reading input. + default implementation, :c:func:`PyOS_Readline`, + before reading input. The returned string must be null-terminated and include the trailing newline, if one was read. Return an empty string if the end of the file is reached before any characters are read. Return ``NULL`` on failure or interruption; a Python exception may be set. - The result must be a string allocated by :c:func:`PyMem_RawMalloc` or + A non-``NULL`` result must be a string allocated by :c:func:`PyMem_RawMalloc` or :c:func:`PyMem_RawRealloc`. .. versionchanged:: 3.4 @@ -202,7 +203,6 @@ the same library that the Python runtime is using. :c:func:`PyMem_Free`. Return ``NULL`` on failure or interruption; a Python exception may be set. - The caller must hold an :term:`attached thread state`. .. c:function:: PyObject* PyRun_String(const char *str, int start, PyObject *globals, PyObject *locals) diff --git a/Doc/c-api/weakref.rst b/Doc/c-api/weakref.rst index 7366db2b941eda6..83ca45ec251e2be 100644 --- a/Doc/c-api/weakref.rst +++ b/Doc/c-api/weakref.rst @@ -108,7 +108,7 @@ as much as it can. .. c:function:: PyObject **PyObject_GET_WEAKREFS_LISTPTR(PyObject *object) - Return a pointer to the head of the list of weak references to *object*. + Return a pointer to an internal linked list of weak references to *object*. *object* must support weak references and must not be ``NULL``. This function is intended for internal use only. Do not access or modify From 9e4430c65d74e3c893379e887753cfd2a1b8df0e Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Tue, 20 Oct 2026 19:28:07 -0400 Subject: [PATCH 11/13] Note the lack of a thread state in the PyOS stuff. --- Doc/c-api/veryhigh.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst index 9d4c69eb2b93acd..7c4ef80592e76b7 100644 --- a/Doc/c-api/veryhigh.rst +++ b/Doc/c-api/veryhigh.rst @@ -151,6 +151,8 @@ the same library that the Python runtime is using. event loops, as done in :file:`Modules/_tkinter.c` in the Python source code. + The function is called without an :term:`attached thread state`. + .. versionchanged:: 3.12 This function is only called from the :ref:`main interpreter `. @@ -167,6 +169,8 @@ the same library that the Python runtime is using. resulting string. For example, the :mod:`readline` module sets this hook to provide line-editing and tab-completion features. + The function is called without an :term:`attached thread state`. + If this pointer is ``NULL``, :c:func:`PyOS_Readline` sets it to the default implementation, :c:func:`PyOS_Readline`, before reading input. From 284f5f4107491563e93814694b7a224551ce7620 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Tue, 20 Oct 2026 19:32:10 -0400 Subject: [PATCH 12/13] Fun Expat stuff. --- Doc/c-api/pyexpat.rst | 55 ++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/Doc/c-api/pyexpat.rst b/Doc/c-api/pyexpat.rst index 948f597e065a86c..739cdfbb37c84d5 100644 --- a/Doc/c-api/pyexpat.rst +++ b/Doc/c-api/pyexpat.rst @@ -53,6 +53,30 @@ which must be included after Expat's :file:`expat.h` header. Major, minor, and micro version numbers of the Expat library used by :mod:`xml.parsers.expat`. + .. c:member:: void (*SetUnknownEncodingHandler)(XML_Parser parser, XML_UnknownEncodingHandler handler, void *encodingHandlerData) + + Pointer to `XML_SetUnknownEncodingHandler + `_. + The handler may set a Python exception on failure. The caller must + check for a Python exception after parsing. + + .. c:member:: int (*DefaultUnknownEncodingHandler)(void *encodingHandlerData, const XML_Char *name, XML_Encoding *info) + + Python's unknown-encoding handler for Expat, used with + ``XML_SetUnknownEncodingHandler``. It uses Python's codec + registry to fill *info*. + The *encodingHandlerData* argument is unused. + Calling this handler requires an :term:`attached thread state`. + + Pointers to the corresponding Expat functions, or ``NULL`` if not + available in the Expat version used by :mod:`xml.parsers.expat`, are + listed below. + + Member names omit the ``XML_`` prefix; for example, ``SetHashSalt`` + exposes Expat's ``XML_SetHashSalt`` function. See the `Expat API reference + `_ for their behavior + and the minimum Expat version they appear in. + .. c:member:: const XML_LChar *(*ErrorString)(enum XML_Error code) enum XML_Error (*GetErrorCode)(XML_Parser parser) XML_Size (*GetErrorColumnNumber)(XML_Parser parser) @@ -69,28 +93,7 @@ which must be included after Expat's :file:`expat.h` header. void (*SetUserData)(XML_Parser parser, void *userData) void (*SetStartDoctypeDeclHandler)(XML_Parser parser, XML_StartDoctypeDeclHandler start) enum XML_Status (*SetEncoding)(XML_Parser parser, const XML_Char *encoding) - - Pointers to the corresponding Expat functions. - Member names omit the ``XML_`` prefix; for example, ``Parse`` - exposes Expat's ``XML_Parse`` function. See the `Expat API reference - `_ for their behavior. - - .. c:member:: void (*SetUnknownEncodingHandler)(XML_Parser parser, XML_UnknownEncodingHandler handler, void *encodingHandlerData) - - Pointer to `XML_SetUnknownEncodingHandler - `_. - The handler may set a Python exception on failure. The caller must - check for a Python exception after parsing. - - .. c:member:: int (*DefaultUnknownEncodingHandler)(void *encodingHandlerData, const XML_Char *name, XML_Encoding *info) - - Python's unknown-encoding handler for Expat, used with - ``XML_SetUnknownEncodingHandler``. It uses Python's codec - registry to fill *info*. - The *encodingHandlerData* argument is unused. - Calling this handler requires an :term:`attached thread state`. - - .. c:member:: int (*SetHashSalt)(XML_Parser parser, unsigned long hash_salt) + int (*SetHashSalt)(XML_Parser parser, unsigned long hash_salt) XML_Bool (*SetReparseDeferralEnabled)(XML_Parser parser, XML_Bool enabled) XML_Bool (*SetAllocTrackerActivationThreshold)(XML_Parser parser, unsigned long long activationThresholdBytes) XML_Bool (*SetAllocTrackerMaximumAmplification)(XML_Parser parser, float maxAmplificationFactor) @@ -98,10 +101,4 @@ which must be included after Expat's :file:`expat.h` header. XML_Bool (*SetBillionLaughsAttackProtectionMaximumAmplification)(XML_Parser parser, float maxAmplificationFactor) XML_Bool (*SetHashSalt16Bytes)(XML_Parser parser, const uint8_t entropy[16]) - Pointers to the corresponding Expat functions, or ``NULL`` if not - available in the Expat version used by :mod:`xml.parsers.expat`. - - Member names omit the ``XML_`` prefix; for example, ``SetHashSalt`` - exposes Expat's ``XML_SetHashSalt`` function. See the `Expat API reference - `_ for their behavior - and the minimum Expat version they appear in. + See the `Expat API reference `_. From 1ac0d683aa33d348806592d3c81975164adcd229 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Tue, 20 Oct 2026 23:04:06 -0400 Subject: [PATCH 13/13] Update Doc/c-api/pyexpat.rst Co-authored-by: Petr Viktorin --- Doc/c-api/pyexpat.rst | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/Doc/c-api/pyexpat.rst b/Doc/c-api/pyexpat.rst index 739cdfbb37c84d5..6f40bf5b7e70534 100644 --- a/Doc/c-api/pyexpat.rst +++ b/Doc/c-api/pyexpat.rst @@ -19,13 +19,8 @@ which must be included after Expat's :file:`expat.h` header. The string identifying the layout of :c:struct:`PyExpat_CAPI`. Before using the function pointers in the structure, check that - its ``magic`` member compares equal to this string using ``strcmp()``, - its ``size`` member is at least :c:expr:`sizeof(struct PyExpat_CAPI)`, and its - :c:member:`PyExpat_CAPI.MAJOR_VERSION`, :c:member:`PyExpat_CAPI.MINOR_VERSION`, - and :c:member:`PyExpat_CAPI.MICRO_VERSION` members equal the - ``XML_MAJOR_VERSION``, ``XML_MINOR_VERSION``, and ``XML_MICRO_VERSION`` - macros, respectively, from the :file:`expat.h` header used to build the - extension. + its ``magic`` member compares equal to this string using ``strcmp()`` + and its ``size`` member is at least :c:expr:`sizeof(struct PyExpat_CAPI)`. .. c:struct:: PyExpat_CAPI