gh-92123: Convert _elementtree types to heap types (#99221)

This commit is contained in:
Erlend E. Aasland 2023-01-20 12:40:06 +01:00 committed by GitHub
parent 9109d46051
commit 3847a6c64b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 185 additions and 236 deletions

View file

@ -181,6 +181,26 @@ def __hash__(self):
r = e.get(X())
self.assertIsNone(r)
@support.cpython_only
def test_immutable_types(self):
root = cET.fromstring('<a></a>')
dataset = (
cET.Element,
cET.TreeBuilder,
cET.XMLParser,
type(root.iter()),
)
for tp in dataset:
with self.subTest(tp=tp):
with self.assertRaisesRegex(TypeError, "immutable"):
tp.foo = 1
@support.cpython_only
def test_disallow_instantiation(self):
root = cET.fromstring('<a></a>')
iter_type = type(root.iter())
support.check_disallow_instantiation(self, iter_type)
@unittest.skipUnless(cET, 'requires _elementtree')
class TestAliasWorking(unittest.TestCase):

View file

@ -0,0 +1 @@
Convert :mod:`elementtree` types to heap types. Patch by Erlend E. Aasland.

View file

@ -70,10 +70,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 */
@ -223,8 +223,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)
/* -------------------------------------------------------------------- */
@ -291,7 +291,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;
@ -373,11 +373,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)
@ -579,7 +579,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;
}
@ -618,6 +618,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));
@ -649,6 +650,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)
@ -660,7 +663,8 @@ element_dealloc(ElementObject* self)
*/
element_gc_clear(self);
Py_TYPE(self)->tp_free((PyObject *)self);
tp->tp_free((PyObject *)self);
Py_DECREF(tp);
Py_TRASHCAN_END
}
@ -669,14 +673,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;
@ -1436,7 +1440,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]*/
@ -1444,7 +1448,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;
@ -1543,14 +1547,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;
@ -2001,16 +2005,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
@ -2040,6 +2034,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 */
@ -2051,7 +2046,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
@ -2063,6 +2059,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;
}
@ -2193,49 +2190,22 @@ 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 |
Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION),
.slots = elementiter_slots,
};
#define INIT_PARENT_STACK_SIZE 8
@ -2245,7 +2215,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;
@ -2302,7 +2272,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 */
@ -2393,6 +2363,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);
@ -2437,9 +2408,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);
}
/* -------------------------------------------------------------------- */
@ -3593,7 +3566,7 @@ _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target,
if (target != Py_None) {
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);
@ -3685,6 +3658,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);
@ -3731,9 +3705,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)
@ -4106,10 +4082,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[] = {
@ -4132,46 +4107,33 @@ 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 |
Py_TPFLAGS_IMMUTABLETYPE),
.slots = element_slots,
};
static PyMethodDef treebuilder_methods[] = {
@ -4184,46 +4146,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 | Py_TPFLAGS_IMMUTABLETYPE,
.slots = treebuilder_slots,
};
static PyMethodDef xmlparser_methods[] = {
@ -4234,46 +4172,25 @@ 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 |
Py_TPFLAGS_IMMUTABLETYPE),
.slots = xmlparser_slots,
};
/* ==================================================================== */
@ -4298,40 +4215,47 @@ 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;
elementtreestate *st;
PyObject *m = NULL;
elementtreestate *st = NULL;
m = PyState_FindModule(&elementtreemodule);
if (m) {
return Py_NewRef(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);
st->deepcopy_obj = _PyImport_GetModuleAttrString("copy", "deepcopy");
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);
@ -4344,62 +4268,66 @@ 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->str_append = PyUnicode_InternFromString("append");
if (st->str_append == NULL) {
return NULL;
goto error;
}
st->str_find = PyUnicode_InternFromString("find");
if (st->str_find == NULL) {
return NULL;
goto error;
}
st->str_findall = PyUnicode_InternFromString("findall");
if (st->str_findall == NULL) {
return NULL;
goto error;
}
st->str_findtext = PyUnicode_InternFromString("findtext");
if (st->str_findtext == NULL) {
return NULL;
goto error;
}
st->str_iterfind = PyUnicode_InternFromString("iterfind");
if (st->str_iterfind == NULL) {
return NULL;
goto error;
}
st->str_tail = PyUnicode_InternFromString("tail");
if (st->str_tail == NULL) {
return NULL;
goto error;
}
st->str_text = PyUnicode_InternFromString("text");
if (st->str_text == NULL) {
return NULL;
goto error;
}
st->str_doctype = PyUnicode_InternFromString("doctype");
if (st->str_doctype == NULL) {
return NULL;
goto error;
}
st->parseerror_obj = PyErr_NewException(
"xml.etree.ElementTree.ParseError", PyExc_SyntaxError, NULL
);
if (PyModule_AddObjectRef(m, "ParseError", st->parseerror_obj) < 0) {
return NULL;
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;
}

View file

@ -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, Element_Type)) {
_PyArg_BadArgument("append", "argument", (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], Element_Type)) {
_PyArg_BadArgument("insert", "argument 2", (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, Element_Type)) {
_PyArg_BadArgument("remove", "argument", (Element_Type)->tp_name, arg);
goto exit;
}
subelement = arg;
@ -1105,4 +1105,4 @@ skip_optional:
exit:
return return_value;
}
/*[clinic end generated code: output=4ad006cadce01571 input=a9049054013a1b77]*/
/*[clinic end generated code: output=db3d6654de9f8013 input=a9049054013a1b77]*/