From 5b857a41d6adecf95babe4318c5013a3b605a44a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sat, 8 Nov 2025 18:18:17 +0100 Subject: [PATCH 1/9] document Expat C API --- Doc/c-api/concrete.rst | 10 ++- Doc/c-api/expat.rst | 192 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 201 insertions(+), 1 deletion(-) create mode 100644 Doc/c-api/expat.rst diff --git a/Doc/c-api/concrete.rst b/Doc/c-api/concrete.rst index 880f7b15ce68e8..dbeea5bbb34558 100644 --- a/Doc/c-api/concrete.rst +++ b/Doc/c-api/concrete.rst @@ -115,5 +115,13 @@ Other Objects gen.rst coro.rst contextvars.rst - datetime.rst typehints.rst + + +C API for extension modules +=========================== + +.. toctree:: + + datetime.rst + expat.rst diff --git a/Doc/c-api/expat.rst b/Doc/c-api/expat.rst new file mode 100644 index 00000000000000..e8873784ba1f87 --- /dev/null +++ b/Doc/c-api/expat.rst @@ -0,0 +1,192 @@ +.. highlight:: c + +Expat C API +----------- + +:mod:`pyexpat` exposes a C interface for extension modules. +Consumers must include the header file :file:`pyexpat.h` (which is not +included by default by :file:`Python.h`) and ``expat.h`` for Expat. + +To use the C API, consider adding the following code in your extension +module initilisation function and store the pointer to the C API in +the module state: + +.. code-block:: + + struct PyExpat_CAPI *capi = NULL; + capi = (struct PyExpat_CAPI *)PyCapsule_Import(PyExpat_CAPSULE_NAME, 0); + if (capi == NULL) { goto error; } + + /* check if the C API is compatible with the version of Expat version */ + if (strcmp(capi->magic, PyExpat_CAPI_MAGIC) != 0 + || (size_t)capi->size < sizeof(struct PyExpat_CAPI) + || capi->MAJOR_VERSION != XML_MAJOR_VERSION + || capi->MINOR_VERSION != XML_MINOR_VERSION + || capi->MICRO_VERSION != XML_MICRO_VERSION + ) { + PyErr_SetString(PyExc_ImportError, "pyexpat version is incompatible"); + goto error; + } + + +.. c:macro:: PyExpat_CAPI_MAGIC + + The Expat C API magic number. + + +.. c:macro:: PyExpat_CAPSULE_NAME + + The Expat C API capsule name to import via :c:func:`PyCapsule_Import`. + + +.. c:struct:: PyExpat_CAPI + + The Expat C API structure. + + .. below are members that were added in Python 2.x + + .. c:member:: char *magic + + Set to :c:macro:`PyExpat_CAPI_MAGIC`. + + .. c:member:: int size + + Set to ``sizeof(struct PyExpat_CAPI)``. + + .. c:member:: int MAJOR_VERSION + int MINOR_VERSION + int MICRO_VERSION + + Set to ``XML_MAJOR_VERSION``, ``XML_MINOR_VERSION``, + and ``XML_MICRO_VERSION`` respectively of the linked + Expat library. + + The following members expose the C API as provided by Expat. + See the `official documentation `_ + for details (some names may slightly differ but the signature and intent + will not). + + .. c:member:: const XML_LChar *(*ErrorString)(enum XML_Error errno) + .. c:member:: enum XML_Error (*GetErrorCode)(XML_Parser parser) + + .. c:member:: XML_Size (*GetErrorColumnNumber)(XML_Parser parser) + .. c:member:: XML_Size (*GetErrorLineNumber)(XML_Parser parser) + + .. c:member:: enum XML_Status (*Parse)(\ + XML_Parser parser,\ + const char *s, int len, int isFinal) + + .. c:member:: XML_Parser (*ParserCreate_MM)(\ + const XML_Char *encoding,\ + const XML_Memory_Handling_Suite *memsuite,\ + const XML_Char *sep) + + .. c:member:: void (*ParserFree)(XML_Parser parser) + + .. c:member:: void (*SetCharacterDataHandler)(\ + XML_Parser parser,\ + XML_CharacterDataHandler handler) + + .. c:member:: void (*SetCommentHandler)(\ + XML_Parser parser,\ + XML_CommentHandler handler) + + .. c:member:: void (*SetDefaultHandlerExpand)(\ + XML_Parser parser,\ + XML_DefaultHandler handler) + + .. c:member:: void (*SetElementHandler)(\ + XML_Parser parser,\ + XML_StartElementHandler start,\ + XML_EndElementHandler end) + + .. c:member:: void (*SetNamespaceDeclHandler)(\ + XML_Parser parser,\ + XML_StartNamespaceDeclHandler start,\ + XML_EndNamespaceDeclHandler end) + + .. c:member:: void (*SetProcessingInstructionHandler)(\ + XML_Parser parser,\ + XML_ProcessingInstructionHandler handler) + + .. c:member:: void (*SetUnknownEncodingHandler)(\ + XML_Parser parser,\ + XML_UnknownEncodingHandler handler,\ + void *encodingHandlerData) + + .. c:member:: void (*SetUserData)(\ + XML_Parser parser,\ + void *userData) + + .. below are members that were added after Python 3.0 + + .. c:member:: void (*SetStartDoctypeDeclHandler)(\ + XML_Parser parser,\ + XML_StartDoctypeDeclHandler start) + + .. versionadded:: 3.2 + + .. c:member:: enum XML_Status (*SetEncoding)(\ + XML_Parser parser,\ + const XML_Char *encoding) + + .. versionadded:: 3.3 + + .. c:member:: int (*DefaultUnknownEncodingHandler)(\ + void *encodingHandlerData,\ + const XML_Char *name,\ + XML_Encoding *info) + + .. versionadded:: 3.3 + + .. c:member:: int (*SetHashSalt)(\ + XML_Parser parser,\ + unsigned long hash_salt) + + Might be NULL for Expat versions prior to 2.1.0. + + .. versionadded:: 3.4 + + .. c:member:: XML_Bool (*SetReparseDeferralEnabled)(\ + XML_Parser parser,\ + XML_Bool enabled) + + Might be NULL for Expat versions prior to 2.6.0. + + .. versionadded:: 3.8 + + .. c:member:: XML_Bool (*SetAllocTrackerActivationThreshold)(\ + XML_Parser parser,\ + unsigned long long activationThresholdBytes) + + Might be NULL for Expat versions prior to 2.7.2. + + .. uncomment this when the backport is done + .. versionadded:: 3.10 + + .. c:member:: XML_Bool (*SetAllocTrackerMaximumAmplification)(\ + XML_Parser parser,\ + float maxAmplificationFactor) + + Might be NULL for Expat versions prior to 2.7.2. + + .. uncomment this when the backport is done + .. versionadded:: 3.10 + + .. c:member:: XML_Bool (*SetBillionLaughsAttackProtectionActivationThreshold)(\ + XML_Parser parser,\ + unsigned long long activationThresholdBytes) + + Might be NULL for Expat versions prior to 2.4.0. + + .. uncomment this when the backport is done + .. versionadded:: 3.10 + + .. c:member:: XML_Bool (*SetBillionLaughsAttackProtectionMaximumAmplification)(\ + XML_Parser parser,\ + float maxAmplificationFactor) + + Might be NULL for Expat versions prior to 2.4.0. + + .. uncomment this when the backport is done + .. versionadded:: 3.10 From e20466a6418f9faf25dac330bcca8d19f3db5758 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sat, 8 Nov 2025 18:38:13 +0100 Subject: [PATCH 2/9] suppress some references --- Doc/c-api/expat.rst | 2 +- Doc/conf.py | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/Doc/c-api/expat.rst b/Doc/c-api/expat.rst index e8873784ba1f87..3514f8d42036ef 100644 --- a/Doc/c-api/expat.rst +++ b/Doc/c-api/expat.rst @@ -3,7 +3,7 @@ Expat C API ----------- -:mod:`pyexpat` exposes a C interface for extension modules. +:mod:`!pyexpat exposes a C interface for extension modules. Consumers must include the header file :file:`pyexpat.h` (which is not included by default by :file:`Python.h`) and ``expat.h`` for Expat. diff --git a/Doc/conf.py b/Doc/conf.py index f1dda10052e109..7e5a45f8f5e0f2 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -223,6 +223,29 @@ ('envvar', 'USERPROFILE'), ] +# Vendored types +nitpick_ignore += [ + ("c:identifier", "XML_Bool"), + ("c:identifier", "XML_Char"), + ("c:identifier", "XML_CharacterDataHandler"), + ("c:identifier", "XML_CommentHandler"), + ("c:identifier", "XML_DefaultHandler"), + ("c:identifier", "XML_Encoding"), + ("c:identifier", "XML_EndElementHandler"), + ("c:identifier", "XML_EndNamespaceDeclHandler"), + ("c:identifier", "XML_Error"), + ("c:identifier", "XML_LChar"), + ("c:identifier", "XML_Memory_Handling_Suite"), + ("c:identifier", "XML_Parser"), + ("c:identifier", "XML_ProcessingInstructionHandler"), + ("c:identifier", "XML_Size"), + ("c:identifier", "XML_StartDoctypeDeclHandler"), + ("c:identifier", "XML_StartElementHandler"), + ("c:identifier", "XML_StartNamespaceDeclHandler"), + ("c:identifier", "XML_Status"), + ("c:identifier", "XML_UnknownEncodingHandler"), +] + # Temporary undocumented names. # In future this list must be empty. nitpick_ignore += [ From 1c51a143126491a1f3983d72b755072f1213d415 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sat, 8 Nov 2025 18:54:16 +0100 Subject: [PATCH 3/9] simplify instructions --- Doc/c-api/expat.rst | 23 ++++++++++++++--------- Include/pyexpat.h | 17 ++++++++++++++--- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/Doc/c-api/expat.rst b/Doc/c-api/expat.rst index 3514f8d42036ef..014dd84f0ca9d6 100644 --- a/Doc/c-api/expat.rst +++ b/Doc/c-api/expat.rst @@ -15,20 +15,25 @@ the module state: struct PyExpat_CAPI *capi = NULL; capi = (struct PyExpat_CAPI *)PyCapsule_Import(PyExpat_CAPSULE_NAME, 0); - if (capi == NULL) { goto error; } - - /* check if the C API is compatible with the version of Expat version */ - if (strcmp(capi->magic, PyExpat_CAPI_MAGIC) != 0 - || (size_t)capi->size < sizeof(struct PyExpat_CAPI) - || capi->MAJOR_VERSION != XML_MAJOR_VERSION - || capi->MINOR_VERSION != XML_MINOR_VERSION - || capi->MICRO_VERSION != XML_MICRO_VERSION - ) { + if (capi == NULL) { + goto error; + } + if (!PyExpat_CheckCompatibility(capi)) { PyErr_SetString(PyExc_ImportError, "pyexpat version is incompatible"); goto error; } +.. c:function:: int PyExpat_CheckCompatibility(struct PyExpat_API *api) + + Return ``1`` if *api* is compatible with the linked Expat library, + and ``0`` otherwise. This function never sets a Python exception. + + *api* must not be ``NULL``. + + .. versionadded:: next + + .. c:macro:: PyExpat_CAPI_MAGIC The Expat C API magic number. diff --git a/Include/pyexpat.h b/Include/pyexpat.h index f523f8bb273983..b418331623e531 100644 --- a/Include/pyexpat.h +++ b/Include/pyexpat.h @@ -6,9 +6,8 @@ #define PyExpat_CAPI_MAGIC "pyexpat.expat_CAPI 1.1" #define PyExpat_CAPSULE_NAME "pyexpat.expat_CAPI" -struct PyExpat_CAPI -{ - char* magic; /* set to PyExpat_CAPI_MAGIC */ +struct PyExpat_CAPI { + char *magic; /* set to PyExpat_CAPI_MAGIC */ int size; /* set to sizeof(struct PyExpat_CAPI) */ int MAJOR_VERSION; int MINOR_VERSION; @@ -65,3 +64,15 @@ struct PyExpat_CAPI /* always add new stuff to the end! */ }; +static inline int +PyExpat_CheckCompatibility(struct PyExpat_CAPI *api) +{ + return ( + api != NULL + && strcmp(api->magic, PyExpat_CAPI_MAGIC) == 0 + && (size_t)api->size >= sizeof(struct PyExpat_CAPI) + && api->MAJOR_VERSION == XML_MAJOR_VERSION + && api->MINOR_VERSION == XML_MINOR_VERSION + && api->MICRO_VERSION == XML_MICRO_VERSION + ); +} From cf35d7183bcedee13b31226baf8f6cd9501ece02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sat, 8 Nov 2025 18:59:18 +0100 Subject: [PATCH 4/9] fixup --- Doc/c-api/expat.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/c-api/expat.rst b/Doc/c-api/expat.rst index 014dd84f0ca9d6..fca35dd2e22b77 100644 --- a/Doc/c-api/expat.rst +++ b/Doc/c-api/expat.rst @@ -24,7 +24,7 @@ the module state: } -.. c:function:: int PyExpat_CheckCompatibility(struct PyExpat_API *api) +.. c:function:: int PyExpat_CheckCompatibility(struct PyExpat_CAPI *api) Return ``1`` if *api* is compatible with the linked Expat library, and ``0`` otherwise. This function never sets a Python exception. From e7e0a7db32448fc4460432866bc5a5f5dfe6ca37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sat, 8 Nov 2025 19:00:58 +0100 Subject: [PATCH 5/9] NULL --- Include/pyexpat.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Include/pyexpat.h b/Include/pyexpat.h index b418331623e531..fb43434f16a869 100644 --- a/Include/pyexpat.h +++ b/Include/pyexpat.h @@ -67,9 +67,9 @@ struct PyExpat_CAPI { static inline int PyExpat_CheckCompatibility(struct PyExpat_CAPI *api) { + assert(api != NULL); return ( - api != NULL - && strcmp(api->magic, PyExpat_CAPI_MAGIC) == 0 + strcmp(api->magic, PyExpat_CAPI_MAGIC) == 0 && (size_t)api->size >= sizeof(struct PyExpat_CAPI) && api->MAJOR_VERSION == XML_MAJOR_VERSION && api->MINOR_VERSION == XML_MINOR_VERSION From 660a1a1d4fe8caec405d27ff999e1c7e7b55ebc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sun, 9 Nov 2025 15:11:51 +0100 Subject: [PATCH 6/9] address review --- Doc/c-api/expat.rst | 30 +++++++++++++---------------- Doc/conf.py | 47 +++++++++++++++++++++++---------------------- Include/pyexpat.h | 13 ------------- 3 files changed, 37 insertions(+), 53 deletions(-) diff --git a/Doc/c-api/expat.rst b/Doc/c-api/expat.rst index fca35dd2e22b77..f5a0284bf6fe1a 100644 --- a/Doc/c-api/expat.rst +++ b/Doc/c-api/expat.rst @@ -18,22 +18,18 @@ the module state: if (capi == NULL) { goto error; } - if (!PyExpat_CheckCompatibility(capi)) { + if (!( + strcmp(capi->magic, PyExpat_CAPI_MAGIC) == 0 + && (size_t)capi->size >= sizeof(struct PyExpat_CAPI) + && capi->MAJOR_VERSION == XML_MAJOR_VERSION + && capi->MINOR_VERSION == XML_MINOR_VERSION + && capi->MICRO_VERSION == XML_MICRO_VERSION + )) { PyErr_SetString(PyExc_ImportError, "pyexpat version is incompatible"); goto error; } -.. c:function:: int PyExpat_CheckCompatibility(struct PyExpat_CAPI *api) - - Return ``1`` if *api* is compatible with the linked Expat library, - and ``0`` otherwise. This function never sets a Python exception. - - *api* must not be ``NULL``. - - .. versionadded:: next - - .. c:macro:: PyExpat_CAPI_MAGIC The Expat C API magic number. @@ -148,7 +144,7 @@ the module state: XML_Parser parser,\ unsigned long hash_salt) - Might be NULL for Expat versions prior to 2.1.0. + Might be ``NULL`` for Expat versions prior to 2.1.0. .. versionadded:: 3.4 @@ -156,7 +152,7 @@ the module state: XML_Parser parser,\ XML_Bool enabled) - Might be NULL for Expat versions prior to 2.6.0. + Might be ``NULL`` for Expat versions prior to 2.6.0. .. versionadded:: 3.8 @@ -164,7 +160,7 @@ the module state: XML_Parser parser,\ unsigned long long activationThresholdBytes) - Might be NULL for Expat versions prior to 2.7.2. + Might be ``NULL`` for Expat versions prior to 2.7.2. .. uncomment this when the backport is done .. versionadded:: 3.10 @@ -173,7 +169,7 @@ the module state: XML_Parser parser,\ float maxAmplificationFactor) - Might be NULL for Expat versions prior to 2.7.2. + Might be ``NULL`` for Expat versions prior to 2.7.2. .. uncomment this when the backport is done .. versionadded:: 3.10 @@ -182,7 +178,7 @@ the module state: XML_Parser parser,\ unsigned long long activationThresholdBytes) - Might be NULL for Expat versions prior to 2.4.0. + Might be ``NULL`` for Expat versions prior to 2.4.0. .. uncomment this when the backport is done .. versionadded:: 3.10 @@ -191,7 +187,7 @@ the module state: XML_Parser parser,\ float maxAmplificationFactor) - Might be NULL for Expat versions prior to 2.4.0. + Might be ``NULL`` for Expat versions prior to 2.4.0. .. uncomment this when the backport is done .. versionadded:: 3.10 diff --git a/Doc/conf.py b/Doc/conf.py index 7e5a45f8f5e0f2..7de0bf6703c2fd 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -223,29 +223,6 @@ ('envvar', 'USERPROFILE'), ] -# Vendored types -nitpick_ignore += [ - ("c:identifier", "XML_Bool"), - ("c:identifier", "XML_Char"), - ("c:identifier", "XML_CharacterDataHandler"), - ("c:identifier", "XML_CommentHandler"), - ("c:identifier", "XML_DefaultHandler"), - ("c:identifier", "XML_Encoding"), - ("c:identifier", "XML_EndElementHandler"), - ("c:identifier", "XML_EndNamespaceDeclHandler"), - ("c:identifier", "XML_Error"), - ("c:identifier", "XML_LChar"), - ("c:identifier", "XML_Memory_Handling_Suite"), - ("c:identifier", "XML_Parser"), - ("c:identifier", "XML_ProcessingInstructionHandler"), - ("c:identifier", "XML_Size"), - ("c:identifier", "XML_StartDoctypeDeclHandler"), - ("c:identifier", "XML_StartElementHandler"), - ("c:identifier", "XML_StartNamespaceDeclHandler"), - ("c:identifier", "XML_Status"), - ("c:identifier", "XML_UnknownEncodingHandler"), -] - # Temporary undocumented names. # In future this list must be empty. nitpick_ignore += [ @@ -270,6 +247,30 @@ nitpick_ignore.append(('c:identifier', name)) del role, name +# Vendored identifiers. The list does not need to be empty. +c_id_attributes = [ + # used in c-api/expat.rst + "XML_Bool", + "XML_Char", + "XML_CharacterDataHandler", + "XML_CommentHandler", + "XML_DefaultHandler", + "XML_Encoding", + "XML_EndElementHandler", + "XML_EndNamespaceDeclHandler", + "XML_Error", + "XML_LChar", + "XML_Memory_Handling_Suite", + "XML_Parser", + "XML_ProcessingInstructionHandler", + "XML_Size", + "XML_StartDoctypeDeclHandler", + "XML_StartElementHandler", + "XML_StartNamespaceDeclHandler", + "XML_Status", + "XML_UnknownEncodingHandler", +] + # Disable Docutils smartquotes for several translations smartquotes_excludes = { 'languages': ['ja', 'fr', 'zh_TW', 'zh_CN'], diff --git a/Include/pyexpat.h b/Include/pyexpat.h index fb43434f16a869..25905e96c6f1c2 100644 --- a/Include/pyexpat.h +++ b/Include/pyexpat.h @@ -63,16 +63,3 @@ struct PyExpat_CAPI { XML_Parser parser, float maxAmplificationFactor); /* always add new stuff to the end! */ }; - -static inline int -PyExpat_CheckCompatibility(struct PyExpat_CAPI *api) -{ - assert(api != NULL); - return ( - strcmp(api->magic, PyExpat_CAPI_MAGIC) == 0 - && (size_t)api->size >= sizeof(struct PyExpat_CAPI) - && api->MAJOR_VERSION == XML_MAJOR_VERSION - && api->MINOR_VERSION == XML_MINOR_VERSION - && api->MICRO_VERSION == XML_MICRO_VERSION - ); -} From cba5d4c220393152d3a9da924700f664c4f75306 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sun, 9 Nov 2025 15:19:14 +0100 Subject: [PATCH 7/9] nevermind, `c_id_attributes` isn't for that --- Doc/conf.py | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/Doc/conf.py b/Doc/conf.py index 7de0bf6703c2fd..a84d2cd278ca13 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -223,6 +223,30 @@ ('envvar', 'USERPROFILE'), ] +# Vendored identifiers without intersphinx support. +nitpick_ignore += [ + # used in c-api/expat.rst + ('c:identifier', 'XML_Bool'), + ('c:identifier', 'XML_Char'), + ('c:identifier', 'XML_CharacterDataHandler'), + ('c:identifier', 'XML_CommentHandler'), + ('c:identifier', 'XML_DefaultHandler'), + ('c:identifier', 'XML_Encoding'), + ('c:identifier', 'XML_EndElementHandler'), + ('c:identifier', 'XML_EndNamespaceDeclHandler'), + ('c:identifier', 'XML_Error'), + ('c:identifier', 'XML_LChar'), + ('c:identifier', 'XML_Memory_Handling_Suite'), + ('c:identifier', 'XML_Parser'), + ('c:identifier', 'XML_ProcessingInstructionHandler'), + ('c:identifier', 'XML_Size'), + ('c:identifier', 'XML_StartDoctypeDeclHandler'), + ('c:identifier', 'XML_StartElementHandler'), + ('c:identifier', 'XML_StartNamespaceDeclHandler'), + ('c:identifier', 'XML_Status'), + ('c:identifier', 'XML_UnknownEncodingHandler'), +] + # Temporary undocumented names. # In future this list must be empty. nitpick_ignore += [ @@ -247,30 +271,6 @@ nitpick_ignore.append(('c:identifier', name)) del role, name -# Vendored identifiers. The list does not need to be empty. -c_id_attributes = [ - # used in c-api/expat.rst - "XML_Bool", - "XML_Char", - "XML_CharacterDataHandler", - "XML_CommentHandler", - "XML_DefaultHandler", - "XML_Encoding", - "XML_EndElementHandler", - "XML_EndNamespaceDeclHandler", - "XML_Error", - "XML_LChar", - "XML_Memory_Handling_Suite", - "XML_Parser", - "XML_ProcessingInstructionHandler", - "XML_Size", - "XML_StartDoctypeDeclHandler", - "XML_StartElementHandler", - "XML_StartNamespaceDeclHandler", - "XML_Status", - "XML_UnknownEncodingHandler", -] - # Disable Docutils smartquotes for several translations smartquotes_excludes = { 'languages': ['ja', 'fr', 'zh_TW', 'zh_CN'], From 50575b583783726f48e6d837b54dbf0d9682ae54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sun, 9 Nov 2025 16:57:08 +0100 Subject: [PATCH 8/9] fixup --- Doc/c-api/concrete.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/c-api/concrete.rst b/Doc/c-api/concrete.rst index a41b7743e5cc45..e0d133ea593d91 100644 --- a/Doc/c-api/concrete.rst +++ b/Doc/c-api/concrete.rst @@ -125,4 +125,4 @@ C API for extension modules curses.rst datetime.rst - expat.rst \ No newline at end of file + expat.rst From e6c452c27768241184a2c8f991a7b64e7cd05a9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sun, 9 Nov 2025 16:58:54 +0100 Subject: [PATCH 9/9] fix markup --- Doc/c-api/expat.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/c-api/expat.rst b/Doc/c-api/expat.rst index f5a0284bf6fe1a..93b5cbcbf7c3d4 100644 --- a/Doc/c-api/expat.rst +++ b/Doc/c-api/expat.rst @@ -3,7 +3,7 @@ Expat C API ----------- -:mod:`!pyexpat exposes a C interface for extension modules. +:mod:`!pyexpat` exposes a C interface for extension modules. Consumers must include the header file :file:`pyexpat.h` (which is not included by default by :file:`Python.h`) and ``expat.h`` for Expat.