}
/* 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 */
} 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)
/* -------------------------------------------------------------------- */
{
ElementObject* self;
- self = PyObject_GC_New(ElementObject, &Element_Type);
+ self = PyObject_GC_New(ElementObject, Element_Type);
if (self == NULL)
return NULL;
self->extra = NULL;
/*[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)
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;
}
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));
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)
*/
element_gc_clear(self);
- Py_TYPE(self)->tp_free((PyObject *)self);
+ tp->tp_free((PyObject *)self);
+ Py_DECREF(tp);
Py_TRASHCAN_END
}
/*[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;
_elementtree.Element.insert
index: Py_ssize_t
- subelement: object(subclass_of='&Element_Type')
+ subelement: object(subclass_of='Element_Type')
/
[clinic start generated code]*/
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;
/*[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;
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
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 */
Py_XDECREF(it->sought_tag);
Py_XDECREF(it->root_element);
- PyObject_GC_Del(it);
+ tp->tp_free(it);
+ Py_DECREF(tp);
}
static int
Py_VISIT(it->root_element);
Py_VISIT(it->sought_tag);
+ Py_VISIT(Py_TYPE(it));
return 0;
}
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
{
ElementIterObject *it;
- it = PyObject_GC_New(ElementIterObject, &ElementIter_Type);
+ it = PyObject_GC_New(ElementIterObject, ElementIter_Type);
if (!it)
return NULL;
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 */
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);
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);
}
/* -------------------------------------------------------------------- */
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);
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);
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)
{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[] = {
{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[] = {
{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[] = {
{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,
};
/* ==================================================================== */
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);
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;
}