summaryrefslogtreecommitdiffstats
path: root/Modules/_elementtree.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/_elementtree.c')
-rw-r--r--Modules/_elementtree.c1236
1 files changed, 702 insertions, 534 deletions
diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c
index cf819e8..11d1aec 100644
--- a/Modules/_elementtree.c
+++ b/Modules/_elementtree.c
@@ -11,6 +11,8 @@
*--------------------------------------------------------------------
*/
+#define PY_SSIZE_T_CLEAN
+
#include "Python.h"
#include "structmember.h"
@@ -185,8 +187,8 @@ typedef struct {
PyObject* attrib;
/* child elements */
- int length; /* actual number of items */
- int allocated; /* allocated items */
+ Py_ssize_t length; /* actual number of items */
+ Py_ssize_t allocated; /* allocated items */
/* this either points to _children or to a malloced buffer */
PyObject* *children;
@@ -251,7 +253,7 @@ LOCAL(void)
dealloc_extra(ElementObject* self)
{
ElementObjectExtra *myextra;
- int i;
+ Py_ssize_t i;
if (!self->extra)
return;
@@ -368,6 +370,14 @@ get_attrib_from_keywords(PyObject *kwds)
return attrib;
}
+/*[clinic input]
+module _elementtree
+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]*/
+
static int
element_init(PyObject *self, PyObject *args, PyObject *kwds)
{
@@ -442,7 +452,7 @@ element_resize(ElementObject* self, Py_ssize_t extra)
return -1;
}
- size = self->extra->length + extra;
+ size = self->extra->length + extra; /* never overflows */
if (size > self->extra->allocated) {
/* use Python 2.4's list growth strategy */
@@ -455,11 +465,6 @@ element_resize(ElementObject* self, Py_ssize_t extra)
size = size ? size : 1;
if ((size_t)size > PY_SSIZE_T_MAX/sizeof(PyObject*))
goto nomemory;
- if (size > INT_MAX) {
- PyErr_SetString(PyExc_OverflowError,
- "too many children");
- return -1;
- }
if (self->extra->children != self->extra->_children) {
/* Coverity CID #182 size_error: Allocating 1 bytes to pointer
* "children", which needs at least 4 bytes. Although it's a
@@ -620,7 +625,7 @@ element_gc_traverse(ElementObject *self, visitproc visit, void *arg)
Py_VISIT(JOIN_OBJ(self->tail));
if (self->extra) {
- int i;
+ Py_ssize_t i;
Py_VISIT(self->extra->attrib);
for (i = 0; i < self->extra->length; ++i)
@@ -661,25 +666,33 @@ element_dealloc(ElementObject* self)
/* -------------------------------------------------------------------- */
-static PyObject*
-element_append(ElementObject* self, PyObject* args)
-{
- PyObject* element;
- if (!PyArg_ParseTuple(args, "O!:append", &Element_Type, &element))
- return NULL;
+/*[clinic input]
+_elementtree.Element.append
- if (element_add_subelement(self, element) < 0)
+ 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]*/
+{
+ if (element_add_subelement(self, subelement) < 0)
return NULL;
Py_RETURN_NONE;
}
-static PyObject*
-element_clearmethod(ElementObject* self, PyObject* args)
-{
- if (!PyArg_ParseTuple(args, ":clear"))
- return NULL;
+/*[clinic input]
+_elementtree.Element.clear
+
+[clinic start generated code]*/
+static PyObject *
+_elementtree_Element_clear_impl(ElementObject *self)
+/*[clinic end generated code: output=8bcd7a51f94cfff6 input=3c719ff94bf45dd6]*/
+{
dealloc_extra(self);
Py_INCREF(Py_None);
@@ -693,15 +706,18 @@ element_clearmethod(ElementObject* self, PyObject* args)
Py_RETURN_NONE;
}
-static PyObject*
-element_copy(ElementObject* self, PyObject* args)
+/*[clinic input]
+_elementtree.Element.__copy__
+
+[clinic start generated code]*/
+
+static PyObject *
+_elementtree_Element___copy___impl(ElementObject *self)
+/*[clinic end generated code: output=2c701ebff7247781 input=ad87aaebe95675bf]*/
{
- int i;
+ Py_ssize_t i;
ElementObject* element;
- if (!PyArg_ParseTuple(args, ":__copy__"))
- return NULL;
-
element = (ElementObject*) create_new_element(
self->tag, (self->extra) ? self->extra->attrib : Py_None);
if (!element)
@@ -732,10 +748,19 @@ element_copy(ElementObject* self, PyObject* args)
return (PyObject*) element;
}
-static PyObject*
-element_deepcopy(ElementObject* self, PyObject* args)
+/*[clinic input]
+_elementtree.Element.__deepcopy__
+
+ memo: object
+ /
+
+[clinic start generated code]*/
+
+static PyObject *
+_elementtree_Element___deepcopy__(ElementObject *self, PyObject *memo)
+/*[clinic end generated code: output=d1f19851d17bf239 input=df24c2b602430b77]*/
{
- int i;
+ Py_ssize_t i;
ElementObject* element;
PyObject* tag;
PyObject* attrib;
@@ -743,10 +768,6 @@ element_deepcopy(ElementObject* self, PyObject* args)
PyObject* tail;
PyObject* id;
- PyObject* memo;
- if (!PyArg_ParseTuple(args, "O:__deepcopy__", &memo))
- return NULL;
-
tag = deepcopy(self->tag, memo);
if (!tag)
return NULL;
@@ -817,17 +838,22 @@ element_deepcopy(ElementObject* self, PyObject* args)
return NULL;
}
-static PyObject*
-element_sizeof(PyObject* myself, PyObject* args)
+/*[clinic input]
+_elementtree.Element.__sizeof__ -> Py_ssize_t
+
+[clinic start generated code]*/
+
+static Py_ssize_t
+_elementtree_Element___sizeof___impl(ElementObject *self)
+/*[clinic end generated code: output=bf73867721008000 input=70f4b323d55a17c1]*/
{
- ElementObject *self = (ElementObject*)myself;
- Py_ssize_t result = sizeof(ElementObject);
+ Py_ssize_t result = _PyObject_SIZE(Py_TYPE(self));
if (self->extra) {
result += sizeof(ElementObjectExtra);
if (self->extra->children != self->extra->_children)
result += sizeof(PyObject*) * self->extra->allocated;
}
- return PyLong_FromSsize_t(result);
+ return result;
}
/* dict keys for getstate/setstate. */
@@ -843,10 +869,16 @@ element_sizeof(PyObject* myself, PyObject* args)
* any unnecessary structures there; and (b) it buys compatibility with 3.2
* pickles. See issue #16076.
*/
+/*[clinic input]
+_elementtree.Element.__getstate__
+
+[clinic start generated code]*/
+
static PyObject *
-element_getstate(ElementObject *self)
+_elementtree_Element___getstate___impl(ElementObject *self)
+/*[clinic end generated code: output=37279aeeb6bb5b04 input=f0d16d7ec2f7adc1]*/
{
- int i, noattrib;
+ Py_ssize_t i, noattrib;
PyObject *instancedict = NULL, *children;
/* Build a list of children. */
@@ -896,16 +928,15 @@ element_setstate_from_attributes(ElementObject *self,
PyObject *tail,
PyObject *children)
{
- int i, nchildren;
+ Py_ssize_t i, nchildren;
if (!tag) {
PyErr_SetString(PyExc_TypeError, "tag may not be NULL");
return NULL;
}
- Py_CLEAR(self->tag);
- self->tag = tag;
- Py_INCREF(self->tag);
+ Py_INCREF(tag);
+ Py_SETREF(self->tag, tag);
_clear_joined_ptr(&self->text);
self->text = text ? JOIN_SET(text, PyList_CheckExact(text)) : Py_None;
@@ -921,18 +952,11 @@ element_setstate_from_attributes(ElementObject *self,
/* Compute 'nchildren'. */
if (children) {
- Py_ssize_t size;
if (!PyList_Check(children)) {
PyErr_SetString(PyExc_TypeError, "'_children' is not a list");
return NULL;
}
- size = PyList_Size(children);
- /* expat limits nchildren to int */
- if (size > INT_MAX) {
- PyErr_SetString(PyExc_OverflowError, "too many children");
- return NULL;
- }
- nchildren = (int)size;
+ nchildren = PyList_Size(children);
}
else {
nchildren = 0;
@@ -955,9 +979,8 @@ element_setstate_from_attributes(ElementObject *self,
/* Stash attrib. */
if (attrib) {
- Py_CLEAR(self->extra->attrib);
- self->extra->attrib = attrib;
Py_INCREF(attrib);
+ Py_SETREF(self->extra->attrib, attrib);
}
Py_RETURN_NONE;
@@ -966,6 +989,7 @@ element_setstate_from_attributes(ElementObject *self,
/* __setstate__ for Element instance from the Python implementation.
* 'state' should be the instance dict.
*/
+
static PyObject *
element_setstate_from_Python(ElementObject *self, PyObject *state)
{
@@ -991,8 +1015,17 @@ element_setstate_from_Python(ElementObject *self, PyObject *state)
return retval;
}
+/*[clinic input]
+_elementtree.Element.__setstate__
+
+ state: object
+ /
+
+[clinic start generated code]*/
+
static PyObject *
-element_setstate(ElementObject *self, PyObject *state)
+_elementtree_Element___setstate__(ElementObject *self, PyObject *state)
+/*[clinic end generated code: output=ea28bf3491b1f75e input=aaf80abea7c1e3b9]*/
{
if (!PyDict_CheckExact(state)) {
PyErr_Format(PyExc_TypeError,
@@ -1046,21 +1079,26 @@ checkpath(PyObject* tag)
return 1; /* unknown type; might be path expression */
}
-static PyObject*
-element_extend(ElementObject* self, PyObject* args)
+/*[clinic input]
+_elementtree.Element.extend
+
+ elements: object
+ /
+
+[clinic start generated code]*/
+
+static PyObject *
+_elementtree_Element_extend(ElementObject *self, PyObject *elements)
+/*[clinic end generated code: output=f6e67fc2ff529191 input=807bc4f31c69f7c0]*/
{
PyObject* seq;
Py_ssize_t i;
- PyObject* seq_in;
- if (!PyArg_ParseTuple(args, "O:extend", &seq_in))
- return NULL;
-
- seq = PySequence_Fast(seq_in, "");
+ seq = PySequence_Fast(elements, "");
if (!seq) {
PyErr_Format(
PyExc_TypeError,
- "expected sequence, not \"%.200s\"", Py_TYPE(seq_in)->tp_name
+ "expected sequence, not \"%.200s\"", Py_TYPE(elements)->tp_name
);
return NULL;
}
@@ -1091,23 +1129,26 @@ element_extend(ElementObject* self, PyObject* args)
Py_RETURN_NONE;
}
-static PyObject*
-element_find(ElementObject *self, PyObject *args, PyObject *kwds)
+/*[clinic input]
+_elementtree.Element.find
+
+ path: object
+ namespaces: object = None
+
+[clinic start generated code]*/
+
+static PyObject *
+_elementtree_Element_find_impl(ElementObject *self, PyObject *path,
+ PyObject *namespaces)
+/*[clinic end generated code: output=41b43f0f0becafae input=359b6985f6489d2e]*/
{
- int i;
- PyObject* tag;
- PyObject* namespaces = Py_None;
- static char *kwlist[] = {"path", "namespaces", 0};
+ Py_ssize_t i;
elementtreestate *st = ET_STATE_GLOBAL;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:find", kwlist,
- &tag, &namespaces))
- return NULL;
-
- if (checkpath(tag) || namespaces != Py_None) {
+ if (checkpath(path) || namespaces != Py_None) {
_Py_IDENTIFIER(find);
return _PyObject_CallMethodId(
- st->elementpath_obj, &PyId_find, "OOO", self, tag, namespaces
+ st->elementpath_obj, &PyId_find, "OOO", self, path, namespaces
);
}
@@ -1120,7 +1161,7 @@ element_find(ElementObject *self, PyObject *args, PyObject *kwds)
if (!Element_CheckExact(item))
continue;
Py_INCREF(item);
- rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, tag, Py_EQ);
+ rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ);
if (rc > 0)
return item;
Py_DECREF(item);
@@ -1131,24 +1172,28 @@ element_find(ElementObject *self, PyObject *args, PyObject *kwds)
Py_RETURN_NONE;
}
-static PyObject*
-element_findtext(ElementObject *self, PyObject *args, PyObject *kwds)
+/*[clinic input]
+_elementtree.Element.findtext
+
+ path: object
+ default: object = None
+ namespaces: object = None
+
+[clinic start generated code]*/
+
+static PyObject *
+_elementtree_Element_findtext_impl(ElementObject *self, PyObject *path,
+ PyObject *default_value,
+ PyObject *namespaces)
+/*[clinic end generated code: output=83b3ba4535d308d2 input=b53a85aa5aa2a916]*/
{
- int i;
- PyObject* tag;
- PyObject* default_value = Py_None;
- PyObject* namespaces = Py_None;
+ Py_ssize_t i;
_Py_IDENTIFIER(findtext);
- static char *kwlist[] = {"path", "default", "namespaces", 0};
elementtreestate *st = ET_STATE_GLOBAL;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OO:findtext", kwlist,
- &tag, &default_value, &namespaces))
- return NULL;
-
- if (checkpath(tag) || namespaces != Py_None)
+ if (checkpath(path) || namespaces != Py_None)
return _PyObject_CallMethodId(
- st->elementpath_obj, &PyId_findtext, "OOOO", self, tag, default_value, namespaces
+ st->elementpath_obj, &PyId_findtext, "OOOO", self, path, default_value, namespaces
);
if (!self->extra) {
@@ -1162,7 +1207,7 @@ element_findtext(ElementObject *self, PyObject *args, PyObject *kwds)
if (!Element_CheckExact(item))
continue;
Py_INCREF(item);
- rc = PyObject_RichCompareBool(item->tag, tag, Py_EQ);
+ rc = PyObject_RichCompareBool(item->tag, path, Py_EQ);
if (rc > 0) {
PyObject* text = element_get_text(item);
if (text == Py_None) {
@@ -1182,20 +1227,24 @@ element_findtext(ElementObject *self, PyObject *args, PyObject *kwds)
return default_value;
}
-static PyObject*
-element_findall(ElementObject *self, PyObject *args, PyObject *kwds)
+/*[clinic input]
+_elementtree.Element.findall
+
+ path: object
+ namespaces: object = None
+
+[clinic start generated code]*/
+
+static PyObject *
+_elementtree_Element_findall_impl(ElementObject *self, PyObject *path,
+ PyObject *namespaces)
+/*[clinic end generated code: output=1a0bd9f5541b711d input=4d9e6505a638550c]*/
{
- int i;
+ Py_ssize_t i;
PyObject* out;
- PyObject* tag;
- PyObject* namespaces = Py_None;
- static char *kwlist[] = {"path", "namespaces", 0};
+ PyObject* tag = path;
elementtreestate *st = ET_STATE_GLOBAL;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:findall", kwlist,
- &tag, &namespaces))
- return NULL;
-
if (checkpath(tag) || namespaces != Py_None) {
_Py_IDENTIFIER(findall);
return _PyObject_CallMethodId(
@@ -1228,36 +1277,41 @@ element_findall(ElementObject *self, PyObject *args, PyObject *kwds)
return out;
}
-static PyObject*
-element_iterfind(ElementObject *self, PyObject *args, PyObject *kwds)
+/*[clinic input]
+_elementtree.Element.iterfind
+
+ path: object
+ namespaces: object = None
+
+[clinic start generated code]*/
+
+static PyObject *
+_elementtree_Element_iterfind_impl(ElementObject *self, PyObject *path,
+ PyObject *namespaces)
+/*[clinic end generated code: output=ecdd56d63b19d40f input=abb974e350fb65c7]*/
{
- PyObject* tag;
- PyObject* namespaces = Py_None;
+ PyObject* tag = path;
_Py_IDENTIFIER(iterfind);
- static char *kwlist[] = {"path", "namespaces", 0};
elementtreestate *st = ET_STATE_GLOBAL;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:iterfind", kwlist,
- &tag, &namespaces)) {
- return NULL;
- }
-
return _PyObject_CallMethodId(
st->elementpath_obj, &PyId_iterfind, "OOO", self, tag, namespaces);
}
-static PyObject*
-element_get(ElementObject* self, PyObject* args, PyObject* kwds)
-{
- PyObject* value;
- static char* kwlist[] = {"key", "default", 0};
+/*[clinic input]
+_elementtree.Element.get
- PyObject* key;
- PyObject* default_value = Py_None;
+ key: object
+ default: object = None
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:get", kwlist, &key,
- &default_value))
- return NULL;
+[clinic start generated code]*/
+
+static PyObject *
+_elementtree_Element_get_impl(ElementObject *self, PyObject *key,
+ PyObject *default_value)
+/*[clinic end generated code: output=523c614142595d75 input=ee153bbf8cdb246e]*/
+{
+ PyObject* value;
if (!self->extra || self->extra->attrib == Py_None)
value = default_value;
@@ -1271,17 +1325,20 @@ element_get(ElementObject* self, PyObject* args, PyObject* kwds)
return value;
}
-static PyObject*
-element_getchildren(ElementObject* self, PyObject* args)
+/*[clinic input]
+_elementtree.Element.getchildren
+
+[clinic start generated code]*/
+
+static PyObject *
+_elementtree_Element_getchildren_impl(ElementObject *self)
+/*[clinic end generated code: output=e50ffe118637b14f input=0f754dfded150d5f]*/
{
- int i;
+ Py_ssize_t i;
PyObject* list;
/* FIXME: report as deprecated? */
- if (!PyArg_ParseTuple(args, ":getchildren"))
- return NULL;
-
if (!self->extra)
return PyList_New(0);
@@ -1303,25 +1360,41 @@ static PyObject *
create_elementiter(ElementObject *self, PyObject *tag, int gettext);
+/*[clinic input]
+_elementtree.Element.iter
+
+ tag: object = None
+
+[clinic start generated code]*/
+
static PyObject *
-element_iter(ElementObject *self, PyObject *args, PyObject *kwds)
+_elementtree_Element_iter_impl(ElementObject *self, PyObject *tag)
+/*[clinic end generated code: output=3f49f9a862941cc5 input=774d5b12e573aedd]*/
{
- PyObject* tag = Py_None;
- static char* kwlist[] = {"tag", 0};
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:iter", kwlist, &tag))
- return NULL;
+ if (PyUnicode_Check(tag)) {
+ if (PyUnicode_READY(tag) < 0)
+ return NULL;
+ if (PyUnicode_GET_LENGTH(tag) == 1 && PyUnicode_READ_CHAR(tag, 0) == '*')
+ tag = Py_None;
+ }
+ else if (PyBytes_Check(tag)) {
+ if (PyBytes_GET_SIZE(tag) == 1 && *PyBytes_AS_STRING(tag) == '*')
+ tag = Py_None;
+ }
return create_elementiter(self, tag, 0);
}
-static PyObject*
-element_itertext(ElementObject* self, PyObject* args)
-{
- if (!PyArg_ParseTuple(args, ":itertext"))
- return NULL;
+/*[clinic input]
+_elementtree.Element.itertext
+
+[clinic start generated code]*/
+static PyObject *
+_elementtree_Element_itertext_impl(ElementObject *self)
+/*[clinic end generated code: output=5fa34b2fbcb65df6 input=af8f0e42cb239c89]*/
+{
return create_elementiter(self, Py_None, 1);
}
@@ -1343,16 +1416,21 @@ element_getitem(PyObject* self_, Py_ssize_t index)
return self->extra->children[index];
}
-static PyObject*
-element_insert(ElementObject* self, PyObject* args)
-{
- int i;
+/*[clinic input]
+_elementtree.Element.insert
- int index;
- PyObject* element;
- if (!PyArg_ParseTuple(args, "iO!:insert", &index,
- &Element_Type, &element))
- return NULL;
+ index: Py_ssize_t
+ 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]*/
+{
+ Py_ssize_t i;
if (!self->extra) {
if (create_extra(self, NULL) < 0)
@@ -1373,32 +1451,38 @@ element_insert(ElementObject* self, PyObject* args)
for (i = self->extra->length; i > index; i--)
self->extra->children[i] = self->extra->children[i-1];
- Py_INCREF(element);
- self->extra->children[index] = element;
+ Py_INCREF(subelement);
+ self->extra->children[index] = subelement;
self->extra->length++;
Py_RETURN_NONE;
}
-static PyObject*
-element_items(ElementObject* self, PyObject* args)
-{
- if (!PyArg_ParseTuple(args, ":items"))
- return NULL;
+/*[clinic input]
+_elementtree.Element.items
+
+[clinic start generated code]*/
+static PyObject *
+_elementtree_Element_items_impl(ElementObject *self)
+/*[clinic end generated code: output=6db2c778ce3f5a4d input=adbe09aaea474447]*/
+{
if (!self->extra || self->extra->attrib == Py_None)
return PyList_New(0);
return PyDict_Items(self->extra->attrib);
}
-static PyObject*
-element_keys(ElementObject* self, PyObject* args)
-{
- if (!PyArg_ParseTuple(args, ":keys"))
- return NULL;
+/*[clinic input]
+_elementtree.Element.keys
+
+[clinic start generated code]*/
+static PyObject *
+_elementtree_Element_keys_impl(ElementObject *self)
+/*[clinic end generated code: output=bc5bfabbf20eeb3c input=f02caf5b496b5b0b]*/
+{
if (!self->extra || self->extra->attrib == Py_None)
return PyList_New(0);
@@ -1414,16 +1498,22 @@ element_length(ElementObject* self)
return self->extra->length;
}
-static PyObject*
-element_makeelement(PyObject* self, PyObject* args, PyObject* kw)
+/*[clinic input]
+_elementtree.Element.makeelement
+
+ tag: object
+ attrib: object
+ /
+
+[clinic start generated code]*/
+
+static PyObject *
+_elementtree_Element_makeelement_impl(ElementObject *self, PyObject *tag,
+ PyObject *attrib)
+/*[clinic end generated code: output=4109832d5bb789ef input=9480d1d2e3e68235]*/
{
PyObject* elem;
- PyObject* tag;
- PyObject* attrib;
- if (!PyArg_ParseTuple(args, "OO:makeelement", &tag, &attrib))
- return NULL;
-
attrib = PyDict_Copy(attrib);
if (!attrib)
return NULL;
@@ -1435,16 +1525,21 @@ element_makeelement(PyObject* self, PyObject* args, PyObject* kw)
return elem;
}
-static PyObject*
-element_remove(ElementObject* self, PyObject* args)
+/*[clinic input]
+_elementtree.Element.remove
+
+ 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]*/
{
- int i;
+ Py_ssize_t i;
int rc;
- PyObject* element;
- PyObject* found;
-
- if (!PyArg_ParseTuple(args, "O!:remove", &Element_Type, &element))
- return NULL;
+ PyObject *found;
if (!self->extra) {
/* element has no children, so raise exception */
@@ -1456,9 +1551,9 @@ element_remove(ElementObject* self, PyObject* args)
}
for (i = 0; i < self->extra->length; i++) {
- if (self->extra->children[i] == element)
+ if (self->extra->children[i] == subelement)
break;
- rc = PyObject_RichCompareBool(self->extra->children[i], element, Py_EQ);
+ rc = PyObject_RichCompareBool(self->extra->children[i], subelement, Py_EQ);
if (rc > 0)
break;
if (rc < 0)
@@ -1466,7 +1561,7 @@ element_remove(ElementObject* self, PyObject* args)
}
if (i >= self->extra->length) {
- /* element is not in children, so raise exception */
+ /* subelement is not in children, so raise exception */
PyErr_SetString(
PyExc_ValueError,
"list.remove(x): x not in list"
@@ -1493,16 +1588,22 @@ element_repr(ElementObject* self)
return PyUnicode_FromFormat("<Element at %p>", self);
}
-static PyObject*
-element_set(ElementObject* self, PyObject* args)
+/*[clinic input]
+_elementtree.Element.set
+
+ key: object
+ value: object
+ /
+
+[clinic start generated code]*/
+
+static PyObject *
+_elementtree_Element_set_impl(ElementObject *self, PyObject *key,
+ PyObject *value)
+/*[clinic end generated code: output=fb938806be3c5656 input=1efe90f7d82b3fe9]*/
{
PyObject* attrib;
- PyObject* key;
- PyObject* value;
- if (!PyArg_ParseTuple(args, "OO:set", &key, &value))
- return NULL;
-
if (!self->extra) {
if (create_extra(self, NULL) < 0)
return NULL;
@@ -1519,19 +1620,18 @@ element_set(ElementObject* self, PyObject* args)
}
static int
-element_setitem(PyObject* self_, Py_ssize_t index_, PyObject* item)
+element_setitem(PyObject* self_, Py_ssize_t index, PyObject* item)
{
ElementObject* self = (ElementObject*) self_;
- int i, index;
+ Py_ssize_t i;
PyObject* old;
- if (!self->extra || index_ < 0 || index_ >= self->extra->length) {
+ if (!self->extra || index < 0 || index >= self->extra->length) {
PyErr_SetString(
PyExc_IndexError,
"child assignment index out of range");
return -1;
}
- index = (int)index_;
old = self->extra->children[index];
@@ -1632,7 +1732,6 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value)
&start, &stop, &step, &slicelen) < 0) {
return -1;
}
- assert(slicelen <= self->extra->length);
if (value == NULL) {
/* Delete slice */
@@ -1694,7 +1793,7 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value)
(self->extra->length - cur) * sizeof(PyObject *));
}
- self->extra->length -= (int)slicelen;
+ self->extra->length -= slicelen;
/* Discard the recycle list with all the deleted sub-elements */
Py_XDECREF(recycle);
@@ -1730,8 +1829,6 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value)
return -1;
}
}
- assert(newlen - slicelen <= INT_MAX - self->extra->length);
- assert(newlen - slicelen >= -self->extra->length);
if (slicelen > 0) {
/* to avoid recursive calls to this method (via decref), move
@@ -1765,7 +1862,7 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value)
self->extra->children[cur] = element;
}
- self->extra->length += (int)(newlen - slicelen);
+ self->extra->length += newlen - slicelen;
Py_DECREF(seq);
@@ -1781,43 +1878,6 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value)
}
}
-static PyMethodDef element_methods[] = {
-
- {"clear", (PyCFunction) element_clearmethod, METH_VARARGS},
-
- {"get", (PyCFunction) element_get, METH_VARARGS | METH_KEYWORDS},
- {"set", (PyCFunction) element_set, METH_VARARGS},
-
- {"find", (PyCFunction) element_find, METH_VARARGS | METH_KEYWORDS},
- {"findtext", (PyCFunction) element_findtext, METH_VARARGS | METH_KEYWORDS},
- {"findall", (PyCFunction) element_findall, METH_VARARGS | METH_KEYWORDS},
-
- {"append", (PyCFunction) element_append, METH_VARARGS},
- {"extend", (PyCFunction) element_extend, METH_VARARGS},
- {"insert", (PyCFunction) element_insert, METH_VARARGS},
- {"remove", (PyCFunction) element_remove, METH_VARARGS},
-
- {"iter", (PyCFunction) element_iter, METH_VARARGS | METH_KEYWORDS},
- {"itertext", (PyCFunction) element_itertext, METH_VARARGS},
- {"iterfind", (PyCFunction) element_iterfind, METH_VARARGS | METH_KEYWORDS},
-
- {"getiterator", (PyCFunction) element_iter, METH_VARARGS | METH_KEYWORDS},
- {"getchildren", (PyCFunction) element_getchildren, METH_VARARGS},
-
- {"items", (PyCFunction) element_items, METH_VARARGS},
- {"keys", (PyCFunction) element_keys, METH_VARARGS},
-
- {"makeelement", (PyCFunction) element_makeelement, METH_VARARGS},
-
- {"__copy__", (PyCFunction) element_copy, METH_VARARGS},
- {"__deepcopy__", (PyCFunction) element_deepcopy, METH_VARARGS},
- {"__sizeof__", element_sizeof, METH_NOARGS},
- {"__getstate__", (PyCFunction)element_getstate, METH_NOARGS},
- {"__setstate__", (PyCFunction)element_setstate, METH_O},
-
- {NULL, NULL}
-};
-
static PyObject*
element_getattro(ElementObject* self, PyObject* nameobj)
{
@@ -1882,9 +1942,8 @@ element_setattro(ElementObject* self, PyObject* nameobj, PyObject* value)
return -1;
if (strcmp(name, "tag") == 0) {
- Py_DECREF(self->tag);
- self->tag = value;
- Py_INCREF(self->tag);
+ Py_INCREF(value);
+ Py_SETREF(self->tag, value);
} else if (strcmp(name, "text") == 0) {
Py_DECREF(JOIN_OBJ(self->text));
self->text = value;
@@ -1898,9 +1957,8 @@ element_setattro(ElementObject* self, PyObject* nameobj, PyObject* value)
if (create_extra(self, NULL) < 0)
return -1;
}
- Py_DECREF(self->extra->attrib);
- self->extra->attrib = value;
- Py_INCREF(self->extra->attrib);
+ Py_INCREF(value);
+ Py_SETREF(self->extra->attrib, value);
} else {
PyErr_SetString(PyExc_AttributeError,
"Can't set arbitrary attributes on Element");
@@ -1920,54 +1978,6 @@ static PySequenceMethods element_as_sequence = {
0,
};
-static PyMappingMethods element_as_mapping = {
- (lenfunc) element_length,
- (binaryfunc) element_subscr,
- (objobjargproc) element_ass_subscr,
-};
-
-static PyTypeObject Element_Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "xml.etree.ElementTree.Element", sizeof(ElementObject), 0,
- /* methods */
- (destructor)element_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_reserved */
- (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 */
- (getattrofunc)element_getattro, /* tp_getattro */
- (setattrofunc)element_setattro, /* 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 */
- 0, /* 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 */
-};
-
/******************************* Element iterator ****************************/
/* ElementIterObject represents the iteration state over an XML element in
@@ -2058,6 +2068,7 @@ elementiter_next(ElementIterObject *it)
ElementObject *cur_parent;
Py_ssize_t child_index;
int rc;
+ ElementObject *elem;
while (1) {
/* Handle the case reached in the beginning and end of iteration, where
@@ -2071,38 +2082,47 @@ elementiter_next(ElementIterObject *it)
PyErr_SetNone(PyExc_StopIteration);
return NULL;
} else {
+ elem = it->root_element;
it->parent_stack = parent_stack_push_new(it->parent_stack,
- it->root_element);
+ elem);
if (!it->parent_stack) {
PyErr_NoMemory();
return NULL;
}
+ Py_INCREF(elem);
it->root_done = 1;
rc = (it->sought_tag == Py_None);
if (!rc) {
- rc = PyObject_RichCompareBool(it->root_element->tag,
+ rc = PyObject_RichCompareBool(elem->tag,
it->sought_tag, Py_EQ);
- if (rc < 0)
+ if (rc < 0) {
+ Py_DECREF(elem);
return NULL;
+ }
}
if (rc) {
if (it->gettext) {
- PyObject *text = element_get_text(it->root_element);
- if (!text)
+ PyObject *text = element_get_text(elem);
+ if (!text) {
+ Py_DECREF(elem);
return NULL;
+ }
+ Py_INCREF(text);
+ Py_DECREF(elem);
rc = PyObject_IsTrue(text);
+ if (rc > 0)
+ return text;
+ Py_DECREF(text);
if (rc < 0)
return NULL;
- if (rc) {
- Py_INCREF(text);
- return text;
- }
} else {
- Py_INCREF(it->root_element);
- return (PyObject *)it->root_element;
+ return (PyObject *)elem;
}
}
+ else {
+ Py_DECREF(elem);
+ }
}
}
@@ -2112,54 +2132,68 @@ elementiter_next(ElementIterObject *it)
cur_parent = it->parent_stack->parent;
child_index = it->parent_stack->child_index;
if (cur_parent->extra && child_index < cur_parent->extra->length) {
- ElementObject *child = (ElementObject *)
- cur_parent->extra->children[child_index];
+ elem = (ElementObject *)cur_parent->extra->children[child_index];
it->parent_stack->child_index++;
it->parent_stack = parent_stack_push_new(it->parent_stack,
- child);
+ elem);
if (!it->parent_stack) {
PyErr_NoMemory();
return NULL;
}
+ Py_INCREF(elem);
if (it->gettext) {
- PyObject *text = element_get_text(child);
- if (!text)
+ PyObject *text = element_get_text(elem);
+ if (!text) {
+ Py_DECREF(elem);
return NULL;
+ }
+ Py_INCREF(text);
+ Py_DECREF(elem);
rc = PyObject_IsTrue(text);
+ if (rc > 0)
+ return text;
+ Py_DECREF(text);
if (rc < 0)
return NULL;
- if (rc) {
- Py_INCREF(text);
- return text;
- }
} else {
rc = (it->sought_tag == Py_None);
if (!rc) {
- rc = PyObject_RichCompareBool(child->tag,
+ rc = PyObject_RichCompareBool(elem->tag,
it->sought_tag, Py_EQ);
- if (rc < 0)
+ if (rc < 0) {
+ Py_DECREF(elem);
return NULL;
+ }
}
if (rc) {
- Py_INCREF(child);
- return (PyObject *)child;
+ return (PyObject *)elem;
}
+ Py_DECREF(elem);
}
}
else {
PyObject *tail;
- ParentLocator *next = it->parent_stack->next;
+ ParentLocator *next;
if (it->gettext) {
+ Py_INCREF(cur_parent);
tail = element_get_tail(cur_parent);
- if (!tail)
+ if (!tail) {
+ Py_DECREF(cur_parent);
return NULL;
+ }
+ Py_INCREF(tail);
+ Py_DECREF(cur_parent);
}
- else
+ else {
tail = Py_None;
- Py_XDECREF(it->parent_stack->parent);
+ Py_INCREF(tail);
+ }
+ next = it->parent_stack->next;
+ cur_parent = it->parent_stack->parent;
PyObject_Free(it->parent_stack);
it->parent_stack = next;
+ Py_XDECREF(cur_parent);
/* Note that extra condition on it->parent_stack->parent here;
* this is because itertext() is supposed to only return *inner*
@@ -2167,12 +2201,14 @@ elementiter_next(ElementIterObject *it)
*/
if (it->parent_stack->parent) {
rc = PyObject_IsTrue(tail);
+ if (rc > 0)
+ return tail;
+ Py_DECREF(tail);
if (rc < 0)
return NULL;
- if (rc) {
- Py_INCREF(tail);
- return tail;
- }
+ }
+ else {
+ Py_DECREF(tail);
}
}
}
@@ -2235,17 +2271,6 @@ create_elementiter(ElementObject *self, PyObject *tag, int gettext)
if (!it)
return NULL;
- if (PyUnicode_Check(tag)) {
- if (PyUnicode_READY(tag) < 0)
- return NULL;
- if (PyUnicode_GET_LENGTH(tag) == 1 && PyUnicode_READ_CHAR(tag, 0) == '*')
- tag = Py_None;
- }
- else if (PyBytes_Check(tag)) {
- if (PyBytes_GET_SIZE(tag) == 1 && *PyBytes_AS_STRING(tag) == '*')
- tag = Py_None;
- }
-
Py_INCREF(tag);
it->sought_tag = tag;
it->root_done = 0;
@@ -2330,23 +2355,24 @@ treebuilder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return (PyObject *)t;
}
+/*[clinic input]
+_elementtree.TreeBuilder.__init__
+
+ element_factory: object = NULL
+
+[clinic start generated code]*/
+
static int
-treebuilder_init(PyObject *self, PyObject *args, PyObject *kwds)
+_elementtree_TreeBuilder___init___impl(TreeBuilderObject *self,
+ PyObject *element_factory)
+/*[clinic end generated code: output=91cfa7558970ee96 input=1b424eeefc35249c]*/
{
- static char *kwlist[] = {"element_factory", 0};
- PyObject *element_factory = NULL;
- TreeBuilderObject *self_tb = (TreeBuilderObject *)self;
PyObject *tmp;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:TreeBuilder", kwlist,
- &element_factory)) {
- return -1;
- }
-
if (element_factory) {
Py_INCREF(element_factory);
- tmp = self_tb->element_factory;
- self_tb->element_factory = element_factory;
+ tmp = self->element_factory;
+ self->element_factory = element_factory;
Py_XDECREF(tmp);
}
@@ -2524,13 +2550,10 @@ treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag,
}
self->index++;
- Py_DECREF(this);
Py_INCREF(node);
- self->this = node;
-
- Py_DECREF(self->last);
+ Py_SETREF(self->this, node);
Py_INCREF(node);
- self->last = node;
+ Py_SETREF(self->last, node);
if (treebuilder_append_event(self, self->start_event_obj, node) < 0)
goto error;
@@ -2603,15 +2626,12 @@ treebuilder_handle_end(TreeBuilderObject* self, PyObject* tag)
return NULL;
}
- self->index--;
-
- item = PyList_GET_ITEM(self->stack, self->index);
- Py_INCREF(item);
-
- Py_DECREF(self->last);
-
+ item = self->last;
self->last = self->this;
- self->this = item;
+ self->index--;
+ self->this = PyList_GET_ITEM(self->stack, self->index);
+ Py_INCREF(self->this);
+ Py_DECREF(item);
if (treebuilder_append_event(self, self->end_event_obj, self->last) < 0)
return NULL;
@@ -2623,23 +2643,33 @@ treebuilder_handle_end(TreeBuilderObject* self, PyObject* tag)
/* -------------------------------------------------------------------- */
/* methods (in alphabetical order) */
-static PyObject*
-treebuilder_data(TreeBuilderObject* self, PyObject* args)
-{
- PyObject* data;
- if (!PyArg_ParseTuple(args, "O:data", &data))
- return NULL;
+/*[clinic input]
+_elementtree.TreeBuilder.data
+
+ data: object
+ /
+
+[clinic start generated code]*/
+static PyObject *
+_elementtree_TreeBuilder_data(TreeBuilderObject *self, PyObject *data)
+/*[clinic end generated code: output=69144c7100795bb2 input=a0540c532b284d29]*/
+{
return treebuilder_handle_data(self, data);
}
-static PyObject*
-treebuilder_end(TreeBuilderObject* self, PyObject* args)
-{
- PyObject* tag;
- if (!PyArg_ParseTuple(args, "O:end", &tag))
- return NULL;
+/*[clinic input]
+_elementtree.TreeBuilder.end
+
+ tag: object
+ /
+[clinic start generated code]*/
+
+static PyObject *
+_elementtree_TreeBuilder_end(TreeBuilderObject *self, PyObject *tag)
+/*[clinic end generated code: output=9a98727cc691cd9d input=22dc3674236f5745]*/
+{
return treebuilder_handle_end(self, tag);
}
@@ -2659,75 +2689,34 @@ treebuilder_done(TreeBuilderObject* self)
return res;
}
-static PyObject*
-treebuilder_close(TreeBuilderObject* self, PyObject* args)
-{
- if (!PyArg_ParseTuple(args, ":close"))
- return NULL;
+/*[clinic input]
+_elementtree.TreeBuilder.close
+[clinic start generated code]*/
+
+static PyObject *
+_elementtree_TreeBuilder_close_impl(TreeBuilderObject *self)
+/*[clinic end generated code: output=b441fee3202f61ee input=f7c9c65dc718de14]*/
+{
return treebuilder_done(self);
}
-static PyObject*
-treebuilder_start(TreeBuilderObject* self, PyObject* args)
-{
- PyObject* tag;
- PyObject* attrib = Py_None;
- if (!PyArg_ParseTuple(args, "O|O:start", &tag, &attrib))
- return NULL;
+/*[clinic input]
+_elementtree.TreeBuilder.start
- return treebuilder_handle_start(self, tag, attrib);
-}
+ tag: object
+ attrs: object = None
+ /
-static PyMethodDef treebuilder_methods[] = {
- {"data", (PyCFunction) treebuilder_data, METH_VARARGS},
- {"start", (PyCFunction) treebuilder_start, METH_VARARGS},
- {"end", (PyCFunction) treebuilder_end, METH_VARARGS},
- {"close", (PyCFunction) treebuilder_close, METH_VARARGS},
- {NULL, NULL}
-};
+[clinic start generated code]*/
-static PyTypeObject TreeBuilder_Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "xml.etree.ElementTree.TreeBuilder", sizeof(TreeBuilderObject), 0,
- /* methods */
- (destructor)treebuilder_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_reserved */
- 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 */
- (initproc)treebuilder_init, /* tp_init */
- PyType_GenericAlloc, /* tp_alloc */
- treebuilder_new, /* tp_new */
- 0, /* tp_free */
-};
+static PyObject *
+_elementtree_TreeBuilder_start_impl(TreeBuilderObject *self, PyObject *tag,
+ PyObject *attrs)
+/*[clinic end generated code: output=e7e9dc2861349411 input=95fc1758dd042c65]*/
+{
+ return treebuilder_handle_start(self, tag, attrs);
+}
/* ==================================================================== */
/* the expat interface */
@@ -2766,7 +2755,11 @@ typedef struct {
} XMLParserObject;
-static PyObject* xmlparser_doctype(XMLParserObject* self, PyObject* args);
+static PyObject*
+_elementtree_XMLParser_doctype(XMLParserObject* self, PyObject* args);
+static PyObject *
+_elementtree_XMLParser_doctype_impl(XMLParserObject *self, PyObject *name,
+ PyObject *pubid, PyObject *system);
/* helpers */
@@ -2844,12 +2837,13 @@ makeuniversal(XMLParserObject* self, const char* string)
* message string is the default for the given error_code.
*/
static void
-expat_set_error(enum XML_Error error_code, int line, int column, char *message)
+expat_set_error(enum XML_Error error_code, Py_ssize_t line, Py_ssize_t column,
+ const char *message)
{
PyObject *errmsg, *error, *position, *code;
elementtreestate *st = ET_STATE_GLOBAL;
- errmsg = PyUnicode_FromFormat("%s: line %d, column %d",
+ errmsg = PyUnicode_FromFormat("%s: line %zd, column %zd",
message ? message : EXPAT(ErrorString)(error_code),
line, column);
if (errmsg == NULL)
@@ -2873,7 +2867,7 @@ expat_set_error(enum XML_Error error_code, int line, int column, char *message)
}
Py_DECREF(code);
- position = Py_BuildValue("(ii)", line, column);
+ position = Py_BuildValue("(nn)", line, column);
if (!position) {
Py_DECREF(error);
return;
@@ -2957,8 +2951,10 @@ expat_start_handler(XMLParserObject* self, const XML_Char* tag_in,
/* attributes */
if (attrib_in[0]) {
attrib = PyDict_New();
- if (!attrib)
+ if (!attrib) {
+ Py_DECREF(tag);
return;
+ }
while (attrib_in[0] && attrib_in[1]) {
PyObject* key = makeuniversal(self, attrib_in[0]);
PyObject* value = PyUnicode_DecodeUTF8(attrib_in[1], strlen(attrib_in[1]), "strict");
@@ -2966,6 +2962,7 @@ expat_start_handler(XMLParserObject* self, const XML_Char* tag_in,
Py_XDECREF(value);
Py_XDECREF(key);
Py_DECREF(attrib);
+ Py_DECREF(tag);
return;
}
ok = PyDict_SetItem(attrib, key, value);
@@ -2973,6 +2970,7 @@ expat_start_handler(XMLParserObject* self, const XML_Char* tag_in,
Py_DECREF(key);
if (ok < 0) {
Py_DECREF(attrib);
+ Py_DECREF(tag);
return;
}
attrib_in += 2;
@@ -2980,8 +2978,10 @@ expat_start_handler(XMLParserObject* self, const XML_Char* tag_in,
} else {
/* Pass an empty dictionary on */
attrib = PyDict_New();
- if (!attrib)
+ if (!attrib) {
+ Py_DECREF(tag);
return;
+ }
}
if (TreeBuilder_CheckExact(self->target)) {
@@ -3169,8 +3169,9 @@ expat_start_doctype_handler(XMLParserObject *self,
!(PyCFunction_Check(parser_doctype) &&
PyCFunction_GET_SELF(parser_doctype) == self_pyobj &&
PyCFunction_GET_FUNCTION(parser_doctype) ==
- (PyCFunction) xmlparser_doctype)) {
- res = xmlparser_doctype(self, NULL);
+ (PyCFunction) _elementtree_XMLParser_doctype)) {
+ res = _elementtree_XMLParser_doctype_impl(self, doctype_name_obj,
+ pubid_obj, sysid_obj);
if (!res)
goto clear;
Py_DECREF(res);
@@ -3229,33 +3230,34 @@ xmlparser_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return (PyObject *)self;
}
-static int
-xmlparser_init(PyObject *self, PyObject *args, PyObject *kwds)
-{
- XMLParserObject *self_xp = (XMLParserObject *)self;
- PyObject *target = NULL, *html = NULL;
- char *encoding = NULL;
- static char *kwlist[] = {"html", "target", "encoding", 0};
+/*[clinic input]
+_elementtree.XMLParser.__init__
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOz:XMLParser", kwlist,
- &html, &target, &encoding)) {
- return -1;
- }
+ html: object = NULL
+ target: object = NULL
+ encoding: str(accept={str, NoneType}) = NULL
- self_xp->entity = PyDict_New();
- if (!self_xp->entity)
+[clinic start generated code]*/
+
+static int
+_elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *html,
+ PyObject *target, const char *encoding)
+/*[clinic end generated code: output=d6a16c63dda54441 input=155bc5695baafffd]*/
+{
+ self->entity = PyDict_New();
+ if (!self->entity)
return -1;
- self_xp->names = PyDict_New();
- if (!self_xp->names) {
- Py_CLEAR(self_xp->entity);
+ self->names = PyDict_New();
+ if (!self->names) {
+ Py_CLEAR(self->entity);
return -1;
}
- self_xp->parser = EXPAT(ParserCreate_MM)(encoding, &ExpatMemoryHandler, "}");
- if (!self_xp->parser) {
- Py_CLEAR(self_xp->entity);
- Py_CLEAR(self_xp->names);
+ self->parser = EXPAT(ParserCreate_MM)(encoding, &ExpatMemoryHandler, "}");
+ if (!self->parser) {
+ Py_CLEAR(self->entity);
+ Py_CLEAR(self->names);
PyErr_NoMemory();
return -1;
}
@@ -3265,55 +3267,55 @@ xmlparser_init(PyObject *self, PyObject *args, PyObject *kwds)
} else {
target = treebuilder_new(&TreeBuilder_Type, NULL, NULL);
if (!target) {
- Py_CLEAR(self_xp->entity);
- Py_CLEAR(self_xp->names);
- EXPAT(ParserFree)(self_xp->parser);
+ Py_CLEAR(self->entity);
+ Py_CLEAR(self->names);
+ EXPAT(ParserFree)(self->parser);
return -1;
}
}
- self_xp->target = target;
+ self->target = target;
- self_xp->handle_start = PyObject_GetAttrString(target, "start");
- self_xp->handle_data = PyObject_GetAttrString(target, "data");
- self_xp->handle_end = PyObject_GetAttrString(target, "end");
- self_xp->handle_comment = PyObject_GetAttrString(target, "comment");
- self_xp->handle_pi = PyObject_GetAttrString(target, "pi");
- self_xp->handle_close = PyObject_GetAttrString(target, "close");
- self_xp->handle_doctype = PyObject_GetAttrString(target, "doctype");
+ self->handle_start = PyObject_GetAttrString(target, "start");
+ self->handle_data = PyObject_GetAttrString(target, "data");
+ self->handle_end = PyObject_GetAttrString(target, "end");
+ self->handle_comment = PyObject_GetAttrString(target, "comment");
+ self->handle_pi = PyObject_GetAttrString(target, "pi");
+ self->handle_close = PyObject_GetAttrString(target, "close");
+ self->handle_doctype = PyObject_GetAttrString(target, "doctype");
PyErr_Clear();
/* configure parser */
- EXPAT(SetUserData)(self_xp->parser, self_xp);
+ EXPAT(SetUserData)(self->parser, self);
EXPAT(SetElementHandler)(
- self_xp->parser,
+ self->parser,
(XML_StartElementHandler) expat_start_handler,
(XML_EndElementHandler) expat_end_handler
);
EXPAT(SetDefaultHandlerExpand)(
- self_xp->parser,
+ self->parser,
(XML_DefaultHandler) expat_default_handler
);
EXPAT(SetCharacterDataHandler)(
- self_xp->parser,
+ self->parser,
(XML_CharacterDataHandler) expat_data_handler
);
- if (self_xp->handle_comment)
+ if (self->handle_comment)
EXPAT(SetCommentHandler)(
- self_xp->parser,
+ self->parser,
(XML_CommentHandler) expat_comment_handler
);
- if (self_xp->handle_pi)
+ if (self->handle_pi)
EXPAT(SetProcessingInstructionHandler)(
- self_xp->parser,
+ self->parser,
(XML_ProcessingInstructionHandler) expat_pi_handler
);
EXPAT(SetStartDoctypeDeclHandler)(
- self_xp->parser,
+ self->parser,
(XML_StartDoctypeDeclHandler) expat_start_doctype_handler
);
EXPAT(SetUnknownEncodingHandler)(
- self_xp->parser,
+ self->parser,
EXPAT(DefaultUnknownEncodingHandler), NULL
);
@@ -3389,15 +3391,18 @@ expat_parse(XMLParserObject* self, const char* data, int data_len, int final)
Py_RETURN_NONE;
}
-static PyObject*
-xmlparser_close(XMLParserObject* self, PyObject* args)
+/*[clinic input]
+_elementtree.XMLParser.close
+
+[clinic start generated code]*/
+
+static PyObject *
+_elementtree_XMLParser_close_impl(XMLParserObject *self)
+/*[clinic end generated code: output=d68d375dd23bc7fb input=ca7909ca78c3abfe]*/
{
/* end feeding data to parser */
PyObject* res;
- if (!PyArg_ParseTuple(args, ":close"))
- return NULL;
-
res = expat_parse(self, "", 0, 1);
if (!res)
return NULL;
@@ -3415,15 +3420,24 @@ xmlparser_close(XMLParserObject* self, PyObject* args)
}
}
-static PyObject*
-xmlparser_feed(XMLParserObject* self, PyObject* arg)
+/*[clinic input]
+_elementtree.XMLParser.feed
+
+ data: object
+ /
+
+[clinic start generated code]*/
+
+static PyObject *
+_elementtree_XMLParser_feed(XMLParserObject *self, PyObject *data)
+/*[clinic end generated code: output=e42b6a78eec7446d input=fe231b6b8de3ce1f]*/
{
/* feed data to parser */
- if (PyUnicode_Check(arg)) {
+ if (PyUnicode_Check(data)) {
Py_ssize_t data_len;
- const char *data = PyUnicode_AsUTF8AndSize(arg, &data_len);
- if (data == NULL)
+ const char *data_ptr = PyUnicode_AsUTF8AndSize(data, &data_len);
+ if (data_ptr == NULL)
return NULL;
if (data_len > INT_MAX) {
PyErr_SetString(PyExc_OverflowError, "size does not fit in an int");
@@ -3431,12 +3445,12 @@ xmlparser_feed(XMLParserObject* self, PyObject* arg)
}
/* Explicitly set UTF-8 encoding. Return code ignored. */
(void)EXPAT(SetEncoding)(self->parser, "utf-8");
- return expat_parse(self, data, (int)data_len, 0);
+ return expat_parse(self, data_ptr, (int)data_len, 0);
}
else {
Py_buffer view;
PyObject *res;
- if (PyObject_GetBuffer(arg, &view, PyBUF_SIMPLE) < 0)
+ if (PyObject_GetBuffer(data, &view, PyBUF_SIMPLE) < 0)
return NULL;
if (view.len > INT_MAX) {
PyBuffer_Release(&view);
@@ -3449,8 +3463,17 @@ xmlparser_feed(XMLParserObject* self, PyObject* arg)
}
}
-static PyObject*
-xmlparser_parse_whole(XMLParserObject* self, PyObject* args)
+/*[clinic input]
+_elementtree.XMLParser._parse_whole
+
+ file: object
+ /
+
+[clinic start generated code]*/
+
+static PyObject *
+_elementtree_XMLParser__parse_whole(XMLParserObject *self, PyObject *file)
+/*[clinic end generated code: output=f797197bb818dda3 input=19ecc893b6f3e752]*/
{
/* (internal) parse the whole input, until end of stream */
PyObject* reader;
@@ -3458,11 +3481,7 @@ xmlparser_parse_whole(XMLParserObject* self, PyObject* args)
PyObject* temp;
PyObject* res;
- PyObject* fileobj;
- if (!PyArg_ParseTuple(args, "O:_parse", &fileobj))
- return NULL;
-
- reader = PyObject_GetAttrString(fileobj, "read");
+ reader = PyObject_GetAttrString(file, "read");
if (!reader)
return NULL;
@@ -3529,8 +3548,20 @@ xmlparser_parse_whole(XMLParserObject* self, PyObject* args)
return res;
}
-static PyObject*
-xmlparser_doctype(XMLParserObject *self, PyObject *args)
+/*[clinic input]
+_elementtree.XMLParser.doctype
+
+ name: object
+ pubid: object
+ system: object
+ /
+
+[clinic start generated code]*/
+
+static PyObject *
+_elementtree_XMLParser_doctype_impl(XMLParserObject *self, PyObject *name,
+ PyObject *pubid, PyObject *system)
+/*[clinic end generated code: output=10fb50c2afded88d input=84050276cca045e1]*/
{
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"This method of XMLParser is deprecated. Define"
@@ -3541,19 +3572,25 @@ xmlparser_doctype(XMLParserObject *self, PyObject *args)
Py_RETURN_NONE;
}
-static PyObject*
-xmlparser_setevents(XMLParserObject *self, PyObject* args)
+/*[clinic input]
+_elementtree.XMLParser._setevents
+
+ events_queue: object(subclass_of='&PyList_Type')
+ events_to_report: object = None
+ /
+
+[clinic start generated code]*/
+
+static PyObject *
+_elementtree_XMLParser__setevents_impl(XMLParserObject *self,
+ PyObject *events_queue,
+ PyObject *events_to_report)
+/*[clinic end generated code: output=1440092922b13ed1 input=59db9742910c6174]*/
{
/* activate element event reporting */
- Py_ssize_t i, seqlen;
+ Py_ssize_t i;
TreeBuilderObject *target;
-
- PyObject *events_queue;
- PyObject *events_to_report = Py_None;
PyObject *events_seq;
- if (!PyArg_ParseTuple(args, "O!|O:_setevents", &PyList_Type, &events_queue,
- &events_to_report))
- return NULL;
if (!TreeBuilder_CheckExact(self->target)) {
PyErr_SetString(
@@ -3567,8 +3604,7 @@ xmlparser_setevents(XMLParserObject *self, PyObject* args)
target = (TreeBuilderObject*) self->target;
Py_INCREF(events_queue);
- Py_XDECREF(target->events);
- target->events = events_queue;
+ Py_SETREF(target->events, events_queue);
/* clear out existing events */
Py_CLEAR(target->start_event_obj);
@@ -3587,46 +3623,41 @@ xmlparser_setevents(XMLParserObject *self, PyObject* args)
return NULL;
}
- seqlen = PySequence_Size(events_seq);
- for (i = 0; i < seqlen; ++i) {
+ for (i = 0; i < PySequence_Size(events_seq); ++i) {
PyObject *event_name_obj = PySequence_Fast_GET_ITEM(events_seq, i);
char *event_name = NULL;
if (PyUnicode_Check(event_name_obj)) {
- event_name = _PyUnicode_AsString(event_name_obj);
+ event_name = PyUnicode_AsUTF8(event_name_obj);
} else if (PyBytes_Check(event_name_obj)) {
event_name = PyBytes_AS_STRING(event_name_obj);
}
-
if (event_name == NULL) {
Py_DECREF(events_seq);
PyErr_Format(PyExc_ValueError, "invalid events sequence");
return NULL;
- } else if (strcmp(event_name, "start") == 0) {
- Py_INCREF(event_name_obj);
- target->start_event_obj = event_name_obj;
+ }
+
+ Py_INCREF(event_name_obj);
+ if (strcmp(event_name, "start") == 0) {
+ Py_SETREF(target->start_event_obj, event_name_obj);
} else if (strcmp(event_name, "end") == 0) {
- Py_INCREF(event_name_obj);
- Py_XDECREF(target->end_event_obj);
- target->end_event_obj = event_name_obj;
+ Py_SETREF(target->end_event_obj, event_name_obj);
} else if (strcmp(event_name, "start-ns") == 0) {
- Py_INCREF(event_name_obj);
- Py_XDECREF(target->start_ns_event_obj);
- target->start_ns_event_obj = event_name_obj;
+ Py_SETREF(target->start_ns_event_obj, event_name_obj);
EXPAT(SetNamespaceDeclHandler)(
self->parser,
(XML_StartNamespaceDeclHandler) expat_start_ns_handler,
(XML_EndNamespaceDeclHandler) expat_end_ns_handler
);
} else if (strcmp(event_name, "end-ns") == 0) {
- Py_INCREF(event_name_obj);
- Py_XDECREF(target->end_ns_event_obj);
- target->end_ns_event_obj = event_name_obj;
+ Py_SETREF(target->end_ns_event_obj, event_name_obj);
EXPAT(SetNamespaceDeclHandler)(
self->parser,
(XML_StartNamespaceDeclHandler) expat_start_ns_handler,
(XML_EndNamespaceDeclHandler) expat_end_ns_handler
);
} else {
+ Py_DECREF(event_name_obj);
Py_DECREF(events_seq);
PyErr_Format(PyExc_ValueError, "unknown event '%s'", event_name);
return NULL;
@@ -3637,15 +3668,6 @@ xmlparser_setevents(XMLParserObject *self, PyObject* args)
Py_RETURN_NONE;
}
-static PyMethodDef xmlparser_methods[] = {
- {"feed", (PyCFunction) xmlparser_feed, METH_O},
- {"close", (PyCFunction) xmlparser_close, METH_VARARGS},
- {"_parse_whole", (PyCFunction) xmlparser_parse_whole, METH_VARARGS},
- {"_setevents", (PyCFunction) xmlparser_setevents, METH_VARARGS},
- {"doctype", (PyCFunction) xmlparser_doctype, METH_VARARGS},
- {NULL, NULL}
-};
-
static PyObject*
xmlparser_getattro(XMLParserObject* self, PyObject* nameobj)
{
@@ -3670,6 +3692,152 @@ xmlparser_getattro(XMLParserObject* self, PyObject* nameobj)
return PyObject_GenericGetAttr((PyObject*) self, nameobj);
}
+#include "clinic/_elementtree.c.h"
+
+static PyMethodDef element_methods[] = {
+
+ _ELEMENTTREE_ELEMENT_CLEAR_METHODDEF
+
+ _ELEMENTTREE_ELEMENT_GET_METHODDEF
+ _ELEMENTTREE_ELEMENT_SET_METHODDEF
+
+ _ELEMENTTREE_ELEMENT_FIND_METHODDEF
+ _ELEMENTTREE_ELEMENT_FINDTEXT_METHODDEF
+ _ELEMENTTREE_ELEMENT_FINDALL_METHODDEF
+
+ _ELEMENTTREE_ELEMENT_APPEND_METHODDEF
+ _ELEMENTTREE_ELEMENT_EXTEND_METHODDEF
+ _ELEMENTTREE_ELEMENT_INSERT_METHODDEF
+ _ELEMENTTREE_ELEMENT_REMOVE_METHODDEF
+
+ _ELEMENTTREE_ELEMENT_ITER_METHODDEF
+ _ELEMENTTREE_ELEMENT_ITERTEXT_METHODDEF
+ _ELEMENTTREE_ELEMENT_ITERFIND_METHODDEF
+
+ {"getiterator", (PyCFunction)_elementtree_Element_iter, METH_VARARGS|METH_KEYWORDS, _elementtree_Element_iter__doc__},
+ _ELEMENTTREE_ELEMENT_GETCHILDREN_METHODDEF
+
+ _ELEMENTTREE_ELEMENT_ITEMS_METHODDEF
+ _ELEMENTTREE_ELEMENT_KEYS_METHODDEF
+
+ _ELEMENTTREE_ELEMENT_MAKEELEMENT_METHODDEF
+
+ _ELEMENTTREE_ELEMENT___COPY___METHODDEF
+ _ELEMENTTREE_ELEMENT___DEEPCOPY___METHODDEF
+ _ELEMENTTREE_ELEMENT___SIZEOF___METHODDEF
+ _ELEMENTTREE_ELEMENT___GETSTATE___METHODDEF
+ _ELEMENTTREE_ELEMENT___SETSTATE___METHODDEF
+
+ {NULL, NULL}
+};
+
+static PyMappingMethods element_as_mapping = {
+ (lenfunc) element_length,
+ (binaryfunc) element_subscr,
+ (objobjargproc) element_ass_subscr,
+};
+
+static PyTypeObject Element_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "xml.etree.ElementTree.Element", sizeof(ElementObject), 0,
+ /* methods */
+ (destructor)element_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ (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 */
+ (getattrofunc)element_getattro, /* tp_getattro */
+ (setattrofunc)element_setattro, /* 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 */
+ 0, /* 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 PyMethodDef treebuilder_methods[] = {
+ _ELEMENTTREE_TREEBUILDER_DATA_METHODDEF
+ _ELEMENTTREE_TREEBUILDER_START_METHODDEF
+ _ELEMENTTREE_TREEBUILDER_END_METHODDEF
+ _ELEMENTTREE_TREEBUILDER_CLOSE_METHODDEF
+ {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_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 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 PyMethodDef xmlparser_methods[] = {
+ _ELEMENTTREE_XMLPARSER_FEED_METHODDEF
+ _ELEMENTTREE_XMLPARSER_CLOSE_METHODDEF
+ _ELEMENTTREE_XMLPARSER__PARSE_WHOLE_METHODDEF
+ _ELEMENTTREE_XMLPARSER__SETEVENTS_METHODDEF
+ _ELEMENTTREE_XMLPARSER_DOCTYPE_METHODDEF
+ {NULL, NULL}
+};
+
static PyTypeObject XMLParser_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"xml.etree.ElementTree.XMLParser", sizeof(XMLParserObject), 0,
@@ -3706,7 +3874,7 @@ static PyTypeObject XMLParser_Type = {
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
- (initproc)xmlparser_init, /* tp_init */
+ _elementtree_XMLParser___init__, /* tp_init */
PyType_GenericAlloc, /* tp_alloc */
xmlparser_new, /* tp_new */
0, /* tp_free */
@@ -3773,7 +3941,7 @@ PyInit__elementtree(void)
if (expat_capi) {
/* check that it's usable */
if (strcmp(expat_capi->magic, PyExpat_CAPI_MAGIC) != 0 ||
- expat_capi->size < sizeof(struct PyExpat_CAPI) ||
+ (size_t)expat_capi->size < sizeof(struct PyExpat_CAPI) ||
expat_capi->MAJOR_VERSION != XML_MAJOR_VERSION ||
expat_capi->MINOR_VERSION != XML_MINOR_VERSION ||
expat_capi->MICRO_VERSION != XML_MICRO_VERSION) {