diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 0d3112a113d..2d6f26b3df0 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 dae5233ee8d..825416f4a39 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 @@ skip_optional: exit: return return_value; } -/*[clinic end generated code: output=3ad029ba71f5ae39 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b7f6a32462fc42a9 input=a9049054013a1b77]*/