[Python-checkins] bpo-39822: Use NULL instead of None for empty attrib in Element. (GH-18735)

Serhiy Storchaka webhook-mailer at python.org
Mon Mar 9 09:13:01 EDT 2020


https://github.com/python/cpython/commit/dccd41e29fb9e75ac53c04ed3b097f51f8f65c4e
commit: dccd41e29fb9e75ac53c04ed3b097f51f8f65c4e
branch: master
author: Serhiy Storchaka <storchaka at gmail.com>
committer: GitHub <noreply at github.com>
date: 2020-03-09T15:12:41+02:00
summary:

bpo-39822: Use NULL instead of None for empty attrib in Element. (GH-18735)

files:
M Modules/_elementtree.c
M Modules/clinic/_elementtree.c.h

diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c
index 0d3112a113da0..2d6f26b3df087 100644
--- a/Modules/_elementtree.c
+++ b/Modules/_elementtree.c
@@ -170,7 +170,7 @@ is_empty_dict(PyObject *obj)
 
 typedef struct {
 
-    /* attributes (a dictionary object), or None if no attributes */
+    /* attributes (a dictionary object), or NULL if no attributes */
     PyObject* attrib;
 
     /* child elements */
@@ -225,10 +225,7 @@ create_extra(ElementObject* self, PyObject* attrib)
         return -1;
     }
 
-    if (!attrib)
-        attrib = Py_None;
-
-    Py_INCREF(attrib);
+    Py_XINCREF(attrib);
     self->extra->attrib = attrib;
 
     self->extra->length = 0;
@@ -246,7 +243,7 @@ dealloc_extra(ElementObjectExtra *extra)
     if (!extra)
         return;
 
-    Py_DECREF(extra->attrib);
+    Py_XDECREF(extra->attrib);
 
     for (i = 0; i < extra->length; i++)
         Py_DECREF(extra->children[i]);
@@ -300,7 +297,7 @@ create_new_element(PyObject* tag, PyObject* attrib)
     ALLOC(sizeof(ElementObject), "create element");
     PyObject_GC_Track(self);
 
-    if (attrib != Py_None && !is_empty_dict(attrib)) {
+    if (attrib != NULL && !is_empty_dict(attrib)) {
         if (create_extra(self, attrib) < 0) {
             Py_DECREF(self);
             return NULL;
@@ -530,13 +527,9 @@ element_get_attrib(ElementObject* self)
 
     PyObject* res = self->extra->attrib;
 
-    if (res == Py_None) {
+    if (!res) {
         /* create missing dictionary */
-        res = PyDict_New();
-        if (!res)
-            return NULL;
-        Py_DECREF(Py_None);
-        self->extra->attrib = res;
+        res = self->extra->attrib = PyDict_New();
     }
 
     return res;
@@ -616,12 +609,10 @@ subelement(PyObject *self, PyObject *args, PyObject *kwds)
             return NULL;
     } else {
         /* no attrib arg, no kwds, so no attribute */
-        Py_INCREF(Py_None);
-        attrib = Py_None;
     }
 
     elem = create_new_element(tag, attrib);
-    Py_DECREF(attrib);
+    Py_XDECREF(attrib);
     if (elem == NULL)
         return NULL;
 
@@ -736,7 +727,7 @@ _elementtree_Element___copy___impl(ElementObject *self)
     ElementObject* element;
 
     element = (ElementObject*) create_new_element(
-        self->tag, (self->extra) ? self->extra->attrib : Py_None);
+        self->tag, self->extra ? self->extra->attrib : NULL);
     if (!element)
         return NULL;
 
@@ -792,21 +783,20 @@ _elementtree_Element___deepcopy___impl(ElementObject *self, PyObject *memo)
     if (!tag)
         return NULL;
 
-    if (self->extra) {
+    if (self->extra && self->extra->attrib) {
         attrib = deepcopy(self->extra->attrib, memo);
         if (!attrib) {
             Py_DECREF(tag);
             return NULL;
         }
     } else {
-        Py_INCREF(Py_None);
-        attrib = Py_None;
+        attrib = NULL;
     }
 
     element = (ElementObject*) create_new_element(tag, attrib);
 
     Py_DECREF(tag);
-    Py_DECREF(attrib);
+    Py_XDECREF(attrib);
 
     if (!element)
         return NULL;
@@ -963,7 +953,7 @@ _elementtree_Element___getstate___impl(ElementObject *self)
         PyList_SET_ITEM(children, i, child);
     }
 
-    if (self->extra && self->extra->attrib != Py_None) {
+    if (self->extra && self->extra->attrib) {
         attrib = self->extra->attrib;
         Py_INCREF(attrib);
     }
@@ -1037,9 +1027,9 @@ element_setstate_from_attributes(ElementObject *self,
         assert(self->extra);
         assert(self->extra->allocated >= nchildren);
         if (oldextra) {
-            assert(self->extra->attrib == Py_None);
+            assert(self->extra->attrib == NULL);
             self->extra->attrib = oldextra->attrib;
-            oldextra->attrib = Py_None;
+            oldextra->attrib = NULL;
         }
 
         /* Copy children */
@@ -1065,10 +1055,8 @@ element_setstate_from_attributes(ElementObject *self,
     }
 
     /* Stash attrib. */
-    if (attrib) {
-        Py_INCREF(attrib);
-        Py_XSETREF(self->extra->attrib, attrib);
-    }
+    Py_XINCREF(attrib);
+    Py_XSETREF(self->extra->attrib, attrib);
     dealloc_extra(oldextra);
 
     Py_RETURN_NONE;
@@ -1401,7 +1389,7 @@ _elementtree_Element_get_impl(ElementObject *self, PyObject *key,
 {
     PyObject* value;
 
-    if (!self->extra || self->extra->attrib == Py_None)
+    if (!self->extra || !self->extra->attrib)
         value = default_value;
     else {
         value = PyDict_GetItemWithError(self->extra->attrib, key);
@@ -1529,7 +1517,7 @@ static PyObject *
 _elementtree_Element_items_impl(ElementObject *self)
 /*[clinic end generated code: output=6db2c778ce3f5a4d input=adbe09aaea474447]*/
 {
-    if (!self->extra || self->extra->attrib == Py_None)
+    if (!self->extra || !self->extra->attrib)
         return PyList_New(0);
 
     return PyDict_Items(self->extra->attrib);
@@ -1544,7 +1532,7 @@ static PyObject *
 _elementtree_Element_keys_impl(ElementObject *self)
 /*[clinic end generated code: output=bc5bfabbf20eeb3c input=f02caf5b496b5b0b]*/
 {
-    if (!self->extra || self->extra->attrib == Py_None)
+    if (!self->extra || !self->extra->attrib)
         return PyList_New(0);
 
     return PyDict_Keys(self->extra->attrib);
@@ -1563,7 +1551,7 @@ element_length(ElementObject* self)
 _elementtree.Element.makeelement
 
     tag: object
-    attrib: object
+    attrib: object(subclass_of='&PyDict_Type')
     /
 
 [clinic start generated code]*/
@@ -1571,7 +1559,7 @@ _elementtree.Element.makeelement
 static PyObject *
 _elementtree_Element_makeelement_impl(ElementObject *self, PyObject *tag,
                                       PyObject *attrib)
-/*[clinic end generated code: output=4109832d5bb789ef input=9480d1d2e3e68235]*/
+/*[clinic end generated code: output=4109832d5bb789ef input=2279d974529c3861]*/
 {
     PyObject* elem;
 
@@ -2043,12 +2031,18 @@ static int
 element_attrib_setter(ElementObject *self, PyObject *value, void *closure)
 {
     _VALIDATE_ATTR_VALUE(value);
+    if (!PyDict_Check(value)) {
+        PyErr_Format(PyExc_TypeError,
+                     "attrib must be dict, not %.200s",
+                     value->ob_type->tp_name);
+        return -1;
+    }
     if (!self->extra) {
         if (create_extra(self, NULL) < 0)
             return -1;
     }
     Py_INCREF(value);
-    Py_SETREF(self->extra->attrib, value);
+    Py_XSETREF(self->extra->attrib, value);
     return 0;
 }
 
@@ -2688,7 +2682,7 @@ treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag,
 
     if (!self->element_factory) {
         node = create_new_element(tag, attrib);
-    } else if (attrib == Py_None) {
+    } else if (attrib == NULL) {
         attrib = PyDict_New();
         if (!attrib)
             return NULL;
@@ -3297,8 +3291,7 @@ expat_start_handler(XMLParserObject* self, const XML_Char* tag_in,
             attrib_in += 2;
         }
     } else {
-        Py_INCREF(Py_None);
-        attrib = Py_None;
+        attrib = NULL;
     }
 
     if (TreeBuilder_CheckExact(self->target)) {
@@ -3307,8 +3300,7 @@ expat_start_handler(XMLParserObject* self, const XML_Char* tag_in,
                                        tag, attrib);
     }
     else if (self->handle_start) {
-        if (attrib == Py_None) {
-            Py_DECREF(attrib);
+        if (attrib == NULL) {
             attrib = PyDict_New();
             if (!attrib) {
                 Py_DECREF(tag);
@@ -3321,7 +3313,7 @@ expat_start_handler(XMLParserObject* self, const XML_Char* tag_in,
         res = NULL;
 
     Py_DECREF(tag);
-    Py_DECREF(attrib);
+    Py_XDECREF(attrib);
 
     Py_XDECREF(res);
 }
diff --git a/Modules/clinic/_elementtree.c.h b/Modules/clinic/_elementtree.c.h
index dae5233ee8d8a..825416f4a3982 100644
--- a/Modules/clinic/_elementtree.c.h
+++ b/Modules/clinic/_elementtree.c.h
@@ -515,6 +515,10 @@ _elementtree_Element_makeelement(ElementObject *self, PyObject *const *args, Py_
         goto exit;
     }
     tag = args[0];
+    if (!PyDict_Check(args[1])) {
+        _PyArg_BadArgument("makeelement", "argument 2", "dict", args[1]);
+        goto exit;
+    }
     attrib = args[1];
     return_value = _elementtree_Element_makeelement_impl(self, tag, attrib);
 
@@ -916,4 +920,4 @@ _elementtree_XMLParser__setevents(XMLParserObject *self, PyObject *const *args,
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=3ad029ba71f5ae39 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=b7f6a32462fc42a9 input=a9049054013a1b77]*/



More information about the Python-checkins mailing list