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

This commit is contained in:
Serhiy Storchaka 2020-03-09 15:12:41 +02:00 committed by GitHub
parent 88944a44aa
commit dccd41e29f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 41 deletions

View file

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

View file

@ -515,6 +515,10 @@ _elementtree_Element_makeelement(ElementObject *self, PyObject *const *args, Py_
goto exit; goto exit;
} }
tag = args[0]; tag = args[0];
if (!PyDict_Check(args[1])) {
_PyArg_BadArgument("makeelement", "argument 2", "dict", args[1]);
goto exit;
}
attrib = args[1]; attrib = args[1];
return_value = _elementtree_Element_makeelement_impl(self, tag, attrib); return_value = _elementtree_Element_makeelement_impl(self, tag, attrib);
@ -916,4 +920,4 @@ skip_optional:
exit: exit:
return return_value; return return_value;
} }
/*[clinic end generated code: output=3ad029ba71f5ae39 input=a9049054013a1b77]*/ /*[clinic end generated code: output=b7f6a32462fc42a9 input=a9049054013a1b77]*/