diff -r 73a665cc2333 Modules/_elementtree.c --- a/Modules/_elementtree.c Sun May 03 14:54:32 2015 -0700 +++ b/Modules/_elementtree.c Mon May 04 10:03:36 2015 +0300 @@ -370,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) { @@ -658,25 +666,33 @@ element_dealloc(ElementObject* self) /* -------------------------------------------------------------------- */ -static PyObject* -element_append(ElementObject* self, PyObject* args) +/*[clinic input] +_elementtree.Element.append + + 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]*/ { - PyObject* element; - if (!PyArg_ParseTuple(args, "O!:append", &Element_Type, &element)) - return NULL; - - if (element_add_subelement(self, element) < 0) + if (element_add_subelement(self, subelement) < 0) return NULL; Py_RETURN_NONE; } -static PyObject* -element_clearmethod(ElementObject* self, PyObject* args) +/*[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]*/ { - if (!PyArg_ParseTuple(args, ":clear")) - return NULL; - dealloc_extra(self); Py_INCREF(Py_None); @@ -690,15 +706,18 @@ element_clearmethod(ElementObject* self, 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]*/ { 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) @@ -729,8 +748,17 @@ element_copy(ElementObject* self, PyObje 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]*/ { Py_ssize_t i; ElementObject* element; @@ -740,10 +768,6 @@ element_deepcopy(ElementObject* self, Py PyObject* tail; PyObject* id; - PyObject* memo; - if (!PyArg_ParseTuple(args, "O:__deepcopy__", &memo)) - return NULL; - tag = deepcopy(self->tag, memo); if (!tag) return NULL; @@ -814,17 +838,22 @@ element_deepcopy(ElementObject* self, Py 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); 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. */ @@ -840,8 +869,14 @@ element_sizeof(PyObject* myself, PyObjec * 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]*/ { Py_ssize_t i, noattrib; PyObject *instancedict = NULL, *children; @@ -956,6 +991,7 @@ element_setstate_from_attributes(Element /* __setstate__ for Element instance from the Python implementation. * 'state' should be the instance dict. */ + static PyObject * element_setstate_from_Python(ElementObject *self, PyObject *state) { @@ -981,8 +1017,17 @@ element_setstate_from_Python(ElementObje 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, @@ -1036,21 +1081,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, seqlen = 0; - 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; } @@ -1078,23 +1128,26 @@ element_extend(ElementObject* self, PyOb 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]*/ { Py_ssize_t i; - PyObject* tag; - PyObject* namespaces = Py_None; - static char *kwlist[] = {"path", "namespaces", 0}; 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 ); } @@ -1104,7 +1157,7 @@ element_find(ElementObject *self, PyObje for (i = 0; i < self->extra->length; i++) { PyObject* item = self->extra->children[i]; if (Element_CheckExact(item) && - PyObject_RichCompareBool(((ElementObject*)item)->tag, tag, Py_EQ) == 1) { + PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ) == 1) { Py_INCREF(item); return item; } @@ -1113,24 +1166,28 @@ element_find(ElementObject *self, PyObje 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]*/ { Py_ssize_t i; - PyObject* tag; - PyObject* default_value = Py_None; - PyObject* namespaces = Py_None; _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) { @@ -1141,7 +1198,7 @@ element_findtext(ElementObject *self, Py for (i = 0; i < self->extra->length; i++) { ElementObject* item = (ElementObject*) self->extra->children[i]; if (Element_CheckExact(item) && - (PyObject_RichCompareBool(item->tag, tag, Py_EQ) == 1)) { + (PyObject_RichCompareBool(item->tag, path, Py_EQ) == 1)) { PyObject* text = element_get_text(item); if (text == Py_None) return PyUnicode_New(0, 0); @@ -1154,20 +1211,24 @@ element_findtext(ElementObject *self, Py 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]*/ { 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( @@ -1196,36 +1257,41 @@ element_findall(ElementObject *self, PyO 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) +/*[clinic input] +_elementtree.Element.get + + key: object + default: object = None + +[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; - static char* kwlist[] = {"key", "default", 0}; - - PyObject* key; - PyObject* default_value = Py_None; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:get", kwlist, &key, - &default_value)) - return NULL; if (!self->extra || self->extra->attrib == Py_None) value = default_value; @@ -1239,17 +1305,20 @@ element_get(ElementObject* self, PyObjec 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]*/ { Py_ssize_t i; PyObject* list; /* FIXME: report as deprecated? */ - if (!PyArg_ParseTuple(args, ":getchildren")) - return NULL; - if (!self->extra) return PyList_New(0); @@ -1271,25 +1340,30 @@ 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; - return create_elementiter(self, tag, 0); } -static PyObject* -element_itertext(ElementObject* self, PyObject* args) +/*[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]*/ { - if (!PyArg_ParseTuple(args, ":itertext")) - return NULL; - return create_elementiter(self, Py_None, 1); } @@ -1311,14 +1385,21 @@ element_getitem(PyObject* self_, Py_ssiz return self->extra->children[index]; } -static PyObject* -element_insert(ElementObject* self, PyObject* args) +/*[clinic input] +_elementtree.Element.insert + + 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 index, i; - PyObject* element; - if (!PyArg_ParseTuple(args, "nO!:insert", &index, - &Element_Type, &element)) - return NULL; + Py_ssize_t i; if (!self->extra) { if (create_extra(self, NULL) < 0) @@ -1339,32 +1420,38 @@ element_insert(ElementObject* self, PyOb 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) +/*[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 (!PyArg_ParseTuple(args, ":items")) - return NULL; - 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) +/*[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 (!PyArg_ParseTuple(args, ":keys")) - return NULL; - if (!self->extra || self->extra->attrib == Py_None) return PyList_New(0); @@ -1380,16 +1467,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; @@ -1401,15 +1494,20 @@ element_makeelement(PyObject* self, PyOb 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]*/ { Py_ssize_t i; - PyObject* element; - if (!PyArg_ParseTuple(args, "O!:remove", &Element_Type, &element)) - return NULL; - if (!self->extra) { /* element has no children, so raise exception */ PyErr_SetString( @@ -1420,14 +1518,14 @@ element_remove(ElementObject* self, PyOb } for (i = 0; i < self->extra->length; i++) { - if (self->extra->children[i] == element) + if (self->extra->children[i] == subelement) break; - if (PyObject_RichCompareBool(self->extra->children[i], element, Py_EQ) == 1) + if (PyObject_RichCompareBool(self->extra->children[i], subelement, Py_EQ) == 1) break; } 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" @@ -1454,16 +1552,22 @@ element_repr(ElementObject* self) return PyUnicode_FromFormat("", 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; @@ -1744,43 +1848,6 @@ element_ass_subscr(PyObject* self_, PyOb } } -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) { @@ -1877,54 +1944,6 @@ static PySequenceMethods element_as_sequ 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 @@ -2264,23 +2283,24 @@ treebuilder_new(PyTypeObject *type, PyOb 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); } @@ -2600,23 +2620,33 @@ treebuilder_handle_namespace(TreeBuilder /* -------------------------------------------------------------------- */ /* methods (in alphabetical order) */ -static PyObject* -treebuilder_data(TreeBuilderObject* self, PyObject* args) +/*[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]*/ { - PyObject* data; - if (!PyArg_ParseTuple(args, "O:data", &data)) - return NULL; - return treebuilder_handle_data(self, data); } -static PyObject* -treebuilder_end(TreeBuilderObject* self, PyObject* args) +/*[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]*/ { - PyObject* tag; - if (!PyArg_ParseTuple(args, "O:end", &tag)) - return NULL; - return treebuilder_handle_end(self, tag); } @@ -2636,31 +2666,1089 @@ treebuilder_done(TreeBuilderObject* self return res; } -static PyObject* -treebuilder_close(TreeBuilderObject* self, PyObject* args) +/*[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]*/ { - if (!PyArg_ParseTuple(args, ":close")) - return NULL; - return treebuilder_done(self); } -static PyObject* -treebuilder_start(TreeBuilderObject* self, PyObject* args) +/*[clinic input] +_elementtree.TreeBuilder.start + + tag: object + attrs: object = None + / + +[clinic start generated code]*/ + +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 */ + +#include "expat.h" +#include "pyexpat.h" + +/* The PyExpat_CAPI structure is an immutable dispatch table, so it can be + * cached globally without being in per-module state. + */ +static struct PyExpat_CAPI *expat_capi; +#define EXPAT(func) (expat_capi->func) + +static XML_Memory_Handling_Suite ExpatMemoryHandler = { + PyObject_Malloc, PyObject_Realloc, PyObject_Free}; + +typedef struct { + PyObject_HEAD + + XML_Parser parser; + + PyObject *target; + PyObject *entity; + + PyObject *names; + + PyObject *handle_start; + PyObject *handle_data; + PyObject *handle_end; + + PyObject *handle_comment; + PyObject *handle_pi; + PyObject *handle_doctype; + + PyObject *handle_close; + +} XMLParserObject; + +#define XMLParser_CheckExact(op) (Py_TYPE(op) == &XMLParser_Type) + +/* helpers */ + +LOCAL(PyObject*) +makeuniversal(XMLParserObject* self, const char* string) +{ + /* convert a UTF-8 tag/attribute name from the expat parser + to a universal name string */ + + Py_ssize_t size = (Py_ssize_t) strlen(string); + PyObject* key; + PyObject* value; + + /* look the 'raw' name up in the names dictionary */ + key = PyBytes_FromStringAndSize(string, size); + if (!key) + return NULL; + + value = PyDict_GetItem(self->names, key); + + if (value) { + Py_INCREF(value); + } else { + /* new name. convert to universal name, and decode as + necessary */ + + PyObject* tag; + char* p; + Py_ssize_t i; + + /* look for namespace separator */ + for (i = 0; i < size; i++) + if (string[i] == '}') + break; + if (i != size) { + /* convert to universal name */ + tag = PyBytes_FromStringAndSize(NULL, size+1); + if (tag == NULL) { + Py_DECREF(key); + return NULL; + } + p = PyBytes_AS_STRING(tag); + p[0] = '{'; + memcpy(p+1, string, size); + size++; + } else { + /* plain name; use key as tag */ + Py_INCREF(key); + tag = key; + } + + /* decode universal name */ + p = PyBytes_AS_STRING(tag); + value = PyUnicode_DecodeUTF8(p, size, "strict"); + Py_DECREF(tag); + if (!value) { + Py_DECREF(key); + return NULL; + } + + /* add to names dictionary */ + if (PyDict_SetItem(self->names, key, value) < 0) { + Py_DECREF(key); + Py_DECREF(value); + return NULL; + } + } + + Py_DECREF(key); + return value; +} + +/* Set the ParseError exception with the given parameters. + * If message is not NULL, it's used as the error string. Otherwise, the + * message string is the default for the given error_code. +*/ +static void +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 %zd, column %zd", + message ? message : EXPAT(ErrorString)(error_code), + line, column); + if (errmsg == NULL) + return; + + error = PyObject_CallFunction(st->parseerror_obj, "O", errmsg); + Py_DECREF(errmsg); + if (!error) + return; + + /* Add code and position attributes */ + code = PyLong_FromLong((long)error_code); + if (!code) { + Py_DECREF(error); + return; + } + if (PyObject_SetAttrString(error, "code", code) == -1) { + Py_DECREF(error); + Py_DECREF(code); + return; + } + Py_DECREF(code); + + position = Py_BuildValue("(nn)", line, column); + if (!position) { + Py_DECREF(error); + return; + } + if (PyObject_SetAttrString(error, "position", position) == -1) { + Py_DECREF(error); + Py_DECREF(position); + return; + } + Py_DECREF(position); + + PyErr_SetObject(st->parseerror_obj, error); + Py_DECREF(error); +} + +/* -------------------------------------------------------------------- */ +/* handlers */ + +static void +expat_default_handler(XMLParserObject* self, const XML_Char* data_in, + int data_len) +{ + PyObject* key; + PyObject* value; + PyObject* res; + + if (data_len < 2 || data_in[0] != '&') + return; + + if (PyErr_Occurred()) + return; + + key = PyUnicode_DecodeUTF8(data_in + 1, data_len - 2, "strict"); + if (!key) + return; + + value = PyDict_GetItem(self->entity, key); + + if (value) { + if (TreeBuilder_CheckExact(self->target)) + res = treebuilder_handle_data( + (TreeBuilderObject*) self->target, value + ); + else if (self->handle_data) + res = PyObject_CallFunction(self->handle_data, "O", value); + else + res = NULL; + Py_XDECREF(res); + } else if (!PyErr_Occurred()) { + /* Report the first error, not the last */ + char message[128] = "undefined entity "; + strncat(message, data_in, data_len < 100?data_len:100); + expat_set_error( + XML_ERROR_UNDEFINED_ENTITY, + EXPAT(GetErrorLineNumber)(self->parser), + EXPAT(GetErrorColumnNumber)(self->parser), + message + ); + } + + Py_DECREF(key); +} + +static void +expat_start_handler(XMLParserObject* self, const XML_Char* tag_in, + const XML_Char **attrib_in) +{ + PyObject* res; + PyObject* tag; + PyObject* attrib; + int ok; + + if (PyErr_Occurred()) + return; + + /* tag name */ + tag = makeuniversal(self, tag_in); + if (!tag) + return; /* parser will look for errors */ + + /* attributes */ + if (attrib_in[0]) { + attrib = PyDict_New(); + if (!attrib) + 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"); + if (!key || !value) { + Py_XDECREF(value); + Py_XDECREF(key); + Py_DECREF(attrib); + return; + } + ok = PyDict_SetItem(attrib, key, value); + Py_DECREF(value); + Py_DECREF(key); + if (ok < 0) { + Py_DECREF(attrib); + return; + } + attrib_in += 2; + } + } else { + /* Pass an empty dictionary on */ + attrib = PyDict_New(); + if (!attrib) + return; + } + + if (TreeBuilder_CheckExact(self->target)) { + /* shortcut */ + res = treebuilder_handle_start((TreeBuilderObject*) self->target, + tag, attrib); + } + else if (self->handle_start) { + res = PyObject_CallFunction(self->handle_start, "OO", tag, attrib); + } else + res = NULL; + + Py_DECREF(tag); + Py_DECREF(attrib); + + Py_XDECREF(res); +} + +static void +expat_data_handler(XMLParserObject* self, const XML_Char* data_in, + int data_len) +{ + PyObject* data; + PyObject* res; + + if (PyErr_Occurred()) + return; + + data = PyUnicode_DecodeUTF8(data_in, data_len, "strict"); + if (!data) + return; /* parser will look for errors */ + + if (TreeBuilder_CheckExact(self->target)) + /* shortcut */ + res = treebuilder_handle_data((TreeBuilderObject*) self->target, data); + else if (self->handle_data) + res = PyObject_CallFunction(self->handle_data, "O", data); + else + res = NULL; + + Py_DECREF(data); + + Py_XDECREF(res); +} + +static void +expat_end_handler(XMLParserObject* self, const XML_Char* tag_in) { PyObject* tag; - PyObject* attrib = Py_None; - if (!PyArg_ParseTuple(args, "O|O:start", &tag, &attrib)) + PyObject* res = NULL; + + if (PyErr_Occurred()) + return; + + if (TreeBuilder_CheckExact(self->target)) + /* shortcut */ + /* the standard tree builder doesn't look at the end tag */ + res = treebuilder_handle_end( + (TreeBuilderObject*) self->target, Py_None + ); + else if (self->handle_end) { + tag = makeuniversal(self, tag_in); + if (tag) { + res = PyObject_CallFunction(self->handle_end, "O", tag); + Py_DECREF(tag); + } + } + + Py_XDECREF(res); +} + +static void +expat_start_ns_handler(XMLParserObject* self, const XML_Char* prefix, + const XML_Char *uri) +{ + PyObject* sprefix = NULL; + PyObject* suri = NULL; + + if (PyErr_Occurred()) + return; + + if (uri) + suri = PyUnicode_DecodeUTF8(uri, strlen(uri), "strict"); + else + suri = PyUnicode_FromString(""); + if (!suri) + return; + + if (prefix) + sprefix = PyUnicode_DecodeUTF8(prefix, strlen(prefix), "strict"); + else + sprefix = PyUnicode_FromString(""); + if (!sprefix) { + Py_DECREF(suri); + return; + } + + treebuilder_handle_namespace( + (TreeBuilderObject*) self->target, 1, sprefix, suri + ); + + Py_DECREF(sprefix); + Py_DECREF(suri); +} + +static void +expat_end_ns_handler(XMLParserObject* self, const XML_Char* prefix_in) +{ + if (PyErr_Occurred()) + return; + + treebuilder_handle_namespace( + (TreeBuilderObject*) self->target, 0, NULL, NULL + ); +} + +static void +expat_comment_handler(XMLParserObject* self, const XML_Char* comment_in) +{ + PyObject* comment; + PyObject* res; + + if (PyErr_Occurred()) + return; + + if (self->handle_comment) { + comment = PyUnicode_DecodeUTF8(comment_in, strlen(comment_in), "strict"); + if (comment) { + res = PyObject_CallFunction(self->handle_comment, "O", comment); + Py_XDECREF(res); + Py_DECREF(comment); + } + } +} + +static void +expat_start_doctype_handler(XMLParserObject *self, + const XML_Char *doctype_name, + const XML_Char *sysid, + const XML_Char *pubid, + int has_internal_subset) +{ + PyObject *self_pyobj = (PyObject *)self; + PyObject *doctype_name_obj, *sysid_obj, *pubid_obj; + PyObject *parser_doctype = NULL; + PyObject *res = NULL; + + if (PyErr_Occurred()) + return; + + doctype_name_obj = makeuniversal(self, doctype_name); + if (!doctype_name_obj) + return; + + if (sysid) { + sysid_obj = makeuniversal(self, sysid); + if (!sysid_obj) { + Py_DECREF(doctype_name_obj); + return; + } + } else { + Py_INCREF(Py_None); + sysid_obj = Py_None; + } + + if (pubid) { + pubid_obj = makeuniversal(self, pubid); + if (!pubid_obj) { + Py_DECREF(doctype_name_obj); + Py_DECREF(sysid_obj); + return; + } + } else { + Py_INCREF(Py_None); + pubid_obj = Py_None; + } + + /* If the target has a handler for doctype, call it. */ + if (self->handle_doctype) { + res = PyObject_CallFunction(self->handle_doctype, "OOO", + doctype_name_obj, pubid_obj, sysid_obj); + Py_CLEAR(res); + } + + /* Now see if the parser itself has a doctype method. If yes and it's + * a subclass, call it but warn about deprecation. If it's not a subclass + * (i.e. vanilla XMLParser), do nothing. + */ + parser_doctype = PyObject_GetAttrString(self_pyobj, "doctype"); + if (parser_doctype) { + if (!XMLParser_CheckExact(self_pyobj)) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "This method of XMLParser is deprecated. Define" + " doctype() method on the TreeBuilder target.", + 1) < 0) { + goto clear; + } + res = PyObject_CallFunction(parser_doctype, "OOO", + doctype_name_obj, pubid_obj, sysid_obj); + Py_CLEAR(res); + } + } + +clear: + Py_XDECREF(parser_doctype); + Py_DECREF(doctype_name_obj); + Py_DECREF(pubid_obj); + Py_DECREF(sysid_obj); +} + +static void +expat_pi_handler(XMLParserObject* self, const XML_Char* target_in, + const XML_Char* data_in) +{ + PyObject* target; + PyObject* data; + PyObject* res; + + if (PyErr_Occurred()) + return; + + if (self->handle_pi) { + target = PyUnicode_DecodeUTF8(target_in, strlen(target_in), "strict"); + data = PyUnicode_DecodeUTF8(data_in, strlen(data_in), "strict"); + if (target && data) { + res = PyObject_CallFunction(self->handle_pi, "OO", target, data); + Py_XDECREF(res); + Py_DECREF(data); + Py_DECREF(target); + } else { + Py_XDECREF(data); + Py_XDECREF(target); + } + } +} + +/* -------------------------------------------------------------------- */ + +static PyObject * +xmlparser_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + XMLParserObject *self = (XMLParserObject *)type->tp_alloc(type, 0); + if (self) { + self->parser = NULL; + self->target = self->entity = self->names = NULL; + self->handle_start = self->handle_data = self->handle_end = NULL; + self->handle_comment = self->handle_pi = self->handle_close = NULL; + self->handle_doctype = NULL; + } + return (PyObject *)self; +} + +/*[clinic input] +_elementtree.XMLParser.__init__ + + html: object = NULL + target: object = NULL + encoding: str(nullable=True) = NULL + +[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=a870da39c80d7d68]*/ +{ + self->entity = PyDict_New(); + if (!self->entity) + return -1; + + self->names = PyDict_New(); + if (!self->names) { + Py_CLEAR(self->entity); + return -1; + } + + self->parser = EXPAT(ParserCreate_MM)(encoding, &ExpatMemoryHandler, "}"); + if (!self->parser) { + Py_CLEAR(self->entity); + Py_CLEAR(self->names); + PyErr_NoMemory(); + return -1; + } + + if (target) { + Py_INCREF(target); + } else { + target = treebuilder_new(&TreeBuilder_Type, NULL, NULL); + if (!target) { + Py_CLEAR(self->entity); + Py_CLEAR(self->names); + EXPAT(ParserFree)(self->parser); + return -1; + } + } + self->target = target; + + 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->parser, self); + EXPAT(SetElementHandler)( + self->parser, + (XML_StartElementHandler) expat_start_handler, + (XML_EndElementHandler) expat_end_handler + ); + EXPAT(SetDefaultHandlerExpand)( + self->parser, + (XML_DefaultHandler) expat_default_handler + ); + EXPAT(SetCharacterDataHandler)( + self->parser, + (XML_CharacterDataHandler) expat_data_handler + ); + if (self->handle_comment) + EXPAT(SetCommentHandler)( + self->parser, + (XML_CommentHandler) expat_comment_handler + ); + if (self->handle_pi) + EXPAT(SetProcessingInstructionHandler)( + self->parser, + (XML_ProcessingInstructionHandler) expat_pi_handler + ); + EXPAT(SetStartDoctypeDeclHandler)( + self->parser, + (XML_StartDoctypeDeclHandler) expat_start_doctype_handler + ); + EXPAT(SetUnknownEncodingHandler)( + self->parser, + EXPAT(DefaultUnknownEncodingHandler), NULL + ); + + return 0; +} + +static int +xmlparser_gc_traverse(XMLParserObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->handle_close); + Py_VISIT(self->handle_pi); + Py_VISIT(self->handle_comment); + Py_VISIT(self->handle_end); + Py_VISIT(self->handle_data); + Py_VISIT(self->handle_start); + + Py_VISIT(self->target); + Py_VISIT(self->entity); + Py_VISIT(self->names); + + return 0; +} + +static int +xmlparser_gc_clear(XMLParserObject *self) +{ + EXPAT(ParserFree)(self->parser); + + Py_CLEAR(self->handle_close); + Py_CLEAR(self->handle_pi); + Py_CLEAR(self->handle_comment); + Py_CLEAR(self->handle_end); + Py_CLEAR(self->handle_data); + Py_CLEAR(self->handle_start); + Py_CLEAR(self->handle_doctype); + + Py_CLEAR(self->target); + Py_CLEAR(self->entity); + Py_CLEAR(self->names); + + return 0; +} + +static void +xmlparser_dealloc(XMLParserObject* self) +{ + PyObject_GC_UnTrack(self); + xmlparser_gc_clear(self); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +LOCAL(PyObject*) +expat_parse(XMLParserObject* self, const char* data, int data_len, int final) +{ + int ok; + + assert(!PyErr_Occurred()); + ok = EXPAT(Parse)(self->parser, data, data_len, final); + + if (PyErr_Occurred()) return NULL; - return treebuilder_handle_start(self, tag, attrib); + if (!ok) { + expat_set_error( + EXPAT(GetErrorCode)(self->parser), + EXPAT(GetErrorLineNumber)(self->parser), + EXPAT(GetErrorColumnNumber)(self->parser), + NULL + ); + return NULL; + } + + Py_RETURN_NONE; } +/*[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; + res = expat_parse(self, "", 0, 1); + if (!res) + return NULL; + + if (TreeBuilder_CheckExact(self->target)) { + Py_DECREF(res); + return treebuilder_done((TreeBuilderObject*) self->target); + } + else if (self->handle_close) { + Py_DECREF(res); + return PyObject_CallFunction(self->handle_close, ""); + } + else { + return res; + } +} + +/*[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(data)) { + Py_ssize_t data_len; + 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"); + return NULL; + } + /* Explicitly set UTF-8 encoding. Return code ignored. */ + (void)EXPAT(SetEncoding)(self->parser, "utf-8"); + return expat_parse(self, data_ptr, (int)data_len, 0); + } + else { + Py_buffer view; + PyObject *res; + if (PyObject_GetBuffer(data, &view, PyBUF_SIMPLE) < 0) + return NULL; + if (view.len > INT_MAX) { + PyBuffer_Release(&view); + PyErr_SetString(PyExc_OverflowError, "size does not fit in an int"); + return NULL; + } + res = expat_parse(self, view.buf, (int)view.len, 0); + PyBuffer_Release(&view); + return res; + } +} + +/*[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; + PyObject* buffer; + PyObject* temp; + PyObject* res; + + reader = PyObject_GetAttrString(file, "read"); + if (!reader) + return NULL; + + /* read from open file object */ + for (;;) { + + buffer = PyObject_CallFunction(reader, "i", 64*1024); + + if (!buffer) { + /* read failed (e.g. due to KeyboardInterrupt) */ + Py_DECREF(reader); + return NULL; + } + + if (PyUnicode_CheckExact(buffer)) { + /* A unicode object is encoded into bytes using UTF-8 */ + if (PyUnicode_GET_LENGTH(buffer) == 0) { + Py_DECREF(buffer); + break; + } + temp = PyUnicode_AsEncodedString(buffer, "utf-8", "surrogatepass"); + Py_DECREF(buffer); + if (!temp) { + /* Propagate exception from PyUnicode_AsEncodedString */ + Py_DECREF(reader); + return NULL; + } + buffer = temp; + } + else if (!PyBytes_CheckExact(buffer) || PyBytes_GET_SIZE(buffer) == 0) { + Py_DECREF(buffer); + break; + } + + if (PyBytes_GET_SIZE(buffer) > INT_MAX) { + Py_DECREF(buffer); + Py_DECREF(reader); + PyErr_SetString(PyExc_OverflowError, "size does not fit in an int"); + return NULL; + } + res = expat_parse( + self, PyBytes_AS_STRING(buffer), (int)PyBytes_GET_SIZE(buffer), 0 + ); + + Py_DECREF(buffer); + + if (!res) { + Py_DECREF(reader); + return NULL; + } + Py_DECREF(res); + + } + + Py_DECREF(reader); + + res = expat_parse(self, "", 0, 1); + + if (res && TreeBuilder_CheckExact(self->target)) { + Py_DECREF(res); + return treebuilder_done((TreeBuilderObject*) self->target); + } + + return res; +} + +/*[clinic input] +_elementtree.XMLParser.doctype + +[clinic start generated code]*/ + +static PyObject * +_elementtree_XMLParser_doctype_impl(XMLParserObject *self) +/*[clinic end generated code: output=d09fdb9c45f3a602 input=20d5e0febf902a2f]*/ +{ + Py_RETURN_NONE; +} + +/*[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; + TreeBuilderObject *target; + PyObject *events_seq; + + if (!TreeBuilder_CheckExact(self->target)) { + PyErr_SetString( + PyExc_TypeError, + "event handling only supported for ElementTree.TreeBuilder " + "targets" + ); + return NULL; + } + + target = (TreeBuilderObject*) self->target; + + Py_INCREF(events_queue); + Py_XDECREF(target->events); + target->events = events_queue; + + /* clear out existing events */ + Py_CLEAR(target->start_event_obj); + Py_CLEAR(target->end_event_obj); + Py_CLEAR(target->start_ns_event_obj); + Py_CLEAR(target->end_ns_event_obj); + + if (events_to_report == Py_None) { + /* default is "end" only */ + target->end_event_obj = PyUnicode_FromString("end"); + Py_RETURN_NONE; + } + + if (!(events_seq = PySequence_Fast(events_to_report, + "events must be a sequence"))) { + return NULL; + } + + seqlen = PySequence_Size(events_seq); + for (i = 0; i < seqlen; ++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); + } 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; + } 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; + } 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; + 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; + EXPAT(SetNamespaceDeclHandler)( + self->parser, + (XML_StartNamespaceDeclHandler) expat_start_ns_handler, + (XML_EndNamespaceDeclHandler) expat_end_ns_handler + ); + } else { + Py_DECREF(events_seq); + PyErr_Format(PyExc_ValueError, "unknown event '%s'", event_name); + return NULL; + } + } + + Py_DECREF(events_seq); + Py_RETURN_NONE; +} + +static PyObject* +xmlparser_getattro(XMLParserObject* self, PyObject* nameobj) +{ + if (PyUnicode_Check(nameobj)) { + PyObject* res; + if (PyUnicode_CompareWithASCIIString(nameobj, "entity") == 0) + res = self->entity; + else if (PyUnicode_CompareWithASCIIString(nameobj, "target") == 0) + res = self->target; + else if (PyUnicode_CompareWithASCIIString(nameobj, "version") == 0) { + return PyUnicode_FromFormat( + "Expat %d.%d.%d", XML_MAJOR_VERSION, + XML_MINOR_VERSION, XML_MICRO_VERSION); + } + else + goto generic; + + Py_INCREF(res); + return res; + } + generic: + 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[] = { - {"data", (PyCFunction) treebuilder_data, METH_VARARGS}, - {"start", (PyCFunction) treebuilder_start, METH_VARARGS}, - {"end", (PyCFunction) treebuilder_end, METH_VARARGS}, - {"close", (PyCFunction) treebuilder_close, METH_VARARGS}, + _ELEMENTTREE_TREEBUILDER_DATA_METHODDEF + _ELEMENTTREE_TREEBUILDER_START_METHODDEF + _ELEMENTTREE_TREEBUILDER_END_METHODDEF + _ELEMENTTREE_TREEBUILDER_CLOSE_METHODDEF {NULL, NULL} }; @@ -2700,953 +3788,21 @@ static PyTypeObject TreeBuilder_Type = { 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - (initproc)treebuilder_init, /* tp_init */ + _elementtree_TreeBuilder___init__, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ treebuilder_new, /* tp_new */ 0, /* tp_free */ }; -/* ==================================================================== */ -/* the expat interface */ - -#include "expat.h" -#include "pyexpat.h" - -/* The PyExpat_CAPI structure is an immutable dispatch table, so it can be - * cached globally without being in per-module state. - */ -static struct PyExpat_CAPI *expat_capi; -#define EXPAT(func) (expat_capi->func) - -static XML_Memory_Handling_Suite ExpatMemoryHandler = { - PyObject_Malloc, PyObject_Realloc, PyObject_Free}; - -typedef struct { - PyObject_HEAD - - XML_Parser parser; - - PyObject *target; - PyObject *entity; - - PyObject *names; - - PyObject *handle_start; - PyObject *handle_data; - PyObject *handle_end; - - PyObject *handle_comment; - PyObject *handle_pi; - PyObject *handle_doctype; - - PyObject *handle_close; - -} XMLParserObject; - -#define XMLParser_CheckExact(op) (Py_TYPE(op) == &XMLParser_Type) - -/* helpers */ - -LOCAL(PyObject*) -makeuniversal(XMLParserObject* self, const char* string) -{ - /* convert a UTF-8 tag/attribute name from the expat parser - to a universal name string */ - - Py_ssize_t size = (Py_ssize_t) strlen(string); - PyObject* key; - PyObject* value; - - /* look the 'raw' name up in the names dictionary */ - key = PyBytes_FromStringAndSize(string, size); - if (!key) - return NULL; - - value = PyDict_GetItem(self->names, key); - - if (value) { - Py_INCREF(value); - } else { - /* new name. convert to universal name, and decode as - necessary */ - - PyObject* tag; - char* p; - Py_ssize_t i; - - /* look for namespace separator */ - for (i = 0; i < size; i++) - if (string[i] == '}') - break; - if (i != size) { - /* convert to universal name */ - tag = PyBytes_FromStringAndSize(NULL, size+1); - if (tag == NULL) { - Py_DECREF(key); - return NULL; - } - p = PyBytes_AS_STRING(tag); - p[0] = '{'; - memcpy(p+1, string, size); - size++; - } else { - /* plain name; use key as tag */ - Py_INCREF(key); - tag = key; - } - - /* decode universal name */ - p = PyBytes_AS_STRING(tag); - value = PyUnicode_DecodeUTF8(p, size, "strict"); - Py_DECREF(tag); - if (!value) { - Py_DECREF(key); - return NULL; - } - - /* add to names dictionary */ - if (PyDict_SetItem(self->names, key, value) < 0) { - Py_DECREF(key); - Py_DECREF(value); - return NULL; - } - } - - Py_DECREF(key); - return value; -} - -/* Set the ParseError exception with the given parameters. - * If message is not NULL, it's used as the error string. Otherwise, the - * message string is the default for the given error_code. -*/ -static void -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 %zd, column %zd", - message ? message : EXPAT(ErrorString)(error_code), - line, column); - if (errmsg == NULL) - return; - - error = PyObject_CallFunction(st->parseerror_obj, "O", errmsg); - Py_DECREF(errmsg); - if (!error) - return; - - /* Add code and position attributes */ - code = PyLong_FromLong((long)error_code); - if (!code) { - Py_DECREF(error); - return; - } - if (PyObject_SetAttrString(error, "code", code) == -1) { - Py_DECREF(error); - Py_DECREF(code); - return; - } - Py_DECREF(code); - - position = Py_BuildValue("(nn)", line, column); - if (!position) { - Py_DECREF(error); - return; - } - if (PyObject_SetAttrString(error, "position", position) == -1) { - Py_DECREF(error); - Py_DECREF(position); - return; - } - Py_DECREF(position); - - PyErr_SetObject(st->parseerror_obj, error); - Py_DECREF(error); -} - -/* -------------------------------------------------------------------- */ -/* handlers */ - -static void -expat_default_handler(XMLParserObject* self, const XML_Char* data_in, - int data_len) -{ - PyObject* key; - PyObject* value; - PyObject* res; - - if (data_len < 2 || data_in[0] != '&') - return; - - if (PyErr_Occurred()) - return; - - key = PyUnicode_DecodeUTF8(data_in + 1, data_len - 2, "strict"); - if (!key) - return; - - value = PyDict_GetItem(self->entity, key); - - if (value) { - if (TreeBuilder_CheckExact(self->target)) - res = treebuilder_handle_data( - (TreeBuilderObject*) self->target, value - ); - else if (self->handle_data) - res = PyObject_CallFunction(self->handle_data, "O", value); - else - res = NULL; - Py_XDECREF(res); - } else if (!PyErr_Occurred()) { - /* Report the first error, not the last */ - char message[128] = "undefined entity "; - strncat(message, data_in, data_len < 100?data_len:100); - expat_set_error( - XML_ERROR_UNDEFINED_ENTITY, - EXPAT(GetErrorLineNumber)(self->parser), - EXPAT(GetErrorColumnNumber)(self->parser), - message - ); - } - - Py_DECREF(key); -} - -static void -expat_start_handler(XMLParserObject* self, const XML_Char* tag_in, - const XML_Char **attrib_in) -{ - PyObject* res; - PyObject* tag; - PyObject* attrib; - int ok; - - if (PyErr_Occurred()) - return; - - /* tag name */ - tag = makeuniversal(self, tag_in); - if (!tag) - return; /* parser will look for errors */ - - /* attributes */ - if (attrib_in[0]) { - attrib = PyDict_New(); - if (!attrib) - 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"); - if (!key || !value) { - Py_XDECREF(value); - Py_XDECREF(key); - Py_DECREF(attrib); - return; - } - ok = PyDict_SetItem(attrib, key, value); - Py_DECREF(value); - Py_DECREF(key); - if (ok < 0) { - Py_DECREF(attrib); - return; - } - attrib_in += 2; - } - } else { - /* Pass an empty dictionary on */ - attrib = PyDict_New(); - if (!attrib) - return; - } - - if (TreeBuilder_CheckExact(self->target)) { - /* shortcut */ - res = treebuilder_handle_start((TreeBuilderObject*) self->target, - tag, attrib); - } - else if (self->handle_start) { - res = PyObject_CallFunction(self->handle_start, "OO", tag, attrib); - } else - res = NULL; - - Py_DECREF(tag); - Py_DECREF(attrib); - - Py_XDECREF(res); -} - -static void -expat_data_handler(XMLParserObject* self, const XML_Char* data_in, - int data_len) -{ - PyObject* data; - PyObject* res; - - if (PyErr_Occurred()) - return; - - data = PyUnicode_DecodeUTF8(data_in, data_len, "strict"); - if (!data) - return; /* parser will look for errors */ - - if (TreeBuilder_CheckExact(self->target)) - /* shortcut */ - res = treebuilder_handle_data((TreeBuilderObject*) self->target, data); - else if (self->handle_data) - res = PyObject_CallFunction(self->handle_data, "O", data); - else - res = NULL; - - Py_DECREF(data); - - Py_XDECREF(res); -} - -static void -expat_end_handler(XMLParserObject* self, const XML_Char* tag_in) -{ - PyObject* tag; - PyObject* res = NULL; - - if (PyErr_Occurred()) - return; - - if (TreeBuilder_CheckExact(self->target)) - /* shortcut */ - /* the standard tree builder doesn't look at the end tag */ - res = treebuilder_handle_end( - (TreeBuilderObject*) self->target, Py_None - ); - else if (self->handle_end) { - tag = makeuniversal(self, tag_in); - if (tag) { - res = PyObject_CallFunction(self->handle_end, "O", tag); - Py_DECREF(tag); - } - } - - Py_XDECREF(res); -} - -static void -expat_start_ns_handler(XMLParserObject* self, const XML_Char* prefix, - const XML_Char *uri) -{ - PyObject* sprefix = NULL; - PyObject* suri = NULL; - - if (PyErr_Occurred()) - return; - - if (uri) - suri = PyUnicode_DecodeUTF8(uri, strlen(uri), "strict"); - else - suri = PyUnicode_FromString(""); - if (!suri) - return; - - if (prefix) - sprefix = PyUnicode_DecodeUTF8(prefix, strlen(prefix), "strict"); - else - sprefix = PyUnicode_FromString(""); - if (!sprefix) { - Py_DECREF(suri); - return; - } - - treebuilder_handle_namespace( - (TreeBuilderObject*) self->target, 1, sprefix, suri - ); - - Py_DECREF(sprefix); - Py_DECREF(suri); -} - -static void -expat_end_ns_handler(XMLParserObject* self, const XML_Char* prefix_in) -{ - if (PyErr_Occurred()) - return; - - treebuilder_handle_namespace( - (TreeBuilderObject*) self->target, 0, NULL, NULL - ); -} - -static void -expat_comment_handler(XMLParserObject* self, const XML_Char* comment_in) -{ - PyObject* comment; - PyObject* res; - - if (PyErr_Occurred()) - return; - - if (self->handle_comment) { - comment = PyUnicode_DecodeUTF8(comment_in, strlen(comment_in), "strict"); - if (comment) { - res = PyObject_CallFunction(self->handle_comment, "O", comment); - Py_XDECREF(res); - Py_DECREF(comment); - } - } -} - -static void -expat_start_doctype_handler(XMLParserObject *self, - const XML_Char *doctype_name, - const XML_Char *sysid, - const XML_Char *pubid, - int has_internal_subset) -{ - PyObject *self_pyobj = (PyObject *)self; - PyObject *doctype_name_obj, *sysid_obj, *pubid_obj; - PyObject *parser_doctype = NULL; - PyObject *res = NULL; - - if (PyErr_Occurred()) - return; - - doctype_name_obj = makeuniversal(self, doctype_name); - if (!doctype_name_obj) - return; - - if (sysid) { - sysid_obj = makeuniversal(self, sysid); - if (!sysid_obj) { - Py_DECREF(doctype_name_obj); - return; - } - } else { - Py_INCREF(Py_None); - sysid_obj = Py_None; - } - - if (pubid) { - pubid_obj = makeuniversal(self, pubid); - if (!pubid_obj) { - Py_DECREF(doctype_name_obj); - Py_DECREF(sysid_obj); - return; - } - } else { - Py_INCREF(Py_None); - pubid_obj = Py_None; - } - - /* If the target has a handler for doctype, call it. */ - if (self->handle_doctype) { - res = PyObject_CallFunction(self->handle_doctype, "OOO", - doctype_name_obj, pubid_obj, sysid_obj); - Py_CLEAR(res); - } - - /* Now see if the parser itself has a doctype method. If yes and it's - * a subclass, call it but warn about deprecation. If it's not a subclass - * (i.e. vanilla XMLParser), do nothing. - */ - parser_doctype = PyObject_GetAttrString(self_pyobj, "doctype"); - if (parser_doctype) { - if (!XMLParser_CheckExact(self_pyobj)) { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "This method of XMLParser is deprecated. Define" - " doctype() method on the TreeBuilder target.", - 1) < 0) { - goto clear; - } - res = PyObject_CallFunction(parser_doctype, "OOO", - doctype_name_obj, pubid_obj, sysid_obj); - Py_CLEAR(res); - } - } - -clear: - Py_XDECREF(parser_doctype); - Py_DECREF(doctype_name_obj); - Py_DECREF(pubid_obj); - Py_DECREF(sysid_obj); -} - -static void -expat_pi_handler(XMLParserObject* self, const XML_Char* target_in, - const XML_Char* data_in) -{ - PyObject* target; - PyObject* data; - PyObject* res; - - if (PyErr_Occurred()) - return; - - if (self->handle_pi) { - target = PyUnicode_DecodeUTF8(target_in, strlen(target_in), "strict"); - data = PyUnicode_DecodeUTF8(data_in, strlen(data_in), "strict"); - if (target && data) { - res = PyObject_CallFunction(self->handle_pi, "OO", target, data); - Py_XDECREF(res); - Py_DECREF(data); - Py_DECREF(target); - } else { - Py_XDECREF(data); - Py_XDECREF(target); - } - } -} - -/* -------------------------------------------------------------------- */ - -static PyObject * -xmlparser_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - XMLParserObject *self = (XMLParserObject *)type->tp_alloc(type, 0); - if (self) { - self->parser = NULL; - self->target = self->entity = self->names = NULL; - self->handle_start = self->handle_data = self->handle_end = NULL; - self->handle_comment = self->handle_pi = self->handle_close = NULL; - self->handle_doctype = NULL; - } - 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}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOz:XMLParser", kwlist, - &html, &target, &encoding)) { - return -1; - } - - self_xp->entity = PyDict_New(); - if (!self_xp->entity) - return -1; - - self_xp->names = PyDict_New(); - if (!self_xp->names) { - Py_CLEAR(self_xp->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); - PyErr_NoMemory(); - return -1; - } - - if (target) { - Py_INCREF(target); - } 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); - return -1; - } - } - self_xp->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"); - - PyErr_Clear(); - - /* configure parser */ - EXPAT(SetUserData)(self_xp->parser, self_xp); - EXPAT(SetElementHandler)( - self_xp->parser, - (XML_StartElementHandler) expat_start_handler, - (XML_EndElementHandler) expat_end_handler - ); - EXPAT(SetDefaultHandlerExpand)( - self_xp->parser, - (XML_DefaultHandler) expat_default_handler - ); - EXPAT(SetCharacterDataHandler)( - self_xp->parser, - (XML_CharacterDataHandler) expat_data_handler - ); - if (self_xp->handle_comment) - EXPAT(SetCommentHandler)( - self_xp->parser, - (XML_CommentHandler) expat_comment_handler - ); - if (self_xp->handle_pi) - EXPAT(SetProcessingInstructionHandler)( - self_xp->parser, - (XML_ProcessingInstructionHandler) expat_pi_handler - ); - EXPAT(SetStartDoctypeDeclHandler)( - self_xp->parser, - (XML_StartDoctypeDeclHandler) expat_start_doctype_handler - ); - EXPAT(SetUnknownEncodingHandler)( - self_xp->parser, - EXPAT(DefaultUnknownEncodingHandler), NULL - ); - - return 0; -} - -static int -xmlparser_gc_traverse(XMLParserObject *self, visitproc visit, void *arg) -{ - Py_VISIT(self->handle_close); - Py_VISIT(self->handle_pi); - Py_VISIT(self->handle_comment); - Py_VISIT(self->handle_end); - Py_VISIT(self->handle_data); - Py_VISIT(self->handle_start); - - Py_VISIT(self->target); - Py_VISIT(self->entity); - Py_VISIT(self->names); - - return 0; -} - -static int -xmlparser_gc_clear(XMLParserObject *self) -{ - EXPAT(ParserFree)(self->parser); - - Py_CLEAR(self->handle_close); - Py_CLEAR(self->handle_pi); - Py_CLEAR(self->handle_comment); - Py_CLEAR(self->handle_end); - Py_CLEAR(self->handle_data); - Py_CLEAR(self->handle_start); - Py_CLEAR(self->handle_doctype); - - Py_CLEAR(self->target); - Py_CLEAR(self->entity); - Py_CLEAR(self->names); - - return 0; -} - -static void -xmlparser_dealloc(XMLParserObject* self) -{ - PyObject_GC_UnTrack(self); - xmlparser_gc_clear(self); - Py_TYPE(self)->tp_free((PyObject *)self); -} - -LOCAL(PyObject*) -expat_parse(XMLParserObject* self, const char* data, int data_len, int final) -{ - int ok; - - assert(!PyErr_Occurred()); - ok = EXPAT(Parse)(self->parser, data, data_len, final); - - if (PyErr_Occurred()) - return NULL; - - if (!ok) { - expat_set_error( - EXPAT(GetErrorCode)(self->parser), - EXPAT(GetErrorLineNumber)(self->parser), - EXPAT(GetErrorColumnNumber)(self->parser), - NULL - ); - return NULL; - } - - Py_RETURN_NONE; -} - -static PyObject* -xmlparser_close(XMLParserObject* self, PyObject* args) -{ - /* end feeding data to parser */ - - PyObject* res; - if (!PyArg_ParseTuple(args, ":close")) - return NULL; - - res = expat_parse(self, "", 0, 1); - if (!res) - return NULL; - - if (TreeBuilder_CheckExact(self->target)) { - Py_DECREF(res); - return treebuilder_done((TreeBuilderObject*) self->target); - } - else if (self->handle_close) { - Py_DECREF(res); - return PyObject_CallFunction(self->handle_close, ""); - } - else { - return res; - } -} - -static PyObject* -xmlparser_feed(XMLParserObject* self, PyObject* arg) -{ - /* feed data to parser */ - - if (PyUnicode_Check(arg)) { - Py_ssize_t data_len; - const char *data = PyUnicode_AsUTF8AndSize(arg, &data_len); - if (data == NULL) - return NULL; - if (data_len > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, "size does not fit in an int"); - return NULL; - } - /* Explicitly set UTF-8 encoding. Return code ignored. */ - (void)EXPAT(SetEncoding)(self->parser, "utf-8"); - return expat_parse(self, data, (int)data_len, 0); - } - else { - Py_buffer view; - PyObject *res; - if (PyObject_GetBuffer(arg, &view, PyBUF_SIMPLE) < 0) - return NULL; - if (view.len > INT_MAX) { - PyBuffer_Release(&view); - PyErr_SetString(PyExc_OverflowError, "size does not fit in an int"); - return NULL; - } - res = expat_parse(self, view.buf, (int)view.len, 0); - PyBuffer_Release(&view); - return res; - } -} - -static PyObject* -xmlparser_parse_whole(XMLParserObject* self, PyObject* args) -{ - /* (internal) parse the whole input, until end of stream */ - PyObject* reader; - PyObject* buffer; - PyObject* temp; - PyObject* res; - - PyObject* fileobj; - if (!PyArg_ParseTuple(args, "O:_parse", &fileobj)) - return NULL; - - reader = PyObject_GetAttrString(fileobj, "read"); - if (!reader) - return NULL; - - /* read from open file object */ - for (;;) { - - buffer = PyObject_CallFunction(reader, "i", 64*1024); - - if (!buffer) { - /* read failed (e.g. due to KeyboardInterrupt) */ - Py_DECREF(reader); - return NULL; - } - - if (PyUnicode_CheckExact(buffer)) { - /* A unicode object is encoded into bytes using UTF-8 */ - if (PyUnicode_GET_LENGTH(buffer) == 0) { - Py_DECREF(buffer); - break; - } - temp = PyUnicode_AsEncodedString(buffer, "utf-8", "surrogatepass"); - Py_DECREF(buffer); - if (!temp) { - /* Propagate exception from PyUnicode_AsEncodedString */ - Py_DECREF(reader); - return NULL; - } - buffer = temp; - } - else if (!PyBytes_CheckExact(buffer) || PyBytes_GET_SIZE(buffer) == 0) { - Py_DECREF(buffer); - break; - } - - if (PyBytes_GET_SIZE(buffer) > INT_MAX) { - Py_DECREF(buffer); - Py_DECREF(reader); - PyErr_SetString(PyExc_OverflowError, "size does not fit in an int"); - return NULL; - } - res = expat_parse( - self, PyBytes_AS_STRING(buffer), (int)PyBytes_GET_SIZE(buffer), 0 - ); - - Py_DECREF(buffer); - - if (!res) { - Py_DECREF(reader); - return NULL; - } - Py_DECREF(res); - - } - - Py_DECREF(reader); - - res = expat_parse(self, "", 0, 1); - - if (res && TreeBuilder_CheckExact(self->target)) { - Py_DECREF(res); - return treebuilder_done((TreeBuilderObject*) self->target); - } - - return res; -} - -static PyObject* -xmlparser_doctype(XMLParserObject *self, PyObject *args) -{ - Py_RETURN_NONE; -} - -static PyObject* -xmlparser_setevents(XMLParserObject *self, PyObject* args) -{ - /* activate element event reporting */ - Py_ssize_t i, seqlen; - 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( - PyExc_TypeError, - "event handling only supported for ElementTree.TreeBuilder " - "targets" - ); - return NULL; - } - - target = (TreeBuilderObject*) self->target; - - Py_INCREF(events_queue); - Py_XDECREF(target->events); - target->events = events_queue; - - /* clear out existing events */ - Py_CLEAR(target->start_event_obj); - Py_CLEAR(target->end_event_obj); - Py_CLEAR(target->start_ns_event_obj); - Py_CLEAR(target->end_ns_event_obj); - - if (events_to_report == Py_None) { - /* default is "end" only */ - target->end_event_obj = PyUnicode_FromString("end"); - Py_RETURN_NONE; - } - - if (!(events_seq = PySequence_Fast(events_to_report, - "events must be a sequence"))) { - return NULL; - } - - seqlen = PySequence_Size(events_seq); - for (i = 0; i < seqlen; ++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); - } 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; - } 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; - } 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; - 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; - EXPAT(SetNamespaceDeclHandler)( - self->parser, - (XML_StartNamespaceDeclHandler) expat_start_ns_handler, - (XML_EndNamespaceDeclHandler) expat_end_ns_handler - ); - } else { - Py_DECREF(events_seq); - PyErr_Format(PyExc_ValueError, "unknown event '%s'", event_name); - return NULL; - } - } - - Py_DECREF(events_seq); - 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}, + _ELEMENTTREE_XMLPARSER_FEED_METHODDEF + _ELEMENTTREE_XMLPARSER_CLOSE_METHODDEF + _ELEMENTTREE_XMLPARSER__PARSE_WHOLE_METHODDEF + _ELEMENTTREE_XMLPARSER__SETEVENTS_METHODDEF + _ELEMENTTREE_XMLPARSER_DOCTYPE_METHODDEF {NULL, NULL} }; -static PyObject* -xmlparser_getattro(XMLParserObject* self, PyObject* nameobj) -{ - if (PyUnicode_Check(nameobj)) { - PyObject* res; - if (PyUnicode_CompareWithASCIIString(nameobj, "entity") == 0) - res = self->entity; - else if (PyUnicode_CompareWithASCIIString(nameobj, "target") == 0) - res = self->target; - else if (PyUnicode_CompareWithASCIIString(nameobj, "version") == 0) { - return PyUnicode_FromFormat( - "Expat %d.%d.%d", XML_MAJOR_VERSION, - XML_MINOR_VERSION, XML_MICRO_VERSION); - } - else - goto generic; - - Py_INCREF(res); - return res; - } - generic: - return PyObject_GenericGetAttr((PyObject*) self, nameobj); -} - static PyTypeObject XMLParser_Type = { PyVarObject_HEAD_INIT(NULL, 0) "xml.etree.ElementTree.XMLParser", sizeof(XMLParserObject), 0, @@ -3683,7 +3839,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 */ diff -r 73a665cc2333 Modules/clinic/_elementtree.c.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modules/clinic/_elementtree.c.h Mon May 04 10:03:36 2015 +0300 @@ -0,0 +1,666 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_elementtree_Element_append__doc__, +"append($self, subelement, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_APPEND_METHODDEF \ + {"append", (PyCFunction)_elementtree_Element_append, METH_O, _elementtree_Element_append__doc__}, + +static PyObject * +_elementtree_Element_append_impl(ElementObject *self, PyObject *subelement); + +static PyObject * +_elementtree_Element_append(ElementObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *subelement; + + if (!PyArg_Parse(arg, "O!:append", &Element_Type, &subelement)) + goto exit; + return_value = _elementtree_Element_append_impl(self, subelement); + +exit: + return return_value; +} + +PyDoc_STRVAR(_elementtree_Element_clear__doc__, +"clear($self, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_CLEAR_METHODDEF \ + {"clear", (PyCFunction)_elementtree_Element_clear, METH_NOARGS, _elementtree_Element_clear__doc__}, + +static PyObject * +_elementtree_Element_clear_impl(ElementObject *self); + +static PyObject * +_elementtree_Element_clear(ElementObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _elementtree_Element_clear_impl(self); +} + +PyDoc_STRVAR(_elementtree_Element___copy____doc__, +"__copy__($self, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT___COPY___METHODDEF \ + {"__copy__", (PyCFunction)_elementtree_Element___copy__, METH_NOARGS, _elementtree_Element___copy____doc__}, + +static PyObject * +_elementtree_Element___copy___impl(ElementObject *self); + +static PyObject * +_elementtree_Element___copy__(ElementObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _elementtree_Element___copy___impl(self); +} + +PyDoc_STRVAR(_elementtree_Element___deepcopy____doc__, +"__deepcopy__($self, memo, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT___DEEPCOPY___METHODDEF \ + {"__deepcopy__", (PyCFunction)_elementtree_Element___deepcopy__, METH_O, _elementtree_Element___deepcopy____doc__}, + +PyDoc_STRVAR(_elementtree_Element___sizeof____doc__, +"__sizeof__($self, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT___SIZEOF___METHODDEF \ + {"__sizeof__", (PyCFunction)_elementtree_Element___sizeof__, METH_NOARGS, _elementtree_Element___sizeof____doc__}, + +static Py_ssize_t +_elementtree_Element___sizeof___impl(ElementObject *self); + +static PyObject * +_elementtree_Element___sizeof__(ElementObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + Py_ssize_t _return_value; + + _return_value = _elementtree_Element___sizeof___impl(self); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_elementtree_Element___getstate____doc__, +"__getstate__($self, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT___GETSTATE___METHODDEF \ + {"__getstate__", (PyCFunction)_elementtree_Element___getstate__, METH_NOARGS, _elementtree_Element___getstate____doc__}, + +static PyObject * +_elementtree_Element___getstate___impl(ElementObject *self); + +static PyObject * +_elementtree_Element___getstate__(ElementObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _elementtree_Element___getstate___impl(self); +} + +PyDoc_STRVAR(_elementtree_Element___setstate____doc__, +"__setstate__($self, state, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT___SETSTATE___METHODDEF \ + {"__setstate__", (PyCFunction)_elementtree_Element___setstate__, METH_O, _elementtree_Element___setstate____doc__}, + +PyDoc_STRVAR(_elementtree_Element_extend__doc__, +"extend($self, elements, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_EXTEND_METHODDEF \ + {"extend", (PyCFunction)_elementtree_Element_extend, METH_O, _elementtree_Element_extend__doc__}, + +PyDoc_STRVAR(_elementtree_Element_find__doc__, +"find($self, /, path, namespaces=None)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_FIND_METHODDEF \ + {"find", (PyCFunction)_elementtree_Element_find, METH_VARARGS|METH_KEYWORDS, _elementtree_Element_find__doc__}, + +static PyObject * +_elementtree_Element_find_impl(ElementObject *self, PyObject *path, + PyObject *namespaces); + +static PyObject * +_elementtree_Element_find(ElementObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "namespaces", NULL}; + PyObject *path; + PyObject *namespaces = Py_None; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:find", _keywords, + &path, &namespaces)) + goto exit; + return_value = _elementtree_Element_find_impl(self, path, namespaces); + +exit: + return return_value; +} + +PyDoc_STRVAR(_elementtree_Element_findtext__doc__, +"findtext($self, /, path, default=None, namespaces=None)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_FINDTEXT_METHODDEF \ + {"findtext", (PyCFunction)_elementtree_Element_findtext, METH_VARARGS|METH_KEYWORDS, _elementtree_Element_findtext__doc__}, + +static PyObject * +_elementtree_Element_findtext_impl(ElementObject *self, PyObject *path, + PyObject *default_value, + PyObject *namespaces); + +static PyObject * +_elementtree_Element_findtext(ElementObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "default", "namespaces", NULL}; + PyObject *path; + PyObject *default_value = Py_None; + PyObject *namespaces = Py_None; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OO:findtext", _keywords, + &path, &default_value, &namespaces)) + goto exit; + return_value = _elementtree_Element_findtext_impl(self, path, default_value, namespaces); + +exit: + return return_value; +} + +PyDoc_STRVAR(_elementtree_Element_findall__doc__, +"findall($self, /, path, namespaces=None)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_FINDALL_METHODDEF \ + {"findall", (PyCFunction)_elementtree_Element_findall, METH_VARARGS|METH_KEYWORDS, _elementtree_Element_findall__doc__}, + +static PyObject * +_elementtree_Element_findall_impl(ElementObject *self, PyObject *path, + PyObject *namespaces); + +static PyObject * +_elementtree_Element_findall(ElementObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "namespaces", NULL}; + PyObject *path; + PyObject *namespaces = Py_None; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:findall", _keywords, + &path, &namespaces)) + goto exit; + return_value = _elementtree_Element_findall_impl(self, path, namespaces); + +exit: + return return_value; +} + +PyDoc_STRVAR(_elementtree_Element_iterfind__doc__, +"iterfind($self, /, path, namespaces=None)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_ITERFIND_METHODDEF \ + {"iterfind", (PyCFunction)_elementtree_Element_iterfind, METH_VARARGS|METH_KEYWORDS, _elementtree_Element_iterfind__doc__}, + +static PyObject * +_elementtree_Element_iterfind_impl(ElementObject *self, PyObject *path, + PyObject *namespaces); + +static PyObject * +_elementtree_Element_iterfind(ElementObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "namespaces", NULL}; + PyObject *path; + PyObject *namespaces = Py_None; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:iterfind", _keywords, + &path, &namespaces)) + goto exit; + return_value = _elementtree_Element_iterfind_impl(self, path, namespaces); + +exit: + return return_value; +} + +PyDoc_STRVAR(_elementtree_Element_get__doc__, +"get($self, /, key, default=None)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_GET_METHODDEF \ + {"get", (PyCFunction)_elementtree_Element_get, METH_VARARGS|METH_KEYWORDS, _elementtree_Element_get__doc__}, + +static PyObject * +_elementtree_Element_get_impl(ElementObject *self, PyObject *key, + PyObject *default_value); + +static PyObject * +_elementtree_Element_get(ElementObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"key", "default", NULL}; + PyObject *key; + PyObject *default_value = Py_None; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:get", _keywords, + &key, &default_value)) + goto exit; + return_value = _elementtree_Element_get_impl(self, key, default_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_elementtree_Element_getchildren__doc__, +"getchildren($self, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_GETCHILDREN_METHODDEF \ + {"getchildren", (PyCFunction)_elementtree_Element_getchildren, METH_NOARGS, _elementtree_Element_getchildren__doc__}, + +static PyObject * +_elementtree_Element_getchildren_impl(ElementObject *self); + +static PyObject * +_elementtree_Element_getchildren(ElementObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _elementtree_Element_getchildren_impl(self); +} + +PyDoc_STRVAR(_elementtree_Element_iter__doc__, +"iter($self, /, tag=None)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_ITER_METHODDEF \ + {"iter", (PyCFunction)_elementtree_Element_iter, METH_VARARGS|METH_KEYWORDS, _elementtree_Element_iter__doc__}, + +static PyObject * +_elementtree_Element_iter_impl(ElementObject *self, PyObject *tag); + +static PyObject * +_elementtree_Element_iter(ElementObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"tag", NULL}; + PyObject *tag = Py_None; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:iter", _keywords, + &tag)) + goto exit; + return_value = _elementtree_Element_iter_impl(self, tag); + +exit: + return return_value; +} + +PyDoc_STRVAR(_elementtree_Element_itertext__doc__, +"itertext($self, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_ITERTEXT_METHODDEF \ + {"itertext", (PyCFunction)_elementtree_Element_itertext, METH_NOARGS, _elementtree_Element_itertext__doc__}, + +static PyObject * +_elementtree_Element_itertext_impl(ElementObject *self); + +static PyObject * +_elementtree_Element_itertext(ElementObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _elementtree_Element_itertext_impl(self); +} + +PyDoc_STRVAR(_elementtree_Element_insert__doc__, +"insert($self, index, subelement, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_INSERT_METHODDEF \ + {"insert", (PyCFunction)_elementtree_Element_insert, METH_VARARGS, _elementtree_Element_insert__doc__}, + +static PyObject * +_elementtree_Element_insert_impl(ElementObject *self, Py_ssize_t index, + PyObject *subelement); + +static PyObject * +_elementtree_Element_insert(ElementObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_ssize_t index; + PyObject *subelement; + + if (!PyArg_ParseTuple(args, "nO!:insert", + &index, &Element_Type, &subelement)) + goto exit; + return_value = _elementtree_Element_insert_impl(self, index, subelement); + +exit: + return return_value; +} + +PyDoc_STRVAR(_elementtree_Element_items__doc__, +"items($self, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_ITEMS_METHODDEF \ + {"items", (PyCFunction)_elementtree_Element_items, METH_NOARGS, _elementtree_Element_items__doc__}, + +static PyObject * +_elementtree_Element_items_impl(ElementObject *self); + +static PyObject * +_elementtree_Element_items(ElementObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _elementtree_Element_items_impl(self); +} + +PyDoc_STRVAR(_elementtree_Element_keys__doc__, +"keys($self, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_KEYS_METHODDEF \ + {"keys", (PyCFunction)_elementtree_Element_keys, METH_NOARGS, _elementtree_Element_keys__doc__}, + +static PyObject * +_elementtree_Element_keys_impl(ElementObject *self); + +static PyObject * +_elementtree_Element_keys(ElementObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _elementtree_Element_keys_impl(self); +} + +PyDoc_STRVAR(_elementtree_Element_makeelement__doc__, +"makeelement($self, tag, attrib, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_MAKEELEMENT_METHODDEF \ + {"makeelement", (PyCFunction)_elementtree_Element_makeelement, METH_VARARGS, _elementtree_Element_makeelement__doc__}, + +static PyObject * +_elementtree_Element_makeelement_impl(ElementObject *self, PyObject *tag, + PyObject *attrib); + +static PyObject * +_elementtree_Element_makeelement(ElementObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *tag; + PyObject *attrib; + + if (!PyArg_UnpackTuple(args, "makeelement", + 2, 2, + &tag, &attrib)) + goto exit; + return_value = _elementtree_Element_makeelement_impl(self, tag, attrib); + +exit: + return return_value; +} + +PyDoc_STRVAR(_elementtree_Element_remove__doc__, +"remove($self, subelement, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_REMOVE_METHODDEF \ + {"remove", (PyCFunction)_elementtree_Element_remove, METH_O, _elementtree_Element_remove__doc__}, + +static PyObject * +_elementtree_Element_remove_impl(ElementObject *self, PyObject *subelement); + +static PyObject * +_elementtree_Element_remove(ElementObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *subelement; + + if (!PyArg_Parse(arg, "O!:remove", &Element_Type, &subelement)) + goto exit; + return_value = _elementtree_Element_remove_impl(self, subelement); + +exit: + return return_value; +} + +PyDoc_STRVAR(_elementtree_Element_set__doc__, +"set($self, key, value, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_SET_METHODDEF \ + {"set", (PyCFunction)_elementtree_Element_set, METH_VARARGS, _elementtree_Element_set__doc__}, + +static PyObject * +_elementtree_Element_set_impl(ElementObject *self, PyObject *key, + PyObject *value); + +static PyObject * +_elementtree_Element_set(ElementObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *key; + PyObject *value; + + if (!PyArg_UnpackTuple(args, "set", + 2, 2, + &key, &value)) + goto exit; + return_value = _elementtree_Element_set_impl(self, key, value); + +exit: + return return_value; +} + +static int +_elementtree_TreeBuilder___init___impl(TreeBuilderObject *self, + PyObject *element_factory); + +static int +_elementtree_TreeBuilder___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + static char *_keywords[] = {"element_factory", NULL}; + PyObject *element_factory = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:TreeBuilder", _keywords, + &element_factory)) + goto exit; + return_value = _elementtree_TreeBuilder___init___impl((TreeBuilderObject *)self, element_factory); + +exit: + return return_value; +} + +PyDoc_STRVAR(_elementtree_TreeBuilder_data__doc__, +"data($self, data, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_TREEBUILDER_DATA_METHODDEF \ + {"data", (PyCFunction)_elementtree_TreeBuilder_data, METH_O, _elementtree_TreeBuilder_data__doc__}, + +PyDoc_STRVAR(_elementtree_TreeBuilder_end__doc__, +"end($self, tag, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_TREEBUILDER_END_METHODDEF \ + {"end", (PyCFunction)_elementtree_TreeBuilder_end, METH_O, _elementtree_TreeBuilder_end__doc__}, + +PyDoc_STRVAR(_elementtree_TreeBuilder_close__doc__, +"close($self, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_TREEBUILDER_CLOSE_METHODDEF \ + {"close", (PyCFunction)_elementtree_TreeBuilder_close, METH_NOARGS, _elementtree_TreeBuilder_close__doc__}, + +static PyObject * +_elementtree_TreeBuilder_close_impl(TreeBuilderObject *self); + +static PyObject * +_elementtree_TreeBuilder_close(TreeBuilderObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _elementtree_TreeBuilder_close_impl(self); +} + +PyDoc_STRVAR(_elementtree_TreeBuilder_start__doc__, +"start($self, tag, attrs=None, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_TREEBUILDER_START_METHODDEF \ + {"start", (PyCFunction)_elementtree_TreeBuilder_start, METH_VARARGS, _elementtree_TreeBuilder_start__doc__}, + +static PyObject * +_elementtree_TreeBuilder_start_impl(TreeBuilderObject *self, PyObject *tag, + PyObject *attrs); + +static PyObject * +_elementtree_TreeBuilder_start(TreeBuilderObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *tag; + PyObject *attrs = Py_None; + + if (!PyArg_UnpackTuple(args, "start", + 1, 2, + &tag, &attrs)) + goto exit; + return_value = _elementtree_TreeBuilder_start_impl(self, tag, attrs); + +exit: + return return_value; +} + +static int +_elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *html, + PyObject *target, const char *encoding); + +static int +_elementtree_XMLParser___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + static char *_keywords[] = {"html", "target", "encoding", NULL}; + PyObject *html = NULL; + PyObject *target = NULL; + const char *encoding = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOz:XMLParser", _keywords, + &html, &target, &encoding)) + goto exit; + return_value = _elementtree_XMLParser___init___impl((XMLParserObject *)self, html, target, encoding); + +exit: + return return_value; +} + +PyDoc_STRVAR(_elementtree_XMLParser_close__doc__, +"close($self, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_XMLPARSER_CLOSE_METHODDEF \ + {"close", (PyCFunction)_elementtree_XMLParser_close, METH_NOARGS, _elementtree_XMLParser_close__doc__}, + +static PyObject * +_elementtree_XMLParser_close_impl(XMLParserObject *self); + +static PyObject * +_elementtree_XMLParser_close(XMLParserObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _elementtree_XMLParser_close_impl(self); +} + +PyDoc_STRVAR(_elementtree_XMLParser_feed__doc__, +"feed($self, data, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_XMLPARSER_FEED_METHODDEF \ + {"feed", (PyCFunction)_elementtree_XMLParser_feed, METH_O, _elementtree_XMLParser_feed__doc__}, + +PyDoc_STRVAR(_elementtree_XMLParser__parse_whole__doc__, +"_parse_whole($self, file, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_XMLPARSER__PARSE_WHOLE_METHODDEF \ + {"_parse_whole", (PyCFunction)_elementtree_XMLParser__parse_whole, METH_O, _elementtree_XMLParser__parse_whole__doc__}, + +PyDoc_STRVAR(_elementtree_XMLParser_doctype__doc__, +"doctype($self, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_XMLPARSER_DOCTYPE_METHODDEF \ + {"doctype", (PyCFunction)_elementtree_XMLParser_doctype, METH_NOARGS, _elementtree_XMLParser_doctype__doc__}, + +static PyObject * +_elementtree_XMLParser_doctype_impl(XMLParserObject *self); + +static PyObject * +_elementtree_XMLParser_doctype(XMLParserObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _elementtree_XMLParser_doctype_impl(self); +} + +PyDoc_STRVAR(_elementtree_XMLParser__setevents__doc__, +"_setevents($self, events_queue, events_to_report=None, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_XMLPARSER__SETEVENTS_METHODDEF \ + {"_setevents", (PyCFunction)_elementtree_XMLParser__setevents, METH_VARARGS, _elementtree_XMLParser__setevents__doc__}, + +static PyObject * +_elementtree_XMLParser__setevents_impl(XMLParserObject *self, + PyObject *events_queue, + PyObject *events_to_report); + +static PyObject * +_elementtree_XMLParser__setevents(XMLParserObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *events_queue; + PyObject *events_to_report = Py_None; + + if (!PyArg_ParseTuple(args, "O!|O:_setevents", + &PyList_Type, &events_queue, &events_to_report)) + goto exit; + return_value = _elementtree_XMLParser__setevents_impl(self, events_queue, events_to_report); + +exit: + return return_value; +} +/*[clinic end generated code: output=119aed84c1545187 input=a9049054013a1b77]*/