Skip to content

Commit dccd41e

Browse files
bpo-39822: Use NULL instead of None for empty attrib in Element. (pythonGH-18735)
1 parent 88944a4 commit dccd41e

File tree

2 files changed

+37
-41
lines changed

2 files changed

+37
-41
lines changed

Modules/_elementtree.c

+32-40
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ is_empty_dict(PyObject *obj)
170170

171171
typedef struct {
172172

173-
/* attributes (a dictionary object), or None if no attributes */
173+
/* attributes (a dictionary object), or NULL if no attributes */
174174
PyObject* attrib;
175175

176176
/* child elements */
@@ -225,10 +225,7 @@ create_extra(ElementObject* self, PyObject* attrib)
225225
return -1;
226226
}
227227

228-
if (!attrib)
229-
attrib = Py_None;
230-
231-
Py_INCREF(attrib);
228+
Py_XINCREF(attrib);
232229
self->extra->attrib = attrib;
233230

234231
self->extra->length = 0;
@@ -246,7 +243,7 @@ dealloc_extra(ElementObjectExtra *extra)
246243
if (!extra)
247244
return;
248245

249-
Py_DECREF(extra->attrib);
246+
Py_XDECREF(extra->attrib);
250247

251248
for (i = 0; i < extra->length; i++)
252249
Py_DECREF(extra->children[i]);
@@ -300,7 +297,7 @@ create_new_element(PyObject* tag, PyObject* attrib)
300297
ALLOC(sizeof(ElementObject), "create element");
301298
PyObject_GC_Track(self);
302299

303-
if (attrib != Py_None && !is_empty_dict(attrib)) {
300+
if (attrib != NULL && !is_empty_dict(attrib)) {
304301
if (create_extra(self, attrib) < 0) {
305302
Py_DECREF(self);
306303
return NULL;
@@ -530,13 +527,9 @@ element_get_attrib(ElementObject* self)
530527

531528
PyObject* res = self->extra->attrib;
532529

533-
if (res == Py_None) {
530+
if (!res) {
534531
/* create missing dictionary */
535-
res = PyDict_New();
536-
if (!res)
537-
return NULL;
538-
Py_DECREF(Py_None);
539-
self->extra->attrib = res;
532+
res = self->extra->attrib = PyDict_New();
540533
}
541534

542535
return res;
@@ -616,12 +609,10 @@ subelement(PyObject *self, PyObject *args, PyObject *kwds)
616609
return NULL;
617610
} else {
618611
/* no attrib arg, no kwds, so no attribute */
619-
Py_INCREF(Py_None);
620-
attrib = Py_None;
621612
}
622613

623614
elem = create_new_element(tag, attrib);
624-
Py_DECREF(attrib);
615+
Py_XDECREF(attrib);
625616
if (elem == NULL)
626617
return NULL;
627618

@@ -736,7 +727,7 @@ _elementtree_Element___copy___impl(ElementObject *self)
736727
ElementObject* element;
737728

738729
element = (ElementObject*) create_new_element(
739-
self->tag, (self->extra) ? self->extra->attrib : Py_None);
730+
self->tag, self->extra ? self->extra->attrib : NULL);
740731
if (!element)
741732
return NULL;
742733

@@ -792,21 +783,20 @@ _elementtree_Element___deepcopy___impl(ElementObject *self, PyObject *memo)
792783
if (!tag)
793784
return NULL;
794785

795-
if (self->extra) {
786+
if (self->extra && self->extra->attrib) {
796787
attrib = deepcopy(self->extra->attrib, memo);
797788
if (!attrib) {
798789
Py_DECREF(tag);
799790
return NULL;
800791
}
801792
} else {
802-
Py_INCREF(Py_None);
803-
attrib = Py_None;
793+
attrib = NULL;
804794
}
805795

806796
element = (ElementObject*) create_new_element(tag, attrib);
807797

808798
Py_DECREF(tag);
809-
Py_DECREF(attrib);
799+
Py_XDECREF(attrib);
810800

811801
if (!element)
812802
return NULL;
@@ -963,7 +953,7 @@ _elementtree_Element___getstate___impl(ElementObject *self)
963953
PyList_SET_ITEM(children, i, child);
964954
}
965955

966-
if (self->extra && self->extra->attrib != Py_None) {
956+
if (self->extra && self->extra->attrib) {
967957
attrib = self->extra->attrib;
968958
Py_INCREF(attrib);
969959
}
@@ -1037,9 +1027,9 @@ element_setstate_from_attributes(ElementObject *self,
10371027
assert(self->extra);
10381028
assert(self->extra->allocated >= nchildren);
10391029
if (oldextra) {
1040-
assert(self->extra->attrib == Py_None);
1030+
assert(self->extra->attrib == NULL);
10411031
self->extra->attrib = oldextra->attrib;
1042-
oldextra->attrib = Py_None;
1032+
oldextra->attrib = NULL;
10431033
}
10441034

10451035
/* Copy children */
@@ -1065,10 +1055,8 @@ element_setstate_from_attributes(ElementObject *self,
10651055
}
10661056

10671057
/* Stash attrib. */
1068-
if (attrib) {
1069-
Py_INCREF(attrib);
1070-
Py_XSETREF(self->extra->attrib, attrib);
1071-
}
1058+
Py_XINCREF(attrib);
1059+
Py_XSETREF(self->extra->attrib, attrib);
10721060
dealloc_extra(oldextra);
10731061

10741062
Py_RETURN_NONE;
@@ -1401,7 +1389,7 @@ _elementtree_Element_get_impl(ElementObject *self, PyObject *key,
14011389
{
14021390
PyObject* value;
14031391

1404-
if (!self->extra || self->extra->attrib == Py_None)
1392+
if (!self->extra || !self->extra->attrib)
14051393
value = default_value;
14061394
else {
14071395
value = PyDict_GetItemWithError(self->extra->attrib, key);
@@ -1529,7 +1517,7 @@ static PyObject *
15291517
_elementtree_Element_items_impl(ElementObject *self)
15301518
/*[clinic end generated code: output=6db2c778ce3f5a4d input=adbe09aaea474447]*/
15311519
{
1532-
if (!self->extra || self->extra->attrib == Py_None)
1520+
if (!self->extra || !self->extra->attrib)
15331521
return PyList_New(0);
15341522

15351523
return PyDict_Items(self->extra->attrib);
@@ -1544,7 +1532,7 @@ static PyObject *
15441532
_elementtree_Element_keys_impl(ElementObject *self)
15451533
/*[clinic end generated code: output=bc5bfabbf20eeb3c input=f02caf5b496b5b0b]*/
15461534
{
1547-
if (!self->extra || self->extra->attrib == Py_None)
1535+
if (!self->extra || !self->extra->attrib)
15481536
return PyList_New(0);
15491537

15501538
return PyDict_Keys(self->extra->attrib);
@@ -1563,15 +1551,15 @@ element_length(ElementObject* self)
15631551
_elementtree.Element.makeelement
15641552
15651553
tag: object
1566-
attrib: object
1554+
attrib: object(subclass_of='&PyDict_Type')
15671555
/
15681556
15691557
[clinic start generated code]*/
15701558

15711559
static PyObject *
15721560
_elementtree_Element_makeelement_impl(ElementObject *self, PyObject *tag,
15731561
PyObject *attrib)
1574-
/*[clinic end generated code: output=4109832d5bb789ef input=9480d1d2e3e68235]*/
1562+
/*[clinic end generated code: output=4109832d5bb789ef input=2279d974529c3861]*/
15751563
{
15761564
PyObject* elem;
15771565

@@ -2043,12 +2031,18 @@ static int
20432031
element_attrib_setter(ElementObject *self, PyObject *value, void *closure)
20442032
{
20452033
_VALIDATE_ATTR_VALUE(value);
2034+
if (!PyDict_Check(value)) {
2035+
PyErr_Format(PyExc_TypeError,
2036+
"attrib must be dict, not %.200s",
2037+
value->ob_type->tp_name);
2038+
return -1;
2039+
}
20462040
if (!self->extra) {
20472041
if (create_extra(self, NULL) < 0)
20482042
return -1;
20492043
}
20502044
Py_INCREF(value);
2051-
Py_SETREF(self->extra->attrib, value);
2045+
Py_XSETREF(self->extra->attrib, value);
20522046
return 0;
20532047
}
20542048

@@ -2688,7 +2682,7 @@ treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag,
26882682

26892683
if (!self->element_factory) {
26902684
node = create_new_element(tag, attrib);
2691-
} else if (attrib == Py_None) {
2685+
} else if (attrib == NULL) {
26922686
attrib = PyDict_New();
26932687
if (!attrib)
26942688
return NULL;
@@ -3297,8 +3291,7 @@ expat_start_handler(XMLParserObject* self, const XML_Char* tag_in,
32973291
attrib_in += 2;
32983292
}
32993293
} else {
3300-
Py_INCREF(Py_None);
3301-
attrib = Py_None;
3294+
attrib = NULL;
33023295
}
33033296

33043297
if (TreeBuilder_CheckExact(self->target)) {
@@ -3307,8 +3300,7 @@ expat_start_handler(XMLParserObject* self, const XML_Char* tag_in,
33073300
tag, attrib);
33083301
}
33093302
else if (self->handle_start) {
3310-
if (attrib == Py_None) {
3311-
Py_DECREF(attrib);
3303+
if (attrib == NULL) {
33123304
attrib = PyDict_New();
33133305
if (!attrib) {
33143306
Py_DECREF(tag);
@@ -3321,7 +3313,7 @@ expat_start_handler(XMLParserObject* self, const XML_Char* tag_in,
33213313
res = NULL;
33223314

33233315
Py_DECREF(tag);
3324-
Py_DECREF(attrib);
3316+
Py_XDECREF(attrib);
33253317

33263318
Py_XDECREF(res);
33273319
}

Modules/clinic/_elementtree.c.h

+5-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)