[Python-checkins] GH-92123: Pass _elementtree state as parameter (#101189)

erlend-aasland webhook-mailer at python.org
Tue Jan 24 06:46:01 EST 2023


https://github.com/python/cpython/commit/b2ac39626a13ae2fb14ec58ea0f0807e47f9910a
commit: b2ac39626a13ae2fb14ec58ea0f0807e47f9910a
branch: main
author: Erlend E. Aasland <erlend.aasland at protonmail.com>
committer: erlend-aasland <erlend.aasland at protonmail.com>
date: 2023-01-24T12:45:55+01:00
summary:

GH-92123: Pass _elementtree state as parameter (#101189)

files:
M Modules/_elementtree.c

diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c
index 8c94cf016106..f7ab8881723f 100644
--- a/Modules/_elementtree.c
+++ b/Modules/_elementtree.c
@@ -297,11 +297,10 @@ clear_extra(ElementObject* self)
  * tag and attributes.
 */
 LOCAL(PyObject*)
-create_new_element(PyObject* tag, PyObject* attrib)
+create_new_element(elementtreestate *st, PyObject *tag, PyObject *attrib)
 {
     ElementObject* self;
 
-    elementtreestate *st = ET_STATE_GLOBAL;
     self = PyObject_GC_New(ElementObject, st->Element_Type);
     if (self == NULL)
         return NULL;
@@ -504,10 +503,10 @@ raise_type_error(PyObject *element)
 }
 
 LOCAL(int)
-element_add_subelement(ElementObject* self, PyObject* element)
+element_add_subelement(elementtreestate *st, ElementObject *self,
+                       PyObject *element)
 {
     /* add a child element to a parent */
-    elementtreestate *st = ET_STATE_GLOBAL;
     if (!Element_Check(st, element)) {
         raise_type_error(element);
         return -1;
@@ -614,12 +613,12 @@ subelement(PyObject *self, PyObject *args, PyObject *kwds)
         /* no attrib arg, no kwds, so no attribute */
     }
 
-    elem = create_new_element(tag, attrib);
+    elem = create_new_element(st, tag, attrib);
     Py_XDECREF(attrib);
     if (elem == NULL)
         return NULL;
 
-    if (element_add_subelement(parent, elem) < 0) {
+    if (element_add_subelement(st, parent, elem) < 0) {
         Py_DECREF(elem);
         return NULL;
     }
@@ -694,7 +693,8 @@ static PyObject *
 _elementtree_Element_append_impl(ElementObject *self, PyObject *subelement)
 /*[clinic end generated code: output=54a884b7cf2295f4 input=439f2bd777288fb6]*/
 {
-    if (element_add_subelement(self, subelement) < 0)
+    elementtreestate *st = ET_STATE_GLOBAL;
+    if (element_add_subelement(st, self, subelement) < 0)
         return NULL;
 
     Py_RETURN_NONE;
@@ -728,9 +728,10 @@ _elementtree_Element___copy___impl(ElementObject *self)
 {
     Py_ssize_t i;
     ElementObject* element;
+    elementtreestate *st = ET_STATE_GLOBAL;
 
     element = (ElementObject*) create_new_element(
-        self->tag, self->extra ? self->extra->attrib : NULL);
+        st, self->tag, self->extra ? self->extra->attrib : NULL);
     if (!element)
         return NULL;
 
@@ -759,7 +760,7 @@ _elementtree_Element___copy___impl(ElementObject *self)
 }
 
 /* Helper for a deep copy. */
-LOCAL(PyObject *) deepcopy(PyObject *, PyObject *);
+LOCAL(PyObject *) deepcopy(elementtreestate *, PyObject *, PyObject *);
 
 /*[clinic input]
 _elementtree.Element.__deepcopy__
@@ -781,12 +782,13 @@ _elementtree_Element___deepcopy___impl(ElementObject *self, PyObject *memo)
     PyObject* tail;
     PyObject* id;
 
-    tag = deepcopy(self->tag, memo);
+    elementtreestate *st = ET_STATE_GLOBAL;
+    tag = deepcopy(st, self->tag, memo);
     if (!tag)
         return NULL;
 
     if (self->extra && self->extra->attrib) {
-        attrib = deepcopy(self->extra->attrib, memo);
+        attrib = deepcopy(st, self->extra->attrib, memo);
         if (!attrib) {
             Py_DECREF(tag);
             return NULL;
@@ -795,7 +797,7 @@ _elementtree_Element___deepcopy___impl(ElementObject *self, PyObject *memo)
         attrib = NULL;
     }
 
-    element = (ElementObject*) create_new_element(tag, attrib);
+    element = (ElementObject*) create_new_element(st, tag, attrib);
 
     Py_DECREF(tag);
     Py_XDECREF(attrib);
@@ -803,12 +805,12 @@ _elementtree_Element___deepcopy___impl(ElementObject *self, PyObject *memo)
     if (!element)
         return NULL;
 
-    text = deepcopy(JOIN_OBJ(self->text), memo);
+    text = deepcopy(st, JOIN_OBJ(self->text), memo);
     if (!text)
         goto error;
     _set_joined_ptr(&element->text, JOIN_SET(text, JOIN_GET(self->text)));
 
-    tail = deepcopy(JOIN_OBJ(self->tail), memo);
+    tail = deepcopy(st, JOIN_OBJ(self->tail), memo);
     if (!tail)
         goto error;
     _set_joined_ptr(&element->tail, JOIN_SET(tail, JOIN_GET(self->tail)));
@@ -818,9 +820,8 @@ _elementtree_Element___deepcopy___impl(ElementObject *self, PyObject *memo)
         if (element_resize(element, self->extra->length) < 0)
             goto error;
 
-        elementtreestate *st = ET_STATE_GLOBAL;
         for (i = 0; i < self->extra->length; i++) {
-            PyObject* child = deepcopy(self->extra->children[i], memo);
+            PyObject* child = deepcopy(st, self->extra->children[i], memo);
             if (!child || !Element_Check(st, child)) {
                 if (child) {
                     raise_type_error(child);
@@ -856,10 +857,9 @@ _elementtree_Element___deepcopy___impl(ElementObject *self, PyObject *memo)
 }
 
 LOCAL(PyObject *)
-deepcopy(PyObject *object, PyObject *memo)
+deepcopy(elementtreestate *st, PyObject *object, PyObject *memo)
 {
     /* do a deep copy of the given object */
-    elementtreestate *st = ET_STATE_GLOBAL;
     PyObject *stack[2];
 
     /* Fast paths */
@@ -974,7 +974,8 @@ _elementtree_Element___getstate___impl(ElementObject *self)
 }
 
 static PyObject *
-element_setstate_from_attributes(ElementObject *self,
+element_setstate_from_attributes(elementtreestate *st,
+                                 ElementObject *self,
                                  PyObject *tag,
                                  PyObject *attrib,
                                  PyObject *text,
@@ -1032,7 +1033,6 @@ element_setstate_from_attributes(ElementObject *self,
         }
 
         /* Copy children */
-        elementtreestate *st = ET_STATE_GLOBAL;
         for (i = 0; i < nchildren; i++) {
             PyObject *child = PyList_GET_ITEM(children, i);
             if (!Element_Check(st, child)) {
@@ -1065,7 +1065,8 @@ element_setstate_from_attributes(ElementObject *self,
  */
 
 static PyObject *
-element_setstate_from_Python(ElementObject *self, PyObject *state)
+element_setstate_from_Python(elementtreestate *st, ElementObject *self,
+                             PyObject *state)
 {
     static char *kwlist[] = {PICKLED_TAG, PICKLED_ATTRIB, PICKLED_TEXT,
                              PICKLED_TAIL, PICKLED_CHILDREN, 0};
@@ -1080,7 +1081,7 @@ element_setstate_from_Python(ElementObject *self, PyObject *state)
 
     if (PyArg_ParseTupleAndKeywords(args, state, "|$OOOOO", kwlist, &tag,
                                     &attrib, &text, &tail, &children))
-        retval = element_setstate_from_attributes(self, tag, attrib, text,
+        retval = element_setstate_from_attributes(st, self, tag, attrib, text,
                                                   tail, children);
     else
         retval = NULL;
@@ -1107,8 +1108,10 @@ _elementtree_Element___setstate__(ElementObject *self, PyObject *state)
                      state);
         return NULL;
     }
-    else
-        return element_setstate_from_Python(self, state);
+    else {
+        elementtreestate *st = ET_STATE_GLOBAL;
+        return element_setstate_from_Python(st, self, state);
+    }
 }
 
 LOCAL(int)
@@ -1190,9 +1193,10 @@ _elementtree_Element_extend(ElementObject *self, PyObject *elements)
         return NULL;
     }
 
+    elementtreestate *st = ET_STATE_GLOBAL;
     for (i = 0; i < PySequence_Fast_GET_SIZE(seq); i++) {
         PyObject* element = Py_NewRef(PySequence_Fast_GET_ITEM(seq, i));
-        if (element_add_subelement(self, element) < 0) {
+        if (element_add_subelement(st, self, element) < 0) {
             Py_DECREF(seq);
             Py_DECREF(element);
             return NULL;
@@ -1391,7 +1395,8 @@ _elementtree_Element_get_impl(ElementObject *self, PyObject *key,
 }
 
 static PyObject *
-create_elementiter(ElementObject *self, PyObject *tag, int gettext);
+create_elementiter(elementtreestate *st, ElementObject *self, PyObject *tag,
+                   int gettext);
 
 
 /*[clinic input]
@@ -1416,7 +1421,8 @@ _elementtree_Element_iter_impl(ElementObject *self, PyObject *tag)
             tag = Py_None;
     }
 
-    return create_elementiter(self, tag, 0);
+    elementtreestate *st = ET_STATE_GLOBAL;
+    return create_elementiter(st, self, tag, 0);
 }
 
 
@@ -1429,7 +1435,8 @@ static PyObject *
 _elementtree_Element_itertext_impl(ElementObject *self)
 /*[clinic end generated code: output=5fa34b2fbcb65df6 input=af8f0e42cb239c89]*/
 {
-    return create_elementiter(self, Py_None, 1);
+    elementtreestate *st = ET_STATE_GLOBAL;
+    return create_elementiter(st, self, Py_None, 1);
 }
 
 
@@ -1567,7 +1574,8 @@ _elementtree_Element_makeelement_impl(ElementObject *self, PyObject *tag,
     if (!attrib)
         return NULL;
 
-    elem = create_new_element(tag, attrib);
+    elementtreestate *st = ET_STATE_GLOBAL;
+    elem = create_new_element(st, tag, attrib);
 
     Py_DECREF(attrib);
 
@@ -2246,11 +2254,11 @@ static PyType_Spec elementiter_spec = {
 #define INIT_PARENT_STACK_SIZE 8
 
 static PyObject *
-create_elementiter(ElementObject *self, PyObject *tag, int gettext)
+create_elementiter(elementtreestate *st, ElementObject *self, PyObject *tag,
+                   int gettext)
 {
     ElementIterObject *it;
 
-    elementtreestate *st = ET_STATE_GLOBAL;
     it = PyObject_GC_New(ElementIterObject, st->ElementIter_Type);
     if (!it)
         return NULL;
@@ -2506,11 +2514,11 @@ _elementtree__set_factories_impl(PyObject *module, PyObject *comment_factory,
 }
 
 static int
-treebuilder_extend_element_text_or_tail(PyObject *element, PyObject **data,
-                                        PyObject **dest, PyObject *name)
+treebuilder_extend_element_text_or_tail(elementtreestate *st, PyObject *element,
+                                        PyObject **data, PyObject **dest,
+                                        PyObject *name)
 {
     /* Fast paths for the "almost always" cases. */
-    elementtreestate *st = ET_STATE_GLOBAL;
     if (Element_CheckExact(st, element)) {
         PyObject *dest_obj = JOIN_OBJ(*dest);
         if (dest_obj == Py_None) {
@@ -2570,24 +2578,24 @@ treebuilder_flush_data(TreeBuilderObject* self)
     if (!self->last_for_tail) {
         PyObject *element = self->last;
         return treebuilder_extend_element_text_or_tail(
-                element, &self->data,
+                st, element, &self->data,
                 &((ElementObject *) element)->text, st->str_text);
     }
     else {
         PyObject *element = self->last_for_tail;
         return treebuilder_extend_element_text_or_tail(
-                element, &self->data,
+                st, element, &self->data,
                 &((ElementObject *) element)->tail, st->str_tail);
     }
 }
 
 static int
-treebuilder_add_subelement(PyObject *element, PyObject *child)
+treebuilder_add_subelement(elementtreestate *st, PyObject *element,
+                           PyObject *child)
 {
-    elementtreestate *st = ET_STATE_GLOBAL;
     if (Element_CheckExact(st, element)) {
         ElementObject *elem = (ElementObject *) element;
-        return element_add_subelement(elem, child);
+        return element_add_subelement(st, elem, child);
     }
     else {
         PyObject *res;
@@ -2633,8 +2641,9 @@ treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag,
     }
 
     if (!self->element_factory) {
-        node = create_new_element(tag, attrib);
-    } else if (attrib == NULL) {
+        node = create_new_element(st, tag, attrib);
+    }
+    else if (attrib == NULL) {
         attrib = PyDict_New();
         if (!attrib)
             return NULL;
@@ -2654,8 +2663,9 @@ treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag,
     Py_CLEAR(self->last_for_tail);
 
     if (this != Py_None) {
-        if (treebuilder_add_subelement(this, node) < 0)
+        if (treebuilder_add_subelement(st, this, node) < 0) {
             goto error;
+        }
     } else {
         if (self->root) {
             PyErr_SetString(
@@ -2774,8 +2784,9 @@ treebuilder_handle_comment(TreeBuilderObject* self, PyObject* text)
 
         this = self->this;
         if (self->insert_comments && this != Py_None) {
-            if (treebuilder_add_subelement(this, comment) < 0)
+            if (treebuilder_add_subelement(self->state, this, comment) < 0) {
                 goto error;
+            }
             Py_XSETREF(self->last_for_tail, Py_NewRef(comment));
         }
     } else {
@@ -2813,8 +2824,9 @@ treebuilder_handle_pi(TreeBuilderObject* self, PyObject* target, PyObject* text)
 
         this = self->this;
         if (self->insert_pis && this != Py_None) {
-            if (treebuilder_add_subelement(this, pi) < 0)
+            if (treebuilder_add_subelement(self->state, this, pi) < 0) {
                 goto error;
+            }
             Py_XSETREF(self->last_for_tail, Py_NewRef(pi));
         }
     } else {
@@ -3091,11 +3103,10 @@ makeuniversal(XMLParserObject* self, const char* string)
  * message string is the default for the given error_code.
 */
 static void
-expat_set_error(enum XML_Error error_code, Py_ssize_t line, Py_ssize_t column,
-                const char *message)
+expat_set_error(elementtreestate *st, enum XML_Error error_code,
+                Py_ssize_t line, Py_ssize_t column, const char *message)
 {
     PyObject *errmsg, *error, *position, *code;
-    elementtreestate *st = ET_STATE_GLOBAL;
 
     errmsg = PyUnicode_FromFormat("%s: line %zd, column %zd",
                 message ? message : EXPAT(ErrorString)(error_code),
@@ -3160,8 +3171,8 @@ expat_default_handler(XMLParserObject* self, const XML_Char* data_in,
 
     value = PyDict_GetItemWithError(self->entity, key);
 
+    elementtreestate *st = self->state;
     if (value) {
-        elementtreestate *st = self->state;
         if (TreeBuilder_CheckExact(st, self->target))
             res = treebuilder_handle_data(
                 (TreeBuilderObject*) self->target, value
@@ -3176,6 +3187,7 @@ expat_default_handler(XMLParserObject* self, const XML_Char* data_in,
         char message[128] = "undefined entity ";
         strncat(message, data_in, data_len < 100?data_len:100);
         expat_set_error(
+            st,
             XML_ERROR_UNDEFINED_ENTITY,
             EXPAT(GetErrorLineNumber)(self->parser),
             EXPAT(GetErrorColumnNumber)(self->parser),
@@ -3774,7 +3786,8 @@ _check_xmlparser(XMLParserObject* self)
 }
 
 LOCAL(PyObject*)
-expat_parse(XMLParserObject* self, const char* data, int data_len, int final)
+expat_parse(elementtreestate *st, XMLParserObject *self, const char *data,
+            int data_len, int final)
 {
     int ok;
 
@@ -3786,6 +3799,7 @@ expat_parse(XMLParserObject* self, const char* data, int data_len, int final)
 
     if (!ok) {
         expat_set_error(
+            st,
             EXPAT(GetErrorCode)(self->parser),
             EXPAT(GetErrorLineNumber)(self->parser),
             EXPAT(GetErrorColumnNumber)(self->parser),
@@ -3813,11 +3827,11 @@ _elementtree_XMLParser_close_impl(XMLParserObject *self)
     if (!_check_xmlparser(self)) {
         return NULL;
     }
-    res = expat_parse(self, "", 0, 1);
+    elementtreestate *st = self->state;
+    res = expat_parse(st, self, "", 0, 1);
     if (!res)
         return NULL;
 
-    elementtreestate *st = self->state;
     if (TreeBuilder_CheckExact(st, self->target)) {
         Py_DECREF(res);
         return treebuilder_done((TreeBuilderObject*) self->target);
@@ -3848,6 +3862,7 @@ _elementtree_XMLParser_feed(XMLParserObject *self, PyObject *data)
     if (!_check_xmlparser(self)) {
         return NULL;
     }
+    elementtreestate *st = self->state;
     if (PyUnicode_Check(data)) {
         Py_ssize_t data_len;
         const char *data_ptr = PyUnicode_AsUTF8AndSize(data, &data_len);
@@ -3859,7 +3874,8 @@ _elementtree_XMLParser_feed(XMLParserObject *self, PyObject *data)
         }
         /* Explicitly set UTF-8 encoding. Return code ignored. */
         (void)EXPAT(SetEncoding)(self->parser, "utf-8");
-        return expat_parse(self, data_ptr, (int)data_len, 0);
+
+        return expat_parse(st, self, data_ptr, (int)data_len, 0);
     }
     else {
         Py_buffer view;
@@ -3871,7 +3887,7 @@ _elementtree_XMLParser_feed(XMLParserObject *self, PyObject *data)
             PyErr_SetString(PyExc_OverflowError, "size does not fit in an int");
             return NULL;
         }
-        res = expat_parse(self, view.buf, (int)view.len, 0);
+        res = expat_parse(st, self, view.buf, (int)view.len, 0);
         PyBuffer_Release(&view);
         return res;
     }
@@ -3903,6 +3919,7 @@ _elementtree_XMLParser__parse_whole(XMLParserObject *self, PyObject *file)
         return NULL;
 
     /* read from open file object */
+    elementtreestate *st = self->state;
     for (;;) {
 
         buffer = PyObject_CallFunction(reader, "i", 64*1024);
@@ -3940,8 +3957,8 @@ _elementtree_XMLParser__parse_whole(XMLParserObject *self, PyObject *file)
             return NULL;
         }
         res = expat_parse(
-            self, PyBytes_AS_STRING(buffer), (int)PyBytes_GET_SIZE(buffer), 0
-            );
+            st, self, PyBytes_AS_STRING(buffer), (int)PyBytes_GET_SIZE(buffer),
+            0);
 
         Py_DECREF(buffer);
 
@@ -3955,9 +3972,8 @@ _elementtree_XMLParser__parse_whole(XMLParserObject *self, PyObject *file)
 
     Py_DECREF(reader);
 
-    res = expat_parse(self, "", 0, 1);
+    res = expat_parse(st, self, "", 0, 1);
 
-    elementtreestate *st = self->state;
     if (res && TreeBuilder_CheckExact(st, self->target)) {
         Py_DECREF(res);
         return treebuilder_done((TreeBuilderObject*) self->target);



More information about the Python-checkins mailing list