diff options
-rw-r--r-- | Modules/_elementtree.c | 148 | ||||
-rw-r--r-- | Modules/clinic/_elementtree.c.h | 14 | ||||
-rw-r--r-- | Tools/c-analyzer/cpython/globals-to-fix.tsv | 4 |
3 files changed, 98 insertions, 68 deletions
diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 93a9d60..3be098a 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -69,13 +69,6 @@ static void _clear_joined_ptr(PyObject **p) } } -/* Types defined by this extension */ -static PyTypeObject *Element_Type; -static PyTypeObject *ElementIter_Type; -static PyTypeObject *TreeBuilder_Type; -static PyTypeObject *XMLParser_Type; - - /* Per-module state; PEP 3121 */ typedef struct { PyObject *parseerror_obj; @@ -92,6 +85,11 @@ typedef struct { PyObject *str_findall; PyObject *str_iterfind; PyObject *str_doctype; + /* Types defined by this extension */ + PyTypeObject *Element_Type; + PyTypeObject *ElementIter_Type; + PyTypeObject *TreeBuilder_Type; + PyTypeObject *XMLParser_Type; } elementtreestate; static struct PyModuleDef elementtreemodule; @@ -132,6 +130,12 @@ elementtree_clear(PyObject *m) Py_CLEAR(st->str_tail); Py_CLEAR(st->str_text); Py_CLEAR(st->str_doctype); + + // Heap types + Py_CLEAR(st->Element_Type); + Py_CLEAR(st->ElementIter_Type); + Py_CLEAR(st->TreeBuilder_Type); + Py_CLEAR(st->XMLParser_Type); return 0; } @@ -144,6 +148,12 @@ elementtree_traverse(PyObject *m, visitproc visit, void *arg) Py_VISIT(st->elementpath_obj); Py_VISIT(st->comment_factory); Py_VISIT(st->pi_factory); + + // Heap types + Py_VISIT(st->Element_Type); + Py_VISIT(st->ElementIter_Type); + Py_VISIT(st->TreeBuilder_Type); + Py_VISIT(st->XMLParser_Type); return 0; } @@ -223,8 +233,8 @@ typedef struct { } ElementObject; -#define Element_CheckExact(op) Py_IS_TYPE(op, Element_Type) -#define Element_Check(op) PyObject_TypeCheck(op, Element_Type) +#define Element_CheckExact(st, op) Py_IS_TYPE(op, (st)->Element_Type) +#define Element_Check(st, op) PyObject_TypeCheck(op, (st)->Element_Type) /* -------------------------------------------------------------------- */ @@ -291,7 +301,8 @@ create_new_element(PyObject* tag, PyObject* attrib) { ElementObject* self; - self = PyObject_GC_New(ElementObject, Element_Type); + elementtreestate *st = ET_STATE_GLOBAL; + self = PyObject_GC_New(ElementObject, st->Element_Type); if (self == NULL) return NULL; self->extra = NULL; @@ -373,11 +384,11 @@ get_attrib_from_keywords(PyObject *kwds) /*[clinic input] module _elementtree -class _elementtree.Element "ElementObject *" "Element_Type" -class _elementtree.TreeBuilder "TreeBuilderObject *" "TreeBuilder_Type" -class _elementtree.XMLParser "XMLParserObject *" "XMLParser_Type" +class _elementtree.Element "ElementObject *" "clinic_state()->Element_Type" +class _elementtree.TreeBuilder "TreeBuilderObject *" "clinic_state()->TreeBuilder_Type" +class _elementtree.XMLParser "XMLParserObject *" "clinic_state()->XMLParser_Type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=1ecdb32b55d9d5de]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6c83ea832d2b0ef1]*/ static int element_init(PyObject *self, PyObject *args, PyObject *kwds) @@ -496,8 +507,8 @@ LOCAL(int) element_add_subelement(ElementObject* self, PyObject* element) { /* add a child element to a parent */ - - if (!Element_Check(element)) { + elementtreestate *st = ET_STATE_GLOBAL; + if (!Element_Check(st, element)) { raise_type_error(element); return -1; } @@ -575,11 +586,12 @@ subelement(PyObject *self, PyObject *args, PyObject *kwds) { PyObject* elem; + elementtreestate *st = ET_STATE_GLOBAL; ElementObject* parent; PyObject* tag; PyObject* attrib = NULL; if (!PyArg_ParseTuple(args, "O!O|O!:SubElement", - Element_Type, &parent, &tag, + st->Element_Type, &parent, &tag, &PyDict_Type, &attrib)) { return NULL; } @@ -673,14 +685,14 @@ element_dealloc(ElementObject* self) /*[clinic input] _elementtree.Element.append - subelement: object(subclass_of='Element_Type') + subelement: object(subclass_of='clinic_state()->Element_Type') / [clinic start generated code]*/ static PyObject * _elementtree_Element_append_impl(ElementObject *self, PyObject *subelement) -/*[clinic end generated code: output=54a884b7cf2295f4 input=59866b732e6e2891]*/ +/*[clinic end generated code: output=54a884b7cf2295f4 input=439f2bd777288fb6]*/ { if (element_add_subelement(self, subelement) < 0) return NULL; @@ -806,9 +818,10 @@ _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); - if (!child || !Element_Check(child)) { + if (!child || !Element_Check(st, child)) { if (child) { raise_type_error(child); Py_DECREF(child); @@ -846,7 +859,7 @@ LOCAL(PyObject *) deepcopy(PyObject *object, PyObject *memo) { /* do a deep copy of the given object */ - elementtreestate *st; + elementtreestate *st = ET_STATE_GLOBAL; PyObject *stack[2]; /* Fast paths */ @@ -869,14 +882,13 @@ deepcopy(PyObject *object, PyObject *memo) return PyDict_Copy(object); /* Fall through to general case */ } - else if (Element_CheckExact(object)) { + else if (Element_CheckExact(st, object)) { return _elementtree_Element___deepcopy___impl( (ElementObject *)object, memo); } } /* General case */ - st = ET_STATE_GLOBAL; if (!st->deepcopy_obj) { PyErr_SetString(PyExc_RuntimeError, "deepcopy helper not found"); @@ -1020,9 +1032,10 @@ 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(child)) { + if (!Element_Check(st, child)) { raise_type_error(child); self->extra->length = i; dealloc_extra(oldextra); @@ -1220,7 +1233,7 @@ _elementtree_Element_find_impl(ElementObject *self, PyObject *path, for (i = 0; i < self->extra->length; i++) { PyObject* item = self->extra->children[i]; int rc; - assert(Element_Check(item)); + assert(Element_Check(st, item)); Py_INCREF(item); rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ); if (rc > 0) @@ -1264,7 +1277,7 @@ _elementtree_Element_findtext_impl(ElementObject *self, PyObject *path, for (i = 0; i < self->extra->length; i++) { PyObject *item = self->extra->children[i]; int rc; - assert(Element_Check(item)); + assert(Element_Check(st, item)); Py_INCREF(item); rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ); if (rc > 0) { @@ -1318,7 +1331,7 @@ _elementtree_Element_findall_impl(ElementObject *self, PyObject *path, for (i = 0; i < self->extra->length; i++) { PyObject* item = self->extra->children[i]; int rc; - assert(Element_Check(item)); + assert(Element_Check(st, item)); Py_INCREF(item); rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ); if (rc != 0 && (rc < 0 || PyList_Append(out, item) < 0)) { @@ -1440,7 +1453,7 @@ element_getitem(PyObject* self_, Py_ssize_t index) _elementtree.Element.insert index: Py_ssize_t - subelement: object(subclass_of='Element_Type') + subelement: object(subclass_of='clinic_state()->Element_Type') / [clinic start generated code]*/ @@ -1448,7 +1461,7 @@ _elementtree.Element.insert static PyObject * _elementtree_Element_insert_impl(ElementObject *self, Py_ssize_t index, PyObject *subelement) -/*[clinic end generated code: output=990adfef4d424c0b input=4382c42ab2659f9b]*/ +/*[clinic end generated code: output=990adfef4d424c0b input=9530f4905aa401ca]*/ { Py_ssize_t i; @@ -1547,14 +1560,14 @@ _elementtree_Element_makeelement_impl(ElementObject *self, PyObject *tag, /*[clinic input] _elementtree.Element.remove - subelement: object(subclass_of='Element_Type') + subelement: object(subclass_of='clinic_state()->Element_Type') / [clinic start generated code]*/ static PyObject * _elementtree_Element_remove_impl(ElementObject *self, PyObject *subelement) -/*[clinic end generated code: output=38fe6c07d6d87d1f input=cbdf9f2ab34d93b0]*/ +/*[clinic end generated code: output=38fe6c07d6d87d1f input=6133e1d05597d5ee]*/ { Py_ssize_t i; int rc; @@ -1668,7 +1681,8 @@ element_setitem(PyObject* self_, Py_ssize_t index, PyObject* item) old = self->extra->children[index]; if (item) { - if (!Element_Check(item)) { + elementtreestate *st = ET_STATE_GLOBAL; + if (!Element_Check(st, item)) { raise_type_error(item); return -1; } @@ -1865,9 +1879,10 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value) } } + elementtreestate *st = ET_STATE_GLOBAL; for (i = 0; i < newlen; i++) { PyObject *element = PySequence_Fast_GET_ITEM(seq, i); - if (!Element_Check(element)) { + if (!Element_Check(st, element)) { raise_type_error(element); Py_DECREF(seq); return -1; @@ -2140,7 +2155,10 @@ elementiter_next(ElementIterObject *it) continue; } - assert(Element_Check(extra->children[child_index])); +#ifndef NDEBUG + elementtreestate *st = ET_STATE_GLOBAL; + assert(Element_Check(st, extra->children[child_index])); +#endif elem = (ElementObject *)Py_NewRef(extra->children[child_index]); item->child_index++; } @@ -2215,7 +2233,8 @@ create_elementiter(ElementObject *self, PyObject *tag, int gettext) { ElementIterObject *it; - it = PyObject_GC_New(ElementIterObject, ElementIter_Type); + elementtreestate *st = ET_STATE_GLOBAL; + it = PyObject_GC_New(ElementIterObject, st->ElementIter_Type); if (!it) return NULL; @@ -2272,7 +2291,7 @@ typedef struct { char insert_pis; } TreeBuilderObject; -#define TreeBuilder_CheckExact(op) Py_IS_TYPE((op), TreeBuilder_Type) +#define TreeBuilder_CheckExact(st, op) Py_IS_TYPE((op), (st)->TreeBuilder_Type) /* -------------------------------------------------------------------- */ /* constructor and destructor */ @@ -2472,7 +2491,8 @@ treebuilder_extend_element_text_or_tail(PyObject *element, PyObject **data, PyObject **dest, PyObject *name) { /* Fast paths for the "almost always" cases. */ - if (Element_CheckExact(element)) { + elementtreestate *st = ET_STATE_GLOBAL; + if (Element_CheckExact(st, element)) { PyObject *dest_obj = JOIN_OBJ(*dest); if (dest_obj == Py_None) { *dest = JOIN_SET(*data, PyList_CheckExact(*data)); @@ -2546,7 +2566,7 @@ static int treebuilder_add_subelement(PyObject *element, PyObject *child) { elementtreestate *st = ET_STATE_GLOBAL; - if (Element_CheckExact(element)) { + if (Element_CheckExact(st, element)) { ElementObject *elem = (ElementObject *) element; return element_add_subelement(elem, child); } @@ -3121,7 +3141,8 @@ expat_default_handler(XMLParserObject* self, const XML_Char* data_in, value = PyDict_GetItemWithError(self->entity, key); if (value) { - if (TreeBuilder_CheckExact(self->target)) + elementtreestate *st = ET_STATE_GLOBAL; + if (TreeBuilder_CheckExact(st, self->target)) res = treebuilder_handle_data( (TreeBuilderObject*) self->target, value ); @@ -3193,7 +3214,8 @@ expat_start_handler(XMLParserObject* self, const XML_Char* tag_in, attrib = NULL; } - if (TreeBuilder_CheckExact(self->target)) { + elementtreestate *st = ET_STATE_GLOBAL; + if (TreeBuilder_CheckExact(st, self->target)) { /* shortcut */ res = treebuilder_handle_start((TreeBuilderObject*) self->target, tag, attrib); @@ -3231,7 +3253,8 @@ expat_data_handler(XMLParserObject* self, const XML_Char* data_in, if (!data) return; /* parser will look for errors */ - if (TreeBuilder_CheckExact(self->target)) + elementtreestate *st = ET_STATE_GLOBAL; + if (TreeBuilder_CheckExact(st, self->target)) /* shortcut */ res = treebuilder_handle_data((TreeBuilderObject*) self->target, data); else if (self->handle_data) @@ -3253,7 +3276,8 @@ expat_end_handler(XMLParserObject* self, const XML_Char* tag_in) if (PyErr_Occurred()) return; - if (TreeBuilder_CheckExact(self->target)) + elementtreestate *st = ET_STATE_GLOBAL; + if (TreeBuilder_CheckExact(st, self->target)) /* shortcut */ /* the standard tree builder doesn't look at the end tag */ res = treebuilder_handle_end( @@ -3287,7 +3311,8 @@ expat_start_ns_handler(XMLParserObject* self, const XML_Char* prefix_in, if (!prefix_in) prefix_in = ""; - if (TreeBuilder_CheckExact(self->target)) { + elementtreestate *st = ET_STATE_GLOBAL; + if (TreeBuilder_CheckExact(st, self->target)) { /* shortcut - TreeBuilder does not actually implement .start_ns() */ TreeBuilderObject *target = (TreeBuilderObject*) self->target; @@ -3337,7 +3362,8 @@ expat_end_ns_handler(XMLParserObject* self, const XML_Char* prefix_in) if (!prefix_in) prefix_in = ""; - if (TreeBuilder_CheckExact(self->target)) { + elementtreestate *st = ET_STATE_GLOBAL; + if (TreeBuilder_CheckExact(st, self->target)) { /* shortcut - TreeBuilder does not actually implement .end_ns() */ TreeBuilderObject *target = (TreeBuilderObject*) self->target; @@ -3365,7 +3391,8 @@ expat_comment_handler(XMLParserObject* self, const XML_Char* comment_in) if (PyErr_Occurred()) return; - if (TreeBuilder_CheckExact(self->target)) { + elementtreestate *st = ET_STATE_GLOBAL; + if (TreeBuilder_CheckExact(st, self->target)) { /* shortcut */ TreeBuilderObject *target = (TreeBuilderObject*) self->target; @@ -3458,7 +3485,8 @@ expat_pi_handler(XMLParserObject* self, const XML_Char* target_in, if (PyErr_Occurred()) return; - if (TreeBuilder_CheckExact(self->target)) { + elementtreestate *st = ET_STATE_GLOBAL; + if (TreeBuilder_CheckExact(st, self->target)) { /* shortcut */ TreeBuilderObject *target = (TreeBuilderObject*) self->target; @@ -3566,7 +3594,8 @@ _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target, if (target != Py_None) { Py_INCREF(target); } else { - target = treebuilder_new(TreeBuilder_Type, NULL, NULL); + elementtreestate *st = ET_STATE_GLOBAL; + target = treebuilder_new(st->TreeBuilder_Type, NULL, NULL); if (!target) { Py_CLEAR(self->entity); Py_CLEAR(self->names); @@ -3767,7 +3796,8 @@ _elementtree_XMLParser_close_impl(XMLParserObject *self) if (!res) return NULL; - if (TreeBuilder_CheckExact(self->target)) { + elementtreestate *st = ET_STATE_GLOBAL; + if (TreeBuilder_CheckExact(st, self->target)) { Py_DECREF(res); return treebuilder_done((TreeBuilderObject*) self->target); } @@ -3906,7 +3936,8 @@ _elementtree_XMLParser__parse_whole(XMLParserObject *self, PyObject *file) res = expat_parse(self, "", 0, 1); - if (res && TreeBuilder_CheckExact(self->target)) { + elementtreestate *st = ET_STATE_GLOBAL; + if (res && TreeBuilder_CheckExact(st, self->target)) { Py_DECREF(res); return treebuilder_done((TreeBuilderObject*) self->target); } @@ -3937,7 +3968,8 @@ _elementtree_XMLParser__setevents_impl(XMLParserObject *self, if (!_check_xmlparser(self)) { return NULL; } - if (!TreeBuilder_CheckExact(self->target)) { + elementtreestate *st = ET_STATE_GLOBAL; + if (!TreeBuilder_CheckExact(st, self->target)) { PyErr_SetString( PyExc_TypeError, "event handling only supported for ElementTree.TreeBuilder " @@ -4046,7 +4078,9 @@ static PyGetSetDef xmlparser_getsetlist[] = { {NULL}, }; +#define clinic_state() (ET_STATE_GLOBAL) #include "clinic/_elementtree.c.h" +#undef clinic_state static PyMethodDef element_methods[] = { @@ -4243,10 +4277,10 @@ PyInit__elementtree(void) st = get_elementtree_state(m); /* Initialize object types */ - CREATE_TYPE(m, ElementIter_Type, &elementiter_spec); - CREATE_TYPE(m, TreeBuilder_Type, &treebuilder_spec); - CREATE_TYPE(m, Element_Type, &element_spec); - CREATE_TYPE(m, XMLParser_Type, &xmlparser_spec); + CREATE_TYPE(m, st->ElementIter_Type, &elementiter_spec); + CREATE_TYPE(m, st->TreeBuilder_Type, &treebuilder_spec); + CREATE_TYPE(m, st->Element_Type, &element_spec); + CREATE_TYPE(m, st->XMLParser_Type, &xmlparser_spec); st->deepcopy_obj = _PyImport_GetModuleAttrString("copy", "deepcopy"); if (st->deepcopy_obj == NULL) { @@ -4314,9 +4348,9 @@ PyInit__elementtree(void) } PyTypeObject *types[] = { - Element_Type, - TreeBuilder_Type, - XMLParser_Type + st->Element_Type, + st->TreeBuilder_Type, + st->XMLParser_Type }; for (size_t i = 0; i < Py_ARRAY_LENGTH(types); i++) { diff --git a/Modules/clinic/_elementtree.c.h b/Modules/clinic/_elementtree.c.h index b816e1b..4bf342c 100644 --- a/Modules/clinic/_elementtree.c.h +++ b/Modules/clinic/_elementtree.c.h @@ -25,8 +25,8 @@ _elementtree_Element_append(ElementObject *self, PyObject *arg) PyObject *return_value = NULL; PyObject *subelement; - if (!PyObject_TypeCheck(arg, Element_Type)) { - _PyArg_BadArgument("append", "argument", (Element_Type)->tp_name, arg); + if (!PyObject_TypeCheck(arg, clinic_state()->Element_Type)) { + _PyArg_BadArgument("append", "argument", (clinic_state()->Element_Type)->tp_name, arg); goto exit; } subelement = arg; @@ -586,8 +586,8 @@ _elementtree_Element_insert(ElementObject *self, PyObject *const *args, Py_ssize } index = ival; } - if (!PyObject_TypeCheck(args[1], Element_Type)) { - _PyArg_BadArgument("insert", "argument 2", (Element_Type)->tp_name, args[1]); + if (!PyObject_TypeCheck(args[1], clinic_state()->Element_Type)) { + _PyArg_BadArgument("insert", "argument 2", (clinic_state()->Element_Type)->tp_name, args[1]); goto exit; } subelement = args[1]; @@ -682,8 +682,8 @@ _elementtree_Element_remove(ElementObject *self, PyObject *arg) PyObject *return_value = NULL; PyObject *subelement; - if (!PyObject_TypeCheck(arg, Element_Type)) { - _PyArg_BadArgument("remove", "argument", (Element_Type)->tp_name, arg); + if (!PyObject_TypeCheck(arg, clinic_state()->Element_Type)) { + _PyArg_BadArgument("remove", "argument", (clinic_state()->Element_Type)->tp_name, arg); goto exit; } subelement = arg; @@ -1105,4 +1105,4 @@ skip_optional: exit: return return_value; } -/*[clinic end generated code: output=db3d6654de9f8013 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d380adb43d8f4a62 input=a9049054013a1b77]*/ diff --git a/Tools/c-analyzer/cpython/globals-to-fix.tsv b/Tools/c-analyzer/cpython/globals-to-fix.tsv index cd08782..761a2ab 100644 --- a/Tools/c-analyzer/cpython/globals-to-fix.tsv +++ b/Tools/c-analyzer/cpython/globals-to-fix.tsv @@ -425,10 +425,6 @@ Modules/_decimal/_decimal.c - PyDecContextManager_Type - Modules/_decimal/_decimal.c - PyDecContext_Type - Modules/_decimal/_decimal.c - PyDecSignalDictMixin_Type - Modules/_decimal/_decimal.c - PyDec_Type - -Modules/_elementtree.c - ElementIter_Type - -Modules/_elementtree.c - Element_Type - -Modules/_elementtree.c - TreeBuilder_Type - -Modules/_elementtree.c - XMLParser_Type - Modules/_pickle.c - Pdata_Type - Modules/_pickle.c - PicklerMemoProxyType - Modules/_pickle.c - Pickler_Type - |