}
}
-/* 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;
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;
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;
}
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;
}
} 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)
/* -------------------------------------------------------------------- */
{
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;
/*[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)
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;
}
{
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;
}
/*[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;
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);
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 */
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");
}
/* 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);
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)
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) {
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)) {
_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]*/
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;
/*[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;
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;
}
}
}
+ 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;
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++;
}
{
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;
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 */
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));
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);
}
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
);
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);
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)
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(
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;
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;
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;
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;
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);
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);
}
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);
}
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 "
{NULL},
};
+#define clinic_state() (ET_STATE_GLOBAL)
#include "clinic/_elementtree.c.h"
+#undef clinic_state
static PyMethodDef element_methods[] = {
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) {
}
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++) {