diff --git a/Misc/NEWS.d/next/Library/2020-11-20-21-06-08.bpo-40077.M-iZq3.rst b/Misc/NEWS.d/next/Library/2020-11-20-21-06-08.bpo-40077.M-iZq3.rst new file mode 100644 index 00000000000000..8a74477a4b359d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-11-20-21-06-08.bpo-40077.M-iZq3.rst @@ -0,0 +1 @@ +Convert :mod:`elementtree` types to heap types. Patch by Erlend E. Aasland. diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 85fdfa7e5ed42c..7e213368a45c5d 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -81,10 +81,10 @@ 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; +static PyTypeObject *Element_Type; +static PyTypeObject *ElementIter_Type; +static PyTypeObject *TreeBuilder_Type; +static PyTypeObject *XMLParser_Type; /* Per-module state; PEP 3121 */ @@ -215,8 +215,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(op) Py_IS_TYPE(op, Element_Type) +#define Element_Check(op) PyObject_TypeCheck(op, Element_Type) /* -------------------------------------------------------------------- */ @@ -284,7 +284,7 @@ create_new_element(PyObject* tag, PyObject* attrib) { ElementObject* self; - self = PyObject_GC_New(ElementObject, &Element_Type); + self = PyObject_GC_New(ElementObject, Element_Type); if (self == NULL) return NULL; self->extra = NULL; @@ -381,11 +381,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 *" "Element_Type" +class _elementtree.TreeBuilder "TreeBuilderObject *" "TreeBuilder_Type" +class _elementtree.XMLParser "XMLParserObject *" "XMLParser_Type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=159aa50a54061c22]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=1ecdb32b55d9d5de]*/ static int element_init(PyObject *self, PyObject *args, PyObject *kwds) @@ -594,7 +594,7 @@ subelement(PyObject *self, PyObject *args, PyObject *kwds) PyObject* tag; PyObject* attrib = NULL; if (!PyArg_ParseTuple(args, "O!O|O!:SubElement", - &Element_Type, &parent, &tag, + Element_Type, &parent, &tag, &PyDict_Type, &attrib)) { return NULL; } @@ -633,6 +633,7 @@ subelement(PyObject *self, PyObject *args, PyObject *kwds) static int element_gc_traverse(ElementObject *self, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(self)); Py_VISIT(self->tag); Py_VISIT(JOIN_OBJ(self->text)); Py_VISIT(JOIN_OBJ(self->tail)); @@ -664,6 +665,8 @@ element_gc_clear(ElementObject *self) static void element_dealloc(ElementObject* self) { + PyTypeObject *tp = Py_TYPE(self); + /* bpo-31095: UnTrack is needed before calling any callbacks */ PyObject_GC_UnTrack(self); Py_TRASHCAN_BEGIN(self, element_dealloc) @@ -676,7 +679,8 @@ element_dealloc(ElementObject* self) element_gc_clear(self); RELEASE(sizeof(ElementObject), "destroy element"); - Py_TYPE(self)->tp_free((PyObject *)self); + tp->tp_free(self); + Py_DECREF(tp); Py_TRASHCAN_END } @@ -685,14 +689,14 @@ element_dealloc(ElementObject* self) /*[clinic input] _elementtree.Element.append - subelement: object(subclass_of='&Element_Type') + subelement: object(subclass_of='Element_Type') / [clinic start generated code]*/ static PyObject * _elementtree_Element_append_impl(ElementObject *self, PyObject *subelement) -/*[clinic end generated code: output=54a884b7cf2295f4 input=3ed648beb5bfa22a]*/ +/*[clinic end generated code: output=54a884b7cf2295f4 input=59866b732e6e2891]*/ { if (element_add_subelement(self, subelement) < 0) return NULL; @@ -1475,7 +1479,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='Element_Type') / [clinic start generated code]*/ @@ -1483,7 +1487,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=cd6fbfcdab52d7a8]*/ +/*[clinic end generated code: output=990adfef4d424c0b input=4382c42ab2659f9b]*/ { Py_ssize_t i; @@ -1583,14 +1587,14 @@ _elementtree_Element_makeelement_impl(ElementObject *self, PyObject *tag, /*[clinic input] _elementtree.Element.remove - subelement: object(subclass_of='&Element_Type') + subelement: object(subclass_of='Element_Type') / [clinic start generated code]*/ static PyObject * _elementtree_Element_remove_impl(ElementObject *self, PyObject *subelement) -/*[clinic end generated code: output=38fe6c07d6d87d1f input=d52fc28ededc0bd8]*/ +/*[clinic end generated code: output=38fe6c07d6d87d1f input=cbdf9f2ab34d93b0]*/ { Py_ssize_t i; int rc; @@ -2052,16 +2056,6 @@ element_attrib_setter(ElementObject *self, PyObject *value, void *closure) return 0; } -static PySequenceMethods element_as_sequence = { - (lenfunc) element_length, - 0, /* sq_concat */ - 0, /* sq_repeat */ - element_getitem, - 0, - element_setitem, - 0, -}; - /******************************* Element iterator ****************************/ /* ElementIterObject represents the iteration state over an XML element in @@ -2091,6 +2085,7 @@ typedef struct { static void elementiter_dealloc(ElementIterObject *it) { + PyTypeObject *tp = Py_TYPE(it); Py_ssize_t i = it->parent_stack_used; it->parent_stack_used = 0; /* bpo-31095: UnTrack is needed before calling any callbacks */ @@ -2102,7 +2097,8 @@ elementiter_dealloc(ElementIterObject *it) Py_XDECREF(it->sought_tag); Py_XDECREF(it->root_element); - PyObject_GC_Del(it); + tp->tp_free(it); + Py_DECREF(tp); } static int @@ -2114,6 +2110,7 @@ elementiter_traverse(ElementIterObject *it, visitproc visit, void *arg) Py_VISIT(it->root_element); Py_VISIT(it->sought_tag); + Py_VISIT(Py_TYPE(it)); return 0; } @@ -2246,49 +2243,21 @@ elementiter_next(ElementIterObject *it) return NULL; } +static PyType_Slot elementiter_slots[] = { + {Py_tp_dealloc, elementiter_dealloc}, + {Py_tp_traverse, elementiter_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, elementiter_next}, + {0, NULL}, +}; -static PyTypeObject ElementIter_Type = { - PyVarObject_HEAD_INIT(NULL, 0) +static PyType_Spec elementiter_spec = { /* Using the module's name since the pure-Python implementation does not have such a type. */ - "_elementtree._element_iterator", /* tp_name */ - sizeof(ElementIterObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)elementiter_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)elementiter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)elementiter_next, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ + .name = "_elementtree._element_iterator", + .basicsize = sizeof(ElementIterObject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .slots = elementiter_slots, }; #define INIT_PARENT_STACK_SIZE 8 @@ -2298,7 +2267,7 @@ create_elementiter(ElementObject *self, PyObject *tag, int gettext) { ElementIterObject *it; - it = PyObject_GC_New(ElementIterObject, &ElementIter_Type); + it = PyObject_GC_New(ElementIterObject, ElementIter_Type); if (!it) return NULL; @@ -2357,7 +2326,7 @@ typedef struct { char insert_pis; } TreeBuilderObject; -#define TreeBuilder_CheckExact(op) Py_IS_TYPE((op), &TreeBuilder_Type) +#define TreeBuilder_CheckExact(op) Py_IS_TYPE((op), TreeBuilder_Type) /* -------------------------------------------------------------------- */ /* constructor and destructor */ @@ -2455,6 +2424,7 @@ _elementtree_TreeBuilder___init___impl(TreeBuilderObject *self, static int treebuilder_gc_traverse(TreeBuilderObject *self, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(self)); Py_VISIT(self->pi_event_obj); Py_VISIT(self->comment_event_obj); Py_VISIT(self->end_ns_event_obj); @@ -2499,9 +2469,11 @@ treebuilder_gc_clear(TreeBuilderObject *self) static void treebuilder_dealloc(TreeBuilderObject *self) { + PyTypeObject *tp = Py_TYPE(self); PyObject_GC_UnTrack(self); treebuilder_gc_clear(self); - Py_TYPE(self)->tp_free((PyObject *)self); + tp->tp_free(self); + Py_DECREF(tp); } /* -------------------------------------------------------------------- */ @@ -3675,7 +3647,7 @@ _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target, if (target) { Py_INCREF(target); } else { - target = treebuilder_new(&TreeBuilder_Type, NULL, NULL); + target = treebuilder_new(TreeBuilder_Type, NULL, NULL); if (!target) { Py_CLEAR(self->entity); Py_CLEAR(self->names); @@ -3767,6 +3739,7 @@ _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target, static int xmlparser_gc_traverse(XMLParserObject *self, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(self)); Py_VISIT(self->handle_close); Py_VISIT(self->handle_pi); Py_VISIT(self->handle_comment); @@ -3813,9 +3786,11 @@ xmlparser_gc_clear(XMLParserObject *self) static void xmlparser_dealloc(XMLParserObject* self) { + PyTypeObject *tp = Py_TYPE(self); PyObject_GC_UnTrack(self); xmlparser_gc_clear(self); - Py_TYPE(self)->tp_free((PyObject *)self); + tp->tp_free(self); + Py_DECREF(tp); } Py_LOCAL_INLINE(int) @@ -4190,10 +4165,9 @@ static PyMethodDef element_methods[] = { {NULL, NULL} }; -static PyMappingMethods element_as_mapping = { - (lenfunc) element_length, - (binaryfunc) element_subscr, - (objobjargproc) element_ass_subscr, +static struct PyMemberDef element_members[] = { + {"__weaklistoffset__", T_PYSSIZET, offsetof(ElementObject, weakreflist), READONLY}, + {NULL}, }; static PyGetSetDef element_getsetlist[] = { @@ -4216,46 +4190,32 @@ static PyGetSetDef element_getsetlist[] = { {NULL}, }; -static PyTypeObject Element_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "xml.etree.ElementTree.Element", sizeof(ElementObject), 0, - /* methods */ - (destructor)element_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)element_repr, /* tp_repr */ - 0, /* tp_as_number */ - &element_as_sequence, /* tp_as_sequence */ - &element_as_mapping, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, - /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)element_gc_traverse, /* tp_traverse */ - (inquiry)element_gc_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(ElementObject, weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - element_methods, /* tp_methods */ - 0, /* tp_members */ - element_getsetlist, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)element_init, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - element_new, /* tp_new */ - 0, /* tp_free */ +static PyType_Slot element_slots[] = { + {Py_tp_dealloc, element_dealloc}, + {Py_tp_repr, element_repr}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_traverse, element_gc_traverse}, + {Py_tp_clear, element_gc_clear}, + {Py_tp_methods, element_methods}, + {Py_tp_members, element_members}, + {Py_tp_getset, element_getsetlist}, + {Py_tp_init, element_init}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_new, element_new}, + {Py_sq_length, element_length}, + {Py_sq_item, element_getitem}, + {Py_sq_ass_item, element_setitem}, + {Py_mp_length, element_length}, + {Py_mp_subscript, element_subscr}, + {Py_mp_ass_subscript, element_ass_subscr}, + {0, NULL}, +}; + +static PyType_Spec element_spec = { + .name = "xml.etree.ElementTree.Element", + .basicsize = sizeof(ElementObject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + .slots = element_slots, }; static PyMethodDef treebuilder_methods[] = { @@ -4268,46 +4228,22 @@ static PyMethodDef treebuilder_methods[] = { {NULL, NULL} }; -static PyTypeObject TreeBuilder_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "xml.etree.ElementTree.TreeBuilder", sizeof(TreeBuilderObject), 0, - /* methods */ - (destructor)treebuilder_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, - /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)treebuilder_gc_traverse, /* tp_traverse */ - (inquiry)treebuilder_gc_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - treebuilder_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - _elementtree_TreeBuilder___init__, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - treebuilder_new, /* tp_new */ - 0, /* tp_free */ +static PyType_Slot treebuilder_slots[] = { + {Py_tp_dealloc, treebuilder_dealloc}, + {Py_tp_traverse, treebuilder_gc_traverse}, + {Py_tp_clear, treebuilder_gc_clear}, + {Py_tp_methods, treebuilder_methods}, + {Py_tp_init, _elementtree_TreeBuilder___init__}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_new, treebuilder_new}, + {0, NULL}, +}; + +static PyType_Spec treebuilder_spec = { + .name = "xml.etree.ElementTree.TreeBuilder", + .basicsize = sizeof(TreeBuilderObject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + .slots = treebuilder_slots, }; static PyMethodDef xmlparser_methods[] = { @@ -4318,46 +4254,24 @@ static PyMethodDef xmlparser_methods[] = { {NULL, NULL} }; -static PyTypeObject XMLParser_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "xml.etree.ElementTree.XMLParser", sizeof(XMLParserObject), 0, - /* methods */ - (destructor)xmlparser_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, - /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)xmlparser_gc_traverse, /* tp_traverse */ - (inquiry)xmlparser_gc_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - xmlparser_methods, /* tp_methods */ - xmlparser_members, /* tp_members */ - xmlparser_getsetlist, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - _elementtree_XMLParser___init__, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - xmlparser_new, /* tp_new */ - 0, /* tp_free */ +static PyType_Slot xmlparser_slots[] = { + {Py_tp_dealloc, xmlparser_dealloc}, + {Py_tp_traverse, xmlparser_gc_traverse}, + {Py_tp_clear, xmlparser_gc_clear}, + {Py_tp_methods, xmlparser_methods}, + {Py_tp_members, xmlparser_members}, + {Py_tp_getset, xmlparser_getsetlist}, + {Py_tp_init, _elementtree_XMLParser___init__}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_new, xmlparser_new}, + {0, NULL}, +}; + +static PyType_Spec xmlparser_spec = { + .name = "xml.etree.ElementTree.XMLParser", + .basicsize = sizeof(XMLParserObject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + .slots = xmlparser_slots, }; /* ==================================================================== */ @@ -4382,11 +4296,22 @@ static struct PyModuleDef elementtreemodule = { elementtree_free }; +#define CREATE_TYPE(module, type, spec) \ +do { \ + if (type != NULL) { \ + break; \ + } \ + type = (PyTypeObject *)PyType_FromModuleAndSpec(module, spec, NULL); \ + if (type == NULL) { \ + goto error; \ + } \ +} while (0) + PyMODINIT_FUNC PyInit__elementtree(void) { - PyObject *m, *temp; - elementtreestate *st; + PyObject *m = NULL, *temp; + elementtreestate *st = NULL; m = PyState_FindModule(&elementtreemodule); if (m) { @@ -4394,33 +4319,29 @@ PyInit__elementtree(void) return m; } - /* Initialize object types */ - if (PyType_Ready(&ElementIter_Type) < 0) - return NULL; - if (PyType_Ready(&TreeBuilder_Type) < 0) - return NULL; - if (PyType_Ready(&Element_Type) < 0) - return NULL; - if (PyType_Ready(&XMLParser_Type) < 0) - return NULL; - m = PyModule_Create(&elementtreemodule); if (!m) - return NULL; + goto error; 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); + if (!(temp = PyImport_ImportModule("copy"))) - return NULL; + goto error; st->deepcopy_obj = PyObject_GetAttrString(temp, "deepcopy"); Py_XDECREF(temp); if (st->deepcopy_obj == NULL) { - return NULL; + goto error; } assert(!PyErr_Occurred()); if (!(st->elementpath_obj = PyImport_ImportModule("xml.etree.ElementPath"))) - return NULL; + goto error; /* link against pyexpat */ expat_capi = PyCapsule_Import(PyExpat_CAPSULE_NAME, 0); @@ -4433,32 +4354,37 @@ PyInit__elementtree(void) expat_capi->MICRO_VERSION != XML_MICRO_VERSION) { PyErr_SetString(PyExc_ImportError, "pyexpat version is incompatible"); - return NULL; + goto error; } } else { - return NULL; + goto error; } st->parseerror_obj = PyErr_NewException( "xml.etree.ElementTree.ParseError", PyExc_SyntaxError, NULL ); Py_INCREF(st->parseerror_obj); - if (PyModule_AddObject(m, "ParseError", st->parseerror_obj) < 0) { - Py_DECREF(st->parseerror_obj); - return NULL; + int res = PyModule_AddObjectRef(m, "ParseError", st->parseerror_obj); + Py_DECREF(st->parseerror_obj); + if (res < 0) { + goto error; } PyTypeObject *types[] = { - &Element_Type, - &TreeBuilder_Type, - &XMLParser_Type + Element_Type, + TreeBuilder_Type, + XMLParser_Type }; for (size_t i = 0; i < Py_ARRAY_LENGTH(types); i++) { if (PyModule_AddType(m, types[i]) < 0) { - return NULL; + goto error; } } return m; + +error: + Py_XDECREF(m); + return NULL; } diff --git a/Modules/clinic/_elementtree.c.h b/Modules/clinic/_elementtree.c.h index 2c9ba47823bf43..28d53e33d3c0c7 100644 --- a/Modules/clinic/_elementtree.c.h +++ b/Modules/clinic/_elementtree.c.h @@ -19,8 +19,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, Element_Type)) { + _PyArg_BadArgument("append", "argument", (Element_Type)->tp_name, arg); goto exit; } subelement = arg; @@ -442,8 +442,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], Element_Type)) { + _PyArg_BadArgument("insert", "argument 2", (Element_Type)->tp_name, args[1]); goto exit; } subelement = args[1]; @@ -538,8 +538,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, Element_Type)) { + _PyArg_BadArgument("remove", "argument", (Element_Type)->tp_name, arg); goto exit; } subelement = arg; @@ -915,4 +915,4 @@ _elementtree_XMLParser__setevents(XMLParserObject *self, PyObject *const *args, exit: return return_value; } -/*[clinic end generated code: output=1385b5e5688f3614 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5ea065ac45181d56 input=a9049054013a1b77]*/