[Python-checkins] GH-103092: isolate `_elementtree` (#104561)

kumaraditya303 webhook-mailer at python.org
Tue May 16 19:35:14 EDT 2023


https://github.com/python/cpython/commit/1b5a2b085c28d230c9ef9bd9b472afc85e087ced
commit: 1b5a2b085c28d230c9ef9bd9b472afc85e087ced
branch: main
author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com>
committer: kumaraditya303 <59607654+kumaraditya303 at users.noreply.github.com>
date: 2023-05-17T05:05:07+05:30
summary:

GH-103092: isolate `_elementtree` (#104561)

files:
M Modules/_elementtree.c

diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c
index 42de3c675c2e..00d9f647ccfd 100644
--- a/Modules/_elementtree.c
+++ b/Modules/_elementtree.c
@@ -15,6 +15,8 @@
 
 #include "Python.h"
 #include "structmember.h"         // PyMemberDef
+#include "expat.h"
+#include "pyexpat.h"
 
 /* -------------------------------------------------------------------- */
 /* configuration */
@@ -90,6 +92,8 @@ typedef struct {
     PyTypeObject *ElementIter_Type;
     PyTypeObject *TreeBuilder_Type;
     PyTypeObject *XMLParser_Type;
+
+    struct PyExpat_CAPI *expat_capi;
 } elementtreestate;
 
 static struct PyModuleDef elementtreemodule;
@@ -146,6 +150,8 @@ elementtree_clear(PyObject *m)
     Py_CLEAR(st->ElementIter_Type);
     Py_CLEAR(st->TreeBuilder_Type);
     Py_CLEAR(st->XMLParser_Type);
+
+    st->expat_capi = NULL;
     return 0;
 }
 
@@ -3031,14 +3037,7 @@ _elementtree_TreeBuilder_start_impl(TreeBuilderObject *self, PyObject *tag,
 /* ==================================================================== */
 /* the expat interface */
 
-#include "expat.h"
-#include "pyexpat.h"
-
-/* The PyExpat_CAPI structure is an immutable dispatch table, so it can be
- * cached globally without being in per-module state.
- */
-static struct PyExpat_CAPI *expat_capi;
-#define EXPAT(func) (expat_capi->func)
+#define EXPAT(st, func) ((st)->expat_capi->func)
 
 static XML_Memory_Handling_Suite ExpatMemoryHandler = {
     PyObject_Malloc, PyObject_Realloc, PyObject_Free};
@@ -3147,7 +3146,7 @@ expat_set_error(elementtreestate *st, enum XML_Error error_code,
     PyObject *errmsg, *error, *position, *code;
 
     errmsg = PyUnicode_FromFormat("%s: line %zd, column %zd",
-                message ? message : EXPAT(ErrorString)(error_code),
+                message ? message : EXPAT(st, ErrorString)(error_code),
                 line, column);
     if (errmsg == NULL)
         return;
@@ -3227,8 +3226,8 @@ expat_default_handler(XMLParserObject* self, const XML_Char* data_in,
         expat_set_error(
             st,
             XML_ERROR_UNDEFINED_ENTITY,
-            EXPAT(GetErrorLineNumber)(self->parser),
-            EXPAT(GetErrorColumnNumber)(self->parser),
+            EXPAT(st, GetErrorLineNumber)(self->parser),
+            EXPAT(st, GetErrorColumnNumber)(self->parser),
             message
             );
     }
@@ -3648,8 +3647,8 @@ _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target,
         Py_CLEAR(self->entity);
         return -1;
     }
-
-    self->parser = EXPAT(ParserCreate_MM)(encoding, &ExpatMemoryHandler, "}");
+    elementtreestate *st = self->state;
+    self->parser = EXPAT(st, ParserCreate_MM)(encoding, &ExpatMemoryHandler, "}");
     if (!self->parser) {
         Py_CLEAR(self->entity);
         Py_CLEAR(self->names);
@@ -3657,15 +3656,14 @@ _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target,
         return -1;
     }
     /* expat < 2.1.0 has no XML_SetHashSalt() */
-    if (EXPAT(SetHashSalt) != NULL) {
-        EXPAT(SetHashSalt)(self->parser,
+    if (EXPAT(st, SetHashSalt) != NULL) {
+        EXPAT(st, SetHashSalt)(self->parser,
                            (unsigned long)_Py_HashSecret.expat.hashsalt);
     }
 
     if (target != Py_None) {
         Py_INCREF(target);
     } else {
-        elementtreestate *st = self->state;
         target = treebuilder_new(st->TreeBuilder_Type, NULL, NULL);
         if (!target) {
             Py_CLEAR(self->entity);
@@ -3713,43 +3711,43 @@ _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target,
     }
 
     /* configure parser */
-    EXPAT(SetUserData)(self->parser, self);
+    EXPAT(st, SetUserData)(self->parser, self);
     if (self->handle_start_ns || self->handle_end_ns)
-        EXPAT(SetNamespaceDeclHandler)(
+        EXPAT(st, SetNamespaceDeclHandler)(
             self->parser,
             (XML_StartNamespaceDeclHandler) expat_start_ns_handler,
             (XML_EndNamespaceDeclHandler) expat_end_ns_handler
             );
-    EXPAT(SetElementHandler)(
+    EXPAT(st, SetElementHandler)(
         self->parser,
         (XML_StartElementHandler) expat_start_handler,
         (XML_EndElementHandler) expat_end_handler
         );
-    EXPAT(SetDefaultHandlerExpand)(
+    EXPAT(st, SetDefaultHandlerExpand)(
         self->parser,
         (XML_DefaultHandler) expat_default_handler
         );
-    EXPAT(SetCharacterDataHandler)(
+    EXPAT(st, SetCharacterDataHandler)(
         self->parser,
         (XML_CharacterDataHandler) expat_data_handler
         );
     if (self->handle_comment)
-        EXPAT(SetCommentHandler)(
+        EXPAT(st, SetCommentHandler)(
             self->parser,
             (XML_CommentHandler) expat_comment_handler
             );
     if (self->handle_pi)
-        EXPAT(SetProcessingInstructionHandler)(
+        EXPAT(st, SetProcessingInstructionHandler)(
             self->parser,
             (XML_ProcessingInstructionHandler) expat_pi_handler
             );
-    EXPAT(SetStartDoctypeDeclHandler)(
+    EXPAT(st, SetStartDoctypeDeclHandler)(
         self->parser,
         (XML_StartDoctypeDeclHandler) expat_start_doctype_handler
         );
-    EXPAT(SetUnknownEncodingHandler)(
+    EXPAT(st, SetUnknownEncodingHandler)(
         self->parser,
-        EXPAT(DefaultUnknownEncodingHandler), NULL
+        EXPAT(st, DefaultUnknownEncodingHandler), NULL
         );
 
     return 0;
@@ -3779,10 +3777,11 @@ xmlparser_gc_traverse(XMLParserObject *self, visitproc visit, void *arg)
 static int
 xmlparser_gc_clear(XMLParserObject *self)
 {
+    elementtreestate *st = self->state;
     if (self->parser != NULL) {
         XML_Parser parser = self->parser;
         self->parser = NULL;
-        EXPAT(ParserFree)(parser);
+        EXPAT(st, ParserFree)(parser);
     }
 
     Py_CLEAR(self->handle_close);
@@ -3830,7 +3829,7 @@ expat_parse(elementtreestate *st, XMLParserObject *self, const char *data,
     int ok;
 
     assert(!PyErr_Occurred());
-    ok = EXPAT(Parse)(self->parser, data, data_len, final);
+    ok = EXPAT(st, Parse)(self->parser, data, data_len, final);
 
     if (PyErr_Occurred())
         return NULL;
@@ -3838,9 +3837,9 @@ expat_parse(elementtreestate *st, XMLParserObject *self, const char *data,
     if (!ok) {
         expat_set_error(
             st,
-            EXPAT(GetErrorCode)(self->parser),
-            EXPAT(GetErrorLineNumber)(self->parser),
-            EXPAT(GetErrorColumnNumber)(self->parser),
+            EXPAT(st, GetErrorCode)(self->parser),
+            EXPAT(st, GetErrorLineNumber)(self->parser),
+            EXPAT(st, GetErrorColumnNumber)(self->parser),
             NULL
             );
         return NULL;
@@ -3911,7 +3910,7 @@ _elementtree_XMLParser_feed(XMLParserObject *self, PyObject *data)
             return NULL;
         }
         /* Explicitly set UTF-8 encoding. Return code ignored. */
-        (void)EXPAT(SetEncoding)(self->parser, "utf-8");
+        (void)EXPAT(st, SetEncoding)(self->parser, "utf-8");
 
         return expat_parse(st, self, data_ptr, (int)data_len, 0);
     }
@@ -4099,27 +4098,27 @@ _elementtree_XMLParser__setevents_impl(XMLParserObject *self,
             Py_XSETREF(target->end_event_obj, Py_NewRef(event_name_obj));
         } else if (strcmp(event_name, "start-ns") == 0) {
             Py_XSETREF(target->start_ns_event_obj, Py_NewRef(event_name_obj));
-            EXPAT(SetNamespaceDeclHandler)(
+            EXPAT(st, SetNamespaceDeclHandler)(
                 self->parser,
                 (XML_StartNamespaceDeclHandler) expat_start_ns_handler,
                 (XML_EndNamespaceDeclHandler) expat_end_ns_handler
                 );
         } else if (strcmp(event_name, "end-ns") == 0) {
             Py_XSETREF(target->end_ns_event_obj, Py_NewRef(event_name_obj));
-            EXPAT(SetNamespaceDeclHandler)(
+            EXPAT(st, SetNamespaceDeclHandler)(
                 self->parser,
                 (XML_StartNamespaceDeclHandler) expat_start_ns_handler,
                 (XML_EndNamespaceDeclHandler) expat_end_ns_handler
                 );
         } else if (strcmp(event_name, "comment") == 0) {
             Py_XSETREF(target->comment_event_obj, Py_NewRef(event_name_obj));
-            EXPAT(SetCommentHandler)(
+            EXPAT(st, SetCommentHandler)(
                 self->parser,
                 (XML_CommentHandler) expat_comment_handler
                 );
         } else if (strcmp(event_name, "pi") == 0) {
             Py_XSETREF(target->pi_event_obj, Py_NewRef(event_name_obj));
-            EXPAT(SetProcessingInstructionHandler)(
+            EXPAT(st, SetProcessingInstructionHandler)(
                 self->parser,
                 (XML_ProcessingInstructionHandler) expat_pi_handler
                 );
@@ -4344,14 +4343,14 @@ module_exec(PyObject *m)
         goto error;
 
     /* link against pyexpat */
-    expat_capi = PyCapsule_Import(PyExpat_CAPSULE_NAME, 0);
-    if (expat_capi) {
+    st->expat_capi = PyCapsule_Import(PyExpat_CAPSULE_NAME, 0);
+    if (st->expat_capi) {
         /* check that it's usable */
-        if (strcmp(expat_capi->magic, PyExpat_CAPI_MAGIC) != 0 ||
-            (size_t)expat_capi->size < sizeof(struct PyExpat_CAPI) ||
-            expat_capi->MAJOR_VERSION != XML_MAJOR_VERSION ||
-            expat_capi->MINOR_VERSION != XML_MINOR_VERSION ||
-            expat_capi->MICRO_VERSION != XML_MICRO_VERSION) {
+        if (strcmp(st->expat_capi->magic, PyExpat_CAPI_MAGIC) != 0 ||
+            (size_t)st->expat_capi->size < sizeof(struct PyExpat_CAPI) ||
+            st->expat_capi->MAJOR_VERSION != XML_MAJOR_VERSION ||
+            st->expat_capi->MINOR_VERSION != XML_MINOR_VERSION ||
+            st->expat_capi->MICRO_VERSION != XML_MICRO_VERSION) {
             PyErr_SetString(PyExc_ImportError,
                             "pyexpat version is incompatible");
             goto error;



More information about the Python-checkins mailing list